Files
edr-platform/apps/edr-freight-web/backoffice/src/shared/utils/faydaOidc.ts
2026-07-10 10:41:48 +03:00

126 lines
4.1 KiB
TypeScript

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;
}