updated mailbox app password

This commit is contained in:
2026-08-13 07:03:40 +01:00
parent 70fa1a5f2c
commit 70c05cc777
21 changed files with 618 additions and 33 deletions
+32
View File
@@ -2,6 +2,7 @@ package smtpserver
import (
"bytes"
"encoding/base64"
"io"
"mime"
"mime/multipart"
@@ -84,6 +85,11 @@ func parseMessage(raw []byte) (*parsedMessage, error) {
break
}
data, _ := io.ReadAll(part)
// multipart.Reader auto-decodes quoted-printable transparently during Read,
// but not base64 (see the mime/multipart docs) — without this, a base64
// attachment/body part is stored/relayed-for-display as raw base64 text
// instead of its actual decoded bytes.
data = decodeContentTransferEncoding(part.Header.Get("Content-Transfer-Encoding"), data)
disp, dispParams, _ := mime.ParseMediaType(part.Header.Get("Content-Disposition"))
partCT := part.Header.Get("Content-Type")
partMediaType, _, _ := mime.ParseMediaType(partCT)
@@ -107,3 +113,29 @@ func parseMessage(raw []byte) (*parsedMessage, error) {
out.BodyText = strings.TrimSpace(out.BodyText)
return out, nil
}
// decodeContentTransferEncoding decodes a MIME part's body per its
// Content-Transfer-Encoding when that isn't already handled transparently by
// multipart.Reader (which only auto-decodes quoted-printable). base64 bodies are
// wrapped at a fixed line length, so whitespace/newlines are stripped before
// decoding. Falls back to the raw bytes on a decode error or any other encoding
// (7bit/8bit/binary need no transform).
func decodeContentTransferEncoding(cte string, data []byte) []byte {
if !strings.EqualFold(strings.TrimSpace(cte), "base64") {
return data
}
cleaned := make([]byte, 0, len(data))
for _, b := range data {
switch b {
case ' ', '\t', '\r', '\n':
continue
default:
cleaned = append(cleaned, b)
}
}
decoded, err := base64.StdEncoding.DecodeString(string(cleaned))
if err != nil {
return data
}
return decoded
}