From 1cbe7afb87731d269fad738cb148b5358c21d023 Mon Sep 17 00:00:00 2001 From: Elio Bischof Date: Tue, 1 Jul 2025 15:38:06 +0200 Subject: [PATCH 1/6] fix: use custom req headers in all server requests --- apps/login/next-env-vars.d.ts | 2 +- apps/login/src/lib/self.ts | 2 +- apps/login/src/lib/server/password.ts | 2 +- apps/login/src/lib/service.ts | 4 ++-- apps/login/src/lib/zitadel.ts | 23 +++++++++++++++++++++++ 5 files changed, 28 insertions(+), 5 deletions(-) diff --git a/apps/login/next-env-vars.d.ts b/apps/login/next-env-vars.d.ts index 691bfa6f56..b7a525858c 100644 --- a/apps/login/next-env-vars.d.ts +++ b/apps/login/next-env-vars.d.ts @@ -28,6 +28,6 @@ declare namespace NodeJS { * Optional: custom request headers to be added to every request * Split by comma, key value pairs separated by colon */ - CUSTOM_REQUEST_HEADERS: string; + CUSTOM_REQUEST_HEADERS?: string; } } diff --git a/apps/login/src/lib/self.ts b/apps/login/src/lib/self.ts index 7375f4f114..8d6f9aac55 100644 --- a/apps/login/src/lib/self.ts +++ b/apps/login/src/lib/self.ts @@ -1,6 +1,6 @@ "use server"; -import { createServerTransport } from "@zitadel/client/node"; +import { createServerTransport } from "./zitadel"; import { createUserServiceClient } from "@zitadel/client/v2"; import { headers } from "next/headers"; import { getSessionCookieById } from "./cookies"; diff --git a/apps/login/src/lib/server/password.ts b/apps/login/src/lib/server/password.ts index 3786145157..0ff31198fc 100644 --- a/apps/login/src/lib/server/password.ts +++ b/apps/login/src/lib/server/password.ts @@ -17,7 +17,7 @@ import { setUserPassword, } from "@/lib/zitadel"; import { ConnectError, create } from "@zitadel/client"; -import { createServerTransport } from "@zitadel/client/node"; +import { createServerTransport } from "../zitadel"; import { createUserServiceClient } from "@zitadel/client/v2"; import { Checks, diff --git a/apps/login/src/lib/service.ts b/apps/login/src/lib/service.ts index 0fbb083b05..bbf50c9fdc 100644 --- a/apps/login/src/lib/service.ts +++ b/apps/login/src/lib/service.ts @@ -1,5 +1,5 @@ import { createClientFor } from "@zitadel/client"; -import { createServerTransport } from "@zitadel/client/node"; +import { createServerTransport } from "./zitadel"; import { IdentityProviderService } from "@zitadel/proto/zitadel/idp/v2/idp_service_pb"; import { OIDCService } from "@zitadel/proto/zitadel/oidc/v2/oidc_service_pb"; import { OrganizationService } from "@zitadel/proto/zitadel/org/v2/org_service_pb"; @@ -50,7 +50,7 @@ export async function createServiceForHost( : [ (next) => { return (req) => { - process.env.CUSTOM_REQUEST_HEADERS.split(",").forEach( + process.env.CUSTOM_REQUEST_HEADERS!.split(",").forEach( (header) => { const kv = header.split(":"); req.header.set(kv[0], kv[1]); diff --git a/apps/login/src/lib/zitadel.ts b/apps/login/src/lib/zitadel.ts index 8a05701e97..5b7ff041f3 100644 --- a/apps/login/src/lib/zitadel.ts +++ b/apps/login/src/lib/zitadel.ts @@ -52,6 +52,8 @@ import { import { unstable_cacheLife as cacheLife } from "next/cache"; import { getUserAgent } from "./fingerprint"; import { createServiceForHost } from "./service"; +import { createServerTransport as libCreateServerTransport } from "@zitadel/client/node"; +import { Transport } from '@connectrpc/connect'; const useCache = process.env.DEBUG !== "true"; @@ -1497,3 +1499,24 @@ export async function listAuthenticationMethodTypes({ userId, }); } + +export function createServerTransport(token: string, baseUrl: string): Transport { + return libCreateServerTransport(token, { + baseUrl, + interceptors: !process.env.CUSTOM_REQUEST_HEADERS + ? undefined + : [ + (next) => { + return (req) => { + process.env.CUSTOM_REQUEST_HEADERS!.split(",").forEach( + (header) => { + const kv = header.split(":"); + req.header.set(kv[0], kv[1]); + }, + ); + return next(req); + }; + }, + ], + }); +} From 816795f94919f1d91cbc6304f1b617b807b48c01 Mon Sep 17 00:00:00 2001 From: Elio Bischof Date: Tue, 1 Jul 2025 15:43:33 +0200 Subject: [PATCH 2/6] clean --- apps/login/src/lib/self.ts | 8 +------- apps/login/src/lib/server/password.ts | 4 +--- apps/login/src/lib/service.ts | 19 +------------------ 3 files changed, 3 insertions(+), 28 deletions(-) diff --git a/apps/login/src/lib/self.ts b/apps/login/src/lib/self.ts index 8d6f9aac55..8be9a27368 100644 --- a/apps/login/src/lib/self.ts +++ b/apps/login/src/lib/self.ts @@ -7,14 +7,8 @@ import { getSessionCookieById } from "./cookies"; import { getServiceUrlFromHeaders } from "./service-url"; import { getSession } from "./zitadel"; -const transport = async (serviceUrl: string, token: string) => { - return createServerTransport(token, { - baseUrl: serviceUrl, - }); -}; - const myUserService = async (serviceUrl: string, sessionToken: string) => { - const transportPromise = await transport(serviceUrl, sessionToken); + const transportPromise = await createServerTransport(sessionToken, serviceUrl); return createUserServiceClient(transportPromise); }; diff --git a/apps/login/src/lib/server/password.ts b/apps/login/src/lib/server/password.ts index 0ff31198fc..700c2f7b92 100644 --- a/apps/login/src/lib/server/password.ts +++ b/apps/login/src/lib/server/password.ts @@ -428,9 +428,7 @@ export async function checkSessionAndSetPassword({ }); } else { const transport = async (serviceUrl: string, token: string) => { - return createServerTransport(token, { - baseUrl: serviceUrl, - }); + return createServerTransport(token, serviceUrl); }; const myUserService = async (serviceUrl: string, sessionToken: string) => { diff --git a/apps/login/src/lib/service.ts b/apps/login/src/lib/service.ts index bbf50c9fdc..76fc178f67 100644 --- a/apps/login/src/lib/service.ts +++ b/apps/login/src/lib/service.ts @@ -43,24 +43,7 @@ export async function createServiceForHost( throw new Error("No token found"); } - const transport = createServerTransport(token, { - baseUrl: serviceUrl, - interceptors: !process.env.CUSTOM_REQUEST_HEADERS - ? undefined - : [ - (next) => { - return (req) => { - process.env.CUSTOM_REQUEST_HEADERS!.split(",").forEach( - (header) => { - const kv = header.split(":"); - req.header.set(kv[0], kv[1]); - }, - ); - return next(req); - }; - }, - ], - }); + const transport = createServerTransport(token, serviceUrl); return createClientFor(service)(transport); } From f0670d86321ef0c2fea4eb098d4b69e4d6586357 Mon Sep 17 00:00:00 2001 From: Elio Bischof Date: Tue, 1 Jul 2025 15:45:06 +0200 Subject: [PATCH 3/6] fmt --- apps/login/src/lib/self.ts | 8 +++++--- apps/login/src/lib/server/password.ts | 2 +- apps/login/src/lib/service.ts | 2 +- apps/login/src/lib/zitadel.ts | 25 ++++++++++++++----------- 4 files changed, 21 insertions(+), 16 deletions(-) diff --git a/apps/login/src/lib/self.ts b/apps/login/src/lib/self.ts index 8be9a27368..df8508c29e 100644 --- a/apps/login/src/lib/self.ts +++ b/apps/login/src/lib/self.ts @@ -1,14 +1,16 @@ "use server"; -import { createServerTransport } from "./zitadel"; import { createUserServiceClient } from "@zitadel/client/v2"; import { headers } from "next/headers"; import { getSessionCookieById } from "./cookies"; import { getServiceUrlFromHeaders } from "./service-url"; -import { getSession } from "./zitadel"; +import { createServerTransport, getSession } from "./zitadel"; const myUserService = async (serviceUrl: string, sessionToken: string) => { - const transportPromise = await createServerTransport(sessionToken, serviceUrl); + const transportPromise = await createServerTransport( + sessionToken, + serviceUrl, + ); return createUserServiceClient(transportPromise); }; diff --git a/apps/login/src/lib/server/password.ts b/apps/login/src/lib/server/password.ts index 700c2f7b92..5c6fb03aa5 100644 --- a/apps/login/src/lib/server/password.ts +++ b/apps/login/src/lib/server/password.ts @@ -17,7 +17,6 @@ import { setUserPassword, } from "@/lib/zitadel"; import { ConnectError, create } from "@zitadel/client"; -import { createServerTransport } from "../zitadel"; import { createUserServiceClient } from "@zitadel/client/v2"; import { Checks, @@ -39,6 +38,7 @@ import { checkPasswordChangeRequired, checkUserVerification, } from "../verify-helper"; +import { createServerTransport } from "../zitadel"; type ResetPasswordCommand = { loginName: string; diff --git a/apps/login/src/lib/service.ts b/apps/login/src/lib/service.ts index 76fc178f67..f7e81cc9d6 100644 --- a/apps/login/src/lib/service.ts +++ b/apps/login/src/lib/service.ts @@ -1,5 +1,4 @@ import { createClientFor } from "@zitadel/client"; -import { createServerTransport } from "./zitadel"; import { IdentityProviderService } from "@zitadel/proto/zitadel/idp/v2/idp_service_pb"; import { OIDCService } from "@zitadel/proto/zitadel/oidc/v2/oidc_service_pb"; import { OrganizationService } from "@zitadel/proto/zitadel/org/v2/org_service_pb"; @@ -8,6 +7,7 @@ import { SessionService } from "@zitadel/proto/zitadel/session/v2/session_servic import { SettingsService } from "@zitadel/proto/zitadel/settings/v2/settings_service_pb"; import { UserService } from "@zitadel/proto/zitadel/user/v2/user_service_pb"; import { systemAPIToken } from "./api"; +import { createServerTransport } from "./zitadel"; type ServiceClass = | typeof IdentityProviderService diff --git a/apps/login/src/lib/zitadel.ts b/apps/login/src/lib/zitadel.ts index 5b7ff041f3..549bf65577 100644 --- a/apps/login/src/lib/zitadel.ts +++ b/apps/login/src/lib/zitadel.ts @@ -1,4 +1,6 @@ +import { Transport } from "@connectrpc/connect"; import { Client, create, Duration } from "@zitadel/client"; +import { createServerTransport as libCreateServerTransport } from "@zitadel/client/node"; import { makeReqCtx } from "@zitadel/client/v2"; import { IdentityProviderService } from "@zitadel/proto/zitadel/idp/v2/idp_service_pb"; import { @@ -52,8 +54,6 @@ import { import { unstable_cacheLife as cacheLife } from "next/cache"; import { getUserAgent } from "./fingerprint"; import { createServiceForHost } from "./service"; -import { createServerTransport as libCreateServerTransport } from "@zitadel/client/node"; -import { Transport } from '@connectrpc/connect'; const useCache = process.env.DEBUG !== "true"; @@ -1500,20 +1500,23 @@ export async function listAuthenticationMethodTypes({ }); } -export function createServerTransport(token: string, baseUrl: string): Transport { +export function createServerTransport( + token: string, + baseUrl: string, +): Transport { return libCreateServerTransport(token, { baseUrl, interceptors: !process.env.CUSTOM_REQUEST_HEADERS - ? undefined - : [ + ? undefined + : [ (next) => { return (req) => { - process.env.CUSTOM_REQUEST_HEADERS!.split(",").forEach( - (header) => { - const kv = header.split(":"); - req.header.set(kv[0], kv[1]); - }, - ); + process.env + .CUSTOM_REQUEST_HEADERS!.split(",") + .forEach((header) => { + const kv = header.split(":"); + req.header.set(kv[0], kv[1]); + }); return next(req); }; }, From ab203a0bae405e58c27b44579807792e3bd886dd Mon Sep 17 00:00:00 2001 From: Elio Bischof Date: Tue, 1 Jul 2025 15:47:58 +0200 Subject: [PATCH 4/6] robust --- apps/login/src/lib/zitadel.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/login/src/lib/zitadel.ts b/apps/login/src/lib/zitadel.ts index 549bf65577..f1ccb385d5 100644 --- a/apps/login/src/lib/zitadel.ts +++ b/apps/login/src/lib/zitadel.ts @@ -1515,7 +1515,11 @@ export function createServerTransport( .CUSTOM_REQUEST_HEADERS!.split(",") .forEach((header) => { const kv = header.split(":"); - req.header.set(kv[0], kv[1]); + if (kv.length === 2) { + req.header.set(kv[0].trim(), kv[1].trim()); + } else { + console.warn(`Skipping malformed header: ${header}`); + } }); return next(req); }; From 28d13262fbe9de310e2833b45ba7b3b6c5c01007 Mon Sep 17 00:00:00 2001 From: Elio Bischof Date: Tue, 1 Jul 2025 16:03:10 +0200 Subject: [PATCH 5/6] import --- apps/login/src/lib/zitadel.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/login/src/lib/zitadel.ts b/apps/login/src/lib/zitadel.ts index f1ccb385d5..53162abce8 100644 --- a/apps/login/src/lib/zitadel.ts +++ b/apps/login/src/lib/zitadel.ts @@ -1,4 +1,3 @@ -import { Transport } from "@connectrpc/connect"; import { Client, create, Duration } from "@zitadel/client"; import { createServerTransport as libCreateServerTransport } from "@zitadel/client/node"; import { makeReqCtx } from "@zitadel/client/v2"; @@ -1503,7 +1502,7 @@ export async function listAuthenticationMethodTypes({ export function createServerTransport( token: string, baseUrl: string, -): Transport { +) { return libCreateServerTransport(token, { baseUrl, interceptors: !process.env.CUSTOM_REQUEST_HEADERS From a634c60232a295ccb5323be0a12e9702000fcfba Mon Sep 17 00:00:00 2001 From: Elio Bischof Date: Tue, 1 Jul 2025 16:04:24 +0200 Subject: [PATCH 6/6] lint --- apps/login/src/lib/zitadel.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/apps/login/src/lib/zitadel.ts b/apps/login/src/lib/zitadel.ts index 53162abce8..483d4e4ac9 100644 --- a/apps/login/src/lib/zitadel.ts +++ b/apps/login/src/lib/zitadel.ts @@ -1499,10 +1499,7 @@ export async function listAuthenticationMethodTypes({ }); } -export function createServerTransport( - token: string, - baseUrl: string, -) { +export function createServerTransport(token: string, baseUrl: string) { return libCreateServerTransport(token, { baseUrl, interceptors: !process.env.CUSTOM_REQUEST_HEADERS