org discovery on idp callback

This commit is contained in:
Max Peintner
2024-12-16 11:15:01 +01:00
parent 6aa4137fe9
commit 53c0892614
3 changed files with 53 additions and 14 deletions

View File

@@ -3,17 +3,27 @@ import { DynamicTheme } from "@/components/dynamic-theme";
import { IdpSignin } from "@/components/idp-signin";
import { idpTypeToIdentityProviderType, PROVIDER_MAPPING } from "@/lib/idp";
import {
addHuman,
addIDPLink,
createUser,
getBrandingSettings,
getIDPByID,
getLoginSettings,
getOrgsByDomain,
listUsers,
retrieveIDPIntent,
} from "@/lib/zitadel";
import { create } from "@zitadel/client";
import { AutoLinkingOption } from "@zitadel/proto/zitadel/idp/v2/idp_pb";
import { OrganizationSchema } from "@zitadel/proto/zitadel/object/v2/object_pb";
import { BrandingSettings } from "@zitadel/proto/zitadel/settings/v2/branding_settings_pb";
import {
AddHumanUserRequest,
AddHumanUserRequestSchema,
} from "@zitadel/proto/zitadel/user/v2/user_service_pb";
import { getLocale, getTranslations } from "next-intl/server";
const ORG_SUFFIX_REGEX = /(?<=@)(.+)/;
async function loginFailed(branding?: BrandingSettings, error: string = "") {
const locale = getLocale();
const t = await getTranslations({ locale, namespace: "idp" });
@@ -192,7 +202,42 @@ export default async function Page(props: {
}
if (options?.isCreationAllowed && options.isAutoCreation) {
const newUser = await createUser(providerType, idpInformation);
let orgToRegisterOn: string | undefined = organization;
let userData: AddHumanUserRequest =
PROVIDER_MAPPING[providerType](idpInformation);
if (
!orgToRegisterOn &&
userData.username && // username or email?
ORG_SUFFIX_REGEX.test(userData.username)
) {
const matched = ORG_SUFFIX_REGEX.exec(userData.username);
const suffix = matched?.[1] ?? "";
// this just returns orgs where the suffix is set as primary domain
const orgs = await getOrgsByDomain(suffix);
const orgToCheckForDiscovery =
orgs.result && orgs.result.length === 1 ? orgs.result[0].id : undefined;
const orgLoginSettings = await getLoginSettings(orgToCheckForDiscovery);
if (orgLoginSettings?.allowDomainDiscovery) {
orgToRegisterOn = orgToCheckForDiscovery;
}
}
if (orgToRegisterOn) {
const organizationSchema = create(OrganizationSchema, {
org: { case: "orgId", value: orgToRegisterOn },
});
userData = create(AddHumanUserRequestSchema, {
...userData,
organization: organizationSchema,
});
}
const newUser = await addHuman(userData);
if (newUser) {
return (

View File

@@ -61,7 +61,7 @@ export default async function Page(props: {
<SignInWithIdp
identityProviders={identityProviders}
authRequestId={authRequestId}
organization={organization ?? defaultOrganization} // use the organization from the searchParams here otherwise fallback to the default organization
organization={organization}
></SignInWithIdp>
)}
</UsernameForm>

View File

@@ -10,8 +10,8 @@ import {
import { createServerTransport } from "@zitadel/node";
import { RequestChallenges } from "@zitadel/proto/zitadel/session/v2/challenge_pb";
import { Checks } from "@zitadel/proto/zitadel/session/v2/session_service_pb";
import { IDPInformation } from "@zitadel/proto/zitadel/user/v2/idp_pb";
import {
AddHumanUserRequest,
RetrieveIdentityProviderIntentRequest,
SetPasswordRequest,
SetPasswordRequestSchema,
@@ -23,7 +23,6 @@ import { create, Duration } from "@zitadel/client";
import { TextQueryMethod } from "@zitadel/proto/zitadel/object/v2/object_pb";
import { CreateCallbackRequest } from "@zitadel/proto/zitadel/oidc/v2/oidc_service_pb";
import { Organization } from "@zitadel/proto/zitadel/org/v2/org_pb";
import { IdentityProviderType } from "@zitadel/proto/zitadel/settings/v2/login_settings_pb";
import type { RedirectURLsJson } from "@zitadel/proto/zitadel/user/v2/idp_pb";
import {
NotificationType,
@@ -39,7 +38,6 @@ import {
UserState,
} from "@zitadel/proto/zitadel/user/v2/user_pb";
import { unstable_cacheLife as cacheLife } from "next/cache";
import { PROVIDER_MAPPING } from "./idp";
const transport = createServerTransport(
process.env.ZITADEL_SERVICE_USER_TOKEN!,
@@ -249,6 +247,10 @@ export async function addHumanUser({
});
}
export async function addHuman(request: AddHumanUserRequest) {
return userService.addHumanUser(request);
}
export async function verifyTOTPRegistration(code: string, userId: string) {
return userService.verifyTOTPRegistration({ code, userId }, {});
}
@@ -487,14 +489,6 @@ export function addIDPLink(
);
}
export function createUser(
provider: IdentityProviderType,
info: IDPInformation,
) {
const userData = PROVIDER_MAPPING[provider](info);
return userService.addHumanUser(userData, {});
}
/**
*
* @param userId the id of the user where the email should be set