@azure/msal-angular 4.0.11 → 4.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/.beachballrc +3 -0
  2. package/.editorconfig +16 -0
  3. package/.eslintrc.json +3 -0
  4. package/CHANGELOG.json +2315 -0
  5. package/CHANGELOG.md +869 -0
  6. package/FAQ.md +182 -0
  7. package/angular.json +51 -0
  8. package/docs/angular-universal.md +64 -0
  9. package/docs/configuration.md +609 -0
  10. package/docs/errors.md +89 -0
  11. package/docs/events.md +262 -0
  12. package/docs/initialization.md +206 -0
  13. package/docs/known-issues.md +19 -0
  14. package/docs/logging.md +47 -0
  15. package/docs/msal-guard.md +208 -0
  16. package/docs/msal-interceptor.md +160 -0
  17. package/docs/multi-tenant.md +90 -0
  18. package/docs/performance.md +50 -0
  19. package/docs/public-apis.md +29 -0
  20. package/docs/redirects.md +257 -0
  21. package/docs/security.md +4 -0
  22. package/docs/ssosilent.md +84 -0
  23. package/docs/v0-v1-upgrade-guide.md +61 -0
  24. package/docs/v1-v2-upgrade-guide.md +70 -0
  25. package/docs/v2-v3-upgrade-guide.md +52 -0
  26. package/docs/v3-v4-upgrade-guide.md +36 -0
  27. package/karma.conf.js +44 -0
  28. package/ng-package.json +7 -0
  29. package/package.json +56 -26
  30. package/src/IMsalService.ts +34 -0
  31. package/src/constants.ts +20 -0
  32. package/src/msal.broadcast.config.ts +8 -0
  33. package/src/msal.broadcast.service.spec.ts +471 -0
  34. package/src/msal.broadcast.service.ts +84 -0
  35. package/src/msal.guard.config.ts +27 -0
  36. package/src/msal.guard.spec.ts +525 -0
  37. package/src/msal.guard.ts +290 -0
  38. package/src/msal.interceptor.config.ts +39 -0
  39. package/src/msal.interceptor.spec.ts +1168 -0
  40. package/src/msal.interceptor.ts +388 -0
  41. package/src/msal.module.ts +51 -0
  42. package/src/msal.navigation.client.spec.ts +96 -0
  43. package/src/msal.navigation.client.ts +59 -0
  44. package/src/msal.redirect.component.spec.ts +64 -0
  45. package/src/msal.redirect.component.ts +26 -0
  46. package/src/msal.service.spec.ts +468 -0
  47. package/src/msal.service.ts +104 -0
  48. package/src/packageMetadata.ts +3 -0
  49. package/{public-api.d.ts → src/public-api.ts} +35 -17
  50. package/src/test.ts +19 -0
  51. package/tsconfig.json +25 -0
  52. package/tsconfig.lib.json +27 -0
  53. package/tsconfig.lib.prod.json +10 -0
  54. package/tsconfig.spec.json +17 -0
  55. package/typedoc.json +10 -0
  56. package/IMsalService.d.ts +0 -17
  57. package/constants.d.ts +0 -5
  58. package/esm2020/IMsalService.mjs +0 -6
  59. package/esm2020/azure-msal-angular.mjs +0 -5
  60. package/esm2020/constants.mjs +0 -10
  61. package/esm2020/msal.broadcast.config.mjs +0 -6
  62. package/esm2020/msal.broadcast.service.mjs +0 -66
  63. package/esm2020/msal.guard.config.mjs +0 -6
  64. package/esm2020/msal.guard.mjs +0 -218
  65. package/esm2020/msal.interceptor.config.mjs +0 -6
  66. package/esm2020/msal.interceptor.mjs +0 -270
  67. package/esm2020/msal.module.mjs +0 -46
  68. package/esm2020/msal.navigation.client.mjs +0 -53
  69. package/esm2020/msal.redirect.component.mjs +0 -31
  70. package/esm2020/msal.service.mjs +0 -88
  71. package/esm2020/packageMetadata.mjs +0 -4
  72. package/esm2020/public-api.mjs +0 -18
  73. package/fesm2015/azure-msal-angular.mjs +0 -762
  74. package/fesm2015/azure-msal-angular.mjs.map +0 -1
  75. package/fesm2020/azure-msal-angular.mjs +0 -758
  76. package/fesm2020/azure-msal-angular.mjs.map +0 -1
  77. package/index.d.ts +0 -5
  78. package/msal.broadcast.config.d.ts +0 -3
  79. package/msal.broadcast.service.d.ts +0 -19
  80. package/msal.guard.config.d.ts +0 -9
  81. package/msal.guard.d.ts +0 -43
  82. package/msal.interceptor.config.d.ts +0 -13
  83. package/msal.interceptor.d.ts +0 -70
  84. package/msal.module.d.ts +0 -13
  85. package/msal.navigation.client.d.ts +0 -19
  86. package/msal.redirect.component.d.ts +0 -15
  87. package/msal.service.d.ts +0 -33
  88. package/packageMetadata.d.ts +0 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@azure/msal-angular",
