From 5797e886b01b8de143d332792a8bebd79125b4f5 Mon Sep 17 00:00:00 2001 From: Shepherd Date: Fri, 11 Oct 2024 13:15:58 -0400 Subject: [PATCH] Add jwtToken property to OSModel Adds jwtToken as a property of OSModel. Removes unused jwtTokenAvailable property from Operation. Removes storing jwtToken in the Database. Since jwtToken is on OSModel, operations can access it from Operation.model.jwtToken and it doesn't need a separate property on Operation. --- .../userPropertyRequests.test.ts | 6 ------ src/core/caching/EncodedModel.ts | 1 + src/core/executors/ExecutorBase.ts | 3 +-- src/core/modelRepo/OSModel.ts | 20 +++++++++++++++++-- src/core/operationRepo/Operation.ts | 9 --------- src/core/requestService/helpers.ts | 5 ----- src/page/managers/LoginManager.ts | 17 +++++++++++++++- src/shared/services/Database.ts | 16 --------------- 8 files changed, 36 insertions(+), 41 deletions(-) diff --git a/__test__/unit/core/requestService/userPropertyRequests.test.ts b/__test__/unit/core/requestService/userPropertyRequests.test.ts index 3c62fcf11..85cd3382c 100644 --- a/__test__/unit/core/requestService/userPropertyRequests.test.ts +++ b/__test__/unit/core/requestService/userPropertyRequests.test.ts @@ -5,14 +5,8 @@ import { ModelName } from '../../../../src/core/models/SupportedModels'; import { UserPropertiesModel } from '../../../../src/core/models/UserPropertiesModel'; import { OSModel } from '../../../../src/core/modelRepo/OSModel'; import { ExecutorResultFailNotRetriable } from '../../../../src/core/executors/ExecutorResult'; -import Database from '../../../../src/shared/services/Database'; describe('User Property Request tests', () => { - beforeAll(() => { - // Required for Operation class - test.stub(Database.prototype, 'getJWTToken', Promise.resolve([])); - }); - test('updateUserProperties returns no retry failure result', async () => { const delta = { changeType: CoreChangeType.Update, diff --git a/src/core/caching/EncodedModel.ts b/src/core/caching/EncodedModel.ts index e8daebf11..8b9b0990e 100644 --- a/src/core/caching/EncodedModel.ts +++ b/src/core/caching/EncodedModel.ts @@ -9,5 +9,6 @@ export default interface EncodedModel { modelName: ModelName; onesignalId?: string; externalId?: string; + jwtToken?: string; [key: string]: unknown; } diff --git a/src/core/executors/ExecutorBase.ts b/src/core/executors/ExecutorBase.ts index d9f11c061..493c88f33 100644 --- a/src/core/executors/ExecutorBase.ts +++ b/src/core/executors/ExecutorBase.ts @@ -150,7 +150,6 @@ export default abstract class ExecutorBase { // TO DO: fix optional model object. should always be defined on operation await operation.model?.awaitOneSignalIdAvailable; - await operation.jwtTokenAvailable; let res: ExecutorResult = { success: false, @@ -169,7 +168,7 @@ export default abstract class ExecutorBase { if (res.result) { // since we took a snapshot of the operation, we get a new instance with the correct model reference const operationInstance = - await Operation.getInstanceWithModelReference(operation); + Operation.getInstanceWithModelReference(operation); operationInstance?.model?.hydrate(res.result as SupportedModel); } OperationCache.delete(operation?.operationId); diff --git a/src/core/modelRepo/OSModel.ts b/src/core/modelRepo/OSModel.ts index 5185b0c3c..da2f78759 100644 --- a/src/core/modelRepo/OSModel.ts +++ b/src/core/modelRepo/OSModel.ts @@ -18,6 +18,7 @@ export class OSModel extends Subscribable> { onesignalIdAvailableCallback?: (onesignalId: string) => void; externalId?: string; applyToRecordId?: string; + jwtToken?: string; constructor( readonly modelName: ModelName, @@ -30,6 +31,7 @@ export class OSModel extends Subscribable> { this.data = data; this.onesignalId = undefined; this.externalId = undefined; + this.jwtToken = undefined; this.awaitOneSignalIdAvailable = new Promise((resolve) => { this.onesignalIdAvailableCallback = resolve; @@ -55,6 +57,11 @@ export class OSModel extends Subscribable> { this.externalId = externalId; } + public setJwtToken(jwtToken?: string): void { + logMethodCall('setJwtToken', { jwtToken }); + this.jwtToken = jwtToken; + } + public setApplyToRecordId(applyToRecordId: string): void { logMethodCall('setapplyToRecordId', { applyToRecordId }); this.applyToRecordId = applyToRecordId; @@ -105,7 +112,15 @@ export class OSModel extends Subscribable> { const modelName = this.modelName; const onesignalId = this.onesignalId; const externalId = this.externalId; - return { modelId, modelName, onesignalId, externalId, ...this.data }; + const jwtToken = this.jwtToken; + return { + modelId, + modelName, + onesignalId, + externalId, + jwtToken, + ...this.data, + }; } /** @@ -115,7 +130,7 @@ export class OSModel extends Subscribable> { */ static decode(encodedModel: EncodedModel): OSModel { logMethodCall('decode', { encodedModel }); - const { modelId, modelName, onesignalId, externalId, ...data } = + const { modelId, modelName, onesignalId, externalId, jwtToken, ...data } = encodedModel; const decodedModel = new OSModel( @@ -126,6 +141,7 @@ export class OSModel extends Subscribable> { decodedModel.setOneSignalId(onesignalId); decodedModel.setExternalId(externalId); + decodedModel.setJwtToken(jwtToken); return decodedModel; } } diff --git a/src/core/operationRepo/Operation.ts b/src/core/operationRepo/Operation.ts index 06c18d202..924f4dae4 100644 --- a/src/core/operationRepo/Operation.ts +++ b/src/core/operationRepo/Operation.ts @@ -12,8 +12,6 @@ export class Operation { payload?: Partial; model?: OSModel; applyToRecordId?: string; - jwtTokenAvailable: Promise; - jwtToken?: string | null; constructor( readonly changeType: CoreChangeType, @@ -25,11 +23,6 @@ export class Operation { this.model = deltas ? deltas[deltas.length - 1].model : undefined; this.applyToRecordId = deltas?.[deltas.length - 1]?.applyToRecordId; this.timestamp = Date.now(); - // eslint-disable-next-line no-async-promise-executor - this.jwtTokenAvailable = new Promise(async (resolve) => { - this.jwtToken = await Database.getJWTToken(); - resolve(); - }); } private getPayload(deltas: CoreDelta[]): any { @@ -99,8 +92,6 @@ export class Operation { operation.operationId = operationId; operation.timestamp = timestamp; operation.payload = payload; - operation.jwtToken = rawOperation.jwtToken; - operation.jwtTokenAvailable = Promise.resolve(); return operation; } else { throw new Error( diff --git a/src/core/requestService/helpers.ts b/src/core/requestService/helpers.ts index 0d1cbed8b..4269c9b28 100644 --- a/src/core/requestService/helpers.ts +++ b/src/core/requestService/helpers.ts @@ -95,8 +95,3 @@ export function processIdentityOperation(operation: Operation): { aliasPair: new AliasPair(AliasPair.ONESIGNAL_ID, onesignalId), }; } - -export async function getJWTHeader(): Promise { - const jwtToken = await Database.getJWTToken(); - return !!jwtToken ? { Authorization: `Bearer ${jwtToken}` } : undefined; -} diff --git a/src/page/managers/LoginManager.ts b/src/page/managers/LoginManager.ts index 81720a169..e95c966ef 100644 --- a/src/page/managers/LoginManager.ts +++ b/src/page/managers/LoginManager.ts @@ -31,8 +31,9 @@ export default class LoginManager { // before, logging in, process anything waiting in the delta queue so it's not lost OneSignal.coreDirector.forceDeltaQueueProcessingOnAllExecutors(); + // set Jwt and send Jwt header regardless if jwtRequired if (token) { - await Database.setJWTToken(token); + this._setJwtTokenOnAllModels(token); } const identityModel = OneSignal.coreDirector.getIdentityModel(); @@ -428,4 +429,18 @@ export default class LoginManager { ); } } + + /* Helper methods */ + private static async _setJwtTokenOnAllModels(token?: string): Promise { + const identityModel = OneSignal.coreDirector.getIdentityModel(); + const propertiesModel = OneSignal.coreDirector.getPropertiesModel(); + const subscriptionModels = + await OneSignal.coreDirector.getAllSubscriptionsModels(); + + identityModel?.setJwtToken(token); + propertiesModel?.setJwtToken(token); + subscriptionModels.forEach((sub) => { + sub.setJwtToken(token); + }); + } } diff --git a/src/shared/services/Database.ts b/src/shared/services/Database.ts index 6b77cd10b..11ff99156 100644 --- a/src/shared/services/Database.ts +++ b/src/shared/services/Database.ts @@ -349,14 +349,6 @@ export default class Database { } } - async setJWTToken(token: string): Promise { - await this.put('Ids', { type: 'jwtToken', id: token }); - } - - async getJWTToken(): Promise { - return await this.get('Ids', 'jwtToken'); - } - async setProvideUserConsent(consent: boolean): Promise { await this.put('Options', { key: 'userConsent', value: consent }); } @@ -529,14 +521,6 @@ export default class Database { return await Database.singletonInstance.getSubscription(); } - static async setJWTToken(token: string) { - return await Database.singletonInstance.setJWTToken(token); - } - - static async getJWTToken(): Promise { - return await Database.singletonInstance.getJWTToken(); - } - static async setConsentGiven(consent: boolean): Promise { return await Database.singletonInstance.setProvideUserConsent(consent); }