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 (