import { Inject, Injectable, OnModuleInit } from '@nestjs/common'; import { createRemoteJWKSet } from 'jose'; import type { JWTVerifyGetKey } from 'jose'; import { APP_ENVIRONMENT } from '../../configuration/src'; import type { AppEnvironment } from '../../configuration/src'; interface OidcDiscoveryDocument { jwks_uri: string; } @Injectable() export class OidcDiscoveryService implements OnModuleInit { private verificationKeySet: JWTVerifyGetKey | undefined; constructor( @Inject(APP_ENVIRONMENT) private readonly environment: AppEnvironment, ) {} async onModuleInit(): Promise { const issuer = this.environment.oidcIssuer.replace(/\/$/, ''); const response = await fetch(`${issuer}/.well-known/openid-configuration`); if (!response.ok) { throw new Error( `Failed to fetch OIDC discovery document: HTTP ${response.status}`, ); } const document = (await response.json()) as OidcDiscoveryDocument; this.verificationKeySet = createRemoteJWKSet(new URL(document.jwks_uri)); } getIssuer(): string { return this.environment.oidcIssuer; } getAudience(): string { return this.environment.oidcAudience; } getVerificationKeySet(): JWTVerifyGetKey { if (!this.verificationKeySet) { throw new Error('OIDC discovery has not completed yet'); } return this.verificationKeySet; } }