Browse Source

Merge pull request #1404 from wunter8/inline-template-newlines

allow newlines in in-line go templates
Philipp C. Heckel 6 months ago
parent
commit
d2b5917e2b
2 changed files with 64 additions and 3 deletions
  1. 9 3
      server/server.go
  2. 55 0
      server/server_test.go

+ 9 - 3
server/server.go

@@ -991,7 +991,14 @@ func (s *Server) parsePublishParams(r *http.Request, m *message) (cache bool, fi
 	} else if call != "" && !isBoolValue(call) && !phoneNumberRegex.MatchString(call) {
 		return false, false, "", "", "", false, errHTTPBadRequestPhoneNumberInvalid
 	}
-	messageStr := strings.ReplaceAll(readParam(r, "x-message", "message", "m"), "\\n", "\n")
+	template = templateMode(readParam(r, "x-template", "template", "tpl"))
+	var messageStr string
+	if template.Enabled() && template.Name() == "" {
+		// don't convert "\n" to literal newline for inline templates
+		messageStr = readParam(r, "x-message", "message", "m")
+	} else {
+		messageStr = strings.ReplaceAll(readParam(r, "x-message", "message", "m"), "\\n", "\n")
+	}
 	if messageStr != "" {
 		m.Message = messageStr
 	}
@@ -1033,7 +1040,6 @@ func (s *Server) parsePublishParams(r *http.Request, m *message) (cache bool, fi
 	if markdown || strings.ToLower(contentType) == "text/markdown" {
 		m.ContentType = "text/markdown"
 	}
-	template = templateMode(readParam(r, "x-template", "template", "tpl"))
 	unifiedpush = readBoolParam(r, false, "x-unifiedpush", "unifiedpush", "up") // see GET too!
 	contentEncoding := readParam(r, "content-encoding")
 	if unifiedpush || contentEncoding == "aes128gcm" {
@@ -1198,7 +1204,7 @@ func (s *Server) renderTemplate(tpl string, source string) (string, error) {
 	if err := t.Execute(limitWriter, data); err != nil {
 		return "", errHTTPBadRequestTemplateExecuteFailed.Wrap("%s", err.Error())
 	}
-	return strings.TrimSpace(buf.String()), nil
+	return strings.TrimSpace(strings.ReplaceAll(buf.String(), "\\n", "\n")), nil // replace any remaining "\n" (those outside of template curly braces) with newlines
 }
 
 func (s *Server) handleBodyAsAttachment(r *http.Request, v *visitor, m *message, body *util.PeekedReadCloser) error {

+ 55 - 0
server/server_test.go

@@ -3069,6 +3069,61 @@ func TestServer_MessageTemplate_UnsafeSprigFunctions(t *testing.T) {
 	require.Equal(t, 40043, toHTTPError(t, response.Body.String()).Code)
 }
 
+func TestServer_MessageTemplate_InlineNewlines(t *testing.T) {
+	t.Parallel()
+	s := newTestServer(t, newTestConfig(t))
+	response := request(t, s, "PUT", "/mytopic", `{}`, map[string]string{
+		"X-Message":  `{{"New\nlines"}}`,
+		"X-Title":    `{{"New\nlines"}}`,
+		"X-Template": "1",
+	})
+
+	require.Equal(t, 200, response.Code)
+	m := toMessage(t, response.Body.String())
+	require.Equal(t, `New
+lines`, m.Message)
+	require.Equal(t, `New
+lines`, m.Title)
+}
+
+func TestServer_MessageTemplate_InlineNewlinesOutsideOfTemplate(t *testing.T) {
+	t.Parallel()
+	s := newTestServer(t, newTestConfig(t))
+	response := request(t, s, "PUT", "/mytopic", `{"foo":"bar","food":"bag"}`, map[string]string{
+		"X-Message":  `{{.foo}}{{"\n"}}{{.food}}`,
+		"X-Title":    `{{.food}}{{"\n"}}{{.foo}}`,
+		"X-Template": "1",
+	})
+
+	require.Equal(t, 200, response.Code)
+	m := toMessage(t, response.Body.String())
+	require.Equal(t, `bar
+bag`, m.Message)
+	require.Equal(t, `bag
+bar`, m.Title)
+}
+
+func TestServer_MessageTemplate_TemplateFileNewlines(t *testing.T) {
+	t.Parallel()
+	c := newTestConfig(t)
+	c.TemplateDir = t.TempDir()
+	require.NoError(t, os.WriteFile(filepath.Join(c.TemplateDir, "newline.yml"), []byte(`
+title: |
+  {{.food}}{{"\n"}}{{.foo}}
+message: |
+  {{.foo}}{{"\n"}}{{.food}}
+`), 0644))
+	s := newTestServer(t, c)
+	response := request(t, s, "POST", "/mytopic?template=newline", `{"foo":"bar","food":"bag"}`, nil)
+	fmt.Println(response.Body.String())
+	require.Equal(t, 200, response.Code)
+	m := toMessage(t, response.Body.String())
+	require.Equal(t, `bar
+bag`, m.Message)
+	require.Equal(t, `bag
+bar`, m.Title)
+}
+
 var (
 	//go:embed testdata/webhook_github_comment_created.json
 	githubCommentCreatedJSON string