export interface FaydaOidcOptions { redirectUri?: string; state?: string; nonce?: string; } /** PKCE code_verifier matching DEFAULT_CODE_CHALLENGE (S256). */ export const FAYDA_CODE_VERIFIER = "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"; const DEFAULT_CODE_CHALLENGE = "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM"; const DEFAULT_NONCE = "g4DEuje5Fx57Vb64dO4oqLHXGT8L8G7g"; const DEFAULT_STATE = "ptOO76SD"; /** OIDC state value that routes the shared /callback to the complaint flow (legacy sign-in). */ export const COMPLAINT_FLOW_STATE = "complaint_flow"; /** Complaint flow OIDC states — distinguish sign-in vs sign-up endpoints. */ export const COMPLAINT_SIGNIN_STATE = "complaint_signin"; export const COMPLAINT_SIGNUP_STATE = "complaint_signup"; export function isComplaintFaydaState(state: string | null): boolean { return ( state === COMPLAINT_FLOW_STATE || state === COMPLAINT_SIGNIN_STATE || state === COMPLAINT_SIGNUP_STATE ); } export function resolveComplaintAuthMode( state: string | null, ): "signin" | "signup" { if (state === COMPLAINT_SIGNUP_STATE) { return "signup"; } return "signin"; } /** OIDC state for unified external-portal Fayda auth (sign-in or sign-up). */ export const EXTERNAL_PORTAL_CONTINUE_STATE = "external_continue"; /** @deprecated Legacy sign-in state — still accepted on callback. */ export const EXTERNAL_PORTAL_SIGNIN_STATE = "external_signin"; /** @deprecated Legacy sign-up state — still accepted on callback. */ export const EXTERNAL_PORTAL_SIGNUP_STATE = "external_signup"; export function isExternalPortalFaydaState(state: string | null): boolean { return ( state === EXTERNAL_PORTAL_CONTINUE_STATE || state === EXTERNAL_PORTAL_SIGNIN_STATE || state === EXTERNAL_PORTAL_SIGNUP_STATE ); } export function startExternalPortalFaydaAuth(): void { const authUrl = generateFaydaAuthorizationUrl({ state: EXTERNAL_PORTAL_CONTINUE_STATE, }); window.location.href = authUrl; } /** * Builds the FAYDA/MOSIP OIDC authorization URL. * Shared by external-portal registration and anonymous complaint flows. */ export function generateFaydaAuthorizationUrl( options: FaydaOidcOptions = {}, ): string { const redirectUri = options.redirectUri || getDefaultFaydaRedirectUri(); const params = new URLSearchParams({ client_id: import.meta.env.VITE_CLIENT_ID || "", redirect_uri: redirectUri, response_type: "code", scope: "openid profile email", acr_values: "mosip:idp:acr:generated-code mosip:idp:acr:linked-wallet mosip:idp:acr:biometrics", claims: '{"userinfo":{"individual_id":{"essential":true},"name":{"essential":true},"phone_number":{"essential":true},"email":{"essential":true},"picture":{"essential":true},"gender":{"essential":true},"birthdate":{"essential":true},"address":{"essential":true}},"id_token":{}}', claims_locales: "en am", code_challenge: DEFAULT_CODE_CHALLENGE, code_challenge_method: "S256", display: "page", nonce: options.nonce || DEFAULT_NONCE, state: options.state || DEFAULT_STATE, ui_locales: "en am", }); const endpoint = import.meta.env.VITE_AUTHORIZATION_ENDPOINT || ""; return `${endpoint}?${params.toString()}`; } /** * Returns the default redirect URI registered with FAYDA (external portal flow). */ export function getDefaultFaydaRedirectUri(): string { return ( import.meta.env.VITE_REDIRECT_URI || `${window.location.origin}/callback` ); } /** * Returns the redirect URI registered with FAYDA for the complaint flow. * * Must exactly match a URI whitelisted in the FAYDA OIDC client — we reuse * the same /callback path as external-portal registration and distinguish * flows via the `state` parameter (see COMPLAINT_FLOW_STATE). */ export function getComplaintFaydaRedirectUri(): string { return ( import.meta.env.VITE_COMPLAINT_REDIRECT_URI || getDefaultFaydaRedirectUri() ); } export function startComplaintFaydaAuth(): void { const authUrl = generateFaydaAuthorizationUrl({ redirectUri: getComplaintFaydaRedirectUri(), state: COMPLAINT_FLOW_STATE, }); window.location.href = authUrl; }