From 5ff8da26b9f799dede2f2986bf7f7b334046469e Mon Sep 17 00:00:00 2001 From: frederikprijck Date: Mon, 14 Aug 2023 17:31:54 +0200 Subject: [PATCH 1/3] Do not expose a grant method --- src/auth/base-auth-api.ts | 47 +++++++++++++++++++++++++++- src/auth/oauth.ts | 64 ++++++++++++++------------------------- src/auth/passwordless.ts | 22 +++++++++----- 3 files changed, 83 insertions(+), 50 deletions(-) diff --git a/src/auth/base-auth-api.ts b/src/auth/base-auth-api.ts index ad3f96860..17502f7d6 100644 --- a/src/auth/base-auth-api.ts +++ b/src/auth/base-auth-api.ts @@ -1,9 +1,17 @@ import { ResponseError } from '../lib/errors.js'; -import { BaseAPI, ClientOptions } from '../lib/runtime.js'; +import { + BaseAPI, + ClientOptions, + InitOverrideFunction, + JSONApiResponse, + RequestOpts, +} from '../lib/runtime.js'; import { AddClientAuthenticationPayload, addClientAuthentication, } from './client-authentication.js'; +import { IDTokenValidator } from './id-token-validator.js'; +import { GrantOptions, TokenSet } from './oauth.js'; export interface AuthenticationClientOptions extends ClientOptions { domain: string; @@ -117,3 +125,40 @@ export class BaseAuthAPI extends BaseAPI { }); } } + +/** + * @private + * Perform an OAuth 2.0 grant. + */ +export async function grant( + grantType: string, + bodyParameters: Record, + { idTokenValidateOptions, initOverrides }: GrantOptions = {}, + idTokenValidator: IDTokenValidator, + request: ( + context: RequestOpts, + initOverrides?: RequestInit | InitOverrideFunction + ) => Promise +): Promise> { + const response = await request( + { + path: '/oauth/token', + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + body: new URLSearchParams({ + client_id: this.clientId, + ...bodyParameters, + grant_type: grantType, + }), + }, + initOverrides + ); + + const res: JSONApiResponse = await JSONApiResponse.fromResponse(response); + if (res.data.id_token) { + await idTokenValidator.validate(res.data.id_token, idTokenValidateOptions); + } + return res; +} diff --git a/src/auth/oauth.ts b/src/auth/oauth.ts index aaf424f95..ccb631ff3 100644 --- a/src/auth/oauth.ts +++ b/src/auth/oauth.ts @@ -1,10 +1,12 @@ import { InitOverride, + InitOverrideFunction, JSONApiResponse, + RequestOpts, VoidApiResponse, validateRequiredRequestParams, } from '../lib/runtime.js'; -import { BaseAuthAPI, AuthenticationClientOptions } from './base-auth-api.js'; +import { BaseAuthAPI, AuthenticationClientOptions, grant } from './base-auth-api.js'; import { IDTokenValidateOptions, IDTokenValidator } from './id-token-validator.js'; export interface TokenSet { @@ -201,36 +203,6 @@ export class OAuth extends BaseAuthAPI { } } - /** - * Perform an OAuth 2.0 grant. - * (You should only need this if you can't find the grant you need in this library.) - */ - async grant( - grantType: string, - bodyParameters: Record, - { idTokenValidateOptions, initOverrides }: GrantOptions = {} - ): Promise> { - const response = await this.request( - { - path: '/oauth/token', - method: 'POST', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - }, - body: new URLSearchParams({ - client_id: this.clientId, - ...bodyParameters, - grant_type: grantType, - }), - }, - initOverrides - ); - - const res: JSONApiResponse = await JSONApiResponse.fromResponse(response); - await this.validateIdToken(res.data, idTokenValidateOptions); - return res; - } - /** * This is the flow that regular web apps use to access an API. * @@ -255,10 +227,12 @@ export class OAuth extends BaseAuthAPI { ): Promise> { validateRequiredRequestParams(bodyParameters, ['code']); - return this.grant( + return grant( 'authorization_code', await this.addClientAuthentication(bodyParameters, true), - options + options, + this.idTokenValidator, + this.request.bind(this) ); } @@ -289,10 +263,12 @@ export class OAuth extends BaseAuthAPI { ): Promise> { validateRequiredRequestParams(bodyParameters, ['code', 'code_verifier']); - return this.grant( + return grant( 'authorization_code', await this.addClientAuthentication(bodyParameters, false), - options + options, + this.idTokenValidator, + this.request.bind(this) ); } @@ -321,10 +297,12 @@ export class OAuth extends BaseAuthAPI { ): Promise> { validateRequiredRequestParams(bodyParameters, ['audience']); - return this.grant( + return grant( 'client_credentials', await this.addClientAuthentication(bodyParameters, true), - options + options, + this.idTokenValidator, + this.request.bind(this) ); } @@ -362,10 +340,12 @@ export class OAuth extends BaseAuthAPI { ): Promise> { validateRequiredRequestParams(bodyParameters, ['username', 'password']); - return this.grant( + return grant( bodyParameters.realm ? 'http://auth0.com/oauth/grant-type/password-realm' : 'password', await this.addClientAuthentication(bodyParameters, false), - options + options, + this.idTokenValidator, + this.request.bind(this) ); } @@ -391,10 +371,12 @@ export class OAuth extends BaseAuthAPI { ): Promise> { validateRequiredRequestParams(bodyParameters, ['refresh_token']); - return this.grant( + return grant( 'refresh_token', await this.addClientAuthentication(bodyParameters, false), - options + options, + this.idTokenValidator, + this.request.bind(this) ); } diff --git a/src/auth/passwordless.ts b/src/auth/passwordless.ts index ceb7c5660..79791677e 100644 --- a/src/auth/passwordless.ts +++ b/src/auth/passwordless.ts @@ -4,8 +4,9 @@ import { VoidApiResponse, validateRequiredRequestParams, } from '../lib/runtime.js'; -import { BaseAuthAPI, AuthenticationClientOptions } from './base-auth-api.js'; -import { OAuth, ClientCredentials, GrantOptions, TokenSet } from './oauth.js'; +import { BaseAuthAPI, AuthenticationClientOptions, grant } from './base-auth-api.js'; +import { IDTokenValidator } from './id-token-validator.js'; +import { ClientCredentials, GrantOptions, TokenSet } from './oauth.js'; export interface SendEmailLinkRequest { /** @@ -75,10 +76,11 @@ export interface LoginWithSMSRequest extends Omit Date: Mon, 14 Aug 2023 17:36:35 +0200 Subject: [PATCH 2/3] add clientId --- src/auth/oauth.ts | 5 +++++ src/auth/passwordless.ts | 2 ++ 2 files changed, 7 insertions(+) diff --git a/src/auth/oauth.ts b/src/auth/oauth.ts index ccb631ff3..7188f0fba 100644 --- a/src/auth/oauth.ts +++ b/src/auth/oauth.ts @@ -231,6 +231,7 @@ export class OAuth extends BaseAuthAPI { 'authorization_code', await this.addClientAuthentication(bodyParameters, true), options, + this.clientId, this.idTokenValidator, this.request.bind(this) ); @@ -267,6 +268,7 @@ export class OAuth extends BaseAuthAPI { 'authorization_code', await this.addClientAuthentication(bodyParameters, false), options, + this.clientId, this.idTokenValidator, this.request.bind(this) ); @@ -301,6 +303,7 @@ export class OAuth extends BaseAuthAPI { 'client_credentials', await this.addClientAuthentication(bodyParameters, true), options, + this.clientId, this.idTokenValidator, this.request.bind(this) ); @@ -344,6 +347,7 @@ export class OAuth extends BaseAuthAPI { bodyParameters.realm ? 'http://auth0.com/oauth/grant-type/password-realm' : 'password', await this.addClientAuthentication(bodyParameters, false), options, + this.clientId, this.idTokenValidator, this.request.bind(this) ); @@ -375,6 +379,7 @@ export class OAuth extends BaseAuthAPI { 'refresh_token', await this.addClientAuthentication(bodyParameters, false), options, + this.clientId, this.idTokenValidator, this.request.bind(this) ); diff --git a/src/auth/passwordless.ts b/src/auth/passwordless.ts index 79791677e..586966378 100644 --- a/src/auth/passwordless.ts +++ b/src/auth/passwordless.ts @@ -227,6 +227,7 @@ export class Passwordless extends BaseAuthAPI { false ), options, + this.clientId, this.idTokenValidator, this.request.bind(this) ); @@ -269,6 +270,7 @@ export class Passwordless extends BaseAuthAPI { false ), options, + this.clientId, this.idTokenValidator, this.request.bind(this) ); From 6418594eb95f5709e8f05817ec80556203c278df Mon Sep 17 00:00:00 2001 From: frederikprijck Date: Mon, 14 Aug 2023 17:41:28 +0200 Subject: [PATCH 3/3] fix --- src/auth/base-auth-api.ts | 3 ++- src/auth/oauth.ts | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/auth/base-auth-api.ts b/src/auth/base-auth-api.ts index 17502f7d6..927700c7e 100644 --- a/src/auth/base-auth-api.ts +++ b/src/auth/base-auth-api.ts @@ -134,6 +134,7 @@ export async function grant( grantType: string, bodyParameters: Record, { idTokenValidateOptions, initOverrides }: GrantOptions = {}, + clientId: string, idTokenValidator: IDTokenValidator, request: ( context: RequestOpts, @@ -148,7 +149,7 @@ export async function grant( 'Content-Type': 'application/x-www-form-urlencoded', }, body: new URLSearchParams({ - client_id: this.clientId, + client_id: clientId, ...bodyParameters, grant_type: grantType, }), diff --git a/src/auth/oauth.ts b/src/auth/oauth.ts index 7188f0fba..bbc480083 100644 --- a/src/auth/oauth.ts +++ b/src/auth/oauth.ts @@ -1,8 +1,6 @@ import { InitOverride, - InitOverrideFunction, JSONApiResponse, - RequestOpts, VoidApiResponse, validateRequiredRequestParams, } from '../lib/runtime.js';