This commit is contained in:
2026-05-24 17:15:48 +00:00
parent 329d5c665a
commit 063b3b643f
22 changed files with 1348 additions and 92 deletions
+36
View File
@@ -232,6 +232,42 @@ func (s *Store) GetBodyParts(ctx context.Context, userID, messageID int64) (*Bod
return bp, nil
}
// GetAttachmentData decrypts and returns the bytes of the n-th attachment (0-based) for a message.
// Also returns filename and content-type. Returns an error when the attachment does not exist.
func (s *Store) GetAttachmentData(ctx context.Context, userID, messageID int64, n int) (data []byte, filename, contentType string, err error) {
att, err := s.db.GetAttachmentByIndex(ctx, messageID, n)
if err != nil {
return nil, "", "", fmt.Errorf("storage: get attachment index: %w", err)
}
if att == nil {
return nil, "", "", fmt.Errorf("storage: attachment %d not found for message %d", n, messageID)
}
key, err := s.crypt.DeriveKey("messages", userID)
if err != nil {
return nil, "", "", fmt.Errorf("storage: derive key: %w", err)
}
var encData []byte
if att.DataPath != "" {
encData, err = os.ReadFile(att.DataPath)
if err != nil {
return nil, "", "", fmt.Errorf("storage: read attachment file: %w", err)
}
} else {
encData = att.DataEnc
}
if len(encData) == 0 {
return nil, "", "", fmt.Errorf("storage: attachment data empty")
}
plain, err := crypto.Decrypt(key, encData)
if err != nil {
return nil, "", "", fmt.Errorf("storage: decrypt attachment: %w", err)
}
return plain, att.Filename, att.ContentType, nil
}
// parseMIME walks a raw RFC822 message and extracts body parts and attachments.
func parseMIME(raw []byte) (bodyText, bodyHTML string, attachments []parsedAttachment) {
m, err := mail.ReadMessage(bytes.NewReader(raw))