From e1a53b12738a00fe6017225fb97575b339895f70 Mon Sep 17 00:00:00 2001 From: Matt Jenkinson <75292329+mattdjenkinson@users.noreply.github.com> Date: Tue, 17 Mar 2026 17:18:00 +0000 Subject: [PATCH 1/2] add support for last used login and fix dark mode accounts text --- apps/login/locales/de.json | 1 + apps/login/locales/en.json | 1 + apps/login/locales/es.json | 1 + apps/login/locales/it.json | 1 + apps/login/locales/pl.json | 1 + apps/login/locales/ru.json | 1 + apps/login/locales/zh.json | 1 + apps/login/next-env.d.ts | 2 +- .../src/app/(main)/(boxed)/accounts/page.tsx | 2 +- .../(main)/(boxed)/authenticator/set/page.tsx | 5 ++++- .../src/app/(main)/(boxed)/idp/link/page.tsx | 6 ++++- .../login/src/app/(main)/(boxed)/idp/page.tsx | 4 ++++ .../(main)/(illustration)/loginname/page.tsx | 4 ++++ .../(main)/(illustration)/register/page.tsx | 4 ++++ .../login/src/components/idps/base-button.tsx | 20 ++++++++++++++--- apps/login/src/components/session-item.tsx | 6 ++--- .../login/src/components/sign-in-with-idp.tsx | 4 +++- apps/login/src/lib/cookies.ts | 22 +++++++++++++++++++ apps/login/src/lib/server/idp.ts | 4 +++- 19 files changed, 78 insertions(+), 12 deletions(-) diff --git a/apps/login/locales/de.json b/apps/login/locales/de.json index 4dd557eedd..fc3e1557dd 100644 --- a/apps/login/locales/de.json +++ b/apps/login/locales/de.json @@ -55,6 +55,7 @@ "signInWithAzureAD": "Mit AzureAD anmelden", "signInWithGithub": "Mit GitHub anmelden", "signInWithGitlab": "Mit GitLab anmelden", + "lastUsed": "Zuletzt verwendet", "loginSuccess": { "title": "Anmeldung erfolgreich", "description": "Sie haben sich erfolgreich angemeldet!" diff --git a/apps/login/locales/en.json b/apps/login/locales/en.json index 3e934ea90c..10fb7b7238 100644 --- a/apps/login/locales/en.json +++ b/apps/login/locales/en.json @@ -57,6 +57,7 @@ "signInWithAzureAD": "Sign in with AzureAD", "signInWithGithub": "Sign in with GitHub", "signInWithGitlab": "Sign in with GitLab", + "lastUsed": "Last used", "loginSuccess": { "title": "Sign in confirmed", "description": "Directing you to your account" diff --git a/apps/login/locales/es.json b/apps/login/locales/es.json index 79cc78b4dd..89e3150d6d 100644 --- a/apps/login/locales/es.json +++ b/apps/login/locales/es.json @@ -55,6 +55,7 @@ "signInWithAzureAD": "Iniciar sesión con AzureAD", "signInWithGithub": "Iniciar sesión con GitHub", "signInWithGitlab": "Iniciar sesión con GitLab", + "lastUsed": "Usado recientemente", "loginSuccess": { "title": "Inicio de sesión exitoso", "description": "¡Has iniciado sesión con éxito!" diff --git a/apps/login/locales/it.json b/apps/login/locales/it.json index 4aaf4d4f86..7ef87fcae6 100644 --- a/apps/login/locales/it.json +++ b/apps/login/locales/it.json @@ -55,6 +55,7 @@ "signInWithAzureAD": "Accedi con AzureAD", "signInWithGithub": "Accedi con GitHub", "signInWithGitlab": "Accedi con GitLab", + "lastUsed": "Usato di recente", "loginSuccess": { "title": "Accesso riuscito", "description": "Accesso effettuato con successo!" diff --git a/apps/login/locales/pl.json b/apps/login/locales/pl.json index 9133e73869..d917d6ee94 100644 --- a/apps/login/locales/pl.json +++ b/apps/login/locales/pl.json @@ -55,6 +55,7 @@ "signInWithAzureAD": "Zaloguj się przez AzureAD", "signInWithGithub": "Zaloguj się przez GitHub", "signInWithGitlab": "Zaloguj się przez GitLab", + "lastUsed": "Ostatnio używane", "loginSuccess": { "title": "Logowanie udane", "description": "Zostałeś pomyślnie zalogowany!" diff --git a/apps/login/locales/ru.json b/apps/login/locales/ru.json index f3ffb0330b..b43f3e03fa 100644 --- a/apps/login/locales/ru.json +++ b/apps/login/locales/ru.json @@ -55,6 +55,7 @@ "signInWithAzureAD": "Войти через AzureAD", "signInWithGithub": "Войти через GitHub", "signInWithGitlab": "Войти через GitLab", + "lastUsed": "Использован последним", "loginSuccess": { "title": "Вход выполнен успешно", "description": "Вы успешно вошли в систему!" diff --git a/apps/login/locales/zh.json b/apps/login/locales/zh.json index 9c9fe953b1..e5391b2b6e 100644 --- a/apps/login/locales/zh.json +++ b/apps/login/locales/zh.json @@ -55,6 +55,7 @@ "signInWithAzureAD": "用 AzureAD 登录", "signInWithGithub": "用 GitHub 登录", "signInWithGitlab": "用 GitLab 登录", + "lastUsed": "上次使用", "loginSuccess": { "title": "登录成功", "description": "您已成功登录!" diff --git a/apps/login/next-env.d.ts b/apps/login/next-env.d.ts index 9edff1c7ca..c4b7818fbb 100755 --- a/apps/login/next-env.d.ts +++ b/apps/login/next-env.d.ts @@ -1,6 +1,6 @@ /// /// -import "./.next/types/routes.d.ts"; +import "./.next/dev/types/routes.d.ts"; // NOTE: This file should not be edited // see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/apps/login/src/app/(main)/(boxed)/accounts/page.tsx b/apps/login/src/app/(main)/(boxed)/accounts/page.tsx index 3c8269cbaa..6c4ae9c16f 100644 --- a/apps/login/src/app/(main)/(boxed)/accounts/page.tsx +++ b/apps/login/src/app/(main)/(boxed)/accounts/page.tsx @@ -86,7 +86,7 @@ export default async function Page(props: {
0 ? "" : "justify-center", )} > diff --git a/apps/login/src/app/(main)/(boxed)/authenticator/set/page.tsx b/apps/login/src/app/(main)/(boxed)/authenticator/set/page.tsx index b4c4ed41ad..4046dc2bdb 100644 --- a/apps/login/src/app/(main)/(boxed)/authenticator/set/page.tsx +++ b/apps/login/src/app/(main)/(boxed)/authenticator/set/page.tsx @@ -5,7 +5,7 @@ import { ChooseAuthenticatorToSetup } from "@/components/choose-authenticator-to import { SignInWithIdp } from "@/components/sign-in-with-idp"; import { Translated } from "@/components/translated"; import { UserAvatar } from "@/components/user-avatar"; -import { getSessionCookieById } from "@/lib/cookies"; +import { getLastUsedIdpId, getSessionCookieById } from "@/lib/cookies"; import { generateRouteMetadata } from "@/lib/metadata"; import { getServiceUrlFromHeaders } from "@/lib/service-url"; import { loadMostRecentSession } from "@/lib/session"; @@ -146,6 +146,8 @@ export default async function Page(props: { return resp.identityProviders; }); + const lastUsedIdpId = await getLastUsedIdpId(); + const params = new URLSearchParams({ initial: "true", // defines that a code is not required and is therefore not shown in the UI }); @@ -200,6 +202,7 @@ export default async function Page(props: { requestId={requestId} organization={sessionWithData.factors?.user?.organizationId} linkOnly={true} // tell the callback function to just link the IDP and not login, to get an error when user is already available + lastUsedIdpId={lastUsedIdpId} > )} diff --git a/apps/login/src/app/(main)/(boxed)/idp/link/page.tsx b/apps/login/src/app/(main)/(boxed)/idp/link/page.tsx index bfe8b8d4ff..980f899856 100644 --- a/apps/login/src/app/(main)/(boxed)/idp/link/page.tsx +++ b/apps/login/src/app/(main)/(boxed)/idp/link/page.tsx @@ -1,6 +1,6 @@ import { SignInWithIdp } from "@/components/sign-in-with-idp"; import { Translated } from "@/components/translated"; -import { getMostRecentSessionCookie } from "@/lib/cookies"; +import { getLastUsedIdpId, getMostRecentSessionCookie } from "@/lib/cookies"; import { idpTypeToSlug } from "@/lib/idp"; import { generateRouteMetadata } from "@/lib/metadata"; import { redirectToIdp } from "@/lib/server/idp"; @@ -63,6 +63,8 @@ export default async function Page(props: { userLoginName = session?.factors?.user?.loginName; } catch {} + const lastUsedIdpId = await getLastUsedIdpId(); + // If not logged in, prompt user to sign-in with the chosen provider if (!userId) { let providersToShow = activeIdentityProviders; @@ -94,6 +96,7 @@ export default async function Page(props: { requestId={requestId} organization={organization} preventCreation={true} // prevent account creation in case they login with a wrong account + lastUsedIdpId={lastUsedIdpId} onSuccessRedirectTo={(() => { // redirect back to the link page with all the params const params = new URLSearchParams(); @@ -183,6 +186,7 @@ export default async function Page(props: { linkOnly={true} userId={userId} onSuccessRedirectTo={"/idp/link"} + lastUsedIdpId={lastUsedIdpId} /> ) : ( diff --git a/apps/login/src/app/(main)/(boxed)/idp/page.tsx b/apps/login/src/app/(main)/(boxed)/idp/page.tsx index 443af1ecc8..d64c8e97ff 100644 --- a/apps/login/src/app/(main)/(boxed)/idp/page.tsx +++ b/apps/login/src/app/(main)/(boxed)/idp/page.tsx @@ -1,5 +1,6 @@ import { SignInWithIdp } from "@/components/sign-in-with-idp"; import { Translated } from "@/components/translated"; +import { getLastUsedIdpId } from "@/lib/cookies"; import { generateRouteMetadata } from "@/lib/metadata"; import { getServiceUrlFromHeaders } from "@/lib/service-url"; import { getActiveIdentityProviders } from "@/lib/zitadel"; @@ -25,6 +26,8 @@ export default async function Page(props: { return resp.identityProviders; }); + const lastUsedIdpId = await getLastUsedIdpId(); + return ( <>

@@ -39,6 +42,7 @@ export default async function Page(props: { identityProviders={identityProviders} requestId={requestId} organization={organization} + lastUsedIdpId={lastUsedIdpId} > )} diff --git a/apps/login/src/app/(main)/(illustration)/loginname/page.tsx b/apps/login/src/app/(main)/(illustration)/loginname/page.tsx index dede494a4a..425e9a274b 100644 --- a/apps/login/src/app/(main)/(illustration)/loginname/page.tsx +++ b/apps/login/src/app/(main)/(illustration)/loginname/page.tsx @@ -1,5 +1,6 @@ import { SignInWithIdp } from "@/components/sign-in-with-idp"; import { Translated } from "@/components/translated"; +import { getLastUsedIdpId } from "@/lib/cookies"; import { UsernameForm } from "@/components/username-form"; import { generateRouteMetadata } from "@/lib/metadata"; import { getServiceUrlFromHeaders } from "@/lib/service-url"; @@ -56,6 +57,8 @@ export default async function Page(props: { return resp.identityProviders; }); + const lastUsedIdpId = await getLastUsedIdpId(); + return ( <>

@@ -89,6 +92,7 @@ export default async function Page(props: { identityProviders={identityProviders} requestId={requestId} organization={organization} + lastUsedIdpId={lastUsedIdpId} > )} diff --git a/apps/login/src/app/(main)/(illustration)/register/page.tsx b/apps/login/src/app/(main)/(illustration)/register/page.tsx index e8b92eebb9..1fd7ebe14b 100644 --- a/apps/login/src/app/(main)/(illustration)/register/page.tsx +++ b/apps/login/src/app/(main)/(illustration)/register/page.tsx @@ -2,6 +2,7 @@ import { Alert } from "@/components/alert"; import { RegisterForm } from "@/components/register-form"; import { SignInWithIdp } from "@/components/sign-in-with-idp"; import { Translated } from "@/components/translated"; +import { getLastUsedIdpId } from "@/lib/cookies"; import { generateRouteMetadata } from "@/lib/metadata"; import { getServiceUrlFromHeaders } from "@/lib/service-url"; import { @@ -55,6 +56,8 @@ export default async function Page(props: { }); }); + const lastUsedIdpId = await getLastUsedIdpId(); + return ( <>

@@ -100,6 +103,7 @@ export default async function Page(props: { identityProviders={identityProviders} requestId={requestId} organization={organization} + lastUsedIdpId={lastUsedIdpId} > )} diff --git a/apps/login/src/components/idps/base-button.tsx b/apps/login/src/components/idps/base-button.tsx index 49feaf0044..bd866f31c3 100644 --- a/apps/login/src/components/idps/base-button.tsx +++ b/apps/login/src/components/idps/base-button.tsx @@ -4,6 +4,7 @@ import { clsx } from "clsx"; import { Loader2 } from "lucide-react"; import { ButtonHTMLAttributes, DetailedHTMLProps, forwardRef } from "react"; import { useFormStatus } from "react-dom"; +import { Translated } from "../translated"; export type SignInWithIdentityProviderProps = DetailedHTMLProps< ButtonHTMLAttributes, @@ -12,6 +13,7 @@ export type SignInWithIdentityProviderProps = DetailedHTMLProps< name?: string; e2e?: string; containerclassname?: string; + isLastUsed?: boolean; }; export const BaseButton = forwardRef< @@ -19,10 +21,17 @@ export const BaseButton = forwardRef< SignInWithIdentityProviderProps >(function BaseButton(props, ref) { const formStatus = useFormStatus(); + const { + isLastUsed, + containerclassname, + e2e, + ...buttonProps + } = props; return (