diff --git a/apps/login/app/(login)/passkey/login/page.tsx b/apps/login/app/(login)/passkey/login/page.tsx index d8eac1ef4f4..e523ff30221 100644 --- a/apps/login/app/(login)/passkey/login/page.tsx +++ b/apps/login/app/(login)/passkey/login/page.tsx @@ -13,7 +13,7 @@ export default async function Page({ }: { searchParams: Record; }) { - const { loginName, altPassword } = searchParams; + const { loginName, altPassword, authRequestId } = searchParams; const sessionFactors = await loadSession(loginName); @@ -48,6 +48,7 @@ export default async function Page({ {loginName && ( )} diff --git a/apps/login/app/(login)/password/page.tsx b/apps/login/app/(login)/password/page.tsx index 0ea96aa6856..5458909be97 100644 --- a/apps/login/app/(login)/password/page.tsx +++ b/apps/login/app/(login)/password/page.tsx @@ -9,7 +9,7 @@ export default async function Page({ }: { searchParams: Record; }) { - const { loginName, promptPasswordless, alt } = searchParams; + const { loginName, promptPasswordless, authRequestId, alt } = searchParams; const sessionFactors = await loadSession(loginName); async function loadSession(loginName?: string) { @@ -46,6 +46,7 @@ export default async function Page({ diff --git a/apps/login/app/api/loginname/route.ts b/apps/login/app/api/loginname/route.ts index 429d072b394..756fe944f3d 100644 --- a/apps/login/app/api/loginname/route.ts +++ b/apps/login/app/api/loginname/route.ts @@ -45,12 +45,11 @@ export async function POST(request: NextRequest) { if (body) { const { loginName, authRequestId } = body; - const domain: string = request.nextUrl.hostname; + // const domain: string = request.nextUrl.hostname; return createSessionAndUpdateCookie( loginName, undefined, - domain, undefined, authRequestId ) diff --git a/apps/login/app/api/session/route.ts b/apps/login/app/api/session/route.ts index a970ff35d6b..28dec3500de 100644 --- a/apps/login/app/api/session/route.ts +++ b/apps/login/app/api/session/route.ts @@ -22,7 +22,7 @@ export async function POST(request: NextRequest) { return createSessionAndUpdateCookie( loginName, password, - domain, + undefined, undefined ).then((session) => { return NextResponse.json(session); @@ -44,7 +44,7 @@ export async function PUT(request: NextRequest) { const body = await request.json(); if (body) { - const { loginName, password, challenges, passkey } = body; + const { loginName, password, challenges, passkey, authRequestId } = body; const recentPromise: Promise = loginName ? getSessionCookieByLoginName(loginName).catch((error) => { @@ -54,7 +54,7 @@ export async function PUT(request: NextRequest) { return Promise.reject(error); }); - const domain: string = request.nextUrl.hostname; + // const domain: string = request.nextUrl.hostname; return recentPromise .then((recent) => { @@ -64,8 +64,8 @@ export async function PUT(request: NextRequest) { recent.loginName, password, passkey, - domain, - challenges + challenges, + authRequestId ).then((session) => { return NextResponse.json({ sessionId: session.id, diff --git a/apps/login/lib/zitadel.ts b/apps/login/lib/zitadel.ts index 62be6b6e0b9..00aa10459c8 100644 --- a/apps/login/lib/zitadel.ts +++ b/apps/login/lib/zitadel.ts @@ -101,7 +101,7 @@ export async function createSession( server: ZitadelServer, loginName: string, password: string | undefined, - challenges: RequestChallenges + challenges: RequestChallenges | undefined ): Promise { const sessionService = session.getSession(server); return password @@ -125,7 +125,7 @@ export async function setSession( sessionToken: string, password: string | undefined, webAuthN: { credentialAssertionData: any } | undefined, - challenges: RequestChallenges + challenges: RequestChallenges | undefined ): Promise { const sessionService = session.getSession(server); diff --git a/apps/login/ui/LoginPasskey.tsx b/apps/login/ui/LoginPasskey.tsx index 74de10ae4d8..feb27c60026 100644 --- a/apps/login/ui/LoginPasskey.tsx +++ b/apps/login/ui/LoginPasskey.tsx @@ -9,10 +9,15 @@ import { Spinner } from "./Spinner"; type Props = { loginName: string; + authRequestId?: string; altPassword: boolean; }; -export default function LoginPasskey({ loginName, altPassword }: Props) { +export default function LoginPasskey({ + loginName, + authRequestId, + altPassword, +}: Props) { const [error, setError] = useState(""); const [loading, setLoading] = useState(false); @@ -60,6 +65,7 @@ export default function LoginPasskey({ loginName, altPassword }: Props) { body: JSON.stringify({ loginName, challenges: [1], // request passkey challenge + authRequestId, }), }); @@ -81,6 +87,7 @@ export default function LoginPasskey({ loginName, altPassword }: Props) { body: JSON.stringify({ loginName, passkey: data, + authRequestId, }), }); @@ -168,11 +175,16 @@ export default function LoginPasskey({ loginName, altPassword }: Props) { diff --git a/apps/login/ui/PasswordForm.tsx b/apps/login/ui/PasswordForm.tsx index e547e801165..d542f2a0eab 100644 --- a/apps/login/ui/PasswordForm.tsx +++ b/apps/login/ui/PasswordForm.tsx @@ -14,12 +14,14 @@ type Inputs = { type Props = { loginName?: string; + authRequestId?: string; isAlternative?: boolean; // whether password was requested as alternative auth method promptPasswordless?: boolean; }; export default function PasswordForm({ loginName, + authRequestId, promptPasswordless, isAlternative, }: Props) { @@ -44,6 +46,7 @@ export default function PasswordForm({ body: JSON.stringify({ loginName, password: values.password, + authRequestId, }), }); diff --git a/apps/login/ui/RegisterFormWithoutPassword.tsx b/apps/login/ui/RegisterFormWithoutPassword.tsx index b75e99514c3..49a89df5cf1 100644 --- a/apps/login/ui/RegisterFormWithoutPassword.tsx +++ b/apps/login/ui/RegisterFormWithoutPassword.tsx @@ -66,6 +66,7 @@ export default function RegisterFormWithoutPassword({ legal }: Props) { }, body: JSON.stringify({ loginName: loginName, + // authRequestId, register does not need an oidc callback at the end }), }); diff --git a/apps/login/ui/SessionItem.tsx b/apps/login/ui/SessionItem.tsx index 3214ea99c0a..383667d1c6d 100644 --- a/apps/login/ui/SessionItem.tsx +++ b/apps/login/ui/SessionItem.tsx @@ -39,7 +39,7 @@ export default function SessionItem({ } const validPassword = session?.factors?.password?.verifiedAt; - const validPasskey = session?.factors?.passkey?.verifiedAt; + const validPasskey = session?.factors?.webAuthN?.verifiedAt; const validUser = validPassword || validPasskey; diff --git a/apps/login/ui/SetPasswordForm.tsx b/apps/login/ui/SetPasswordForm.tsx index 2efe33b8e54..6b065a376ff 100644 --- a/apps/login/ui/SetPasswordForm.tsx +++ b/apps/login/ui/SetPasswordForm.tsx @@ -79,6 +79,7 @@ export default function SetPasswordForm({ body: JSON.stringify({ loginName: loginName, password: password, + // authRequestId, register does not need an oidc callback }), }); diff --git a/apps/login/ui/UsernameForm.tsx b/apps/login/ui/UsernameForm.tsx index dda5b722554..91ee7d180c3 100644 --- a/apps/login/ui/UsernameForm.tsx +++ b/apps/login/ui/UsernameForm.tsx @@ -65,16 +65,18 @@ export default function UsernameForm({ const method = response.authMethodTypes[0]; switch (method) { case 1: //AuthenticationMethodType.AUTHENTICATION_METHOD_TYPE_PASSWORD: + const paramsPassword: any = { loginName: values.loginName }; + + if (loginSettings?.passkeysType === 1) { + paramsPassword.promptPasswordless = `true`; // PasskeysType.PASSKEYS_TYPE_ALLOWED, + } + + if (authRequestId) { + paramsPassword.authRequestId = authRequestId; + } + return router.push( - "/password?" + - new URLSearchParams( - loginSettings?.passkeysType === 1 - ? { - loginName: values.loginName, - promptPasswordless: `true`, // PasskeysType.PASSKEYS_TYPE_ALLOWED, - } - : { loginName: values.loginName } - ) + "/password?" + new URLSearchParams(paramsPassword) ); case 2: // AuthenticationMethodType.AUTHENTICATION_METHOD_TYPE_PASSKEY return router.push( @@ -82,16 +84,17 @@ export default function UsernameForm({ new URLSearchParams({ loginName: values.loginName }) ); default: + const paramsPasskey: any = { loginName: values.loginName }; + + if (loginSettings?.passkeysType === 1) { + paramsPasskey.promptPasswordless = `true`; // PasskeysType.PASSKEYS_TYPE_ALLOWED, + } + + if (authRequestId) { + paramsPasskey.authRequestId = authRequestId; + } return router.push( - "/password?" + - new URLSearchParams( - loginSettings?.passkeysType === 1 - ? { - loginName: values.loginName, - promptPasswordless: `true`, // PasskeysType.PASSKEYS_TYPE_ALLOWED, - } - : { loginName: values.loginName } - ) + "/password?" + new URLSearchParams(paramsPasskey) ); } } else if ( diff --git a/apps/login/utils/session.ts b/apps/login/utils/session.ts index 85c8ab0028a..0f492a7cee8 100644 --- a/apps/login/utils/session.ts +++ b/apps/login/utils/session.ts @@ -4,19 +4,17 @@ import { addSessionToCookie, updateSessionCookie, } from "./cookies"; -import { ChallengeKind, Session, Challenges } from "@zitadel/server"; +import { Session, Challenges, RequestChallenges } from "@zitadel/server"; export async function createSessionAndUpdateCookie( loginName: string, password: string | undefined, - domain: string, - challenges: ChallengeKind[] | undefined, + challenges: RequestChallenges | undefined, authRequestId: string | undefined ): Promise { const createdSession = await createSession( server, loginName, - domain, password, challenges ); @@ -61,15 +59,13 @@ export async function setSessionAndUpdateCookie( loginName: string, password: string | undefined, passkey: { credentialAssertionData: any } | undefined, - domain: string | undefined, - challenges: ChallengeKind[] | undefined, + challenges: RequestChallenges | undefined, authRequestId: string | undefined ): Promise { return setSession( server, sessionId, sessionToken, - domain, password, passkey, challenges