3
- "version": "4.0.11",
3
+ "version": "4.0.13",
4
4
  "author": {
5
5
  "name": "Microsoft",
6
6
  "email": "nugetaad@microsoft.com",
@@ -12,36 +12,66 @@
12
12
  "url": "https://github.com/AzureAD/microsoft-authentication-library-for-js.git"
13
13
  },
14
14
  "description": "Microsoft Authentication Library for Angular",
15
- "typings": "index.d.ts",
15
+ "scripts": {
16
+ "ng": "ng",
17
+ "start": "ng serve",
18
+ "build": "ng build",
19
+ "build:prod": "ng build --configuration production",
20
+ "build:all": "npm run build:browser && npm run build",
21
+ "build:all:prod": "npm run build:browser && npm run build:prod",
22
+ "build:browser": "cd ../.. && npm run build --workspace=@azure/msal-common --workspace=@azure/msal-browser",
23
+ "build:pack": "npm run build && cd dist && npm pack",
24
+ "deploy": "npm run build:all:prod && npm publish ./dist --workspaces=false",
25
+ "test": "ng test",
26
+ "test:coverage": "npm test",
27
+ "lint": "eslint src --ext .ts",
28
+ "lint:fix": "npm run lint -- --fix",
29
+ "e2e": "ng e2e",
30
+ "prepack": "npm run build:all",
31
+ "prepublishOnly": "echo Use npm run deploy && exit 1",
32
+ "format:check": "prettier --ignore-path .gitignore --check src",
33
+ "format:fix": "prettier --ignore-path .gitignore --write src"
34
+ },
35
+ "typings": "./dist/azure-msal-angular.d.ts",
16
36
  "beachball": {
17
37
  "disallowedChangeTypes": [
18
38
  "major"
19
39
  ]
20
40
  },
41
+ "devDependencies": {
42
+ "@angular-devkit/build-angular": "^15.1.5",
43
+ "@angular/animations": "^15.1.4",
44
+ "@angular/cli": "^15.1.5",
45
+ "@angular/common": "^15.1.4",
46
+ "@angular/compiler": "^15.1.4",
47
+ "@angular/compiler-cli": "^15.1.4",
48
+ "@angular/core": "^15.1.4",
49
+ "@angular/forms": "^15.1.4",
50
+ "@angular/platform-browser": "^15.1.4",
51
+ "@angular/platform-browser-dynamic": "^15.1.4",
52
+ "@angular/router": "^15.1.4",
53
+ "@azure/msal-browser": "^4.13.2",
54
+ "@types/jasmine": "~3.6.0",
55
+ "@types/jasminewd2": "~2.0.3",
56
+ "@types/node": "^12.11.1",
57
+ "eslint-config-msal": "file:../../shared-configs/eslint-config-msal",
58
+ "jasmine-core": "~4.0.0",
59
+ "jasmine-spec-reporter": "~5.0.0",
60
+ "karma": "~6.3.2",
61
+ "karma-chrome-launcher": "~3.1.0",
62
+ "karma-coverage-istanbul-reporter": "~3.0.2",
63
+ "karma-jasmine": "~5.0.0",
64
+ "karma-jasmine-html-reporter": "^2.0.0",
65
+ "ng-packagr": "^15.1.2",
66
+ "prettier": "2.8.7",
67
+ "rxjs": "^7.8.1",
68
+ "ts-node": "~8.3.0",
69
+ "tslib": "^2.0.0",
70
+ "typescript": "~4.8.4",
71
+ "zone.js": "~0.11.8"
72
+ },
21
73
  "peerDependencies": {
22
- "@azure/msal-browser": "^4.11.1",
74
+ "@azure/msal-browser": "^4.13.2",
23
75
  "rxjs": "^7.0.0"
24
- },
25
- "module": "fesm2015/azure-msal-angular.mjs",
26
- "es2020": "fesm2020/azure-msal-angular.mjs",
27
- "esm2020": "esm2020/azure-msal-angular.mjs",
28
- "fesm2020": "fesm2020/azure-msal-angular.mjs",
29
- "fesm2015": "fesm2015/azure-msal-angular.mjs",
30
- "exports": {
31
- "./package.json": {
32
- "default": "./package.json"
33
- },
34
- ".": {
35
- "types": "./index.d.ts",
36
- "esm2020": "./esm2020/azure-msal-angular.mjs",
37
- "es2020": "./fesm2020/azure-msal-angular.mjs",
38
- "es2015": "./fesm2015/azure-msal-angular.mjs",
39
- "node": "./fesm2015/azure-msal-angular.mjs",
40
- "default": "./fesm2020/azure-msal-angular.mjs"
41
- }
42
- },
43
- "sideEffects": false,
44
- "dependencies": {
45
- "tslib": "^2.3.0"
46
76
  }
