diff --git a/apps/login/cypress/integration/login.cy.ts b/apps/login/cypress/integration/login.cy.ts
index d4edf570d68..1d6472d5e66 100644
--- a/apps/login/cypress/integration/login.cy.ts
+++ b/apps/login/cypress/integration/login.cy.ts
@@ -156,12 +156,9 @@ describe("login", () => {
},
});
});
- it("should redirect a user with passwordless authentication to /passkey/login", () => {
+ it("should redirect a user with passwordless authentication to /passkey", () => {
cy.visit("/loginname?loginName=john%40zitadel.com&submit=true");
- cy.location("pathname", { timeout: 10_000 }).should(
- "eq",
- "/passkey/login",
- );
+ cy.location("pathname", { timeout: 10_000 }).should("eq", "/passkey");
});
});
});
diff --git a/apps/login/readme.md b/apps/login/readme.md
index 15386cb2665..a085df7ea37 100644
--- a/apps/login/readme.md
+++ b/apps/login/readme.md
@@ -68,7 +68,7 @@ After a loginname is entered, a `listUsers` request is made using the loginName
**USER FOUND:** If only one user is found, we query `listAuthenticationMethodTypes` to identify future steps.
If no authentication methods are found, we render an error stating: _User has no available authentication methods._ (exception see below.)
-Now if only one method is found, we continue with the corresponding step (/password, /passkey/login).
+Now if only one method is found, we continue with the corresponding step (/password, /passkey).
If multiple methods are set, we prefer passkeys over any other method, so we redirect to /passkey, second option is IDP, and third is password.
If password is the next step, we check `loginSettings.passkeysType` for PasskeysType.ALLOWED, and prompt the user to setup passkeys afterwards.
@@ -123,3 +123,33 @@ If `email` or `sms` is requested as method, the current session of the user is u
The `time-based` (TOTP) method does not require a trigger, therefore no `updateSession()` is performed and no resendLink under the code field is shown.
The submission of the code updates the session and continues to sign in the user.
+
+### /u2f
+
+
+
+This page requests a webAuthN challenge for the user and updates the session afterwards.
+
+Requests to the APIs made:
+
+- `getBrandingSettings(org?)`
+- `getSession()`
+- `updateSession()`
+
+When updating the session for the webAuthN challenge, we set `userVerificationRequirement` to `UserVerificationRequirement.DISCOURAGED` as this will request the webAuthN method as second factor and not as primary method.
+After updating the session, the user is signed in.
+
+### /passkey
+
+
+
+This page requests a webAuthN challenge for the user and updates the session afterwards.
+
+Requests to the APIs made:
+
+- `getBrandingSettings(org?)`
+- `getSession()`
+- `updateSession()`
+
+When updating the session for the webAuthN challenge, we set `userVerificationRequirement` to `UserVerificationRequirement.REQUIRED` as this will request the webAuthN method as primary method to login.
+After updating the session, the user is signed in.
diff --git a/apps/login/src/app/(login)/passkey/login/page.tsx b/apps/login/src/app/(login)/passkey/page.tsx
similarity index 100%
rename from apps/login/src/app/(login)/passkey/login/page.tsx
rename to apps/login/src/app/(login)/passkey/page.tsx
diff --git a/apps/login/src/lib/server/loginname.ts b/apps/login/src/lib/server/loginname.ts
index a566b30ad84..66fd2d824a6 100644
--- a/apps/login/src/lib/server/loginname.ts
+++ b/apps/login/src/lib/server/loginname.ts
@@ -123,9 +123,7 @@ export async function sendLoginname(command: SendLoginnameCommand) {
command.organization ?? session.factors?.user?.organizationId;
}
- return redirect(
- "/passkey/login?" + new URLSearchParams(paramsPasskey),
- );
+ return redirect("/passkey?" + new URLSearchParams(paramsPasskey));
}
} else {
// prefer passkey in favor of other methods
@@ -144,7 +142,7 @@ export async function sendLoginname(command: SendLoginnameCommand) {
command.organization ?? session.factors?.user?.organizationId;
}
- return redirect("/passkey/login?" + new URLSearchParams(passkeyParams));
+ return redirect("/passkey?" + new URLSearchParams(passkeyParams));
} else if (
methods.authMethodTypes.includes(AuthenticationMethodType.IDP)
) {
diff --git a/apps/login/src/ui/RegisterPasskey.tsx b/apps/login/src/ui/RegisterPasskey.tsx
index 2b5c1b12e45..9391e62f63e 100644
--- a/apps/login/src/ui/RegisterPasskey.tsx
+++ b/apps/login/src/ui/RegisterPasskey.tsx
@@ -151,7 +151,7 @@ export default function RegisterPasskey({
// params.set("altPassword", ${false}); // without setting altPassword this does not allow password
// params.set("loginName", resp.loginName);
- router.push("/passkey/login?" + params);
+ router.push("/passkey?" + params);
} else {
router.push("/accounts?" + params);
}