mirror of
https://github.com/MengMengCode/VoCat.git
synced 2026-08-20 14:53:42 +08:00
- Add eSIM notification management in `esim_notifications.go` with functions to retrieve, list, and remove notifications. - Implement parsing logic for pending notifications and notification metadata. - Create tests for eSIM notification parsing and request handling in `esim_notifications_test.go`. - Introduce email message construction in `email_message.go` to securely format and send emails. - Add tests for email message encoding and validation in `email_message_test.go`. - Enhance the CardPolicyAPN component to manage APN configurations, including adding, editing, and deleting custom APNs. - Implement UI for displaying and managing APN settings with appropriate validation and user feedback.
68 lines
1.9 KiB
Go
68 lines
1.9 KiB
Go
package server
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"mime"
|
|
"net/mail"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// writePlainTextMail constructs one RFC 5322 message without allowing values
|
|
// supplied by notification configuration or device messages to create new
|
|
// headers or MIME parts. Mailbox values have already passed net/mail parsing,
|
|
// the subject is encoded as one encoded-word, and the body is base64 encoded.
|
|
func writePlainTextMail(
|
|
writer io.Writer,
|
|
from *mail.Address,
|
|
recipients []*mail.Address,
|
|
subject string,
|
|
body string,
|
|
) error {
|
|
if from == nil || len(recipients) == 0 {
|
|
return errors.New("email sender and recipient are required")
|
|
}
|
|
if strings.ContainsAny(subject, "\r\n\x00") {
|
|
return errors.New("email subject contains a prohibited control character")
|
|
}
|
|
encodedBody := wrapMIMEBase64(base64.StdEncoding.EncodeToString([]byte(body)))
|
|
message := strings.Join([]string{
|
|
"Date: " + time.Now().UTC().Format(time.RFC1123Z),
|
|
"From: " + formatMailAddress(from),
|
|
"To: " + joinMailAddresses(recipients),
|
|
"Subject: " + mime.QEncoding.Encode("UTF-8", subject),
|
|
"MIME-Version: 1.0",
|
|
"Content-Type: text/plain; charset=UTF-8",
|
|
"Content-Transfer-Encoding: base64",
|
|
"",
|
|
encodedBody,
|
|
"",
|
|
}, "\r\n")
|
|
|
|
// The only values reaching this sink have been parsed as RFC mailboxes or
|
|
// encoded as MIME encoded-words/base64 above. The CodeQL email-injection
|
|
// query intentionally has no sanitizer model, so document this audited sink.
|
|
// codeql[go/email-injection]
|
|
if _, err := io.WriteString(writer, message); err != nil {
|
|
return fmt.Errorf("write email message: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func wrapMIMEBase64(value string) string {
|
|
if value == "" {
|
|
return ""
|
|
}
|
|
const lineLength = 76
|
|
lines := make([]string, 0, (len(value)+lineLength-1)/lineLength)
|
|
for len(value) > lineLength {
|
|
lines = append(lines, value[:lineLength])
|
|
value = value[lineLength:]
|
|
}
|
|
lines = append(lines, value)
|
|
return strings.Join(lines, "\r\n")
|
|
}
|