From ad5c8d33db5a7e97fd51334bfb20aa944767abc8 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sat, 20 Sep 2025 15:57:11 +0200 Subject: [PATCH 01/54] loosen regex to allow for more comples go templates --- internals/proxy/middlewares/template.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internals/proxy/middlewares/template.go b/internals/proxy/middlewares/template.go index 4365185d..bd2daf35 100644 --- a/internals/proxy/middlewares/template.go +++ b/internals/proxy/middlewares/template.go @@ -111,7 +111,7 @@ func TemplateBody(data map[string]any, VARIABLES map[string]any) (map[string]any jsonStr := jsonutils.ToJson(data) if jsonStr != "" { - re, err := regexp.Compile(`{{\s*\@([a-zA-Z0-9_.]+)\s*}}`) + re, err := regexp.Compile(`{{.*(\@[a-zA-Z0-9_.]+).*}}`) if err != nil { return data, false, err From dfdfd346d14807fedafbd9bb1c24dade24a63150 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sat, 20 Sep 2025 16:39:51 +0200 Subject: [PATCH 02/54] update regex for json templating --- utils/templating/templating.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/utils/templating/templating.go b/utils/templating/templating.go index 3f66c90d..31175120 100644 --- a/utils/templating/templating.go +++ b/utils/templating/templating.go @@ -128,11 +128,11 @@ func RenderJSONTemplate(name string, data map[string]any, variables map[string]a tmplStr := string(jsonBytes) - re, err := regexp.Compile(`{{\s*\.([a-zA-Z0-9_.]+)\s*}}`) + re, err := regexp.Compile(`{{.*(\.[a-zA-Z0-9_.]+).*}}`) // Add normalize() to be able to remove Quotes from Arrays if err == nil { - tmplStr = re.ReplaceAllString(tmplStr, "{{normalize .$1}}") + tmplStr = re.ReplaceAllString(tmplStr, "{{normalize $1}}") } templt := CreateTemplateWithFunc(name, template.FuncMap{ @@ -166,7 +166,7 @@ func RenderJSONTemplate(name string, data map[string]any, variables map[string]a } func RenderNormalizedTemplate(name string, tmplStr string, variables any) (string, error) { - re, err := regexp.Compile(`{{\s*\.(\w+)\s*}}`) + re, err := regexp.Compile(`{{.*\.[a-zA-Z0-9_.]+.*}}`) // Add normalize() to normalize arrays to [item1,item2] if err == nil { From f87b937f2a913cdcbb5ad1db6f8881be7ab47b64 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sat, 20 Sep 2025 17:04:05 +0200 Subject: [PATCH 03/54] fixed regex not matching --- internals/proxy/middlewares/template.go | 4 ++-- utils/templating/templating.go | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/internals/proxy/middlewares/template.go b/internals/proxy/middlewares/template.go index bd2daf35..a4ebed63 100644 --- a/internals/proxy/middlewares/template.go +++ b/internals/proxy/middlewares/template.go @@ -111,13 +111,13 @@ func TemplateBody(data map[string]any, VARIABLES map[string]any) (map[string]any jsonStr := jsonutils.ToJson(data) if jsonStr != "" { - re, err := regexp.Compile(`{{.*(\@[a-zA-Z0-9_.]+).*}}`) + re, err := regexp.Compile(`{{.*?\@([a-zA-Z0-9_.]+).*?}}`) if err != nil { return data, false, err } - jsonStr = re.ReplaceAllString(jsonStr, "{{.$1}}") + jsonStr = re.ReplaceAllString(jsonStr, ".$1") normalizedData, err := jsonutils.GetJsonSafe[map[string]any](jsonStr) diff --git a/utils/templating/templating.go b/utils/templating/templating.go index 31175120..fbccc001 100644 --- a/utils/templating/templating.go +++ b/utils/templating/templating.go @@ -128,11 +128,11 @@ func RenderJSONTemplate(name string, data map[string]any, variables map[string]a tmplStr := string(jsonBytes) - re, err := regexp.Compile(`{{.*(\.[a-zA-Z0-9_.]+).*}}`) + re, err := regexp.Compile(`{{.*?\.([a-zA-Z0-9_.]+).*?}}`) // Add normalize() to be able to remove Quotes from Arrays if err == nil { - tmplStr = re.ReplaceAllString(tmplStr, "{{normalize $1}}") + tmplStr = re.ReplaceAllString(tmplStr, "{{normalize .$1}}") } templt := CreateTemplateWithFunc(name, template.FuncMap{ @@ -166,7 +166,7 @@ func RenderJSONTemplate(name string, data map[string]any, variables map[string]a } func RenderNormalizedTemplate(name string, tmplStr string, variables any) (string, error) { - re, err := regexp.Compile(`{{.*\.[a-zA-Z0-9_.]+.*}}`) + re, err := regexp.Compile(`{{.*?\.([a-zA-Z0-9_.]+).*?}}`) // Add normalize() to normalize arrays to [item1,item2] if err == nil { From 4abbd8ca1f51caa75d70368ce84ec64ff1ab6594 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sat, 20 Sep 2025 17:07:38 +0200 Subject: [PATCH 04/54] debug --- utils/templating/templating.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/utils/templating/templating.go b/utils/templating/templating.go index fbccc001..69d3a264 100644 --- a/utils/templating/templating.go +++ b/utils/templating/templating.go @@ -7,6 +7,8 @@ import ( "regexp" "strings" "text/template" + + "github.com/codeshelldev/secured-signal-api/utils/logger" ) func normalize(value any) string { @@ -139,6 +141,8 @@ func RenderJSONTemplate(name string, data map[string]any, variables map[string]a "normalize": normalizeJSON, }) + logger.Dev("Template: ", tmplStr) + jsonStr, err := ParseTemplate(templt, tmplStr, variables) if err != nil { From 354c2e883fb0c94f936c9ccd945d8a12ef7a8b22 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sat, 20 Sep 2025 17:27:20 +0200 Subject: [PATCH 05/54] update regex --- utils/templating/templating.go | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/utils/templating/templating.go b/utils/templating/templating.go index 69d3a264..41a5e02e 100644 --- a/utils/templating/templating.go +++ b/utils/templating/templating.go @@ -130,11 +130,14 @@ func RenderJSONTemplate(name string, data map[string]any, variables map[string]a tmplStr := string(jsonBytes) - re, err := regexp.Compile(`{{.*?\.([a-zA-Z0-9_.]+).*?}}`) + re, err := regexp.Compile(`{{[^}]+}}`) // Add normalize() to be able to remove Quotes from Arrays if err == nil { - tmplStr = re.ReplaceAllString(tmplStr, "{{normalize .$1}}") + tmplStr = re.ReplaceAllStringFunc(tmplStr, func(tag string) string { + dotTag := "." + tag + return strings.ReplaceAll(tag, dotTag, "(normalize " + dotTag + ")") + }) } templt := CreateTemplateWithFunc(name, template.FuncMap{ @@ -170,11 +173,14 @@ func RenderJSONTemplate(name string, data map[string]any, variables map[string]a } func RenderNormalizedTemplate(name string, tmplStr string, variables any) (string, error) { - re, err := regexp.Compile(`{{.*?\.([a-zA-Z0-9_.]+).*?}}`) + re, err := regexp.Compile(`{{[^}]+}}`) // Add normalize() to normalize arrays to [item1,item2] if err == nil { - tmplStr = re.ReplaceAllString(tmplStr, "{{normalize .$1}}") + tmplStr = re.ReplaceAllStringFunc(tmplStr, func(tag string) string { + dotTag := "." + tag + return strings.ReplaceAll(tag, dotTag, "(normalize " + dotTag + ")") + }) } templt := CreateTemplateWithFunc(name, template.FuncMap{ @@ -182,4 +188,4 @@ func RenderNormalizedTemplate(name string, tmplStr string, variables any) (strin }) return ParseTemplate(templt, tmplStr, variables) -} \ No newline at end of file +} From 58489b43cccc9e501c44c2968029bcbbccd6a309 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sat, 20 Sep 2025 17:29:19 +0200 Subject: [PATCH 06/54] Update template.go regex --- internals/proxy/middlewares/template.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/internals/proxy/middlewares/template.go b/internals/proxy/middlewares/template.go index a4ebed63..ce6077e4 100644 --- a/internals/proxy/middlewares/template.go +++ b/internals/proxy/middlewares/template.go @@ -111,13 +111,16 @@ func TemplateBody(data map[string]any, VARIABLES map[string]any) (map[string]any jsonStr := jsonutils.ToJson(data) if jsonStr != "" { - re, err := regexp.Compile(`{{.*?\@([a-zA-Z0-9_.]+).*?}}`) + re, err := regexp.Compile(`{{[^}]+}}`) if err != nil { return data, false, err } - jsonStr = re.ReplaceAllString(jsonStr, ".$1") + tmplStr = re.ReplaceAllStringFunc(tmplStr, func(tag string) string { + dotTag := "." + tag + return strings.ReplaceAll(tag, dotTag, "(normalize " + dotTag + ")") + }) normalizedData, err := jsonutils.GetJsonSafe[map[string]any](jsonStr) @@ -184,4 +187,4 @@ func TemplateQuery(reqUrl *url.URL, data map[string]any, VARIABLES any) (string, reqRawQuery := originalQueryData.Encode() return reqRawQuery, data, modified, nil -} \ No newline at end of file +} From bf9ad9f96b908085c61c6539a15eeed51f83cbc5 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sat, 20 Sep 2025 20:35:16 +0200 Subject: [PATCH 07/54] update regex --- internals/proxy/middlewares/template.go | 13 ++++--- utils/templating/templating.go | 52 ++++++++++++++++++------- 2 files changed, 44 insertions(+), 21 deletions(-) diff --git a/internals/proxy/middlewares/template.go b/internals/proxy/middlewares/template.go index ce6077e4..d06b4852 100644 --- a/internals/proxy/middlewares/template.go +++ b/internals/proxy/middlewares/template.go @@ -111,17 +111,18 @@ func TemplateBody(data map[string]any, VARIABLES map[string]any) (map[string]any jsonStr := jsonutils.ToJson(data) if jsonStr != "" { - re, err := regexp.Compile(`{{[^}]+}}`) + jsonStr, err := templating.TransformTemplateKeys(jsonStr, '@', func(re *regexp.Regexp, match string) string { + return re.ReplaceAllStringFunc(match, func(varMatch string) string { + varName := re.ReplaceAllString(varMatch, "$1") + + return "." + varName + }) + }) if err != nil { return data, false, err } - tmplStr = re.ReplaceAllStringFunc(tmplStr, func(tag string) string { - dotTag := "." + tag - return strings.ReplaceAll(tag, dotTag, "(normalize " + dotTag + ")") - }) - normalizedData, err := jsonutils.GetJsonSafe[map[string]any](jsonStr) if err == nil { diff --git a/utils/templating/templating.go b/utils/templating/templating.go index 41a5e02e..2354fbaa 100644 --- a/utils/templating/templating.go +++ b/utils/templating/templating.go @@ -79,6 +79,36 @@ func cleanQuotedPairsJSON(s string) string { }) } +func AddTemplateFunc(tmplStr string, funcName string) (string, error) { + return TransformTemplateKeys(tmplStr, '.', func(re *regexp.Regexp, match string) string { + return re.ReplaceAllStringFunc(match, func(varMatch string) string { + varName := re.ReplaceAllString(varMatch, "$1") + + return strings.ReplaceAll(varMatch, varName, "(" + funcName + " " + varName + ")") + }) + }) +} + +func TransformTemplateKeys(tmplStr string, tmplKey rune, transform func(varRegex *regexp.Regexp, m string) string) (string, error) { + re, err := regexp.Compile(`{{[^}]+}}`) + + if err != nil { + return tmplStr, err + } + + varRe, err := regexp.Compile(`\` + string(tmplKey) + `(\w+)`) + + if err != nil { + return tmplStr, err + } + + tmplStr = re.ReplaceAllStringFunc(tmplStr, func(match string) string { + return transform(varRe, match) + }) + + return tmplStr, nil +} + func ParseTemplate(templt *template.Template, tmplStr string, variables any) (string, error) { tmpl, err := templt.Parse(tmplStr) @@ -130,14 +160,10 @@ func RenderJSONTemplate(name string, data map[string]any, variables map[string]a tmplStr := string(jsonBytes) - re, err := regexp.Compile(`{{[^}]+}}`) + tmplStr, err = AddTemplateFunc(tmplStr, "normalize") - // Add normalize() to be able to remove Quotes from Arrays - if err == nil { - tmplStr = re.ReplaceAllStringFunc(tmplStr, func(tag string) string { - dotTag := "." + tag - return strings.ReplaceAll(tag, dotTag, "(normalize " + dotTag + ")") - }) + if err != nil { + return nil, err } templt := CreateTemplateWithFunc(name, template.FuncMap{ @@ -155,7 +181,7 @@ func RenderJSONTemplate(name string, data map[string]any, variables map[string]a jsonStr = cleanQuotedPairsJSON(jsonStr) // Remove the Quotes around "<<[item1,item2]>>" - re, err = regexp.Compile(`"<<(.*?)>>"`) + re, err := regexp.Compile(`"<<(.*?)>>"`) if err != nil { return nil, err @@ -173,14 +199,10 @@ func RenderJSONTemplate(name string, data map[string]any, variables map[string]a } func RenderNormalizedTemplate(name string, tmplStr string, variables any) (string, error) { - re, err := regexp.Compile(`{{[^}]+}}`) + tmplStr, err := AddTemplateFunc(tmplStr, "normalize") - // Add normalize() to normalize arrays to [item1,item2] - if err == nil { - tmplStr = re.ReplaceAllStringFunc(tmplStr, func(tag string) string { - dotTag := "." + tag - return strings.ReplaceAll(tag, dotTag, "(normalize " + dotTag + ")") - }) + if err != nil { + return tmplStr, err } templt := CreateTemplateWithFunc(name, template.FuncMap{ From e5d0459d2f4cf8af9f2395bf16dcb8c4d446b00b Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sat, 20 Sep 2025 20:43:28 +0200 Subject: [PATCH 08/54] debugging templating char issue --- utils/templating/templating.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/utils/templating/templating.go b/utils/templating/templating.go index 2354fbaa..094e3490 100644 --- a/utils/templating/templating.go +++ b/utils/templating/templating.go @@ -199,8 +199,12 @@ func RenderJSONTemplate(name string, data map[string]any, variables map[string]a } func RenderNormalizedTemplate(name string, tmplStr string, variables any) (string, error) { + logger.Dev("Before AddTemplateFunc: ", tmplStr) + tmplStr, err := AddTemplateFunc(tmplStr, "normalize") + logger.Dev("After AddTemplateFunc: ", tmplStr) + if err != nil { return tmplStr, err } From 415485581a05753fa3347cd434c0dfd9f19b81f2 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sat, 20 Sep 2025 20:48:00 +0200 Subject: [PATCH 09/54] fixed missing dot in template normilization --- utils/templating/templating.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/templating/templating.go b/utils/templating/templating.go index 094e3490..18d5afda 100644 --- a/utils/templating/templating.go +++ b/utils/templating/templating.go @@ -82,7 +82,7 @@ func cleanQuotedPairsJSON(s string) string { func AddTemplateFunc(tmplStr string, funcName string) (string, error) { return TransformTemplateKeys(tmplStr, '.', func(re *regexp.Regexp, match string) string { return re.ReplaceAllStringFunc(match, func(varMatch string) string { - varName := re.ReplaceAllString(varMatch, "$1") + varName := re.ReplaceAllString(varMatch, ".$1") return strings.ReplaceAll(varMatch, varName, "(" + funcName + " " + varName + ")") }) From 477fab938a7b53e0f7c6e5660a1f40a9711b2cd8 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sat, 20 Sep 2025 20:52:38 +0200 Subject: [PATCH 10/54] debug --- utils/templating/templating.go | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/utils/templating/templating.go b/utils/templating/templating.go index 18d5afda..0750e642 100644 --- a/utils/templating/templating.go +++ b/utils/templating/templating.go @@ -96,7 +96,7 @@ func TransformTemplateKeys(tmplStr string, tmplKey rune, transform func(varRegex return tmplStr, err } - varRe, err := regexp.Compile(`\` + string(tmplKey) + `(\w+)`) + varRe, err := regexp.Compile(`\` + string(tmplKey) + `([a-zA-Z0-9_.])`) if err != nil { return tmplStr, err @@ -160,8 +160,12 @@ func RenderJSONTemplate(name string, data map[string]any, variables map[string]a tmplStr := string(jsonBytes) + logger.Dev("Before AddTemplateFunc: ", tmplStr) + tmplStr, err = AddTemplateFunc(tmplStr, "normalize") + logger.Dev("After AddTemplateFunc: ", tmplStr) + if err != nil { return nil, err } @@ -170,8 +174,6 @@ func RenderJSONTemplate(name string, data map[string]any, variables map[string]a "normalize": normalizeJSON, }) - logger.Dev("Template: ", tmplStr) - jsonStr, err := ParseTemplate(templt, tmplStr, variables) if err != nil { @@ -199,12 +201,8 @@ func RenderJSONTemplate(name string, data map[string]any, variables map[string]a } func RenderNormalizedTemplate(name string, tmplStr string, variables any) (string, error) { - logger.Dev("Before AddTemplateFunc: ", tmplStr) - tmplStr, err := AddTemplateFunc(tmplStr, "normalize") - logger.Dev("After AddTemplateFunc: ", tmplStr) - if err != nil { return tmplStr, err } From b503215a6b6f4892038d5e59c15b02b9fd16e209 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sat, 20 Sep 2025 20:55:05 +0200 Subject: [PATCH 11/54] added missing `+` in regex --- utils/templating/templating.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/utils/templating/templating.go b/utils/templating/templating.go index 0750e642..d8c8fab2 100644 --- a/utils/templating/templating.go +++ b/utils/templating/templating.go @@ -96,7 +96,7 @@ func TransformTemplateKeys(tmplStr string, tmplKey rune, transform func(varRegex return tmplStr, err } - varRe, err := regexp.Compile(`\` + string(tmplKey) + `([a-zA-Z0-9_.])`) + varRe, err := regexp.Compile(`\` + string(tmplKey) + `([a-zA-Z0-9_.]+)`) if err != nil { return tmplStr, err @@ -160,12 +160,8 @@ func RenderJSONTemplate(name string, data map[string]any, variables map[string]a tmplStr := string(jsonBytes) - logger.Dev("Before AddTemplateFunc: ", tmplStr) - tmplStr, err = AddTemplateFunc(tmplStr, "normalize") - logger.Dev("After AddTemplateFunc: ", tmplStr) - if err != nil { return nil, err } @@ -174,6 +170,8 @@ func RenderJSONTemplate(name string, data map[string]any, variables map[string]a "normalize": normalizeJSON, }) + logger.Dev("Template: ", tmplStr) + jsonStr, err := ParseTemplate(templt, tmplStr, variables) if err != nil { From 44e138094b36fc587393d24ca173420741c354e2 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sat, 20 Sep 2025 20:57:54 +0200 Subject: [PATCH 12/54] readded missing debugs --- utils/templating/templating.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/utils/templating/templating.go b/utils/templating/templating.go index d8c8fab2..bf200838 100644 --- a/utils/templating/templating.go +++ b/utils/templating/templating.go @@ -160,8 +160,12 @@ func RenderJSONTemplate(name string, data map[string]any, variables map[string]a tmplStr := string(jsonBytes) + logger.Dev("Before AddTemplateFunc: ", tmplStr) + tmplStr, err = AddTemplateFunc(tmplStr, "normalize") + logger.Dev("After AddTemplateFunc: ", tmplStr) + if err != nil { return nil, err } From 108c6c7ecff5a6bfc3bae228495f2a64c6864f82 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sat, 20 Sep 2025 21:22:43 +0200 Subject: [PATCH 13/54] try unescaping string --- utils/templating/templating.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/utils/templating/templating.go b/utils/templating/templating.go index bf200838..a7a0235f 100644 --- a/utils/templating/templating.go +++ b/utils/templating/templating.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "regexp" + "strconv" "strings" "text/template" @@ -162,6 +163,8 @@ func RenderJSONTemplate(name string, data map[string]any, variables map[string]a logger.Dev("Before AddTemplateFunc: ", tmplStr) + tmplStr, _ = strconv.Unquote(`"` + tmplStr + `"`) + tmplStr, err = AddTemplateFunc(tmplStr, "normalize") logger.Dev("After AddTemplateFunc: ", tmplStr) From a2d3655357d915e4dddcd373b15e146a2c6ee7ed Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sat, 20 Sep 2025 21:36:27 +0200 Subject: [PATCH 14/54] testing newline behaviour --- utils/templating/templating.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/utils/templating/templating.go b/utils/templating/templating.go index a7a0235f..c96ebd5a 100644 --- a/utils/templating/templating.go +++ b/utils/templating/templating.go @@ -5,7 +5,6 @@ import ( "encoding/json" "fmt" "regexp" - "strconv" "strings" "text/template" @@ -161,9 +160,10 @@ func RenderJSONTemplate(name string, data map[string]any, variables map[string]a tmplStr := string(jsonBytes) - logger.Dev("Before AddTemplateFunc: ", tmplStr) + tmplStr = strings.ReplaceAll(tmplStr, "\n", ` + `) - tmplStr, _ = strconv.Unquote(`"` + tmplStr + `"`) + logger.Dev("Before AddTemplateFunc: ", tmplStr) tmplStr, err = AddTemplateFunc(tmplStr, "normalize") From 739eb6f3cfec6b99944ac8c03761fcd83fc06506 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sat, 20 Sep 2025 22:23:27 +0200 Subject: [PATCH 15/54] test new json templating func --- tests/json_test.go | 6 +-- utils/stringutils/stringutils.go | 2 +- utils/templating/templating.go | 76 ++++++++++++++++---------------- 3 files changed, 41 insertions(+), 43 deletions(-) diff --git a/tests/json_test.go b/tests/json_test.go index 87f10bb4..0a3eb7dd 100644 --- a/tests/json_test.go +++ b/tests/json_test.go @@ -44,11 +44,7 @@ func TestJsonTemplating(t *testing.T) { "key2": 4, } - got, err := templating.RenderJSONTemplate("json", data, variables) - - if err != nil { - t.Error("Error Templating JSON: ", err.Error()) - } + got := templating.RenderDataKeyTemplateRecursive("", data, variables) expectedStr := jsonutils.ToJson(expected) gotStr := jsonutils.ToJson(got) diff --git a/utils/stringutils/stringutils.go b/utils/stringutils/stringutils.go index 1857ee7d..92a93645 100644 --- a/utils/stringutils/stringutils.go +++ b/utils/stringutils/stringutils.go @@ -1,4 +1,4 @@ -package safestrings +package stringutils import ( "regexp" diff --git a/utils/templating/templating.go b/utils/templating/templating.go index c96ebd5a..ada83105 100644 --- a/utils/templating/templating.go +++ b/utils/templating/templating.go @@ -8,7 +8,7 @@ import ( "strings" "text/template" - "github.com/codeshelldev/secured-signal-api/utils/logger" + "github.com/codeshelldev/secured-signal-api/utils/stringutils" ) func normalize(value any) string { @@ -151,58 +151,60 @@ func RenderJSON(name string, data map[string]any, variables map[string]any) (map return data, nil } -func RenderJSONTemplate(name string, data map[string]any, variables map[string]any) (map[string]any, error) { - jsonBytes, err := json.Marshal(data) +func RenderDataKeyTemplateRecursive(key any, value any, variables map[string]any) (any) { + strKey, isStr := key.(string) - if err != nil { - return nil, err + if !isStr { + strKey = "!string" } - tmplStr := string(jsonBytes) - - tmplStr = strings.ReplaceAll(tmplStr, "\n", ` - `) - - logger.Dev("Before AddTemplateFunc: ", tmplStr) - - tmplStr, err = AddTemplateFunc(tmplStr, "normalize") - - logger.Dev("After AddTemplateFunc: ", tmplStr) + switch typedValue := value.(type) { + case map[string]any: + data := map[string]any{} - if err != nil { - return nil, err - } + for mapKey, mapValue := range typedValue { + data[mapKey] = RenderDataKeyTemplateRecursive(mapKey, mapValue, variables) + } - templt := CreateTemplateWithFunc(name, template.FuncMap{ - "normalize": normalizeJSON, - }) + return data - logger.Dev("Template: ", tmplStr) + case []any: + data := []any{} - jsonStr, err := ParseTemplate(templt, tmplStr, variables) + for arrayIndex, arrayValue := range typedValue { + data = append(data, RenderDataKeyTemplateRecursive(arrayIndex, arrayValue, variables)) + } - if err != nil { - return nil, err - } + return data + + case string: + templt := CreateTemplateWithFunc("json:" + strKey, template.FuncMap{ + "normalize": normalize, + }) - jsonStr = cleanQuotedPairsJSON(jsonStr) + tmplStr, _ := AddTemplateFunc(typedValue, "normalize") - // Remove the Quotes around "<<[item1,item2]>>" - re, err := regexp.Compile(`"<<(.*?)>>"`) + templatedValue, _ := ParseTemplate(templt, tmplStr, variables) - if err != nil { - return nil, err - } + re, _ := regexp.Compile(`{{[^}]+}}`) - jsonStr = re.ReplaceAllString(jsonStr, "$1") + filtered := re.ReplaceAllString(tmplStr, "") - err = json.Unmarshal([]byte(jsonStr), &data) + re, _ = regexp.Compile(`(\S+)`) - if err != nil { - return nil, err + if !re.MatchString(filtered) { + return stringutils.ToType(templatedValue) + } + + return templatedValue + + default: + return typedValue } +} - return data, nil +func RenderJSONTemplate(name string, data map[string]any, variables map[string]any) (map[string]any, error) { + return RenderDataKeyTemplateRecursive("", data, variables).(map[string]any), nil } func RenderNormalizedTemplate(name string, tmplStr string, variables any) (string, error) { From 227c239698d4d50211eb7f3e9449686eba315837 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sat, 20 Sep 2025 22:28:10 +0200 Subject: [PATCH 16/54] debugging new json templater --- utils/templating/templating.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/utils/templating/templating.go b/utils/templating/templating.go index ada83105..dcf1c2dd 100644 --- a/utils/templating/templating.go +++ b/utils/templating/templating.go @@ -4,10 +4,12 @@ import ( "bytes" "encoding/json" "fmt" + "maps" "regexp" "strings" "text/template" + "github.com/codeshelldev/secured-signal-api/utils/logger" "github.com/codeshelldev/secured-signal-api/utils/stringutils" ) @@ -138,9 +140,7 @@ func CreateTemplateWithFunc(name string, funcMap template.FuncMap) (*template.Te func RenderJSON(name string, data map[string]any, variables map[string]any) (map[string]any, error) { combinedData := data - for key, value := range variables { - combinedData[key] = value - } + maps.Copy(combinedData, variables) data, err := RenderJSONTemplate(name, data, combinedData) @@ -178,6 +178,8 @@ func RenderDataKeyTemplateRecursive(key any, value any, variables map[string]any return data case string: + logger.Dev(typedValue) + templt := CreateTemplateWithFunc("json:" + strKey, template.FuncMap{ "normalize": normalize, }) From 68a60e892e06892e159ce0418f987eeebc33749d Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sat, 20 Sep 2025 22:31:46 +0200 Subject: [PATCH 17/54] further debugging --- utils/templating/templating.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/utils/templating/templating.go b/utils/templating/templating.go index dcf1c2dd..c2e2af57 100644 --- a/utils/templating/templating.go +++ b/utils/templating/templating.go @@ -178,7 +178,7 @@ func RenderDataKeyTemplateRecursive(key any, value any, variables map[string]any return data case string: - logger.Dev(typedValue) + logger.Dev("Raw:\n", typedValue) templt := CreateTemplateWithFunc("json:" + strKey, template.FuncMap{ "normalize": normalize, @@ -188,6 +188,8 @@ func RenderDataKeyTemplateRecursive(key any, value any, variables map[string]any templatedValue, _ := ParseTemplate(templt, tmplStr, variables) + logger.Dev("Templated:\n", templatedValue) + re, _ := regexp.Compile(`{{[^}]+}}`) filtered := re.ReplaceAllString(tmplStr, "") From 739220cd5097d80376858e4017a291cf1b3eff5c Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sat, 20 Sep 2025 22:34:05 +0200 Subject: [PATCH 18/54] testing templating --- utils/templating/templating.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/utils/templating/templating.go b/utils/templating/templating.go index c2e2af57..d8bea54d 100644 --- a/utils/templating/templating.go +++ b/utils/templating/templating.go @@ -186,7 +186,11 @@ func RenderDataKeyTemplateRecursive(key any, value any, variables map[string]any tmplStr, _ := AddTemplateFunc(typedValue, "normalize") - templatedValue, _ := ParseTemplate(templt, tmplStr, variables) + templatedValue, err := ParseTemplate(templt, tmplStr, variables) + + if err != nil { + logger.Dev(err.Error()) + } logger.Dev("Templated:\n", templatedValue) From c117da0611f016341763fff5afac27c8b3af6134 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sat, 20 Sep 2025 22:37:51 +0200 Subject: [PATCH 19/54] debugging --- utils/templating/templating.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/utils/templating/templating.go b/utils/templating/templating.go index d8bea54d..0964f48d 100644 --- a/utils/templating/templating.go +++ b/utils/templating/templating.go @@ -184,7 +184,9 @@ func RenderDataKeyTemplateRecursive(key any, value any, variables map[string]any "normalize": normalize, }) - tmplStr, _ := AddTemplateFunc(typedValue, "normalize") + //tmplStr, _ := AddTemplateFunc(typedValue, "normalize") + + tmplStr := typedValue templatedValue, err := ParseTemplate(templt, tmplStr, variables) From febabe523de475709bd2b9849163d1f565622aea Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sat, 20 Sep 2025 22:42:37 +0200 Subject: [PATCH 20/54] debugging empty message --- internals/proxy/middlewares/message.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/internals/proxy/middlewares/message.go b/internals/proxy/middlewares/message.go index 8f63a5d5..7a41f892 100644 --- a/internals/proxy/middlewares/message.go +++ b/internals/proxy/middlewares/message.go @@ -6,6 +6,7 @@ import ( "net/http" "strconv" + "github.com/codeshelldev/secured-signal-api/utils/jsonutils" log "github.com/codeshelldev/secured-signal-api/utils/logger" request "github.com/codeshelldev/secured-signal-api/utils/request" ) @@ -84,8 +85,12 @@ func (data MessageMiddleware) Use() http.Handler { func TemplateMessage(template string, data map[string]any, VARIABLES map[string]any) (map[string]any, error) { data["message_template"] = template + log.Dev(jsonutils.ToJson(data)) + data, ok, err := TemplateBody(data, VARIABLES) + log.Dev(jsonutils.ToJson(data)) + if err != nil || !ok || data == nil { return data, err } From f617f0fed10553d5727ec8f5248c152e3d480d2d Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sat, 20 Sep 2025 22:47:15 +0200 Subject: [PATCH 21/54] more testing --- internals/proxy/middlewares/message.go | 8 ++++---- internals/proxy/middlewares/template.go | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/internals/proxy/middlewares/message.go b/internals/proxy/middlewares/message.go index 7a41f892..894cc12b 100644 --- a/internals/proxy/middlewares/message.go +++ b/internals/proxy/middlewares/message.go @@ -85,13 +85,13 @@ func (data MessageMiddleware) Use() http.Handler { func TemplateMessage(template string, data map[string]any, VARIABLES map[string]any) (map[string]any, error) { data["message_template"] = template - log.Dev(jsonutils.ToJson(data)) + log.Dev("Before:\n",jsonutils.ToJson(data)) - data, ok, err := TemplateBody(data, VARIABLES) + data, _, err := TemplateBody(data, VARIABLES) - log.Dev(jsonutils.ToJson(data)) + log.Dev("After:\n",jsonutils.ToJson(data)) - if err != nil || !ok || data == nil { + if err != nil || data == nil { return data, err } diff --git a/internals/proxy/middlewares/template.go b/internals/proxy/middlewares/template.go index d06b4852..afc5583d 100644 --- a/internals/proxy/middlewares/template.go +++ b/internals/proxy/middlewares/template.go @@ -132,6 +132,8 @@ func TemplateBody(data map[string]any, VARIABLES map[string]any) (map[string]any templatedData, err := templating.RenderJSON("body", data, VARIABLES) + log.Dev("After:\n",jsonutils.ToJson(templatedData)) + if err != nil { return data, false, err } From 81fe946c4bb256c04c81c66fc4d13c15c3827cdd Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sat, 20 Sep 2025 22:57:52 +0200 Subject: [PATCH 22/54] restrict regex to only {{.var}} --- internals/proxy/middlewares/template.go | 2 -- utils/templating/templating.go | 10 ++-------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/internals/proxy/middlewares/template.go b/internals/proxy/middlewares/template.go index afc5583d..d06b4852 100644 --- a/internals/proxy/middlewares/template.go +++ b/internals/proxy/middlewares/template.go @@ -132,8 +132,6 @@ func TemplateBody(data map[string]any, VARIABLES map[string]any) (map[string]any templatedData, err := templating.RenderJSON("body", data, VARIABLES) - log.Dev("After:\n",jsonutils.ToJson(templatedData)) - if err != nil { return data, false, err } diff --git a/utils/templating/templating.go b/utils/templating/templating.go index 0964f48d..bdccb0a3 100644 --- a/utils/templating/templating.go +++ b/utils/templating/templating.go @@ -92,7 +92,7 @@ func AddTemplateFunc(tmplStr string, funcName string) (string, error) { } func TransformTemplateKeys(tmplStr string, tmplKey rune, transform func(varRegex *regexp.Regexp, m string) string) (string, error) { - re, err := regexp.Compile(`{{[^}]+}}`) + re, err := regexp.Compile(`{{\s+\` + string(tmplKey) + `[a-zA-Z0-9_.]+\s+}}`) if err != nil { return tmplStr, err @@ -178,15 +178,11 @@ func RenderDataKeyTemplateRecursive(key any, value any, variables map[string]any return data case string: - logger.Dev("Raw:\n", typedValue) - templt := CreateTemplateWithFunc("json:" + strKey, template.FuncMap{ "normalize": normalize, }) - //tmplStr, _ := AddTemplateFunc(typedValue, "normalize") - - tmplStr := typedValue + tmplStr, _ := AddTemplateFunc(typedValue, "normalize") templatedValue, err := ParseTemplate(templt, tmplStr, variables) @@ -194,8 +190,6 @@ func RenderDataKeyTemplateRecursive(key any, value any, variables map[string]any logger.Dev(err.Error()) } - logger.Dev("Templated:\n", templatedValue) - re, _ := regexp.Compile(`{{[^}]+}}`) filtered := re.ReplaceAllString(tmplStr, "") From 557c709b144282a0ce68e83c3deb9fcefd4e9abe Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sat, 20 Sep 2025 23:02:18 +0200 Subject: [PATCH 23/54] fix --- utils/templating/templating.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/utils/templating/templating.go b/utils/templating/templating.go index bdccb0a3..d8d9ba79 100644 --- a/utils/templating/templating.go +++ b/utils/templating/templating.go @@ -83,6 +83,12 @@ func cleanQuotedPairsJSON(s string) string { func AddTemplateFunc(tmplStr string, funcName string) (string, error) { return TransformTemplateKeys(tmplStr, '.', func(re *regexp.Regexp, match string) string { + reSimple, _ := regexp.Compile(`{{\s+\.[a-zA-Z0-9_.]+\s+}}`) + + if !reSimple.MatchString(match) { + return match + } + return re.ReplaceAllStringFunc(match, func(varMatch string) string { varName := re.ReplaceAllString(varMatch, ".$1") @@ -92,7 +98,7 @@ func AddTemplateFunc(tmplStr string, funcName string) (string, error) { } func TransformTemplateKeys(tmplStr string, tmplKey rune, transform func(varRegex *regexp.Regexp, m string) string) (string, error) { - re, err := regexp.Compile(`{{\s+\` + string(tmplKey) + `[a-zA-Z0-9_.]+\s+}}`) + re, err := regexp.Compile(`{{[^}]+}}`) if err != nil { return tmplStr, err From 35462e8e4c64979f141c3fced1c880a4d768c083 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sat, 20 Sep 2025 23:09:53 +0200 Subject: [PATCH 24/54] possible fix for nil message when no template provided --- internals/proxy/middlewares/message.go | 16 +++++++++------- utils/templating/templating.go | 1 + 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/internals/proxy/middlewares/message.go b/internals/proxy/middlewares/message.go index 894cc12b..f9858103 100644 --- a/internals/proxy/middlewares/message.go +++ b/internals/proxy/middlewares/message.go @@ -46,15 +46,17 @@ func (data MessageMiddleware) Use() http.Handler { if !body.Empty { bodyData = body.Data - newData, err := TemplateMessage(messageTemplate, bodyData, variables) + if messageTemplate != "" { + newData, err := TemplateMessage(messageTemplate, bodyData, variables) - if err != nil { - log.Error("Error Templating Message: ", err.Error()) - } + if err != nil { + log.Error("Error Templating Message: ", err.Error()) + } - if newData["message"] != bodyData["message"] && newData["message"] != "" { - bodyData = newData - modifiedBody = true + if newData["message"] != bodyData["message"] && newData["message"] != "" && newData["message"] != nil { + bodyData = newData + modifiedBody = true + } } } diff --git a/utils/templating/templating.go b/utils/templating/templating.go index d8d9ba79..d9eeb901 100644 --- a/utils/templating/templating.go +++ b/utils/templating/templating.go @@ -203,6 +203,7 @@ func RenderDataKeyTemplateRecursive(key any, value any, variables map[string]any re, _ = regexp.Compile(`(\S+)`) if !re.MatchString(filtered) { + logger.Dev(templatedValue) return stringutils.ToType(templatedValue) } From 003585db2a8de13abb21a3c4ab877c6d01928dc7 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sat, 20 Sep 2025 23:15:08 +0200 Subject: [PATCH 25/54] debugging --- internals/proxy/middlewares/message.go | 5 ----- internals/proxy/middlewares/template.go | 3 +++ 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/internals/proxy/middlewares/message.go b/internals/proxy/middlewares/message.go index f9858103..9794ce62 100644 --- a/internals/proxy/middlewares/message.go +++ b/internals/proxy/middlewares/message.go @@ -6,7 +6,6 @@ import ( "net/http" "strconv" - "github.com/codeshelldev/secured-signal-api/utils/jsonutils" log "github.com/codeshelldev/secured-signal-api/utils/logger" request "github.com/codeshelldev/secured-signal-api/utils/request" ) @@ -87,12 +86,8 @@ func (data MessageMiddleware) Use() http.Handler { func TemplateMessage(template string, data map[string]any, VARIABLES map[string]any) (map[string]any, error) { data["message_template"] = template - log.Dev("Before:\n",jsonutils.ToJson(data)) - data, _, err := TemplateBody(data, VARIABLES) - log.Dev("After:\n",jsonutils.ToJson(data)) - if err != nil || data == nil { return data, err } diff --git a/internals/proxy/middlewares/template.go b/internals/proxy/middlewares/template.go index d06b4852..4994557f 100644 --- a/internals/proxy/middlewares/template.go +++ b/internals/proxy/middlewares/template.go @@ -139,6 +139,9 @@ func TemplateBody(data map[string]any, VARIABLES map[string]any) (map[string]any beforeStr := jsonutils.ToJson(templatedData) afterStr := jsonutils.ToJson(data) + log.Dev(beforeStr) + log.Dev(afterStr) + modified = beforeStr == afterStr return templatedData, modified, nil From 04deb7d80251411c01c8696034bbd174aba4ec31 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sat, 20 Sep 2025 23:18:01 +0200 Subject: [PATCH 26/54] fixed modified flag --- internals/proxy/middlewares/template.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internals/proxy/middlewares/template.go b/internals/proxy/middlewares/template.go index 4994557f..7d2c256c 100644 --- a/internals/proxy/middlewares/template.go +++ b/internals/proxy/middlewares/template.go @@ -142,7 +142,7 @@ func TemplateBody(data map[string]any, VARIABLES map[string]any) (map[string]any log.Dev(beforeStr) log.Dev(afterStr) - modified = beforeStr == afterStr + modified = beforeStr != afterStr return templatedData, modified, nil } From 1193a688fa43ae1a6255c9a7296b361251444209 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sat, 20 Sep 2025 23:23:58 +0200 Subject: [PATCH 27/54] more debugging --- internals/proxy/middlewares/aliases.go | 2 ++ internals/proxy/middlewares/template.go | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/internals/proxy/middlewares/aliases.go b/internals/proxy/middlewares/aliases.go index 1f737b99..b1e877fa 100644 --- a/internals/proxy/middlewares/aliases.go +++ b/internals/proxy/middlewares/aliases.go @@ -73,6 +73,8 @@ func (data AliasMiddleware) Use() http.Handler { strData := body.ToString() + log.Debug("Applied Data Aliasing: ", strData) + req.ContentLength = int64(len(strData)) req.Header.Set("Content-Length", strconv.Itoa(len(strData))) } diff --git a/internals/proxy/middlewares/template.go b/internals/proxy/middlewares/template.go index 7d2c256c..c8457983 100644 --- a/internals/proxy/middlewares/template.go +++ b/internals/proxy/middlewares/template.go @@ -136,8 +136,8 @@ func TemplateBody(data map[string]any, VARIABLES map[string]any) (map[string]any return data, false, err } - beforeStr := jsonutils.ToJson(templatedData) - afterStr := jsonutils.ToJson(data) + beforeStr := jsonutils.ToJson(data) + afterStr := jsonutils.ToJson(templatedData) log.Dev(beforeStr) log.Dev(afterStr) From db4c7dd41e0b8e52fbd36e4ba9b839a7a01cc5b7 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sat, 20 Sep 2025 23:34:51 +0200 Subject: [PATCH 28/54] fix message overwrite --- internals/proxy/middlewares/aliases.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/internals/proxy/middlewares/aliases.go b/internals/proxy/middlewares/aliases.go index b1e877fa..9d501ed0 100644 --- a/internals/proxy/middlewares/aliases.go +++ b/internals/proxy/middlewares/aliases.go @@ -91,7 +91,9 @@ func processDataAliases(aliases map[string][]middlewareTypes.DataAlias, data map for key, alias := range aliases { key, value := getData(key, alias, data) - aliasData[key] = value + if value != nil { + aliasData[key] = value + } } return aliasData From f16ebe9b26713e26a089291dadf845d9c30a61d6 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sun, 21 Sep 2025 11:35:33 +0200 Subject: [PATCH 29/54] added headers to templating with `#` --- .github/templates/README.template.md | 47 +++++++++++++++- internals/proxy/middlewares/message.go | 12 ++-- internals/proxy/middlewares/template.go | 74 +++++++++++++++++++++---- tests/json_test.go | 6 +- utils/request/request.go | 10 ++++ utils/templating/templating.go | 62 +++++++++++++++------ 6 files changed, 175 insertions(+), 36 deletions(-) diff --git a/.github/templates/README.template.md b/.github/templates/README.template.md index ef746791..41639da9 100644 --- a/.github/templates/README.template.md +++ b/.github/templates/README.template.md @@ -220,6 +220,50 @@ If you are using Environment Variables as an example you won't be able to specif > If you have a string that should not be turned into any other type, then you will need to escape all Type Denotations, `[]` or `{}` (also `-`) with a `\` **Backslash** (or Double Backslash). > An **Odd** number of **Backslashes** **escape** the character in front of them and an **Even** number leave the character **as-is**. +### Templating + +Secured Signal API uses Golang's [Standard Templating Library](https://pkg.go.dev/text/template). +This means that any valid Go template string will also work in Secured Signal API. + +Go's templating library is used in the following features: + +- [Message Templates](#message-templates) +- [Placeholders](#placeholders) + +This makes advanced [Message Templates](#message-templates) like this one possible: + +```yaml +settings: + messageTemplate: | + {{- /* Variable declaration */ -}} + {{- $greeting := "Hello" -}} + {{- /* Simple variable output */ -}} + {{ $greeting }}, {{ @name }}! + {{- /* If-else conditional */}} + {{ if @age -}} + You are {{ @age }} years old. + {{- else -}} + Age unknown. + {{- end }} + {{- /* Range over slice */}} + Your friends: + {{- range @friends }} + - {{ . }} + {{- else }} + You have no friends. + {{- end }} + {{- /* Range over map */}} + Profile details: + {{- range $key, $value := @profile }} + - {{ $key }}: {{ $value }} + {{- end }} + {{- /* Nested templates */ -}} + {{ define "footer" -}} + This is the footer for {{ @name }}. + {{- end }} + {{ template "footer" . -}} +``` + ### API Token(s) During Authentication Secured Signal API will try to match the given Token against the list of Tokens inside of these Variables. @@ -301,7 +345,8 @@ settings: Sent with Secured Signal API. ``` -Use `{{@data.key}}` to reference Body Keys and `{{.KEY}}` for Variables. +Message Templates support [Standard Golang Templating](#templating). +Use `@data.key` to reference Body Keys and `.KEY` for Variables. ### Data Aliases diff --git a/internals/proxy/middlewares/message.go b/internals/proxy/middlewares/message.go index 9794ce62..80747089 100644 --- a/internals/proxy/middlewares/message.go +++ b/internals/proxy/middlewares/message.go @@ -46,7 +46,9 @@ func (data MessageMiddleware) Use() http.Handler { bodyData = body.Data if messageTemplate != "" { - newData, err := TemplateMessage(messageTemplate, bodyData, variables) + headerData := request.GetReqHeaders(req) + + newData, err := TemplateMessage(messageTemplate, bodyData, headerData, variables) if err != nil { log.Error("Error Templating Message: ", err.Error()) @@ -83,13 +85,13 @@ func (data MessageMiddleware) Use() http.Handler { }) } -func TemplateMessage(template string, data map[string]any, VARIABLES map[string]any) (map[string]any, error) { - data["message_template"] = template +func TemplateMessage(template string, bodyData map[string]any, headerData map[string]any, variables map[string]any) (map[string]any, error) { + bodyData["message_template"] = template - data, _, err := TemplateBody(data, VARIABLES) + data, _, err := TemplateBody(bodyData, headerData, variables) if err != nil || data == nil { - return data, err + return bodyData, err } data["message"] = data["message_template"] diff --git a/internals/proxy/middlewares/template.go b/internals/proxy/middlewares/template.go index c8457983..4d5848e9 100644 --- a/internals/proxy/middlewares/template.go +++ b/internals/proxy/middlewares/template.go @@ -42,7 +42,9 @@ func (data TemplateMiddleware) Use() http.Handler { if !body.Empty { var modified bool - bodyData, modified, err = TemplateBody(body.Data, variables) + headerData := request.GetReqHeaders(req) + + bodyData, modified, err = TemplateBody(body.Data, headerData, variables) if err != nil { log.Error("Error Templating JSON: ", err.Error()) @@ -105,24 +107,24 @@ func (data TemplateMiddleware) Use() http.Handler { }) } -func TemplateBody(data map[string]any, VARIABLES map[string]any) (map[string]any, bool, error) { - var modified bool - +func normalizeData(prefix rune, data map[string]any) (map[string]any, error) { jsonStr := jsonutils.ToJson(data) if jsonStr != "" { - jsonStr, err := templating.TransformTemplateKeys(jsonStr, '@', func(re *regexp.Regexp, match string) string { + toVar, err := templating.TransformTemplateKeys(jsonStr, prefix, func(re *regexp.Regexp, match string) string { return re.ReplaceAllStringFunc(match, func(varMatch string) string { varName := re.ReplaceAllString(varMatch, "$1") - return "." + varName + return "." + string(prefix) + varName }) }) if err != nil { - return data, false, err + return data, err } + jsonStr = toVar + normalizedData, err := jsonutils.GetJsonSafe[map[string]any](jsonStr) if err == nil { @@ -130,17 +132,65 @@ func TemplateBody(data map[string]any, VARIABLES map[string]any) (map[string]any } } - templatedData, err := templating.RenderJSON("body", data, VARIABLES) + return data, nil +} + +func prefixData(prefix rune, data map[string]any) (map[string]any) { + res := map[string]any{} + + for key, value := range data { + res[string(prefix) + key] = value + } + + return res +} + +func TemplateBody(bodyData map[string]any, headers map[string]any, VARIABLES map[string]any) (map[string]any, bool, error) { + var modified bool + + // Normalize #Var and @Var to .#Var and .@Var + data := bodyData + + bodyData, err := normalizeData('@', data) if err != nil { return data, false, err + } else { + data = bodyData } - beforeStr := jsonutils.ToJson(data) - afterStr := jsonutils.ToJson(templatedData) + headerData, err := normalizeData('#', data) - log.Dev(beforeStr) - log.Dev(afterStr) + if err != nil { + return data, false, err + } else { + data = headerData + } + + // Prefix Body Data with @ + bodyData = prefixData('@', bodyData) + + // Prefix Header Data with # + headerData = prefixData('#', headerData) + + variables := VARIABLES + + for key, value := range bodyData { + variables[key] = value + } + + for key, value := range headerData { + variables[key] = value + } + + templatedData, err := templating.RenderJSON("body", data, variables) + + if err != nil { + return bodyData, false, err + } + + beforeStr := jsonutils.ToJson(bodyData) + afterStr := jsonutils.ToJson(templatedData) modified = beforeStr != afterStr diff --git a/tests/json_test.go b/tests/json_test.go index 0a3eb7dd..0a8cad7c 100644 --- a/tests/json_test.go +++ b/tests/json_test.go @@ -44,7 +44,11 @@ func TestJsonTemplating(t *testing.T) { "key2": 4, } - got := templating.RenderDataKeyTemplateRecursive("", data, variables) + got, err := templating.RenderDataKeyTemplateRecursive("", data, variables) + + if err != nil { + t.Error("Error Templating JSON:\n", err.Error()) + } expectedStr := jsonutils.ToJson(expected) gotStr := jsonutils.ToJson(got) diff --git a/utils/request/request.go b/utils/request/request.go index cf26ab59..32fa389a 100644 --- a/utils/request/request.go +++ b/utils/request/request.go @@ -95,6 +95,16 @@ func GetBody(req *http.Request) ([]byte, error) { return bodyBytes, nil } +func GetReqHeaders(req *http.Request) (map[string]any) { + data := map[string]any{} + + for key, value := range req.Header { + data[key] = value + } + + return data +} + func GetReqBody(w http.ResponseWriter, req *http.Request) (Body, error) { bytes, err := GetBody(req) diff --git a/utils/templating/templating.go b/utils/templating/templating.go index d9eeb901..17b473cb 100644 --- a/utils/templating/templating.go +++ b/utils/templating/templating.go @@ -9,7 +9,6 @@ import ( "strings" "text/template" - "github.com/codeshelldev/secured-signal-api/utils/logger" "github.com/codeshelldev/secured-signal-api/utils/stringutils" ) @@ -83,7 +82,7 @@ func cleanQuotedPairsJSON(s string) string { func AddTemplateFunc(tmplStr string, funcName string) (string, error) { return TransformTemplateKeys(tmplStr, '.', func(re *regexp.Regexp, match string) string { - reSimple, _ := regexp.Compile(`{{\s+\.[a-zA-Z0-9_.]+\s+}}`) + reSimple, _ := regexp.Compile(`{{\s*\.[a-zA-Z0-9_.]+\s*}}`) if !reSimple.MatchString(match) { return match @@ -157,7 +156,9 @@ func RenderJSON(name string, data map[string]any, variables map[string]any) (map return data, nil } -func RenderDataKeyTemplateRecursive(key any, value any, variables map[string]any) (any) { +func RenderDataKeyTemplateRecursive(key any, value any, variables map[string]any) (any, error) { + var err error + strKey, isStr := key.(string) if !isStr { @@ -169,19 +170,35 @@ func RenderDataKeyTemplateRecursive(key any, value any, variables map[string]any data := map[string]any{} for mapKey, mapValue := range typedValue { - data[mapKey] = RenderDataKeyTemplateRecursive(mapKey, mapValue, variables) + var templatedValue any + + templatedValue, err = RenderDataKeyTemplateRecursive(mapKey, mapValue, variables) + + if err != nil { + return mapValue, err + } + + data[mapKey] = templatedValue } - return data + return data, err case []any: data := []any{} for arrayIndex, arrayValue := range typedValue { - data = append(data, RenderDataKeyTemplateRecursive(arrayIndex, arrayValue, variables)) + var templatedValue any + + templatedValue, err = RenderDataKeyTemplateRecursive(arrayIndex, arrayValue, variables) + + if err != nil { + return arrayValue, err + } + + data = append(data, templatedValue) } - return data + return data, err case string: templt := CreateTemplateWithFunc("json:" + strKey, template.FuncMap{ @@ -193,29 +210,40 @@ func RenderDataKeyTemplateRecursive(key any, value any, variables map[string]any templatedValue, err := ParseTemplate(templt, tmplStr, variables) if err != nil { - logger.Dev(err.Error()) + return typedValue, err } - re, _ := regexp.Compile(`{{[^}]+}}`) + templateRe, err := regexp.Compile(`{{[^}]+}}`) - filtered := re.ReplaceAllString(tmplStr, "") + if err == nil { + nonWhitespaceRe, err := regexp.Compile(`(\S+)`) - re, _ = regexp.Compile(`(\S+)`) + if err == nil { + filtered := nonWhitespaceRe.ReplaceAllString(tmplStr, "") - if !re.MatchString(filtered) { - logger.Dev(templatedValue) - return stringutils.ToType(templatedValue) + if !templateRe.MatchString(filtered) { + return stringutils.ToType(templatedValue), err + } + } } - return templatedValue + return templatedValue, err default: - return typedValue + return typedValue, err } } func RenderJSONTemplate(name string, data map[string]any, variables map[string]any) (map[string]any, error) { - return RenderDataKeyTemplateRecursive("", data, variables).(map[string]any), nil + res, err := RenderDataKeyTemplateRecursive("", data, variables) + + mapRes, ok := res.(map[string]any) + + if !ok { + return data, err + } + + return mapRes, err } func RenderNormalizedTemplate(name string, tmplStr string, variables any) (string, error) { From d3393028b4b4ac675e9de7b54e78e49652d3b152 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sun, 21 Sep 2025 11:38:03 +0200 Subject: [PATCH 30/54] remove unneeded funcs --- utils/templating/templating.go | 52 ---------------------------------- 1 file changed, 52 deletions(-) diff --git a/utils/templating/templating.go b/utils/templating/templating.go index 17b473cb..d3aeb4ff 100644 --- a/utils/templating/templating.go +++ b/utils/templating/templating.go @@ -2,7 +2,6 @@ package templating import ( "bytes" - "encoding/json" "fmt" "maps" "regexp" @@ -29,57 +28,6 @@ func normalize(value any) string { } } -func normalizeJSON(value any) string { - if value == nil { - return "" - } - - switch value.(type) { - case []any, []string, map[string]any, int, float64, bool: - object, _ := json.Marshal(value) - - if string(object) == "{}" { - return value.(string) - } - - return "<<" + string(object) + ">>" - - default: - return value.(string) - } -} - -func cleanQuotedPairsJSON(s string) string { - quoteRe, err := regexp.Compile(`"([^"]*?)"`) - - if err != nil { - return s - } - - pairRe, err := regexp.Compile(`<<([^<>]+)>>`) - - if err != nil { - return s - } - - return quoteRe.ReplaceAllStringFunc(s, func(container string) string { - inner := container[1 : len(container)-1] // remove quotes - - matches := pairRe.FindAllStringSubmatchIndex(inner, -1) - - // ONE pair which fills whole "" - if len(matches) == 1 && matches[0][0] == 0 && matches[0][1] == len(inner) { - return container // keep <<...>> untouched - } - - // MULTIPLE pairs || that do not fill whole "" - inner = pairRe.ReplaceAllString(inner, "$1") - inner = strings.ReplaceAll(inner, `"`, `'`) - - return `"` + inner + `"` - }) -} - func AddTemplateFunc(tmplStr string, funcName string) (string, error) { return TransformTemplateKeys(tmplStr, '.', func(re *regexp.Regexp, match string) string { reSimple, _ := regexp.Compile(`{{\s*\.[a-zA-Z0-9_.]+\s*}}`) From e1e439bcc614641ace7451317da80be1e74c36cb Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sun, 21 Sep 2025 11:49:20 +0200 Subject: [PATCH 31/54] debugging template issues --- internals/proxy/middlewares/template.go | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/internals/proxy/middlewares/template.go b/internals/proxy/middlewares/template.go index 4d5848e9..107d8529 100644 --- a/internals/proxy/middlewares/template.go +++ b/internals/proxy/middlewares/template.go @@ -3,6 +3,7 @@ package middlewares import ( "bytes" "io" + "maps" "net/http" "net/url" "regexp" @@ -174,14 +175,12 @@ func TemplateBody(bodyData map[string]any, headers map[string]any, VARIABLES map headerData = prefixData('#', headerData) variables := VARIABLES + + maps.Copy(bodyData, variables) + maps.Copy(headerData, variables) - for key, value := range bodyData { - variables[key] = value - } - - for key, value := range headerData { - variables[key] = value - } + log.Dev("Body:\n", jsonutils.ToJson(bodyData)) + log.Dev("Headers:\n", jsonutils.ToJson(headerData)) templatedData, err := templating.RenderJSON("body", data, variables) From 69cf270e5cb00ba1309260eb036b69916539248a Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sun, 21 Sep 2025 11:52:44 +0200 Subject: [PATCH 32/54] testing --- internals/proxy/middlewares/template.go | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/internals/proxy/middlewares/template.go b/internals/proxy/middlewares/template.go index 107d8529..5df437e8 100644 --- a/internals/proxy/middlewares/template.go +++ b/internals/proxy/middlewares/template.go @@ -146,26 +146,20 @@ func prefixData(prefix rune, data map[string]any) (map[string]any) { return res } -func TemplateBody(bodyData map[string]any, headers map[string]any, VARIABLES map[string]any) (map[string]any, bool, error) { +func TemplateBody(bodyData map[string]any, headerData map[string]any, VARIABLES map[string]any) (map[string]any, bool, error) { var modified bool // Normalize #Var and @Var to .#Var and .@Var - data := bodyData - - bodyData, err := normalizeData('@', data) + bodyData, err := normalizeData('@', bodyData) if err != nil { - return data, false, err - } else { - data = bodyData + return bodyData, false, err } - headerData, err := normalizeData('#', data) + headerData, err = normalizeData('#', headerData) if err != nil { - return data, false, err - } else { - data = headerData + return bodyData, false, err } // Prefix Body Data with @ @@ -182,7 +176,7 @@ func TemplateBody(bodyData map[string]any, headers map[string]any, VARIABLES map log.Dev("Body:\n", jsonutils.ToJson(bodyData)) log.Dev("Headers:\n", jsonutils.ToJson(headerData)) - templatedData, err := templating.RenderJSON("body", data, variables) + templatedData, err := templating.RenderJSON("body", bodyData, variables) if err != nil { return bodyData, false, err From 4678bd226e10e471b772a2ae5c35ffe4441eb1c5 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sun, 21 Sep 2025 11:56:45 +0200 Subject: [PATCH 33/54] fixed copy-order --- internals/proxy/middlewares/template.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internals/proxy/middlewares/template.go b/internals/proxy/middlewares/template.go index 5df437e8..2565eee8 100644 --- a/internals/proxy/middlewares/template.go +++ b/internals/proxy/middlewares/template.go @@ -170,8 +170,8 @@ func TemplateBody(bodyData map[string]any, headerData map[string]any, VARIABLES variables := VARIABLES - maps.Copy(bodyData, variables) - maps.Copy(headerData, variables) + maps.Copy(variables, bodyData) + maps.Copy(variables, headerData) log.Dev("Body:\n", jsonutils.ToJson(bodyData)) log.Dev("Headers:\n", jsonutils.ToJson(headerData)) From 8ea9b951171fca8b73329e5e51bdf3102b93b728 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sun, 21 Sep 2025 12:02:54 +0200 Subject: [PATCH 34/54] dont combine headers with body --- utils/templating/templating.go | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/utils/templating/templating.go b/utils/templating/templating.go index d3aeb4ff..100624df 100644 --- a/utils/templating/templating.go +++ b/utils/templating/templating.go @@ -3,7 +3,6 @@ package templating import ( "bytes" "fmt" - "maps" "regexp" "strings" "text/template" @@ -91,11 +90,7 @@ func CreateTemplateWithFunc(name string, funcMap template.FuncMap) (*template.Te } func RenderJSON(name string, data map[string]any, variables map[string]any) (map[string]any, error) { - combinedData := data - - maps.Copy(combinedData, variables) - - data, err := RenderJSONTemplate(name, data, combinedData) + data, err := RenderJSONTemplate(name, data, variables) if err != nil { return data, err From db476a32a1db973c7803af7bc8c2bea2ce21cded Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sun, 21 Sep 2025 12:05:59 +0200 Subject: [PATCH 35/54] debugging leaftover `@`'s --- internals/proxy/middlewares/template.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internals/proxy/middlewares/template.go b/internals/proxy/middlewares/template.go index 2565eee8..689870aa 100644 --- a/internals/proxy/middlewares/template.go +++ b/internals/proxy/middlewares/template.go @@ -152,6 +152,8 @@ func TemplateBody(bodyData map[string]any, headerData map[string]any, VARIABLES // Normalize #Var and @Var to .#Var and .@Var bodyData, err := normalizeData('@', bodyData) + log.Dev("Normalized:\n", jsonutils.ToJson(bodyData)) + if err != nil { return bodyData, false, err } From 1ffaf808b1ee69e0c94e0d835e2e9b43bf429f46 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sun, 21 Sep 2025 12:15:05 +0200 Subject: [PATCH 36/54] use literal strings to prefix not illegal chars: `@` + `#` --- internals/proxy/middlewares/template.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/internals/proxy/middlewares/template.go b/internals/proxy/middlewares/template.go index 689870aa..5b3c3fc2 100644 --- a/internals/proxy/middlewares/template.go +++ b/internals/proxy/middlewares/template.go @@ -108,7 +108,7 @@ func (data TemplateMiddleware) Use() http.Handler { }) } -func normalizeData(prefix rune, data map[string]any) (map[string]any, error) { +func normalizeData(prefix string, data map[string]any) (map[string]any, error) { jsonStr := jsonutils.ToJson(data) if jsonStr != "" { @@ -116,7 +116,7 @@ func normalizeData(prefix rune, data map[string]any) (map[string]any, error) { return re.ReplaceAllStringFunc(match, func(varMatch string) string { varName := re.ReplaceAllString(varMatch, "$1") - return "." + string(prefix) + varName + return "." + prefix + varName }) }) @@ -136,11 +136,11 @@ func normalizeData(prefix rune, data map[string]any) (map[string]any, error) { return data, nil } -func prefixData(prefix rune, data map[string]any) (map[string]any) { +func prefixData(prefix string, data map[string]any) (map[string]any) { res := map[string]any{} for key, value := range data { - res[string(prefix) + key] = value + res[prefix + key] = value } return res @@ -149,8 +149,8 @@ func prefixData(prefix rune, data map[string]any) (map[string]any) { func TemplateBody(bodyData map[string]any, headerData map[string]any, VARIABLES map[string]any) (map[string]any, bool, error) { var modified bool - // Normalize #Var and @Var to .#Var and .@Var - bodyData, err := normalizeData('@', bodyData) + // Normalize #Var and @Var to .HEADER_KEY_Var and .BODY_KEY_Var + bodyData, err := normalizeData("BODY_KEY_", bodyData) log.Dev("Normalized:\n", jsonutils.ToJson(bodyData)) @@ -158,17 +158,17 @@ func TemplateBody(bodyData map[string]any, headerData map[string]any, VARIABLES return bodyData, false, err } - headerData, err = normalizeData('#', headerData) + headerData, err = normalizeData("HEADER_KEY_", headerData) if err != nil { return bodyData, false, err } // Prefix Body Data with @ - bodyData = prefixData('@', bodyData) + bodyData = prefixData("BODY_KEY_", bodyData) // Prefix Header Data with # - headerData = prefixData('#', headerData) + headerData = prefixData("HEADER_KEY_", headerData) variables := VARIABLES From eb2132c233ecad9d1aefe620304889bc7ede4a28 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sun, 21 Sep 2025 12:18:38 +0200 Subject: [PATCH 37/54] fix --- internals/proxy/middlewares/template.go | 20 ++++++++++---------- utils/templating/templating.go | 6 +++--- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/internals/proxy/middlewares/template.go b/internals/proxy/middlewares/template.go index 5b3c3fc2..851ac6d8 100644 --- a/internals/proxy/middlewares/template.go +++ b/internals/proxy/middlewares/template.go @@ -108,15 +108,15 @@ func (data TemplateMiddleware) Use() http.Handler { }) } -func normalizeData(prefix string, data map[string]any) (map[string]any, error) { +func normalizeData(fromPrefix, toPrefix string, data map[string]any) (map[string]any, error) { jsonStr := jsonutils.ToJson(data) if jsonStr != "" { - toVar, err := templating.TransformTemplateKeys(jsonStr, prefix, func(re *regexp.Regexp, match string) string { + toVar, err := templating.TransformTemplateKeys(jsonStr, fromPrefix, func(re *regexp.Regexp, match string) string { return re.ReplaceAllStringFunc(match, func(varMatch string) string { varName := re.ReplaceAllString(varMatch, "$1") - return "." + prefix + varName + return "." + toPrefix + varName }) }) @@ -149,8 +149,8 @@ func prefixData(prefix string, data map[string]any) (map[string]any) { func TemplateBody(bodyData map[string]any, headerData map[string]any, VARIABLES map[string]any) (map[string]any, bool, error) { var modified bool - // Normalize #Var and @Var to .HEADER_KEY_Var and .BODY_KEY_Var - bodyData, err := normalizeData("BODY_KEY_", bodyData) + // Normalize #Var and @Var to .header_key_Var and .body_key_Var + bodyData, err := normalizeData("@", "body_key_", bodyData) log.Dev("Normalized:\n", jsonutils.ToJson(bodyData)) @@ -158,17 +158,17 @@ func TemplateBody(bodyData map[string]any, headerData map[string]any, VARIABLES return bodyData, false, err } - headerData, err = normalizeData("HEADER_KEY_", headerData) + headerData, err = normalizeData("#", "header_key_", headerData) if err != nil { return bodyData, false, err } - // Prefix Body Data with @ - bodyData = prefixData("BODY_KEY_", bodyData) + // Prefix Body Data with body_key_ + bodyData = prefixData("body_key_", bodyData) - // Prefix Header Data with # - headerData = prefixData("HEADER_KEY_", headerData) + // Prefix Header Data with header_key_ + headerData = prefixData("header_key_", headerData) variables := VARIABLES diff --git a/utils/templating/templating.go b/utils/templating/templating.go index 100624df..758199b5 100644 --- a/utils/templating/templating.go +++ b/utils/templating/templating.go @@ -28,7 +28,7 @@ func normalize(value any) string { } func AddTemplateFunc(tmplStr string, funcName string) (string, error) { - return TransformTemplateKeys(tmplStr, '.', func(re *regexp.Regexp, match string) string { + return TransformTemplateKeys(tmplStr, `\.`, func(re *regexp.Regexp, match string) string { reSimple, _ := regexp.Compile(`{{\s*\.[a-zA-Z0-9_.]+\s*}}`) if !reSimple.MatchString(match) { @@ -43,14 +43,14 @@ func AddTemplateFunc(tmplStr string, funcName string) (string, error) { }) } -func TransformTemplateKeys(tmplStr string, tmplKey rune, transform func(varRegex *regexp.Regexp, m string) string) (string, error) { +func TransformTemplateKeys(tmplStr string, prefix string, transform func(varRegex *regexp.Regexp, m string) string) (string, error) { re, err := regexp.Compile(`{{[^}]+}}`) if err != nil { return tmplStr, err } - varRe, err := regexp.Compile(`\` + string(tmplKey) + `([a-zA-Z0-9_.]+)`) + varRe, err := regexp.Compile(string(prefix) + `([a-zA-Z0-9_.]+)`) if err != nil { return tmplStr, err From d4deecfdf8c5da4e41cfd489c9ae91aa97c4245e Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sun, 21 Sep 2025 12:22:43 +0200 Subject: [PATCH 38/54] debugging --- internals/proxy/middlewares/message.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internals/proxy/middlewares/message.go b/internals/proxy/middlewares/message.go index 80747089..542ed132 100644 --- a/internals/proxy/middlewares/message.go +++ b/internals/proxy/middlewares/message.go @@ -6,6 +6,7 @@ import ( "net/http" "strconv" + "github.com/codeshelldev/secured-signal-api/utils/jsonutils" log "github.com/codeshelldev/secured-signal-api/utils/logger" request "github.com/codeshelldev/secured-signal-api/utils/request" ) @@ -90,6 +91,8 @@ func TemplateMessage(template string, bodyData map[string]any, headerData map[st data, _, err := TemplateBody(bodyData, headerData, variables) + log.Dev("msg:\n", jsonutils.ToJson(data)) + if err != nil || data == nil { return bodyData, err } From 794034208e98451f806178069c37df7e2be060eb Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sun, 21 Sep 2025 12:25:32 +0200 Subject: [PATCH 39/54] fix --- internals/proxy/middlewares/template.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/internals/proxy/middlewares/template.go b/internals/proxy/middlewares/template.go index 851ac6d8..03bba5c1 100644 --- a/internals/proxy/middlewares/template.go +++ b/internals/proxy/middlewares/template.go @@ -146,22 +146,22 @@ func prefixData(prefix string, data map[string]any) (map[string]any) { return res } -func TemplateBody(bodyData map[string]any, headerData map[string]any, VARIABLES map[string]any) (map[string]any, bool, error) { +func TemplateBody(body map[string]any, headers map[string]any, VARIABLES map[string]any) (map[string]any, bool, error) { var modified bool // Normalize #Var and @Var to .header_key_Var and .body_key_Var - bodyData, err := normalizeData("@", "body_key_", bodyData) + bodyData, err := normalizeData("@", "body_key_", body) log.Dev("Normalized:\n", jsonutils.ToJson(bodyData)) if err != nil { - return bodyData, false, err + return body, false, err } - headerData, err = normalizeData("#", "header_key_", headerData) + headerData, err := normalizeData("#", "header_key_", headers) if err != nil { - return bodyData, false, err + return body, false, err } // Prefix Body Data with body_key_ @@ -178,13 +178,13 @@ func TemplateBody(bodyData map[string]any, headerData map[string]any, VARIABLES log.Dev("Body:\n", jsonutils.ToJson(bodyData)) log.Dev("Headers:\n", jsonutils.ToJson(headerData)) - templatedData, err := templating.RenderJSON("body", bodyData, variables) + templatedData, err := templating.RenderJSON("body", body, variables) if err != nil { return bodyData, false, err } - beforeStr := jsonutils.ToJson(bodyData) + beforeStr := jsonutils.ToJson(body) afterStr := jsonutils.ToJson(templatedData) modified = beforeStr != afterStr From 9899092c6f54dc4b27e7026049ffb45912f5c54e Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sun, 21 Sep 2025 12:30:00 +0200 Subject: [PATCH 40/54] fixed body_key_ persisting after templating --- internals/proxy/middlewares/template.go | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/internals/proxy/middlewares/template.go b/internals/proxy/middlewares/template.go index 03bba5c1..b01f8a7f 100644 --- a/internals/proxy/middlewares/template.go +++ b/internals/proxy/middlewares/template.go @@ -150,38 +150,38 @@ func TemplateBody(body map[string]any, headers map[string]any, VARIABLES map[str var modified bool // Normalize #Var and @Var to .header_key_Var and .body_key_Var - bodyData, err := normalizeData("@", "body_key_", body) + normalizedBody, err := normalizeData("@", "body_key_", body) - log.Dev("Normalized:\n", jsonutils.ToJson(bodyData)) + log.Dev("Normalized:\n", jsonutils.ToJson(normalizedBody)) if err != nil { return body, false, err } - headerData, err := normalizeData("#", "header_key_", headers) + normalizedHeaders, err := normalizeData("#", "header_key_", headers) if err != nil { return body, false, err } // Prefix Body Data with body_key_ - bodyData = prefixData("body_key_", bodyData) + prefixedBody := prefixData("body_key_", normalizedBody) // Prefix Header Data with header_key_ - headerData = prefixData("header_key_", headerData) + prefixedHeaders := prefixData("header_key_", normalizedHeaders) variables := VARIABLES - maps.Copy(variables, bodyData) - maps.Copy(variables, headerData) + maps.Copy(variables, prefixedBody) + maps.Copy(variables, prefixedHeaders) - log.Dev("Body:\n", jsonutils.ToJson(bodyData)) - log.Dev("Headers:\n", jsonutils.ToJson(headerData)) + log.Dev("Body:\n", jsonutils.ToJson(prefixedBody)) + log.Dev("Headers:\n", jsonutils.ToJson(prefixedHeaders)) - templatedData, err := templating.RenderJSON("body", body, variables) + templatedData, err := templating.RenderJSON("body", normalizedBody, variables) if err != nil { - return bodyData, false, err + return body, false, err } beforeStr := jsonutils.ToJson(body) From 60ee50fc3a749032aa217221de0f56c8ea03a3ee Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sun, 21 Sep 2025 12:36:29 +0200 Subject: [PATCH 41/54] redact auth header --- internals/proxy/middlewares/template.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/internals/proxy/middlewares/template.go b/internals/proxy/middlewares/template.go index b01f8a7f..9c754496 100644 --- a/internals/proxy/middlewares/template.go +++ b/internals/proxy/middlewares/template.go @@ -8,6 +8,7 @@ import ( "net/url" "regexp" "strconv" + "strings" jsonutils "github.com/codeshelldev/secured-signal-api/utils/jsonutils" log "github.com/codeshelldev/secured-signal-api/utils/logger" @@ -146,6 +147,16 @@ func prefixData(prefix string, data map[string]any) (map[string]any) { return res } +func cleanHeaders(headers map[string]any) map[string]any { + authHeader, ok := headers["Authorization"].(string) + + if !ok { + authHeader = "REDACTED" + } + + headers["Authorization"] = strings.SplitAfterN(authHeader, ` `, 1)[0] + " REDACTED" +} + func TemplateBody(body map[string]any, headers map[string]any, VARIABLES map[string]any) (map[string]any, bool, error) { var modified bool From c5eff6280678c7ae7249a9ff434a221581bf707a Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sun, 21 Sep 2025 12:39:13 +0200 Subject: [PATCH 42/54] implemented cleaning --- internals/proxy/middlewares/template.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/internals/proxy/middlewares/template.go b/internals/proxy/middlewares/template.go index 9c754496..7b38b257 100644 --- a/internals/proxy/middlewares/template.go +++ b/internals/proxy/middlewares/template.go @@ -155,16 +155,18 @@ func cleanHeaders(headers map[string]any) map[string]any { } headers["Authorization"] = strings.SplitAfterN(authHeader, ` `, 1)[0] + " REDACTED" + + return headers } func TemplateBody(body map[string]any, headers map[string]any, VARIABLES map[string]any) (map[string]any, bool, error) { var modified bool + headers = cleanHeaders(headers) + // Normalize #Var and @Var to .header_key_Var and .body_key_Var normalizedBody, err := normalizeData("@", "body_key_", body) - log.Dev("Normalized:\n", jsonutils.ToJson(normalizedBody)) - if err != nil { return body, false, err } @@ -186,9 +188,6 @@ func TemplateBody(body map[string]any, headers map[string]any, VARIABLES map[str maps.Copy(variables, prefixedBody) maps.Copy(variables, prefixedHeaders) - log.Dev("Body:\n", jsonutils.ToJson(prefixedBody)) - log.Dev("Headers:\n", jsonutils.ToJson(prefixedHeaders)) - templatedData, err := templating.RenderJSON("body", normalizedBody, variables) if err != nil { From 5fba451f9dab2a36f82753f70e24b346b9505a6b Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sun, 21 Sep 2025 12:46:50 +0200 Subject: [PATCH 43/54] convert dashes to underscores --- internals/proxy/middlewares/template.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internals/proxy/middlewares/template.go b/internals/proxy/middlewares/template.go index 7b38b257..b12fcba3 100644 --- a/internals/proxy/middlewares/template.go +++ b/internals/proxy/middlewares/template.go @@ -117,6 +117,9 @@ func normalizeData(fromPrefix, toPrefix string, data map[string]any) (map[string return re.ReplaceAllStringFunc(match, func(varMatch string) string { varName := re.ReplaceAllString(varMatch, "$1") + // Convert dashes into underscores, because of template syntax + varName = strings.ReplaceAll(varName, "-", "_") + return "." + toPrefix + varName }) }) From 94a2d50a6dd157ecff1ed85dc11049d507d787f9 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sun, 21 Sep 2025 12:48:10 +0200 Subject: [PATCH 44/54] actually do not convert, let user handle --- internals/proxy/middlewares/template.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/internals/proxy/middlewares/template.go b/internals/proxy/middlewares/template.go index b12fcba3..7b38b257 100644 --- a/internals/proxy/middlewares/template.go +++ b/internals/proxy/middlewares/template.go @@ -117,9 +117,6 @@ func normalizeData(fromPrefix, toPrefix string, data map[string]any) (map[string return re.ReplaceAllStringFunc(match, func(varMatch string) string { varName := re.ReplaceAllString(varMatch, "$1") - // Convert dashes into underscores, because of template syntax - varName = strings.ReplaceAll(varName, "-", "_") - return "." + toPrefix + varName }) }) From 17093e92734bab428f47e3e543af470c3fc20716 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sun, 21 Sep 2025 12:52:25 +0200 Subject: [PATCH 45/54] convert - into _ in headers --- internals/proxy/middlewares/template.go | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/internals/proxy/middlewares/template.go b/internals/proxy/middlewares/template.go index 7b38b257..78f37e64 100644 --- a/internals/proxy/middlewares/template.go +++ b/internals/proxy/middlewares/template.go @@ -148,15 +148,23 @@ func prefixData(prefix string, data map[string]any) (map[string]any) { } func cleanHeaders(headers map[string]any) map[string]any { - authHeader, ok := headers["Authorization"].(string) + cleanedHeaders := map[string]any{} + + for key, value := range headers { + cleanedKey := strings.ReplaceAll(key, "-", "_") + + cleanedHeaders[cleanedKey] = value + } + + authHeader, ok := cleanedHeaders["Authorization"].(string) if !ok { authHeader = "REDACTED" } - headers["Authorization"] = strings.SplitAfterN(authHeader, ` `, 1)[0] + " REDACTED" + cleanedHeaders["Authorization"] = strings.SplitAfterN(authHeader, ` `, 1)[0] + " REDACTED" - return headers + return cleanedHeaders } func TemplateBody(body map[string]any, headers map[string]any, VARIABLES map[string]any) (map[string]any, bool, error) { @@ -171,7 +179,7 @@ func TemplateBody(body map[string]any, headers map[string]any, VARIABLES map[str return body, false, err } - normalizedHeaders, err := normalizeData("#", "header_key_", headers) + normalizedBody, err = normalizeData("#", "header_key_", normalizedBody) if err != nil { return body, false, err @@ -181,7 +189,7 @@ func TemplateBody(body map[string]any, headers map[string]any, VARIABLES map[str prefixedBody := prefixData("body_key_", normalizedBody) // Prefix Header Data with header_key_ - prefixedHeaders := prefixData("header_key_", normalizedHeaders) + prefixedHeaders := prefixData("header_key_", headers) variables := VARIABLES From d127ef4f9c7a8af84f64ffc1018f1a01a2cd659c Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sun, 21 Sep 2025 12:59:28 +0200 Subject: [PATCH 46/54] debug array conversion error --- utils/templating/templating.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/utils/templating/templating.go b/utils/templating/templating.go index 758199b5..3ab45b70 100644 --- a/utils/templating/templating.go +++ b/utils/templating/templating.go @@ -7,6 +7,7 @@ import ( "strings" "text/template" + "github.com/codeshelldev/secured-signal-api/utils/logger" "github.com/codeshelldev/secured-signal-api/utils/stringutils" ) @@ -50,7 +51,7 @@ func TransformTemplateKeys(tmplStr string, prefix string, transform func(varRege return tmplStr, err } - varRe, err := regexp.Compile(string(prefix) + `([a-zA-Z0-9_.]+)`) + varRe, err := regexp.Compile(string(prefix) + `("*[a-zA-Z0-9_.]+"*)`) if err != nil { return tmplStr, err @@ -164,6 +165,8 @@ func RenderDataKeyTemplateRecursive(key any, value any, variables map[string]any if err == nil { filtered := nonWhitespaceRe.ReplaceAllString(tmplStr, "") + logger.Dev(filtered) + if !templateRe.MatchString(filtered) { return stringutils.ToType(templatedValue), err } From 26d55d8e4130ca48d7c73a47c34fab9ee9783835 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sun, 21 Sep 2025 13:02:06 +0200 Subject: [PATCH 47/54] fixed regex order --- utils/templating/templating.go | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/utils/templating/templating.go b/utils/templating/templating.go index 3ab45b70..41e810d6 100644 --- a/utils/templating/templating.go +++ b/utils/templating/templating.go @@ -7,7 +7,6 @@ import ( "strings" "text/template" - "github.com/codeshelldev/secured-signal-api/utils/logger" "github.com/codeshelldev/secured-signal-api/utils/stringutils" ) @@ -163,11 +162,9 @@ func RenderDataKeyTemplateRecursive(key any, value any, variables map[string]any nonWhitespaceRe, err := regexp.Compile(`(\S+)`) if err == nil { - filtered := nonWhitespaceRe.ReplaceAllString(tmplStr, "") + filtered := templateRe.ReplaceAllString(tmplStr, "") - logger.Dev(filtered) - - if !templateRe.MatchString(filtered) { + if !nonWhitespaceRe.MatchString(filtered) { return stringutils.ToType(templatedValue), err } } From 905bb7361d7b566db6f6f01524475c3243d511c9 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sun, 21 Sep 2025 13:06:47 +0200 Subject: [PATCH 48/54] check headers --- internals/proxy/middlewares/message.go | 3 --- internals/proxy/middlewares/template.go | 4 ++++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/internals/proxy/middlewares/message.go b/internals/proxy/middlewares/message.go index 542ed132..80747089 100644 --- a/internals/proxy/middlewares/message.go +++ b/internals/proxy/middlewares/message.go @@ -6,7 +6,6 @@ import ( "net/http" "strconv" - "github.com/codeshelldev/secured-signal-api/utils/jsonutils" log "github.com/codeshelldev/secured-signal-api/utils/logger" request "github.com/codeshelldev/secured-signal-api/utils/request" ) @@ -91,8 +90,6 @@ func TemplateMessage(template string, bodyData map[string]any, headerData map[st data, _, err := TemplateBody(bodyData, headerData, variables) - log.Dev("msg:\n", jsonutils.ToJson(data)) - if err != nil || data == nil { return bodyData, err } diff --git a/internals/proxy/middlewares/template.go b/internals/proxy/middlewares/template.go index 78f37e64..47dc2175 100644 --- a/internals/proxy/middlewares/template.go +++ b/internals/proxy/middlewares/template.go @@ -170,8 +170,12 @@ func cleanHeaders(headers map[string]any) map[string]any { func TemplateBody(body map[string]any, headers map[string]any, VARIABLES map[string]any) (map[string]any, bool, error) { var modified bool + log.Dev("B-Headers:\n", jsonutils.ToJson(headers)) + headers = cleanHeaders(headers) + log.Dev("A-Headers:\n", jsonutils.ToJson(headers)) + // Normalize #Var and @Var to .header_key_Var and .body_key_Var normalizedBody, err := normalizeData("@", "body_key_", body) From 0758f88731565445e432e59e2ec2d5185db6310a Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sun, 21 Sep 2025 13:10:48 +0200 Subject: [PATCH 49/54] removed due to expected behaviour --- internals/proxy/middlewares/template.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/internals/proxy/middlewares/template.go b/internals/proxy/middlewares/template.go index 47dc2175..78f37e64 100644 --- a/internals/proxy/middlewares/template.go +++ b/internals/proxy/middlewares/template.go @@ -170,12 +170,8 @@ func cleanHeaders(headers map[string]any) map[string]any { func TemplateBody(body map[string]any, headers map[string]any, VARIABLES map[string]any) (map[string]any, bool, error) { var modified bool - log.Dev("B-Headers:\n", jsonutils.ToJson(headers)) - headers = cleanHeaders(headers) - log.Dev("A-Headers:\n", jsonutils.ToJson(headers)) - // Normalize #Var and @Var to .header_key_Var and .body_key_Var normalizedBody, err := normalizeData("@", "body_key_", body) From 268fd8bff42c4b66916ef6c8e391b76053404910 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sun, 21 Sep 2025 13:17:58 +0200 Subject: [PATCH 50/54] fix auth header appearing as array --- internals/proxy/middlewares/template.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internals/proxy/middlewares/template.go b/internals/proxy/middlewares/template.go index 78f37e64..8f7e6eb6 100644 --- a/internals/proxy/middlewares/template.go +++ b/internals/proxy/middlewares/template.go @@ -156,13 +156,13 @@ func cleanHeaders(headers map[string]any) map[string]any { cleanedHeaders[cleanedKey] = value } - authHeader, ok := cleanedHeaders["Authorization"].(string) + authHeader, ok := cleanedHeaders["Authorization"].([]string) if !ok { - authHeader = "REDACTED" + authHeader = []string{"UNKNOWN REDACTED"} } - cleanedHeaders["Authorization"] = strings.SplitAfterN(authHeader, ` `, 1)[0] + " REDACTED" + cleanedHeaders["Authorization"] = strings.SplitAfterN(authHeader[0], ` `, 1)[0] + " REDACTED" return cleanedHeaders } From a68a26eca51e3b9aca67bd0d7b4e5bc70bb2a44a Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sun, 21 Sep 2025 13:23:13 +0200 Subject: [PATCH 51/54] fix header --- internals/proxy/middlewares/template.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internals/proxy/middlewares/template.go b/internals/proxy/middlewares/template.go index 8f7e6eb6..aae554fe 100644 --- a/internals/proxy/middlewares/template.go +++ b/internals/proxy/middlewares/template.go @@ -162,7 +162,7 @@ func cleanHeaders(headers map[string]any) map[string]any { authHeader = []string{"UNKNOWN REDACTED"} } - cleanedHeaders["Authorization"] = strings.SplitAfterN(authHeader[0], ` `, 1)[0] + " REDACTED" + cleanedHeaders["Authorization"] = strings.Split(authHeader[0], ` `)[0] + "REDACTED" return cleanedHeaders } From 2e056d6a3588ed130a9d940b103d49d3b048c96a Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sun, 21 Sep 2025 13:50:12 +0200 Subject: [PATCH 52/54] add space between auth header --- internals/proxy/middlewares/template.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internals/proxy/middlewares/template.go b/internals/proxy/middlewares/template.go index aae554fe..ca096570 100644 --- a/internals/proxy/middlewares/template.go +++ b/internals/proxy/middlewares/template.go @@ -162,7 +162,7 @@ func cleanHeaders(headers map[string]any) map[string]any { authHeader = []string{"UNKNOWN REDACTED"} } - cleanedHeaders["Authorization"] = strings.Split(authHeader[0], ` `)[0] + "REDACTED" + cleanedHeaders["Authorization"] = strings.Split(authHeader[0], ` `)[0] + " REDACTED" return cleanedHeaders } From 9ff0b2b90a10c14367e4d387bf92575d6c804e65 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sun, 21 Sep 2025 13:57:48 +0200 Subject: [PATCH 53/54] update README --- .github/templates/README.template.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/.github/templates/README.template.md b/.github/templates/README.template.md index 41639da9..98a4bfb8 100644 --- a/.github/templates/README.template.md +++ b/.github/templates/README.template.md @@ -123,7 +123,11 @@ curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer API_T If you are not comfortable / don't want to hardcode your Number for example and/or Recipients in you, may use **Placeholders** in your Request. -You can use [**Variable**](#variables) `{{.NUMBER}}` Placeholders and **Body** Placeholders `{{@data.key}}`. +| Type | Example | Note | +| :--------------------- | :------------------ | :--------------- | +| Body | `{{@data.key}}` | | +| Header | `{{#Content_Type}}` | `-` becomes `_` | +| [Variable](#variables) | `{{.VAR}}` | always uppercase | | Type | Example | | :---- | :--------------------------------------------------------------- | @@ -235,33 +239,30 @@ This makes advanced [Message Templates](#message-templates) like this one possib ```yaml settings: messageTemplate: | - {{- /* Variable declaration */ -}} {{- $greeting := "Hello" -}} - {{- /* Simple variable output */ -}} {{ $greeting }}, {{ @name }}! - {{- /* If-else conditional */}} {{ if @age -}} You are {{ @age }} years old. {{- else -}} Age unknown. {{- end }} - {{- /* Range over slice */}} Your friends: {{- range @friends }} - {{ . }} {{- else }} You have no friends. {{- end }} - {{- /* Range over map */}} Profile details: {{- range $key, $value := @profile }} - {{ $key }}: {{ $value }} {{- end }} - {{- /* Nested templates */ -}} {{ define "footer" -}} This is the footer for {{ @name }}. {{- end }} {{ template "footer" . -}} + ------------------------------------ + Content-Type: {{ #Content_Type }} + Redacted Auth Header: {{ #Authorization }} ``` ### API Token(s) @@ -346,7 +347,7 @@ settings: ``` Message Templates support [Standard Golang Templating](#templating). -Use `@data.key` to reference Body Keys and `.KEY` for Variables. +Use `@data.key` to reference Body Keys, `#Content_Type` for Headers and `.KEY` for Variables. ### Data Aliases From 8814a9e0196f6a215ef1fc5fd7d8b2b6bce3d440 Mon Sep 17 00:00:00 2001 From: CodeShell <122738806+CodeShellDev@users.noreply.github.com> Date: Sun, 21 Sep 2025 13:59:11 +0200 Subject: [PATCH 54/54] add highlighting to readme --- .github/templates/README.template.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/templates/README.template.md b/.github/templates/README.template.md index 98a4bfb8..2aca1565 100644 --- a/.github/templates/README.template.md +++ b/.github/templates/README.template.md @@ -123,12 +123,16 @@ curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer API_T If you are not comfortable / don't want to hardcode your Number for example and/or Recipients in you, may use **Placeholders** in your Request. +**How to use:** + | Type | Example | Note | | :--------------------- | :------------------ | :--------------- | | Body | `{{@data.key}}` | | | Header | `{{#Content_Type}}` | `-` becomes `_` | | [Variable](#variables) | `{{.VAR}}` | always uppercase | +**Where to use:** + | Type | Example | | :---- | :--------------------------------------------------------------- | | Body | `{"number": "{{ .NUMBER }}", "recipients": "{{ .RECIPIENTS }}"}` |