From be8014831034b3e617b8f55e9ae94ac3091db760 Mon Sep 17 00:00:00 2001 From: Simon Loir Date: Tue, 21 Oct 2025 21:29:05 +0200 Subject: [PATCH 1/4] fix(templates): add trim on payload in value processor --- packages/server/src/templates/processors.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/server/src/templates/processors.ts b/packages/server/src/templates/processors.ts index 5d9270aa1..665b7706a 100644 --- a/packages/server/src/templates/processors.ts +++ b/packages/server/src/templates/processors.ts @@ -141,8 +141,8 @@ export function processValue( } if ( typeof payload === "string" && - payload.startsWith("{") && - payload.endsWith("}") + payload.trim().startsWith("{") && + payload.trim().endsWith("}") ) { try { payload = JSON.parse(payload); From 036eaa3c2d4946a7772bde4c1318b2ee0616a764 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Tue, 21 Oct 2025 19:34:37 +0000 Subject: [PATCH 2/4] [autofix.ci] apply automated fixes --- .../components/dashboard/impersonation/impersonation-bar.tsx | 2 +- apps/dokploy/components/layouts/user-nav.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/dokploy/components/dashboard/impersonation/impersonation-bar.tsx b/apps/dokploy/components/dashboard/impersonation/impersonation-bar.tsx index a5aae598c..b96b7c866 100644 --- a/apps/dokploy/components/dashboard/impersonation/impersonation-bar.tsx +++ b/apps/dokploy/components/dashboard/impersonation/impersonation-bar.tsx @@ -281,7 +281,7 @@ export const ImpersonationBar = () => {
diff --git a/apps/dokploy/components/layouts/user-nav.tsx b/apps/dokploy/components/layouts/user-nav.tsx index ca5854196..337e8f483 100644 --- a/apps/dokploy/components/layouts/user-nav.tsx +++ b/apps/dokploy/components/layouts/user-nav.tsx @@ -44,7 +44,7 @@ export const UserNav = () => { > From 7bddc6f46b063b41b8790c4254ea2400bb4fe24d Mon Sep 17 00:00:00 2001 From: Simon Loir Date: Wed, 22 Oct 2025 14:53:28 +0200 Subject: [PATCH 3/4] fix(templates): use trimStart and trimEnd instead of generic trim --- packages/server/src/templates/processors.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/server/src/templates/processors.ts b/packages/server/src/templates/processors.ts index 665b7706a..9e73fb1f4 100644 --- a/packages/server/src/templates/processors.ts +++ b/packages/server/src/templates/processors.ts @@ -141,8 +141,8 @@ export function processValue( } if ( typeof payload === "string" && - payload.trim().startsWith("{") && - payload.trim().endsWith("}") + payload.trimStart().startsWith("{") && + payload.trimEnd().endsWith("}") ) { try { payload = JSON.parse(payload); From ba7a325e8f7ad57d3efdce725d995de896d5fc1b Mon Sep 17 00:00:00 2001 From: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com> Date: Fri, 24 Oct 2025 23:25:55 -0600 Subject: [PATCH 4/4] test(helpers): add tests for JWT payload handling with newlines and whitespace --- .../templates/helpers.template.test.ts | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/apps/dokploy/__test__/templates/helpers.template.test.ts b/apps/dokploy/__test__/templates/helpers.template.test.ts index 1144b65fe..3ae92ae20 100644 --- a/apps/dokploy/__test__/templates/helpers.template.test.ts +++ b/apps/dokploy/__test__/templates/helpers.template.test.ts @@ -228,5 +228,58 @@ describe("helpers functions", () => { "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3MzU2ODk2MDAsImV4cCI6MTczNTY5MzIwMCwiaXNzIjoidGVzdC1pc3N1ZXIiLCJjdXN0b21wcm9wIjoiY3VzdG9tdmFsdWUifQ.m42U7PZSUSCf7gBOJrxJir0rQmyPq4rA59Dydr_QahI", ); }); + + it("should handle JWT payload with newlines and whitespace by trimming them", () => { + const iat = Math.floor(new Date("2025-01-01T00:00:00Z").getTime() / 1000); + const expiry = iat + 3600; + const payloadWithNewlines = `{ + "role": "anon", + "iss": "supabase", + "exp": ${expiry} +} +`; + const jwt = processValue( + "${jwt:secret:payload}", + { + secret: "mysecret", + payload: payloadWithNewlines, + }, + mockSchema, + ); + expect(jwt).toMatch(jwtMatchExp); + const parts = jwt.split(".") as JWTParts; + jwtCheckHeader(parts[0]); + const decodedPayload = jwtBase64Decode(parts[1]); + expect(decodedPayload).toHaveProperty("role"); + expect(decodedPayload.role).toEqual("anon"); + expect(decodedPayload).toHaveProperty("iss"); + expect(decodedPayload.iss).toEqual("supabase"); + expect(decodedPayload).toHaveProperty("exp"); + expect(decodedPayload.exp).toEqual(expiry); + }); + + it("should handle JWT payload with leading and trailing whitespace", () => { + const iat = Math.floor(new Date("2025-01-01T00:00:00Z").getTime() / 1000); + const expiry = iat + 3600; + const payloadWithWhitespace = ` {"role": "service_role", "iss": "supabase", "exp": ${expiry}} `; + const jwt = processValue( + "${jwt:secret:payload}", + { + secret: "mysecret", + payload: payloadWithWhitespace, + }, + mockSchema, + ); + expect(jwt).toMatch(jwtMatchExp); + const parts = jwt.split(".") as JWTParts; + jwtCheckHeader(parts[0]); + const decodedPayload = jwtBase64Decode(parts[1]); + expect(decodedPayload).toHaveProperty("role"); + expect(decodedPayload.role).toEqual("service_role"); + expect(decodedPayload).toHaveProperty("iss"); + expect(decodedPayload.iss).toEqual("supabase"); + expect(decodedPayload).toHaveProperty("exp"); + expect(decodedPayload.exp).toEqual(expiry); + }); }); });