Files
zitadel/apps/login/src/components/idp-process-handler.tsx
T
2397247925 fix(login): improve contrast of IDP processing message (#12309)
# Which Problems Are Solved

This improves the contrast of the “Processing authentication...” message
shown while Login V2 processes the IDP authentication flow.

The previous style used text-gray-600 without a dark-mode variant. This
color is hard-coded in the component and is not affected by the branding
colors, so users may see low contrast depending on the active
theme/background.

This PR updates the message text to use a higher-contrast light/dark
color pair.

---------

Co-authored-by: Max Peintner <[email protected]>
Co-authored-by: Max Peintner <[email protected]>
2026-06-24 10:30:44 +00:00

113 lines
3.1 KiB
TypeScript

"use client";
import { processIDPCallback } from "@/lib/server/idp-intent";
import { useTranslations } from "next-intl";
import { useRouter } from "next/navigation";
import { useEffect, useRef, useState } from "react";
import { Alert } from "./alert";
import { AutoSubmitForm } from "./auto-submit-form";
import { Spinner } from "./spinner";
type Props = {
provider: string;
id: string;
token: string;
requestId?: string;
organization?: string;
link?: string;
sessionId?: string;
linkFingerprint?: string;
postErrorRedirectUrl?: string;
};
/**
* Client component that handles IDP callback processing.
* Must be client-side to allow cookie modifications via server actions.
*/
export function IdpProcessHandler({
provider,
id,
token,
requestId,
organization,
link,
sessionId,
linkFingerprint,
postErrorRedirectUrl,
}: Props) {
const t = useTranslations("idp");
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const [samlData, setSamlData] = useState<{ url: string; fields: Record<string, string> } | null>(null);
const executedRef = useRef(false);
const router = useRouter();
useEffect(() => {
// Prevent double execution in React Strict Mode
if (executedRef.current) {
return;
}
executedRef.current = true;
console.log("[IDP Process Handler] Starting IDP callback processing from client");
processIDPCallback({
provider,
id,
token,
requestId,
organization,
sessionId,
linkFingerprint,
postErrorRedirectUrl,
})
.then((result) => {
if (result.error) {
console.error("[IDP Process Handler] Error:", result.error);
setError(result.error);
setLoading(false);
return;
}
if (result.redirect) {
console.log("[IDP Process Handler] Redirecting to:", result.redirect);
router.push(result.redirect);
return;
}
if (result.samlData) {
console.log("[IDP Process Handler] Received samlData, rendering AutoSubmitForm");
setSamlData(result.samlData);
setLoading(false);
return;
}
setError(t("processing.noRedirect"));
setLoading(false);
})
.catch((err) => {
console.error("[IDP Process Handler] Unexpected error:", err);
setError(err instanceof Error ? err.message : t("processing.unexpectedError"));
setLoading(false);
});
}, [provider, id, token, requestId, organization, link, sessionId, linkFingerprint, postErrorRedirectUrl, router, t]);
return (
<div className="flex items-center justify-center">
{samlData && <AutoSubmitForm url={samlData.url} fields={samlData.fields} />}
{loading && (
<div className="flex flex-col items-center space-y-4">
<Spinner className="h-8 w-8" />
<p className="text-sm text-gray-700 dark:text-gray-300">{t("processing.message")}</p>
</div>
)}
{error && (
<div className="max-w-md py-4">
<Alert>{error}</Alert>
</div>
)}
</div>
);
}