mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
119 lines
3.5 KiB
TypeScript
119 lines
3.5 KiB
TypeScript
import { registerAs } from '@nestjs/config';
|
|
|
|
export interface FaydaJwk {
|
|
kty: 'RSA';
|
|
use?: string;
|
|
kid?: string;
|
|
alg?: string;
|
|
n: string;
|
|
e: string;
|
|
d: string;
|
|
p?: string;
|
|
q?: string;
|
|
dp?: string;
|
|
dq?: string;
|
|
qi?: string;
|
|
}
|
|
|
|
export type FaydaPlatform = 'WEB' | 'MOBILE';
|
|
|
|
export interface FaydaConfig {
|
|
enabled: boolean;
|
|
clientId: string;
|
|
authorizationEndpoint: string;
|
|
tokenEndpoint: string;
|
|
userInfoEndpoint: string;
|
|
redirectUri: string;
|
|
privateJwk: FaydaJwk;
|
|
scope: string;
|
|
acrValues: string;
|
|
claimsLocales: string;
|
|
sessionTtlMinutes: number;
|
|
}
|
|
|
|
const REQUIRED_VARS = [
|
|
'FAYDA_CLIENT_ID',
|
|
'FAYDA_AUTHORIZATION_ENDPOINT',
|
|
'FAYDA_TOKEN_ENDPOINT',
|
|
'FAYDA_USERINFO_ENDPOINT',
|
|
'FAYDA_PRIVATE_KEY_BASE64',
|
|
] as const;
|
|
|
|
function decodePrivateJwk(base64: string): FaydaJwk {
|
|
let jwk: unknown;
|
|
try {
|
|
const json = Buffer.from(base64, 'base64').toString('utf8');
|
|
jwk = JSON.parse(json);
|
|
} catch (err) {
|
|
throw new Error(
|
|
`FAYDA_PRIVATE_KEY_BASE64 is not valid Base64-encoded JSON: ${(err as Error).message}`,
|
|
);
|
|
}
|
|
if (!jwk || typeof jwk !== 'object') {
|
|
throw new Error('FAYDA_PRIVATE_KEY_BASE64 must decode to a JSON object');
|
|
}
|
|
const candidate = jwk as Partial<FaydaJwk>;
|
|
if (candidate.kty !== 'RSA') {
|
|
throw new Error('FAYDA_PRIVATE_KEY_BASE64 JWK must have kty="RSA"');
|
|
}
|
|
if (!candidate.n || !candidate.e || !candidate.d) {
|
|
throw new Error(
|
|
'FAYDA_PRIVATE_KEY_BASE64 JWK is missing required RSA private-key fields (n, e, d)',
|
|
);
|
|
}
|
|
return candidate as FaydaJwk;
|
|
}
|
|
|
|
export default registerAs('fayda', (): FaydaConfig => {
|
|
const enabled = (process.env.FAYDA_ENABLED ?? 'false').toLowerCase() === 'true';
|
|
const scope = process.env.FAYDA_SCOPE ?? 'openid profile email';
|
|
const acrValues = process.env.FAYDA_ACR_VALUES ?? 'mosip:idp:acr:generated-code';
|
|
const claimsLocales = process.env.FAYDA_CLAIMS_LOCALES ?? 'en am';
|
|
const sessionTtl = Number.parseInt(process.env.FAYDA_SESSION_TTL_MINUTES ?? '10', 10);
|
|
const redirectUri = process.env.FAYDA_REDIRECT_URI ?? '';
|
|
if (!enabled) {
|
|
return {
|
|
enabled: false,
|
|
clientId: process.env.FAYDA_CLIENT_ID ?? '',
|
|
authorizationEndpoint: process.env.FAYDA_AUTHORIZATION_ENDPOINT ?? '',
|
|
tokenEndpoint: process.env.FAYDA_TOKEN_ENDPOINT ?? '',
|
|
userInfoEndpoint: process.env.FAYDA_USERINFO_ENDPOINT ?? '',
|
|
redirectUri,
|
|
privateJwk: { kty: 'RSA', n: '', e: '', d: '' },
|
|
scope,
|
|
acrValues,
|
|
claimsLocales,
|
|
sessionTtlMinutes: Number.isNaN(sessionTtl) || sessionTtl <= 0 ? 10 : sessionTtl,
|
|
};
|
|
}
|
|
|
|
const missing = REQUIRED_VARS.filter((name) => !process.env[name]);
|
|
if (missing.length > 0) {
|
|
throw new Error(
|
|
`Fayda integration is enabled (FAYDA_ENABLED=true) but the following env vars are missing: ${missing.join(', ')}`,
|
|
);
|
|
}
|
|
if (!redirectUri) {
|
|
throw new Error(
|
|
'Fayda integration is enabled but the redirect URI is missing: set FAYDA_REDIRECT_URI',
|
|
);
|
|
}
|
|
if (Number.isNaN(sessionTtl) || sessionTtl <= 0) {
|
|
throw new Error('FAYDA_SESSION_TTL_MINUTES must be a positive integer');
|
|
}
|
|
|
|
return {
|
|
enabled: true,
|
|
clientId: process.env.FAYDA_CLIENT_ID!,
|
|
authorizationEndpoint: process.env.FAYDA_AUTHORIZATION_ENDPOINT!,
|
|
tokenEndpoint: process.env.FAYDA_TOKEN_ENDPOINT!,
|
|
userInfoEndpoint: process.env.FAYDA_USERINFO_ENDPOINT!,
|
|
redirectUri,
|
|
privateJwk: decodePrivateJwk(process.env.FAYDA_PRIVATE_KEY_BASE64!),
|
|
scope,
|
|
acrValues,
|
|
claimsLocales,
|
|
sessionTtlMinutes: sessionTtl,
|
|
};
|
|
});
|