@memberjunction/ng-auth-services 5.14.0 → 5.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/dist/lib/AngularAuthProviderFactory.d.ts +2 -2
  2. package/dist/lib/AngularAuthProviderFactory.d.ts.map +1 -1
  3. package/dist/lib/AngularAuthProviderFactory.js +11 -6
  4. package/dist/lib/AngularAuthProviderFactory.js.map +1 -1
  5. package/dist/lib/__tests__/auth-services.test.js +145 -9
  6. package/dist/lib/__tests__/auth-services.test.js.map +1 -1
  7. package/dist/lib/mjexplorer-auth-base.service.d.ts +29 -3
  8. package/dist/lib/mjexplorer-auth-base.service.d.ts.map +1 -1
  9. package/dist/lib/mjexplorer-auth-base.service.js +45 -0
  10. package/dist/lib/mjexplorer-auth-base.service.js.map +1 -1
  11. package/dist/lib/providers/mjexplorer-auth0-provider.service.d.ts +1 -1
  12. package/dist/lib/providers/mjexplorer-auth0-provider.service.d.ts.map +1 -1
  13. package/dist/lib/providers/mjexplorer-auth0-provider.service.js +8 -2
  14. package/dist/lib/providers/mjexplorer-auth0-provider.service.js.map +1 -1
  15. package/dist/lib/providers/mjexplorer-msal-provider.service.d.ts +1 -1
  16. package/dist/lib/providers/mjexplorer-msal-provider.service.d.ts.map +1 -1
  17. package/dist/lib/providers/mjexplorer-msal-provider.service.js +1 -1
  18. package/dist/lib/providers/mjexplorer-msal-provider.service.js.map +1 -1
  19. package/dist/lib/providers/mjexplorer-okta-provider.service.d.ts +1 -1
  20. package/dist/lib/providers/mjexplorer-okta-provider.service.d.ts.map +1 -1
  21. package/dist/lib/providers/mjexplorer-okta-provider.service.js +1 -1
  22. package/dist/lib/providers/mjexplorer-okta-provider.service.js.map +1 -1
  23. package/dist/lib/redirect.component.d.ts +3 -2
  24. package/dist/lib/redirect.component.d.ts.map +1 -1
  25. package/dist/lib/redirect.component.js +11 -6
  26. package/dist/lib/redirect.component.js.map +1 -1
  27. package/package.json +3 -3
@@ -7,14 +7,14 @@ import * as i0 from "@angular/core";
7
7
  */
