From 9b55010a460ca812aed44dae678458030a1a50ab Mon Sep 17 00:00:00 2001 From: Tom Opdebeeck Date: Mon, 19 Jul 2021 17:16:17 +0200 Subject: [PATCH] fix: cleanup provider methods Signed-off-by: Tom Opdebeeck --- .../src/providers/gitlab/provider.ts | 108 ++++++++++-------- 1 file changed, 58 insertions(+), 50 deletions(-) diff --git a/plugins/auth-backend/src/providers/gitlab/provider.ts b/plugins/auth-backend/src/providers/gitlab/provider.ts index 25440dab75..d229165562 100644 --- a/plugins/auth-backend/src/providers/gitlab/provider.ts +++ b/plugins/auth-backend/src/providers/gitlab/provider.ts @@ -58,40 +58,16 @@ type PrivateInfo = { export type GitlabAuthProviderOptions = OAuthProviderOptions & { baseUrl: string; signInResolver?: SignInResolver; - authHandler: AuthHandler; + authHandler?: AuthHandler; tokenIssuer: TokenIssuer; catalogIdentityClient: CatalogIdentityClient; logger: Logger; }; -const extractUserId = (profile: ProfileInfo): string => { +export const extractGitLabUserId = (profile: ProfileInfo): string => { return profile.username || (profile.email?.split('@')[0] as string); }; -function transformResult(result: OAuthResult): OAuthResult { - const { fullProfile, ...authResult } = result; - - fullProfile.photos = [ - ...(fullProfile.photos ?? []), - ...((fullProfile as FullProfile).avatarUrl - ? [{ value: (fullProfile as FullProfile).avatarUrl as string }] - : []), - ]; - - const profile = makeProfileInfo(fullProfile); - - if (!profile.username && !profile.email) { - throw new Error('Profile contained no username or email'); - } - - fullProfile.id = extractUserId(profile); - - return { - ...authResult, - fullProfile, - }; -} - export const gitlabDefaultSignInResolver: SignInResolver = async ( info, ctx, @@ -102,7 +78,7 @@ export const gitlabDefaultSignInResolver: SignInResolver = async ( throw new Error('Profile contained no username or email'); } - const id = extractUserId(profile); + const id = extractGitLabUserId(profile); const token = await ctx.tokenIssuer.issueToken({ claims: { sub: id, ent: [`user:default/${id}`] }, @@ -111,6 +87,13 @@ export const gitlabDefaultSignInResolver: SignInResolver = async ( return { id, token }; }; +export const gitlabDefaultAuthHandler: AuthHandler = async ({ + fullProfile, + params, +}) => ({ + profile: makeProfileInfo(fullProfile, params.id_token), +}); + export class GitlabAuthProvider implements OAuthHandlers { private readonly _strategy: GitlabStrategy; private readonly signInResolver?: SignInResolver; @@ -120,11 +103,11 @@ export class GitlabAuthProvider implements OAuthHandlers { private readonly logger: Logger; constructor(options: GitlabAuthProviderOptions) { - this.signInResolver = options.signInResolver; - this.authHandler = options.authHandler; - this.tokenIssuer = options.tokenIssuer; - this.logger = options.logger; this.catalogIdentityClient = options.catalogIdentityClient; + this.logger = options.logger; + this.tokenIssuer = options.tokenIssuer; + this.authHandler = options.authHandler || gitlabDefaultAuthHandler; + this.signInResolver = this.createSignInResolverFn(options); this._strategy = new GitlabStrategy( { @@ -197,7 +180,8 @@ export class GitlabAuthProvider implements OAuthHandlers { } private async handleResult(result: OAuthResult): Promise { - const { profile } = await this.authHandler(transformResult(result)); + const transformedResult = this.transformResult(result); + const { profile } = await this.authHandler(transformedResult); const response: OAuthResponse = { providerInfo: { @@ -225,6 +209,46 @@ export class GitlabAuthProvider implements OAuthHandlers { return response; } + + private createSignInResolverFn({ + signInResolver, + catalogIdentityClient, + tokenIssuer, + logger, + }: GitlabAuthProviderOptions): SignInResolver { + const resolver = signInResolver || gitlabDefaultSignInResolver; + + return info => + resolver(info, { + catalogIdentityClient, + tokenIssuer, + logger, + }); + } + + private transformResult(result: OAuthResult): OAuthResult { + const { fullProfile, ...authResult } = result; + + fullProfile.photos = [ + ...(fullProfile.photos ?? []), + ...((fullProfile as FullProfile).avatarUrl + ? [{ value: (fullProfile as FullProfile).avatarUrl as string }] + : []), + ]; + + const profile = makeProfileInfo(fullProfile); + + if (!profile.username && !profile.email) { + throw new Error('Profile contained no username or email'); + } + + fullProfile.id = extractGitLabUserId(profile); + + return { + ...authResult, + fullProfile, + }; + } } export type GitlabProviderOptions = { @@ -271,29 +295,13 @@ export const createGitlabProvider = ( tokenIssuer, }); - const authHandler: AuthHandler = options?.authHandler - ? options.authHandler - : async ({ fullProfile, params }) => ({ - profile: makeProfileInfo(fullProfile, params.id_token), - }); - - const signInResolverFn = - options?.signIn?.resolver ?? gitlabDefaultSignInResolver; - - const signInResolver: SignInResolver = info => - signInResolverFn(info, { - catalogIdentityClient, - tokenIssuer, - logger, - }); - const provider = new GitlabAuthProvider({ clientId, clientSecret, callbackUrl, baseUrl, - authHandler, - signInResolver, + authHandler: options?.authHandler, + signInResolver: options?.signIn?.resolver, catalogIdentityClient, logger, tokenIssuer,