diff --git a/lib/__tests__/sdk/oauth2-flows/ClientCredentials.spec.ts b/lib/__tests__/sdk/oauth2-flows/ClientCredentials.spec.ts index 73a7d7d..d2b9647 100644 --- a/lib/__tests__/sdk/oauth2-flows/ClientCredentials.spec.ts +++ b/lib/__tests__/sdk/oauth2-flows/ClientCredentials.spec.ts @@ -82,7 +82,8 @@ describe('ClientCredentials', () => { sessionManager, mockAccessToken, 'access_token', - validationDetails + validationDetails, + 'persistent' ); const client = new ClientCredentials(clientConfig); diff --git a/lib/__tests__/sdk/utilities/token-utils.spec.ts b/lib/__tests__/sdk/utilities/token-utils.spec.ts index b746b4a..d989485 100644 --- a/lib/__tests__/sdk/utilities/token-utils.spec.ts +++ b/lib/__tests__/sdk/utilities/token-utils.spec.ts @@ -62,7 +62,8 @@ describe('token-utils', () => { sessionManager, mockAccessToken, 'access_token', - validationDetails + validationDetails, + 'persistent' ); expect(await sessionManager.getSessionItem('access_token')).toBe( mockAccessToken @@ -79,7 +80,8 @@ describe('token-utils', () => { sessionManager, mockAccessToken, 'access_token', - validationDetails + validationDetails, + 'persistent' ); }; await expect(commitTokenFn).rejects.toBeInstanceOf(KindeSDKError); @@ -96,7 +98,8 @@ describe('token-utils', () => { sessionManager, mockIdToken, 'id_token', - validationDetails + validationDetails, + 'persistent' ); const storedUser = await getUserFromSession(sessionManager, validationDetails); diff --git a/lib/sdk/oauth2-flows/ClientCredentials.ts b/lib/sdk/oauth2-flows/ClientCredentials.ts index a6dfde6..fbbc3a4 100644 --- a/lib/sdk/oauth2-flows/ClientCredentials.ts +++ b/lib/sdk/oauth2-flows/ClientCredentials.ts @@ -1,4 +1,4 @@ -import { createLocalJWKSet } from 'jose'; +import { createLocalJWKSet, jwtVerify } from 'jose'; import { type SessionManager } from '../session-managers/index.js'; import * as utilities from '../utilities/index.js'; import { getSDKHeader } from '../version.js'; @@ -54,13 +54,20 @@ export class ClientCredentials { if (accessToken && !isTokenExpired) { return accessToken; } - const payload = await this.fetchAccessTokenFor(sessionManager); + + const key = await this.tokenValidationDetails.keyProvider(); + const result = await jwtVerify(payload.access_token, key); + + const sessionType = + result.payload.ksp === 'non_persistent' ? 'session' : 'persistent'; + await utilities.commitTokenToSession( sessionManager, payload.access_token, 'access_token', - this.tokenValidationDetails + this.tokenValidationDetails, + sessionType ); return payload.access_token; } diff --git a/lib/sdk/session-managers/types.ts b/lib/sdk/session-managers/types.ts index 7c25fdb..9f6868d 100644 --- a/lib/sdk/session-managers/types.ts +++ b/lib/sdk/session-managers/types.ts @@ -7,7 +7,11 @@ type Awaitable = Promise; export interface SessionManager { getSessionItem: (itemKey: string) => Awaitable; - setSessionItem: (itemKey: string, itemValue: T) => Awaitable; + setSessionItem: ( + itemKey: string, + itemValue: T, + sessionType?: string + ) => Awaitable; removeSessionItem: (itemKey: string) => Awaitable; destroySession: () => Awaitable; } diff --git a/lib/sdk/utilities/token-utils.ts b/lib/sdk/utilities/token-utils.ts index 126ba7a..5ffb399 100644 --- a/lib/sdk/utilities/token-utils.ts +++ b/lib/sdk/utilities/token-utils.ts @@ -13,12 +13,16 @@ import { jwtVerify } from 'jose'; * @param {SessionManager} sessionManager * @param {string} token * @param {TokenType} type + * @param {TokenValidationDetailsType} validationDetails + * @param {string} sessionType - Determines if the token should be stored as 'session' or 'persistent' + */ export const commitTokenToSession = async ( sessionManager: SessionManager, token: string, type: TokenType, - validationDetails: TokenValidationDetailsType + validationDetails: TokenValidationDetailsType, + sessionType: string ): Promise => { if (!token) { await sessionManager.removeSessionItem(type); @@ -37,7 +41,7 @@ export const commitTokenToSession = async ( } } - await sessionManager.setSessionItem(type, token); + await sessionManager.setSessionItem(type, token, sessionType); }; /** @@ -51,24 +55,33 @@ export const commitTokensToSession = async ( tokens: TokenCollection, validationDetails: TokenValidationDetailsType ): Promise => { + const key = await validationDetails.keyProvider(); + const result = await jwtVerify(tokens.access_token, key); + + const sessionType = + result.payload.ksp === 'non_persistent' ? 'session' : 'persistent'; + await Promise.all([ commitTokenToSession( sessionManager, tokens.refresh_token, 'refresh_token', - validationDetails + validationDetails, + sessionType ), commitTokenToSession( sessionManager, tokens.access_token, 'access_token', - validationDetails + validationDetails, + sessionType ), commitTokenToSession( sessionManager, tokens.id_token, 'id_token', - validationDetails + validationDetails, + sessionType ), ]); }; diff --git a/package.json b/package.json index c4fe31d..191d86d 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "postbuild": "node sdk-version.js clean && ncp ./package-cjs.json ./dist-cjs/package.json && ncp ./package-esm.json ./dist/package.json", "prebuild": "node sdk-version.js && rimraf dist dist-cjs lib/models lib/apis", "lint": "eslint . && prettier . --check", - "lint:fix": "eslint --fix . && prettier . --check", + "lint:fix": "eslint --fix . && prettier . --write", "test": "jest --passWithNoTests", "lint-staged": "lint-staged", "husky": "husky install",