From 6877d364fc863d037b90f6bdadced96f1e124f85 Mon Sep 17 00:00:00 2001 From: Matt Jenkinson <75292329+mattdjenkinson@users.noreply.github.com> Date: Wed, 18 Mar 2026 17:20:09 +0000 Subject: [PATCH 1/2] chore: remove waitlist text and fix last used badge bug --- PR_SUMMARY.md | 95 +++++++++++++++++++ apps/login/locales/de.json | 9 +- apps/login/locales/en.json | 9 +- apps/login/locales/es.json | 9 +- apps/login/locales/it.json | 9 +- apps/login/locales/pl.json | 9 +- apps/login/locales/ru.json | 9 +- apps/login/locales/zh.json | 9 +- .../(boxed)/idp/[provider]/success/page.tsx | 5 + .../(illustration)/register/_login-btn.tsx | 6 -- .../(main)/(illustration)/register/page.tsx | 5 +- apps/login/src/components/idp-signin.tsx | 4 +- .../components/idps/pages/linking-success.tsx | 2 + .../components/idps/pages/login-success.tsx | 2 + apps/login/src/lib/server/idp.ts | 12 ++- apps/login/src/lib/server/register.ts | 4 + 16 files changed, 178 insertions(+), 20 deletions(-) create mode 100644 PR_SUMMARY.md diff --git a/PR_SUMMARY.md b/PR_SUMMARY.md new file mode 100644 index 0000000000..0cc9c1473c --- /dev/null +++ b/PR_SUMMARY.md @@ -0,0 +1,95 @@ +# PR Summary + +## Overview + +This PR introduces a "last used" badge for identity provider (IDP) login buttons, improves the registration/waitlist UI copy, and adds i18n support across all locale files. + +--- + +## Features + +### 1. Last Used Badge on IDP Buttons + +- **What**: A "Last used" badge appears on the identity provider (Google, Apple, GitHub, etc.) that the user last successfully signed in with. +- **Storage**: The last-used IDP ID is stored in an HTTP-only cookie (`last-used-idp-id`) with a 1-year expiry. +- **When it's set**: The cookie is **only** set when authentication completes successfully—not when the user merely clicks an IDP button. +- **Where it appears**: The badge is shown on IDP buttons across: + - Login name page + - IDP selection page + - Register page + - Authenticator setup page + - IDP link page + +**Technical details:** +- Cookie helpers: `setLastUsedIdpId()` and `getLastUsedIdpId()` in `lib/cookies.ts` +- Cookie is set in: + - `createNewSessionFromIdpIntent` (when returning redirect, including email verification and MFA flows) + - `registerUserAndLinkToIDP` (when registration with IDP linking succeeds) +- `idpId` is passed through the success flow: success page → `loginSuccess`/`linkingSuccess` → `IdpSignin` → `createNewSessionFromIdpIntent` +- `BaseButton` shows the badge when `isLastUsed` is true; custom props are destructured to avoid passing them to the DOM + +### 2. Registration / Waitlist UI Updates + +- **Register page**: Uses the new `waitlist` namespace with `title`, `subtitle`, and `description` for clearer hierarchy. +- **Login button**: Removed the waitlist question/info block from the register page footer. +- **Layout**: Title in `h3`, subtitle in `h1`, description in `p` for improved visual hierarchy. + +--- + +## Locale Updates + +All locale files (de, es, it, pl, ru, zh) were updated to match `en.json`: + +| Key | Description | +|-----|-------------| +| `loginname.register` | "Create account" (was "Register new user" etc.) | +| `waitlist.title` | "Welcome!" | +| `waitlist.subtitle` | "Let's get you started" | +| `waitlist.description` | "Create your free account with just a few details" | +| `register.alreadyRegistered` | "Already have an account?" | +| `register.loginNow` | "Log in here." | +| `idp.lastUsed` | "Last used" (for the IDP badge) | + +--- + +## Files Changed + +### Core Feature +- `apps/login/src/lib/cookies.ts` – Cookie helpers for last-used IDP +- `apps/login/src/components/idps/base-button.tsx` – Badge UI and prop handling +- `apps/login/src/components/sign-in-with-idp.tsx` – Pass `lastUsedIdpId` and `isLastUsed` +- `apps/login/src/components/idp-signin.tsx` – Pass `idpId` to session creation +- `apps/login/src/components/idps/pages/login-success.tsx` – Pass `idpId` to `IdpSignin` +- `apps/login/src/components/idps/pages/linking-success.tsx` – Pass `idpId` to `IdpSignin` +- `apps/login/src/lib/server/idp.ts` – Set cookie on success, pass `idpId` through flow +- `apps/login/src/lib/server/register.ts` – Set cookie on successful IDP registration +- `apps/login/src/app/(main)/(boxed)/idp/[provider]/success/page.tsx` – Pass `idpId` to success components + +### Pages Using SignInWithIdp (pass `lastUsedIdpId`) +- `apps/login/src/app/(main)/(illustration)/loginname/page.tsx` +- `apps/login/src/app/(main)/(boxed)/idp/page.tsx` +- `apps/login/src/app/(main)/(illustration)/register/page.tsx` +- `apps/login/src/app/(main)/(boxed)/authenticator/set/page.tsx` +- `apps/login/src/app/(main)/(boxed)/idp/link/page.tsx` + +### UI Updates +- `apps/login/src/app/(main)/(illustration)/register/page.tsx` – Waitlist title/subtitle/description +- `apps/login/src/app/(main)/(illustration)/register/_login-btn.tsx` – Removed waitlist block + +### Locales +- `apps/login/locales/de.json` +- `apps/login/locales/en.json` +- `apps/login/locales/es.json` +- `apps/login/locales/it.json` +- `apps/login/locales/pl.json` +- `apps/login/locales/ru.json` +- `apps/login/locales/zh.json` + +--- + +## Testing Notes + +- Verify the "Last used" badge appears on the correct IDP after a successful sign-in. +- Verify the badge does **not** appear when the user clicks an IDP but does not complete auth (e.g. cancels or fails). +- Verify translations render correctly for de, es, it, pl, ru, zh. +- Verify the register page shows the new waitlist copy and layout. diff --git a/apps/login/locales/de.json b/apps/login/locales/de.json index fc3e1557dd..30a8c12408 100644 --- a/apps/login/locales/de.json +++ b/apps/login/locales/de.json @@ -22,7 +22,7 @@ "loginname": { "title": "Willkommen zurück!", "description": "Geben Sie Ihre Anmeldedaten ein.", - "register": "Neuen Benutzer registrieren", + "register": "Konto erstellen", "submit": "Weiter" }, "password": { @@ -186,6 +186,8 @@ "title": "Registrierung fehlgeschlagen", "description": "Einige Daten fehlen. Bitte überprüfen Sie Ihre Eingaben." }, + "alreadyRegistered": "Bereits ein Konto?", + "loginNow": "Hier anmelden.", "title": "Registrieren", "description": "Erstellen Sie Ihr ZITADEL-Konto.", "noMethodAvailableWarning": "Keine Authentifizierungsmethode verfügbar. Bitte wenden Sie sich an den Administrator.", @@ -201,6 +203,11 @@ "submit": "Weiter" } }, + "waitlist": { + "title": "Willkommen!", + "subtitle": "Lass uns loslegen", + "description": "Erstellen Sie Ihr kostenloses Konto mit nur wenigen Angaben" + }, "invite": { "title": "Benutzer einladen", "description": "Geben Sie die E-Mail-Adresse des Benutzers ein, den Sie einladen möchten.", diff --git a/apps/login/locales/en.json b/apps/login/locales/en.json index 10fb7b7238..322b0eaa13 100644 --- a/apps/login/locales/en.json +++ b/apps/login/locales/en.json @@ -22,7 +22,7 @@ "loginname": { "title": "Welcome", "description": "Choose your login method:", - "register": "Request access", + "register": "Create account", "submit": "Continue", "notRegistered": "Not registered?", "termsOfService": "By continuing, you agree to Datum's Terms of Service and Privacy Policy, and to receive periodic emails with updates." @@ -188,7 +188,7 @@ "title": "Missing data", "description": "Provide email, first and last name to register." }, - "alreadyRegistered": "Have an invitation?", + "alreadyRegistered": "Already have an account?", "loginNow": "Log in here.", "onWaitListQuestion": "Still on the waitlist? ", "onWaitListInfo": "We'll email you when it's your turn!", @@ -208,8 +208,9 @@ } }, "waitlist": { - "title": "Get on the waitlist", - "description": "Choose how you’ll log in so you can access Datum as soon as the doors open - no extra setup needed." + "title": "Welcome!", + "subtitle": "Let's get you started", + "description": "Create your free account with just a few details" }, "invite": { "title": "Invite User", diff --git a/apps/login/locales/es.json b/apps/login/locales/es.json index 89e3150d6d..1c5693b946 100644 --- a/apps/login/locales/es.json +++ b/apps/login/locales/es.json @@ -22,7 +22,7 @@ "loginname": { "title": "¡Bienvenido de nuevo!", "description": "Introduce tus datos de acceso.", - "register": "Registrar nuevo usuario", + "register": "Crear cuenta", "submit": "Continuar" }, "password": { @@ -186,6 +186,8 @@ "title": "Datos faltantes", "description": "No se proporcionaron datos suficientes para el registro." }, + "alreadyRegistered": "¿Ya tienes una cuenta?", + "loginNow": "Inicia sesión aquí.", "title": "Registrarse", "description": "Crea tu cuenta ZITADEL.", "noMethodAvailableWarning": "No hay métodos de autenticación disponibles. Por favor, contacta a tu administrador.", @@ -201,6 +203,11 @@ "submit": "Continuar" } }, + "waitlist": { + "title": "¡Bienvenido!", + "subtitle": "Empecemos", + "description": "Crea tu cuenta gratuita con solo unos pocos detalles" + }, "invite": { "title": "Invitar usuario", "description": "Introduce el correo electrónico del usuario que deseas invitar.", diff --git a/apps/login/locales/it.json b/apps/login/locales/it.json index 7ef87fcae6..01d10f90d8 100644 --- a/apps/login/locales/it.json +++ b/apps/login/locales/it.json @@ -22,7 +22,7 @@ "loginname": { "title": "Bentornato!", "description": "Inserisci i tuoi dati di accesso.", - "register": "Registrati come nuovo utente", + "register": "Crea account", "submit": "Continua" }, "password": { @@ -186,6 +186,8 @@ "title": "Registrazione", "description": "Inserisci i tuoi dati per registrarti." }, + "alreadyRegistered": "Hai già un account?", + "loginNow": "Accedi qui.", "title": "Registrati", "description": "Crea il tuo account ZITADEL.", "noMethodAvailableWarning": "Nessun metodo di autenticazione disponibile. Contatta l'amministratore di sistema per assistenza.", @@ -201,6 +203,11 @@ "submit": "Continua" } }, + "waitlist": { + "title": "Benvenuto!", + "subtitle": "Iniziamo", + "description": "Crea il tuo account gratuito con pochi dettagli" + }, "invite": { "title": "Invita Utente", "description": "Inserisci l'indirizzo email dell'utente che desideri invitare.", diff --git a/apps/login/locales/pl.json b/apps/login/locales/pl.json index d917d6ee94..026fdf51e4 100644 --- a/apps/login/locales/pl.json +++ b/apps/login/locales/pl.json @@ -22,7 +22,7 @@ "loginname": { "title": "Witamy ponownie!", "description": "Wprowadź dane logowania.", - "register": "Zarejestruj nowego użytkownika", + "register": "Utwórz konto", "submit": "Kontynuuj" }, "password": { @@ -186,6 +186,8 @@ "title": "Brak danych", "description": "Podaj e-mail, imię i nazwisko, aby się zarejestrować." }, + "alreadyRegistered": "Masz już konto?", + "loginNow": "Zaloguj się tutaj.", "title": "Rejestracja", "description": "Utwórz konto ZITADEL.", "noMethodAvailableWarning": "Brak dostępnych metod uwierzytelniania. Skontaktuj się z administratorem.", @@ -201,6 +203,11 @@ "submit": "Kontynuuj" } }, + "waitlist": { + "title": "Witaj!", + "subtitle": "Zacznijmy", + "description": "Utwórz swoje darmowe konto za pomocą kilku informacji" + }, "invite": { "title": "Zaproś użytkownika", "description": "Podaj adres e-mail oraz imię i nazwisko użytkownika, którego chcesz zaprosić.", diff --git a/apps/login/locales/ru.json b/apps/login/locales/ru.json index b43f3e03fa..e1a49a0761 100644 --- a/apps/login/locales/ru.json +++ b/apps/login/locales/ru.json @@ -22,7 +22,7 @@ "loginname": { "title": "С возвращением!", "description": "Введите свои данные для входа.", - "register": "Зарегистрировать нового пользователя", + "register": "Создать аккаунт", "submit": "Продолжить" }, "password": { @@ -186,6 +186,8 @@ "title": "Недостаточно данных", "description": "Укажите email, имя и фамилию для регистрации." }, + "alreadyRegistered": "Уже есть аккаунт?", + "loginNow": "Войти здесь.", "title": "Регистрация", "description": "Создайте свой аккаунт ZITADEL.", "noMethodAvailableWarning": "Нет доступных методов аутентификации. Обратитесь к администратору.", @@ -201,6 +203,11 @@ "submit": "Продолжить" } }, + "waitlist": { + "title": "Добро пожаловать!", + "subtitle": "Давайте начнём", + "description": "Создайте бесплатную учётную запись всего за несколько шагов" + }, "invite": { "title": "Пригласить пользователя", "description": "Укажите email и имя пользователя для приглашения.", diff --git a/apps/login/locales/zh.json b/apps/login/locales/zh.json index e5391b2b6e..439b1d6ce6 100644 --- a/apps/login/locales/zh.json +++ b/apps/login/locales/zh.json @@ -22,7 +22,7 @@ "loginname": { "title": "欢迎回来!", "description": "请输入您的登录信息。", - "register": "注册新用户", + "register": "创建账户", "submit": "继续" }, "password": { @@ -186,6 +186,8 @@ "title": "缺少数据", "description": "请提供所有必需的数据。" }, + "alreadyRegistered": "已有账户?", + "loginNow": "在此登录。", "title": "注册", "description": "创建您的 ZITADEL 账户。", "noMethodAvailableWarning": "没有可用的认证方法。请联系您的系统管理员。", @@ -201,6 +203,11 @@ "submit": "继续" } }, + "waitlist": { + "title": "欢迎!", + "subtitle": "让我们开始吧", + "description": "只需几个细节即可创建您的免费账户" + }, "invite": { "title": "邀请用户", "description": "提供您想邀请的用户的电子邮箱地址和姓名。", diff --git a/apps/login/src/app/(main)/(boxed)/idp/[provider]/success/page.tsx b/apps/login/src/app/(main)/(boxed)/idp/[provider]/success/page.tsx index 880f9862f2..56abe81bb3 100644 --- a/apps/login/src/app/(main)/(boxed)/idp/[provider]/success/page.tsx +++ b/apps/login/src/app/(main)/(boxed)/idp/[provider]/success/page.tsx @@ -261,6 +261,7 @@ export default async function Page(props: { { idpIntentId: id, idpIntentToken: token }, requestId, onSuccessRedirectTo, + idpInformation.idpId, ); } @@ -328,6 +329,7 @@ export default async function Page(props: { { idpIntentId: id, idpIntentToken: token }, requestId, onSuccessRedirectTo, + idpInformation.idpId, ); } } @@ -383,6 +385,8 @@ export default async function Page(props: { foundUser.userId, { idpIntentId: id, idpIntentToken: token }, requestId, + undefined, + idpInformation.idpId, ); } } @@ -487,6 +491,7 @@ export default async function Page(props: { userId={newUser.userId} idpIntent={{ idpIntentId: id, idpIntentToken: token }} requestId={requestId} + idpId={idpInformation.idpId} /> ); diff --git a/apps/login/src/app/(main)/(illustration)/register/_login-btn.tsx b/apps/login/src/app/(main)/(illustration)/register/_login-btn.tsx index 67ae7b16c7..06e2c644ab 100644 --- a/apps/login/src/app/(main)/(illustration)/register/_login-btn.tsx +++ b/apps/login/src/app/(main)/(illustration)/register/_login-btn.tsx @@ -19,12 +19,6 @@ export const LoginBtn = () => { -
- - - - -
); }; diff --git a/apps/login/src/app/(main)/(illustration)/register/page.tsx b/apps/login/src/app/(main)/(illustration)/register/page.tsx index 1fd7ebe14b..6ce085c84c 100644 --- a/apps/login/src/app/(main)/(illustration)/register/page.tsx +++ b/apps/login/src/app/(main)/(illustration)/register/page.tsx @@ -60,8 +60,11 @@ export default async function Page(props: { return ( <> -

+

+

+

+

diff --git a/apps/login/src/components/idp-signin.tsx b/apps/login/src/components/idp-signin.tsx index c8f23fdbaa..4a2d72d0f1 100644 --- a/apps/login/src/components/idp-signin.tsx +++ b/apps/login/src/components/idp-signin.tsx @@ -8,13 +8,13 @@ import { Alert } from "./alert"; type Props = { userId: string; - // organization: string; idpIntent: { idpIntentId: string; idpIntentToken: string; }; requestId?: string; onSuccessRedirectTo?: string; + idpId?: string; }; export function IdpSignin({ @@ -22,6 +22,7 @@ export function IdpSignin({ idpIntent: { idpIntentId, idpIntentToken }, requestId, onSuccessRedirectTo, + idpId, }: Props) { const [isPending, startTransition] = useTransition(); const [error, setError] = useState(null); @@ -37,6 +38,7 @@ export function IdpSignin({ idpIntentToken, }, requestId, + idpId, }) .then((response) => { if (response && "error" in response && response?.error) { diff --git a/apps/login/src/components/idps/pages/linking-success.tsx b/apps/login/src/components/idps/pages/linking-success.tsx index 843c3fb16b..0568637956 100644 --- a/apps/login/src/components/idps/pages/linking-success.tsx +++ b/apps/login/src/components/idps/pages/linking-success.tsx @@ -6,6 +6,7 @@ export async function linkingSuccess( idpIntent: { idpIntentId: string; idpIntentToken: string }, requestId?: string, onSuccessRedirectTo?: string, + idpId?: string, ) { return ( <> @@ -21,6 +22,7 @@ export async function linkingSuccess( idpIntent={idpIntent} requestId={requestId} onSuccessRedirectTo={onSuccessRedirectTo} + idpId={idpId} /> ); diff --git a/apps/login/src/components/idps/pages/login-success.tsx b/apps/login/src/components/idps/pages/login-success.tsx index b3ab8579b5..dae394a103 100644 --- a/apps/login/src/components/idps/pages/login-success.tsx +++ b/apps/login/src/components/idps/pages/login-success.tsx @@ -6,6 +6,7 @@ export async function loginSuccess( idpIntent: { idpIntentId: string; idpIntentToken: string }, requestId?: string, onSuccessRedirectTo?: string, + idpId?: string, ) { return ( <> @@ -21,6 +22,7 @@ export async function loginSuccess( idpIntent={idpIntent} requestId={requestId} onSuccessRedirectTo={onSuccessRedirectTo} + idpId={idpId} /> ); diff --git a/apps/login/src/lib/server/idp.ts b/apps/login/src/lib/server/idp.ts index 9592ca9a22..f1dcb8da06 100644 --- a/apps/login/src/lib/server/idp.ts +++ b/apps/login/src/lib/server/idp.ts @@ -52,7 +52,6 @@ export async function redirectToIdp( // redirect to LDAP page where username and password is requested if (provider === "ldap") { - await setLastUsedIdpId(idpId); params.set("idpId", idpId); redirect(`/idp/ldap?` + params.toString()); } @@ -70,7 +69,6 @@ export async function redirectToIdp( } if (response && "redirect" in response && response?.redirect) { - await setLastUsedIdpId(idpId); redirect(response.redirect); } @@ -114,6 +112,7 @@ type CreateNewSessionCommand = { password?: string; organization?: string; requestId?: string; + idpId?: string; }; export async function createNewSessionFromIdpIntent( @@ -171,6 +170,9 @@ export async function createNewSessionFromIdpIntent( ); if (emailVerificationCheck?.redirect) { + if (command.idpId) { + await setLastUsedIdpId(command.idpId); + } return emailVerificationCheck; } @@ -197,6 +199,9 @@ export async function createNewSessionFromIdpIntent( command.requestId, ); if (mfaFactorCheck?.redirect) { + if (command.idpId) { + await setLastUsedIdpId(command.idpId); + } return mfaFactorCheck; } @@ -215,6 +220,9 @@ export async function createNewSessionFromIdpIntent( ); if (url) { + if (command.idpId) { + await setLastUsedIdpId(command.idpId); + } return { redirect: url }; } } diff --git a/apps/login/src/lib/server/register.ts b/apps/login/src/lib/server/register.ts index f84b4c8d51..1824a54ecb 100644 --- a/apps/login/src/lib/server/register.ts +++ b/apps/login/src/lib/server/register.ts @@ -1,5 +1,6 @@ "use server"; +import { setLastUsedIdpId } from "@/lib/cookies"; import { createSessionAndUpdateCookie, createSessionForIdpAndUpdateCookie, @@ -229,5 +230,8 @@ export async function registerUserAndLinkToIDP( loginSettings?.defaultRedirectUri, ); + if (url) { + await setLastUsedIdpId(command.idpId); + } return { redirect: url }; } From c000aa408fa0a853d7d519b443e615c4da803d57 Mon Sep 17 00:00:00 2001 From: Matt Jenkinson <75292329+mattdjenkinson@users.noreply.github.com> Date: Wed, 18 Mar 2026 17:23:07 +0000 Subject: [PATCH 2/2] remove pr summary --- PR_SUMMARY.md | 95 --------------------------------------------------- 1 file changed, 95 deletions(-) delete mode 100644 PR_SUMMARY.md diff --git a/PR_SUMMARY.md b/PR_SUMMARY.md deleted file mode 100644 index 0cc9c1473c..0000000000 --- a/PR_SUMMARY.md +++ /dev/null @@ -1,95 +0,0 @@ -# PR Summary - -## Overview - -This PR introduces a "last used" badge for identity provider (IDP) login buttons, improves the registration/waitlist UI copy, and adds i18n support across all locale files. - ---- - -## Features - -### 1. Last Used Badge on IDP Buttons - -- **What**: A "Last used" badge appears on the identity provider (Google, Apple, GitHub, etc.) that the user last successfully signed in with. -- **Storage**: The last-used IDP ID is stored in an HTTP-only cookie (`last-used-idp-id`) with a 1-year expiry. -- **When it's set**: The cookie is **only** set when authentication completes successfully—not when the user merely clicks an IDP button. -- **Where it appears**: The badge is shown on IDP buttons across: - - Login name page - - IDP selection page - - Register page - - Authenticator setup page - - IDP link page - -**Technical details:** -- Cookie helpers: `setLastUsedIdpId()` and `getLastUsedIdpId()` in `lib/cookies.ts` -- Cookie is set in: - - `createNewSessionFromIdpIntent` (when returning redirect, including email verification and MFA flows) - - `registerUserAndLinkToIDP` (when registration with IDP linking succeeds) -- `idpId` is passed through the success flow: success page → `loginSuccess`/`linkingSuccess` → `IdpSignin` → `createNewSessionFromIdpIntent` -- `BaseButton` shows the badge when `isLastUsed` is true; custom props are destructured to avoid passing them to the DOM - -### 2. Registration / Waitlist UI Updates - -- **Register page**: Uses the new `waitlist` namespace with `title`, `subtitle`, and `description` for clearer hierarchy. -- **Login button**: Removed the waitlist question/info block from the register page footer. -- **Layout**: Title in `h3`, subtitle in `h1`, description in `p` for improved visual hierarchy. - ---- - -## Locale Updates - -All locale files (de, es, it, pl, ru, zh) were updated to match `en.json`: - -| Key | Description | -|-----|-------------| -| `loginname.register` | "Create account" (was "Register new user" etc.) | -| `waitlist.title` | "Welcome!" | -| `waitlist.subtitle` | "Let's get you started" | -| `waitlist.description` | "Create your free account with just a few details" | -| `register.alreadyRegistered` | "Already have an account?" | -| `register.loginNow` | "Log in here." | -| `idp.lastUsed` | "Last used" (for the IDP badge) | - ---- - -## Files Changed - -### Core Feature -- `apps/login/src/lib/cookies.ts` – Cookie helpers for last-used IDP -- `apps/login/src/components/idps/base-button.tsx` – Badge UI and prop handling -- `apps/login/src/components/sign-in-with-idp.tsx` – Pass `lastUsedIdpId` and `isLastUsed` -- `apps/login/src/components/idp-signin.tsx` – Pass `idpId` to session creation -- `apps/login/src/components/idps/pages/login-success.tsx` – Pass `idpId` to `IdpSignin` -- `apps/login/src/components/idps/pages/linking-success.tsx` – Pass `idpId` to `IdpSignin` -- `apps/login/src/lib/server/idp.ts` – Set cookie on success, pass `idpId` through flow -- `apps/login/src/lib/server/register.ts` – Set cookie on successful IDP registration -- `apps/login/src/app/(main)/(boxed)/idp/[provider]/success/page.tsx` – Pass `idpId` to success components - -### Pages Using SignInWithIdp (pass `lastUsedIdpId`) -- `apps/login/src/app/(main)/(illustration)/loginname/page.tsx` -- `apps/login/src/app/(main)/(boxed)/idp/page.tsx` -- `apps/login/src/app/(main)/(illustration)/register/page.tsx` -- `apps/login/src/app/(main)/(boxed)/authenticator/set/page.tsx` -- `apps/login/src/app/(main)/(boxed)/idp/link/page.tsx` - -### UI Updates -- `apps/login/src/app/(main)/(illustration)/register/page.tsx` – Waitlist title/subtitle/description -- `apps/login/src/app/(main)/(illustration)/register/_login-btn.tsx` – Removed waitlist block - -### Locales -- `apps/login/locales/de.json` -- `apps/login/locales/en.json` -- `apps/login/locales/es.json` -- `apps/login/locales/it.json` -- `apps/login/locales/pl.json` -- `apps/login/locales/ru.json` -- `apps/login/locales/zh.json` - ---- - -## Testing Notes - -- Verify the "Last used" badge appears on the correct IDP after a successful sign-in. -- Verify the badge does **not** appear when the user clicks an IDP but does not complete auth (e.g. cancels or fails). -- Verify translations render correctly for de, es, it, pl, ru, zh. -- Verify the register page shows the new waitlist copy and layout.