26 lines
1.5 KiB
TypeScript
26 lines
1.5 KiB
TypeScript
import { createLocalJWKSet, jwtVerify } from 'jose';
|
|
import { configuration, requireLiveConfig } from '../src/lib/server/config';
|
|
import { applicationJwt, TokenCipher } from '../src/lib/server/security';
|
|
|
|
let stage = 'required live settings';
|
|
try {
|
|
const config = configuration();
|
|
requireLiveConfig(config);
|
|
stage = 'encryption-key round trip';
|
|
const cipher = new TokenCipher(config.encryptionKey);
|
|
const encrypted = await cipher.seal({ sentinel: true }, 'configuration-check');
|
|
const decrypted = await cipher.open<{ sentinel: boolean }>(encrypted, 'configuration-check');
|
|
if (decrypted.sentinel !== true) throw new Error();
|
|
stage = 'application signing key / public JWKS match';
|
|
const jwksValue = process.env.APP_AUTH_JWKS ?? '';
|
|
const prefix = 'data:application/json;base64,';
|
|
if (!jwksValue.startsWith(prefix)) throw new Error();
|
|
const jwks = createLocalJWKSet(JSON.parse(Buffer.from(jwksValue.slice(prefix.length), 'base64').toString('utf8')));
|
|
const jwt = await applicationJwt({ userId: 'configuration-check', sessionId: 'configuration-check', issuer: config.issuer, privateKey: config.privateKey });
|
|
await jwtVerify(jwt, jwks, { issuer: config.issuer, audience: 'eve-intelligence', algorithms: ['RS256'] });
|
|
console.log('Live configuration passed: required settings, encryption round trip, and matching application JWT keys. No secret values displayed.');
|
|
} catch {
|
|
console.error(`Live configuration failed at: ${stage}. Values and raw errors suppressed.`);
|
|
process.exitCode = 1;
|
|
}
|