8
8
  export declare class AngularAuthProviderFactory {
9
9
  private injector;
10
- private static instance;
10
+ private static readonly _globalStoreKey;
11
11
  private providers;
12
12
  private providerConfigs;
13
13
  constructor(injector: Injector);
14
14
  /**
15
15
  * Get singleton instance
16
16
  */
17
- static getInstance(): AngularAuthProviderFactory;
17
+ static get Instance(): AngularAuthProviderFactory;
18
18
  /**
19
19
  * Create a provider based on configuration
20
20
  */
@@ -1 +1 @@
1
- {"version":3,"file":"AngularAuthProviderFactory.d.ts","sourceRoot":"","sources":["../../src/lib/AngularAuthProviderFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGrD,OAAO,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;;AAElF;;;GAGG;AACH,qBAGa,0BAA0B;IAKzB,OAAO,CAAC,QAAQ;IAJ5B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA6B;IACpD,OAAO,CAAC,SAAS,CAAgD;IACjE,OAAO,CAAC,eAAe,CAA+B;gBAElC,QAAQ,EAAE,QAAQ;IAItC;;OAEG;IACH,MAAM,CAAC,WAAW,IAAI,0BAA0B;IAOhD;;OAEG;IACH,cAAc,CAAC,MAAM,EAAE,yBAAyB,GAAG,oBAAoB;IAoCvE;;OAEG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,GAAG,SAAS;IAI3D;;OAEG;IACH,kBAAkB,IAAI,MAAM,EAAE;IAO9B;;OAEG;IACH,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIvC;;OAEG;IACH,cAAc,IAAI,IAAI;IAKtB;;;OAGG;IACH,MAAM,CAAC,0BAA0B,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,GAAG,GAAG,EAAE;yCA9F7D,0BAA0B;6CAA1B,0BAA0B;CA+HtC"}
1
+ {"version":3,"file":"AngularAuthProviderFactory.d.ts","sourceRoot":"","sources":["../../src/lib/AngularAuthProviderFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGrD,OAAO,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;;AAElF;;;GAGG;AACH,qBAGa,0BAA0B;IAKzB,OAAO,CAAC,QAAQ;IAJ5B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAA8C;IACrF,OAAO,CAAC,SAAS,CAAgD;IACjE,OAAO,CAAC,eAAe,CAA+B;gBAElC,QAAQ,EAAE,QAAQ;IAQtC;;OAEG;IACH,WAAkB,QAAQ,IAAI,0BAA0B,CAMvD;IAED;;OAEG;IACH,cAAc,CAAC,MAAM,EAAE,yBAAyB,GAAG,oBAAoB;IAoCvE;;OAEG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,GAAG,SAAS;IAI3D;;OAEG;IACH,kBAAkB,IAAI,MAAM,EAAE;IAO9B;;OAEG;IACH,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIvC;;OAEG;IACH,cAAc,IAAI,IAAI;IAKtB;;;OAGG;IACH,MAAM,CAAC,0BAA0B,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,GAAG,GAAG,EAAE;yCAnG7D,0BAA0B;6CAA1B,0BAA0B;CAoItC"}
@@ -1,5 +1,5 @@
1
1
  import { Injectable } from '@angular/core';
2
- import { MJGlobal } from '@memberjunction/global';
2
+ import { MJGlobal, GetGlobalObjectStore } from '@memberjunction/global';
3
3
  import { MJAuthBase } from './mjexplorer-auth-base.service';
4
4
  import * as i0 from "@angular/core";
5
5
  /**
@@ -8,21 +8,26 @@ import * as i0 from "@angular/core";
8
8
  */
9
9
  export class AngularAuthProviderFactory {
10
10
  injector;
11
- static instance;
11
+ static _globalStoreKey = '___SINGLETON__AngularAuthProviderFactory';
12
12
  providers = new Map();
13
13
  providerConfigs = new Map();
14
14
  constructor(injector) {
15
15
  this.injector = injector;
16
- AngularAuthProviderFactory.instance = this;
16
+ const g = GetGlobalObjectStore();
17
+ if (g[AngularAuthProviderFactory._globalStoreKey]) {
18
+ return g[AngularAuthProviderFactory._globalStoreKey];
19
+ }
20
+ g[AngularAuthProviderFactory._globalStoreKey] = this;
17
21
  }
18
22
  /**
19
23
  * Get singleton instance
20
24
  */
21
- static getInstance() {
22
- if (!AngularAuthProviderFactory.instance) {
25
+ static get Instance() {
26
+ const instance = GetGlobalObjectStore()[AngularAuthProviderFactory._globalStoreKey];
27
+ if (!instance) {
23
28
  throw new Error('AngularAuthProviderFactory not initialized. Ensure it is provided in your module.');
24
29
  }
25
- return AngularAuthProviderFactory.instance;
30
+ return instance;
26
31
  }
27
32
  /**
28
33
  * Create a provider based on configuration
@@ -1 +1 @@
1
- {"version":3,"file":"AngularAuthProviderFactory.js","sourceRoot":"","sources":["../../src/lib/AngularAuthProviderFactory.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, Injector } from '@angular/core';\nimport { MJGlobal } from '@memberjunction/global';\nimport { MJAuthBase } from './mjexplorer-auth-base.service';\nimport { IAngularAuthProvider, AngularAuthProviderConfig } from './IAuthProvider';\n\n/**\n * Factory for creating Angular authentication providers\n * Uses MJGlobal ClassFactory pattern for extensibility\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class AngularAuthProviderFactory {\n private static instance: AngularAuthProviderFactory;\n private providers: Map<string, IAngularAuthProvider> = new Map();\n private providerConfigs: Map<string, any> = new Map();\n\n constructor(private injector: Injector) {\n AngularAuthProviderFactory.instance = this;\n }\n\n /**\n * Get singleton instance\n */\n static getInstance(): AngularAuthProviderFactory {\n if (!AngularAuthProviderFactory.instance) {\n throw new Error('AngularAuthProviderFactory not initialized. Ensure it is provided in your module.');\n }\n return AngularAuthProviderFactory.instance;\n }\n\n /**\n * Create a provider based on configuration\n */\n createProvider(config: AngularAuthProviderConfig): IAngularAuthProvider {\n \n const existingProvider = this.providers.get(config.type);\n if (existingProvider) {\n return existingProvider;\n }\n\n try {\n // Use MJGlobal ClassFactory to create the provider instance\n // Pass config as the first constructor argument\n const provider = MJGlobal.Instance.ClassFactory.CreateInstance<MJAuthBase>(\n MJAuthBase, \n config.type,\n config // Pass config as constructor argument, not injector\n );\n\n if (!provider) {\n throw new Error(`No provider registered for type: ${config.type}. Available types: ${this.getRegisteredTypes().join(', ')}`);\n }\n\n // Validate the configuration\n if (!provider.validateConfig(config)) {\n throw new Error(`Invalid configuration for provider type: ${config.type}`);\n }\n\n // Store the provider instance\n this.providers.set(config.type, provider);\n this.providerConfigs.set(config.type, config);\n\n return provider;\n } catch (error) {\n console.error(`Failed to create auth provider for type ${config.type}:`, error);\n throw error;\n }\n }\n\n /**\n * Get a provider by type\n */\n getProvider(type: string): IAngularAuthProvider | undefined {\n return this.providers.get(type);\n }\n\n /**\n * Get all registered provider types\n */\n getRegisteredTypes(): string[] {\n const registrations = MJGlobal.Instance.ClassFactory.GetRegistrationsByRootClass(MJAuthBase);\n const types = registrations.map(reg => reg.Key).filter((key): key is string => key !== null);\n // Return unique types only, as multiple classes can be registered with the same key\n return [...new Set(types)];\n }\n\n /**\n * Check if a provider type is registered\n */\n isTypeRegistered(type: string): boolean {\n return this.getRegisteredTypes().includes(type);\n }\n\n /**\n * Clear all providers (useful for testing)\n */\n clearProviders(): void {\n this.providers.clear();\n this.providerConfigs.clear();\n }\n\n /**\n * Get provider-specific Angular services that need to be injected\n * This uses the static angularProviderFactory property on each provider class for extensibility\n */\n static getProviderAngularServices(type: string, environment: any): any[] {\n \n const normalizedType = type?.toLowerCase();\n \n // Get the provider class from the ClassFactory\n const registration = MJGlobal.Instance.ClassFactory.GetRegistration(\n MJAuthBase, \n normalizedType\n );\n const providerClass = registration?.SubClass as any;\n \n if (!providerClass) {\n console.warn(`No provider class registered for type: ${type}`);\n return [];\n }\n \n // Check if the provider class has the factory property (new pattern)\n if (providerClass.angularProviderFactory) {\n // Call the factory function to get the required providers\n const services = providerClass.angularProviderFactory(environment);\n return services;\n } \n // Fallback to old method name for backward compatibility\n else if (typeof providerClass.getRequiredAngularProviders === 'function') {\n console.warn(`Provider ${type} uses deprecated getRequiredAngularProviders method. Please update to use angularProviderFactory property.`);\n return providerClass.getRequiredAngularProviders(environment);\n } \n else {\n // Provider doesn't define required Angular services (might not need any)\n return [];\n }\n }\n\n}"]}
1
+ {"version":3,"file":"AngularAuthProviderFactory.js","sourceRoot":"","sources":["../../src/lib/AngularAuthProviderFactory.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, Injector } from '@angular/core';\nimport { MJGlobal, GetGlobalObjectStore } from '@memberjunction/global';\nimport { MJAuthBase } from './mjexplorer-auth-base.service';\nimport { IAngularAuthProvider, AngularAuthProviderConfig } from './IAuthProvider';\n\n/**\n * Factory for creating Angular authentication providers\n * Uses MJGlobal ClassFactory pattern for extensibility\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class AngularAuthProviderFactory {\n private static readonly _globalStoreKey = '___SINGLETON__AngularAuthProviderFactory';\n private providers: Map<string, IAngularAuthProvider> = new Map();\n private providerConfigs: Map<string, any> = new Map();\n\n constructor(private injector: Injector) {\n const g = GetGlobalObjectStore()!;\n if (g[AngularAuthProviderFactory._globalStoreKey]) {\n return g[AngularAuthProviderFactory._globalStoreKey] as AngularAuthProviderFactory;\n }\n g[AngularAuthProviderFactory._globalStoreKey] = this;\n }\n\n /**\n * Get singleton instance\n */\n public static get Instance(): AngularAuthProviderFactory {\n const instance = GetGlobalObjectStore()![AngularAuthProviderFactory._globalStoreKey] as AngularAuthProviderFactory;\n if (!instance) {\n throw new Error('AngularAuthProviderFactory not initialized. Ensure it is provided in your module.');\n }\n return instance;\n }\n\n /**\n * Create a provider based on configuration\n */\n createProvider(config: AngularAuthProviderConfig): IAngularAuthProvider {\n \n const existingProvider = this.providers.get(config.type);\n if (existingProvider) {\n return existingProvider;\n }\n\n try {\n // Use MJGlobal ClassFactory to create the provider instance\n // Pass config as the first constructor argument\n const provider = MJGlobal.Instance.ClassFactory.CreateInstance<MJAuthBase>(\n MJAuthBase, \n config.type,\n config // Pass config as constructor argument, not injector\n );\n\n if (!provider) {\n throw new Error(`No provider registered for type: ${config.type}. Available types: ${this.getRegisteredTypes().join(', ')}`);\n }\n\n // Validate the configuration\n if (!provider.validateConfig(config)) {\n throw new Error(`Invalid configuration for provider type: ${config.type}`);\n }\n\n // Store the provider instance\n this.providers.set(config.type, provider);\n this.providerConfigs.set(config.type, config);\n\n return provider;\n } catch (error) {\n console.error(`Failed to create auth provider for type ${config.type}:`, error);\n throw error;\n }\n }\n\n /**\n * Get a provider by type\n */\n getProvider(type: string): IAngularAuthProvider | undefined {\n return this.providers.get(type);\n }\n\n /**\n * Get all registered provider types\n */\n getRegisteredTypes(): string[] {\n const registrations = MJGlobal.Instance.ClassFactory.GetRegistrationsByRootClass(MJAuthBase);\n const types = registrations.map(reg => reg.Key).filter((key): key is string => key !== null);\n // Return unique types only, as multiple classes can be registered with the same key\n return [...new Set(types)];\n }\n\n /**\n * Check if a provider type is registered\n */\n isTypeRegistered(type: string): boolean {\n return this.getRegisteredTypes().includes(type);\n }\n\n /**\n * Clear all providers (useful for testing)\n */\n clearProviders(): void {\n this.providers.clear();\n this.providerConfigs.clear();\n }\n\n /**\n * Get provider-specific Angular services that need to be injected\n * This uses the static angularProviderFactory property on each provider class for extensibility\n */\n static getProviderAngularServices(type: string, environment: any): any[] {\n \n const normalizedType = type?.toLowerCase();\n \n // Get the provider class from the ClassFactory\n const registration = MJGlobal.Instance.ClassFactory.GetRegistration(\n MJAuthBase, \n normalizedType\n );\n const providerClass = registration?.SubClass as any;\n \n if (!providerClass) {\n console.warn(`No provider class registered for type: ${type}`);\n return [];\n }\n \n // Check if the provider class has the factory property (new pattern)\n if (providerClass.angularProviderFactory) {\n // Call the factory function to get the required providers\n const services = providerClass.angularProviderFactory(environment);\n return services;\n } \n // Fallback to old method name for backward compatibility\n else if (typeof providerClass.getRequiredAngularProviders === 'function') {\n console.warn(`Provider ${type} uses deprecated getRequiredAngularProviders method. Please update to use angularProviderFactory property.`);\n return providerClass.getRequiredAngularProviders(environment);\n } \n else {\n // Provider doesn't define required Angular services (might not need any)\n return [];\n }\n }\n\n}"]}
@@ -4,7 +4,7 @@
4
4
  * - Auth types
5
5
  * - MJAuthBase (via dynamic import)
6
6
  */
7
- import { describe, it, expect, vi, beforeEach } from 'vitest';
7
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
8
8
  // Mock Angular
9
9
  vi.mock('@angular/core', () => ({
10
10
  Injectable: () => (target) => target,
@@ -68,7 +68,7 @@ describe('MJAuthBase', () => {
68
68
  type = 'test';
69
69
  async initialize() { }
70
70
  async loginInternal() { }
71
- async logout() { }
71
+ async logoutInternal() { }
72
72
  async handleCallback() { }
73
73
  async extractIdTokenInternal() { return 'token'; }
74
74
  async extractTokenInfoInternal() { return { idToken: 'token', expiresAt: 0 }; }
@@ -87,7 +87,7 @@ describe('MJAuthBase', () => {
87
87
  type = 'test';
88
88
  async initialize() { }
89
89
  async loginInternal() { }
90
- async logout() { }
90
+ async logoutInternal() { }
91
91
  async handleCallback() { }
92
92
  async extractIdTokenInternal() { return 'token'; }
93
93
  async extractTokenInfoInternal() { return { idToken: 'token', expiresAt: 0 }; }
@@ -107,7 +107,7 @@ describe('MJAuthBase', () => {
107
107
  type = 'test';
108
108
  async initialize() { }
109
109
  async loginInternal() { }
110
- async logout() { }
110
+ async logoutInternal() { }
111
111
  async handleCallback() { }
112
112
  async extractIdTokenInternal() { return 'token'; }
113
113
  async extractTokenInfoInternal() { return { idToken: 'token', expiresAt: 0 }; }
@@ -125,7 +125,7 @@ describe('MJAuthBase', () => {
125
125
  type = 'test';
126
126
  async initialize() { }
127
127
  async loginInternal() { }
128
- async logout() { }
128
+ async logoutInternal() { }
129
129
  async handleCallback() { }
130
130
  async extractIdTokenInternal() { return 'token'; }
131
131
  async extractTokenInfoInternal() { return { idToken: 'token', expiresAt: 0 }; }
@@ -145,7 +145,7 @@ describe('MJAuthBase', () => {
145
145
  type = 'test';
146
146
  async initialize() { }
147
147
  async loginInternal() { }
148
- async logout() { }
148
+ async logoutInternal() { }
149
149
  async handleCallback() { }
150
150
  async extractIdTokenInternal() { return 'token'; }
151
151
  async extractTokenInfoInternal() { return { idToken: 'token', expiresAt: 0 }; }
@@ -165,7 +165,7 @@ describe('MJAuthBase', () => {
165
165
  type = 'test';
166
166
  async initialize() { }
167
167
  async loginInternal() { }
168
- async logout() { }
168
+ async logoutInternal() { }
169
169
  async handleCallback() { }
170
170
  async extractIdTokenInternal() { return 'token'; }
171
171
  async extractTokenInfoInternal() { return { idToken: 'token', expiresAt: 0 }; }
@@ -185,7 +185,7 @@ describe('MJAuthBase', () => {
185
185
  type = 'test';
186
186
  async initialize() { }
187
187
  async loginInternal() { }
188
- async logout() { }
188
+ async logoutInternal() { }
189
189
  async handleCallback() { }
190
190
  async extractIdTokenInternal() { return 'my-test-token'; }
191
191
  async extractTokenInfoInternal() { return { idToken: 'token', expiresAt: 0 }; }
@@ -204,7 +204,7 @@ describe('MJAuthBase', () => {
204
204
  type = 'test';
205
205
  async initialize() { }
206
206
  async loginInternal() { }
207
- async logout() { }
207
+ async logoutInternal() { }
208
208
  async handleCallback() { }
209
209
  async extractIdTokenInternal() { return 'token'; }
210
210
  async extractTokenInfoInternal() { return { idToken: 'token', expiresAt: 0 }; }
@@ -220,6 +220,142 @@ describe('MJAuthBase', () => {
220
220
  expect(typeof result.subscribe).toBe('function');
221
221
  });
222
222
  });
223
+ // ======================= logout and cache clearing =======================
224
+ describe('logout and cache clearing', () => {
225
+ let MJAuthBase;
226
+ beforeEach(async () => {
227
+ global.window = { location: { pathname: '/test', search: '' } };
228
+ const mod = await import('../mjexplorer-auth-base.service');
229
+ MJAuthBase = mod.MJAuthBase;
230
+ });
231
+ afterEach(() => {
232
+ vi.unstubAllGlobals();
233
+ });
234
+ /**
235
+ * Build a minimal TestProvider. The logoutSpy tracks logoutInternal calls.
236
+ * Pass preservedKeys to override the default preservedLocalStorageKeys getter.
237
+ */
238
+ function makeProvider(preservedKeys) {
239
+ const logoutSpy = vi.fn().mockResolvedValue(undefined);
240
+ class TestProvider extends MJAuthBase {
241
+ type = 'test';
242
+ logoutSpy = logoutSpy;
243
+ async initialize() { }
244
+ async loginInternal() { }
245
+ async logoutInternal() { return logoutSpy(); }
246
+ async handleCallback() { }
247
+ async extractIdTokenInternal() { return 'token'; }
248
+ async extractTokenInfoInternal() { return { idToken: 'token', expiresAt: 0 }; }
249
+ async extractUserInfoInternal() { return { id: '1', email: 'a@b.c', name: 'Test' }; }
250
+ async refreshTokenInternal() { return { success: true, token: { idToken: 'token', expiresAt: 0 } }; }
251
+ classifyErrorInternal() { return { type: 'UNKNOWN_ERROR', message: 'err' }; }
252
+ async getProfilePictureUrlInternal() { return null; }
253
+ async handleSessionExpiryInternal() { }
254
+ get preservedLocalStorageKeys() {
255
+ return preservedKeys ?? super.preservedLocalStorageKeys;
256
+ }
257
+ }
258
+ return new TestProvider({ name: 'test', type: 'test', clientId: 'test-client' });
259
+ }
260
+ /** Stub localStorage with a fixed set of key/value pairs, return a spy on removeItem. */
261
+ function stubLocalStorage(items) {
262
+ const keys = Object.keys(items);
263
+ const removeItem = vi.fn();
264
+ vi.stubGlobal('localStorage', {
265
+ length: keys.length,
266
+ key: (i) => keys[i] ?? null,
267
+ removeItem,
268
+ });
269
+ return { removeItem };
270
+ }
271
+ /** Stub indexedDB.deleteDatabase to resolve immediately via onsuccess. */
272
+ function stubIndexedDB() {
273
+ const deleteDatabase = vi.fn(() => {
274
+ const req = {};
275
+ Object.defineProperty(req, 'onsuccess', { configurable: true, set(fn) { fn(); } });
276
+ Object.defineProperty(req, 'onerror', { configurable: true, set() { } });
277
+ Object.defineProperty(req, 'onblocked', { configurable: true, set() { } });
278
+ return req;
279
+ });
280
+ vi.stubGlobal('indexedDB', { deleteDatabase });
281
+ return { deleteDatabase };
282
+ }
283
+ it('should call logoutInternal during logout', async () => {
284
+ stubLocalStorage({});
285
+ stubIndexedDB();
286
+ const provider = makeProvider();
287
+ await provider.logout();
288
+ expect(provider.logoutSpy).toHaveBeenCalledOnce();
289
+ });
290
+ it('should remove non-preserved localStorage keys on logout', async () => {
291
+ const { removeItem } = stubLocalStorage({
292
+ 'mj-session-id': 'abc',
293
+ 'auth0.token': 'xyz',
294
+ 'mj-login-theme': 'dark',
295
+ });
296
+ stubIndexedDB();
297
+ await makeProvider().logout();
298
+ expect(removeItem).toHaveBeenCalledWith('mj-session-id');
299
+ expect(removeItem).toHaveBeenCalledWith('auth0.token');
300
+ expect(removeItem).not.toHaveBeenCalledWith('mj-login-theme');
301
+ });
302
+ it('should preserve mj-login-theme by default even when it is the only key', async () => {
303
+ const { removeItem } = stubLocalStorage({ 'mj-login-theme': 'dark' });
304
+ stubIndexedDB();
305
+ await makeProvider().logout();
306
+ expect(removeItem).not.toHaveBeenCalled();
307
+ });
308
+ it('should delete the MJ_Metadata IndexedDB on logout', async () => {
309
+ stubLocalStorage({});
310
+ const { deleteDatabase } = stubIndexedDB();
311
+ await makeProvider().logout();
312
+ expect(deleteDatabase).toHaveBeenCalledWith('MJ_Metadata');
313
+ });
314
+ it('should clear caches before calling logoutInternal', async () => {
315
+ const callOrder = [];
316
+ const deleteDatabase = vi.fn(() => {
317
+ callOrder.push('clearCaches');
318
+ const req = {};
319
+ Object.defineProperty(req, 'onsuccess', { configurable: true, set(fn) { fn(); } });
320
+ Object.defineProperty(req, 'onerror', { configurable: true, set() { } });
321
+ Object.defineProperty(req, 'onblocked', { configurable: true, set() { } });
322
+ return req;
323
+ });
324
+ vi.stubGlobal('indexedDB', { deleteDatabase });
325
+ stubLocalStorage({});
326
+ const logoutSpy = vi.fn().mockImplementation(async () => {
327
+ callOrder.push('logoutInternal');
328
+ });
329
+ class OrderTestProvider extends MJAuthBase {
330
+ type = 'test';
331
+ async initialize() { }
332
+ async loginInternal() { }
333
+ async logoutInternal() { return logoutSpy(); }
334
+ async handleCallback() { }
335
+ async extractIdTokenInternal() { return 'token'; }
336
+ async extractTokenInfoInternal() { return { idToken: 'token', expiresAt: 0 }; }
337
+ async extractUserInfoInternal() { return { id: '1', email: 'a@b.c', name: 'Test' }; }
338
+ async refreshTokenInternal() { return { success: true, token: { idToken: 'token', expiresAt: 0 } }; }
339
+ classifyErrorInternal() { return { type: 'UNKNOWN_ERROR', message: 'err' }; }
340
+ async getProfilePictureUrlInternal() { return null; }
341
+ async handleSessionExpiryInternal() { }
342
+ }
343
+ await new OrderTestProvider({ name: 'test', type: 'test', clientId: 'test-client' }).logout();
344
+ expect(callOrder).toEqual(['clearCaches', 'logoutInternal']);
345
+ });
346
+ it('should respect overridden preservedLocalStorageKeys in a subclass', async () => {
347
+ const { removeItem } = stubLocalStorage({
348
+ 'mj-login-theme': 'dark',
349
+ 'my-app-setting': 'value',
350
+ 'session-data': 'to-remove',
351
+ });
352
+ stubIndexedDB();
353
+ await makeProvider(new Set(['mj-login-theme', 'my-app-setting'])).logout();
354
+ expect(removeItem).toHaveBeenCalledWith('session-data');
355
+ expect(removeItem).not.toHaveBeenCalledWith('mj-login-theme');
356
+ expect(removeItem).not.toHaveBeenCalledWith('my-app-setting');
357
+ });
358
+ });
223
359
  // ======================= AngularAuthProviderFactory =======================
224
360
  describe('AngularAuthProviderFactory', () => {
225
361
  let Factory;
@@ -1 +1 @@
1
- {"version":3,"file":"auth-services.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/auth-services.test.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Tests for auth-services package:\n * - AngularAuthProviderFactory\n * - Auth types\n * - MJAuthBase (via dynamic import)\n */\nimport { describe, it, expect, vi, beforeEach } from 'vitest';\nimport { AuthErrorType } from '../auth-types';\n\n// Mock Angular\nvi.mock('@angular/core', () => ({\n Injectable: () => (target: Function) => target,\n Injector: class {},\n}));\n\nvi.mock('@memberjunction/global', () => ({\n MJGlobal: {\n Instance: {\n ClassFactory: {\n CreateInstance: vi.fn(),\n GetRegistrationsByRootClass: vi.fn(() => []),\n GetRegistration: vi.fn(),\n },\n }\n },\n}));\n\nvi.mock('@memberjunction/core', () => ({\n AuthProviderConfig: class {},\n}));\n\nvi.mock('rxjs', async () => {\n const actual = await vi.importActual<typeof import('rxjs')>('rxjs');\n return actual;\n});\n\n// ======================= Auth types =======================\ndescribe('AuthErrorType enum', () => {\n it('should have expected error types', async () => {\n const { AuthErrorType } = await import('../auth-types');\n expect(AuthErrorType.TOKEN_EXPIRED).toBe('TOKEN_EXPIRED');\n expect(AuthErrorType.NO_ACTIVE_SESSION).toBe('NO_ACTIVE_SESSION');\n expect(AuthErrorType.INTERACTION_REQUIRED).toBe('INTERACTION_REQUIRED');\n expect(AuthErrorType.USER_CANCELLED).toBe('USER_CANCELLED');\n expect(AuthErrorType.NETWORK_ERROR).toBe('NETWORK_ERROR');\n expect(AuthErrorType.CONFIGURATION_ERROR).toBe('CONFIGURATION_ERROR');\n expect(AuthErrorType.UNKNOWN_ERROR).toBe('UNKNOWN_ERROR');\n });\n});\n\n// ======================= IAuthProvider interface =======================\ndescribe('IAuthProvider interface', () => {\n it('should export the interface module', async () => {\n const mod = await import('../IAuthProvider');\n expect(mod).toBeDefined();\n });\n});\n\n// ======================= MJAuthBase =======================\ndescribe('MJAuthBase', () => {\n let MJAuthBase: typeof import('../mjexplorer-auth-base.service').MJAuthBase;\n\n beforeEach(async () => {\n // Mock window before importing\n (global as Record<string, unknown>).window = { location: { pathname: '/test', search: '?q=1' } };\n\n const mod = await import('../mjexplorer-auth-base.service');\n MJAuthBase = mod.MJAuthBase;\n });\n\n it('should be importable', () => {\n expect(MJAuthBase).toBeDefined();\n });\n\n it('should capture initial window location in constructor', () => {\n // Create a concrete test subclass inline\n class TestProvider extends MJAuthBase {\n readonly type = 'test';\n async initialize(): Promise<void> {}\n protected async loginInternal(): Promise<void> {}\n async logout(): Promise<void> {}\n async handleCallback(): Promise<void> {}\n protected async extractIdTokenInternal() { return 'token'; }\n protected async extractTokenInfoInternal() { return { idToken: 'token', expiresAt: 0 }; }\n protected async extractUserInfoInternal() { return { id: '1', email: 'a@b.c', name: 'Test' }; }\n protected async refreshTokenInternal() { return { success: true, token: { idToken: 'token', expiresAt: 0 } }; }\n protected classifyErrorInternal() { return { type: 'UNKNOWN_ERROR' as AuthErrorType, message: 'err' }; }\n protected async getProfilePictureUrlInternal() { return null; }\n protected async handleSessionExpiryInternal() {}\n }\n\n const provider = new TestProvider({ name: 'test', type: 'test', clientId: 'test-client' });\n expect(provider.initialPath).toBe('/test');\n expect(provider.initialSearch).toBe('?q=1');\n });\n\n it('should validate config with clientId', () => {\n class TestProvider extends MJAuthBase {\n readonly type = 'test';\n async initialize(): Promise<void> {}\n protected async loginInternal(): Promise<void> {}\n async logout(): Promise<void> {}\n async handleCallback(): Promise<void> {}\n protected async extractIdTokenInternal() { return 'token'; }\n protected async extractTokenInfoInternal() { return { idToken: 'token', expiresAt: 0 }; }\n protected async extractUserInfoInternal() { return { id: '1', email: 'a@b.c', name: 'Test' }; }\n protected async refreshTokenInternal() { return { success: true, token: { idToken: 'token', expiresAt: 0 } }; }\n protected classifyErrorInternal() { return { type: 'UNKNOWN_ERROR' as AuthErrorType, message: 'err' }; }\n protected async getProfilePictureUrlInternal() { return null; }\n protected async handleSessionExpiryInternal() {}\n }\n\n const provider = new TestProvider({ name: 'test', type: 'test', clientId: 'test-client' });\n expect(provider.validateConfig({ clientId: 'my-client' })).toBe(true);\n expect(provider.validateConfig({})).toBe(false);\n expect(provider.validateConfig({ clientId: '' })).toBe(false);\n });\n\n it('should return clientId as required config', () => {\n class TestProvider extends MJAuthBase {\n readonly type = 'test';\n async initialize(): Promise<void> {}\n protected async loginInternal(): Promise<void> {}\n async logout(): Promise<void> {}\n async handleCallback(): Promise<void> {}\n protected async extractIdTokenInternal() { return 'token'; }\n protected async extractTokenInfoInternal() { return { idToken: 'token', expiresAt: 0 }; }\n protected async extractUserInfoInternal() { return { id: '1', email: 'a@b.c', name: 'Test' }; }\n protected async refreshTokenInternal() { return { success: true, token: { idToken: 'token', expiresAt: 0 } }; }\n protected classifyErrorInternal() { return { type: 'UNKNOWN_ERROR' as AuthErrorType, message: 'err' }; }\n protected async getProfilePictureUrlInternal() { return null; }\n protected async handleSessionExpiryInternal() {}\n }\n\n const provider = new TestProvider({ name: 'test', type: 'test', clientId: 'test-client' });\n expect(provider.getRequiredConfig()).toEqual(['clientId']);\n });\n\n it('should emit false for isAuthenticated initially', () => {\n class TestProvider extends MJAuthBase {\n readonly type = 'test';\n async initialize(): Promise<void> {}\n protected async loginInternal(): Promise<void> {}\n async logout(): Promise<void> {}\n async handleCallback(): Promise<void> {}\n protected async extractIdTokenInternal() { return 'token'; }\n protected async extractTokenInfoInternal() { return { idToken: 'token', expiresAt: 0 }; }\n protected async extractUserInfoInternal() { return { id: '1', email: 'a@b.c', name: 'Test' }; }\n protected async refreshTokenInternal() { return { success: true, token: { idToken: 'token', expiresAt: 0 } }; }\n protected classifyErrorInternal() { return { type: 'UNKNOWN_ERROR' as AuthErrorType, message: 'err' }; }\n protected async getProfilePictureUrlInternal() { return null; }\n protected async handleSessionExpiryInternal() {}\n }\n\n const provider = new TestProvider({ name: 'test', type: 'test', clientId: 'test-client' });\n let value: boolean | undefined;\n provider.isAuthenticated().subscribe(v => value = v);\n expect(value).toBe(false);\n });\n\n it('should emit null for getUserInfo initially', () => {\n class TestProvider extends MJAuthBase {\n readonly type = 'test';\n async initialize(): Promise<void> {}\n protected async loginInternal(): Promise<void> {}\n async logout(): Promise<void> {}\n async handleCallback(): Promise<void> {}\n protected async extractIdTokenInternal() { return 'token'; }\n protected async extractTokenInfoInternal() { return { idToken: 'token', expiresAt: 0 }; }\n protected async extractUserInfoInternal() { return { id: '1', email: 'a@b.c', name: 'Test' }; }\n protected async refreshTokenInternal() { return { success: true, token: { idToken: 'token', expiresAt: 0 } }; }\n protected classifyErrorInternal() { return { type: 'UNKNOWN_ERROR' as AuthErrorType, message: 'err' }; }\n protected async getProfilePictureUrlInternal() { return null; }\n protected async handleSessionExpiryInternal() {}\n }\n\n const provider = new TestProvider({ name: 'test', type: 'test', clientId: 'test-client' });\n let value: unknown = 'not-null';\n provider.getUserInfo().subscribe(v => value = v);\n expect(value).toBeNull();\n });\n\n it('should delegate classifyError to classifyErrorInternal', () => {\n class TestProvider extends MJAuthBase {\n readonly type = 'test';\n async initialize(): Promise<void> {}\n protected async loginInternal(): Promise<void> {}\n async logout(): Promise<void> {}\n async handleCallback(): Promise<void> {}\n protected async extractIdTokenInternal() { return 'token'; }\n protected async extractTokenInfoInternal() { return { idToken: 'token', expiresAt: 0 }; }\n protected async extractUserInfoInternal() { return { id: '1', email: 'a@b.c', name: 'Test' }; }\n protected async refreshTokenInternal() { return { success: true, token: { idToken: 'token', expiresAt: 0 } }; }\n protected classifyErrorInternal() { return { type: 'UNKNOWN_ERROR' as AuthErrorType, message: 'Custom error msg' }; }\n protected async getProfilePictureUrlInternal() { return null; }\n protected async handleSessionExpiryInternal() {}\n }\n\n const provider = new TestProvider({ name: 'test', type: 'test', clientId: 'test-client' });\n const result = provider.classifyError(new Error('test'));\n expect(result.type).toBe('UNKNOWN_ERROR');\n expect(result.message).toBe('Custom error msg');\n });\n\n it('should return token from getIdToken', async () => {\n class TestProvider extends MJAuthBase {\n readonly type = 'test';\n async initialize(): Promise<void> {}\n protected async loginInternal(): Promise<void> {}\n async logout(): Promise<void> {}\n async handleCallback(): Promise<void> {}\n protected async extractIdTokenInternal() { return 'my-test-token'; }\n protected async extractTokenInfoInternal() { return { idToken: 'token', expiresAt: 0 }; }\n protected async extractUserInfoInternal() { return { id: '1', email: 'a@b.c', name: 'Test' }; }\n protected async refreshTokenInternal() { return { success: true, token: { idToken: 'token', expiresAt: 0 } }; }\n protected classifyErrorInternal() { return { type: 'UNKNOWN_ERROR' as AuthErrorType, message: 'err' }; }\n protected async getProfilePictureUrlInternal() { return null; }\n protected async handleSessionExpiryInternal() {}\n }\n\n const provider = new TestProvider({ name: 'test', type: 'test', clientId: 'test-client' });\n const token = await provider.getIdToken();\n expect(token).toBe('my-test-token');\n });\n\n it('should return an observable from login', () => {\n class TestProvider extends MJAuthBase {\n readonly type = 'test';\n async initialize(): Promise<void> {}\n protected async loginInternal(): Promise<void> {}\n async logout(): Promise<void> {}\n async handleCallback(): Promise<void> {}\n protected async extractIdTokenInternal() { return 'token'; }\n protected async extractTokenInfoInternal() { return { idToken: 'token', expiresAt: 0 }; }\n protected async extractUserInfoInternal() { return { id: '1', email: 'a@b.c', name: 'Test' }; }\n protected async refreshTokenInternal() { return { success: true, token: { idToken: 'token', expiresAt: 0 } }; }\n protected classifyErrorInternal() { return { type: 'UNKNOWN_ERROR' as AuthErrorType, message: 'err' }; }\n protected async getProfilePictureUrlInternal() { return null; }\n protected async handleSessionExpiryInternal() {}\n }\n\n const provider = new TestProvider({ name: 'test', type: 'test', clientId: 'test-client' });\n const result = provider.login();\n expect(result).toBeDefined();\n expect(typeof result.subscribe).toBe('function');\n });\n});\n\n// ======================= AngularAuthProviderFactory =======================\ndescribe('AngularAuthProviderFactory', () => {\n let Factory: typeof import('../AngularAuthProviderFactory').AngularAuthProviderFactory;\n\n beforeEach(async () => {\n const mod = await import('../AngularAuthProviderFactory');\n Factory = mod.AngularAuthProviderFactory;\n });\n\n it('should create a new factory instance', () => {\n const factory = new Factory({ get: vi.fn() } as never);\n expect(factory).toBeDefined();\n });\n\n it('should return undefined for unregistered provider', () => {\n const factory = new Factory({ get: vi.fn() } as never);\n expect(factory.getProvider('nonexistent')).toBeUndefined();\n });\n\n it('should clear providers', () => {\n const factory = new Factory({ get: vi.fn() } as never);\n factory.clearProviders();\n expect(factory.getProvider('test')).toBeUndefined();\n });\n});\n"]}
1
+ {"version":3,"file":"auth-services.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/auth-services.test.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Tests for auth-services package:\n * - AngularAuthProviderFactory\n * - Auth types\n * - MJAuthBase (via dynamic import)\n */\nimport { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';\nimport { AuthErrorType } from '../auth-types';\n\n// Mock Angular\nvi.mock('@angular/core', () => ({\n Injectable: () => (target: Function) => target,\n Injector: class {},\n}));\n\nvi.mock('@memberjunction/global', () => ({\n MJGlobal: {\n Instance: {\n ClassFactory: {\n CreateInstance: vi.fn(),\n GetRegistrationsByRootClass: vi.fn(() => []),\n GetRegistration: vi.fn(),\n },\n }\n },\n}));\n\nvi.mock('@memberjunction/core', () => ({\n AuthProviderConfig: class {},\n}));\n\nvi.mock('rxjs', async () => {\n const actual = await vi.importActual<typeof import('rxjs')>('rxjs');\n return actual;\n});\n\n// ======================= Auth types =======================\ndescribe('AuthErrorType enum', () => {\n it('should have expected error types', async () => {\n const { AuthErrorType } = await import('../auth-types');\n expect(AuthErrorType.TOKEN_EXPIRED).toBe('TOKEN_EXPIRED');\n expect(AuthErrorType.NO_ACTIVE_SESSION).toBe('NO_ACTIVE_SESSION');\n expect(AuthErrorType.INTERACTION_REQUIRED).toBe('INTERACTION_REQUIRED');\n expect(AuthErrorType.USER_CANCELLED).toBe('USER_CANCELLED');\n expect(AuthErrorType.NETWORK_ERROR).toBe('NETWORK_ERROR');\n expect(AuthErrorType.CONFIGURATION_ERROR).toBe('CONFIGURATION_ERROR');\n expect(AuthErrorType.UNKNOWN_ERROR).toBe('UNKNOWN_ERROR');\n });\n});\n\n// ======================= IAuthProvider interface =======================\ndescribe('IAuthProvider interface', () => {\n it('should export the interface module', async () => {\n const mod = await import('../IAuthProvider');\n expect(mod).toBeDefined();\n });\n});\n\n// ======================= MJAuthBase =======================\ndescribe('MJAuthBase', () => {\n let MJAuthBase: typeof import('../mjexplorer-auth-base.service').MJAuthBase;\n\n beforeEach(async () => {\n // Mock window before importing\n (global as Record<string, unknown>).window = { location: { pathname: '/test', search: '?q=1' } };\n\n const mod = await import('../mjexplorer-auth-base.service');\n MJAuthBase = mod.MJAuthBase;\n });\n\n it('should be importable', () => {\n expect(MJAuthBase).toBeDefined();\n });\n\n it('should capture initial window location in constructor', () => {\n // Create a concrete test subclass inline\n class TestProvider extends MJAuthBase {\n readonly type = 'test';\n async initialize(): Promise<void> {}\n protected async loginInternal(): Promise<void> {}\n protected async logoutInternal(): Promise<void> {}\n async handleCallback(): Promise<void> {}\n protected async extractIdTokenInternal() { return 'token'; }\n protected async extractTokenInfoInternal() { return { idToken: 'token', expiresAt: 0 }; }\n protected async extractUserInfoInternal() { return { id: '1', email: 'a@b.c', name: 'Test' }; }\n protected async refreshTokenInternal() { return { success: true, token: { idToken: 'token', expiresAt: 0 } }; }\n protected classifyErrorInternal() { return { type: 'UNKNOWN_ERROR' as AuthErrorType, message: 'err' }; }\n protected async getProfilePictureUrlInternal() { return null; }\n protected async handleSessionExpiryInternal() {}\n }\n\n const provider = new TestProvider({ name: 'test', type: 'test', clientId: 'test-client' });\n expect(provider.initialPath).toBe('/test');\n expect(provider.initialSearch).toBe('?q=1');\n });\n\n it('should validate config with clientId', () => {\n class TestProvider extends MJAuthBase {\n readonly type = 'test';\n async initialize(): Promise<void> {}\n protected async loginInternal(): Promise<void> {}\n protected async logoutInternal(): Promise<void> {}\n async handleCallback(): Promise<void> {}\n protected async extractIdTokenInternal() { return 'token'; }\n protected async extractTokenInfoInternal() { return { idToken: 'token', expiresAt: 0 }; }\n protected async extractUserInfoInternal() { return { id: '1', email: 'a@b.c', name: 'Test' }; }\n protected async refreshTokenInternal() { return { success: true, token: { idToken: 'token', expiresAt: 0 } }; }\n protected classifyErrorInternal() { return { type: 'UNKNOWN_ERROR' as AuthErrorType, message: 'err' }; }\n protected async getProfilePictureUrlInternal() { return null; }\n protected async handleSessionExpiryInternal() {}\n }\n\n const provider = new TestProvider({ name: 'test', type: 'test', clientId: 'test-client' });\n expect(provider.validateConfig({ clientId: 'my-client' })).toBe(true);\n expect(provider.validateConfig({})).toBe(false);\n expect(provider.validateConfig({ clientId: '' })).toBe(false);\n });\n\n it('should return clientId as required config', () => {\n class TestProvider extends MJAuthBase {\n readonly type = 'test';\n async initialize(): Promise<void> {}\n protected async loginInternal(): Promise<void> {}\n protected async logoutInternal(): Promise<void> {}\n async handleCallback(): Promise<void> {}\n protected async extractIdTokenInternal() { return 'token'; }\n protected async extractTokenInfoInternal() { return { idToken: 'token', expiresAt: 0 }; }\n protected async extractUserInfoInternal() { return { id: '1', email: 'a@b.c', name: 'Test' }; }\n protected async refreshTokenInternal() { return { success: true, token: { idToken: 'token', expiresAt: 0 } }; }\n protected classifyErrorInternal() { return { type: 'UNKNOWN_ERROR' as AuthErrorType, message: 'err' }; }\n protected async getProfilePictureUrlInternal() { return null; }\n protected async handleSessionExpiryInternal() {}\n }\n\n const provider = new TestProvider({ name: 'test', type: 'test', clientId: 'test-client' });\n expect(provider.getRequiredConfig()).toEqual(['clientId']);\n });\n\n it('should emit false for isAuthenticated initially', () => {\n class TestProvider extends MJAuthBase {\n readonly type = 'test';\n async initialize(): Promise<void> {}\n protected async loginInternal(): Promise<void> {}\n protected async logoutInternal(): Promise<void> {}\n async handleCallback(): Promise<void> {}\n protected async extractIdTokenInternal() { return 'token'; }\n protected async extractTokenInfoInternal() { return { idToken: 'token', expiresAt: 0 }; }\n protected async extractUserInfoInternal() { return { id: '1', email: 'a@b.c', name: 'Test' }; }\n protected async refreshTokenInternal() { return { success: true, token: { idToken: 'token', expiresAt: 0 } }; }\n protected classifyErrorInternal() { return { type: 'UNKNOWN_ERROR' as AuthErrorType, message: 'err' }; }\n protected async getProfilePictureUrlInternal() { return null; }\n protected async handleSessionExpiryInternal() {}\n }\n\n const provider = new TestProvider({ name: 'test', type: 'test', clientId: 'test-client' });\n let value: boolean | undefined;\n provider.isAuthenticated().subscribe(v => value = v);\n expect(value).toBe(false);\n });\n\n it('should emit null for getUserInfo initially', () => {\n class TestProvider extends MJAuthBase {\n readonly type = 'test';\n async initialize(): Promise<void> {}\n protected async loginInternal(): Promise<void> {}\n protected async logoutInternal(): Promise<void> {}\n async handleCallback(): Promise<void> {}\n protected async extractIdTokenInternal() { return 'token'; }\n protected async extractTokenInfoInternal() { return { idToken: 'token', expiresAt: 0 }; }\n protected async extractUserInfoInternal() { return { id: '1', email: 'a@b.c', name: 'Test' }; }\n protected async refreshTokenInternal() { return { success: true, token: { idToken: 'token', expiresAt: 0 } }; }\n protected classifyErrorInternal() { return { type: 'UNKNOWN_ERROR' as AuthErrorType, message: 'err' }; }\n protected async getProfilePictureUrlInternal() { return null; }\n protected async handleSessionExpiryInternal() {}\n }\n\n const provider = new TestProvider({ name: 'test', type: 'test', clientId: 'test-client' });\n let value: unknown = 'not-null';\n provider.getUserInfo().subscribe(v => value = v);\n expect(value).toBeNull();\n });\n\n it('should delegate classifyError to classifyErrorInternal', () => {\n class TestProvider extends MJAuthBase {\n readonly type = 'test';\n async initialize(): Promise<void> {}\n protected async loginInternal(): Promise<void> {}\n protected async logoutInternal(): Promise<void> {}\n async handleCallback(): Promise<void> {}\n protected async extractIdTokenInternal() { return 'token'; }\n protected async extractTokenInfoInternal() { return { idToken: 'token', expiresAt: 0 }; }\n protected async extractUserInfoInternal() { return { id: '1', email: 'a@b.c', name: 'Test' }; }\n protected async refreshTokenInternal() { return { success: true, token: { idToken: 'token', expiresAt: 0 } }; }\n protected classifyErrorInternal() { return { type: 'UNKNOWN_ERROR' as AuthErrorType, message: 'Custom error msg' }; }\n protected async getProfilePictureUrlInternal() { return null; }\n protected async handleSessionExpiryInternal() {}\n }\n\n const provider = new TestProvider({ name: 'test', type: 'test', clientId: 'test-client' });\n const result = provider.classifyError(new Error('test'));\n expect(result.type).toBe('UNKNOWN_ERROR');\n expect(result.message).toBe('Custom error msg');\n });\n\n it('should return token from getIdToken', async () => {\n class TestProvider extends MJAuthBase {\n readonly type = 'test';\n async initialize(): Promise<void> {}\n protected async loginInternal(): Promise<void> {}\n protected async logoutInternal(): Promise<void> {}\n async handleCallback(): Promise<void> {}\n protected async extractIdTokenInternal() { return 'my-test-token'; }\n protected async extractTokenInfoInternal() { return { idToken: 'token', expiresAt: 0 }; }\n protected async extractUserInfoInternal() { return { id: '1', email: 'a@b.c', name: 'Test' }; }\n protected async refreshTokenInternal() { return { success: true, token: { idToken: 'token', expiresAt: 0 } }; }\n protected classifyErrorInternal() { return { type: 'UNKNOWN_ERROR' as AuthErrorType, message: 'err' }; }\n protected async getProfilePictureUrlInternal() { return null; }\n protected async handleSessionExpiryInternal() {}\n }\n\n const provider = new TestProvider({ name: 'test', type: 'test', clientId: 'test-client' });\n const token = await provider.getIdToken();\n expect(token).toBe('my-test-token');\n });\n\n it('should return an observable from login', () => {\n class TestProvider extends MJAuthBase {\n readonly type = 'test';\n async initialize(): Promise<void> {}\n protected async loginInternal(): Promise<void> {}\n protected async logoutInternal(): Promise<void> {}\n async handleCallback(): Promise<void> {}\n protected async extractIdTokenInternal() { return 'token'; }\n protected async extractTokenInfoInternal() { return { idToken: 'token', expiresAt: 0 }; }\n protected async extractUserInfoInternal() { return { id: '1', email: 'a@b.c', name: 'Test' }; }\n protected async refreshTokenInternal() { return { success: true, token: { idToken: 'token', expiresAt: 0 } }; }\n protected classifyErrorInternal() { return { type: 'UNKNOWN_ERROR' as AuthErrorType, message: 'err' }; }\n protected async getProfilePictureUrlInternal() { return null; }\n protected async handleSessionExpiryInternal() {}\n }\n\n const provider = new TestProvider({ name: 'test', type: 'test', clientId: 'test-client' });\n const result = provider.login();\n expect(result).toBeDefined();\n expect(typeof result.subscribe).toBe('function');\n });\n});\n\n// ======================= logout and cache clearing =======================\ndescribe('logout and cache clearing', () => {\n let MJAuthBase: typeof import('../mjexplorer-auth-base.service').MJAuthBase;\n\n beforeEach(async () => {\n (global as Record<string, unknown>).window = { location: { pathname: '/test', search: '' } };\n const mod = await import('../mjexplorer-auth-base.service');\n MJAuthBase = mod.MJAuthBase;\n });\n\n afterEach(() => {\n vi.unstubAllGlobals();\n });\n\n /**\n * Build a minimal TestProvider. The logoutSpy tracks logoutInternal calls.\n * Pass preservedKeys to override the default preservedLocalStorageKeys getter.\n */\n function makeProvider(preservedKeys?: Set<string>) {\n const logoutSpy = vi.fn<() => Promise<void>>().mockResolvedValue(undefined);\n class TestProvider extends MJAuthBase {\n readonly type = 'test';\n readonly logoutSpy = logoutSpy;\n async initialize(): Promise<void> {}\n protected async loginInternal(): Promise<void> {}\n protected async logoutInternal(): Promise<void> { return logoutSpy(); }\n async handleCallback(): Promise<void> {}\n protected async extractIdTokenInternal() { return 'token'; }\n protected async extractTokenInfoInternal() { return { idToken: 'token', expiresAt: 0 }; }\n protected async extractUserInfoInternal() { return { id: '1', email: 'a@b.c', name: 'Test' }; }\n protected async refreshTokenInternal() { return { success: true as const, token: { idToken: 'token', expiresAt: 0 } }; }\n protected classifyErrorInternal() { return { type: 'UNKNOWN_ERROR' as AuthErrorType, message: 'err' }; }\n protected async getProfilePictureUrlInternal() { return null; }\n protected async handleSessionExpiryInternal() {}\n override get preservedLocalStorageKeys(): Set<string> {\n return preservedKeys ?? super.preservedLocalStorageKeys;\n }\n }\n return new TestProvider({ name: 'test', type: 'test', clientId: 'test-client' });\n }\n\n /** Stub localStorage with a fixed set of key/value pairs, return a spy on removeItem. */\n function stubLocalStorage(items: Record<string, string>) {\n const keys = Object.keys(items);\n const removeItem = vi.fn();\n vi.stubGlobal('localStorage', {\n length: keys.length,\n key: (i: number) => keys[i] ?? null,\n removeItem,\n });\n return { removeItem };\n }\n\n /** Stub indexedDB.deleteDatabase to resolve immediately via onsuccess. */\n function stubIndexedDB() {\n const deleteDatabase = vi.fn(() => {\n const req = {} as Record<string, unknown>;\n Object.defineProperty(req, 'onsuccess', { configurable: true, set(fn: () => void) { fn(); } });\n Object.defineProperty(req, 'onerror', { configurable: true, set() {} });\n Object.defineProperty(req, 'onblocked', { configurable: true, set() {} });\n return req;\n });\n vi.stubGlobal('indexedDB', { deleteDatabase });\n return { deleteDatabase };\n }\n\n it('should call logoutInternal during logout', async () => {\n stubLocalStorage({});\n stubIndexedDB();\n const provider = makeProvider();\n await provider.logout();\n expect(provider.logoutSpy).toHaveBeenCalledOnce();\n });\n\n it('should remove non-preserved localStorage keys on logout', async () => {\n const { removeItem } = stubLocalStorage({\n 'mj-session-id': 'abc',\n 'auth0.token': 'xyz',\n 'mj-login-theme': 'dark',\n });\n stubIndexedDB();\n await makeProvider().logout();\n expect(removeItem).toHaveBeenCalledWith('mj-session-id');\n expect(removeItem).toHaveBeenCalledWith('auth0.token');\n expect(removeItem).not.toHaveBeenCalledWith('mj-login-theme');\n });\n\n it('should preserve mj-login-theme by default even when it is the only key', async () => {\n const { removeItem } = stubLocalStorage({ 'mj-login-theme': 'dark' });\n stubIndexedDB();\n await makeProvider().logout();\n expect(removeItem).not.toHaveBeenCalled();\n });\n\n it('should delete the MJ_Metadata IndexedDB on logout', async () => {\n stubLocalStorage({});\n const { deleteDatabase } = stubIndexedDB();\n await makeProvider().logout();\n expect(deleteDatabase).toHaveBeenCalledWith('MJ_Metadata');\n });\n\n it('should clear caches before calling logoutInternal', async () => {\n const callOrder: string[] = [];\n const deleteDatabase = vi.fn(() => {\n callOrder.push('clearCaches');\n const req = {} as Record<string, unknown>;\n Object.defineProperty(req, 'onsuccess', { configurable: true, set(fn: () => void) { fn(); } });\n Object.defineProperty(req, 'onerror', { configurable: true, set() {} });\n Object.defineProperty(req, 'onblocked', { configurable: true, set() {} });\n return req;\n });\n vi.stubGlobal('indexedDB', { deleteDatabase });\n stubLocalStorage({});\n\n const logoutSpy = vi.fn<() => Promise<void>>().mockImplementation(async () => {\n callOrder.push('logoutInternal');\n });\n class OrderTestProvider extends MJAuthBase {\n readonly type = 'test';\n async initialize(): Promise<void> {}\n protected async loginInternal(): Promise<void> {}\n protected async logoutInternal(): Promise<void> { return logoutSpy(); }\n async handleCallback(): Promise<void> {}\n protected async extractIdTokenInternal() { return 'token'; }\n protected async extractTokenInfoInternal() { return { idToken: 'token', expiresAt: 0 }; }\n protected async extractUserInfoInternal() { return { id: '1', email: 'a@b.c', name: 'Test' }; }\n protected async refreshTokenInternal() { return { success: true as const, token: { idToken: 'token', expiresAt: 0 } }; }\n protected classifyErrorInternal() { return { type: 'UNKNOWN_ERROR' as AuthErrorType, message: 'err' }; }\n protected async getProfilePictureUrlInternal() { return null; }\n protected async handleSessionExpiryInternal() {}\n }\n await new OrderTestProvider({ name: 'test', type: 'test', clientId: 'test-client' }).logout();\n expect(callOrder).toEqual(['clearCaches', 'logoutInternal']);\n });\n\n it('should respect overridden preservedLocalStorageKeys in a subclass', async () => {\n const { removeItem } = stubLocalStorage({\n 'mj-login-theme': 'dark',\n 'my-app-setting': 'value',\n 'session-data': 'to-remove',\n });\n stubIndexedDB();\n await makeProvider(new Set(['mj-login-theme', 'my-app-setting'])).logout();\n expect(removeItem).toHaveBeenCalledWith('session-data');\n expect(removeItem).not.toHaveBeenCalledWith('mj-login-theme');\n expect(removeItem).not.toHaveBeenCalledWith('my-app-setting');\n });\n});\n\n// ======================= AngularAuthProviderFactory =======================\ndescribe('AngularAuthProviderFactory', () => {\n let Factory: typeof import('../AngularAuthProviderFactory').AngularAuthProviderFactory;\n\n beforeEach(async () => {\n const mod = await import('../AngularAuthProviderFactory');\n Factory = mod.AngularAuthProviderFactory;\n });\n\n it('should create a new factory instance', () => {\n const factory = new Factory({ get: vi.fn() } as never);\n expect(factory).toBeDefined();\n });\n\n it('should return undefined for unregistered provider', () => {\n const factory = new Factory({ get: vi.fn() } as never);\n expect(factory.getProvider('nonexistent')).toBeUndefined();\n });\n\n it('should clear providers', () => {\n const factory = new Factory({ get: vi.fn() } as never);\n factory.clearProviders();\n expect(factory.getProvider('test')).toBeUndefined();\n });\n});\n"]}
@@ -60,11 +60,13 @@ export declare abstract class MJAuthBase implements IAngularAuthProvider {
60
60
  */
61
61
  protected abstract loginInternal(options?: Record<string, unknown>): Promise<void>;
62
62
  /**
63
- * Logout implementation
63
+ * Provider-specific logout implementation
64
64
  *
65
- * Subclasses implement provider-specific logout flow.
65
+ * Subclasses implement provider-specific logout flow (redirect, SDK logout, etc.).
66
+ * The base class `logout()` calls `clearClientCaches()` before invoking this method,
67
+ * so providers do NOT need to handle cache clearing themselves.
66
68
  */
67
- abstract logout(): Promise<void>;
69
+ protected abstract logoutInternal(): Promise<void>;
68
70
  /**
69
71
  * Handle OAuth callback
70
72
  *
@@ -157,6 +159,30 @@ export declare abstract class MJAuthBase implements IAngularAuthProvider {
157
159
  * - `this.authBase.login().subscribe()` (Observable)
158
160
  */
159
161
  login(options?: Record<string, unknown>): Observable<void>;
162
+ /**
163
+ * Logout — clears all MJ client-side caches then delegates to the provider.
164
+ *
165
+ * Cache clearing happens universally regardless of auth provider so that a
166
+ * subsequent login as a different user never sees the previous user's data.
167
+ * Providers that need to clear additional caches should override
168
+ * `logoutInternal()` and call `super.logoutInternal()` if applicable.
169
+ */
170
+ logout(): Promise<void>;
171
+ /**
172
+ * localStorage keys that survive a logout (e.g. UI theme preference).
173
+ *
174
+ * Override this getter in a subclass to preserve additional keys specific
175
+ * to your provider or application.
176
+ */
177
+ protected get preservedLocalStorageKeys(): Set<string>;
178
+ /**
179
+ * Clears MJ client-side caches before logout.
180
+ *
181
+ * Removes all localStorage entries except those returned by
182
+ * `preservedLocalStorageKeys`, and deletes the `MJ_Metadata` IndexedDB
183
+ * database so a subsequent user session starts with a clean slate.
184
+ */
185
+ protected clearClientCaches(): Promise<void>;
160
186
  /**
161
187
  * Check if user is authenticated (Observable stream)
162
188
  *
@@ -1 +1 @@
1
- {"version":3,"file":"mjexplorer-auth-base.service.d.ts","sourceRoot":"","sources":["../../src/lib/mjexplorer-auth-base.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mjexplorer-auth-base.service.d.ts","sourceRoot":"","sources":["../../src/lib/mjexplorer-auth-base.service.ts"],"names":[],"mappings":"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"}
@@ -61,6 +61,51 @@ export class MJAuthBase {
61
61
  login(options) {
62
62
  return from(this.loginInternal(options));
63
63
  }
64
+ /**
65
+ * Logout — clears all MJ client-side caches then delegates to the provider.
66
+ *
67
+ * Cache clearing happens universally regardless of auth provider so that a
68
+ * subsequent login as a different user never sees the previous user's data.
69
+ * Providers that need to clear additional caches should override
70
+ * `logoutInternal()` and call `super.logoutInternal()` if applicable.
71
+ */
72
+ async logout() {
73
+ await this.clearClientCaches();
74
+ await this.logoutInternal();
75
+ }
76
+ /**
77
+ * localStorage keys that survive a logout (e.g. UI theme preference).
78
+ *
79
+ * Override this getter in a subclass to preserve additional keys specific
80
+ * to your provider or application.
81
+ */
82
+ get preservedLocalStorageKeys() {
83
+ return new Set(['mj-login-theme']);
84
+ }
85
+ /**
86
+ * Clears MJ client-side caches before logout.
87
+ *
88
+ * Removes all localStorage entries except those returned by
89
+ * `preservedLocalStorageKeys`, and deletes the `MJ_Metadata` IndexedDB
90
+ * database so a subsequent user session starts with a clean slate.
91
+ */
92
+ async clearClientCaches() {
93
+ const preserved = this.preservedLocalStorageKeys;
94
+ const keysToRemove = [];
95
+ for (let i = 0; i < localStorage.length; i++) {
96
+ const key = localStorage.key(i);
97
+ if (key && !preserved.has(key)) {
98
+ keysToRemove.push(key);
99
+ }
100
+ }
101
+ keysToRemove.forEach(key => localStorage.removeItem(key));
102
+ await new Promise((resolve) => {
103
+ const req = indexedDB.deleteDatabase('MJ_Metadata');
104
+ req.onsuccess = () => resolve();
105
+ req.onerror = () => resolve();
106
+ req.onblocked = () => resolve();
107
+ });
108
+ }
64
109
  /**
65
110
  * Check if user is authenticated (Observable stream)
66
111
  *