From 2f843621bf2e0697d2494c37bfe0657916e01d68 Mon Sep 17 00:00:00 2001 From: peintnermax Date: Mon, 26 Aug 2024 09:26:23 +0200 Subject: [PATCH 1/5] find org context from loginname --- apps/login/src/app/api/loginname/route.ts | 28 ++++++++++++++++++++++- apps/login/src/lib/zitadel.ts | 10 +++++--- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/apps/login/src/app/api/loginname/route.ts b/apps/login/src/app/api/loginname/route.ts index b6751ae9164..3287f9361c9 100644 --- a/apps/login/src/app/api/loginname/route.ts +++ b/apps/login/src/app/api/loginname/route.ts @@ -2,6 +2,7 @@ import { idpTypeToSlug } from "@/lib/idp"; import { getActiveIdentityProviders, getLoginSettings, + getOrgsByDomainSuffix, listAuthenticationMethodTypes, listUsers, startIdentityProviderFlow, @@ -9,6 +10,8 @@ import { import { createSessionForUserIdAndUpdateCookie } from "@/utils/session"; import { NextRequest, NextResponse } from "next/server"; +const ORG_SUFFIX_REGEX = /(?<=@)(.+)/; + export async function POST(request: NextRequest) { const body = await request.json(); if (body) { @@ -104,14 +107,37 @@ export async function POST(request: NextRequest) { loginSettings?.allowRegister && loginSettings?.allowUsernamePassword ) { - const params: any = { organization }; + let orgToRegisterOn: string | undefined = organization; + + if ( + !orgToRegisterOn && + loginName && + ORG_SUFFIX_REGEX.test(loginName) + ) { + const matched = ORG_SUFFIX_REGEX.exec(loginName); + const suffix = matched?.[1] ?? ""; + + const orgs = await getOrgsByDomainSuffix(suffix); + orgToRegisterOn = + orgs.result && orgs.result.length === 1 + ? orgs.result[0].id + : undefined; + } + + const params: any = {}; + if (authRequestId) { params.authRequestId = authRequestId; } + if (loginName) { params.email = loginName; } + if (orgToRegisterOn) { + params.organization = orgToRegisterOn; + } + const registerUrl = new URL( "/register?" + new URLSearchParams(params), request.url, diff --git a/apps/login/src/lib/zitadel.ts b/apps/login/src/lib/zitadel.ts index f075cc88a2f..1a8b5430591 100644 --- a/apps/login/src/lib/zitadel.ts +++ b/apps/login/src/lib/zitadel.ts @@ -5,6 +5,7 @@ import { createUserServiceClient, createIdpServiceClient, makeReqCtx, + createOrganizationServiceClient, } from "@zitadel/client/v2"; import { createManagementServiceClient } from "@zitadel/client/v1"; import { createServerTransport } from "@zitadel/node"; @@ -36,10 +37,10 @@ const transport = createServerTransport( ); export const sessionService = createSessionServiceClient(transport); -export const managementService = createManagementServiceClient(transport); export const userService = createUserServiceClient(transport); export const oidcService = createOIDCServiceClient(transport); export const idpService = createIdpServiceClient(transport); +export const orgService = createOrganizationServiceClient(transport); export const settingsService = createSettingsServiceClient(transport); @@ -292,8 +293,11 @@ export async function listUsers({ ); } -export async function getOrgByDomain(domain: string) { - return managementService.getOrgByDomainGlobal({ domain }, {}); +export async function getOrgsByDomainSuffix(domain: string) { + return orgService.listOrganizations( + { queries: [{ query: { case: "domainQuery", value: { domain } } }] }, + {}, + ); } export async function startIdentityProviderFlow({ From 50c360c0cf1550b9e0ed6fb2b63f0325bf04f514 Mon Sep 17 00:00:00 2001 From: peintnermax Date: Mon, 26 Aug 2024 09:50:19 +0200 Subject: [PATCH 2/5] org discovery on register --- apps/login/src/app/api/loginname/route.ts | 1 + apps/login/src/lib/zitadel.ts | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/apps/login/src/app/api/loginname/route.ts b/apps/login/src/app/api/loginname/route.ts index 3287f9361c9..b03de844bc4 100644 --- a/apps/login/src/app/api/loginname/route.ts +++ b/apps/login/src/app/api/loginname/route.ts @@ -117,6 +117,7 @@ export async function POST(request: NextRequest) { const matched = ORG_SUFFIX_REGEX.exec(loginName); const suffix = matched?.[1] ?? ""; + // this just returns orgs where the suffix is set as primary domain const orgs = await getOrgsByDomainSuffix(suffix); orgToRegisterOn = orgs.result && orgs.result.length === 1 diff --git a/apps/login/src/lib/zitadel.ts b/apps/login/src/lib/zitadel.ts index 1a8b5430591..d07b7e7e1ee 100644 --- a/apps/login/src/lib/zitadel.ts +++ b/apps/login/src/lib/zitadel.ts @@ -295,7 +295,16 @@ export async function listUsers({ export async function getOrgsByDomainSuffix(domain: string) { return orgService.listOrganizations( - { queries: [{ query: { case: "domainQuery", value: { domain } } }] }, + { + queries: [ + { + query: { + case: "domainQuery", + value: { domain, method: TextQueryMethod.EQUALS }, + }, + }, + ], + }, {}, ); } From 2a1cb2d38b7ccd0305877b51b219a736c7dc060c Mon Sep 17 00:00:00 2001 From: peintnermax Date: Tue, 27 Aug 2024 11:27:43 +0200 Subject: [PATCH 3/5] replace mgmt service request --- apps/login/src/app/api/loginname/route.ts | 7 ++++--- apps/login/src/app/login/route.ts | 8 +++++--- apps/login/src/lib/zitadel.ts | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/apps/login/src/app/api/loginname/route.ts b/apps/login/src/app/api/loginname/route.ts index b03de844bc4..1ea440604c3 100644 --- a/apps/login/src/app/api/loginname/route.ts +++ b/apps/login/src/app/api/loginname/route.ts @@ -2,7 +2,7 @@ import { idpTypeToSlug } from "@/lib/idp"; import { getActiveIdentityProviders, getLoginSettings, - getOrgsByDomainSuffix, + getOrgsByDomain, listAuthenticationMethodTypes, listUsers, startIdentityProviderFlow, @@ -112,13 +112,14 @@ export async function POST(request: NextRequest) { if ( !orgToRegisterOn && loginName && - ORG_SUFFIX_REGEX.test(loginName) + ORG_SUFFIX_REGEX.test(loginName) && + loginSettings.allowDomainDiscovery ) { const matched = ORG_SUFFIX_REGEX.exec(loginName); const suffix = matched?.[1] ?? ""; // this just returns orgs where the suffix is set as primary domain - const orgs = await getOrgsByDomainSuffix(suffix); + const orgs = await getOrgsByDomain(suffix); orgToRegisterOn = orgs.result && orgs.result.length === 1 ? orgs.result[0].id diff --git a/apps/login/src/app/login/route.ts b/apps/login/src/app/login/route.ts index 85eae70ee0c..628320056da 100644 --- a/apps/login/src/app/login/route.ts +++ b/apps/login/src/app/login/route.ts @@ -6,7 +6,7 @@ import { createCallback, getActiveIdentityProviders, getAuthRequest, - getOrgByDomain, + getOrgsByDomain, listSessions, startIdentityProviderFlow, } from "@/lib/zitadel"; @@ -147,8 +147,10 @@ export async function GET(request: NextRequest) { const matched = ORG_DOMAIN_SCOPE_REGEX.exec(orgDomainScope); const orgDomain = matched?.[1] ?? ""; if (orgDomain) { - const org = await getOrgByDomain(orgDomain); - organization = org?.org?.id ?? ""; + const orgs = await getOrgsByDomain(orgDomain); + if (orgs.result && orgs.result.length === 1) { + organization = orgs.result[0].id ?? ""; + } } } } diff --git a/apps/login/src/lib/zitadel.ts b/apps/login/src/lib/zitadel.ts index d07b7e7e1ee..97ba6402fe7 100644 --- a/apps/login/src/lib/zitadel.ts +++ b/apps/login/src/lib/zitadel.ts @@ -293,7 +293,7 @@ export async function listUsers({ ); } -export async function getOrgsByDomainSuffix(domain: string) { +export async function getOrgsByDomain(domain: string) { return orgService.listOrganizations( { queries: [ From c6bf23c126844f5708a2df69fa4f2b3eb8fe4ad2 Mon Sep 17 00:00:00 2001 From: peintnermax Date: Thu, 29 Aug 2024 14:43:36 +0200 Subject: [PATCH 4/5] use org loginSettings --- apps/login/src/app/api/loginname/route.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/apps/login/src/app/api/loginname/route.ts b/apps/login/src/app/api/loginname/route.ts index 1ea440604c3..464eddf4e18 100644 --- a/apps/login/src/app/api/loginname/route.ts +++ b/apps/login/src/app/api/loginname/route.ts @@ -112,18 +112,24 @@ export async function POST(request: NextRequest) { if ( !orgToRegisterOn && loginName && - ORG_SUFFIX_REGEX.test(loginName) && - loginSettings.allowDomainDiscovery + ORG_SUFFIX_REGEX.test(loginName) ) { const matched = ORG_SUFFIX_REGEX.exec(loginName); const suffix = matched?.[1] ?? ""; // this just returns orgs where the suffix is set as primary domain const orgs = await getOrgsByDomain(suffix); - orgToRegisterOn = + const orgToCheckForDiscovery = orgs.result && orgs.result.length === 1 ? orgs.result[0].id : undefined; + + const orgLoginSettings = await getLoginSettings( + orgToCheckForDiscovery, + ); + if (orgLoginSettings?.allowDomainDiscovery) { + orgToRegisterOn = orgToCheckForDiscovery; + } } const params: any = {}; From 2b3decec2807a08653e697b5c4fdad97b68f2afa Mon Sep 17 00:00:00 2001 From: peintnermax Date: Thu, 29 Aug 2024 15:18:12 +0200 Subject: [PATCH 5/5] update paths --- packages/zitadel-client/src/v3alpha.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/zitadel-client/src/v3alpha.ts b/packages/zitadel-client/src/v3alpha.ts index 52b3b4c8ffd..967487fda8a 100644 --- a/packages/zitadel-client/src/v3alpha.ts +++ b/packages/zitadel-client/src/v3alpha.ts @@ -1,6 +1,6 @@ -import { UserSchemaService } from "@zitadel/proto/zitadel/user/schema/v3alpha/user_schema_service_connect"; -import { UserService } from "@zitadel/proto/zitadel/user/v3alpha/user_service_connect"; +import { ZITADELUsers } from "@zitadel/proto/zitadel/resources/user/v3alpha/user_service_connect"; +import { ZITADELUserSchemas } from "@zitadel/proto/zitadel/resources/userschema/v3alpha/user_schema_service_connect.js"; import { createClientFor } from "./helpers"; -export const createUserSchemaServiceClient = createClientFor(UserSchemaService); -export const createUserServiceClient = createClientFor(UserService); +export const createUserSchemaServiceClient = createClientFor(ZITADELUserSchemas); +export const createUserServiceClient = createClientFor(ZITADELUsers);