From 3e2de7417ba5710ab5e17bde5ede8652bbcb463d Mon Sep 17 00:00:00 2001 From: Natoandro Date: Tue, 23 Jan 2024 12:09:14 +0300 Subject: [PATCH] fix(oauth2-profiler): fix OAuth2 profiler params (#562) Pass the appropriate request URL and headers to the profiler resolver. #### Motivation and context It used the provider url instead of the (typegate) request URL, causing internal queries to fail. #### Migration notes _N/A_ ### Checklist - [x] The change come with new or modified tests - [x] Hard-to-understand functions have explanatory comments - [x] End-user documentation is updated to reflect the change --- typegate/src/services/auth/mod.ts | 2 +- typegate/src/services/auth/protocols/basic.ts | 2 +- .../src/services/auth/protocols/internal.ts | 2 +- typegate/src/services/auth/protocols/jwt.ts | 2 +- .../src/services/auth/protocols/oauth2.ts | 32 ++++++++++++++----- .../src/services/auth/protocols/protocol.ts | 2 +- 6 files changed, 29 insertions(+), 13 deletions(-) diff --git a/typegate/src/services/auth/mod.ts b/typegate/src/services/auth/mod.ts index 1e9240e262..5788f66274 100644 --- a/typegate/src/services/auth/mod.ts +++ b/typegate/src/services/auth/mod.ts @@ -97,7 +97,7 @@ export async function ensureJWT( const [context, nextAuth] = await auth.tokenMiddleware( token, - new URL(request.url), + request, ); if (nextAuth !== null) { // "" is valid as it signal to remove the token diff --git a/typegate/src/services/auth/protocols/basic.ts b/typegate/src/services/auth/protocols/basic.ts index ca70fece20..aad0ec2957 100644 --- a/typegate/src/services/auth/protocols/basic.ts +++ b/typegate/src/services/auth/protocols/basic.ts @@ -35,7 +35,7 @@ export class BasicAuth extends Protocol { tokenMiddleware( jwt: string, - _url: URL, + _request: Request, ): Promise<[Record, string | null]> { try { const [username, token] = b64decode(jwt).split( diff --git a/typegate/src/services/auth/protocols/internal.ts b/typegate/src/services/auth/protocols/internal.ts index 0df74806e4..90a321f4bf 100644 --- a/typegate/src/services/auth/protocols/internal.ts +++ b/typegate/src/services/auth/protocols/internal.ts @@ -24,7 +24,7 @@ export class InternalAuth extends Protocol { async tokenMiddleware( token: string, - _url: URL, + _request: Request, ): Promise<[Record, string | null]> { try { const claims = await verifyJWT(token); diff --git a/typegate/src/services/auth/protocols/jwt.ts b/typegate/src/services/auth/protocols/jwt.ts index 0adcd1bae2..9c17a872b3 100644 --- a/typegate/src/services/auth/protocols/jwt.ts +++ b/typegate/src/services/auth/protocols/jwt.ts @@ -47,7 +47,7 @@ export class JWTAuth extends Protocol { async tokenMiddleware( token: string, - _url: URL, + _request: Request, ): Promise<[Record, string | null]> { try { const claims = await jwt.verify(token, this.signKey); diff --git a/typegate/src/services/auth/protocols/oauth2.ts b/typegate/src/services/auth/protocols/oauth2.ts index ea34d4bda9..8808202790 100644 --- a/typegate/src/services/auth/protocols/oauth2.ts +++ b/typegate/src/services/auth/protocols/oauth2.ts @@ -55,7 +55,10 @@ class AuthProfiler { }); } - async transform(profile: any, url: string) { + async transform( + profile: any, + request: Request, + ) { const { tg, runtimeReferences } = this.authParameters; const funcNode = tg.type(this.funcIndex, Type.FUNCTION); const mat = tg.materializer(funcNode.materializer); @@ -63,7 +66,15 @@ class AuthProfiler { const validatorInputWeak = generateWeakValidator(tg, funcNode.input); const validatorOutput = generateValidator(tg, funcNode.output); - const input = { ...profile, _: { info: { url } } }; + const input = { + ...profile, + _: { + info: { + url: new URL(request.url), + headers: Object.fromEntries(request.headers.entries()), + }, + }, + }; validatorInputWeak(input); // Note: this assumes func is a simple t.func(inp, out, mat) @@ -154,7 +165,7 @@ export class OAuth2Auth extends Protocol { this.typegraphName, ); const tokens = await client.code.getToken(url, { state, codeVerifier }); - const token = await this.createJWT(tokens); + const token = await this.createJWT(tokens, request); const headers = await setEncryptedSessionCookie( url.hostname, this.typegraphName, @@ -211,8 +222,9 @@ export class OAuth2Auth extends Protocol { async tokenMiddleware( token: string, - url: URL, + request: Request, ): Promise<[Record, string | null]> { + const url = new URL(request.url); const typegraphPath = `/${this.typegraphName}`; const client = new OAuth2Client({ ...this.clientData, @@ -236,7 +248,7 @@ export class OAuth2Auth extends Protocol { if (new Date().valueOf() / 1000 > claims.refreshAt) { try { const newClaims = await client.refreshToken.refresh(refreshToken); - const token = await this.createJWT(newClaims); + const token = await this.createJWT(newClaims, request); return [ claims, token ?? "", // token or clear @@ -252,6 +264,7 @@ export class OAuth2Auth extends Protocol { private async getProfile( token: Tokens, + request: Request, ): Promise> { if (!this.profileUrl) { return null; @@ -270,7 +283,7 @@ export class OAuth2Auth extends Protocol { let profile = await res.json(); if (this.authProfiler) { - profile = await this.authProfiler!.transform(profile, url); + profile = await this.authProfiler!.transform(profile, request); } return profile; @@ -279,8 +292,11 @@ export class OAuth2Auth extends Protocol { } } - private async createJWT(token: Tokens): Promise { - const profile = await this.getProfile(token); + private async createJWT( + token: Tokens, + request: Request, + ): Promise { + const profile = await this.getProfile(token, request); const profileClaims: ProfileClaims = profile ? mapKeys(profile, (k) => `profile.${k}`) : {}; diff --git a/typegate/src/services/auth/protocols/protocol.ts b/typegate/src/services/auth/protocols/protocol.ts index 12b5b2f296..0609c7b5e6 100644 --- a/typegate/src/services/auth/protocols/protocol.ts +++ b/typegate/src/services/auth/protocols/protocol.ts @@ -12,6 +12,6 @@ export abstract class Protocol { abstract tokenMiddleware( token: string, - url: URL, + request: Request, ): Promise<[Record, string | null]>; }