77 lines
1.8 KiB
Go
77 lines
1.8 KiB
Go
package mail
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/ultisuite/ulti-backend/internal/mail/sanitize"
|
|
)
|
|
|
|
const resanitizeBatchSize = 200
|
|
|
|
type ResanitizeBodiesResult struct {
|
|
Scanned int `json:"scanned"`
|
|
Updated int `json:"updated"`
|
|
}
|
|
|
|
// ResanitizeAccountBodies re-applies email HTML sanitization to stored messages.
|
|
func (s *Service) ResanitizeAccountBodies(ctx context.Context, externalID, accountID string) (ResanitizeBodiesResult, error) {
|
|
if err := s.verifyAccountOwnership(ctx, externalID, accountID); err != nil {
|
|
return ResanitizeBodiesResult{}, err
|
|
}
|
|
return s.ResanitizeAccountBodiesByID(ctx, accountID)
|
|
}
|
|
|
|
// ResanitizeAccountBodiesByID re-sanitizes messages without an ownership check (CLI/admin).
|
|
func (s *Service) ResanitizeAccountBodiesByID(ctx context.Context, accountID string) (ResanitizeBodiesResult, error) {
|
|
var result ResanitizeBodiesResult
|
|
var lastID string
|
|
for {
|
|
rows, err := s.db.Query(ctx, `
|
|
SELECT id, body_html
|
|
FROM messages
|
|
WHERE account_id = $1
|
|
AND body_html <> ''
|
|
AND ($2 = '' OR id > $2::uuid)
|
|
ORDER BY id
|
|
LIMIT $3
|
|
`, accountID, lastID, resanitizeBatchSize)
|
|
if err != nil {
|
|
return result, err
|
|
}
|
|
|
|
batchCount := 0
|
|
for rows.Next() {
|
|
var id, bodyHTML string
|
|
if err := rows.Scan(&id, &bodyHTML); err != nil {
|
|
rows.Close()
|
|
return result, err
|
|
}
|
|
batchCount++
|
|
result.Scanned++
|
|
lastID = id
|
|
|
|
sanitized := sanitize.SanitizeHTML(bodyHTML)
|
|
if sanitized == bodyHTML {
|
|
continue
|
|
}
|
|
if _, err := s.db.Exec(ctx, `
|
|
UPDATE messages SET body_html = $2, updated_at = NOW() WHERE id = $1
|
|
`, id, sanitized); err != nil {
|
|
rows.Close()
|
|
return result, err
|
|
}
|
|
result.Updated++
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return result, err
|
|
}
|
|
rows.Close()
|
|
|
|
if batchCount < resanitizeBatchSize {
|
|
break
|
|
}
|
|
}
|
|
|
|
return result, nil
|
|
}
|