From 5631b1540abcde4812ba3ed7d6a85e8ad2d43a03 Mon Sep 17 00:00:00 2001 From: yusing Date: Sat, 28 Jun 2025 14:46:54 +0800 Subject: [PATCH] fix(notif): refactor and fix json payload validation and handling --- internal/notif/mime_types.go | 8 ++++++++ internal/notif/webhook.go | 31 +++++++++++++++++++++++++------ 2 files changed, 33 insertions(+), 6 deletions(-) create mode 100644 internal/notif/mime_types.go diff --git a/internal/notif/mime_types.go b/internal/notif/mime_types.go new file mode 100644 index 00000000..aae1504e --- /dev/null +++ b/internal/notif/mime_types.go @@ -0,0 +1,8 @@ +package notif + +const ( + MimeTypeJSON = "application/json" + MimeTypeForm = "application/x-www-form-urlencoded" + MimeTypeText = "text/plain" + MimeTypeMarkdown = "text/markdown" +) diff --git a/internal/notif/webhook.go b/internal/notif/webhook.go index a0c7d65f..6a274fe2 100644 --- a/internal/notif/webhook.go +++ b/internal/notif/webhook.go @@ -33,16 +33,18 @@ func (webhook *Webhook) Validate() gperr.Error { switch webhook.MIMEType { case "": - webhook.MIMEType = "application/json" - case "application/json", "application/x-www-form-urlencoded", "text/plain": + webhook.MIMEType = MimeTypeJSON + case MimeTypeJSON, MimeTypeForm, MimeTypeText: default: - return gperr.New("invalid mime_type, expect empty, 'application/json', 'application/x-www-form-urlencoded' or 'text/plain'") + return gperr.Errorf("invalid mime_type, expect %s", strings.Join([]string{"empty", MimeTypeJSON, MimeTypeForm, MimeTypeText}, ", ")) } switch webhook.Template { case "": - if webhook.MIMEType == "application/json" && !json.Valid([]byte(webhook.Payload)) { - return gperr.New("invalid payload, expect valid JSON") + if webhook.MIMEType == MimeTypeJSON { + if !validateJSONPayload(webhook.Payload) { + return gperr.New("invalid payload, expect valid JSON") + } } if webhook.Payload == "" { return gperr.New("invalid payload, expect non-empty") @@ -50,7 +52,7 @@ func (webhook *Webhook) Validate() gperr.Error { case "discord": webhook.ColorMode = "dec" webhook.Method = http.MethodPost - webhook.MIMEType = "application/json" + webhook.MIMEType = MimeTypeJSON if webhook.Payload == "" { webhook.Payload = discordPayload } @@ -115,6 +117,12 @@ func (webhook *Webhook) MarshalMessage(logMsg *LogMessage) ([]byte, error) { if err != nil { return nil, err } + if webhook.MIMEType == MimeTypeJSON { + message, err = json.Marshal(string(message)) + if err != nil { + return nil, err + } + } plTempl := strings.NewReplacer( "$title", string(title), "$message", string(message), @@ -130,3 +138,14 @@ func (webhook *Webhook) MarshalMessage(logMsg *LogMessage) ([]byte, error) { pl = plTempl.Replace(pl) return []byte(pl), nil } + +func validateJSONPayload(payload string) bool { + replacer := strings.NewReplacer( + "$title", `""`, + "$message", `""`, + "$fields", `""`, + "$color", "", + ) + payload = replacer.Replace(payload) + return json.Valid([]byte(payload)) +}