47
- }
77
+ }
@@ -0,0 +1,34 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import {
7
+ EndSessionRequest,
8
+ AuthenticationResult,
9
+ PopupRequest,
10
+ RedirectRequest,
11
+ SilentRequest,
12
+ Logger,
13
+ SsoSilentRequest,
14
+ } from "@azure/msal-browser";
15
+ import { Observable } from "rxjs";
16
+
17
+ export interface IMsalService {
18
+ initialize(): Observable<void>;
19
+ acquireTokenPopup(request: PopupRequest): Observable<AuthenticationResult>;
20
+ acquireTokenRedirect(request: RedirectRequest): Observable<void>;
21
+ acquireTokenSilent(
22
+ silentRequest: SilentRequest
23
+ ): Observable<AuthenticationResult>;
24
+ handleRedirectObservable(): Observable<AuthenticationResult | null>;
25
+ loginPopup(request?: PopupRequest): Observable<AuthenticationResult>;
26
+ loginRedirect(request?: RedirectRequest): Observable<void>;
27
+ // @deprecated: Use logoutRedirect or logoutPopup
28
+ logout(logoutRequest?: EndSessionRequest): Observable<void>;
29
+ logoutRedirect(logoutRequest?: EndSessionRequest): Observable<void>;
30
+ logoutPopup(logoutRequest?: EndSessionRequest): Observable<void>;
31
+ ssoSilent(request: SsoSilentRequest): Observable<AuthenticationResult>;
32
+ getLogger(): Logger;
33
+ setLogger(logger: Logger): void;
34
+ }
@@ -0,0 +1,20 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import { InjectionToken } from "@angular/core";
7
+
8
+ export const MSAL_INSTANCE = new InjectionToken<string>("MSAL_INSTANCE");
9
+
10
+ export const MSAL_GUARD_CONFIG = new InjectionToken<string>(
11
+ "MSAL_GUARD_CONFIG"
12
+ );
13
+
14
+ export const MSAL_INTERCEPTOR_CONFIG = new InjectionToken<string>(
15
+ "MSAL_INTERCEPTOR_CONFIG"
16
+ );
17
+
18
+ export const MSAL_BROADCAST_CONFIG = new InjectionToken<string>(
19
+ "MSAL_BROADCAST_CONFIG"
20
+ );
@@ -0,0 +1,8 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ export type MsalBroadcastConfiguration = {
7
+ eventsToReplay: number;
8
+ };
@@ -0,0 +1,471 @@
1
+ import { TestBed } from "@angular/core/testing";
2
+ import {
3
+ EventHandler,
4
+ EventType,
5
+ InteractionStatus,
6
+ InteractionType,
7
+ PublicClientApplication,
8
+ } from "@azure/msal-browser";
9
+ import { Subscription } from "rxjs";
10
+ import { MsalModule, MSAL_BROADCAST_CONFIG } from "./public-api";
11
+ import { MsalBroadcastService } from "./msal.broadcast.service";
12
+
13
+ let broadcastService: MsalBroadcastService;
14
+ let subscription: Subscription;
15
+
16
+ const msalInstance = new PublicClientApplication({
17
+ auth: {
18
+ clientId: "b5c2e510-4a17-4feb-b219-e55aa5b74144",
19
+ redirectUri: "http://localhost:4200",
20
+ },
21
+ });
22
+
23
+ let eventHandler;
24
+ const eventSpy = jasmine.createSpy("addEventCallback");
25
+ msalInstance.addEventCallback = eventSpy;
26
+
27
+ function initializeMsal(providers: any[] = []) {
28
+ TestBed.resetTestingModule();
29
+
30
+ eventHandler = new EventHandler();
31
+ eventSpy.and.callFake((callback, types) => {
32
+ return eventHandler.addEventCallback(callback, types);
33
+ });
34
+
35
+ TestBed.configureTestingModule({
36
+ imports: [
37
+ MsalModule.forRoot(msalInstance, null, {
38
+ interactionType: InteractionType.Popup,
39
+ protectedResourceMap: new Map(),
40
+ }),
41
+ ],
42
+ providers: [MsalBroadcastService, ...providers],
43
+ teardown: { destroyAfterEach: false },
44
+ });
45
+ broadcastService = TestBed.inject(MsalBroadcastService);
46
+ }
47
+
48
+ describe("MsalBroadcastService", () => {
49
+ beforeEach(() => {
50
+ initializeMsal();
51
+ });
52
+
53
+ afterEach(() => {
54
+ subscription.unsubscribe();
55
+ });
56
+
57
+ it("broadcasts event from PublicClientApplication", (done) => {
58
+ const sub = broadcastService.msalSubject$.subscribe((result) => {
59
+ expect(result.eventType).toEqual(EventType.LOGIN_START);
60
+ expect(result.interactionType).toEqual(InteractionType.Popup);
61
+ expect(result.payload).toEqual(null);
62
+ expect(result.error).toEqual(null);
63
+ expect(result.timestamp).toBeInstanceOf(Number);
64
+ sub.unsubscribe();
65
+ });
66
+
67
+ const expectedInProgress = [
68
+ InteractionStatus.Startup,
69
+ InteractionStatus.Login,
70
+ ];
71
+ let index = 0;
72
+
73
+ subscription = broadcastService.inProgress$.subscribe((result) => {
74
+ expect(result).toEqual(expectedInProgress[index]);
75
+ if (index === expectedInProgress.length - 1) {
76
+ done();
77
+ } else {
78
+ index++;
79
+ }
80
+ });
81
+
82
+ eventHandler.emitEvent(EventType.LOGIN_START, InteractionType.Popup);
83
+ });
84
+
85
+ it("broadcasts previous events if MsalBroadcastConfig set and eventsToReplay is greater than 0", (done) => {
86
+ initializeMsal([
87
+ {
88
+ provide: MSAL_BROADCAST_CONFIG,
89
+ useValue: {
90
+ eventsToReplay: 3,
91
+ },
92
+ },
93
+ ]);
94
+
95
+ const expectedMsalSubjectFirstSubscription = [
96
+ {
97
+ eventType: EventType.LOGIN_START,
98
+ interactionType: InteractionType.Redirect,
99
+ payload: null,
100
+ error: null,
101
+ },
102
+ ];
103
+ let firstIndex = 0;
104
+
105
+ subscription = broadcastService.msalSubject$.subscribe((result) => {
106
+ expect(result.eventType).toEqual(
107
+ expectedMsalSubjectFirstSubscription[firstIndex].eventType
108
+ );
109
+ expect(result.interactionType).toEqual(
110
+ expectedMsalSubjectFirstSubscription[firstIndex].interactionType
111
+ );
112
+ expect(result.payload).toEqual(
113
+ expectedMsalSubjectFirstSubscription[firstIndex].payload
114
+ );
115
+ expect(result.error).toEqual(
116
+ expectedMsalSubjectFirstSubscription[firstIndex].error
117
+ );
118
+ expect(result.timestamp).toBeInstanceOf(Number);
119
+ if (firstIndex === expectedMsalSubjectFirstSubscription.length - 1) {
120
+ return;
121
+ } else {
122
+ firstIndex++;
123
+ }
124
+ });
125
+
126
+ eventHandler.emitEvent(EventType.LOGIN_START, InteractionType.Redirect);
127
+
128
+ subscription.unsubscribe();
129
+
130
+ let index = 0;
131
+ const expectedMsalSubject = [
132
+ {
133
+ eventType: EventType.LOGIN_START,
134
+ interactionType: InteractionType.Redirect,
135
+ payload: null,
136
+ error: null,
137
+ },
138
+ {
139
+ eventType: EventType.HANDLE_REDIRECT_START,
140
+ interactionType: InteractionType.Redirect,
141
+ payload: null,
142
+ error: null,
143
+ },
144
+ {
145
+ eventType: EventType.HANDLE_REDIRECT_END,
146
+ interactionType: InteractionType.Redirect,
147
+ payload: null,
148
+ error: null,
149
+ },
150
+ ];
151
+
152
+ const newSubscription = broadcastService.msalSubject$.subscribe(
153
+ (result) => {
154
+ expect(result.eventType).toEqual(expectedMsalSubject[index].eventType);
155
+ expect(result.interactionType).toEqual(
156
+ expectedMsalSubject[index].interactionType
157
+ );
158
+ expect(result.payload).toEqual(expectedMsalSubject[index].payload);
159
+ expect(result.error).toEqual(expectedMsalSubject[index].error);
160
+ expect(result.timestamp).toBeInstanceOf(Number);
161
+ if (index === expectedMsalSubject.length - 1) {
162
+ done();
163
+ } else {
164
+ index++;
165
+ }
166
+ }
167
+ );
168
+
169
+ eventHandler.emitEvent(
170
+ EventType.HANDLE_REDIRECT_START,
171
+ InteractionType.Redirect
172
+ );
173
+ eventHandler.emitEvent(
174
+ EventType.HANDLE_REDIRECT_END,
175
+ InteractionType.Redirect
176
+ );
177
+
178
+ newSubscription.unsubscribe();
179
+ });
180
+
181
+ it("broadcasts the set number of past events if MsalBroadcastConfig and eventsToReplay is set", (done) => {
182
+ initializeMsal([
183
+ {
184
+ provide: MSAL_BROADCAST_CONFIG,
185
+ useValue: {
186
+ eventsToReplay: 1,
187
+ },
188
+ },
189
+ ]);
190
+
191
+ const expectedMsalSubjectFirstSubscription = [
192
+ {
193
+ eventType: EventType.INITIALIZE_START,
194
+ interactionType: InteractionType.Redirect,
195
+ payload: null,
196
+ error: null,
197
+ },
198
+ {
199
+ eventType: EventType.LOGIN_START,
200
+ interactionType: InteractionType.Redirect,
201
+ payload: null,
202
+ error: null,
203
+ },
204
+ ];
205
+ let firstIndex = 0;
206
+
207
+ subscription = broadcastService.msalSubject$.subscribe((result) => {
208
+ expect(result.eventType).toEqual(
209
+ expectedMsalSubjectFirstSubscription[firstIndex].eventType
210
+ );
211
+ expect(result.interactionType).toEqual(
212
+ expectedMsalSubjectFirstSubscription[firstIndex].interactionType
213
+ );
214
+ expect(result.payload).toEqual(
215
+ expectedMsalSubjectFirstSubscription[firstIndex].payload
216
+ );
217
+ expect(result.error).toEqual(
218
+ expectedMsalSubjectFirstSubscription[firstIndex].error
219
+ );
220
+ expect(result.timestamp).toBeInstanceOf(Number);
221
+ if (firstIndex === expectedMsalSubjectFirstSubscription.length - 1) {
222
+ return;
223
+ } else {
224
+ firstIndex++;
225
+ }
226
+ });
227
+
228
+ eventHandler.emitEvent(
229
+ EventType.INITIALIZE_START,
230
+ InteractionType.Redirect
231
+ );
232
+ eventHandler.emitEvent(EventType.LOGIN_START, InteractionType.Redirect);
233
+
234
+ subscription.unsubscribe();
235
+
236
+ let index = 0;
237
+ const expectedMsalSubject = [
238
+ {
239
+ eventType: EventType.LOGIN_START,
240
+ interactionType: InteractionType.Redirect,
241
+ payload: null,
242
+ error: null,
243
+ },
244
+ {
245
+ eventType: EventType.HANDLE_REDIRECT_START,
246
+ interactionType: InteractionType.Redirect,
247
+ payload: null,
248
+ error: null,
249
+ },
250
+ {
251
+ eventType: EventType.HANDLE_REDIRECT_END,
252
+ interactionType: InteractionType.Redirect,
253
+ payload: null,
254
+ error: null,
255
+ },
256
+ ];
257
+
258
+ const newSubscription = broadcastService.msalSubject$.subscribe(
259
+ (result) => {
260
+ expect(result.eventType).toEqual(expectedMsalSubject[index].eventType);
261
+ expect(result.interactionType).toEqual(
262
+ expectedMsalSubject[index].interactionType
263
+ );
264
+ expect(result.payload).toEqual(expectedMsalSubject[index].payload);
265
+ expect(result.error).toEqual(expectedMsalSubject[index].error);
266
+ expect(result.timestamp).toBeInstanceOf(Number);
267
+ if (index === expectedMsalSubject.length - 1) {
268
+ done();
269
+ } else {
270
+ index++;
271
+ }
272
+ }
273
+ );
274
+
275
+ eventHandler.emitEvent(
276
+ EventType.HANDLE_REDIRECT_START,
277
+ InteractionType.Redirect
278
+ );
279
+ eventHandler.emitEvent(
280
+ EventType.HANDLE_REDIRECT_END,
281
+ InteractionType.Redirect
282
+ );
283
+
284
+ newSubscription.unsubscribe();
285
+ });
286
+
287
+ it("does not broadcasts previous events if MsalBroadcastConfig is not set", (done) => {
288
+ const expectedMsalSubjectFirstSubscription = [
289
+ {
290
+ eventType: EventType.LOGIN_START,
291
+ interactionType: InteractionType.Redirect,
292
+ payload: null,
293
+ error: null,
294
+ },
295
+ ];
296
+ let firstIndex = 0;
297
+
298
+ subscription = broadcastService.msalSubject$.subscribe((result) => {
299
+ expect(result.eventType).toEqual(
300
+ expectedMsalSubjectFirstSubscription[firstIndex].eventType
301
+ );
302
+ expect(result.interactionType).toEqual(
303
+ expectedMsalSubjectFirstSubscription[firstIndex].interactionType
304
+ );
305
+ expect(result.payload).toEqual(
306
+ expectedMsalSubjectFirstSubscription[firstIndex].payload
307
+ );
308
+ expect(result.error).toEqual(
309
+ expectedMsalSubjectFirstSubscription[firstIndex].error
310
+ );
311
+ expect(result.timestamp).toBeInstanceOf(Number);
312
+ if (firstIndex === expectedMsalSubjectFirstSubscription.length - 1) {
313
+ return;
314
+ } else {
315
+ firstIndex++;
316
+ }
317
+ });
318
+
319
+ eventHandler.emitEvent(EventType.LOGIN_START, InteractionType.Redirect);
320
+
321
+ subscription.unsubscribe();
322
+
323
+ let index = 0;
324
+ const expectedMsalSubject = [
325
+ {
326
+ eventType: EventType.HANDLE_REDIRECT_START,
327
+ interactionType: InteractionType.Redirect,
328
+ payload: null,
329
+ error: null,
330
+ },
331
+ {
332
+ eventType: EventType.HANDLE_REDIRECT_END,
333
+ interactionType: InteractionType.Redirect,
334
+ payload: null,
335
+ error: null,
336
+ },
337
+ ];
338
+
339
+ const newSubscription = broadcastService.msalSubject$.subscribe(
340
+ (result) => {
341
+ expect(result.eventType).toEqual(expectedMsalSubject[index].eventType);
342
+ expect(result.interactionType).toEqual(
343
+ expectedMsalSubject[index].interactionType
344
+ );
345
+ expect(result.payload).toEqual(expectedMsalSubject[index].payload);
346
+ expect(result.error).toEqual(expectedMsalSubject[index].error);
347
+ expect(result.timestamp).toBeInstanceOf(Number);
348
+ if (index === expectedMsalSubject.length - 1) {
349
+ done();
350
+ } else {
351
+ index++;
352
+ }
353
+ }
354
+ );
355
+
356
+ eventHandler.emitEvent(
357
+ EventType.HANDLE_REDIRECT_START,
358
+ InteractionType.Redirect
359
+ );
360
+ eventHandler.emitEvent(
361
+ EventType.HANDLE_REDIRECT_END,
362
+ InteractionType.Redirect
363
+ );
364
+
365
+ newSubscription.unsubscribe();
366
+ });
367
+
368
+ it("LOGIN_SUCCESS event does not set inProgress to None if handleRedirect is still in progress", (done) => {
369
+ const expectedInProgress = [
370
+ InteractionStatus.Startup,
371
+ InteractionStatus.HandleRedirect,
372
+ ];
373
+ let index = 0;
374
+
375
+ subscription = broadcastService.inProgress$.subscribe((result) => {
376
+ expect(result).toEqual(expectedInProgress[index]);
377
+ if (index === expectedInProgress.length - 1) {
378
+ done();
379
+ } else {
380
+ index++;
381
+ }
382
+ });
383
+
384
+ eventHandler.emitEvent(
385
+ EventType.HANDLE_REDIRECT_START,
386
+ InteractionType.Redirect
387
+ );
388
+ eventHandler.emitEvent(EventType.LOGIN_SUCCESS, InteractionType.Redirect);
389
+ });
390
+
391
+ it("HANDLE_REDIRECT_END event sets inProgress to None if handleRedirect is in progress", (done) => {
392
+ const expectedInProgress = [
393
+ InteractionStatus.Startup,
394
+ InteractionStatus.HandleRedirect,
395
+ InteractionStatus.None,
396
+ ];
397
+ let index = 0;
398
+
399
+ subscription = broadcastService.inProgress$.subscribe((result) => {
400
+ expect(result).toEqual(expectedInProgress[index]);
401
+ if (index === expectedInProgress.length - 1) {
402
+ done();
403
+ } else {
404
+ index++;
405
+ }
406
+ });
407
+
408
+ eventHandler.emitEvent(
409
+ EventType.HANDLE_REDIRECT_START,
410
+ InteractionType.Redirect
411
+ );
412
+ eventHandler.emitEvent(EventType.LOGIN_SUCCESS, InteractionType.Redirect);
413
+ eventHandler.emitEvent(
414
+ EventType.HANDLE_REDIRECT_END,
415
+ InteractionType.Redirect
416
+ );
417
+ });
418
+
419
+ it("HANDLE_REDIRECT_END event does not set inProgress to None if login is in progress", (done) => {
420
+ const expectedInProgress = [
421
+ InteractionStatus.Startup,
422
+ InteractionStatus.HandleRedirect,
423
+ InteractionStatus.Login,
424
+ ];
425
+ let index = 0;
426
+
427
+ subscription = broadcastService.inProgress$.subscribe((result) => {
428
+ expect(result).toEqual(expectedInProgress[index]);
429
+ if (index === expectedInProgress.length - 1) {
430
+ done();
431
+ } else {
432
+ index++;
433
+ }
434
+ });
435
+
436
+ eventHandler.emitEvent(
437
+ EventType.HANDLE_REDIRECT_START,
438
+ InteractionType.Redirect
439
+ );
440
+ eventHandler.emitEvent(EventType.LOGIN_START, InteractionType.Redirect);
441
+ eventHandler.emitEvent(
442
+ EventType.HANDLE_REDIRECT_END,
443
+ InteractionType.Redirect
444
+ );
445
+ });
446
+
447
+ it("automatically sets inProgress to None when handleRedirectPromise returns without emitting an event", (done) => {
448
+ const expectedInProgress = [
449
+ InteractionStatus.Startup,
450
+ InteractionStatus.None,
451
+ ];
452
+ let index = 0;
453
+
454
+ subscription = broadcastService.inProgress$.subscribe((result) => {
455
+ expect(result).toEqual(expectedInProgress[index]);
456
+ if (index === expectedInProgress.length - 1) {
457
+ done();
458
+ } else if (expectedInProgress[index] === InteractionStatus.Startup) {
459
+ index++;
460
+ broadcastService.resetInProgressEvent();
461
+ } else {
462
+ index++;
463
+ }
464
+ });
465
+
466
+ eventHandler.emitEvent(
467
+ EventType.INITIALIZE_START,
468
+ InteractionType.Redirect
469
+ );
470
+ });
471
+ });