@memberjunction/ng-auth-services 5.14.0 → 5.15.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.
- package/dist/lib/__tests__/auth-services.test.js +145 -9
- package/dist/lib/__tests__/auth-services.test.js.map +1 -1
- package/dist/lib/mjexplorer-auth-base.service.d.ts +29 -3
- package/dist/lib/mjexplorer-auth-base.service.d.ts.map +1 -1
- package/dist/lib/mjexplorer-auth-base.service.js +45 -0
- package/dist/lib/mjexplorer-auth-base.service.js.map +1 -1
- package/dist/lib/providers/mjexplorer-auth0-provider.service.d.ts +1 -1
- package/dist/lib/providers/mjexplorer-auth0-provider.service.d.ts.map +1 -1
- package/dist/lib/providers/mjexplorer-auth0-provider.service.js +8 -2
- package/dist/lib/providers/mjexplorer-auth0-provider.service.js.map +1 -1
- package/dist/lib/providers/mjexplorer-msal-provider.service.d.ts +1 -1
- package/dist/lib/providers/mjexplorer-msal-provider.service.d.ts.map +1 -1
- package/dist/lib/providers/mjexplorer-msal-provider.service.js +1 -1
- package/dist/lib/providers/mjexplorer-msal-provider.service.js.map +1 -1
- package/dist/lib/providers/mjexplorer-okta-provider.service.d.ts +1 -1
- package/dist/lib/providers/mjexplorer-okta-provider.service.d.ts.map +1 -1
- package/dist/lib/providers/mjexplorer-okta-provider.service.js +1 -1
- package/dist/lib/providers/mjexplorer-okta-provider.service.js.map +1 -1
- package/package.json +3 -3
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
*
|
|
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
|
|
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":"AACA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAQ,MAAM,MAAM,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAClF,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EACnB,MAAM,cAAc,CAAC;;AAEtB;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,8BACsB,UAAW,YAAW,oBAAoB;IAC9D,SAAS,CAAC,MAAM,EAAE,yBAAyB,CAAC;IAG5C,SAAS,CAAC,gBAAgB,2BAAuC;IACjE,SAAS,CAAC,SAAS,2CAAsD;IACzE,SAAS,CAAC,UAAU,0BAAmC;IAEvD,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,cAAc,CAAuB;IAE7C;;OAEG;IACH,IAAI,WAAW,IAAI,MAAM,GAAG,IAAI,CAE/B;IAED;;OAEG;IACH,IAAI,aAAa,IAAI,MAAM,GAAG,IAAI,CAEjC;IAED;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEnB,MAAM,EAAE,yBAAyB;IAU7C;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAEpC;;;;;OAKG;IACH,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAElF
|
|
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
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mjexplorer-auth-base.service.js","sourceRoot":"","sources":["../../src/lib/mjexplorer-auth-base.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@angular/core';\nimport { Observable, BehaviorSubject, from } from 'rxjs';\nimport { IAngularAuthProvider, AngularAuthProviderConfig } from './IAuthProvider';\nimport {\n StandardUserInfo,\n StandardAuthToken,\n StandardAuthError,\n TokenRefreshResult\n} from './auth-types';\n\n/**\n * Base class for Angular authentication providers - v3.0.0\n *\n * Provides common functionality and enforces the provider interface.\n * All concrete providers (MSAL, Auth0, Okta) should extend this class.\n *\n * ## Key Improvements in v3.0:\n * - Proper abstraction - no more leaky provider-specific logic\n * - Standardized types - no more `any` types\n * - Clean token access - no more `__raw || idToken` patterns\n * - Semantic error handling - no more provider-specific error checks\n *\n * ## For Provider Implementers:\n * Extend this class and implement the abstract methods:\n * - `extractIdTokenInternal()` - Extract token from provider storage\n * - `extractTokenInfoInternal()` - Extract full token info\n * - `extractUserInfoInternal()` - Map claims to StandardUserInfo\n * - `refreshTokenInternal()` - Implement refresh mechanism\n * - `classifyErrorInternal()` - Map errors to AuthErrorType\n *\n * @version 3.0.0\n */\n@Injectable()\nexport abstract class MJAuthBase implements IAngularAuthProvider {\n protected config: AngularAuthProviderConfig;\n\n // State management with proper types (no more 'any'!)\n protected isAuthenticated$ = new BehaviorSubject<boolean>(false);\n protected userInfo$ = new BehaviorSubject<StandardUserInfo | null>(null);\n protected userEmail$ = new BehaviorSubject<string>('');\n\n private _initialPath: string | null = null;\n private _initialSearch: string | null = null;\n\n /**\n * Contains the initial path from window.location.pathname before any work was done by auth services\n */\n get initialPath(): string | null {\n return this._initialPath;\n }\n\n /**\n * Contains the initial search/query string from window.location.search before any work was done by auth services\n */\n get initialSearch(): string | null {\n return this._initialSearch;\n }\n\n /**\n * Provider type identifier\n * Must be implemented by concrete providers\n */\n abstract readonly type: string;\n\n constructor(config: AngularAuthProviderConfig) {\n this.config = config;\n this._initialPath = window.location.pathname;\n this._initialSearch = window.location.search;\n }\n\n // ============================================================================\n // ABSTRACT METHODS (Must be implemented by concrete providers)\n // ============================================================================\n\n /**\n * Initialize the provider\n *\n * Subclasses should override to set up provider-specific initialization,\n * handle redirect callbacks, restore sessions, etc.\n */\n abstract initialize(): Promise<void>;\n\n /**\n * Internal login implementation\n *\n * Subclasses implement provider-specific login flow.\n * This is called by the public login() method.\n */\n protected abstract loginInternal(options?: Record<string, unknown>): Promise<void>;\n\n /**\n * Logout implementation\n *\n * Subclasses implement provider-specific logout flow.\n */\n abstract logout(): Promise<void>;\n\n /**\n * Handle OAuth callback\n *\n * Subclasses implement provider-specific callback handling.\n */\n abstract handleCallback(): Promise<void>;\n\n /**\n * Extract ID token from provider-specific storage\n *\n * This is where providers hide their implementation details.\n * - Auth0: Extracts from claims.__raw\n * - MSAL: Extracts from response.idToken\n * - Okta: Extracts from authState.idToken\n *\n * @returns Promise resolving to token string or null if not authenticated\n */\n protected abstract extractIdTokenInternal(): Promise<string | null>;\n\n /**\n * Extract complete token info from provider-specific storage\n *\n * Maps provider-specific token structure to StandardAuthToken.\n *\n * @returns Promise resolving to StandardAuthToken or null if not authenticated\n */\n protected abstract extractTokenInfoInternal(): Promise<StandardAuthToken | null>;\n\n /**\n * Extract user info from provider-specific claims\n *\n * Maps provider-specific claim structure to StandardUserInfo.\n * This is where providers translate their claims (sub, email, name, etc.)\n * into the standard structure.\n *\n * @returns Promise resolving to StandardUserInfo or null if not authenticated\n */\n protected abstract extractUserInfoInternal(): Promise<StandardUserInfo | null>;\n\n /**\n * Refresh token using provider-specific mechanism\n *\n * Implements the provider's token refresh logic using whatever mechanism\n * is appropriate (silent refresh with refresh tokens, iframe-based token\n * acquisition, etc.).\n *\n * Should return success with token if refresh succeeds, or failure with\n * appropriate error type (TOKEN_EXPIRED, INTERACTION_REQUIRED, etc.) if\n * refresh fails.\n *\n * @returns Promise resolving to TokenRefreshResult indicating success/failure\n */\n protected abstract refreshTokenInternal(): Promise<TokenRefreshResult>;\n\n /**\n * Classify provider-specific error into standard error type\n *\n * Maps provider-specific errors to semantic AuthErrorType values.\n * Examines error objects, error codes, and messages to determine the\n * appropriate category (TOKEN_EXPIRED, INTERACTION_REQUIRED, NETWORK_ERROR, etc.).\n *\n * @param error The error to classify\n * @returns StandardAuthError with categorized type and user-friendly message\n */\n protected abstract classifyErrorInternal(error: unknown): StandardAuthError;\n\n /**\n * Get profile picture URL from auth provider\n *\n * Retrieves the user's profile picture using provider-specific mechanisms.\n * Some providers include the URL in user claims, others require API calls\n * to fetch the image.\n *\n * @returns Promise resolving to image URL or null if not available\n */\n protected abstract getProfilePictureUrlInternal(): Promise<string | null>;\n\n /**\n * Handle session expiry when silent refresh fails\n *\n * Called internally when silent token refresh fails with TOKEN_EXPIRED or\n * INTERACTION_REQUIRED errors. Providers that support refresh tokens can\n * implement this as a no-op. Providers that require interactive re-authentication\n * should initiate the appropriate flow (redirect, popup, etc.).\n *\n * Note: If this method redirects the page, it may never return. The app will\n * reload after authentication completes and re-initialize with a fresh token.\n *\n * @returns Promise that resolves if re-auth completed, or never returns if redirected\n */\n protected abstract handleSessionExpiryInternal(): Promise<void>;\n\n // ============================================================================\n // PUBLIC API (Concrete implementations using abstract internals)\n // ============================================================================\n\n /**\n * Public login method with Observable wrapper for backward compatibility\n *\n * Consumers can use either:\n * - `await this.authBase.login()` (Promise)\n * - `this.authBase.login().subscribe()` (Observable)\n */\n login(options?: Record<string, unknown>): Observable<void> {\n return from(this.loginInternal(options));\n }\n\n /**\n * Check if user is authenticated (Observable stream)\n *\n * Returns a reactive stream that emits authentication state changes.\n * Consumers can subscribe to react to login/logout events.\n */\n isAuthenticated(): Observable<boolean> {\n return this.isAuthenticated$.asObservable();\n }\n\n /**\n * Get user info as Observable stream\n *\n * Returns standardized user info, hiding provider-specific claim structures.\n * No more need for consumers to merge claims or check provider-specific fields!\n */\n getUserInfo(): Observable<StandardUserInfo | null> {\n return this.userInfo$.asObservable();\n }\n\n /**\n * Get user email as Observable stream\n */\n getUserEmail(): Observable<string> {\n return this.userEmail$.asObservable();\n }\n\n /**\n * Get ID token string (primary token method)\n *\n * This is the clean abstraction - no provider-specific logic needed!\n * Replaces the old pattern of: `claims?.__raw || claims?.idToken`\n *\n * @example\n * ```typescript\n * const token = await this.authBase.getIdToken();\n * if (token) {\n * setupGraphQLClient(token, apiUrl);\n * }\n * ```\n */\n async getIdToken(): Promise<string | null> {\n return this.extractIdTokenInternal();\n }\n\n /**\n * Get complete token information\n *\n * Returns full token details including expiration and scopes.\n * Use this when you need more than just the token string.\n */\n async getTokenInfo(): Promise<StandardAuthToken | null> {\n return this.extractTokenInfoInternal();\n }\n\n /**\n * Refresh authentication token\n *\n * Attempts to obtain a fresh authentication token using the provider's\n * refresh mechanism. If silent refresh fails due to session expiry, the\n * provider will handle re-authentication automatically (which may involve\n * redirecting to the auth provider's login page).\n *\n * Returns StandardAuthToken on success, or throws on complete failure.\n *\n * IMPORTANT: If the provider requires interactive re-authentication (redirect\n * or popup), this method may never return. The app will reload after\n * authentication completes and re-initialize with a fresh token.\n *\n * @returns Promise resolving to StandardAuthToken or throws on failure\n *\n * @example\n * ```typescript\n * const token = await this.authBase.refreshToken();\n * return token.idToken; // Always succeeds or throws\n * ```\n */\n async refreshToken(): Promise<StandardAuthToken> {\n // Try silent refresh\n const result = await this.refreshTokenInternal();\n\n if (result.success && result.token) {\n // Update state if refresh succeeded\n try {\n const userInfo = await this.extractUserInfoInternal();\n if (userInfo) {\n this.updateUserInfo(userInfo);\n }\n } catch {\n // User info update failed, but token refresh succeeded\n // Don't fail the entire refresh for this\n }\n\n return result.token;\n }\n\n // Silent refresh failed - check if we can handle session expiry\n const errorType = result.error?.type;\n if (errorType === 'TOKEN_EXPIRED' || errorType === 'INTERACTION_REQUIRED') {\n // Let provider handle session expiry (may redirect and never return)\n await this.handleSessionExpiryInternal();\n\n // If we reach here (didn't redirect), retry refresh once\n const retryResult = await this.refreshTokenInternal();\n if (retryResult.success && retryResult.token) {\n // Update state with new token\n try {\n const userInfo = await this.extractUserInfoInternal();\n if (userInfo) {\n this.updateUserInfo(userInfo);\n }\n } catch {\n // Ignore user info update errors\n }\n\n return retryResult.token;\n }\n }\n\n // Complete failure - throw error\n throw new Error(result.error?.userMessage || 'Token refresh failed');\n }\n\n /**\n * Classify an error into standard error type\n *\n * Converts provider-specific errors into semantic categories.\n * Eliminates need for consumers to check error.name or error types.\n *\n * @example\n * ```typescript\n * const authError = this.authBase.classifyError(err);\n * if (authError.type === AuthErrorType.TOKEN_EXPIRED) {\n * this.showMessage(authError.userMessage);\n * }\n * ```\n */\n classifyError(error: unknown): StandardAuthError {\n return this.classifyErrorInternal(error);\n }\n\n /**\n * Get profile picture URL from auth provider\n *\n * Returns the user's profile picture URL if available from the auth provider.\n * This abstracts away provider-specific logic:\n * - Microsoft/MSAL: Fetches from Graph API\n * - Auth0/Okta: Returns from user claims\n *\n * @returns Promise resolving to image URL or null if not available\n *\n * @example\n * ```typescript\n * const pictureUrl = await this.authBase.getProfilePictureUrl();\n * if (pictureUrl) {\n * this.userAvatar = pictureUrl;\n * }\n * ```\n */\n async getProfilePictureUrl(): Promise<string | null> {\n return this.getProfilePictureUrlInternal();\n }\n\n // ============================================================================\n // HELPER METHODS (For subclasses to update state)\n // ============================================================================\n\n /**\n * Update authentication state\n *\n * Subclasses should call this when authentication state changes\n * (after login, logout, session check, etc.)\n */\n protected updateAuthState(isAuthenticated: boolean): void {\n this.isAuthenticated$.next(isAuthenticated);\n }\n\n /**\n * Update user info\n *\n * Subclasses should call this when user info is retrieved or updated.\n * This automatically updates the email stream as well.\n */\n protected updateUserInfo(userInfo: StandardUserInfo | null): void {\n this.userInfo$.next(userInfo);\n\n if (userInfo?.email) {\n this.userEmail$.next(userInfo.email);\n } else {\n this.userEmail$.next('');\n }\n }\n\n // ============================================================================\n // CONFIGURATION & VALIDATION\n // ============================================================================\n\n /**\n * Get required configuration fields\n *\n * Default implementation requires clientId.\n * Subclasses can override to add provider-specific requirements.\n */\n getRequiredConfig(): string[] {\n return ['clientId'];\n }\n\n /**\n * Validate provider configuration\n *\n * Checks that all required fields are present and non-empty.\n * Subclasses can override to add custom validation logic.\n */\n validateConfig(config: Record<string, unknown>): boolean {\n const requiredFields = this.getRequiredConfig();\n return requiredFields.every(field =>\n config[field] !== undefined && config[field] !== ''\n );\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"mjexplorer-auth-base.service.js","sourceRoot":"","sources":["../../src/lib/mjexplorer-auth-base.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@angular/core';\nimport { Observable, BehaviorSubject, from } from 'rxjs';\nimport { IAngularAuthProvider, AngularAuthProviderConfig } from './IAuthProvider';\nimport {\n StandardUserInfo,\n StandardAuthToken,\n StandardAuthError,\n TokenRefreshResult\n} from './auth-types';\n\n/**\n * Base class for Angular authentication providers - v3.0.0\n *\n * Provides common functionality and enforces the provider interface.\n * All concrete providers (MSAL, Auth0, Okta) should extend this class.\n *\n * ## Key Improvements in v3.0:\n * - Proper abstraction - no more leaky provider-specific logic\n * - Standardized types - no more `any` types\n * - Clean token access - no more `__raw || idToken` patterns\n * - Semantic error handling - no more provider-specific error checks\n *\n * ## For Provider Implementers:\n * Extend this class and implement the abstract methods:\n * - `extractIdTokenInternal()` - Extract token from provider storage\n * - `extractTokenInfoInternal()` - Extract full token info\n * - `extractUserInfoInternal()` - Map claims to StandardUserInfo\n * - `refreshTokenInternal()` - Implement refresh mechanism\n * - `classifyErrorInternal()` - Map errors to AuthErrorType\n *\n * @version 3.0.0\n */\n@Injectable()\nexport abstract class MJAuthBase implements IAngularAuthProvider {\n protected config: AngularAuthProviderConfig;\n\n // State management with proper types (no more 'any'!)\n protected isAuthenticated$ = new BehaviorSubject<boolean>(false);\n protected userInfo$ = new BehaviorSubject<StandardUserInfo | null>(null);\n protected userEmail$ = new BehaviorSubject<string>('');\n\n private _initialPath: string | null = null;\n private _initialSearch: string | null = null;\n\n /**\n * Contains the initial path from window.location.pathname before any work was done by auth services\n */\n get initialPath(): string | null {\n return this._initialPath;\n }\n\n /**\n * Contains the initial search/query string from window.location.search before any work was done by auth services\n */\n get initialSearch(): string | null {\n return this._initialSearch;\n }\n\n /**\n * Provider type identifier\n * Must be implemented by concrete providers\n */\n abstract readonly type: string;\n\n constructor(config: AngularAuthProviderConfig) {\n this.config = config;\n this._initialPath = window.location.pathname;\n this._initialSearch = window.location.search;\n }\n\n // ============================================================================\n // ABSTRACT METHODS (Must be implemented by concrete providers)\n // ============================================================================\n\n /**\n * Initialize the provider\n *\n * Subclasses should override to set up provider-specific initialization,\n * handle redirect callbacks, restore sessions, etc.\n */\n abstract initialize(): Promise<void>;\n\n /**\n * Internal login implementation\n *\n * Subclasses implement provider-specific login flow.\n * This is called by the public login() method.\n */\n protected abstract loginInternal(options?: Record<string, unknown>): Promise<void>;\n\n /**\n * Provider-specific logout implementation\n *\n * Subclasses implement provider-specific logout flow (redirect, SDK logout, etc.).\n * The base class `logout()` calls `clearClientCaches()` before invoking this method,\n * so providers do NOT need to handle cache clearing themselves.\n */\n protected abstract logoutInternal(): Promise<void>;\n\n /**\n * Handle OAuth callback\n *\n * Subclasses implement provider-specific callback handling.\n */\n abstract handleCallback(): Promise<void>;\n\n /**\n * Extract ID token from provider-specific storage\n *\n * This is where providers hide their implementation details.\n * - Auth0: Extracts from claims.__raw\n * - MSAL: Extracts from response.idToken\n * - Okta: Extracts from authState.idToken\n *\n * @returns Promise resolving to token string or null if not authenticated\n */\n protected abstract extractIdTokenInternal(): Promise<string | null>;\n\n /**\n * Extract complete token info from provider-specific storage\n *\n * Maps provider-specific token structure to StandardAuthToken.\n *\n * @returns Promise resolving to StandardAuthToken or null if not authenticated\n */\n protected abstract extractTokenInfoInternal(): Promise<StandardAuthToken | null>;\n\n /**\n * Extract user info from provider-specific claims\n *\n * Maps provider-specific claim structure to StandardUserInfo.\n * This is where providers translate their claims (sub, email, name, etc.)\n * into the standard structure.\n *\n * @returns Promise resolving to StandardUserInfo or null if not authenticated\n */\n protected abstract extractUserInfoInternal(): Promise<StandardUserInfo | null>;\n\n /**\n * Refresh token using provider-specific mechanism\n *\n * Implements the provider's token refresh logic using whatever mechanism\n * is appropriate (silent refresh with refresh tokens, iframe-based token\n * acquisition, etc.).\n *\n * Should return success with token if refresh succeeds, or failure with\n * appropriate error type (TOKEN_EXPIRED, INTERACTION_REQUIRED, etc.) if\n * refresh fails.\n *\n * @returns Promise resolving to TokenRefreshResult indicating success/failure\n */\n protected abstract refreshTokenInternal(): Promise<TokenRefreshResult>;\n\n /**\n * Classify provider-specific error into standard error type\n *\n * Maps provider-specific errors to semantic AuthErrorType values.\n * Examines error objects, error codes, and messages to determine the\n * appropriate category (TOKEN_EXPIRED, INTERACTION_REQUIRED, NETWORK_ERROR, etc.).\n *\n * @param error The error to classify\n * @returns StandardAuthError with categorized type and user-friendly message\n */\n protected abstract classifyErrorInternal(error: unknown): StandardAuthError;\n\n /**\n * Get profile picture URL from auth provider\n *\n * Retrieves the user's profile picture using provider-specific mechanisms.\n * Some providers include the URL in user claims, others require API calls\n * to fetch the image.\n *\n * @returns Promise resolving to image URL or null if not available\n */\n protected abstract getProfilePictureUrlInternal(): Promise<string | null>;\n\n /**\n * Handle session expiry when silent refresh fails\n *\n * Called internally when silent token refresh fails with TOKEN_EXPIRED or\n * INTERACTION_REQUIRED errors. Providers that support refresh tokens can\n * implement this as a no-op. Providers that require interactive re-authentication\n * should initiate the appropriate flow (redirect, popup, etc.).\n *\n * Note: If this method redirects the page, it may never return. The app will\n * reload after authentication completes and re-initialize with a fresh token.\n *\n * @returns Promise that resolves if re-auth completed, or never returns if redirected\n */\n protected abstract handleSessionExpiryInternal(): Promise<void>;\n\n // ============================================================================\n // PUBLIC API (Concrete implementations using abstract internals)\n // ============================================================================\n\n /**\n * Public login method with Observable wrapper for backward compatibility\n *\n * Consumers can use either:\n * - `await this.authBase.login()` (Promise)\n * - `this.authBase.login().subscribe()` (Observable)\n */\n login(options?: Record<string, unknown>): Observable<void> {\n return from(this.loginInternal(options));\n }\n\n /**\n * Logout — clears all MJ client-side caches then delegates to the provider.\n *\n * Cache clearing happens universally regardless of auth provider so that a\n * subsequent login as a different user never sees the previous user's data.\n * Providers that need to clear additional caches should override\n * `logoutInternal()` and call `super.logoutInternal()` if applicable.\n */\n async logout(): Promise<void> {\n await this.clearClientCaches();\n await this.logoutInternal();\n }\n\n /**\n * localStorage keys that survive a logout (e.g. UI theme preference).\n *\n * Override this getter in a subclass to preserve additional keys specific\n * to your provider or application.\n */\n protected get preservedLocalStorageKeys(): Set<string> {\n return new Set(['mj-login-theme']);\n }\n\n /**\n * Clears MJ client-side caches before logout.\n *\n * Removes all localStorage entries except those returned by\n * `preservedLocalStorageKeys`, and deletes the `MJ_Metadata` IndexedDB\n * database so a subsequent user session starts with a clean slate.\n */\n protected async clearClientCaches(): Promise<void> {\n const preserved = this.preservedLocalStorageKeys;\n const keysToRemove: string[] = [];\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i);\n if (key && !preserved.has(key)) {\n keysToRemove.push(key);\n }\n }\n keysToRemove.forEach(key => localStorage.removeItem(key));\n\n await new Promise<void>((resolve) => {\n const req = indexedDB.deleteDatabase('MJ_Metadata');\n req.onsuccess = () => resolve();\n req.onerror = () => resolve();\n req.onblocked = () => resolve();\n });\n }\n\n /**\n * Check if user is authenticated (Observable stream)\n *\n * Returns a reactive stream that emits authentication state changes.\n * Consumers can subscribe to react to login/logout events.\n */\n isAuthenticated(): Observable<boolean> {\n return this.isAuthenticated$.asObservable();\n }\n\n /**\n * Get user info as Observable stream\n *\n * Returns standardized user info, hiding provider-specific claim structures.\n * No more need for consumers to merge claims or check provider-specific fields!\n */\n getUserInfo(): Observable<StandardUserInfo | null> {\n return this.userInfo$.asObservable();\n }\n\n /**\n * Get user email as Observable stream\n */\n getUserEmail(): Observable<string> {\n return this.userEmail$.asObservable();\n }\n\n /**\n * Get ID token string (primary token method)\n *\n * This is the clean abstraction - no provider-specific logic needed!\n * Replaces the old pattern of: `claims?.__raw || claims?.idToken`\n *\n * @example\n * ```typescript\n * const token = await this.authBase.getIdToken();\n * if (token) {\n * setupGraphQLClient(token, apiUrl);\n * }\n * ```\n */\n async getIdToken(): Promise<string | null> {\n return this.extractIdTokenInternal();\n }\n\n /**\n * Get complete token information\n *\n * Returns full token details including expiration and scopes.\n * Use this when you need more than just the token string.\n */\n async getTokenInfo(): Promise<StandardAuthToken | null> {\n return this.extractTokenInfoInternal();\n }\n\n /**\n * Refresh authentication token\n *\n * Attempts to obtain a fresh authentication token using the provider's\n * refresh mechanism. If silent refresh fails due to session expiry, the\n * provider will handle re-authentication automatically (which may involve\n * redirecting to the auth provider's login page).\n *\n * Returns StandardAuthToken on success, or throws on complete failure.\n *\n * IMPORTANT: If the provider requires interactive re-authentication (redirect\n * or popup), this method may never return. The app will reload after\n * authentication completes and re-initialize with a fresh token.\n *\n * @returns Promise resolving to StandardAuthToken or throws on failure\n *\n * @example\n * ```typescript\n * const token = await this.authBase.refreshToken();\n * return token.idToken; // Always succeeds or throws\n * ```\n */\n async refreshToken(): Promise<StandardAuthToken> {\n // Try silent refresh\n const result = await this.refreshTokenInternal();\n\n if (result.success && result.token) {\n // Update state if refresh succeeded\n try {\n const userInfo = await this.extractUserInfoInternal();\n if (userInfo) {\n this.updateUserInfo(userInfo);\n }\n } catch {\n // User info update failed, but token refresh succeeded\n // Don't fail the entire refresh for this\n }\n\n return result.token;\n }\n\n // Silent refresh failed - check if we can handle session expiry\n const errorType = result.error?.type;\n if (errorType === 'TOKEN_EXPIRED' || errorType === 'INTERACTION_REQUIRED') {\n // Let provider handle session expiry (may redirect and never return)\n await this.handleSessionExpiryInternal();\n\n // If we reach here (didn't redirect), retry refresh once\n const retryResult = await this.refreshTokenInternal();\n if (retryResult.success && retryResult.token) {\n // Update state with new token\n try {\n const userInfo = await this.extractUserInfoInternal();\n if (userInfo) {\n this.updateUserInfo(userInfo);\n }\n } catch {\n // Ignore user info update errors\n }\n\n return retryResult.token;\n }\n }\n\n // Complete failure - throw error\n throw new Error(result.error?.userMessage || 'Token refresh failed');\n }\n\n /**\n * Classify an error into standard error type\n *\n * Converts provider-specific errors into semantic categories.\n * Eliminates need for consumers to check error.name or error types.\n *\n * @example\n * ```typescript\n * const authError = this.authBase.classifyError(err);\n * if (authError.type === AuthErrorType.TOKEN_EXPIRED) {\n * this.showMessage(authError.userMessage);\n * }\n * ```\n */\n classifyError(error: unknown): StandardAuthError {\n return this.classifyErrorInternal(error);\n }\n\n /**\n * Get profile picture URL from auth provider\n *\n * Returns the user's profile picture URL if available from the auth provider.\n * This abstracts away provider-specific logic:\n * - Microsoft/MSAL: Fetches from Graph API\n * - Auth0/Okta: Returns from user claims\n *\n * @returns Promise resolving to image URL or null if not available\n *\n * @example\n * ```typescript\n * const pictureUrl = await this.authBase.getProfilePictureUrl();\n * if (pictureUrl) {\n * this.userAvatar = pictureUrl;\n * }\n * ```\n */\n async getProfilePictureUrl(): Promise<string | null> {\n return this.getProfilePictureUrlInternal();\n }\n\n // ============================================================================\n // HELPER METHODS (For subclasses to update state)\n // ============================================================================\n\n /**\n * Update authentication state\n *\n * Subclasses should call this when authentication state changes\n * (after login, logout, session check, etc.)\n */\n protected updateAuthState(isAuthenticated: boolean): void {\n this.isAuthenticated$.next(isAuthenticated);\n }\n\n /**\n * Update user info\n *\n * Subclasses should call this when user info is retrieved or updated.\n * This automatically updates the email stream as well.\n */\n protected updateUserInfo(userInfo: StandardUserInfo | null): void {\n this.userInfo$.next(userInfo);\n\n if (userInfo?.email) {\n this.userEmail$.next(userInfo.email);\n } else {\n this.userEmail$.next('');\n }\n }\n\n // ============================================================================\n // CONFIGURATION & VALIDATION\n // ============================================================================\n\n /**\n * Get required configuration fields\n *\n * Default implementation requires clientId.\n * Subclasses can override to add provider-specific requirements.\n */\n getRequiredConfig(): string[] {\n return ['clientId'];\n }\n\n /**\n * Validate provider configuration\n *\n * Checks that all required fields are present and non-empty.\n * Subclasses can override to add custom validation logic.\n */\n validateConfig(config: Record<string, unknown>): boolean {\n const requiredFields = this.getRequiredConfig();\n return requiredFields.every(field =>\n config[field] !== undefined && config[field] !== ''\n );\n }\n}\n"]}
|
|
@@ -43,7 +43,7 @@ export declare class MJAuth0Provider extends MJAuthBase {
|
|
|
43
43
|
constructor(auth: AuthService);
|
|
44
44
|
initialize(): Promise<void>;
|
|
45
45
|
protected loginInternal(options?: Record<string, unknown>): Promise<void>;
|
|
46
|
-
|
|
46
|
+
protected logoutInternal(): Promise<void>;
|
|
47
47
|
handleCallback(): Promise<void>;
|
|
48
48
|
/**
|
|
49
49
|
* Extract ID token from Auth0's storage
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mjexplorer-auth0-provider.service.d.ts","sourceRoot":"","sources":["../../../src/lib/providers/mjexplorer-auth0-provider.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAiB,SAAS,EAAyC,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAI1J,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EAEjB,kBAAkB,EACnB,MAAM,eAAe,CAAC;;AACvB;;;;;;GAMG;AACH,qBAIa,eAAgB,SAAQ,UAAU;IA+C1B,IAAI,EAAE,WAAW;IA9CpC,MAAM,CAAC,QAAQ,CAAC,aAAa,WAAW;IACxC,QAAQ,CAAC,IAAI,WAAiC;IAC9C,OAAO,CAAC,YAAY,CAAS;IAE7B;;;OAGG;IACH,MAAM,CAAC,sBAAsB,GAAI,aAAa,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;SAoCnE;gBAEiB,IAAI,EAAE,WAAW;IAY9B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;cA0CjB,aAAa,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"mjexplorer-auth0-provider.service.d.ts","sourceRoot":"","sources":["../../../src/lib/providers/mjexplorer-auth0-provider.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAiB,SAAS,EAAyC,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAI1J,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EAEjB,kBAAkB,EACnB,MAAM,eAAe,CAAC;;AACvB;;;;;;GAMG;AACH,qBAIa,eAAgB,SAAQ,UAAU;IA+C1B,IAAI,EAAE,WAAW;IA9CpC,MAAM,CAAC,QAAQ,CAAC,aAAa,WAAW;IACxC,QAAQ,CAAC,IAAI,WAAiC;IAC9C,OAAO,CAAC,YAAY,CAAS;IAE7B;;;OAGG;IACH,MAAM,CAAC,sBAAsB,GAAI,aAAa,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;SAoCnE;gBAEiB,IAAI,EAAE,WAAW;IAY9B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;cA0CjB,aAAa,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;cAK/D,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAWzC,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IASrC;;;;;OAKG;cACa,sBAAsB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAWhE;;;;OAIG;cACa,wBAAwB,IAAI,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAuB7E;;;;OAIG;cACa,uBAAuB,IAAI,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAc3E;;;;;OAKG;cACa,oBAAoB,IAAI,OAAO,CAAC,kBAAkB,CAAC;IA6CnE;;;;OAIG;IACH,SAAS,CAAC,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,iBAAiB;YAgEpD,iBAAiB;IAM/B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAc9B;;;;;OAKG;cACa,4BAA4B,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAUtE;;;;;;OAMG;cACa,2BAA2B,IAAI,OAAO,CAAC,IAAI,CAAC;IASnD,iBAAiB,IAAI,MAAM,EAAE;IAI7B,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO;yCAjXvD,eAAe;6CAAf,eAAe;CAqX3B"}
|
|
@@ -115,8 +115,14 @@ let MJAuth0Provider = class MJAuth0Provider extends MJAuthBase {
|
|
|
115
115
|
await this.ensureInitialized();
|
|
116
116
|
this.auth.loginWithRedirect(options);
|
|
117
117
|
}
|
|
118
|
-
async
|
|
119
|
-
|
|
118
|
+
async logoutInternal() {
|
|
119
|
+
// Subscribe to the Observable so Auth0 Angular SDK v2's authState.refresh() fires.
|
|
120
|
+
try {
|
|
121
|
+
await firstValueFrom(this.auth.logout({ logoutParams: { returnTo: document.location.origin } }));
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
// Expected when Auth0 redirects the browser before the Observable completes.
|
|
125
|
+
}
|
|
120
126
|
}
|
|
121
127
|
async handleCallback() {
|
|
122
128
|
// Auth0 Angular SDK handles callbacks internally via interceptors
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mjexplorer-auth0-provider.service.js","sourceRoot":"","sources":["../../../src/lib/providers/mjexplorer-auth0-provider.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@angular/core';\nimport { RegisterClass } from '@memberjunction/global';\nimport { MJAuthBase } from '../mjexplorer-auth-base.service';\nimport { AuthService, IdToken, User, AuthGuard, AuthConfigService, Auth0ClientService, Auth0ClientFactory, AuthClientConfig } from '@auth0/auth0-angular';\nimport { Observable, of, firstValueFrom } from 'rxjs';\nimport { take, filter } from 'rxjs/operators';\nimport { AngularAuthProviderConfig } from '../IAuthProvider';\nimport {\n StandardUserInfo,\n StandardAuthToken,\n StandardAuthError,\n AuthErrorType,\n TokenRefreshResult\n} from '../auth-types';\n/**\n * Auth0 authentication provider implementation - v3.0.0\n *\n * Implements the abstract methods from MJAuthBase to hide Auth0-specific details.\n * The key abstraction is that Auth0 stores the JWT in `idTokenClaims.__raw`,\n * but consumers never need to know this detail.\n */\n@Injectable({\n providedIn: 'root'\n})\n@RegisterClass(MJAuthBase, 'auth0')\nexport class MJAuth0Provider extends MJAuthBase {\n static readonly PROVIDER_TYPE = 'auth0';\n readonly type = MJAuth0Provider.PROVIDER_TYPE;\n private _initialized = false;\n\n /**\n * Factory function to provide Angular dependencies required by Auth0\n * Stored as a static property for the factory to access without instantiation\n */\n static angularProviderFactory = (environment: Record<string, unknown>) => {\n // Check if we're on the MCP OAuth callback path\n const isMCPOAuthCallback = window.location.pathname.startsWith('/oauth/callback');\n\n return [\n AuthService,\n AuthGuard,\n {\n provide: AuthConfigService,\n useValue: {\n domain: environment['AUTH0_DOMAIN'],\n clientId: environment['AUTH0_CLIENTID'],\n authorizationParams: {\n redirect_uri: window.location.origin,\n scope: 'openid profile email offline_access',\n // No audience parameter - uses ID tokens (matches pre-refactor behavior)\n // ID tokens have aud=clientId by default and contain user claims\n },\n cacheLocation: 'localstorage',\n // Enable refresh tokens so we can refresh without relying on Auth0 session cookies\n useRefreshTokens: true,\n // Use rotating refresh tokens for better security\n useRefreshTokensFallback: true,\n // CRITICAL: Skip Auth0's redirect callback handling for MCP OAuth callbacks\n // The /oauth/callback path is used by MCP OAuth, not Auth0. If we don't skip,\n // Auth0 will consume the code parameter and redirect to /, preventing the\n // OAuthCallbackComponent from processing the MCP OAuth flow.\n skipRedirectCallback: isMCPOAuthCallback,\n },\n },\n {\n provide: Auth0ClientService,\n useFactory: Auth0ClientFactory.createClient,\n deps: [AuthClientConfig],\n }\n ];\n };\n\n constructor(public auth: AuthService) {\n const config: AngularAuthProviderConfig = {\n name: MJAuth0Provider.PROVIDER_TYPE,\n type: MJAuth0Provider.PROVIDER_TYPE\n };\n super(config);\n }\n\n // ============================================================================\n // LIFECYCLE METHODS\n // ============================================================================\n\n async initialize(): Promise<void> {\n if (this._initialized) {\n return;\n }\n\n // CRITICAL: Wait for Auth0 SDK to process any redirect callback\n // The SDK handles this internally and updates isLoading$ when done\n await firstValueFrom(this.auth.isLoading$.pipe(\n filter(loading => !loading),\n take(1)\n ));\n\n // Get current authentication state\n const isAuthenticated = await firstValueFrom(this.auth.isAuthenticated$);\n\n // CRITICAL: Get current user BEFORE setting up subscriptions\n // This ensures userInfo$ has a value before app.component.ts subscribes\n if (isAuthenticated) {\n const user = await firstValueFrom(this.auth.user$);\n if (user) {\n const userInfo = this.mapAuth0UserToStandard(user);\n this.updateUserInfo(userInfo);\n }\n }\n\n // Subscribe to authentication state and user info for future changes\n this.auth.isAuthenticated$.subscribe((loggedIn) => {\n this.updateAuthState(loggedIn);\n });\n\n this.auth.user$.subscribe((user) => {\n if (user) {\n const userInfo = this.mapAuth0UserToStandard(user);\n this.updateUserInfo(userInfo);\n } else {\n this.updateUserInfo(null);\n }\n });\n\n this._initialized = true;\n }\n\n protected async loginInternal(options?: Record<string, unknown>): Promise<void> {\n await this.ensureInitialized();\n this.auth.loginWithRedirect(options);\n }\n\n async logout(): Promise<void> {\n this.auth.logout({ logoutParams: { returnTo: document.location.origin } });\n }\n\n async handleCallback(): Promise<void> {\n // Auth0 Angular SDK handles callbacks internally via interceptors\n // This method exists for interface compatibility\n }\n\n // ============================================================================\n // ABSTRACT METHOD IMPLEMENTATIONS (v3.0.0)\n // ============================================================================\n\n /**\n * Extract ID token from Auth0's storage\n *\n * Auth0 stores the JWT string in idTokenClaims.__raw\n * This is the key abstraction - consumers never need to know about __raw!\n */\n protected async extractIdTokenInternal(): Promise<string | null> {\n try {\n const claims = await firstValueFrom(this.auth.idTokenClaims$);\n // Auth0-specific detail: JWT is in __raw property\n return claims?.__raw || null;\n } catch (error) {\n console.error('[Auth0] Error extracting ID token:', error);\n return null;\n }\n }\n\n /**\n * Extract complete token info from Auth0\n *\n * Maps Auth0's token structure to StandardAuthToken\n */\n protected async extractTokenInfoInternal(): Promise<StandardAuthToken | null> {\n try {\n const claims = await firstValueFrom(this.auth.idTokenClaims$);\n if (!claims) {\n return null;\n }\n\n const idToken = claims.__raw;\n if (!idToken) {\n return null;\n }\n\n return {\n idToken,\n expiresAt: claims.exp ? claims.exp * 1000 : 0, // Convert to milliseconds\n scopes: claims.scope ? claims.scope.split(' ') : undefined\n };\n } catch (error) {\n console.error('[Auth0] Error extracting token info:', error);\n return null;\n }\n }\n\n /**\n * Extract user info from Auth0 claims\n *\n * Maps Auth0's user object structure to StandardUserInfo\n */\n protected async extractUserInfoInternal(): Promise<StandardUserInfo | null> {\n try {\n const user = await firstValueFrom(this.auth.user$);\n if (!user) {\n return null;\n }\n\n return this.mapAuth0UserToStandard(user);\n } catch (error) {\n console.error('[Auth0] Error extracting user info:', error);\n return null;\n }\n }\n\n /**\n * Refresh token using Auth0's silent authentication\n *\n * Uses cacheMode: 'off' to bypass cache and force token refresh\n * With useRefreshTokens: true and offline_access scope, this will use refresh tokens\n */\n protected async refreshTokenInternal(): Promise<TokenRefreshResult> {\n try {\n console.log('[Auth0] Attempting to refresh token...');\n\n // Force token refresh by bypassing cache\n // With useRefreshTokens: true and offline_access scope, this will use refresh tokens\n await firstValueFrom(this.auth.getAccessTokenSilently({\n cacheMode: 'off'\n }));\n\n // Small delay to ensure Auth0 SDK has updated observables\n await new Promise(resolve => setTimeout(resolve, 100));\n\n // Extract fresh token info from updated observables\n const token = await this.extractTokenInfoInternal();\n\n if (!token) {\n return {\n success: false,\n error: {\n type: AuthErrorType.NO_ACTIVE_SESSION,\n message: 'Token refresh succeeded but could not extract token info',\n userMessage: 'Session refresh failed. Please log in again.'\n }\n };\n }\n\n console.log('[Auth0] Token refresh successful', {\n expiresAt: new Date(token.expiresAt).toISOString()\n });\n\n return {\n success: true,\n token\n };\n } catch (error) {\n console.error('[Auth0] Token refresh failed:', error);\n\n return {\n success: false,\n error: this.classifyErrorInternal(error)\n };\n }\n }\n\n /**\n * Classify Auth0-specific errors into semantic types\n *\n * Maps Auth0 error patterns to AuthErrorType enum\n */\n protected classifyErrorInternal(error: unknown): StandardAuthError {\n const errorObj = error as Record<string, unknown>;\n const message = errorObj?.['message'] as string || 'Unknown error';\n const errorType = errorObj?.['error'] as string || '';\n\n // Check for specific Auth0 error patterns\n if (message.includes('jwt expired') || message.includes('token expired')) {\n return {\n type: AuthErrorType.TOKEN_EXPIRED,\n message,\n originalError: error,\n userMessage: 'Your session has expired. Please log in again.'\n };\n }\n\n if (errorType === 'login_required' || message.includes('login_required')) {\n return {\n type: AuthErrorType.NO_ACTIVE_SESSION,\n message,\n originalError: error,\n userMessage: 'You need to log in to continue.'\n };\n }\n\n if (errorType === 'consent_required' || message.includes('consent_required')) {\n return {\n type: AuthErrorType.INTERACTION_REQUIRED,\n message,\n originalError: error,\n userMessage: 'Additional permissions are required. Please log in again.'\n };\n }\n\n if (message.includes('user closed') || message.includes('cancelled')) {\n return {\n type: AuthErrorType.USER_CANCELLED,\n message,\n originalError: error,\n userMessage: 'Login was cancelled.'\n };\n }\n\n if (message.includes('network') || message.includes('fetch')) {\n return {\n type: AuthErrorType.NETWORK_ERROR,\n message,\n originalError: error,\n userMessage: 'Network error. Please check your connection and try again.'\n };\n }\n\n // Default to unknown error\n return {\n type: AuthErrorType.UNKNOWN_ERROR,\n message,\n originalError: error,\n userMessage: 'An unexpected error occurred. Please try again.'\n };\n }\n\n // ============================================================================\n // HELPER METHODS\n // ============================================================================\n\n private async ensureInitialized(): Promise<void> {\n if (!this._initialized) {\n await this.initialize();\n }\n }\n\n /**\n * Map Auth0 User object to StandardUserInfo\n */\n private mapAuth0UserToStandard(user: User): StandardUserInfo {\n return {\n id: user.sub || '',\n email: user.email || '',\n name: user.name || '',\n givenName: user.given_name,\n familyName: user.family_name,\n preferredUsername: user.nickname,\n pictureUrl: user.picture,\n locale: user.locale,\n emailVerified: user.email_verified\n };\n }\n\n /**\n * Get profile picture URL from Auth0\n *\n * Auth0 includes the picture URL directly in user claims.\n * No additional API call needed.\n */\n protected async getProfilePictureUrlInternal(): Promise<string | null> {\n try {\n const user = await firstValueFrom(this.auth.user$);\n return user?.picture || null;\n } catch (error) {\n console.error('[Auth0] Error getting profile picture:', error);\n return null;\n }\n }\n\n /**\n * Handle session expiry - no-op for Auth0\n *\n * Auth0 uses refresh tokens (offline_access scope), so it doesn't need\n * interactive re-authentication when tokens expire. If refresh fails,\n * the base class will throw an error and the user must log out/in manually.\n */\n protected async handleSessionExpiryInternal(): Promise<void> {\n // No-op - Auth0 doesn't need interactive re-auth\n return;\n }\n\n // ============================================================================\n // CONFIGURATION\n // ============================================================================\n\n override getRequiredConfig(): string[] {\n return ['clientId', 'domain'];\n }\n\n override validateConfig(_config: Record<string, unknown>): boolean {\n // Auth0 configuration is handled by Angular module providers\n return true;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"mjexplorer-auth0-provider.service.js","sourceRoot":"","sources":["../../../src/lib/providers/mjexplorer-auth0-provider.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@angular/core';\nimport { RegisterClass } from '@memberjunction/global';\nimport { MJAuthBase } from '../mjexplorer-auth-base.service';\nimport { AuthService, IdToken, User, AuthGuard, AuthConfigService, Auth0ClientService, Auth0ClientFactory, AuthClientConfig } from '@auth0/auth0-angular';\nimport { Observable, of, firstValueFrom } from 'rxjs';\nimport { take, filter } from 'rxjs/operators';\nimport { AngularAuthProviderConfig } from '../IAuthProvider';\nimport {\n StandardUserInfo,\n StandardAuthToken,\n StandardAuthError,\n AuthErrorType,\n TokenRefreshResult\n} from '../auth-types';\n/**\n * Auth0 authentication provider implementation - v3.0.0\n *\n * Implements the abstract methods from MJAuthBase to hide Auth0-specific details.\n * The key abstraction is that Auth0 stores the JWT in `idTokenClaims.__raw`,\n * but consumers never need to know this detail.\n */\n@Injectable({\n providedIn: 'root'\n})\n@RegisterClass(MJAuthBase, 'auth0')\nexport class MJAuth0Provider extends MJAuthBase {\n static readonly PROVIDER_TYPE = 'auth0';\n readonly type = MJAuth0Provider.PROVIDER_TYPE;\n private _initialized = false;\n\n /**\n * Factory function to provide Angular dependencies required by Auth0\n * Stored as a static property for the factory to access without instantiation\n */\n static angularProviderFactory = (environment: Record<string, unknown>) => {\n // Check if we're on the MCP OAuth callback path\n const isMCPOAuthCallback = window.location.pathname.startsWith('/oauth/callback');\n\n return [\n AuthService,\n AuthGuard,\n {\n provide: AuthConfigService,\n useValue: {\n domain: environment['AUTH0_DOMAIN'],\n clientId: environment['AUTH0_CLIENTID'],\n authorizationParams: {\n redirect_uri: window.location.origin,\n scope: 'openid profile email offline_access',\n // No audience parameter - uses ID tokens (matches pre-refactor behavior)\n // ID tokens have aud=clientId by default and contain user claims\n },\n cacheLocation: 'localstorage',\n // Enable refresh tokens so we can refresh without relying on Auth0 session cookies\n useRefreshTokens: true,\n // Use rotating refresh tokens for better security\n useRefreshTokensFallback: true,\n // CRITICAL: Skip Auth0's redirect callback handling for MCP OAuth callbacks\n // The /oauth/callback path is used by MCP OAuth, not Auth0. If we don't skip,\n // Auth0 will consume the code parameter and redirect to /, preventing the\n // OAuthCallbackComponent from processing the MCP OAuth flow.\n skipRedirectCallback: isMCPOAuthCallback,\n },\n },\n {\n provide: Auth0ClientService,\n useFactory: Auth0ClientFactory.createClient,\n deps: [AuthClientConfig],\n }\n ];\n };\n\n constructor(public auth: AuthService) {\n const config: AngularAuthProviderConfig = {\n name: MJAuth0Provider.PROVIDER_TYPE,\n type: MJAuth0Provider.PROVIDER_TYPE\n };\n super(config);\n }\n\n // ============================================================================\n // LIFECYCLE METHODS\n // ============================================================================\n\n async initialize(): Promise<void> {\n if (this._initialized) {\n return;\n }\n\n // CRITICAL: Wait for Auth0 SDK to process any redirect callback\n // The SDK handles this internally and updates isLoading$ when done\n await firstValueFrom(this.auth.isLoading$.pipe(\n filter(loading => !loading),\n take(1)\n ));\n\n // Get current authentication state\n const isAuthenticated = await firstValueFrom(this.auth.isAuthenticated$);\n\n // CRITICAL: Get current user BEFORE setting up subscriptions\n // This ensures userInfo$ has a value before app.component.ts subscribes\n if (isAuthenticated) {\n const user = await firstValueFrom(this.auth.user$);\n if (user) {\n const userInfo = this.mapAuth0UserToStandard(user);\n this.updateUserInfo(userInfo);\n }\n }\n\n // Subscribe to authentication state and user info for future changes\n this.auth.isAuthenticated$.subscribe((loggedIn) => {\n this.updateAuthState(loggedIn);\n });\n\n this.auth.user$.subscribe((user) => {\n if (user) {\n const userInfo = this.mapAuth0UserToStandard(user);\n this.updateUserInfo(userInfo);\n } else {\n this.updateUserInfo(null);\n }\n });\n\n this._initialized = true;\n }\n\n protected async loginInternal(options?: Record<string, unknown>): Promise<void> {\n await this.ensureInitialized();\n this.auth.loginWithRedirect(options);\n }\n\n protected async logoutInternal(): Promise<void> {\n // Subscribe to the Observable so Auth0 Angular SDK v2's authState.refresh() fires.\n try {\n await firstValueFrom(\n this.auth.logout({ logoutParams: { returnTo: document.location.origin } })\n );\n } catch {\n // Expected when Auth0 redirects the browser before the Observable completes.\n }\n }\n\n async handleCallback(): Promise<void> {\n // Auth0 Angular SDK handles callbacks internally via interceptors\n // This method exists for interface compatibility\n }\n\n // ============================================================================\n // ABSTRACT METHOD IMPLEMENTATIONS (v3.0.0)\n // ============================================================================\n\n /**\n * Extract ID token from Auth0's storage\n *\n * Auth0 stores the JWT string in idTokenClaims.__raw\n * This is the key abstraction - consumers never need to know about __raw!\n */\n protected async extractIdTokenInternal(): Promise<string | null> {\n try {\n const claims = await firstValueFrom(this.auth.idTokenClaims$);\n // Auth0-specific detail: JWT is in __raw property\n return claims?.__raw || null;\n } catch (error) {\n console.error('[Auth0] Error extracting ID token:', error);\n return null;\n }\n }\n\n /**\n * Extract complete token info from Auth0\n *\n * Maps Auth0's token structure to StandardAuthToken\n */\n protected async extractTokenInfoInternal(): Promise<StandardAuthToken | null> {\n try {\n const claims = await firstValueFrom(this.auth.idTokenClaims$);\n if (!claims) {\n return null;\n }\n\n const idToken = claims.__raw;\n if (!idToken) {\n return null;\n }\n\n return {\n idToken,\n expiresAt: claims.exp ? claims.exp * 1000 : 0, // Convert to milliseconds\n scopes: claims.scope ? claims.scope.split(' ') : undefined\n };\n } catch (error) {\n console.error('[Auth0] Error extracting token info:', error);\n return null;\n }\n }\n\n /**\n * Extract user info from Auth0 claims\n *\n * Maps Auth0's user object structure to StandardUserInfo\n */\n protected async extractUserInfoInternal(): Promise<StandardUserInfo | null> {\n try {\n const user = await firstValueFrom(this.auth.user$);\n if (!user) {\n return null;\n }\n\n return this.mapAuth0UserToStandard(user);\n } catch (error) {\n console.error('[Auth0] Error extracting user info:', error);\n return null;\n }\n }\n\n /**\n * Refresh token using Auth0's silent authentication\n *\n * Uses cacheMode: 'off' to bypass cache and force token refresh\n * With useRefreshTokens: true and offline_access scope, this will use refresh tokens\n */\n protected async refreshTokenInternal(): Promise<TokenRefreshResult> {\n try {\n console.log('[Auth0] Attempting to refresh token...');\n\n // Force token refresh by bypassing cache\n // With useRefreshTokens: true and offline_access scope, this will use refresh tokens\n await firstValueFrom(this.auth.getAccessTokenSilently({\n cacheMode: 'off'\n }));\n\n // Small delay to ensure Auth0 SDK has updated observables\n await new Promise(resolve => setTimeout(resolve, 100));\n\n // Extract fresh token info from updated observables\n const token = await this.extractTokenInfoInternal();\n\n if (!token) {\n return {\n success: false,\n error: {\n type: AuthErrorType.NO_ACTIVE_SESSION,\n message: 'Token refresh succeeded but could not extract token info',\n userMessage: 'Session refresh failed. Please log in again.'\n }\n };\n }\n\n console.log('[Auth0] Token refresh successful', {\n expiresAt: new Date(token.expiresAt).toISOString()\n });\n\n return {\n success: true,\n token\n };\n } catch (error) {\n console.error('[Auth0] Token refresh failed:', error);\n\n return {\n success: false,\n error: this.classifyErrorInternal(error)\n };\n }\n }\n\n /**\n * Classify Auth0-specific errors into semantic types\n *\n * Maps Auth0 error patterns to AuthErrorType enum\n */\n protected classifyErrorInternal(error: unknown): StandardAuthError {\n const errorObj = error as Record<string, unknown>;\n const message = errorObj?.['message'] as string || 'Unknown error';\n const errorType = errorObj?.['error'] as string || '';\n\n // Check for specific Auth0 error patterns\n if (message.includes('jwt expired') || message.includes('token expired')) {\n return {\n type: AuthErrorType.TOKEN_EXPIRED,\n message,\n originalError: error,\n userMessage: 'Your session has expired. Please log in again.'\n };\n }\n\n if (errorType === 'login_required' || message.includes('login_required')) {\n return {\n type: AuthErrorType.NO_ACTIVE_SESSION,\n message,\n originalError: error,\n userMessage: 'You need to log in to continue.'\n };\n }\n\n if (errorType === 'consent_required' || message.includes('consent_required')) {\n return {\n type: AuthErrorType.INTERACTION_REQUIRED,\n message,\n originalError: error,\n userMessage: 'Additional permissions are required. Please log in again.'\n };\n }\n\n if (message.includes('user closed') || message.includes('cancelled')) {\n return {\n type: AuthErrorType.USER_CANCELLED,\n message,\n originalError: error,\n userMessage: 'Login was cancelled.'\n };\n }\n\n if (message.includes('network') || message.includes('fetch')) {\n return {\n type: AuthErrorType.NETWORK_ERROR,\n message,\n originalError: error,\n userMessage: 'Network error. Please check your connection and try again.'\n };\n }\n\n // Default to unknown error\n return {\n type: AuthErrorType.UNKNOWN_ERROR,\n message,\n originalError: error,\n userMessage: 'An unexpected error occurred. Please try again.'\n };\n }\n\n // ============================================================================\n // HELPER METHODS\n // ============================================================================\n\n private async ensureInitialized(): Promise<void> {\n if (!this._initialized) {\n await this.initialize();\n }\n }\n\n /**\n * Map Auth0 User object to StandardUserInfo\n */\n private mapAuth0UserToStandard(user: User): StandardUserInfo {\n return {\n id: user.sub || '',\n email: user.email || '',\n name: user.name || '',\n givenName: user.given_name,\n familyName: user.family_name,\n preferredUsername: user.nickname,\n pictureUrl: user.picture,\n locale: user.locale,\n emailVerified: user.email_verified\n };\n }\n\n /**\n * Get profile picture URL from Auth0\n *\n * Auth0 includes the picture URL directly in user claims.\n * No additional API call needed.\n */\n protected async getProfilePictureUrlInternal(): Promise<string | null> {\n try {\n const user = await firstValueFrom(this.auth.user$);\n return user?.picture || null;\n } catch (error) {\n console.error('[Auth0] Error getting profile picture:', error);\n return null;\n }\n }\n\n /**\n * Handle session expiry - no-op for Auth0\n *\n * Auth0 uses refresh tokens (offline_access scope), so it doesn't need\n * interactive re-authentication when tokens expire. If refresh fails,\n * the base class will throw an error and the user must log out/in manually.\n */\n protected async handleSessionExpiryInternal(): Promise<void> {\n // No-op - Auth0 doesn't need interactive re-auth\n return;\n }\n\n // ============================================================================\n // CONFIGURATION\n // ============================================================================\n\n override getRequiredConfig(): string[] {\n return ['clientId', 'domain'];\n }\n\n override validateConfig(_config: Record<string, unknown>): boolean {\n // Auth0 configuration is handled by Angular module providers\n return true;\n }\n}\n"]}
|
|
@@ -47,7 +47,7 @@ export declare class MJMSALProvider extends MJAuthBase implements OnDestroy {
|
|
|
47
47
|
initialize(): Promise<void>;
|
|
48
48
|
private _performInitialization;
|
|
49
49
|
protected loginInternal(options?: Record<string, unknown>): Promise<void>;
|
|
50
|
-
|
|
50
|
+
protected logoutInternal(): Promise<void>;
|
|
51
51
|
handleCallback(): Promise<void>;
|
|
52
52
|
/**
|
|
53
53
|
* Extract ID token from MSAL's storage
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mjexplorer-msal-provider.service.d.ts","sourceRoot":"","sources":["../../../src/lib/providers/mjexplorer-msal-provider.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,SAAS,EAAE,MAAM,eAAe,CAAC;AAEtD,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAE7D,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAA6D,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAE9I,OAAO,EAAuF,uBAAuB,EAAE,eAAe,EAAoB,MAAM,qBAAqB,CAAC;AAGtL,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EAEjB,kBAAkB,EACnB,MAAM,eAAe,CAAC;;AACvB;;;;;;GAMG;AACH,qBAIa,cAAe,SAAQ,UAAW,YAAW,SAAS;IA+C9C,IAAI,EAAE,WAAW;IAAE,OAAO,CAAC,oBAAoB;IA9ClE,MAAM,CAAC,QAAQ,CAAC,aAAa,UAAU;IACvC,QAAQ,CAAC,IAAI,UAAgC;IAE7C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAuB;IACpD,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAAuC;IACjF,OAAO,CAAC,YAAY,CAA8B;IAElD;;;OAGG;IACH,MAAM,CAAC,sBAAsB,GAAI,aAAa,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;;;;;;;;;;;;SAiCnE;gBAEiB,IAAI,EAAE,WAAW,EAAU,oBAAoB,EAAE,oBAAoB;IAYlF,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;YASnB,sBAAsB;cAkEpB,aAAa,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"mjexplorer-msal-provider.service.d.ts","sourceRoot":"","sources":["../../../src/lib/providers/mjexplorer-msal-provider.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,SAAS,EAAE,MAAM,eAAe,CAAC;AAEtD,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAE7D,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAA6D,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAE9I,OAAO,EAAuF,uBAAuB,EAAE,eAAe,EAAoB,MAAM,qBAAqB,CAAC;AAGtL,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EAEjB,kBAAkB,EACnB,MAAM,eAAe,CAAC;;AACvB;;;;;;GAMG;AACH,qBAIa,cAAe,SAAQ,UAAW,YAAW,SAAS;IA+C9C,IAAI,EAAE,WAAW;IAAE,OAAO,CAAC,oBAAoB;IA9ClE,MAAM,CAAC,QAAQ,CAAC,aAAa,UAAU;IACvC,QAAQ,CAAC,IAAI,UAAgC;IAE7C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAuB;IACpD,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAAuC;IACjF,OAAO,CAAC,YAAY,CAA8B;IAElD;;;OAGG;IACH,MAAM,CAAC,sBAAsB,GAAI,aAAa,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;;;;;;;;;;;;SAiCnE;gBAEiB,IAAI,EAAE,WAAW,EAAU,oBAAoB,EAAE,oBAAoB;IAYlF,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;YASnB,sBAAsB;cAkEpB,aAAa,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;cAqB/D,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAOzC,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAUrC;;;;;OAKG;cACa,sBAAsB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAkDhE;;;;OAIG;cACa,wBAAwB,IAAI,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IA4C7E;;;;OAIG;cACa,uBAAuB,IAAI,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAgB3E;;;;;;;;;;;;;OAaG;cACa,oBAAoB,IAAI,OAAO,CAAC,kBAAkB,CAAC;IAwGnE;;;;;OAKG;IACH,SAAS,CAAC,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,iBAAiB;YAiHpD,iBAAiB;IAQ/B;;;;;;;;OAQG;IACH,OAAO,CAAC,YAAY;IAepB;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAYhC;;;;;;OAMG;cACa,4BAA4B,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAqCtE;;;;;;OAMG;cACa,2BAA2B,IAAI,OAAO,CAAC,IAAI,CAAC;IAqBnD,iBAAiB,IAAI,MAAM,EAAE;IAI7B,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO;IASlE,WAAW,IAAI,IAAI;yCA3pBR,cAAc;6CAAd,cAAc;CAiqB1B"}
|
|
@@ -160,7 +160,7 @@ let MJMSALProvider = class MJMSALProvider extends MJAuthBase {
|
|
|
160
160
|
});
|
|
161
161
|
});
|
|
162
162
|
}
|
|
163
|
-
async
|
|
163
|
+
async logoutInternal() {
|
|
164
164
|
await this.ensureInitialized();
|
|
165
165
|
this.auth.logoutRedirect().subscribe(() => {
|
|
166
166
|
// Logout will trigger a redirect
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mjexplorer-msal-provider.service.js","sourceRoot":"","sources":["../../../src/lib/providers/mjexplorer-msal-provider.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, OnDestroy } from '@angular/core';\nimport { RegisterClass } from '@memberjunction/global';\nimport { MJAuthBase } from '../mjexplorer-auth-base.service';\nimport { BehaviorSubject, Observable, Subject, catchError, filter, from, map, of, throwError, takeUntil, take } from 'rxjs';\nimport { MsalBroadcastService, MsalService, MSAL_INSTANCE, MSAL_GUARD_CONFIG, MSAL_INTERCEPTOR_CONFIG, MsalGuard } from '@azure/msal-angular';\nimport { AccountInfo, AuthenticationResult } from '@azure/msal-common';\nimport { CacheLookupPolicy, ClientAuthError, InteractionRequiredAuthError, InteractionStatus, PublicClientApplication, InteractionType, BrowserAuthError } from '@azure/msal-browser';\nimport { LogError } from '@memberjunction/core';\nimport { AngularAuthProviderConfig } from '../IAuthProvider';\nimport {\n StandardUserInfo,\n StandardAuthToken,\n StandardAuthError,\n AuthErrorType,\n TokenRefreshResult\n} from '../auth-types';\n/**\n * MSAL (Microsoft Authentication Library) provider implementation - v3.0.0\n *\n * Implements the abstract methods from MJAuthBase to hide MSAL-specific details.\n * The key abstraction is that MSAL stores the JWT in AuthenticationResult.idToken,\n * but consumers never need to know this detail.\n */\n@Injectable({\n providedIn: 'root'\n})\n@RegisterClass(MJAuthBase, 'msal')\nexport class MJMSALProvider extends MJAuthBase implements OnDestroy {\n static readonly PROVIDER_TYPE = 'msal';\n readonly type = MJMSALProvider.PROVIDER_TYPE;\n\n private readonly _destroying$ = new Subject<void>();\n private readonly _initializationCompleted$ = new BehaviorSubject<boolean>(false);\n private _initPromise: Promise<void> | null = null;\n\n /**\n * Factory function to provide Angular dependencies required by MSAL\n * Stored as a static property for the factory to access without instantiation\n */\n static angularProviderFactory = (environment: Record<string, unknown>) => [\n {\n provide: MSAL_INSTANCE,\n useValue: new PublicClientApplication({\n auth: {\n clientId: environment['CLIENT_ID'] as string,\n authority: environment['CLIENT_AUTHORITY'] as string,\n redirectUri: window.location.origin,\n },\n cache: {\n cacheLocation: 'localStorage',\n },\n }),\n },\n {\n provide: MSAL_GUARD_CONFIG,\n useValue: {\n interactionType: InteractionType.Redirect,\n authRequest: {\n scopes: ['User.Read'],\n },\n },\n },\n {\n provide: MSAL_INTERCEPTOR_CONFIG,\n useValue: {\n interactionType: InteractionType.Redirect,\n protectedResourceMap: new Map([['https://graph.microsoft.com/v1.0/me', ['user.read']]]),\n },\n },\n MsalService,\n MsalGuard,\n MsalBroadcastService\n ];\n\n constructor(public auth: MsalService, private msalBroadcastService: MsalBroadcastService) {\n const config: AngularAuthProviderConfig = {\n name: MJMSALProvider.PROVIDER_TYPE,\n type: MJMSALProvider.PROVIDER_TYPE\n };\n super(config);\n }\n\n // ============================================================================\n // LIFECYCLE METHODS\n // ============================================================================\n\n async initialize(): Promise<void> {\n if (this._initPromise) {\n return this._initPromise;\n }\n\n this._initPromise = this._performInitialization();\n return this._initPromise;\n }\n\n private async _performInitialization(): Promise<void> {\n console.debug('[MSAL] Starting initialization...');\n await this.auth.instance.initialize();\n console.debug('[MSAL] MSAL instance initialized');\n\n // Handle redirect immediately after initialization\n const redirectResponse = await this.auth.instance.handleRedirectPromise();\n console.debug('[MSAL] Redirect response:', redirectResponse ? 'Found' : 'None');\n\n if (redirectResponse && redirectResponse.account) {\n // User just logged in via redirect\n console.debug('[MSAL] Processing redirect login');\n this.auth.instance.setActiveAccount(redirectResponse.account);\n this.updateAuthState(true);\n\n // Update user info from account\n const userInfo = this.mapMSALAccountToStandard(redirectResponse.account);\n this.updateUserInfo(userInfo);\n\n this._initializationCompleted$.next(true);\n console.debug('[MSAL] Initialization completed (redirect login)');\n } else {\n // Set active account if we have one from cache\n const accounts = this.auth.instance.getAllAccounts();\n console.debug('[MSAL] Cached accounts found:', accounts.length);\n\n if (accounts.length > 0) {\n console.debug('[MSAL] Restoring session from cached account:', accounts[0].username);\n this.auth.instance.setActiveAccount(accounts[0]);\n this.updateAuthState(true);\n\n // Update user info from cached account\n const userInfo = this.mapMSALAccountToStandard(accounts[0]);\n this.updateUserInfo(userInfo);\n\n this._initializationCompleted$.next(true);\n console.debug('[MSAL] Initialization completed (cached session restored)');\n } else {\n console.debug('[MSAL] No cached accounts, user needs to log in');\n }\n }\n\n // Subscribe to broadcast service for ongoing auth state changes\n this.msalBroadcastService.inProgress$\n .pipe(\n filter((status: InteractionStatus) => status === InteractionStatus.None),\n takeUntil(this._destroying$)\n )\n .subscribe(() => {\n const accounts = this.auth.instance.getAllAccounts();\n const isAuth = accounts.length > 0;\n\n this.updateAuthState(isAuth);\n\n if (isAuth) {\n this.auth.instance.setActiveAccount(accounts[0]);\n const userInfo = this.mapMSALAccountToStandard(accounts[0]);\n this.updateUserInfo(userInfo);\n } else {\n this.updateUserInfo(null);\n }\n\n this._initializationCompleted$.next(true);\n });\n }\n\n protected async loginInternal(options?: Record<string, unknown>): Promise<void> {\n await this.ensureInitialized();\n\n const silentRequest = {\n scopes: ['User.Read', 'email', 'profile'],\n ...options\n };\n\n return new Promise((resolve, reject) => {\n this.auth.loginRedirect(silentRequest).subscribe({\n next: () => {\n resolve();\n },\n error: (error) => {\n LogError(error);\n reject(error);\n }\n });\n });\n }\n\n async logout(): Promise<void> {\n await this.ensureInitialized();\n this.auth.logoutRedirect().subscribe(() => {\n // Logout will trigger a redirect\n });\n }\n\n async handleCallback(): Promise<void> {\n // MSAL Angular handles callbacks internally through its broadcast service\n // The handleRedirectPromise is called in initialize()\n await this.ensureInitialized();\n }\n\n // ============================================================================\n // ABSTRACT METHOD IMPLEMENTATIONS (v3.0.0)\n // ============================================================================\n\n /**\n * Extract ID token from MSAL's storage\n *\n * MSAL stores the JWT in AuthenticationResult.idToken\n * This is the key abstraction - consumers never need to know about MSAL's structure!\n */\n protected async extractIdTokenInternal(): Promise<string | null> {\n try {\n await this.ensureInitialized();\n\n const account = this.auth.instance.getActiveAccount();\n if (!account) {\n return null;\n }\n\n // First try to get cached token from account\n // This avoids unnecessary iframe calls that can timeout\n if (account.idToken) {\n // Check if token is expired or about to expire (within 5-minute buffer)\n // This prevents the race condition where proactive refresh hasn't completed\n // but the cached token is already expired\n if (this.isTokenValid(account.idToken, 300)) {\n return account.idToken;\n }\n\n // Token expired or near-expiry — force a silent refresh\n console.debug('[MSAL] Cached token expired or near-expiry, forcing silent refresh');\n try {\n const response = await this.auth.instance.acquireTokenSilent({\n scopes: ['User.Read', 'email', 'profile'],\n account: account,\n forceRefresh: true\n });\n return response.idToken || null;\n } catch (refreshError) {\n console.warn('[MSAL] Silent refresh failed, returning expired cached token:', refreshError);\n // Fall through to existing cache-only acquisition below\n }\n }\n\n // If not in account, try silent token acquisition from cache only\n // Use CacheLookupPolicy.AccessToken to avoid iframe calls\n const response = await this.auth.instance.acquireTokenSilent({\n scopes: ['User.Read', 'email', 'profile'],\n account: account,\n cacheLookupPolicy: CacheLookupPolicy.AccessToken\n });\n\n // MSAL-specific detail: JWT is in idToken property\n return response.idToken || null;\n } catch (error) {\n console.error('[MSAL] Error extracting ID token:', error);\n return null;\n }\n }\n\n /**\n * Extract complete token info from MSAL\n *\n * Maps MSAL's AuthenticationResult to StandardAuthToken\n */\n protected async extractTokenInfoInternal(): Promise<StandardAuthToken | null> {\n try {\n await this.ensureInitialized();\n\n const account = this.auth.instance.getActiveAccount();\n if (!account) {\n return null;\n }\n\n // Use cache-only lookup to avoid iframe timeouts during normal token extraction\n const response = await this.auth.instance.acquireTokenSilent({\n scopes: ['User.Read', 'email', 'profile'],\n account: account,\n cacheLookupPolicy: CacheLookupPolicy.AccessToken\n });\n\n if (!response.idToken) {\n return null;\n }\n\n return {\n idToken: response.idToken,\n accessToken: response.accessToken,\n expiresAt: response.expiresOn ? response.expiresOn.getTime() : 0,\n scopes: response.scopes\n };\n } catch (error) {\n // If acquireTokenSilent fails (e.g., iframe timeout), try to use cached account data\n console.error('[MSAL] Error extracting token info:', error);\n\n const account = this.auth.instance.getActiveAccount();\n if (account?.idToken) {\n // Return basic token info from account if available\n return {\n idToken: account.idToken,\n expiresAt: 0, // Unknown from account alone\n scopes: []\n };\n }\n\n return null;\n }\n }\n\n /**\n * Extract user info from MSAL account\n *\n * Maps MSAL's AccountInfo structure to StandardUserInfo\n */\n protected async extractUserInfoInternal(): Promise<StandardUserInfo | null> {\n try {\n await this.ensureInitialized();\n\n const account = this.auth.instance.getActiveAccount();\n if (!account) {\n return null;\n }\n\n return this.mapMSALAccountToStandard(account);\n } catch (error) {\n console.error('[MSAL] Error extracting user info:', error);\n return null;\n }\n }\n\n /**\n * Refresh token using MSAL's silent token acquisition\n *\n * MSAL 5.x Best Practices:\n * - Pass account parameter for reliable silent acquisition\n * - Use forceRefresh: true to bypass cache and get fresh tokens from Azure AD\n * - Handle MSAL 5.x specific error codes (timed_out, no_tokens_found, etc.)\n *\n * IMPORTANT: This method is called when the server has already rejected the current\n * token as expired (JWT_EXPIRED). Using CacheLookupPolicy.Default here can return a\n * cached ID token that is still expired (e.g. when the access token has a longer\n * lifetime than the ID token). forceRefresh: true ensures a network round-trip to\n * Azure AD so both the access token and ID token are genuinely refreshed.\n */\n protected async refreshTokenInternal(): Promise<TokenRefreshResult> {\n try {\n await this.ensureInitialized();\n\n const account = this.auth.instance.getActiveAccount();\n if (!account) {\n return {\n success: false,\n error: {\n type: AuthErrorType.NO_ACTIVE_SESSION,\n message: 'No active account found',\n userMessage: 'You need to log in to continue.'\n }\n };\n }\n\n // MSAL 5.x: Pass account for reliable silent acquisition\n // Use forceRefresh to bypass cache and ensure a network round-trip.\n // This is critical because this method is called after the server rejected\n // the current token — returning a cached (potentially stale) ID token would\n // cause the retry to fail with the same JWT_EXPIRED error.\n const response = await this.auth.instance.acquireTokenSilent({\n scopes: ['User.Read', 'email', 'profile'],\n account: account,\n forceRefresh: true\n });\n\n if (!response.idToken) {\n return {\n success: false,\n error: {\n type: AuthErrorType.NO_ACTIVE_SESSION,\n message: 'Token refresh succeeded but no ID token returned',\n userMessage: 'Session refresh failed. Please log in again.'\n }\n };\n }\n\n // Safety net: verify the refreshed token is actually valid.\n // This should always pass after a forced refresh, but guards against\n // edge cases like severe clock skew between client and Azure AD.\n if (!this.isTokenValid(response.idToken)) {\n console.warn('[MSAL] Forced refresh returned an expired ID token — requesting interaction');\n return {\n success: false,\n error: {\n type: AuthErrorType.INTERACTION_REQUIRED,\n message: 'Token refresh returned an expired ID token',\n userMessage: 'Your session has expired. Redirecting to login...'\n }\n };\n }\n\n const token: StandardAuthToken = {\n idToken: response.idToken,\n accessToken: response.accessToken,\n expiresAt: response.expiresOn ? response.expiresOn.getTime() : 0,\n scopes: response.scopes\n };\n\n return {\n success: true,\n token\n };\n } catch (error) {\n console.error('[MSAL] Token refresh failed:', error);\n\n // Handle MSAL 5.x error codes that require user interaction\n // - timed_out: MSAL 5.x iframe timeout (replaces monitor_window_timeout from 3.x)\n // - monitor_window_timeout: Legacy MSAL 3.x iframe timeout\n // - no_tokens_found: No cached tokens available\n // - no_account_error: Account not found in cache\n // - InteractionRequiredAuthError: Server requires user interaction\n const errorCode = (error as Record<string, unknown>)?.errorCode as string | undefined;\n const interactionRequiredCodes = [\n 'monitor_window_timeout',\n 'timed_out',\n 'no_tokens_found',\n 'no_account_error',\n 'login_required',\n 'consent_required',\n 'token_refresh_required' // ClientAuthError when cached token needs refresh\n ];\n\n if (interactionRequiredCodes.includes(errorCode || '') || error instanceof InteractionRequiredAuthError) {\n // Return INTERACTION_REQUIRED error - base class will call handleSessionExpiryInternal\n return {\n success: false,\n error: {\n type: AuthErrorType.INTERACTION_REQUIRED,\n message: `Silent token refresh failed - interaction required (${errorCode || 'unknown'})`,\n userMessage: 'Your session has expired. Redirecting to login...',\n originalError: error\n }\n };\n }\n\n return {\n success: false,\n error: this.classifyErrorInternal(error)\n };\n }\n }\n\n /**\n * Classify MSAL-specific errors into semantic types\n *\n * Maps MSAL error classes to AuthErrorType enum.\n * Updated for MSAL 5.x error codes.\n */\n protected classifyErrorInternal(error: unknown): StandardAuthError {\n const errorObj = error as Record<string, unknown>;\n const message = errorObj?.['message'] as string || 'Unknown error';\n const errorCode = errorObj?.['errorCode'] as string || '';\n\n // Check for specific MSAL error types\n if (error instanceof InteractionRequiredAuthError) {\n return {\n type: AuthErrorType.INTERACTION_REQUIRED,\n message,\n originalError: error,\n userMessage: 'Additional authentication is required. Please log in again.'\n };\n }\n\n // ClientAuthError — covers codes like token_refresh_required that are not\n // surfaced through BrowserAuthError or InteractionRequiredAuthError.\n if (error instanceof ClientAuthError) {\n if (errorCode === 'token_refresh_required') {\n return {\n type: AuthErrorType.INTERACTION_REQUIRED,\n message,\n originalError: error,\n userMessage: 'Your session has expired. Please log in again.'\n };\n }\n\n return {\n type: AuthErrorType.TOKEN_EXPIRED,\n message,\n originalError: error,\n userMessage: 'Your session has expired. Please log in again.'\n };\n }\n\n if (error instanceof BrowserAuthError) {\n // Check specific error codes - MSAL 5.x codes\n if (errorCode === 'user_cancelled' || message.includes('user cancelled')) {\n return {\n type: AuthErrorType.USER_CANCELLED,\n message,\n originalError: error,\n userMessage: 'Login was cancelled.'\n };\n }\n\n // MSAL 5.x timeout and session errors that require interaction\n const interactionRequiredCodes = [\n 'timed_out',\n 'monitor_window_timeout',\n 'no_tokens_found',\n 'no_account_error',\n 'login_required',\n 'consent_required'\n ];\n if (interactionRequiredCodes.includes(errorCode)) {\n return {\n type: AuthErrorType.INTERACTION_REQUIRED,\n message,\n originalError: error,\n userMessage: 'Your session has expired. Please log in again.'\n };\n }\n\n return {\n type: AuthErrorType.NO_ACTIVE_SESSION,\n message,\n originalError: error,\n userMessage: 'Authentication error. Please log in again.'\n };\n }\n\n // Check message patterns\n if (message.includes('token') && message.includes('expired')) {\n return {\n type: AuthErrorType.TOKEN_EXPIRED,\n message,\n originalError: error,\n userMessage: 'Your session has expired. Please log in again.'\n };\n }\n\n if (message.includes('network') || message.includes('fetch')) {\n return {\n type: AuthErrorType.NETWORK_ERROR,\n message,\n originalError: error,\n userMessage: 'Network error. Please check your connection and try again.'\n };\n }\n\n if (message.includes('you need to be authorized')) {\n return {\n type: AuthErrorType.TOKEN_EXPIRED,\n message,\n originalError: error,\n userMessage: 'Your session has expired. Please log in again.'\n };\n }\n\n // Default to unknown error\n return {\n type: AuthErrorType.UNKNOWN_ERROR,\n message,\n originalError: error,\n userMessage: 'An unexpected error occurred. Please try again.'\n };\n }\n\n // ============================================================================\n // HELPER METHODS\n // ============================================================================\n\n private async ensureInitialized(): Promise<void> {\n if (!this._initPromise) {\n await this.initialize();\n } else if (!this._initializationCompleted$.value) {\n await this._initPromise;\n }\n }\n\n /**\n * Check if a JWT token is still valid with an optional buffer period.\n * Decodes the payload to read the `exp` claim without cryptographic verification\n * (expiry is a timing check, not an authenticity check).\n *\n * @param token - The JWT string to check\n * @param bufferSeconds - Number of seconds before actual expiry to consider the token invalid (default: 0)\n * @returns true if the token's exp claim is beyond (now + buffer), false otherwise\n */\n private isTokenValid(token: string, bufferSeconds: number = 0): boolean {\n try {\n const parts = token.split('.');\n if (parts.length !== 3) {\n return false;\n }\n const payload = JSON.parse(atob(parts[1])) as { exp?: number };\n const expiresAtMs = (payload.exp ?? 0) * 1000;\n return expiresAtMs > Date.now() + (bufferSeconds * 1000);\n } catch {\n // If we can't decode the token, treat it as invalid\n return false;\n }\n }\n\n /**\n * Map MSAL AccountInfo to StandardUserInfo\n */\n private mapMSALAccountToStandard(account: AccountInfo): StandardUserInfo {\n return {\n id: account.localAccountId || account.homeAccountId,\n email: account.username || '',\n name: account.name || account.username || '',\n givenName: account.idTokenClaims?.['given_name'] as string,\n familyName: account.idTokenClaims?.['family_name'] as string,\n preferredUsername: account.username,\n emailVerified: true // MSAL doesn't provide this, assume true\n };\n }\n\n /**\n * Get profile picture URL from Microsoft Graph API\n *\n * MSAL requires fetching the photo from Microsoft Graph.\n * This is the key advantage of encapsulation - consumers don't need\n * to know about Graph API, they just call getProfilePictureUrl()!\n */\n protected async getProfilePictureUrlInternal(): Promise<string | null> {\n try {\n await this.ensureInitialized();\n\n const account = this.auth.instance.getActiveAccount();\n if (!account) {\n return null;\n }\n\n // Get access token for Microsoft Graph\n const response = await this.auth.instance.acquireTokenSilent({\n scopes: ['User.Read'],\n account: account,\n forceRefresh: false\n });\n\n if (!response.accessToken) {\n return null;\n }\n\n // Fetch photo from Microsoft Graph\n const graphResponse = await fetch('https://graph.microsoft.com/v1.0/me/photo/$value', {\n headers: { 'Authorization': `Bearer ${response.accessToken}` }\n });\n\n if (graphResponse.ok) {\n const blob = await graphResponse.blob();\n return URL.createObjectURL(blob);\n }\n\n return null;\n } catch (error) {\n console.error('[MSAL] Error getting profile picture:', error);\n return null;\n }\n }\n\n /**\n * Handle session expiry by redirecting to Microsoft login\n *\n * This method is called by the base class when silent token refresh fails\n * with INTERACTION_REQUIRED error. It redirects to Microsoft login and never returns.\n * After authentication, the app will reload and re-initialize with a fresh token.\n */\n protected async handleSessionExpiryInternal(): Promise<void> {\n console.debug('[MSAL] Redirecting to Microsoft login for re-authentication...');\n\n // Initiate redirect authentication - page will navigate away\n this.auth.loginRedirect({\n scopes: ['User.Read', 'email', 'profile'],\n prompt: 'select_account'\n }).subscribe({\n error: (redirectError) => {\n console.error('[MSAL] Redirect initiation failed:', redirectError);\n }\n });\n\n // Return a promise that never resolves - page will navigate before this matters\n return new Promise<void>(() => {});\n }\n\n // ============================================================================\n // CONFIGURATION\n // ============================================================================\n\n override getRequiredConfig(): string[] {\n return ['clientId', 'tenantId'];\n }\n\n override validateConfig(_config: Record<string, unknown>): boolean {\n // MSAL configuration is handled by Angular module providers\n return true;\n }\n\n // ============================================================================\n // CLEANUP\n // ============================================================================\n\n ngOnDestroy(): void {\n this._destroying$.next();\n this._destroying$.complete();\n this._initPromise = null;\n this._initializationCompleted$.complete();\n }\n}"]}
|
|
1
|
+
{"version":3,"file":"mjexplorer-msal-provider.service.js","sourceRoot":"","sources":["../../../src/lib/providers/mjexplorer-msal-provider.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, OnDestroy } from '@angular/core';\nimport { RegisterClass } from '@memberjunction/global';\nimport { MJAuthBase } from '../mjexplorer-auth-base.service';\nimport { BehaviorSubject, Observable, Subject, catchError, filter, from, map, of, throwError, takeUntil, take } from 'rxjs';\nimport { MsalBroadcastService, MsalService, MSAL_INSTANCE, MSAL_GUARD_CONFIG, MSAL_INTERCEPTOR_CONFIG, MsalGuard } from '@azure/msal-angular';\nimport { AccountInfo, AuthenticationResult } from '@azure/msal-common';\nimport { CacheLookupPolicy, ClientAuthError, InteractionRequiredAuthError, InteractionStatus, PublicClientApplication, InteractionType, BrowserAuthError } from '@azure/msal-browser';\nimport { LogError } from '@memberjunction/core';\nimport { AngularAuthProviderConfig } from '../IAuthProvider';\nimport {\n StandardUserInfo,\n StandardAuthToken,\n StandardAuthError,\n AuthErrorType,\n TokenRefreshResult\n} from '../auth-types';\n/**\n * MSAL (Microsoft Authentication Library) provider implementation - v3.0.0\n *\n * Implements the abstract methods from MJAuthBase to hide MSAL-specific details.\n * The key abstraction is that MSAL stores the JWT in AuthenticationResult.idToken,\n * but consumers never need to know this detail.\n */\n@Injectable({\n providedIn: 'root'\n})\n@RegisterClass(MJAuthBase, 'msal')\nexport class MJMSALProvider extends MJAuthBase implements OnDestroy {\n static readonly PROVIDER_TYPE = 'msal';\n readonly type = MJMSALProvider.PROVIDER_TYPE;\n\n private readonly _destroying$ = new Subject<void>();\n private readonly _initializationCompleted$ = new BehaviorSubject<boolean>(false);\n private _initPromise: Promise<void> | null = null;\n\n /**\n * Factory function to provide Angular dependencies required by MSAL\n * Stored as a static property for the factory to access without instantiation\n */\n static angularProviderFactory = (environment: Record<string, unknown>) => [\n {\n provide: MSAL_INSTANCE,\n useValue: new PublicClientApplication({\n auth: {\n clientId: environment['CLIENT_ID'] as string,\n authority: environment['CLIENT_AUTHORITY'] as string,\n redirectUri: window.location.origin,\n },\n cache: {\n cacheLocation: 'localStorage',\n },\n }),\n },\n {\n provide: MSAL_GUARD_CONFIG,\n useValue: {\n interactionType: InteractionType.Redirect,\n authRequest: {\n scopes: ['User.Read'],\n },\n },\n },\n {\n provide: MSAL_INTERCEPTOR_CONFIG,\n useValue: {\n interactionType: InteractionType.Redirect,\n protectedResourceMap: new Map([['https://graph.microsoft.com/v1.0/me', ['user.read']]]),\n },\n },\n MsalService,\n MsalGuard,\n MsalBroadcastService\n ];\n\n constructor(public auth: MsalService, private msalBroadcastService: MsalBroadcastService) {\n const config: AngularAuthProviderConfig = {\n name: MJMSALProvider.PROVIDER_TYPE,\n type: MJMSALProvider.PROVIDER_TYPE\n };\n super(config);\n }\n\n // ============================================================================\n // LIFECYCLE METHODS\n // ============================================================================\n\n async initialize(): Promise<void> {\n if (this._initPromise) {\n return this._initPromise;\n }\n\n this._initPromise = this._performInitialization();\n return this._initPromise;\n }\n\n private async _performInitialization(): Promise<void> {\n console.debug('[MSAL] Starting initialization...');\n await this.auth.instance.initialize();\n console.debug('[MSAL] MSAL instance initialized');\n\n // Handle redirect immediately after initialization\n const redirectResponse = await this.auth.instance.handleRedirectPromise();\n console.debug('[MSAL] Redirect response:', redirectResponse ? 'Found' : 'None');\n\n if (redirectResponse && redirectResponse.account) {\n // User just logged in via redirect\n console.debug('[MSAL] Processing redirect login');\n this.auth.instance.setActiveAccount(redirectResponse.account);\n this.updateAuthState(true);\n\n // Update user info from account\n const userInfo = this.mapMSALAccountToStandard(redirectResponse.account);\n this.updateUserInfo(userInfo);\n\n this._initializationCompleted$.next(true);\n console.debug('[MSAL] Initialization completed (redirect login)');\n } else {\n // Set active account if we have one from cache\n const accounts = this.auth.instance.getAllAccounts();\n console.debug('[MSAL] Cached accounts found:', accounts.length);\n\n if (accounts.length > 0) {\n console.debug('[MSAL] Restoring session from cached account:', accounts[0].username);\n this.auth.instance.setActiveAccount(accounts[0]);\n this.updateAuthState(true);\n\n // Update user info from cached account\n const userInfo = this.mapMSALAccountToStandard(accounts[0]);\n this.updateUserInfo(userInfo);\n\n this._initializationCompleted$.next(true);\n console.debug('[MSAL] Initialization completed (cached session restored)');\n } else {\n console.debug('[MSAL] No cached accounts, user needs to log in');\n }\n }\n\n // Subscribe to broadcast service for ongoing auth state changes\n this.msalBroadcastService.inProgress$\n .pipe(\n filter((status: InteractionStatus) => status === InteractionStatus.None),\n takeUntil(this._destroying$)\n )\n .subscribe(() => {\n const accounts = this.auth.instance.getAllAccounts();\n const isAuth = accounts.length > 0;\n\n this.updateAuthState(isAuth);\n\n if (isAuth) {\n this.auth.instance.setActiveAccount(accounts[0]);\n const userInfo = this.mapMSALAccountToStandard(accounts[0]);\n this.updateUserInfo(userInfo);\n } else {\n this.updateUserInfo(null);\n }\n\n this._initializationCompleted$.next(true);\n });\n }\n\n protected async loginInternal(options?: Record<string, unknown>): Promise<void> {\n await this.ensureInitialized();\n\n const silentRequest = {\n scopes: ['User.Read', 'email', 'profile'],\n ...options\n };\n\n return new Promise((resolve, reject) => {\n this.auth.loginRedirect(silentRequest).subscribe({\n next: () => {\n resolve();\n },\n error: (error) => {\n LogError(error);\n reject(error);\n }\n });\n });\n }\n\n protected async logoutInternal(): Promise<void> {\n await this.ensureInitialized();\n this.auth.logoutRedirect().subscribe(() => {\n // Logout will trigger a redirect\n });\n }\n\n async handleCallback(): Promise<void> {\n // MSAL Angular handles callbacks internally through its broadcast service\n // The handleRedirectPromise is called in initialize()\n await this.ensureInitialized();\n }\n\n // ============================================================================\n // ABSTRACT METHOD IMPLEMENTATIONS (v3.0.0)\n // ============================================================================\n\n /**\n * Extract ID token from MSAL's storage\n *\n * MSAL stores the JWT in AuthenticationResult.idToken\n * This is the key abstraction - consumers never need to know about MSAL's structure!\n */\n protected async extractIdTokenInternal(): Promise<string | null> {\n try {\n await this.ensureInitialized();\n\n const account = this.auth.instance.getActiveAccount();\n if (!account) {\n return null;\n }\n\n // First try to get cached token from account\n // This avoids unnecessary iframe calls that can timeout\n if (account.idToken) {\n // Check if token is expired or about to expire (within 5-minute buffer)\n // This prevents the race condition where proactive refresh hasn't completed\n // but the cached token is already expired\n if (this.isTokenValid(account.idToken, 300)) {\n return account.idToken;\n }\n\n // Token expired or near-expiry — force a silent refresh\n console.debug('[MSAL] Cached token expired or near-expiry, forcing silent refresh');\n try {\n const response = await this.auth.instance.acquireTokenSilent({\n scopes: ['User.Read', 'email', 'profile'],\n account: account,\n forceRefresh: true\n });\n return response.idToken || null;\n } catch (refreshError) {\n console.warn('[MSAL] Silent refresh failed, returning expired cached token:', refreshError);\n // Fall through to existing cache-only acquisition below\n }\n }\n\n // If not in account, try silent token acquisition from cache only\n // Use CacheLookupPolicy.AccessToken to avoid iframe calls\n const response = await this.auth.instance.acquireTokenSilent({\n scopes: ['User.Read', 'email', 'profile'],\n account: account,\n cacheLookupPolicy: CacheLookupPolicy.AccessToken\n });\n\n // MSAL-specific detail: JWT is in idToken property\n return response.idToken || null;\n } catch (error) {\n console.error('[MSAL] Error extracting ID token:', error);\n return null;\n }\n }\n\n /**\n * Extract complete token info from MSAL\n *\n * Maps MSAL's AuthenticationResult to StandardAuthToken\n */\n protected async extractTokenInfoInternal(): Promise<StandardAuthToken | null> {\n try {\n await this.ensureInitialized();\n\n const account = this.auth.instance.getActiveAccount();\n if (!account) {\n return null;\n }\n\n // Use cache-only lookup to avoid iframe timeouts during normal token extraction\n const response = await this.auth.instance.acquireTokenSilent({\n scopes: ['User.Read', 'email', 'profile'],\n account: account,\n cacheLookupPolicy: CacheLookupPolicy.AccessToken\n });\n\n if (!response.idToken) {\n return null;\n }\n\n return {\n idToken: response.idToken,\n accessToken: response.accessToken,\n expiresAt: response.expiresOn ? response.expiresOn.getTime() : 0,\n scopes: response.scopes\n };\n } catch (error) {\n // If acquireTokenSilent fails (e.g., iframe timeout), try to use cached account data\n console.error('[MSAL] Error extracting token info:', error);\n\n const account = this.auth.instance.getActiveAccount();\n if (account?.idToken) {\n // Return basic token info from account if available\n return {\n idToken: account.idToken,\n expiresAt: 0, // Unknown from account alone\n scopes: []\n };\n }\n\n return null;\n }\n }\n\n /**\n * Extract user info from MSAL account\n *\n * Maps MSAL's AccountInfo structure to StandardUserInfo\n */\n protected async extractUserInfoInternal(): Promise<StandardUserInfo | null> {\n try {\n await this.ensureInitialized();\n\n const account = this.auth.instance.getActiveAccount();\n if (!account) {\n return null;\n }\n\n return this.mapMSALAccountToStandard(account);\n } catch (error) {\n console.error('[MSAL] Error extracting user info:', error);\n return null;\n }\n }\n\n /**\n * Refresh token using MSAL's silent token acquisition\n *\n * MSAL 5.x Best Practices:\n * - Pass account parameter for reliable silent acquisition\n * - Use forceRefresh: true to bypass cache and get fresh tokens from Azure AD\n * - Handle MSAL 5.x specific error codes (timed_out, no_tokens_found, etc.)\n *\n * IMPORTANT: This method is called when the server has already rejected the current\n * token as expired (JWT_EXPIRED). Using CacheLookupPolicy.Default here can return a\n * cached ID token that is still expired (e.g. when the access token has a longer\n * lifetime than the ID token). forceRefresh: true ensures a network round-trip to\n * Azure AD so both the access token and ID token are genuinely refreshed.\n */\n protected async refreshTokenInternal(): Promise<TokenRefreshResult> {\n try {\n await this.ensureInitialized();\n\n const account = this.auth.instance.getActiveAccount();\n if (!account) {\n return {\n success: false,\n error: {\n type: AuthErrorType.NO_ACTIVE_SESSION,\n message: 'No active account found',\n userMessage: 'You need to log in to continue.'\n }\n };\n }\n\n // MSAL 5.x: Pass account for reliable silent acquisition\n // Use forceRefresh to bypass cache and ensure a network round-trip.\n // This is critical because this method is called after the server rejected\n // the current token — returning a cached (potentially stale) ID token would\n // cause the retry to fail with the same JWT_EXPIRED error.\n const response = await this.auth.instance.acquireTokenSilent({\n scopes: ['User.Read', 'email', 'profile'],\n account: account,\n forceRefresh: true\n });\n\n if (!response.idToken) {\n return {\n success: false,\n error: {\n type: AuthErrorType.NO_ACTIVE_SESSION,\n message: 'Token refresh succeeded but no ID token returned',\n userMessage: 'Session refresh failed. Please log in again.'\n }\n };\n }\n\n // Safety net: verify the refreshed token is actually valid.\n // This should always pass after a forced refresh, but guards against\n // edge cases like severe clock skew between client and Azure AD.\n if (!this.isTokenValid(response.idToken)) {\n console.warn('[MSAL] Forced refresh returned an expired ID token — requesting interaction');\n return {\n success: false,\n error: {\n type: AuthErrorType.INTERACTION_REQUIRED,\n message: 'Token refresh returned an expired ID token',\n userMessage: 'Your session has expired. Redirecting to login...'\n }\n };\n }\n\n const token: StandardAuthToken = {\n idToken: response.idToken,\n accessToken: response.accessToken,\n expiresAt: response.expiresOn ? response.expiresOn.getTime() : 0,\n scopes: response.scopes\n };\n\n return {\n success: true,\n token\n };\n } catch (error) {\n console.error('[MSAL] Token refresh failed:', error);\n\n // Handle MSAL 5.x error codes that require user interaction\n // - timed_out: MSAL 5.x iframe timeout (replaces monitor_window_timeout from 3.x)\n // - monitor_window_timeout: Legacy MSAL 3.x iframe timeout\n // - no_tokens_found: No cached tokens available\n // - no_account_error: Account not found in cache\n // - InteractionRequiredAuthError: Server requires user interaction\n const errorCode = (error as Record<string, unknown>)?.errorCode as string | undefined;\n const interactionRequiredCodes = [\n 'monitor_window_timeout',\n 'timed_out',\n 'no_tokens_found',\n 'no_account_error',\n 'login_required',\n 'consent_required',\n 'token_refresh_required' // ClientAuthError when cached token needs refresh\n ];\n\n if (interactionRequiredCodes.includes(errorCode || '') || error instanceof InteractionRequiredAuthError) {\n // Return INTERACTION_REQUIRED error - base class will call handleSessionExpiryInternal\n return {\n success: false,\n error: {\n type: AuthErrorType.INTERACTION_REQUIRED,\n message: `Silent token refresh failed - interaction required (${errorCode || 'unknown'})`,\n userMessage: 'Your session has expired. Redirecting to login...',\n originalError: error\n }\n };\n }\n\n return {\n success: false,\n error: this.classifyErrorInternal(error)\n };\n }\n }\n\n /**\n * Classify MSAL-specific errors into semantic types\n *\n * Maps MSAL error classes to AuthErrorType enum.\n * Updated for MSAL 5.x error codes.\n */\n protected classifyErrorInternal(error: unknown): StandardAuthError {\n const errorObj = error as Record<string, unknown>;\n const message = errorObj?.['message'] as string || 'Unknown error';\n const errorCode = errorObj?.['errorCode'] as string || '';\n\n // Check for specific MSAL error types\n if (error instanceof InteractionRequiredAuthError) {\n return {\n type: AuthErrorType.INTERACTION_REQUIRED,\n message,\n originalError: error,\n userMessage: 'Additional authentication is required. Please log in again.'\n };\n }\n\n // ClientAuthError — covers codes like token_refresh_required that are not\n // surfaced through BrowserAuthError or InteractionRequiredAuthError.\n if (error instanceof ClientAuthError) {\n if (errorCode === 'token_refresh_required') {\n return {\n type: AuthErrorType.INTERACTION_REQUIRED,\n message,\n originalError: error,\n userMessage: 'Your session has expired. Please log in again.'\n };\n }\n\n return {\n type: AuthErrorType.TOKEN_EXPIRED,\n message,\n originalError: error,\n userMessage: 'Your session has expired. Please log in again.'\n };\n }\n\n if (error instanceof BrowserAuthError) {\n // Check specific error codes - MSAL 5.x codes\n if (errorCode === 'user_cancelled' || message.includes('user cancelled')) {\n return {\n type: AuthErrorType.USER_CANCELLED,\n message,\n originalError: error,\n userMessage: 'Login was cancelled.'\n };\n }\n\n // MSAL 5.x timeout and session errors that require interaction\n const interactionRequiredCodes = [\n 'timed_out',\n 'monitor_window_timeout',\n 'no_tokens_found',\n 'no_account_error',\n 'login_required',\n 'consent_required'\n ];\n if (interactionRequiredCodes.includes(errorCode)) {\n return {\n type: AuthErrorType.INTERACTION_REQUIRED,\n message,\n originalError: error,\n userMessage: 'Your session has expired. Please log in again.'\n };\n }\n\n return {\n type: AuthErrorType.NO_ACTIVE_SESSION,\n message,\n originalError: error,\n userMessage: 'Authentication error. Please log in again.'\n };\n }\n\n // Check message patterns\n if (message.includes('token') && message.includes('expired')) {\n return {\n type: AuthErrorType.TOKEN_EXPIRED,\n message,\n originalError: error,\n userMessage: 'Your session has expired. Please log in again.'\n };\n }\n\n if (message.includes('network') || message.includes('fetch')) {\n return {\n type: AuthErrorType.NETWORK_ERROR,\n message,\n originalError: error,\n userMessage: 'Network error. Please check your connection and try again.'\n };\n }\n\n if (message.includes('you need to be authorized')) {\n return {\n type: AuthErrorType.TOKEN_EXPIRED,\n message,\n originalError: error,\n userMessage: 'Your session has expired. Please log in again.'\n };\n }\n\n // Default to unknown error\n return {\n type: AuthErrorType.UNKNOWN_ERROR,\n message,\n originalError: error,\n userMessage: 'An unexpected error occurred. Please try again.'\n };\n }\n\n // ============================================================================\n // HELPER METHODS\n // ============================================================================\n\n private async ensureInitialized(): Promise<void> {\n if (!this._initPromise) {\n await this.initialize();\n } else if (!this._initializationCompleted$.value) {\n await this._initPromise;\n }\n }\n\n /**\n * Check if a JWT token is still valid with an optional buffer period.\n * Decodes the payload to read the `exp` claim without cryptographic verification\n * (expiry is a timing check, not an authenticity check).\n *\n * @param token - The JWT string to check\n * @param bufferSeconds - Number of seconds before actual expiry to consider the token invalid (default: 0)\n * @returns true if the token's exp claim is beyond (now + buffer), false otherwise\n */\n private isTokenValid(token: string, bufferSeconds: number = 0): boolean {\n try {\n const parts = token.split('.');\n if (parts.length !== 3) {\n return false;\n }\n const payload = JSON.parse(atob(parts[1])) as { exp?: number };\n const expiresAtMs = (payload.exp ?? 0) * 1000;\n return expiresAtMs > Date.now() + (bufferSeconds * 1000);\n } catch {\n // If we can't decode the token, treat it as invalid\n return false;\n }\n }\n\n /**\n * Map MSAL AccountInfo to StandardUserInfo\n */\n private mapMSALAccountToStandard(account: AccountInfo): StandardUserInfo {\n return {\n id: account.localAccountId || account.homeAccountId,\n email: account.username || '',\n name: account.name || account.username || '',\n givenName: account.idTokenClaims?.['given_name'] as string,\n familyName: account.idTokenClaims?.['family_name'] as string,\n preferredUsername: account.username,\n emailVerified: true // MSAL doesn't provide this, assume true\n };\n }\n\n /**\n * Get profile picture URL from Microsoft Graph API\n *\n * MSAL requires fetching the photo from Microsoft Graph.\n * This is the key advantage of encapsulation - consumers don't need\n * to know about Graph API, they just call getProfilePictureUrl()!\n */\n protected async getProfilePictureUrlInternal(): Promise<string | null> {\n try {\n await this.ensureInitialized();\n\n const account = this.auth.instance.getActiveAccount();\n if (!account) {\n return null;\n }\n\n // Get access token for Microsoft Graph\n const response = await this.auth.instance.acquireTokenSilent({\n scopes: ['User.Read'],\n account: account,\n forceRefresh: false\n });\n\n if (!response.accessToken) {\n return null;\n }\n\n // Fetch photo from Microsoft Graph\n const graphResponse = await fetch('https://graph.microsoft.com/v1.0/me/photo/$value', {\n headers: { 'Authorization': `Bearer ${response.accessToken}` }\n });\n\n if (graphResponse.ok) {\n const blob = await graphResponse.blob();\n return URL.createObjectURL(blob);\n }\n\n return null;\n } catch (error) {\n console.error('[MSAL] Error getting profile picture:', error);\n return null;\n }\n }\n\n /**\n * Handle session expiry by redirecting to Microsoft login\n *\n * This method is called by the base class when silent token refresh fails\n * with INTERACTION_REQUIRED error. It redirects to Microsoft login and never returns.\n * After authentication, the app will reload and re-initialize with a fresh token.\n */\n protected async handleSessionExpiryInternal(): Promise<void> {\n console.debug('[MSAL] Redirecting to Microsoft login for re-authentication...');\n\n // Initiate redirect authentication - page will navigate away\n this.auth.loginRedirect({\n scopes: ['User.Read', 'email', 'profile'],\n prompt: 'select_account'\n }).subscribe({\n error: (redirectError) => {\n console.error('[MSAL] Redirect initiation failed:', redirectError);\n }\n });\n\n // Return a promise that never resolves - page will navigate before this matters\n return new Promise<void>(() => {});\n }\n\n // ============================================================================\n // CONFIGURATION\n // ============================================================================\n\n override getRequiredConfig(): string[] {\n return ['clientId', 'tenantId'];\n }\n\n override validateConfig(_config: Record<string, unknown>): boolean {\n // MSAL configuration is handled by Angular module providers\n return true;\n }\n\n // ============================================================================\n // CLEANUP\n // ============================================================================\n\n ngOnDestroy(): void {\n this._destroying$.next();\n this._destroying$.complete();\n this._initPromise = null;\n this._initializationCompleted$.complete();\n }\n}"]}
|
|
@@ -34,7 +34,7 @@ export declare class MJOktaProvider extends MJAuthBase {
|
|
|
34
34
|
});
|
|
35
35
|
initialize(): Promise<void>;
|
|
36
36
|
protected loginInternal(options?: Record<string, unknown>): Promise<void>;
|
|
37
|
-
|
|
37
|
+
protected logoutInternal(): Promise<void>;
|
|
38
38
|
handleCallback(): Promise<void>;
|
|
39
39
|
/**
|
|
40
40
|
* Extract ID token from Okta's storage
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mjexplorer-okta-provider.service.d.ts","sourceRoot":"","sources":["../../../src/lib/providers/mjexplorer-okta-provider.service.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAE7D,OAAiB,EAAE,eAAe,EAAwB,MAAM,oBAAoB,CAAC;AACrF,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EAEjB,kBAAkB,EACnB,MAAM,eAAe,CAAC;;AACvB;;;;;;GAMG;AACH,qBAIa,cAAe,SAAQ,UAAU;IAuBV,OAAO,CAAC,UAAU;IAtBpD,MAAM,CAAC,QAAQ,CAAC,aAAa,UAAU;IACvC,QAAQ,CAAC,IAAI,UAAgC;IAC7C,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,YAAY,CAAS;IAE7B;;;OAGG;IACH,MAAM,CAAC,sBAAsB,GAAI,aAAa,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;;QAWnE;gBAEwC,UAAU,EAAE,eAAe,GAAG;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;IAyCrF,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;cA4DjB,aAAa,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"mjexplorer-okta-provider.service.d.ts","sourceRoot":"","sources":["../../../src/lib/providers/mjexplorer-okta-provider.service.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAE7D,OAAiB,EAAE,eAAe,EAAwB,MAAM,oBAAoB,CAAC;AACrF,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EAEjB,kBAAkB,EACnB,MAAM,eAAe,CAAC;;AACvB;;;;;;GAMG;AACH,qBAIa,cAAe,SAAQ,UAAU;IAuBV,OAAO,CAAC,UAAU;IAtBpD,MAAM,CAAC,QAAQ,CAAC,aAAa,UAAU;IACvC,QAAQ,CAAC,IAAI,UAAgC;IAC7C,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,YAAY,CAAS;IAE7B;;;OAGG;IACH,MAAM,CAAC,sBAAsB,GAAI,aAAa,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;;QAWnE;gBAEwC,UAAU,EAAE,eAAe,GAAG;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;IAyCrF,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;cA4DjB,aAAa,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;cAoB/D,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAuBzC,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAyBrC;;;;;OAKG;cACa,sBAAsB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAWhE;;;;OAIG;cACa,wBAAwB,IAAI,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAqB7E;;;;OAIG;cACa,uBAAuB,IAAI,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAc3E;;;;OAIG;cACa,oBAAoB,IAAI,OAAO,CAAC,kBAAkB,CAAC;IAwFnE;;;;;;;;;OASG;IACH,SAAS,CAAC,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,iBAAiB;IA8FlE;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAc9B;;;;;OAKG;cACa,4BAA4B,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAsBtE;;;;;;OAMG;cACa,2BAA2B,IAAI,OAAO,CAAC,IAAI,CAAC;IASnD,iBAAiB,IAAI,MAAM,EAAE;IAI7B,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO;yCApgBtD,cAAc;6CAAd,cAAc;CAugB1B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mjexplorer-okta-provider.service.js","sourceRoot":"","sources":["../../../src/lib/providers/mjexplorer-okta-provider.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, Inject } from '@angular/core';\nimport { RegisterClass } from '@memberjunction/global';\nimport { Observable, BehaviorSubject, from } from 'rxjs';\nimport { MJAuthBase } from '../mjexplorer-auth-base.service';\nimport { AngularAuthProviderConfig } from '../IAuthProvider';\nimport OktaAuth, { OktaAuthOptions, IDToken, AccessToken } from '@okta/okta-auth-js';\nimport {\n StandardUserInfo,\n StandardAuthToken,\n StandardAuthError,\n AuthErrorType,\n TokenRefreshResult\n} from '../auth-types';\n/**\n * Okta authentication provider implementation - v3.0.0\n *\n * Implements the abstract methods from MJAuthBase to hide Okta-specific details.\n * The key abstraction is that Okta stores the JWT in IDToken.idToken,\n * but consumers never need to know this detail.\n */\n@Injectable({\n providedIn: 'root'\n})\n@RegisterClass(MJAuthBase, 'okta')\nexport class MJOktaProvider extends MJAuthBase {\n static readonly PROVIDER_TYPE = 'okta';\n readonly type = MJOktaProvider.PROVIDER_TYPE;\n private oktaAuth: OktaAuth;\n private isRefreshing = false;\n\n /**\n * Factory function to provide Angular dependencies required by Okta\n * Stored as a static property for the factory to access without instantiation\n */\n static angularProviderFactory = (environment: Record<string, unknown>) => [\n {\n provide: 'oktaConfig',\n useValue: {\n clientId: environment['OKTA_CLIENTID'],\n domain: environment['OKTA_DOMAIN'],\n issuer: environment['OKTA_ISSUER'] || `https://${environment['OKTA_DOMAIN']}/oauth2/default`,\n redirectUri: environment['OKTA_REDIRECT_URI'] || window.location.origin,\n scopes: environment['OKTA_SCOPES'] || ['openid', 'profile', 'email']\n }\n }\n ];\n\n constructor(@Inject('oktaConfig') private oktaConfig: OktaAuthOptions & { domain?: string }) {\n const config: AngularAuthProviderConfig = {\n name: MJOktaProvider.PROVIDER_TYPE,\n type: MJOktaProvider.PROVIDER_TYPE\n };\n super(config);\n\n // Build configuration with defaults\n const oktaAuthConfig: OktaAuthOptions = {\n clientId: this.oktaConfig.clientId,\n redirectUri: this.oktaConfig.redirectUri || window.location.origin + '/callback',\n scopes: this.oktaConfig.scopes || ['openid', 'profile', 'email'],\n pkce: true, // Use PKCE for security\n ...this.oktaConfig,\n // Set issuer after spread to ensure it's not overwritten if not present in config\n issuer: this.oktaConfig.issuer || (this.oktaConfig.domain ? `https://${this.oktaConfig.domain}/oauth2/default` : '')\n };\n\n this.oktaAuth = new OktaAuth(oktaAuthConfig);\n\n // Listen for token events\n this.oktaAuth.authStateManager.subscribe((authState: unknown) => {\n const state = authState as { isAuthenticated?: boolean; idToken?: IDToken };\n this.updateAuthState(state.isAuthenticated || false);\n\n // Don't update user info if we're in the middle of a refresh\n if (!this.isRefreshing) {\n if (state.isAuthenticated && state.idToken) {\n const userInfo = this.mapOktaTokenToStandard(state.idToken);\n this.updateUserInfo(userInfo);\n } else {\n this.updateUserInfo(null);\n }\n }\n });\n }\n\n // ============================================================================\n // LIFECYCLE METHODS\n // ============================================================================\n\n async initialize(): Promise<void> {\n // Check URL for logout indicator\n const urlParams = new URLSearchParams(window.location.search);\n const isPostLogout = urlParams.has('logout');\n\n if (isPostLogout) {\n // We're returning from a logout, clear the URL and stay logged out\n window.history.replaceState({}, document.title, window.location.pathname);\n return;\n }\n\n // Check if we're returning from a login redirect\n // Note: handleRedirect() is the modern v7.x replacement for deprecated handleLoginRedirect()\n if (this.oktaAuth.isLoginRedirect()) {\n try {\n await this.oktaAuth.handleRedirect();\n\n // After handling redirect, check if we're authenticated\n const authState = await this.oktaAuth.authStateManager.getAuthState();\n\n if (authState?.isAuthenticated) {\n this.updateAuthState(true);\n\n // Get and update user info\n const idToken = await this.oktaAuth.tokenManager.get('idToken') as IDToken;\n if (idToken) {\n const userInfo = this.mapOktaTokenToStandard(idToken);\n this.updateUserInfo(userInfo);\n }\n }\n } catch (error) {\n console.error('[Okta] Initialization redirect handling error:', error);\n }\n return; // Don't check for existing session after handling redirect\n }\n\n // Only check for existing session if not a redirect\n try {\n const isAuthenticated = await this.oktaAuth.isAuthenticated();\n\n if (isAuthenticated) {\n // Double-check we actually have valid tokens\n const idToken = await this.oktaAuth.tokenManager.get('idToken') as IDToken;\n\n if (idToken?.idToken) {\n this.updateAuthState(true);\n\n // Update user info from cached token\n const userInfo = this.mapOktaTokenToStandard(idToken);\n this.updateUserInfo(userInfo);\n } else {\n // No valid tokens, stay logged out\n this.updateAuthState(false);\n }\n }\n } catch (error) {\n console.warn('[Okta] Error checking authentication status:', error);\n }\n }\n\n protected async loginInternal(options?: Record<string, unknown>): Promise<void> {\n try {\n // Check if we're in a redirect callback\n // Note: handleRedirect() is the modern v7.x replacement for deprecated handleLoginRedirect()\n if (this.oktaAuth.isLoginRedirect()) {\n await this.oktaAuth.handleRedirect();\n return;\n }\n\n // Start the login flow\n await this.oktaAuth.signInWithRedirect({\n originalUri: (options?.['targetUrl'] as string) || '/',\n ...options\n });\n } catch (error) {\n console.error('[Okta] Login error:', error);\n throw error;\n }\n }\n\n async logout(): Promise<void> {\n try {\n // Clear the local authentication state immediately\n this.updateAuthState(false);\n this.updateUserInfo(null);\n\n // Clear all tokens from local storage\n await this.oktaAuth.tokenManager.clear();\n\n // Sign out from Okta completely\n await this.oktaAuth.signOut({\n postLogoutRedirectUri: window.location.origin,\n clearTokensBeforeRedirect: true\n });\n\n // Note: The signOut call will redirect the browser, so code after this won't execute\n } catch (error) {\n console.error('[Okta] Logout error:', error);\n // If logout fails, at least clear local state and reload\n window.location.href = window.location.origin;\n }\n }\n\n async handleCallback(): Promise<void> {\n try {\n // Note: handleRedirect() is the modern v7.x replacement for deprecated handleLoginRedirect()\n if (this.oktaAuth.isLoginRedirect()) {\n await this.oktaAuth.handleRedirect();\n\n // After handling redirect, check if we're authenticated\n const authState = await this.oktaAuth.authStateManager.getAuthState();\n if (authState?.isAuthenticated) {\n // Do a controlled reload after successful login\n setTimeout(() => {\n window.location.href = window.location.origin;\n }, 100);\n }\n }\n } catch (error) {\n console.error('[Okta] Callback handling error:', error);\n throw error;\n }\n }\n\n // ============================================================================\n // ABSTRACT METHOD IMPLEMENTATIONS (v3.0.0)\n // ============================================================================\n\n /**\n * Extract ID token from Okta's storage\n *\n * Okta stores the JWT in IDToken.idToken\n * This is the key abstraction - consumers never need to know about Okta's structure!\n */\n protected async extractIdTokenInternal(): Promise<string | null> {\n try {\n const idToken = await this.oktaAuth.tokenManager.get('idToken') as IDToken;\n // Okta-specific detail: JWT is in idToken property\n return idToken?.idToken || null;\n } catch (error) {\n console.error('[Okta] Error extracting ID token:', error);\n return null;\n }\n }\n\n /**\n * Extract complete token info from Okta\n *\n * Maps Okta's token structure to StandardAuthToken\n */\n protected async extractTokenInfoInternal(): Promise<StandardAuthToken | null> {\n try {\n const idToken = await this.oktaAuth.tokenManager.get('idToken') as IDToken;\n const accessToken = await this.oktaAuth.tokenManager.get('accessToken') as AccessToken;\n\n if (!idToken?.idToken) {\n return null;\n }\n\n return {\n idToken: idToken.idToken,\n accessToken: accessToken?.accessToken,\n expiresAt: idToken.expiresAt ? idToken.expiresAt * 1000 : 0, // Convert to milliseconds\n scopes: idToken.scopes\n };\n } catch (error) {\n console.error('[Okta] Error extracting token info:', error);\n return null;\n }\n }\n\n /**\n * Extract user info from Okta claims\n *\n * Maps Okta's IDToken structure to StandardUserInfo\n */\n protected async extractUserInfoInternal(): Promise<StandardUserInfo | null> {\n try {\n const idToken = await this.oktaAuth.tokenManager.get('idToken') as IDToken;\n if (!idToken) {\n return null;\n }\n\n return this.mapOktaTokenToStandard(idToken);\n } catch (error) {\n console.error('[Okta] Error extracting user info:', error);\n return null;\n }\n }\n\n /**\n * Refresh token using Okta's token renewal\n *\n * Uses renewTokens() to get new tokens silently\n */\n protected async refreshTokenInternal(): Promise<TokenRefreshResult> {\n try {\n console.log('[Okta] Attempting to refresh token...');\n\n // Set flag to prevent authStateManager from triggering updates\n this.isRefreshing = true;\n\n // First check if we're authenticated\n const isAuthenticated = await this.oktaAuth.isAuthenticated();\n\n if (!isAuthenticated) {\n this.isRefreshing = false;\n return {\n success: false,\n error: {\n type: AuthErrorType.NO_ACTIVE_SESSION,\n message: 'User is not authenticated',\n userMessage: 'You need to log in to continue.'\n }\n };\n }\n\n // Check if tokens exist\n const idToken = await this.oktaAuth.tokenManager.get('idToken') as IDToken;\n const accessToken = await this.oktaAuth.tokenManager.get('accessToken') as AccessToken;\n\n if (!idToken || !accessToken) {\n this.isRefreshing = false;\n return {\n success: false,\n error: {\n type: AuthErrorType.NO_ACTIVE_SESSION,\n message: 'No tokens available to refresh',\n userMessage: 'Session not found. Please log in again.'\n }\n };\n }\n\n // Attempt to renew tokens\n const renewedTokens = await this.oktaAuth.token.renewTokens();\n\n if (renewedTokens.idToken) {\n // Store the renewed tokens\n this.oktaAuth.tokenManager.setTokens(renewedTokens);\n\n // Wait a moment before resetting the flag\n await new Promise(resolve => setTimeout(resolve, 100));\n\n this.isRefreshing = false;\n\n const newIdToken = renewedTokens.idToken as IDToken;\n console.log('[Okta] Token refresh successful', {\n expiresAt: newIdToken.expiresAt ? new Date(newIdToken.expiresAt * 1000).toISOString() : 'N/A'\n });\n\n const token: StandardAuthToken = {\n idToken: newIdToken.idToken || '',\n accessToken: renewedTokens.accessToken?.accessToken,\n expiresAt: newIdToken.expiresAt ? newIdToken.expiresAt * 1000 : 0,\n scopes: newIdToken.scopes\n };\n\n return {\n success: true,\n token\n };\n }\n\n this.isRefreshing = false;\n return {\n success: false,\n error: {\n type: AuthErrorType.NO_ACTIVE_SESSION,\n message: 'Token renewal succeeded but no ID token returned',\n userMessage: 'Session refresh failed. Please log in again.'\n }\n };\n } catch (error) {\n console.error('[Okta] Token refresh failed:', error);\n this.isRefreshing = false;\n\n return {\n success: false,\n error: this.classifyErrorInternal(error)\n };\n }\n }\n\n /**\n * Classify Okta-specific errors into semantic types\n *\n * Maps Okta error patterns to AuthErrorType enum.\n * Updated for okta-auth-js v7.x error codes.\n *\n * Error sources:\n * - errorCode: From Okta SDK errors (AuthSdkError, AuthApiError)\n * - error: From OAuth /token endpoint responses (invalid_grant, access_denied, etc.)\n */\n protected classifyErrorInternal(error: unknown): StandardAuthError {\n const errorObj = error as Record<string, unknown>;\n const message = errorObj?.['message'] as string || 'Unknown error';\n const errorCode = errorObj?.['errorCode'] as string || '';\n // OAuth errors from /token endpoint use 'error' field instead of 'errorCode'\n const oauthError = errorObj?.['error'] as string || '';\n\n // Handle invalid_grant - refresh token is invalid or expired\n // This is a common error when refresh tokens expire or are revoked\n if (errorCode === 'invalid_grant' || oauthError === 'invalid_grant' ||\n message.includes('refresh token is invalid or expired')) {\n return {\n type: AuthErrorType.TOKEN_EXPIRED,\n message,\n originalError: error,\n userMessage: 'Your session has expired. Please log in again.'\n };\n }\n\n // Handle access_denied - user or server denied the request\n if (errorCode === 'access_denied' || oauthError === 'access_denied' ||\n message.includes('access_denied')) {\n return {\n type: AuthErrorType.USER_CANCELLED,\n message,\n originalError: error,\n userMessage: 'Access was denied. Please try again.'\n };\n }\n\n // Check for specific Okta error patterns\n if (errorCode === 'login_required' || oauthError === 'login_required' ||\n message.includes('login_required')) {\n return {\n type: AuthErrorType.NO_ACTIVE_SESSION,\n message,\n originalError: error,\n userMessage: 'You need to log in to continue.'\n };\n }\n\n if (message.includes('not to prompt') || message.includes('consent_required') ||\n oauthError === 'consent_required') {\n return {\n type: AuthErrorType.INTERACTION_REQUIRED,\n message,\n originalError: error,\n userMessage: 'Additional authentication is required. Please log in again.'\n };\n }\n\n // Handle both user_cancelled (SDK) and user_canceled_request (OAuth redirect)\n if (errorCode === 'user_cancelled' || errorCode === 'user_canceled_request' ||\n oauthError === 'user_canceled_request' ||\n message.includes('user cancelled') || message.includes('user canceled')) {\n return {\n type: AuthErrorType.USER_CANCELLED,\n message,\n originalError: error,\n userMessage: 'Login was cancelled.'\n };\n }\n\n if (message.includes('token expired') || message.includes('invalid_token') || message.includes('unauthorized')) {\n return {\n type: AuthErrorType.TOKEN_EXPIRED,\n message,\n originalError: error,\n userMessage: 'Your session has expired. Please log in again.'\n };\n }\n\n if (message.includes('network') || message.includes('fetch') || message.includes('Load failed')) {\n return {\n type: AuthErrorType.NETWORK_ERROR,\n message,\n originalError: error,\n userMessage: 'Network error. Please check your connection and try again.'\n };\n }\n\n // Default to unknown error\n return {\n type: AuthErrorType.UNKNOWN_ERROR,\n message,\n originalError: error,\n userMessage: 'An unexpected error occurred. Please try again.'\n };\n }\n\n // ============================================================================\n // HELPER METHODS\n // ============================================================================\n\n /**\n * Map Okta IDToken to StandardUserInfo\n */\n private mapOktaTokenToStandard(idToken: IDToken): StandardUserInfo {\n const claims = idToken.claims;\n\n return {\n id: claims.sub || '',\n email: claims.email as string || '',\n name: claims.name as string || '',\n givenName: claims.given_name as string,\n familyName: claims.family_name as string,\n preferredUsername: claims.preferred_username as string,\n emailVerified: claims.email_verified as boolean\n };\n }\n\n /**\n * Get profile picture URL from Okta\n *\n * Okta may include picture URL in user claims, similar to Auth0.\n * If available, we can also fetch from Okta's /userinfo endpoint.\n */\n protected async getProfilePictureUrlInternal(): Promise<string | null> {\n try {\n const idToken = await this.oktaAuth.tokenManager.get('idToken') as IDToken;\n if (!idToken) {\n return null;\n }\n\n // Check if picture is in claims\n const pictureUrl = idToken.claims.picture as string;\n if (pictureUrl) {\n return pictureUrl;\n }\n\n // Alternatively, fetch from userinfo endpoint\n const user = await this.oktaAuth.getUser();\n return (user?.picture as string) || null;\n } catch (error) {\n console.error('[Okta] Error getting profile picture:', error);\n return null;\n }\n }\n\n /**\n * Handle session expiry - no-op for Okta\n *\n * Okta uses refresh tokens, so it doesn't need interactive re-authentication\n * when tokens expire. If refresh fails, the base class will throw an error\n * and the user must log out/in manually.\n */\n protected async handleSessionExpiryInternal(): Promise<void> {\n // No-op - Okta doesn't need interactive re-auth\n return;\n }\n\n // ============================================================================\n // CONFIGURATION\n // ============================================================================\n\n override getRequiredConfig(): string[] {\n return ['clientId', 'domain'];\n }\n\n override validateConfig(config: Record<string, unknown>): boolean {\n return !!(config['clientId'] && (config['domain'] || config['issuer']));\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"mjexplorer-okta-provider.service.js","sourceRoot":"","sources":["../../../src/lib/providers/mjexplorer-okta-provider.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, Inject } from '@angular/core';\nimport { RegisterClass } from '@memberjunction/global';\nimport { Observable, BehaviorSubject, from } from 'rxjs';\nimport { MJAuthBase } from '../mjexplorer-auth-base.service';\nimport { AngularAuthProviderConfig } from '../IAuthProvider';\nimport OktaAuth, { OktaAuthOptions, IDToken, AccessToken } from '@okta/okta-auth-js';\nimport {\n StandardUserInfo,\n StandardAuthToken,\n StandardAuthError,\n AuthErrorType,\n TokenRefreshResult\n} from '../auth-types';\n/**\n * Okta authentication provider implementation - v3.0.0\n *\n * Implements the abstract methods from MJAuthBase to hide Okta-specific details.\n * The key abstraction is that Okta stores the JWT in IDToken.idToken,\n * but consumers never need to know this detail.\n */\n@Injectable({\n providedIn: 'root'\n})\n@RegisterClass(MJAuthBase, 'okta')\nexport class MJOktaProvider extends MJAuthBase {\n static readonly PROVIDER_TYPE = 'okta';\n readonly type = MJOktaProvider.PROVIDER_TYPE;\n private oktaAuth: OktaAuth;\n private isRefreshing = false;\n\n /**\n * Factory function to provide Angular dependencies required by Okta\n * Stored as a static property for the factory to access without instantiation\n */\n static angularProviderFactory = (environment: Record<string, unknown>) => [\n {\n provide: 'oktaConfig',\n useValue: {\n clientId: environment['OKTA_CLIENTID'],\n domain: environment['OKTA_DOMAIN'],\n issuer: environment['OKTA_ISSUER'] || `https://${environment['OKTA_DOMAIN']}/oauth2/default`,\n redirectUri: environment['OKTA_REDIRECT_URI'] || window.location.origin,\n scopes: environment['OKTA_SCOPES'] || ['openid', 'profile', 'email']\n }\n }\n ];\n\n constructor(@Inject('oktaConfig') private oktaConfig: OktaAuthOptions & { domain?: string }) {\n const config: AngularAuthProviderConfig = {\n name: MJOktaProvider.PROVIDER_TYPE,\n type: MJOktaProvider.PROVIDER_TYPE\n };\n super(config);\n\n // Build configuration with defaults\n const oktaAuthConfig: OktaAuthOptions = {\n clientId: this.oktaConfig.clientId,\n redirectUri: this.oktaConfig.redirectUri || window.location.origin + '/callback',\n scopes: this.oktaConfig.scopes || ['openid', 'profile', 'email'],\n pkce: true, // Use PKCE for security\n ...this.oktaConfig,\n // Set issuer after spread to ensure it's not overwritten if not present in config\n issuer: this.oktaConfig.issuer || (this.oktaConfig.domain ? `https://${this.oktaConfig.domain}/oauth2/default` : '')\n };\n\n this.oktaAuth = new OktaAuth(oktaAuthConfig);\n\n // Listen for token events\n this.oktaAuth.authStateManager.subscribe((authState: unknown) => {\n const state = authState as { isAuthenticated?: boolean; idToken?: IDToken };\n this.updateAuthState(state.isAuthenticated || false);\n\n // Don't update user info if we're in the middle of a refresh\n if (!this.isRefreshing) {\n if (state.isAuthenticated && state.idToken) {\n const userInfo = this.mapOktaTokenToStandard(state.idToken);\n this.updateUserInfo(userInfo);\n } else {\n this.updateUserInfo(null);\n }\n }\n });\n }\n\n // ============================================================================\n // LIFECYCLE METHODS\n // ============================================================================\n\n async initialize(): Promise<void> {\n // Check URL for logout indicator\n const urlParams = new URLSearchParams(window.location.search);\n const isPostLogout = urlParams.has('logout');\n\n if (isPostLogout) {\n // We're returning from a logout, clear the URL and stay logged out\n window.history.replaceState({}, document.title, window.location.pathname);\n return;\n }\n\n // Check if we're returning from a login redirect\n // Note: handleRedirect() is the modern v7.x replacement for deprecated handleLoginRedirect()\n if (this.oktaAuth.isLoginRedirect()) {\n try {\n await this.oktaAuth.handleRedirect();\n\n // After handling redirect, check if we're authenticated\n const authState = await this.oktaAuth.authStateManager.getAuthState();\n\n if (authState?.isAuthenticated) {\n this.updateAuthState(true);\n\n // Get and update user info\n const idToken = await this.oktaAuth.tokenManager.get('idToken') as IDToken;\n if (idToken) {\n const userInfo = this.mapOktaTokenToStandard(idToken);\n this.updateUserInfo(userInfo);\n }\n }\n } catch (error) {\n console.error('[Okta] Initialization redirect handling error:', error);\n }\n return; // Don't check for existing session after handling redirect\n }\n\n // Only check for existing session if not a redirect\n try {\n const isAuthenticated = await this.oktaAuth.isAuthenticated();\n\n if (isAuthenticated) {\n // Double-check we actually have valid tokens\n const idToken = await this.oktaAuth.tokenManager.get('idToken') as IDToken;\n\n if (idToken?.idToken) {\n this.updateAuthState(true);\n\n // Update user info from cached token\n const userInfo = this.mapOktaTokenToStandard(idToken);\n this.updateUserInfo(userInfo);\n } else {\n // No valid tokens, stay logged out\n this.updateAuthState(false);\n }\n }\n } catch (error) {\n console.warn('[Okta] Error checking authentication status:', error);\n }\n }\n\n protected async loginInternal(options?: Record<string, unknown>): Promise<void> {\n try {\n // Check if we're in a redirect callback\n // Note: handleRedirect() is the modern v7.x replacement for deprecated handleLoginRedirect()\n if (this.oktaAuth.isLoginRedirect()) {\n await this.oktaAuth.handleRedirect();\n return;\n }\n\n // Start the login flow\n await this.oktaAuth.signInWithRedirect({\n originalUri: (options?.['targetUrl'] as string) || '/',\n ...options\n });\n } catch (error) {\n console.error('[Okta] Login error:', error);\n throw error;\n }\n }\n\n protected async logoutInternal(): Promise<void> {\n try {\n // Clear the local authentication state immediately\n this.updateAuthState(false);\n this.updateUserInfo(null);\n\n // Clear all tokens from local storage\n await this.oktaAuth.tokenManager.clear();\n\n // Sign out from Okta completely\n await this.oktaAuth.signOut({\n postLogoutRedirectUri: window.location.origin,\n clearTokensBeforeRedirect: true\n });\n\n // Note: The signOut call will redirect the browser, so code after this won't execute\n } catch (error) {\n console.error('[Okta] Logout error:', error);\n // If logout fails, at least clear local state and reload\n window.location.href = window.location.origin;\n }\n }\n\n async handleCallback(): Promise<void> {\n try {\n // Note: handleRedirect() is the modern v7.x replacement for deprecated handleLoginRedirect()\n if (this.oktaAuth.isLoginRedirect()) {\n await this.oktaAuth.handleRedirect();\n\n // After handling redirect, check if we're authenticated\n const authState = await this.oktaAuth.authStateManager.getAuthState();\n if (authState?.isAuthenticated) {\n // Do a controlled reload after successful login\n setTimeout(() => {\n window.location.href = window.location.origin;\n }, 100);\n }\n }\n } catch (error) {\n console.error('[Okta] Callback handling error:', error);\n throw error;\n }\n }\n\n // ============================================================================\n // ABSTRACT METHOD IMPLEMENTATIONS (v3.0.0)\n // ============================================================================\n\n /**\n * Extract ID token from Okta's storage\n *\n * Okta stores the JWT in IDToken.idToken\n * This is the key abstraction - consumers never need to know about Okta's structure!\n */\n protected async extractIdTokenInternal(): Promise<string | null> {\n try {\n const idToken = await this.oktaAuth.tokenManager.get('idToken') as IDToken;\n // Okta-specific detail: JWT is in idToken property\n return idToken?.idToken || null;\n } catch (error) {\n console.error('[Okta] Error extracting ID token:', error);\n return null;\n }\n }\n\n /**\n * Extract complete token info from Okta\n *\n * Maps Okta's token structure to StandardAuthToken\n */\n protected async extractTokenInfoInternal(): Promise<StandardAuthToken | null> {\n try {\n const idToken = await this.oktaAuth.tokenManager.get('idToken') as IDToken;\n const accessToken = await this.oktaAuth.tokenManager.get('accessToken') as AccessToken;\n\n if (!idToken?.idToken) {\n return null;\n }\n\n return {\n idToken: idToken.idToken,\n accessToken: accessToken?.accessToken,\n expiresAt: idToken.expiresAt ? idToken.expiresAt * 1000 : 0, // Convert to milliseconds\n scopes: idToken.scopes\n };\n } catch (error) {\n console.error('[Okta] Error extracting token info:', error);\n return null;\n }\n }\n\n /**\n * Extract user info from Okta claims\n *\n * Maps Okta's IDToken structure to StandardUserInfo\n */\n protected async extractUserInfoInternal(): Promise<StandardUserInfo | null> {\n try {\n const idToken = await this.oktaAuth.tokenManager.get('idToken') as IDToken;\n if (!idToken) {\n return null;\n }\n\n return this.mapOktaTokenToStandard(idToken);\n } catch (error) {\n console.error('[Okta] Error extracting user info:', error);\n return null;\n }\n }\n\n /**\n * Refresh token using Okta's token renewal\n *\n * Uses renewTokens() to get new tokens silently\n */\n protected async refreshTokenInternal(): Promise<TokenRefreshResult> {\n try {\n console.log('[Okta] Attempting to refresh token...');\n\n // Set flag to prevent authStateManager from triggering updates\n this.isRefreshing = true;\n\n // First check if we're authenticated\n const isAuthenticated = await this.oktaAuth.isAuthenticated();\n\n if (!isAuthenticated) {\n this.isRefreshing = false;\n return {\n success: false,\n error: {\n type: AuthErrorType.NO_ACTIVE_SESSION,\n message: 'User is not authenticated',\n userMessage: 'You need to log in to continue.'\n }\n };\n }\n\n // Check if tokens exist\n const idToken = await this.oktaAuth.tokenManager.get('idToken') as IDToken;\n const accessToken = await this.oktaAuth.tokenManager.get('accessToken') as AccessToken;\n\n if (!idToken || !accessToken) {\n this.isRefreshing = false;\n return {\n success: false,\n error: {\n type: AuthErrorType.NO_ACTIVE_SESSION,\n message: 'No tokens available to refresh',\n userMessage: 'Session not found. Please log in again.'\n }\n };\n }\n\n // Attempt to renew tokens\n const renewedTokens = await this.oktaAuth.token.renewTokens();\n\n if (renewedTokens.idToken) {\n // Store the renewed tokens\n this.oktaAuth.tokenManager.setTokens(renewedTokens);\n\n // Wait a moment before resetting the flag\n await new Promise(resolve => setTimeout(resolve, 100));\n\n this.isRefreshing = false;\n\n const newIdToken = renewedTokens.idToken as IDToken;\n console.log('[Okta] Token refresh successful', {\n expiresAt: newIdToken.expiresAt ? new Date(newIdToken.expiresAt * 1000).toISOString() : 'N/A'\n });\n\n const token: StandardAuthToken = {\n idToken: newIdToken.idToken || '',\n accessToken: renewedTokens.accessToken?.accessToken,\n expiresAt: newIdToken.expiresAt ? newIdToken.expiresAt * 1000 : 0,\n scopes: newIdToken.scopes\n };\n\n return {\n success: true,\n token\n };\n }\n\n this.isRefreshing = false;\n return {\n success: false,\n error: {\n type: AuthErrorType.NO_ACTIVE_SESSION,\n message: 'Token renewal succeeded but no ID token returned',\n userMessage: 'Session refresh failed. Please log in again.'\n }\n };\n } catch (error) {\n console.error('[Okta] Token refresh failed:', error);\n this.isRefreshing = false;\n\n return {\n success: false,\n error: this.classifyErrorInternal(error)\n };\n }\n }\n\n /**\n * Classify Okta-specific errors into semantic types\n *\n * Maps Okta error patterns to AuthErrorType enum.\n * Updated for okta-auth-js v7.x error codes.\n *\n * Error sources:\n * - errorCode: From Okta SDK errors (AuthSdkError, AuthApiError)\n * - error: From OAuth /token endpoint responses (invalid_grant, access_denied, etc.)\n */\n protected classifyErrorInternal(error: unknown): StandardAuthError {\n const errorObj = error as Record<string, unknown>;\n const message = errorObj?.['message'] as string || 'Unknown error';\n const errorCode = errorObj?.['errorCode'] as string || '';\n // OAuth errors from /token endpoint use 'error' field instead of 'errorCode'\n const oauthError = errorObj?.['error'] as string || '';\n\n // Handle invalid_grant - refresh token is invalid or expired\n // This is a common error when refresh tokens expire or are revoked\n if (errorCode === 'invalid_grant' || oauthError === 'invalid_grant' ||\n message.includes('refresh token is invalid or expired')) {\n return {\n type: AuthErrorType.TOKEN_EXPIRED,\n message,\n originalError: error,\n userMessage: 'Your session has expired. Please log in again.'\n };\n }\n\n // Handle access_denied - user or server denied the request\n if (errorCode === 'access_denied' || oauthError === 'access_denied' ||\n message.includes('access_denied')) {\n return {\n type: AuthErrorType.USER_CANCELLED,\n message,\n originalError: error,\n userMessage: 'Access was denied. Please try again.'\n };\n }\n\n // Check for specific Okta error patterns\n if (errorCode === 'login_required' || oauthError === 'login_required' ||\n message.includes('login_required')) {\n return {\n type: AuthErrorType.NO_ACTIVE_SESSION,\n message,\n originalError: error,\n userMessage: 'You need to log in to continue.'\n };\n }\n\n if (message.includes('not to prompt') || message.includes('consent_required') ||\n oauthError === 'consent_required') {\n return {\n type: AuthErrorType.INTERACTION_REQUIRED,\n message,\n originalError: error,\n userMessage: 'Additional authentication is required. Please log in again.'\n };\n }\n\n // Handle both user_cancelled (SDK) and user_canceled_request (OAuth redirect)\n if (errorCode === 'user_cancelled' || errorCode === 'user_canceled_request' ||\n oauthError === 'user_canceled_request' ||\n message.includes('user cancelled') || message.includes('user canceled')) {\n return {\n type: AuthErrorType.USER_CANCELLED,\n message,\n originalError: error,\n userMessage: 'Login was cancelled.'\n };\n }\n\n if (message.includes('token expired') || message.includes('invalid_token') || message.includes('unauthorized')) {\n return {\n type: AuthErrorType.TOKEN_EXPIRED,\n message,\n originalError: error,\n userMessage: 'Your session has expired. Please log in again.'\n };\n }\n\n if (message.includes('network') || message.includes('fetch') || message.includes('Load failed')) {\n return {\n type: AuthErrorType.NETWORK_ERROR,\n message,\n originalError: error,\n userMessage: 'Network error. Please check your connection and try again.'\n };\n }\n\n // Default to unknown error\n return {\n type: AuthErrorType.UNKNOWN_ERROR,\n message,\n originalError: error,\n userMessage: 'An unexpected error occurred. Please try again.'\n };\n }\n\n // ============================================================================\n // HELPER METHODS\n // ============================================================================\n\n /**\n * Map Okta IDToken to StandardUserInfo\n */\n private mapOktaTokenToStandard(idToken: IDToken): StandardUserInfo {\n const claims = idToken.claims;\n\n return {\n id: claims.sub || '',\n email: claims.email as string || '',\n name: claims.name as string || '',\n givenName: claims.given_name as string,\n familyName: claims.family_name as string,\n preferredUsername: claims.preferred_username as string,\n emailVerified: claims.email_verified as boolean\n };\n }\n\n /**\n * Get profile picture URL from Okta\n *\n * Okta may include picture URL in user claims, similar to Auth0.\n * If available, we can also fetch from Okta's /userinfo endpoint.\n */\n protected async getProfilePictureUrlInternal(): Promise<string | null> {\n try {\n const idToken = await this.oktaAuth.tokenManager.get('idToken') as IDToken;\n if (!idToken) {\n return null;\n }\n\n // Check if picture is in claims\n const pictureUrl = idToken.claims.picture as string;\n if (pictureUrl) {\n return pictureUrl;\n }\n\n // Alternatively, fetch from userinfo endpoint\n const user = await this.oktaAuth.getUser();\n return (user?.picture as string) || null;\n } catch (error) {\n console.error('[Okta] Error getting profile picture:', error);\n return null;\n }\n }\n\n /**\n * Handle session expiry - no-op for Okta\n *\n * Okta uses refresh tokens, so it doesn't need interactive re-authentication\n * when tokens expire. If refresh fails, the base class will throw an error\n * and the user must log out/in manually.\n */\n protected async handleSessionExpiryInternal(): Promise<void> {\n // No-op - Okta doesn't need interactive re-auth\n return;\n }\n\n // ============================================================================\n // CONFIGURATION\n // ============================================================================\n\n override getRequiredConfig(): string[] {\n return ['clientId', 'domain'];\n }\n\n override validateConfig(config: Record<string, unknown>): boolean {\n return !!(config['clientId'] && (config['domain'] || config['issuer']));\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/ng-auth-services",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.15.0",
|
|
4
4
|
"description": "MemberJunction Explorer: Authentication Services",
|
|
5
5
|
"main": "./dist/public-api.js",
|
|
6
6
|
"typings": "./dist/public-api.d.ts",
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
"@okta/okta-auth-js": "^7.14.1"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@memberjunction/core": "5.
|
|
34
|
-
"@memberjunction/global": "5.
|
|
33
|
+
"@memberjunction/core": "5.15.0",
|
|
34
|
+
"@memberjunction/global": "5.15.0",
|
|
35
35
|
"rxjs": "^7.8.2",
|
|
36
36
|
"tslib": "^2.8.1"
|
|
37
37
|
},
|