From 01df9fc06ddfefce3c4ffabe6125fa8d7664d3ae Mon Sep 17 00:00:00 2001 From: peintnermax Date: Fri, 30 Aug 2024 10:46:33 +0200 Subject: [PATCH] idp cleanup --- apps/login/src/lib/server/session.ts | 26 +++++++++----- apps/login/src/ui/PasswordForm.tsx | 14 +++++--- apps/login/src/ui/SignInWithIDP.tsx | 47 ++++++++++++++------------ packages/zitadel-client/src/v3alpha.ts | 4 +-- 4 files changed, 55 insertions(+), 36 deletions(-) diff --git a/apps/login/src/lib/server/session.ts b/apps/login/src/lib/server/session.ts index d45f32dd389..f226b655480 100644 --- a/apps/login/src/lib/server/session.ts +++ b/apps/login/src/lib/server/session.ts @@ -19,7 +19,11 @@ import { } from "@/utils/session"; import { headers } from "next/headers"; import { Checks } from "@zitadel/proto/zitadel/session/v2/session_service_pb"; -import { RequestChallenges } from "@zitadel/proto/zitadel/session/v2/challenge_pb"; +import { + RequestChallenges, + RequestChallengesSchema, +} from "@zitadel/proto/zitadel/session/v2/challenge_pb"; +import { create } from "@zitadel/client"; type CreateNewSessionCommand = { userId: string; @@ -71,7 +75,7 @@ export type UpdateSessionCommand = { }; export async function updateSession(options: UpdateSessionCommand) { - const { + let { loginName, sessionId, organization, @@ -110,21 +114,25 @@ export async function updateSession(options: UpdateSessionCommand) { if (recent && challenges && (!challenges.otpEmail || !challenges.otpSms)) { const sessionResponse = await getSession(recent.id, recent.token); - if (sessionResponse && sessionResponse.session.factors.user.id) { + if (sessionResponse && sessionResponse?.session?.factors?.user?.id) { const userResponse = await getUserByID( sessionResponse.session.factors.user.id, ); const humanUser = - userResponse.user.type.case === "human" + userResponse.user?.type.case === "human" ? userResponse.user.type.value : undefined; - if (!challenges.otpEmail && humanUser.email.email) { - challenges.otpEmail = humanUser.email.email; + if (!challenges.otpEmail && humanUser?.email?.email) { + challenges = create(RequestChallengesSchema, { + otpEmail: { deliveryType: { case: "sendCode", value: {} } }, + }); } - if (!challenges.otpSms && humanUser.phone.phone) { - challenges.otpSms = humanUser.phone.phone; + if (!challenges.otpEmail && humanUser?.email?.email) { + challenges = create(RequestChallengesSchema, { + otpSms: { returnCode: true }, + }); } } } @@ -138,7 +146,7 @@ export async function updateSession(options: UpdateSessionCommand) { // if password, check if user has MFA methods let authMethods; - if (checks && checks.password && session.factors.user.id) { + if (checks && checks.password && session.factors?.user?.id) { const response = await listAuthenticationMethodTypes( session.factors.user.id, ); diff --git a/apps/login/src/ui/PasswordForm.tsx b/apps/login/src/ui/PasswordForm.tsx index c39fe2ccd9a..f4ef804e9f3 100644 --- a/apps/login/src/ui/PasswordForm.tsx +++ b/apps/login/src/ui/PasswordForm.tsx @@ -12,7 +12,9 @@ import { LoginSettings } from "@zitadel/proto/zitadel/settings/v2/login_settings import { CheckPassword, Checks, + ChecksSchema, } from "@zitadel/proto/zitadel/session/v2/session_service_pb"; +import { create } from "@zitadel/client"; import { AuthenticationMethodType } from "@zitadel/proto/zitadel/user/v2/user_service_pb"; import { updateSession } from "@/lib/server/session"; @@ -54,9 +56,9 @@ export default function PasswordForm({ const response = await updateSession({ loginName, organization, - checks: { + checks: create(ChecksSchema, { password: { password: values.password }, - } as Checks, + }), authRequestId, }).catch((error: Error) => { setError(error.message ?? "Could not verify password"); @@ -103,7 +105,11 @@ export default function PasswordForm({ // if no passwordless -> /passkey/add // exclude password and passwordless - if (!submitted || !submitted.authMethods) { + if ( + !submitted || + !submitted.authMethods || + !submitted.factors?.user?.loginName + ) { setError("Could not verify password"); return; } @@ -154,7 +160,7 @@ export default function PasswordForm({ return router.push(`/mfa?` + params); } else if ( submitted.factors && - !submitted.factors.passwordless && // if session was not verified with a passkey + !submitted.factors.webAuthN && // if session was not verified with a passkey promptPasswordless && // if explicitly prompted due policy !isAlternative // escaped if password was used as an alternative method ) { diff --git a/apps/login/src/ui/SignInWithIDP.tsx b/apps/login/src/ui/SignInWithIDP.tsx index dcf743b7e5a..dd555331d7d 100644 --- a/apps/login/src/ui/SignInWithIDP.tsx +++ b/apps/login/src/ui/SignInWithIDP.tsx @@ -60,6 +60,17 @@ export function SignInWithIDP({ return response; } + async function navigateToAuthUrl(id: string, type: IdentityProviderType) { + const startFlowResponse = await startFlow(id, idpTypeToSlug(type)); + if ( + startFlowResponse && + startFlowResponse.nextStep.case === "authUrl" && + startFlowResponse?.nextStep.value + ) { + router.push(startFlowResponse.nextStep.value); + } + } + return (
{identityProviders && @@ -70,12 +81,7 @@ export function SignInWithIDP({ - startFlow( - idp.id, - idpTypeToSlug(IdentityProviderType.GITHUB), - ).then(({ authUrl }) => { - router.push(authUrl); - }) + navigateToAuthUrl(idp.id, IdentityProviderType.GITHUB) } > ); @@ -83,7 +89,9 @@ export function SignInWithIDP({ return ( alert("TODO: unimplemented")} + onClick={() => + navigateToAuthUrl(idp.id, IdentityProviderType.GITHUB_ES) + } > ); case IdentityProviderType.AZURE_AD: @@ -91,12 +99,7 @@ export function SignInWithIDP({ - startFlow( - idp.id, - idpTypeToSlug(IdentityProviderType.AZURE_AD), - ).then(({ authUrl }) => { - router.push(authUrl); - }) + navigateToAuthUrl(idp.id, IdentityProviderType.AZURE_AD) } > ); @@ -107,12 +110,7 @@ export function SignInWithIDP({ e2e="google" name={idp.name} onClick={() => - startFlow( - idp.id, - idpTypeToSlug(IdentityProviderType.GOOGLE), - ).then(({ authUrl }) => { - router.push(authUrl); - }) + navigateToAuthUrl(idp.id, IdentityProviderType.GOOGLE) } > ); @@ -120,14 +118,21 @@ export function SignInWithIDP({ return ( alert("TODO: unimplemented")} + onClick={() => + navigateToAuthUrl(idp.id, IdentityProviderType.GITLAB) + } > ); case IdentityProviderType.GITLAB_SELF_HOSTED: return ( alert("TODO: unimplemented")} + onClick={() => + navigateToAuthUrl( + idp.id, + IdentityProviderType.GITLAB_SELF_HOSTED, + ) + } > ); default: diff --git a/packages/zitadel-client/src/v3alpha.ts b/packages/zitadel-client/src/v3alpha.ts index f403ad37a90..166fcb2b6ec 100644 --- a/packages/zitadel-client/src/v3alpha.ts +++ b/packages/zitadel-client/src/v3alpha.ts @@ -1,5 +1,5 @@ -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"; +import { ZITADELUsers } from "@zitadel/proto/zitadel/resources/user/v3alpha/user_service_pb"; +import { ZITADELUserSchemas } from "@zitadel/proto/zitadel/resources/userschema/v3alpha/user_schema_service_pb"; import { createClientFor } from "./helpers"; export const createUserSchemaServiceClient = createClientFor(ZITADELUserSchemas);