import { useSearchParams } from "react-router";
import { EditorialMessage } from "@/client/components/editorial-message";
interface ErrorExplanation {
title: string;
body: string;
hint?: string;
}
const explainError = (code: string | null): ErrorExplanation => {
switch (code) {
case "state_mismatch":
case "invalid_state":
return {
title: "The state didn't match.",
body: "The authentication response carried a different state than the one we set when you started. This usually means the request took too long to complete, you opened the callback in a different browser, or a third party tampered with the redirect.",
hint: "Start over from the sign-in page. If it keeps happening, clear cookies for this site and try again.",
};
case "account_not_linked":
case "social_account_not_linked":
case "signup_disabled":
case "user_not_found":
return {
title: "That identity isn't linked.",
body: "tessera is invite-only and won't create a new account from a GitHub or Google sign-in. The email returned by the provider is not associated with any tessera user.",
hint: "If you already have a tessera account, sign in with email and password first, then link the social provider from your account page.",
};
case "callback_url_mismatch":
case "invalid_redirect_uri":
return {
title: "The redirect URI is unregistered.",
body: "The provider returned the callback to a URL that isn't on the registered list for this OAuth client.",
hint: "If you're the operator, register the URL via the admin clients page (or update the OAuth app on the provider's side to use one that is registered).",
};
case "invalid_token":
case "expired_token":
return {
title: "The token is no longer valid.",
body: "The credential or code you presented has expired or has already been used. Codes from /authorize are single-use and short-lived.",
hint: "Start over from the sign-in page.",
};
case "rate_limited":
return {
title: "Too many attempts.",
body: "You hit the per-IP rate limit for this endpoint. tessera throttles sign-in and invite acceptance to slow brute-force attempts.",
hint: "Wait a minute and try again.",
};
default:
return {
title: "We couldn't admit you.",
body: "tessera received an authentication response that didn't validate. The original sign-in request may have expired, or the upstream provider returned an error we don't recognize.",
hint: "Start over from the sign-in page.",
};
}
};
export const AuthErrorPage = () => {
const [params] = useSearchParams();
const code = params.get("error");
const description = params.get("error_description");
const explanation = explainError(code);
return (
<>