From 41bafc0d41df046d5c023bbee6aa1979c6ac1a5c Mon Sep 17 00:00:00 2001 From: Max Peintner Date: Wed, 29 Jan 2025 15:47:31 +0100 Subject: [PATCH] zitadel.ts adaptations --- apps/login/next-env-vars.d.ts | 21 ++- apps/login/src/app/(login)/accounts/page.tsx | 2 +- .../app/(login)/authenticator/set/page.tsx | 2 +- .../(login)/idp/[provider]/failure/page.tsx | 2 +- .../(login)/idp/[provider]/success/page.tsx | 2 +- apps/login/src/app/(login)/idp/page.tsx | 2 +- apps/login/src/app/(login)/invite/page.tsx | 2 +- .../src/app/(login)/invite/success/page.tsx | 2 +- apps/login/src/app/(login)/loginname/page.tsx | 2 +- apps/login/src/app/(login)/mfa/page.tsx | 2 +- apps/login/src/app/(login)/mfa/set/page.tsx | 2 +- .../src/app/(login)/otp/[method]/page.tsx | 2 +- .../src/app/(login)/otp/[method]/set/page.tsx | 2 +- apps/login/src/app/(login)/passkey/page.tsx | 2 +- .../src/app/(login)/passkey/set/page.tsx | 2 +- .../src/app/(login)/password/change/page.tsx | 2 +- apps/login/src/app/(login)/password/page.tsx | 2 +- .../src/app/(login)/password/set/page.tsx | 2 +- apps/login/src/app/(login)/register/page.tsx | 2 +- .../app/(login)/register/password/page.tsx | 2 +- apps/login/src/app/(login)/signedin/page.tsx | 2 +- apps/login/src/app/(login)/u2f/page.tsx | 2 +- apps/login/src/app/(login)/u2f/set/page.tsx | 2 +- apps/login/src/app/(login)/verify/page.tsx | 2 +- apps/login/src/app/login/route.ts | 2 +- apps/login/src/lib/api.ts | 55 +++++- apps/login/src/lib/self.ts | 2 +- apps/login/src/lib/server/cookie.ts | 6 +- apps/login/src/lib/server/idp.ts | 4 +- apps/login/src/lib/server/invite.ts | 2 +- apps/login/src/lib/server/loginname.ts | 6 +- apps/login/src/lib/server/otp.ts | 2 +- apps/login/src/lib/server/passkeys.ts | 6 +- apps/login/src/lib/server/password.ts | 8 +- apps/login/src/lib/server/register.ts | 2 +- apps/login/src/lib/server/session.ts | 8 +- apps/login/src/lib/server/u2f.ts | 4 +- apps/login/src/lib/server/verify.ts | 8 +- apps/login/src/lib/service.ts | 19 +- apps/login/src/lib/zitadel.ts | 172 ++++++++++++++++-- apps/login/src/middleware.ts | 2 +- turbo.json | 9 +- 42 files changed, 290 insertions(+), 94 deletions(-) diff --git a/apps/login/next-env-vars.d.ts b/apps/login/next-env-vars.d.ts index be266fd5a04..61bf0c5b063 100644 --- a/apps/login/next-env-vars.d.ts +++ b/apps/login/next-env-vars.d.ts @@ -3,17 +3,32 @@ declare namespace NodeJS { /** * Multitenancy: The system api url */ - AUDIENCE: string; + QA_AUDIENCE: string; /** * Multitenancy: The service user id */ - SYSTEM_USER_ID: string; + QA_SYSTEM_USER_ID: string; /** * Multitenancy: The service user private key */ - SYSTEM_USER_PRIVATE_KEY: string; + QA_SYSTEM_USER_PRIVATE_KEY: string; + + /** + * Multitenancy: The system api url for prod environment + */ + PROD_AUDIENCE: string; + + /** + * Multitenancy: The service user id for prod environment + */ + PROD_SYSTEM_USER_ID: string; + + /** + * Multitenancy: The service user private key for prod environment + */ + PROD_SYSTEM_USER_PRIVATE_KEY: string; /** * Self hosting: The instance url diff --git a/apps/login/src/app/(login)/accounts/page.tsx b/apps/login/src/app/(login)/accounts/page.tsx index e9518dbfb5b..998cb7f641c 100644 --- a/apps/login/src/app/(login)/accounts/page.tsx +++ b/apps/login/src/app/(login)/accounts/page.tsx @@ -39,7 +39,7 @@ export default async function Page(props: { const organization = searchParams?.organization; const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); let defaultOrganization; if (!organization) { diff --git a/apps/login/src/app/(login)/authenticator/set/page.tsx b/apps/login/src/app/(login)/authenticator/set/page.tsx index 28bc0b70774..dddde2628af 100644 --- a/apps/login/src/app/(login)/authenticator/set/page.tsx +++ b/apps/login/src/app/(login)/authenticator/set/page.tsx @@ -30,7 +30,7 @@ export default async function Page(props: { const { loginName, authRequestId, organization, sessionId } = searchParams; const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const sessionWithData = sessionId ? await loadSessionById(serviceUrl, sessionId, organization) diff --git a/apps/login/src/app/(login)/idp/[provider]/failure/page.tsx b/apps/login/src/app/(login)/idp/[provider]/failure/page.tsx index bb1272f332b..6a62e2515ea 100644 --- a/apps/login/src/app/(login)/idp/[provider]/failure/page.tsx +++ b/apps/login/src/app/(login)/idp/[provider]/failure/page.tsx @@ -25,7 +25,7 @@ export default async function Page(props: { const { organization } = searchParams; const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const branding = await getBrandingSettings({ serviceUrl, organization }); diff --git a/apps/login/src/app/(login)/idp/[provider]/success/page.tsx b/apps/login/src/app/(login)/idp/[provider]/success/page.tsx index 0d26606a3e0..8cdb6cec836 100644 --- a/apps/login/src/app/(login)/idp/[provider]/success/page.tsx +++ b/apps/login/src/app/(login)/idp/[provider]/success/page.tsx @@ -40,7 +40,7 @@ export default async function Page(props: { const { provider } = params; const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const branding = await getBrandingSettings({ serviceUrl, organization }); diff --git a/apps/login/src/app/(login)/idp/page.tsx b/apps/login/src/app/(login)/idp/page.tsx index bda16051af9..53a77910d35 100644 --- a/apps/login/src/app/(login)/idp/page.tsx +++ b/apps/login/src/app/(login)/idp/page.tsx @@ -16,7 +16,7 @@ export default async function Page(props: { const organization = searchParams?.organization; const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const identityProviders = await getActiveIdentityProviders({ serviceUrl, diff --git a/apps/login/src/app/(login)/invite/page.tsx b/apps/login/src/app/(login)/invite/page.tsx index cc06281eecb..1b1ac334702 100644 --- a/apps/login/src/app/(login)/invite/page.tsx +++ b/apps/login/src/app/(login)/invite/page.tsx @@ -21,7 +21,7 @@ export default async function Page(props: { let { firstname, lastname, email, organization } = searchParams; const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); if (!organization) { const org = await getDefaultOrg({ serviceUrl }); diff --git a/apps/login/src/app/(login)/invite/success/page.tsx b/apps/login/src/app/(login)/invite/success/page.tsx index b8692d5c5b3..e21b8ac4dac 100644 --- a/apps/login/src/app/(login)/invite/success/page.tsx +++ b/apps/login/src/app/(login)/invite/success/page.tsx @@ -19,7 +19,7 @@ export default async function Page(props: { let { userId, organization } = searchParams; const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); if (!organization) { const org = await getDefaultOrg({ serviceUrl }); diff --git a/apps/login/src/app/(login)/loginname/page.tsx b/apps/login/src/app/(login)/loginname/page.tsx index 6e1a97b2b6f..65dc02d0463 100644 --- a/apps/login/src/app/(login)/loginname/page.tsx +++ b/apps/login/src/app/(login)/loginname/page.tsx @@ -26,7 +26,7 @@ export default async function Page(props: { const submit: boolean = searchParams?.submit === "true"; const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); let defaultOrganization; if (!organization) { diff --git a/apps/login/src/app/(login)/mfa/page.tsx b/apps/login/src/app/(login)/mfa/page.tsx index ce658129c33..94f93ac1adb 100644 --- a/apps/login/src/app/(login)/mfa/page.tsx +++ b/apps/login/src/app/(login)/mfa/page.tsx @@ -25,7 +25,7 @@ export default async function Page(props: { const { loginName, authRequestId, organization, sessionId } = searchParams; const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const sessionFactors = sessionId ? await loadSessionById(serviceUrl, sessionId, organization) diff --git a/apps/login/src/app/(login)/mfa/set/page.tsx b/apps/login/src/app/(login)/mfa/set/page.tsx index a2a3c5d933f..a5c3eb3fc8f 100644 --- a/apps/login/src/app/(login)/mfa/set/page.tsx +++ b/apps/login/src/app/(login)/mfa/set/page.tsx @@ -52,7 +52,7 @@ export default async function Page(props: { } = searchParams; const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const sessionWithData = sessionId ? await loadSessionById(serviceUrl, sessionId, organization) diff --git a/apps/login/src/app/(login)/otp/[method]/page.tsx b/apps/login/src/app/(login)/otp/[method]/page.tsx index 4d29777f6be..77c465826ca 100644 --- a/apps/login/src/app/(login)/otp/[method]/page.tsx +++ b/apps/login/src/app/(login)/otp/[method]/page.tsx @@ -24,7 +24,7 @@ export default async function Page(props: { const tError = await getTranslations({ locale, namespace: "error" }); const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const host = _headers.get("host"); if (!host || typeof host !== "string") { diff --git a/apps/login/src/app/(login)/otp/[method]/set/page.tsx b/apps/login/src/app/(login)/otp/[method]/set/page.tsx index 1e80d847a26..ebb65fe699b 100644 --- a/apps/login/src/app/(login)/otp/[method]/set/page.tsx +++ b/apps/login/src/app/(login)/otp/[method]/set/page.tsx @@ -34,7 +34,7 @@ export default async function Page(props: { const { method } = params; const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const branding = await getBrandingSettings({ serviceUrl, organization }); const loginSettings = await getLoginSettings({ serviceUrl, organization }); diff --git a/apps/login/src/app/(login)/passkey/page.tsx b/apps/login/src/app/(login)/passkey/page.tsx index 2ec8b0d6270..41610d89301 100644 --- a/apps/login/src/app/(login)/passkey/page.tsx +++ b/apps/login/src/app/(login)/passkey/page.tsx @@ -25,7 +25,7 @@ export default async function Page(props: { searchParams; const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const sessionFactors = sessionId ? await loadSessionById(serviceUrl, sessionId, organization) diff --git a/apps/login/src/app/(login)/passkey/set/page.tsx b/apps/login/src/app/(login)/passkey/set/page.tsx index 1035f4b55eb..6b99076b50a 100644 --- a/apps/login/src/app/(login)/passkey/set/page.tsx +++ b/apps/login/src/app/(login)/passkey/set/page.tsx @@ -20,7 +20,7 @@ export default async function Page(props: { searchParams; const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const session = await loadMostRecentSession({ serviceUrl, diff --git a/apps/login/src/app/(login)/password/change/page.tsx b/apps/login/src/app/(login)/password/change/page.tsx index 4ea08083951..ef6390d88cd 100644 --- a/apps/login/src/app/(login)/password/change/page.tsx +++ b/apps/login/src/app/(login)/password/change/page.tsx @@ -16,7 +16,7 @@ export default async function Page(props: { searchParams: Promise>; }) { const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const searchParams = await props.searchParams; const locale = getLocale(); diff --git a/apps/login/src/app/(login)/password/page.tsx b/apps/login/src/app/(login)/password/page.tsx index e794f7bbbcc..dfb07c934de 100644 --- a/apps/login/src/app/(login)/password/page.tsx +++ b/apps/login/src/app/(login)/password/page.tsx @@ -25,7 +25,7 @@ export default async function Page(props: { let { loginName, organization, authRequestId, alt } = searchParams; const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); let defaultOrganization; if (!organization) { diff --git a/apps/login/src/app/(login)/password/set/page.tsx b/apps/login/src/app/(login)/password/set/page.tsx index 2f29a66630a..55d21658f40 100644 --- a/apps/login/src/app/(login)/password/set/page.tsx +++ b/apps/login/src/app/(login)/password/set/page.tsx @@ -27,7 +27,7 @@ export default async function Page(props: { searchParams; const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); // also allow no session to be found (ignoreUnkownUsername) let session: Session | undefined; diff --git a/apps/login/src/app/(login)/register/page.tsx b/apps/login/src/app/(login)/register/page.tsx index adb1f28310e..a218852ec7d 100644 --- a/apps/login/src/app/(login)/register/page.tsx +++ b/apps/login/src/app/(login)/register/page.tsx @@ -23,7 +23,7 @@ export default async function Page(props: { searchParams; const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); if (!organization) { const org: Organization | null = await getDefaultOrg({ serviceUrl }); diff --git a/apps/login/src/app/(login)/register/password/page.tsx b/apps/login/src/app/(login)/register/password/page.tsx index 2eac65536db..7ebe79e8699 100644 --- a/apps/login/src/app/(login)/register/password/page.tsx +++ b/apps/login/src/app/(login)/register/password/page.tsx @@ -23,7 +23,7 @@ export default async function Page(props: { searchParams; const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); if (!organization) { const org: Organization | null = await getDefaultOrg({ serviceUrl }); diff --git a/apps/login/src/app/(login)/signedin/page.tsx b/apps/login/src/app/(login)/signedin/page.tsx index f387925500a..6e5deda3452 100644 --- a/apps/login/src/app/(login)/signedin/page.tsx +++ b/apps/login/src/app/(login)/signedin/page.tsx @@ -61,7 +61,7 @@ export default async function Page(props: { searchParams: Promise }) { const t = await getTranslations({ locale, namespace: "signedin" }); const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const { loginName, authRequestId, organization } = searchParams; const sessionFactors = await loadSession( diff --git a/apps/login/src/app/(login)/u2f/page.tsx b/apps/login/src/app/(login)/u2f/page.tsx index c5db30a21c5..93632d2f28f 100644 --- a/apps/login/src/app/(login)/u2f/page.tsx +++ b/apps/login/src/app/(login)/u2f/page.tsx @@ -20,7 +20,7 @@ export default async function Page(props: { const { loginName, authRequestId, sessionId, organization } = searchParams; const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const host = _headers.get("host"); if (!host || typeof host !== "string") { diff --git a/apps/login/src/app/(login)/u2f/set/page.tsx b/apps/login/src/app/(login)/u2f/set/page.tsx index 79f5d3ab504..2d1e6b85071 100644 --- a/apps/login/src/app/(login)/u2f/set/page.tsx +++ b/apps/login/src/app/(login)/u2f/set/page.tsx @@ -19,7 +19,7 @@ export default async function Page(props: { const { loginName, organization, authRequestId, checkAfter } = searchParams; const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const sessionFactors = await loadMostRecentSession({ serviceUrl, diff --git a/apps/login/src/app/(login)/verify/page.tsx b/apps/login/src/app/(login)/verify/page.tsx index 833ed663df5..673d78af93e 100644 --- a/apps/login/src/app/(login)/verify/page.tsx +++ b/apps/login/src/app/(login)/verify/page.tsx @@ -26,7 +26,7 @@ export default async function Page(props: { searchParams: Promise }) { searchParams; const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const host = _headers.get("host"); if (!host || typeof host !== "string") { diff --git a/apps/login/src/app/login/route.ts b/apps/login/src/app/login/route.ts index f3663425701..04548c95a7b 100644 --- a/apps/login/src/app/login/route.ts +++ b/apps/login/src/app/login/route.ts @@ -199,7 +199,7 @@ export async function GET(request: NextRequest) { const sessionId = searchParams.get("sessionId"); const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); // TODO: find a better way to handle _rsc (react server components) requests and block them to avoid conflicts when creating oidc callback const _rsc = searchParams.get("_rsc"); diff --git a/apps/login/src/lib/api.ts b/apps/login/src/lib/api.ts index ba70a764f32..11acd701e05 100644 --- a/apps/login/src/lib/api.ts +++ b/apps/login/src/lib/api.ts @@ -1,17 +1,52 @@ import { newSystemToken } from "@zitadel/client/node"; -export async function systemAPIToken() { - const audience = process.env.AUDIENCE; - const userID = process.env.SYSTEM_USER_ID; - const key = process.env.SYSTEM_USER_PRIVATE_KEY; +export async function systemAPIToken({ + serviceRegion, +}: { + serviceRegion: string; +}) { + const QA = { + audience: process.env.QA_AUDIENCE, + userID: process.env.QA_SYSTEM_USER_ID, + token: Buffer.from( + process.env.QA_SYSTEM_USER_PRIVATE_KEY, + "base64", + ).toString("utf-8"), + }; - const decodedToken = Buffer.from(key, "base64").toString("utf-8"); + const PROD = { + audience: process.env.QA_AUDIENCE, + userID: process.env.QA_SYSTEM_USER_ID, + token: Buffer.from( + process.env.PROD_SYSTEM_USER_PRIVATE_KEY, + "base64", + ).toString("utf-8"), + }; - const token = newSystemToken({ - audience: audience, - subject: userID, - key: decodedToken, - }); + let token; + + switch (serviceRegion) { + case "eu1": + token = newSystemToken({ + audience: QA.audience, + subject: QA.userID, + key: QA.token, + }); + break; + case "us1": + token = newSystemToken({ + audience: PROD.audience, + subject: PROD.userID, + key: PROD.token, + }); + break; + default: + token = newSystemToken({ + audience: QA.audience, + subject: QA.userID, + key: QA.token, + }); + } return token; } diff --git a/apps/login/src/lib/self.ts b/apps/login/src/lib/self.ts index 0553aef21bf..3c7482f43e5 100644 --- a/apps/login/src/lib/self.ts +++ b/apps/login/src/lib/self.ts @@ -26,7 +26,7 @@ export async function setMyPassword({ password: string; }) { const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const sessionCookie = await getSessionCookieById({ sessionId }); diff --git a/apps/login/src/lib/server/cookie.ts b/apps/login/src/lib/server/cookie.ts index 9f20c1a00db..e199bfd896a 100644 --- a/apps/login/src/lib/server/cookie.ts +++ b/apps/login/src/lib/server/cookie.ts @@ -35,7 +35,7 @@ export async function createSessionAndUpdateCookie( lifetime?: Duration, ): Promise { const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const createdSession = await createSessionFromChecks({ serviceUrl, @@ -97,7 +97,7 @@ export async function createSessionForIdpAndUpdateCookie( lifetime?: Duration, ): Promise { const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const createdSession = await createSessionForUserIdAndIdpIntent({ serviceUrl, @@ -159,7 +159,7 @@ export async function setSessionAndUpdateCookie( lifetime?: Duration, ) { const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); return setSession({ serviceUrl, diff --git a/apps/login/src/lib/server/idp.ts b/apps/login/src/lib/server/idp.ts index 3e597c50415..daef0aaeb63 100644 --- a/apps/login/src/lib/server/idp.ts +++ b/apps/login/src/lib/server/idp.ts @@ -19,7 +19,7 @@ export type StartIDPFlowCommand = { export async function startIDPFlow(command: StartIDPFlowCommand) { const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const host = _headers.get("host"); if (!host) { @@ -60,7 +60,7 @@ export async function createNewSessionFromIdpIntent( command: CreateNewSessionCommand, ) { const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const host = _headers.get("host"); if (!host) { diff --git a/apps/login/src/lib/server/invite.ts b/apps/login/src/lib/server/invite.ts index 56986930f93..4e9c52ce9e3 100644 --- a/apps/login/src/lib/server/invite.ts +++ b/apps/login/src/lib/server/invite.ts @@ -22,7 +22,7 @@ export type RegisterUserResponse = { export async function inviteUser(command: InviteUserCommand) { const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const host = _headers.get("host"); if (!host) { diff --git a/apps/login/src/lib/server/loginname.ts b/apps/login/src/lib/server/loginname.ts index 13bf7f0ed06..e894dcdd3fe 100644 --- a/apps/login/src/lib/server/loginname.ts +++ b/apps/login/src/lib/server/loginname.ts @@ -34,7 +34,7 @@ const ORG_SUFFIX_REGEX = /(?<=@)(.+)/; export async function sendLoginname(command: SendLoginnameCommand) { const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const host = _headers.get("host"); if (!host) { @@ -80,7 +80,7 @@ export async function sendLoginname(command: SendLoginnameCommand) { if (identityProviders.length === 1) { const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const host = _headers.get("host"); if (!host) { @@ -129,7 +129,7 @@ export async function sendLoginname(command: SendLoginnameCommand) { if (identityProviders.length === 1) { const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const host = _headers.get("host"); if (!host) { diff --git a/apps/login/src/lib/server/otp.ts b/apps/login/src/lib/server/otp.ts index 72c663e9fe2..868fee03a50 100644 --- a/apps/login/src/lib/server/otp.ts +++ b/apps/login/src/lib/server/otp.ts @@ -27,7 +27,7 @@ export type SetOTPCommand = { export async function setOTP(command: SetOTPCommand) { const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const recentSession = command.sessionId ? await getSessionCookieById({ sessionId: command.sessionId }).catch( diff --git a/apps/login/src/lib/server/passkeys.ts b/apps/login/src/lib/server/passkeys.ts index 97255ead863..c2b2856a92e 100644 --- a/apps/login/src/lib/server/passkeys.ts +++ b/apps/login/src/lib/server/passkeys.ts @@ -43,7 +43,7 @@ export async function registerPasskeyLink( const { sessionId } = command; const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const host = _headers.get("host"); if (!host) { @@ -90,7 +90,7 @@ export async function registerPasskeyLink( export async function verifyPasskeyRegistration(command: VerifyPasskeyCommand) { const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); // if no name is provided, try to generate one from the user agent let passkeyName = command.passkeyName; @@ -153,7 +153,7 @@ export async function sendPasskey(command: SendPasskeyCommand) { } const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const loginSettings = await getLoginSettings({ serviceUrl, organization }); diff --git a/apps/login/src/lib/server/password.ts b/apps/login/src/lib/server/password.ts index 74518efabee..ec7d61b7d18 100644 --- a/apps/login/src/lib/server/password.ts +++ b/apps/login/src/lib/server/password.ts @@ -45,7 +45,7 @@ type ResetPasswordCommand = { export async function resetPassword(command: ResetPasswordCommand) { const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const host = _headers.get("host"); if (!host || typeof host !== "string") { @@ -85,7 +85,7 @@ export type UpdateSessionCommand = { export async function sendPassword(command: UpdateSessionCommand) { const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); let sessionCookie = await getSessionCookieByLoginName({ loginName: command.loginName, @@ -255,7 +255,7 @@ export async function changePassword(command: { password: string; }) { const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); // check for init state const { user } = await getUserByID({ serviceUrl, userId: command.userId }); @@ -284,7 +284,7 @@ export async function checkSessionAndSetPassword({ password, }: CheckSessionAndSetPasswordCommand) { const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const sessionCookie = await getSessionCookieById({ sessionId }); diff --git a/apps/login/src/lib/server/register.ts b/apps/login/src/lib/server/register.ts index 67021f21f65..dd8d6d20312 100644 --- a/apps/login/src/lib/server/register.ts +++ b/apps/login/src/lib/server/register.ts @@ -29,7 +29,7 @@ export type RegisterUserResponse = { }; export async function registerUser(command: RegisterUserCommand) { const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const host = _headers.get("host"); if (!host || typeof host !== "string") { diff --git a/apps/login/src/lib/server/session.ts b/apps/login/src/lib/server/session.ts index db165dfabd1..658ba41fe82 100644 --- a/apps/login/src/lib/server/session.ts +++ b/apps/login/src/lib/server/session.ts @@ -25,7 +25,7 @@ export async function continueWithSession({ ...session }: Session & { authRequestId?: string }) { const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const loginSettings = await getLoginSettings({ serviceUrl, @@ -88,7 +88,7 @@ export async function updateSession(options: UpdateSessionCommand) { } const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const host = _headers.get("host"); if (!host) { @@ -152,7 +152,7 @@ type ClearSessionOptions = { export async function clearSession(options: ClearSessionOptions) { const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const { sessionId } = options; @@ -175,7 +175,7 @@ type CleanupSessionCommand = { export async function cleanupSession({ sessionId }: CleanupSessionCommand) { const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const sessionCookie = await getSessionCookieById({ sessionId }); diff --git a/apps/login/src/lib/server/u2f.ts b/apps/login/src/lib/server/u2f.ts index 5eaabce5326..223a5fa78ff 100644 --- a/apps/login/src/lib/server/u2f.ts +++ b/apps/login/src/lib/server/u2f.ts @@ -21,7 +21,7 @@ type VerifyU2FCommand = { export async function addU2F(command: RegisterU2FCommand) { const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const host = _headers.get("host"); if (!host || typeof host !== "string") { @@ -59,7 +59,7 @@ export async function addU2F(command: RegisterU2FCommand) { export async function verifyU2F(command: VerifyU2FCommand) { const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const host = _headers.get("host"); if (!host || typeof host !== "string") { diff --git a/apps/login/src/lib/server/verify.ts b/apps/login/src/lib/server/verify.ts index 6c07197b875..befad512ef3 100644 --- a/apps/login/src/lib/server/verify.ts +++ b/apps/login/src/lib/server/verify.ts @@ -30,7 +30,7 @@ export async function verifyTOTP( organization?: string, ) { const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); return loadMostRecentSession({ serviceUrl, @@ -62,7 +62,7 @@ type VerifyUserByEmailCommand = { export async function sendVerification(command: VerifyUserByEmailCommand) { const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const verifyResponse = command.isInvite ? await verifyInviteCode({ @@ -244,7 +244,7 @@ type resendVerifyEmailCommand = { export async function resendVerification(command: resendVerifyEmailCommand) { const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const host = _headers.get("host"); if (!host) { @@ -290,7 +290,7 @@ export async function sendVerificationRedirectWithoutCheck( command: SendVerificationRedirectWithoutCheckCommand, ) { const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); if (!("loginName" in command || "userId" in command)) { return { error: "No userId, nor loginname provided" }; diff --git a/apps/login/src/lib/service.ts b/apps/login/src/lib/service.ts index f6c70c66d30..b1042a4e2e8 100644 --- a/apps/login/src/lib/service.ts +++ b/apps/login/src/lib/service.ts @@ -20,16 +20,17 @@ type ServiceClass = export async function createServiceForHost( service: T, serviceUrl: string, + serviceRegion: string, ) { let token; // if we are running in a multitenancy context, use the system user token if ( - process.env.AUDIENCE && - process.env.SYSTEM_USER_ID && - process.env.SYSTEM_USER_PRIVATE_KEY + process.env.QA_AUDIENCE && + process.env.QA_SYSTEM_USER_ID && + process.env.QA_SYSTEM_USER_PRIVATE_KEY ) { - token = await systemAPIToken(); + token = await systemAPIToken(serviceRegion); } else if (process.env.ZITADEL_SERVICE_USER_TOKEN) { token = process.env.ZITADEL_SERVICE_USER_TOKEN; } @@ -49,7 +50,10 @@ export async function createServiceForHost( return createClientFor(service)(transport); } -export function getServiceUrlFromHeaders(headers: ReadonlyHeaders): string { +export function getServiceUrlFromHeaders(headers: ReadonlyHeaders): { + serviceUrl: string; + serviceRegion: string; +} { let instanceUrl: string = process.env.ZITADEL_API_URL; const forwardedHost = headers.get("x-zitadel-forward-host"); @@ -70,5 +74,8 @@ export function getServiceUrlFromHeaders(headers: ReadonlyHeaders): string { } } - return instanceUrl; + return { + serviceUrl: instanceUrl, + serviceRegion: headers.get("x-zitadel-region") || "", + }; } diff --git a/apps/login/src/lib/zitadel.ts b/apps/login/src/lib/zitadel.ts index 5a03e5ece07..f24e5f73dfc 100644 --- a/apps/login/src/lib/zitadel.ts +++ b/apps/login/src/lib/zitadel.ts @@ -55,13 +55,15 @@ async function cacheWrapper(callback: Promise) { export async function getBrandingSettings({ serviceUrl, + serviceRegion, organization, }: { serviceUrl: string; + serviceRegion: string; organization?: string; }) { const settingsService: Client = - await createServiceForHost(SettingsService, serviceUrl); + await createServiceForHost(SettingsService, serviceUrl, serviceRegion); const callback = settingsService .getBrandingSettings({ ctx: makeReqCtx(organization) }, {}) @@ -72,13 +74,15 @@ export async function getBrandingSettings({ export async function getLoginSettings({ serviceUrl, + serviceRegion, organization, }: { serviceUrl: string; + serviceRegion: string; organization?: string; }) { const settingsService: Client = - await createServiceForHost(SettingsService, serviceUrl); + await createServiceForHost(SettingsService, serviceUrl, serviceRegion); const callback = settingsService .getLoginSettings({ ctx: makeReqCtx(organization) }, {}) @@ -89,14 +93,17 @@ export async function getLoginSettings({ export async function listIDPLinks({ serviceUrl, + serviceRegion, userId, }: { serviceUrl: string; + serviceRegion: string; userId: string; }) { const userService: Client = await createServiceForHost( UserService, serviceUrl, + serviceRegion, ); return userService.listIDPLinks({ userId }, {}); @@ -104,14 +111,17 @@ export async function listIDPLinks({ export async function addOTPEmail({ serviceUrl, + serviceRegion, userId, }: { serviceUrl: string; + serviceRegion: string; userId: string; }) { const userService: Client = await createServiceForHost( UserService, serviceUrl, + serviceRegion, ); return userService.addOTPEmail({ userId }, {}); @@ -119,14 +129,17 @@ export async function addOTPEmail({ export async function addOTPSMS({ serviceUrl, + serviceRegion, userId, }: { serviceUrl: string; + serviceRegion: string; userId: string; }) { const userService: Client = await createServiceForHost( UserService, serviceUrl, + serviceRegion, ); return userService.addOTPSMS({ userId }, {}); @@ -134,14 +147,17 @@ export async function addOTPSMS({ export async function registerTOTP({ serviceUrl, + serviceRegion, userId, }: { serviceUrl: string; + serviceRegion: string; userId: string; }) { const userService: Client = await createServiceForHost( UserService, serviceUrl, + serviceRegion, ); return userService.registerTOTP({ userId }, {}); @@ -149,11 +165,13 @@ export async function registerTOTP({ export async function getGeneralSettings({ serviceUrl, + serviceRegion, }: { serviceUrl: string; + serviceRegion: string; }) { const settingsService: Client = - await createServiceForHost(SettingsService, serviceUrl); + await createServiceForHost(SettingsService, serviceUrl, serviceRegion); const callback = settingsService .getGeneralSettings({}, {}) @@ -164,13 +182,15 @@ export async function getGeneralSettings({ export async function getLegalAndSupportSettings({ serviceUrl, + serviceRegion, organization, }: { serviceUrl: string; + serviceRegion: string; organization?: string; }) { const settingsService: Client = - await createServiceForHost(SettingsService, serviceUrl); + await createServiceForHost(SettingsService, serviceUrl, serviceRegion); const callback = settingsService .getLegalAndSupportSettings({ ctx: makeReqCtx(organization) }, {}) @@ -181,13 +201,15 @@ export async function getLegalAndSupportSettings({ export async function getPasswordComplexitySettings({ serviceUrl, + serviceRegion, organization, }: { serviceUrl: string; + serviceRegion: string; organization?: string; }) { const settingsService: Client = - await createServiceForHost(SettingsService, serviceUrl); + await createServiceForHost(SettingsService, serviceUrl, serviceRegion); const callback = settingsService .getPasswordComplexitySettings({ ctx: makeReqCtx(organization) }) @@ -198,28 +220,32 @@ export async function getPasswordComplexitySettings({ export async function createSessionFromChecks({ serviceUrl, + serviceRegion, checks, challenges, lifetime, }: { serviceUrl: string; + serviceRegion: string; checks: Checks; challenges: RequestChallenges | undefined; lifetime?: Duration; }) { const sessionService: Client = - await createServiceForHost(SessionService, serviceUrl); + await createServiceForHost(SessionService, serviceUrl, serviceRegion); return sessionService.createSession({ checks, challenges, lifetime }, {}); } export async function createSessionForUserIdAndIdpIntent({ serviceUrl, + serviceRegion, userId, idpIntent, lifetime, }: { serviceUrl: string; + serviceRegion: string; userId: string; idpIntent: { idpIntentId?: string | undefined; @@ -228,7 +254,7 @@ export async function createSessionForUserIdAndIdpIntent({ lifetime?: Duration; }) { const sessionService: Client = - await createServiceForHost(SessionService, serviceUrl); + await createServiceForHost(SessionService, serviceUrl, serviceRegion); return sessionService.createSession({ checks: { @@ -246,6 +272,7 @@ export async function createSessionForUserIdAndIdpIntent({ export async function setSession({ serviceUrl, + serviceRegion, sessionId, sessionToken, challenges, @@ -253,6 +280,7 @@ export async function setSession({ lifetime, }: { serviceUrl: string; + serviceRegion: string; sessionId: string; sessionToken: string; challenges: RequestChallenges | undefined; @@ -260,7 +288,7 @@ export async function setSession({ lifetime?: Duration; }) { const sessionService: Client = - await createServiceForHost(SessionService, serviceUrl); + await createServiceForHost(SessionService, serviceUrl, serviceRegion); return sessionService.setSession( { @@ -277,42 +305,51 @@ export async function setSession({ export async function getSession({ serviceUrl, + serviceRegion, sessionId, sessionToken, }: { serviceUrl: string; + serviceRegion: string; sessionId: string; sessionToken: string; }) { const sessionService: Client = - await createServiceForHost(SessionService, serviceUrl); + await createServiceForHost(SessionService, serviceUrl, serviceRegion); return sessionService.getSession({ sessionId, sessionToken }, {}); } export async function deleteSession({ serviceUrl, + serviceRegion, sessionId, sessionToken, }: { serviceUrl: string; + serviceRegion: string; sessionId: string; sessionToken: string; }) { const sessionService: Client = - await createServiceForHost(SessionService, serviceUrl); + await createServiceForHost(SessionService, serviceUrl, serviceRegion); return sessionService.deleteSession({ sessionId, sessionToken }, {}); } type ListSessionsCommand = { serviceUrl: string; + serviceRegion: string; ids: string[]; }; -export async function listSessions({ serviceUrl, ids }: ListSessionsCommand) { +export async function listSessions({ + serviceUrl, + serviceRegion, + ids, +}: ListSessionsCommand) { const sessionService: Client = - await createServiceForHost(SessionService, serviceUrl); + await createServiceForHost(SessionService, serviceUrl, serviceRegion); return sessionService.listSessions( { @@ -331,6 +368,7 @@ export async function listSessions({ serviceUrl, ids }: ListSessionsCommand) { export type AddHumanUserData = { serviceUrl: string; + serviceRegion: string; firstName: string; lastName: string; email: string; @@ -340,6 +378,7 @@ export type AddHumanUserData = { export async function addHumanUser({ serviceUrl, + serviceRegion, email, firstName, lastName, @@ -349,6 +388,7 @@ export async function addHumanUser({ const userService: Client = await createServiceForHost( UserService, serviceUrl, + serviceRegion, ); return userService.addHumanUser({ @@ -372,14 +412,17 @@ export async function addHumanUser({ export async function addHuman({ serviceUrl, + serviceRegion, request, }: { serviceUrl: string; + serviceRegion: string; request: AddHumanUserRequest; }) { const userService: Client = await createServiceForHost( UserService, serviceUrl, + serviceRegion, ); return userService.addHumanUser(request); @@ -387,16 +430,19 @@ export async function addHuman({ export async function verifyTOTPRegistration({ serviceUrl, + serviceRegion, code, userId, }: { serviceUrl: string; + serviceRegion: string; code: string; userId: string; }) { const userService: Client = await createServiceForHost( UserService, serviceUrl, + serviceRegion, ); return userService.verifyTOTPRegistration({ code, userId }, {}); @@ -404,14 +450,17 @@ export async function verifyTOTPRegistration({ export async function getUserByID({ serviceUrl, + serviceRegion, userId, }: { serviceUrl: string; + serviceRegion: string; userId: string; }) { const userService: Client = await createServiceForHost( UserService, serviceUrl, + serviceRegion, ); return userService.getUserByID({ userId }, {}); @@ -419,16 +468,19 @@ export async function getUserByID({ export async function verifyInviteCode({ serviceUrl, + serviceRegion, userId, verificationCode, }: { serviceUrl: string; + serviceRegion: string; userId: string; verificationCode: string; }) { const userService: Client = await createServiceForHost( UserService, serviceUrl, + serviceRegion, ); return userService.verifyInviteCode({ userId, verificationCode }, {}); @@ -436,14 +488,17 @@ export async function verifyInviteCode({ export async function resendInviteCode({ serviceUrl, + serviceRegion, userId, }: { serviceUrl: string; + serviceRegion: string; userId: string; }) { const userService: Client = await createServiceForHost( UserService, serviceUrl, + serviceRegion, ); return userService.resendInviteCode({ userId }, {}); @@ -451,10 +506,12 @@ export async function resendInviteCode({ export async function sendEmailCode({ serviceUrl, + serviceRegion, userId, urlTemplate, }: { serviceUrl: string; + serviceRegion: string; userId: string; urlTemplate: string; }) { @@ -473,6 +530,7 @@ export async function sendEmailCode({ const userService: Client = await createServiceForHost( UserService, serviceUrl, + serviceRegion, ); return userService.sendEmailCode(medium, {}); @@ -480,10 +538,12 @@ export async function sendEmailCode({ export async function createInviteCode({ serviceUrl, + serviceRegion, urlTemplate, userId, }: { serviceUrl: string; + serviceRegion: string; urlTemplate: string; userId: string; }) { @@ -499,6 +559,7 @@ export async function createInviteCode({ const userService: Client = await createServiceForHost( UserService, serviceUrl, + serviceRegion, ); return userService.createInviteCode( @@ -515,6 +576,7 @@ export async function createInviteCode({ export type ListUsersCommand = { serviceUrl: string; + serviceRegion: string; loginName?: string; userName?: string; email?: string; @@ -524,6 +586,7 @@ export type ListUsersCommand = { export async function listUsers({ serviceUrl, + serviceRegion, loginName, userName, phone, @@ -615,6 +678,7 @@ export async function listUsers({ const userService: Client = await createServiceForHost( UserService, serviceUrl, + serviceRegion, ); return userService.listUsers({ queries }); @@ -622,6 +686,7 @@ export async function listUsers({ export type SearchUsersCommand = { serviceUrl: string; + serviceRegion: string; searchValue: string; loginSettings: LoginSettings; organizationId?: string; @@ -667,6 +732,7 @@ const EmailQuery = (searchValue: string) => * */ export async function searchUsers({ serviceUrl, + serviceRegion, searchValue, loginSettings, organizationId, @@ -700,6 +766,7 @@ export async function searchUsers({ const userService: Client = await createServiceForHost( UserService, serviceUrl, + serviceRegion, ); const loginNameResult = await userService.listUsers({ queries }); @@ -786,11 +853,13 @@ export async function searchUsers({ export async function getDefaultOrg({ serviceUrl, + serviceRegion, }: { serviceUrl: string; + serviceRegion: string; }): Promise { const orgService: Client = - await createServiceForHost(OrganizationService, serviceUrl); + await createServiceForHost(OrganizationService, serviceUrl, serviceRegion); return orgService .listOrganizations( @@ -811,13 +880,15 @@ export async function getDefaultOrg({ export async function getOrgsByDomain({ serviceUrl, + serviceRegion, domain, }: { serviceUrl: string; + serviceRegion: string; domain: string; }) { const orgService: Client = - await createServiceForHost(OrganizationService, serviceUrl); + await createServiceForHost(OrganizationService, serviceUrl, serviceRegion); return orgService.listOrganizations( { @@ -836,16 +907,19 @@ export async function getOrgsByDomain({ export async function startIdentityProviderFlow({ serviceUrl, + serviceRegion, idpId, urls, }: { serviceUrl: string; + serviceRegion: string; idpId: string; urls: RedirectURLsJson; }) { const userService: Client = await createServiceForHost( UserService, serviceUrl, + serviceRegion, ); return userService.startIdentityProviderIntent({ @@ -859,16 +933,19 @@ export async function startIdentityProviderFlow({ export async function retrieveIdentityProviderInformation({ serviceUrl, + serviceRegion, idpIntentId, idpIntentToken, }: { serviceUrl: string; + serviceRegion: string; idpIntentId: string; idpIntentToken: string; }) { const userService: Client = await createServiceForHost( UserService, serviceUrl, + serviceRegion, ); return userService.retrieveIdentityProviderIntent({ @@ -879,12 +956,18 @@ export async function retrieveIdentityProviderInformation({ export async function getAuthRequest({ serviceUrl, + serviceRegion, authRequestId, }: { serviceUrl: string; + serviceRegion: string; authRequestId: string; }) { - const oidcService = await createServiceForHost(OIDCService, serviceUrl); + const oidcService = await createServiceForHost( + OIDCService, + serviceUrl, + serviceRegion, + ); return oidcService.getAuthRequest({ authRequestId, @@ -893,28 +976,37 @@ export async function getAuthRequest({ export async function createCallback({ serviceUrl, + serviceRegion, req, }: { serviceUrl: string; + serviceRegion: string; req: CreateCallbackRequest; }) { - const oidcService = await createServiceForHost(OIDCService, serviceUrl); + const oidcService = await createServiceForHost( + OIDCService, + serviceUrl, + serviceRegion, + ); return oidcService.createCallback(req); } export async function verifyEmail({ serviceUrl, + serviceRegion, userId, verificationCode, }: { serviceUrl: string; + serviceRegion: string; userId: string; verificationCode: string; }) { const userService: Client = await createServiceForHost( UserService, serviceUrl, + serviceRegion, ); return userService.verifyEmail( @@ -928,10 +1020,12 @@ export async function verifyEmail({ export async function resendEmailCode({ serviceUrl, + serviceRegion, userId, urlTemplate, }: { serviceUrl: string; + serviceRegion: string; userId: string; urlTemplate: string; }) { @@ -948,6 +1042,7 @@ export async function resendEmailCode({ const userService: Client = await createServiceForHost( UserService, serviceUrl, + serviceRegion, ); return userService.resendEmailCode(request, {}); @@ -955,16 +1050,19 @@ export async function resendEmailCode({ export async function retrieveIDPIntent({ serviceUrl, + serviceRegion, id, token, }: { serviceUrl: string; + serviceRegion: string; id: string; token: string; }) { const userService: Client = await createServiceForHost( UserService, serviceUrl, + serviceRegion, ); return userService.retrieveIdentityProviderIntent( @@ -975,29 +1073,38 @@ export async function retrieveIDPIntent({ export async function getIDPByID({ serviceUrl, + serviceRegion, id, }: { serviceUrl: string; + serviceRegion: string; id: string; }) { const idpService: Client = - await createServiceForHost(IdentityProviderService, serviceUrl); + await createServiceForHost( + IdentityProviderService, + serviceUrl, + serviceRegion, + ); return idpService.getIDPByID({ id }, {}).then((resp) => resp.idp); } export async function addIDPLink({ serviceUrl, + serviceRegion, idp, userId, }: { serviceUrl: string; + serviceRegion: string; idp: { id: string; userId: string; userName: string }; userId: string; }) { const userService: Client = await createServiceForHost( UserService, serviceUrl, + serviceRegion, ); return userService.addIDPLink( @@ -1015,10 +1122,12 @@ export async function addIDPLink({ export async function passwordReset({ serviceUrl, + serviceRegion, userId, urlTemplate, }: { serviceUrl: string; + serviceRegion: string; userId: string; urlTemplate?: string; }) { @@ -1034,6 +1143,7 @@ export async function passwordReset({ const userService: Client = await createServiceForHost( UserService, serviceUrl, + serviceRegion, ); return userService.passwordReset( @@ -1050,12 +1160,14 @@ export async function passwordReset({ export async function setUserPassword({ serviceUrl, + serviceRegion, userId, password, user, code, }: { serviceUrl: string; + serviceRegion: string; userId: string; password: string; user: User; @@ -1097,6 +1209,7 @@ export async function setUserPassword({ const userService: Client = await createServiceForHost( UserService, serviceUrl, + serviceRegion, ); return userService.setPassword(payload, {}).catch((error) => { @@ -1111,14 +1224,17 @@ export async function setUserPassword({ export async function setPassword({ serviceUrl, + serviceRegion, payload, }: { serviceUrl: string; + serviceRegion: string; payload: SetPasswordRequest; }) { const userService: Client = await createServiceForHost( UserService, serviceUrl, + serviceRegion, ); return userService.setPassword(payload, {}); @@ -1132,14 +1248,17 @@ export async function setPassword({ */ export async function createPasskeyRegistrationLink({ serviceUrl, + serviceRegion, userId, }: { serviceUrl: string; + serviceRegion: string; userId: string; }) { const userService: Client = await createServiceForHost( UserService, serviceUrl, + serviceRegion, ); return userService.createPasskeyRegistrationLink({ @@ -1160,16 +1279,19 @@ export async function createPasskeyRegistrationLink({ */ export async function registerU2F({ serviceUrl, + serviceRegion, userId, domain, }: { serviceUrl: string; + serviceRegion: string; userId: string; domain: string; }) { const userService: Client = await createServiceForHost( UserService, serviceUrl, + serviceRegion, ); return userService.registerU2F({ @@ -1186,14 +1308,17 @@ export async function registerU2F({ */ export async function verifyU2FRegistration({ serviceUrl, + serviceRegion, request, }: { serviceUrl: string; + serviceRegion: string; request: VerifyU2FRegistrationRequest; }) { const userService: Client = await createServiceForHost( UserService, serviceUrl, + serviceRegion, ); return userService.verifyU2FRegistration(request, {}); @@ -1208,10 +1333,12 @@ export async function verifyU2FRegistration({ */ export async function getActiveIdentityProviders({ serviceUrl, + serviceRegion, orgId, linking_allowed, }: { serviceUrl: string; + serviceRegion: string; orgId?: string; linking_allowed?: boolean; }) { @@ -1220,7 +1347,7 @@ export async function getActiveIdentityProviders({ props.linkingAllowed = linking_allowed; } const settingsService: Client = - await createServiceForHost(SettingsService, serviceUrl); + await createServiceForHost(SettingsService, serviceUrl, serviceRegion); return settingsService.getActiveIdentityProviders(props, {}); } @@ -1233,14 +1360,17 @@ export async function getActiveIdentityProviders({ */ export async function verifyPasskeyRegistration({ serviceUrl, + serviceRegion, request, }: { serviceUrl: string; + serviceRegion: string; request: VerifyPasskeyRegistrationRequest; }) { const userService: Client = await createServiceForHost( UserService, serviceUrl, + serviceRegion, ); return userService.verifyPasskeyRegistration(request, {}); @@ -1256,11 +1386,13 @@ export async function verifyPasskeyRegistration({ */ export async function registerPasskey({ serviceUrl, + serviceRegion, userId, code, domain, }: { serviceUrl: string; + serviceRegion: string; userId: string; code: { id: string; code: string }; domain: string; @@ -1268,6 +1400,7 @@ export async function registerPasskey({ const userService: Client = await createServiceForHost( UserService, serviceUrl, + serviceRegion, ); return userService.registerPasskey({ @@ -1285,14 +1418,17 @@ export async function registerPasskey({ */ export async function listAuthenticationMethodTypes({ serviceUrl, + serviceRegion, userId, }: { serviceUrl: string; + serviceRegion: string; userId: string; }) { const userService: Client = await createServiceForHost( UserService, serviceUrl, + serviceRegion, ); return userService.listAuthenticationMethodTypes({ diff --git a/apps/login/src/middleware.ts b/apps/login/src/middleware.ts index cb42234cac4..8ffe8e58302 100644 --- a/apps/login/src/middleware.ts +++ b/apps/login/src/middleware.ts @@ -23,7 +23,7 @@ export async function middleware(request: NextRequest) { const _headers = await headers(); - const serviceUrl = getServiceUrlFromHeaders(_headers); + const { serviceUrl, serviceRegion } = getServiceUrlFromHeaders(_headers); const instanceHost = `${serviceUrl}`.replace("https://", ""); diff --git a/turbo.json b/turbo.json index 1db73e60c96..b342c3f52ae 100644 --- a/turbo.json +++ b/turbo.json @@ -6,9 +6,12 @@ "DEBUG", "VERCEL_URL", "EMAIL_VERIFICATION", - "AUDIENCE", - "SYSTEM_USER_ID", - "SYSTEM_USER_PRIVATE_KEY", + "QA_AUDIENCE", + "QA_SYSTEM_USER_ID", + "QA_SYSTEM_USER_PRIVATE_KEY", + "PROD_AUDIENCE", + "PROD_SYSTEM_USER_ID", + "PROD_SYSTEM_USER_PRIVATE_KEY", "ZITADEL_API_URL", "ZITADEL_SERVICE_USER_ID", "ZITADEL_SERVICE_USER_TOKEN",