chore: migrate oauth to repo (#13211)

This commit is contained in:
Daniel Dietzler
2024-10-05 22:37:33 +02:00
committed by GitHub
parent 9d9bf1c88d
commit a5e9adb593
8 changed files with 171 additions and 121 deletions

View File

@@ -0,0 +1,73 @@
import { Inject, Injectable, InternalServerErrorException } from '@nestjs/common';
import { custom, generators, Issuer } from 'openid-client';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { IOAuthRepository, OAuthConfig, OAuthProfile } from 'src/interfaces/oauth.interface';
import { Instrumentation } from 'src/utils/instrumentation';
@Instrumentation()
@Injectable()
export class OAuthRepository implements IOAuthRepository {
constructor(@Inject(ILoggerRepository) private logger: ILoggerRepository) {
this.logger.setContext(OAuthRepository.name);
}
init() {
custom.setHttpOptionsDefaults({ timeout: 30_000 });
}
async authorize(config: OAuthConfig, redirectUrl: string) {
const client = await this.getClient(config);
return client.authorizationUrl({
redirect_uri: redirectUrl,
scope: config.scope,
state: generators.state(),
});
}
async getLogoutEndpoint(config: OAuthConfig) {
const client = await this.getClient(config);
return client.issuer.metadata.end_session_endpoint;
}
async getProfile(config: OAuthConfig, url: string, redirectUrl: string): Promise<OAuthProfile> {
const client = await this.getClient(config);
const params = client.callbackParams(url);
try {
const tokens = await client.callback(redirectUrl, params, { state: params.state });
return await client.userinfo<OAuthProfile>(tokens.access_token || '');
} catch (error: Error | any) {
if (error.message.includes('unexpected JWT alg received')) {
this.logger.warn(
[
'Algorithm mismatch. Make sure the signing algorithm is set correctly in the OAuth settings.',
'Or, that you have specified a signing key in your OAuth provider.',
].join(' '),
);
}
throw error;
}
}
private async getClient({
issuerUrl,
clientId,
clientSecret,
profileSigningAlgorithm,
signingAlgorithm,
}: OAuthConfig) {
try {
const issuer = await Issuer.discover(issuerUrl);
return new issuer.Client({
client_id: clientId,
client_secret: clientSecret,
response_types: ['code'],
userinfo_signed_response_alg: profileSigningAlgorithm === 'none' ? undefined : profileSigningAlgorithm,
id_token_signed_response_alg: signingAlgorithm,
});
} catch (error: any | AggregateError) {
this.logger.error(`Error in OAuth discovery: ${error}`, error?.stack, error?.errors);
throw new InternalServerErrorException(`Error in OAuth discovery: ${error}`, { cause: error });
}
}
}