diff --git a/apps/login/readme.md b/apps/login/readme.md
index dc461f02b88..547c2283785 100644
--- a/apps/login/readme.md
+++ b/apps/login/readme.md
@@ -204,6 +204,8 @@ Requests to the APIs made:
If the loginname decides to redirect the user to this page, a button to skip appears which will sign the user in afterwards.
After a passkey is registered, we redirect the user to `/passkey` to verify it again and sign in with the new method. The `createPasskeyRegistrationLink()` uses the token of the session which is determined by the flow.
+> NOTE: this page allows passkeys to be created only if the current session is valid (self service), or no authentication method is set (register). TODO: to be implemented.
+
> NOTE: Redirecting the user to `/passkey` will not be required in future and the currently used session will be hydrated directly after registering. (https://github.com/zitadel/zitadel/issues/8611)
### /otp/time-based/set
@@ -212,10 +214,29 @@ This page registers a time based OTP method for a user.
+Requests to the APIs made:
+
+- `getBrandingSettings(org?)`
+- `getSession()`
+- `registerTOTP()`
+- `verifyTOTP()`
+
+After the setup is done, the user is redirected to verify the TOTP method on `/otp/time-based`.
+
+> NOTE: Redirecting the user to `/otp/time-based` will not be required in future and the currently used session will be hydrated directly. (https://github.com/zitadel/zitadel/issues/8611)
+
### /otp/email/set /otp/sms/set
This page registers either an Email OTP method or SMS OTP method for a user.
+Requests to the APIs made:
+
+- `getBrandingSettings(org?)`
+- `getSession()`
+- `addOTPEmail()` / `addOTPSMS()`
+
+This page directly calls `addOTPEmail()` or `addOTPSMS()` when invoked and shows a success message.
+
### /u2f/set
This page registers a U2F method for a user.
@@ -239,6 +260,8 @@ This page shows a register page, which gets firstname and lastname of a user as
+
+
Requests to the APIs made:
- `listOrganizations()` :warning: TODO: determine the default organization if no context is set
@@ -275,6 +298,21 @@ Both /success and /failure pages are designed to intercept the responses from th
### /verify
+This page verifies the email to be valid. It page of the login can also be invoked without an active session.
+The context of the user is taken from the url and is set in the email template.
+
+
+
+Requests to the APIs made:
+
+- `getBrandingSettings(org?)`
+- `getLoginSettings(org?)`
+- `verifyEmail()`
+
+If the page is invoked with an active session (right after a register with password), the user is signed in or redirected to the loginname if no context is known.
+
+> NOTE: This page will be extended to support invitations. In such case, authentication methods of the user are loaded and if none available, shown as possible next step (`/passkey/set`, `password/set`).
+
### /accounts
This page shows an overview of all current sessions.
diff --git a/apps/login/screenshots/register_password.png b/apps/login/screenshots/register_password.png
new file mode 100644
index 00000000000..31515bda9ad
Binary files /dev/null and b/apps/login/screenshots/register_password.png differ
diff --git a/apps/login/screenshots/verify.png b/apps/login/screenshots/verify.png
new file mode 100644
index 00000000000..c13e6a3a88c
Binary files /dev/null and b/apps/login/screenshots/verify.png differ
diff --git a/apps/login/src/app/(login)/otp/[method]/set/page.tsx b/apps/login/src/app/(login)/otp/[method]/set/page.tsx
index 22b22461846..a43e0a08409 100644
--- a/apps/login/src/app/(login)/otp/[method]/set/page.tsx
+++ b/apps/login/src/app/(login)/otp/[method]/set/page.tsx
@@ -31,8 +31,7 @@ export default async function Page({
organization,
});
- let totpResponse: RegisterTOTPResponse | undefined,
- totpError: Error | undefined;
+ let totpResponse: RegisterTOTPResponse | undefined, error: Error | undefined;
if (session && session.factors?.user?.id) {
if (method === "time-based") {
await registerTOTP(session.factors.user.id)
@@ -41,15 +40,21 @@ export default async function Page({
totpResponse = resp;
}
})
- .catch((error) => {
- totpError = error;
+ .catch((err) => {
+ error = err;
});
} else if (method === "sms") {
// does not work
- await addOTPSMS(session.factors.user.id);
+ await addOTPSMS(session.factors.user.id).catch((error) => {
+ console.error(error);
+ error = new Error("Could not add OTP via SMS");
+ });
} else if (method === "email") {
// works
- await addOTPEmail(session.factors.user.id);
+ await addOTPEmail(session.factors.user.id).catch((error) => {
+ console.error(error);
+ error = new Error("Could not add OTP via Email");
+ });
} else {
throw new Error("Invalid method");
}
@@ -98,9 +103,9 @@ export default async function Page({
)}
- {totpError && (
+ {error && (