From 24eca5f6ffaeed6a67a59b0997584b0347bef114 Mon Sep 17 00:00:00 2001 From: Mostafa Rashed <17770919+mrashed-dev@users.noreply.github.com> Date: Tue, 30 Jan 2024 23:46:52 +0400 Subject: [PATCH] Changed `clientSecret` to optional for token exchange methods; defaults to API Key now (#531) clientSecret is not required if the API Key used for the SDK and the clientId belong to the same application. --- CHANGELOG.md | 1 + src/models/auth.ts | 8 +++---- src/resources/auth.ts | 18 ++++++++++------ tests/resources/auth.spec.ts | 42 ++++++++++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 64d524a3..405debac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Changelog ### Unreleased +* Changed `clientSecret` to optional for token exchange methods; defaults to API Key now * Fix missing `type` field in `Event` model ### 7.0.0-beta.4 / 2024-01-12 diff --git a/src/models/auth.ts b/src/models/auth.ts index bd63ebff..0804198f 100644 --- a/src/models/auth.ts +++ b/src/models/auth.ts @@ -80,9 +80,9 @@ export interface CodeExchangeRequest { */ clientId: string; /** - * Client secret of the application. + * Client secret of the application. If not provided, the API Key will be used instead. */ - clientSecret: string; + clientSecret?: string; /** * The original plain text code verifier (code_challenge) used in the initial authorization request (PKCE). */ @@ -106,9 +106,9 @@ export interface TokenExchangeRequest { */ clientId: string; /** - * Client secret of the application. + * Client secret of the application. If not provided, the API Key will be used instead. */ - clientSecret: string; + clientSecret?: string; } /** diff --git a/src/resources/auth.ts b/src/resources/auth.ts index cc9a22d3..9eae63ad 100644 --- a/src/resources/auth.ts +++ b/src/resources/auth.ts @@ -46,17 +46,17 @@ export class Auth extends Resource { public exchangeCodeForToken( request: CodeExchangeRequest ): Promise { - const body: Record = { - ...request, - grantType: 'authorization_code', - }; - if (request.codeVerifier) { - body.codeVerifier = request.codeVerifier; + if (!request.clientSecret) { + request.clientSecret = this.apiClient.apiKey; } + return this.apiClient.request({ method: 'POST', path: `/v3/connect/token`, - body, + body: { + ...request, + grantType: 'authorization_code', + }, }); } @@ -68,6 +68,10 @@ export class Auth extends Resource { public refreshAccessToken( request: TokenExchangeRequest ): Promise { + if (!request.clientSecret) { + request.clientSecret = this.apiClient.apiKey; + } + return this.apiClient.request({ method: 'POST', path: `/v3/connect/token`, diff --git a/tests/resources/auth.spec.ts b/tests/resources/auth.spec.ts index e4eeb424..b20f37c1 100644 --- a/tests/resources/auth.spec.ts +++ b/tests/resources/auth.spec.ts @@ -45,6 +45,27 @@ describe('Auth', () => { }); }); + it('should default clientSecret to the API key', async () => { + const payload: CodeExchangeRequest = { + clientId: 'clientId', + redirectUri: 'https://redirect.uri/path', + code: 'code', + }; + await auth.exchangeCodeForToken(payload); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/connect/token', + body: { + clientId: 'clientId', + clientSecret: 'apiKey', + redirectUri: 'https://redirect.uri/path', + code: 'code', + grantType: 'authorization_code', + }, + }); + }); + it('should set codeVerifier', async () => { const payload: CodeExchangeRequest = { clientId: 'clientId', @@ -92,6 +113,27 @@ describe('Auth', () => { }, }); }); + + it('should default clientSecret to the API key', async () => { + const payload: TokenExchangeRequest = { + clientId: 'clientId', + redirectUri: 'https://redirect.uri/path', + refreshToken: 'refreshToken', + }; + await auth.refreshAccessToken(payload); + + expect(apiClient.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/v3/connect/token', + body: { + clientId: 'clientId', + clientSecret: 'apiKey', + redirectUri: 'https://redirect.uri/path', + refreshToken: 'refreshToken', + grantType: 'refresh_token', + }, + }); + }); }); }); describe('customAuthentication', () => {