From 6f7bb5afccd1ea6e899e99cca7bbf265a867640c Mon Sep 17 00:00:00 2001 From: pilip-ton Date: Thu, 4 Dec 2025 11:51:59 -0600 Subject: [PATCH 1/4] Added cleanup for local and sessionstorafe if auth error occured. Needed if the app changes token/appName --- src/app.ts | 4 ++++ src/controllers/Network.controller.ts | 23 +++++++++++++++++++ src/repositories/BatchStorage.ts | 5 +++++ src/services/Batch.service.ts | 32 ++++++++++++++++++++++++++- 4 files changed, 63 insertions(+), 1 deletion(-) diff --git a/src/app.ts b/src/app.ts index 735cc73..0944383 100644 --- a/src/app.ts +++ b/src/app.ts @@ -73,4 +73,8 @@ export class App { public getAppName() { return this.appName; } + + public clearStorage() { + this.batchService.clearStorage(); + } } diff --git a/src/controllers/Network.controller.ts b/src/controllers/Network.controller.ts index 1d5a7a7..58f9668 100644 --- a/src/controllers/Network.controller.ts +++ b/src/controllers/Network.controller.ts @@ -21,7 +21,30 @@ export class NetworkController { public init() {} + private async checkAuthError(res: Response): Promise { + if (res.status === 400 || res.status === 403) { + try { + const responseText = await res.clone().text(); + const responseData = responseText ? JSON.parse(responseText) : {}; + const errorMessage = responseData.message || responseData.error || responseText || ''; + const errorMessageLower = errorMessage.toLowerCase(); + + if (errorMessageLower.includes('invalid app_name') || + errorMessageLower.includes('the domain name does not match')) { + return true; + } + } catch (e) { + // Ignore parsing errors + } + } + return false; + } + private readonly responseToParams = async (res: Response)=> { + const isAuthError = await this.checkAuthError(res); + if (isAuthError) { + this.appModule.clearStorage(); + } return res; } diff --git a/src/repositories/BatchStorage.ts b/src/repositories/BatchStorage.ts index e62853f..d4f648c 100644 --- a/src/repositories/BatchStorage.ts +++ b/src/repositories/BatchStorage.ts @@ -41,4 +41,9 @@ export class BatchStorage { this.localStorage.setItem(this.key, JSON.stringify(value)); this.sessionStorage.setItem(this.key, JSON.stringify(value)); } + + public clearStorage() { + this.localStorage.removeItem(this.key); + this.sessionStorage.removeItem(this.key); + } } \ No newline at end of file diff --git a/src/services/Batch.service.ts b/src/services/Batch.service.ts index b68353e..1e667bf 100644 --- a/src/services/Batch.service.ts +++ b/src/services/Batch.service.ts @@ -64,6 +64,10 @@ export class BatchService { } } + public clearStorage() { + this.storage.clearStorage(); + } + private processQueue() { const data: Record[] = this.storage.getBatch(); @@ -72,9 +76,35 @@ export class BatchService { } } + private async checkAuthError(res: Response): Promise { + if (res.status === 400 || res.status === 403) { + try { + const responseText = await res.clone().text(); + const responseData = responseText ? JSON.parse(responseText) : {}; + const errorMessage = responseData.message || responseData.error || responseText || ''; + const errorMessageLower = errorMessage.toLowerCase(); + + if (errorMessageLower.includes('invalid app_name') || + errorMessageLower.includes('the domain name does not match')) { + return true; + } + } catch (e) { + // Ignore parsing errors + } + } + return false; + } + private sendBatch(batch: Record[]) { this.stopBatching(); - this.appModule.recordEvents(batch).then((res: Response)=> { + this.appModule.recordEvents(batch).then(async (res: Response)=> { + const isAuthError = await this.checkAuthError(res); + if (isAuthError) { + this.storage.clearStorage(); + this.stopBatching(); + return; + } + if (String(res.status) === '429') { this.startBatching(); From b50e17e1f0227d90aca86c1b4fe782d9497dfef5 Mon Sep 17 00:00:00 2001 From: pilip-ton Date: Thu, 4 Dec 2025 13:15:30 -0600 Subject: [PATCH 2/4] code cleanup --- src/controllers/Network.controller.ts | 23 ++--------------------- src/repositories/BatchStorage.ts | 3 +-- src/services/Batch.service.ts | 25 +++---------------------- src/utils/checkAuthError.ts | 16 ++++++++++++++++ 4 files changed, 22 insertions(+), 45 deletions(-) create mode 100644 src/utils/checkAuthError.ts diff --git a/src/controllers/Network.controller.ts b/src/controllers/Network.controller.ts index 58f9668..518fc4d 100644 --- a/src/controllers/Network.controller.ts +++ b/src/controllers/Network.controller.ts @@ -2,6 +2,7 @@ import { App } from '../app' import { BACKEND_URL, STAGING_BACKEND_URL } from '../constants' import { Errors, throwError } from '../errors' import { compressData } from '../utils/compress'; +import { checkAuthError } from '../utils/checkAuthError'; export class NetworkController { private appModule: App; @@ -21,28 +22,8 @@ export class NetworkController { public init() {} - private async checkAuthError(res: Response): Promise { - if (res.status === 400 || res.status === 403) { - try { - const responseText = await res.clone().text(); - const responseData = responseText ? JSON.parse(responseText) : {}; - const errorMessage = responseData.message || responseData.error || responseText || ''; - const errorMessageLower = errorMessage.toLowerCase(); - - if (errorMessageLower.includes('invalid app_name') || - errorMessageLower.includes('the domain name does not match')) { - return true; - } - } catch (e) { - // Ignore parsing errors - } - } - return false; - } - private readonly responseToParams = async (res: Response)=> { - const isAuthError = await this.checkAuthError(res); - if (isAuthError) { + if (await checkAuthError(res)) { this.appModule.clearStorage(); } return res; diff --git a/src/repositories/BatchStorage.ts b/src/repositories/BatchStorage.ts index d4f648c..856cbb5 100644 --- a/src/repositories/BatchStorage.ts +++ b/src/repositories/BatchStorage.ts @@ -43,7 +43,6 @@ export class BatchStorage { } public clearStorage() { - this.localStorage.removeItem(this.key); - this.sessionStorage.removeItem(this.key); + this.setItem([]); } } \ No newline at end of file diff --git a/src/services/Batch.service.ts b/src/services/Batch.service.ts index 1e667bf..2daef32 100644 --- a/src/services/Batch.service.ts +++ b/src/services/Batch.service.ts @@ -1,6 +1,7 @@ import {BATCH_KEY, Events} from "../constants"; import { App } from "../app"; import { BatchStorage } from "../repositories/BatchStorage"; +import { checkAuthError } from "../utils/checkAuthError"; export class BatchService { private appModule: App; @@ -76,31 +77,11 @@ export class BatchService { } } - private async checkAuthError(res: Response): Promise { - if (res.status === 400 || res.status === 403) { - try { - const responseText = await res.clone().text(); - const responseData = responseText ? JSON.parse(responseText) : {}; - const errorMessage = responseData.message || responseData.error || responseText || ''; - const errorMessageLower = errorMessage.toLowerCase(); - - if (errorMessageLower.includes('invalid app_name') || - errorMessageLower.includes('the domain name does not match')) { - return true; - } - } catch (e) { - // Ignore parsing errors - } - } - return false; - } - private sendBatch(batch: Record[]) { this.stopBatching(); this.appModule.recordEvents(batch).then(async (res: Response)=> { - const isAuthError = await this.checkAuthError(res); - if (isAuthError) { - this.storage.clearStorage(); + if (await checkAuthError(res)) { + this.storage.setItem([]); this.stopBatching(); return; } diff --git a/src/utils/checkAuthError.ts b/src/utils/checkAuthError.ts new file mode 100644 index 0000000..46bb875 --- /dev/null +++ b/src/utils/checkAuthError.ts @@ -0,0 +1,16 @@ +export async function checkAuthError(res: Response): Promise { + if (res.status === 400 || res.status === 403) { + try { + const responseText = await res.clone().text(); + const responseData = responseText ? JSON.parse(responseText) : {}; + const errorMessage = (responseData.message || responseData.error || '').toLowerCase(); + + return errorMessage.includes('invalid app_name'); + } catch (e) { + return false; + } + } + return false; +} + + From 48a64242c856ffcbed33e9713220655e1d5122b8 Mon Sep 17 00:00:00 2001 From: pilip-ton Date: Thu, 4 Dec 2025 15:00:36 -0600 Subject: [PATCH 3/4] Use token + appName as storage key to prevent data mixing --- src/repositories/BatchStorage.ts | 4 ---- src/services/Batch.service.ts | 15 ++------------- src/utils/checkAuthError.ts | 16 ---------------- 3 files changed, 2 insertions(+), 33 deletions(-) delete mode 100644 src/utils/checkAuthError.ts diff --git a/src/repositories/BatchStorage.ts b/src/repositories/BatchStorage.ts index 856cbb5..e62853f 100644 --- a/src/repositories/BatchStorage.ts +++ b/src/repositories/BatchStorage.ts @@ -41,8 +41,4 @@ export class BatchStorage { this.localStorage.setItem(this.key, JSON.stringify(value)); this.sessionStorage.setItem(this.key, JSON.stringify(value)); } - - public clearStorage() { - this.setItem([]); - } } \ No newline at end of file diff --git a/src/services/Batch.service.ts b/src/services/Batch.service.ts index 2daef32..a3b635b 100644 --- a/src/services/Batch.service.ts +++ b/src/services/Batch.service.ts @@ -1,7 +1,6 @@ import {BATCH_KEY, Events} from "../constants"; import { App } from "../app"; import { BatchStorage } from "../repositories/BatchStorage"; -import { checkAuthError } from "../utils/checkAuthError"; export class BatchService { private appModule: App; @@ -14,7 +13,7 @@ export class BatchService { constructor(appModule: App) { this.appModule = appModule; - this.storage = new BatchStorage(this.BATCH_KEY + '-' + this.appModule.getApiToken()); + this.storage = new BatchStorage(this.BATCH_KEY + '-' + this.appModule.getApiToken() + '-' + this.appModule.getAppName()); } public init() { @@ -65,10 +64,6 @@ export class BatchService { } } - public clearStorage() { - this.storage.clearStorage(); - } - private processQueue() { const data: Record[] = this.storage.getBatch(); @@ -79,13 +74,7 @@ export class BatchService { private sendBatch(batch: Record[]) { this.stopBatching(); - this.appModule.recordEvents(batch).then(async (res: Response)=> { - if (await checkAuthError(res)) { - this.storage.setItem([]); - this.stopBatching(); - return; - } - + this.appModule.recordEvents(batch).then((res: Response)=> { if (String(res.status) === '429') { this.startBatching(); diff --git a/src/utils/checkAuthError.ts b/src/utils/checkAuthError.ts deleted file mode 100644 index 46bb875..0000000 --- a/src/utils/checkAuthError.ts +++ /dev/null @@ -1,16 +0,0 @@ -export async function checkAuthError(res: Response): Promise { - if (res.status === 400 || res.status === 403) { - try { - const responseText = await res.clone().text(); - const responseData = responseText ? JSON.parse(responseText) : {}; - const errorMessage = (responseData.message || responseData.error || '').toLowerCase(); - - return errorMessage.includes('invalid app_name'); - } catch (e) { - return false; - } - } - return false; -} - - From c854aed219616a04316751f6315d3240a38b2b3d Mon Sep 17 00:00:00 2001 From: pilip-ton Date: Thu, 4 Dec 2025 15:02:16 -0600 Subject: [PATCH 4/4] Revert app.ts and Network.controller.ts to match master --- src/app.ts | 4 ---- src/controllers/Network.controller.ts | 4 ---- 2 files changed, 8 deletions(-) diff --git a/src/app.ts b/src/app.ts index 0944383..735cc73 100644 --- a/src/app.ts +++ b/src/app.ts @@ -73,8 +73,4 @@ export class App { public getAppName() { return this.appName; } - - public clearStorage() { - this.batchService.clearStorage(); - } } diff --git a/src/controllers/Network.controller.ts b/src/controllers/Network.controller.ts index 518fc4d..1d5a7a7 100644 --- a/src/controllers/Network.controller.ts +++ b/src/controllers/Network.controller.ts @@ -2,7 +2,6 @@ import { App } from '../app' import { BACKEND_URL, STAGING_BACKEND_URL } from '../constants' import { Errors, throwError } from '../errors' import { compressData } from '../utils/compress'; -import { checkAuthError } from '../utils/checkAuthError'; export class NetworkController { private appModule: App; @@ -23,9 +22,6 @@ export class NetworkController { public init() {} private readonly responseToParams = async (res: Response)=> { - if (await checkAuthError(res)) { - this.appModule.clearStorage(); - } return res; }