@azure/msal-angular 4.0.12 → 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
@@ -1,758 +0,0 @@
1
- import * as i0 from '@angular/core';
2
- import { InjectionToken, Injectable, Inject, Optional, Component, NgModule } from '@angular/core';
3
- import { InteractionStatus, EventMessageUtils, WrapperSKU, InteractionType, BrowserConfigurationAuthError, UrlString, BrowserUtils, StringUtils, NavigationClient } from '@azure/msal-browser';
4
- import { ReplaySubject, Subject, BehaviorSubject, from, of, EMPTY } from 'rxjs';
5
- import * as i3 from '@angular/common';
6
- import { DOCUMENT, CommonModule } from '@angular/common';
7
- import { map, concatMap, catchError, switchMap, take, filter } from 'rxjs/operators';
8
- import * as i4 from '@angular/router';
9
-
10
- /* eslint-disable header/header */
11
- const name = "@azure/msal-angular";
12
- const version = "4.0.12";
13
-
14
- /*
15
- * Copyright (c) Microsoft Corporation. All rights reserved.
16
- * Licensed under the MIT License.
17
- */
18
- const MSAL_INSTANCE = new InjectionToken("MSAL_INSTANCE");
19
- const MSAL_GUARD_CONFIG = new InjectionToken("MSAL_GUARD_CONFIG");
20
- const MSAL_INTERCEPTOR_CONFIG = new InjectionToken("MSAL_INTERCEPTOR_CONFIG");
21
- const MSAL_BROADCAST_CONFIG = new InjectionToken("MSAL_BROADCAST_CONFIG");
22
-
23
- /*
24
- * Copyright (c) Microsoft Corporation. All rights reserved.
25
- * Licensed under the MIT License.
26
- */
27
- class MsalBroadcastService {
28
- constructor(msalInstance, msalBroadcastConfig) {
29
- this.msalInstance = msalInstance;
30
- this.msalBroadcastConfig = msalBroadcastConfig;
31
- // Make _msalSubject a ReplaySubject if configured to replay past events
32
- if (this.msalBroadcastConfig &&
33
- this.msalBroadcastConfig.eventsToReplay > 0) {
34
- this.msalInstance
35
- .getLogger()
36
- .clone(name, version)
37
- .verbose(`BroadcastService - eventsToReplay set on BroadcastConfig, replaying the last ${this.msalBroadcastConfig.eventsToReplay} events`);
38
- this._msalSubject = new ReplaySubject(this.msalBroadcastConfig.eventsToReplay);
39
- }
40
- else {
41
- // Defaults to _msalSubject being a Subject
42
- this._msalSubject = new Subject();
43
- }
44
- this.msalSubject$ = this._msalSubject.asObservable();
45
- // InProgress as BehaviorSubject so most recent inProgress state will be available upon subscription
46
- this._inProgress = new BehaviorSubject(InteractionStatus.Startup);
47
- this.inProgress$ = this._inProgress.asObservable();
48
- this.msalInstance.addEventCallback((message) => {
49
- this._msalSubject.next(message);
50
- const status = EventMessageUtils.getInteractionStatusFromEvent(message, this._inProgress.value);
51
- if (status !== null) {
52
- this.msalInstance
53
- .getLogger()
54
- .clone(name, version)
55
- .verbose(`BroadcastService - ${message.eventType} results in setting inProgress from ${this._inProgress.value} to ${status}`);
56
- this._inProgress.next(status);
57
- }
58
- });
59
- }
60
- /**
61
- * Resets inProgress state to None
62
- */
63
- resetInProgressEvent() {
64
- if (this._inProgress.value === InteractionStatus.Startup) {
65
- this._inProgress.next(InteractionStatus.None);
66
- }
67
- }
68
- }
69
- MsalBroadcastService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MsalBroadcastService, deps: [{ token: MSAL_INSTANCE }, { token: MSAL_BROADCAST_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
70
- MsalBroadcastService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MsalBroadcastService });
71
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MsalBroadcastService, decorators: [{
72
- type: Injectable
73
- }], ctorParameters: function () { return [{ type: undefined, decorators: [{
74
- type: Inject,
75
- args: [MSAL_INSTANCE]
76
- }] }, { type: undefined, decorators: [{
77
- type: Optional
78
- }, {
79
- type: Inject,
80
- args: [MSAL_BROADCAST_CONFIG]
81
- }] }]; } });
82
-
83
- /*
84
- * Copyright (c) Microsoft Corporation. All rights reserved.
85
- * Licensed under the MIT License.
86
- */
87
- class MsalService {
88
- constructor(instance, location, injector) {
89
- this.instance = instance;
90
- this.location = location;
91
- this.injector = injector;
92
- const hash = this.location.path(true).split("#").pop();
93
- if (hash) {
94
- this.redirectHash = `#${hash}`;
95
- }
96
- this.instance.initializeWrapperLibrary(WrapperSKU.Angular, version);
97
- }
98
- initialize() {
99
- return from(this.instance.initialize());
100
- }
101
- acquireTokenPopup(request) {
102
- return from(this.instance.acquireTokenPopup(request));
103
- }
104
- acquireTokenRedirect(request) {
105
- return from(this.instance.acquireTokenRedirect(request));
106
- }
107
- acquireTokenSilent(silentRequest) {
108
- return from(this.instance.acquireTokenSilent(silentRequest));
109
- }
110
- handleRedirectObservable(hash) {
111
- return from(this.instance
112
- .initialize()
113
- .then(() => this.instance.handleRedirectPromise(hash || this.redirectHash))
114
- .finally(() => {
115
- // update inProgress state to none
116
- this.injector.get(MsalBroadcastService).resetInProgressEvent();
117
- }));
118
- }
119
- loginPopup(request) {
120
- return from(this.instance.loginPopup(request));
121
- }
122
- loginRedirect(request) {
123
- return from(this.instance.loginRedirect(request));
124
- }
125
- // @deprecated: Use logoutRedirect or logoutPopup
126
- logout(logoutRequest) {
127
- return from(this.instance.logout(logoutRequest));
128
- }
129
- logoutRedirect(logoutRequest) {
130
- return from(this.instance.logoutRedirect(logoutRequest));
131
- }
132
- logoutPopup(logoutRequest) {
133
- return from(this.instance.logoutPopup(logoutRequest));
134
- }
135
- ssoSilent(request) {
136
- return from(this.instance.ssoSilent(request));
137
- }
138
- /**
139
- * Gets logger for msal-angular.
140
- * If no logger set, returns logger instance created with same options as msal-browser
141
- */
142
- getLogger() {
143
- if (!this.logger) {
144
- this.logger = this.instance.getLogger().clone(name, version);
145
- }
146
- return this.logger;
147
- }
148
- // Create a logger instance for msal-angular with the same options as msal-browser
149
- setLogger(logger) {
150
- this.logger = logger.clone(name, version);
151
- this.instance.setLogger(logger);
152
- }
153
- }
154
- MsalService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MsalService, deps: [{ token: MSAL_INSTANCE }, { token: i3.Location }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable });
155
- MsalService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MsalService });
156
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MsalService, decorators: [{
157
- type: Injectable
158
- }], ctorParameters: function () { return [{ type: undefined, decorators: [{
159
- type: Inject,
160
- args: [MSAL_INSTANCE]
161
- }] }, { type: i3.Location }, { type: i0.Injector }]; } });
162
-
163
- /*
164
- * Copyright (c) Microsoft Corporation. All rights reserved.
165
- * Licensed under the MIT License.
166
- */
167
- class MsalGuard {
168
- constructor(msalGuardConfig, msalBroadcastService, authService, location, router) {
169
- this.msalGuardConfig = msalGuardConfig;
170
- this.msalBroadcastService = msalBroadcastService;
171
- this.authService = authService;
172
- this.location = location;
173
- this.router = router;
174
- // Subscribing so events in MsalGuard will set inProgress$ observable
175
- this.msalBroadcastService.inProgress$.subscribe();
176
- }
177
- /**
178
- * Parses url string to UrlTree
179
- * @param url
180
- */
181
- parseUrl(url) {
182
- return this.router.parseUrl(url);
183
- }
184
- /**
185
- * Builds the absolute url for the destination page
186
- * @param path Relative path of requested page
187
- * @returns Full destination url
188
- */
189
- getDestinationUrl(path) {
190
- this.authService.getLogger().verbose("Guard - getting destination url");
191
- // Absolute base url for the application (default to origin if base element not present)
192
- const baseElements = document.getElementsByTagName("base");
193
- const baseUrl = this.location.normalize(baseElements.length ? baseElements[0].href : window.location.origin);
194
- // Path of page (including hash, if using hash routing)
195
- const pathUrl = this.location.prepareExternalUrl(path);
196
- // Hash location strategy
197
- if (pathUrl.startsWith("#")) {
198
- this.authService
199
- .getLogger()
200
- .verbose("Guard - destination by hash routing");
201
- return `${baseUrl}/${pathUrl}`;
202
- }
203
- /*
204
- * If using path location strategy, pathUrl will include the relative portion of the base path (e.g. /base/page).
205
- * Since baseUrl also includes /base, can just concatentate baseUrl + path
206
- */
207
- return `${baseUrl}${path}`;
208
- }
209
- /**
210
- * Interactively prompt the user to login
211
- * @param url Path of the requested page
212
- */
213
- loginInteractively(state) {
214
- const authRequest = typeof this.msalGuardConfig.authRequest === "function"
215
- ? this.msalGuardConfig.authRequest(this.authService, state)
216
- : { ...this.msalGuardConfig.authRequest };
217
- if (this.msalGuardConfig.interactionType === InteractionType.Popup) {
218
- this.authService.getLogger().verbose("Guard - logging in by popup");
219
- return this.authService.loginPopup(authRequest).pipe(map((response) => {
220
- this.authService
221
- .getLogger()
222
- .verbose("Guard - login by popup successful, can activate, setting active account");
223
- this.authService.instance.setActiveAccount(response.account);
224
- return true;
225
- }));
226
- }
227
- this.authService.getLogger().verbose("Guard - logging in by redirect");
228
- const redirectStartPage = this.getDestinationUrl(state.url);
229
- return this.authService
230
- .loginRedirect({
231
- redirectStartPage,
232
- ...authRequest,
233
- })
234
- .pipe(map(() => false));
235
- }
236
- /**
237
- * Helper which checks for the correct interaction type, prevents page with Guard to be set as redirect, and calls handleRedirectObservable
238
- * @param state
239
- */
240
- activateHelper(state) {
241
- if (this.msalGuardConfig.interactionType !== InteractionType.Popup &&
242
- this.msalGuardConfig.interactionType !== InteractionType.Redirect) {
243
- throw new BrowserConfigurationAuthError("invalid_interaction_type", "Invalid interaction type provided to MSAL Guard. InteractionType.Popup or InteractionType.Redirect must be provided in the MsalGuardConfiguration");
244
- }
245
- this.authService.getLogger().verbose("MSAL Guard activated");
246
- /*
247
- * If a page with MSAL Guard is set as the redirect for acquireTokenSilent,
248
- * short-circuit to prevent redirecting or popups.
249
- */
250
- if (typeof window !== "undefined") {
251
- if (UrlString.hashContainsKnownProperties(window.location.hash) &&
252
- BrowserUtils.isInIframe() &&
253
- !this.authService.instance.getConfiguration().system
254
- .allowRedirectInIframe) {
255
- this.authService
256
- .getLogger()
257
- .warning("Guard - redirectUri set to page with MSAL Guard. It is recommended to not set redirectUri to a page that requires authentication.");
258
- return of(false);
259
- }
260
- }
261
- else {
262
- this.authService
263
- .getLogger()
264
- .info("Guard - window is undefined, MSAL does not support server-side token acquisition");
265
- return of(true);
266
- }
267
- /**
268
- * If a loginFailedRoute is set in the config, set this as the loginFailedRoute
269
- */
270
- if (this.msalGuardConfig.loginFailedRoute) {
271
- this.loginFailedRoute = this.parseUrl(this.msalGuardConfig.loginFailedRoute);
272
- }
273
- // Capture current path before it gets changed by handleRedirectObservable
274
- const currentPath = this.location.path(true);
275
- return this.authService.initialize().pipe(concatMap(() => {
276
- return this.authService.handleRedirectObservable();
277
- }), concatMap(() => {
278
- if (!this.authService.instance.getAllAccounts().length) {
279
- if (state) {
280
- this.authService
281
- .getLogger()
282
- .verbose("Guard - no accounts retrieved, log in required to activate");
283
- return this.loginInteractively(state);
284
- }
285
- this.authService
286
- .getLogger()
287
- .verbose("Guard - no accounts retrieved, no state, cannot load");
288
- return of(false);
289
- }
290
- this.authService
291
- .getLogger()
292
- .verbose("Guard - at least 1 account exists, can activate or load");
293
- // Prevent navigating the app to /#code= or /code=
294
- if (state) {
295
- /*
296
- * Path routing:
297
- * state.url: /#code=...
298
- * state.root.fragment: code=...
299
- */
300
- /*
301
- * Hash routing:
302
- * state.url: /code
303
- * state.root.fragment: null
304
- */
305
- const urlContainsCode = this.includesCode(state.url);
306
- const fragmentContainsCode = !!state.root &&
307
- !!state.root.fragment &&
308
- this.includesCode(`#${state.root.fragment}`);
309
- const hashRouting = this.location.prepareExternalUrl(state.url).indexOf("#") === 0;
310
- // Ensure code parameter is in fragment (and not in query parameter), or that hash hash routing is used
311
- if (urlContainsCode && (fragmentContainsCode || hashRouting)) {
312
- this.authService
313
- .getLogger()
314
- .info("Guard - Hash contains known code response, stopping navigation.");
315
- // Path routing (navigate to current path without hash)
316
- if (currentPath.indexOf("#") > -1) {
317
- return of(this.parseUrl(this.location.path()));
318
- }
319
- // Hash routing (navigate to root path)
320
- return of(this.parseUrl(""));
321
- }
322
- }
323
- return of(true);
324
- }), catchError((error) => {
325
- this.authService
326
- .getLogger()
327
- .error("Guard - error while logging in, unable to activate");
328
- this.authService
329
- .getLogger()
330
- .errorPii(`Guard - error: ${error.message}`);
331
- /**
332
- * If a loginFailedRoute is set, checks to see if state is passed before returning route
333
- */
334
- if (this.loginFailedRoute && state) {
335
- this.authService
336
- .getLogger()
337
- .verbose("Guard - loginFailedRoute set, redirecting");
338
- return of(this.loginFailedRoute);
339
- }
340
- return of(false);
341
- }));
342
- }
343
- includesCode(path) {
344
- return ((path.lastIndexOf("/code") > -1 &&
345
- path.lastIndexOf("/code") === path.length - "/code".length) || // path.endsWith("/code")
346
- path.indexOf("#code=") > -1 ||
347
- path.indexOf("&code=") > -1);
348
- }
349
- canActivate(route, state) {
350
- this.authService.getLogger().verbose("Guard - canActivate");
351
- return this.activateHelper(state);
352
- }
353
- canActivateChild(route, state) {
354
- this.authService.getLogger().verbose("Guard - canActivateChild");
355
- return this.activateHelper(state);
356
- }
357
- canMatch() {
358
- this.authService.getLogger().verbose("Guard - canLoad");
359
- return this.activateHelper();
360
- }
361
- }
362
- MsalGuard.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MsalGuard, deps: [{ token: MSAL_GUARD_CONFIG }, { token: MsalBroadcastService }, { token: MsalService }, { token: i3.Location }, { token: i4.Router }], target: i0.ɵɵFactoryTarget.Injectable });
363
- MsalGuard.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MsalGuard });
364
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MsalGuard, decorators: [{
365
- type: Injectable
366
- }], ctorParameters: function () { return [{ type: undefined, decorators: [{
367
- type: Inject,
368
- args: [MSAL_GUARD_CONFIG]
369
- }] }, { type: MsalBroadcastService }, { type: MsalService }, { type: i3.Location }, { type: i4.Router }]; } });
370
-
371
- /*
372
- * Copyright (c) Microsoft Corporation. All rights reserved.
373
- * Licensed under the MIT License.
374
- */
375
- class MsalInterceptor {
376
- constructor(msalInterceptorConfig, authService, location, msalBroadcastService,
377
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
378
- document) {
379
- this.msalInterceptorConfig = msalInterceptorConfig;
380
- this.authService = authService;
381
- this.location = location;
382
- this.msalBroadcastService = msalBroadcastService;
383
- this._document = document;
384
- }
385
- intercept(req, // eslint-disable-line @typescript-eslint/no-explicit-any
386
- next
387
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
388
- ) {
389
- if (this.msalInterceptorConfig.interactionType !== InteractionType.Popup &&
390
- this.msalInterceptorConfig.interactionType !== InteractionType.Redirect) {
391
- throw new BrowserConfigurationAuthError("invalid_interaction_type", "Invalid interaction type provided to MSAL Interceptor. InteractionType.Popup, InteractionType.Redirect must be provided in the msalInterceptorConfiguration");
392
- }
393
- this.authService.getLogger().verbose("MSAL Interceptor activated");
394
- const scopes = this.getScopesForEndpoint(req.url, req.method);
395
- // If no scopes for endpoint, does not acquire token
396
- if (!scopes || scopes.length === 0) {
397
- this.authService
398
- .getLogger()
399
- .verbose("Interceptor - no scopes for endpoint");
400
- return next.handle(req);
401
- }
402
- // Sets account as active account or first account
403
- let account;
404
- if (!!this.authService.instance.getActiveAccount()) {
405
- this.authService
406
- .getLogger()
407
- .verbose("Interceptor - active account selected");
408
- account = this.authService.instance.getActiveAccount();
409
- }
410
- else {
411
- this.authService
412
- .getLogger()
413
- .verbose("Interceptor - no active account, fallback to first account");
414
- account = this.authService.instance.getAllAccounts()[0];
415
- }
416
- const authRequest = typeof this.msalInterceptorConfig.authRequest === "function"
417
- ? this.msalInterceptorConfig.authRequest(this.authService, req, {
418
- account: account,
419
- })
420
- : { ...this.msalInterceptorConfig.authRequest, account };
421
- this.authService
422
- .getLogger()
423
- .info(`Interceptor - ${scopes.length} scopes found for endpoint`);
424
- this.authService
425
- .getLogger()
426
- .infoPii(`Interceptor - [${scopes}] scopes found for ${req.url}`);
427
- return this.acquireToken(authRequest, scopes, account).pipe(switchMap((result) => {
428
- this.authService
429
- .getLogger()
430
- .verbose("Interceptor - setting authorization headers");
431
- const headers = req.headers.set("Authorization", `Bearer ${result.accessToken}`);
432
- const requestClone = req.clone({ headers });
433
- return next.handle(requestClone);
434
- }));
435
- }
436
- /**
437
- * Try to acquire token silently. Invoke interaction if acquireTokenSilent rejected with error or resolved with null access token
438
- * @param authRequest Request
439
- * @param scopes Array of scopes for the request
440
- * @param account Account
441
- * @returns Authentication result
442
- */
443
- acquireToken(authRequest, scopes, account) {
444
- // Note: For MSA accounts, include openid scope when calling acquireTokenSilent to return idToken
445
- return this.authService
446
- .acquireTokenSilent({ ...authRequest, scopes, account })
447
- .pipe(catchError(() => {
448
- this.authService
449
- .getLogger()
450
- .error("Interceptor - acquireTokenSilent rejected with error. Invoking interaction to resolve.");
451
- return this.msalBroadcastService.inProgress$.pipe(take(1), switchMap((status) => {
452
- if (status === InteractionStatus.None) {
453
- return this.acquireTokenInteractively(authRequest, scopes);
454
- }
455
- return this.msalBroadcastService.inProgress$.pipe(filter((status) => status === InteractionStatus.None), take(1), switchMap(() => this.acquireToken(authRequest, scopes, account)));
456
- }));
457
- }), switchMap((result) => {
458
- if (!result.accessToken) {
459
- this.authService
460
- .getLogger()
461
- .error("Interceptor - acquireTokenSilent resolved with null access token. Known issue with B2C tenants, invoking interaction to resolve.");
462
- return this.msalBroadcastService.inProgress$.pipe(filter((status) => status === InteractionStatus.None), take(1), switchMap(() => this.acquireTokenInteractively(authRequest, scopes)));
463
- }
464
- return of(result);
465
- }));
466
- }
467
- /**
468
- * Invoke interaction for the given set of scopes
469
- * @param authRequest Request
470
- * @param scopes Array of scopes for the request
471
- * @returns Result from the interactive request
472
- */
473
- acquireTokenInteractively(authRequest, scopes) {
474
- if (this.msalInterceptorConfig.interactionType === InteractionType.Popup) {
475
- this.authService
476
- .getLogger()
477
- .verbose("Interceptor - error acquiring token silently, acquiring by popup");
478
- return this.authService.acquireTokenPopup({ ...authRequest, scopes });
479
- }
480
- this.authService
481
- .getLogger()
482
- .verbose("Interceptor - error acquiring token silently, acquiring by redirect");
483
- const redirectStartPage = window.location.href;
484
- this.authService.acquireTokenRedirect({
485
- ...authRequest,
486
- scopes,
487
- redirectStartPage,
488
- });
489
- return EMPTY;
490
- }
491
- /**
492
- * Looks up the scopes for the given endpoint from the protectedResourceMap
493
- * @param endpoint Url of the request
494
- * @param httpMethod Http method of the request
495
- * @returns Array of scopes, or null if not found
496
- *
497
- */
498
- getScopesForEndpoint(endpoint, httpMethod) {
499
- this.authService
500
- .getLogger()
501
- .verbose("Interceptor - getting scopes for endpoint");
502
- // Ensures endpoints and protected resources compared are normalized
503
- const normalizedEndpoint = this.location.normalize(endpoint);
504
- const protectedResourcesArray = Array.from(this.msalInterceptorConfig.protectedResourceMap.keys());
505
- const matchingProtectedResources = this.matchResourcesToEndpoint(protectedResourcesArray, normalizedEndpoint);
506
- if (matchingProtectedResources.length > 0) {
507
- return this.matchScopesToEndpoint(this.msalInterceptorConfig.protectedResourceMap, matchingProtectedResources, httpMethod);
508
- }
509
- return null;
510
- }
511
- /**
512
- * Finds resource endpoints that match request endpoint
513
- * @param protectedResourcesEndpoints
514
- * @param endpoint
515
- * @returns
516
- */
517
- matchResourcesToEndpoint(protectedResourcesEndpoints, endpoint) {
518
- const matchingResources = [];
519
- protectedResourcesEndpoints.forEach((key) => {
520
- const normalizedKey = this.location.normalize(key);
521
- // Get url components
522
- const absoluteKey = this.getAbsoluteUrl(normalizedKey);
523
- const keyComponents = new URL(absoluteKey);
524
- const absoluteEndpoint = this.getAbsoluteUrl(endpoint);
525
- const endpointComponents = new URL(absoluteEndpoint);
526
- if (this.checkUrlComponents(keyComponents, endpointComponents)) {
527
- matchingResources.push(key);
528
- }
529
- });
530
- return matchingResources;
531
- }
532
- /**
533
- * Compares URL segments between key and endpoint
534
- * @param key
535
- * @param endpoint
536
- * @returns
537
- */
538
- checkUrlComponents(keyComponents, endpointComponents) {
539
- // URL properties from https://developer.mozilla.org/en-US/docs/Web/API/URL
540
- const urlProperties = ["protocol", "host", "pathname", "search", "hash"];
541
- for (const property of urlProperties) {
542
- if (keyComponents[property]) {
543
- const decodedInput = decodeURIComponent(keyComponents[property]);
544
- if (!StringUtils.matchPattern(decodedInput, endpointComponents[property])) {
545
- return false;
546
- }
547
- }
548
- }
549
- return true;
550
- }
551
- /**
552
- * Transforms relative urls to absolute urls
553
- * @param url
554
- * @returns
555
- */
556
- getAbsoluteUrl(url) {
557
- const link = this._document.createElement("a");
558
- link.href = url;
559
- return link.href;
560
- }
561
- /**
562
- * Finds scopes from first matching endpoint with HTTP method that matches request
563
- * @param protectedResourceMap Protected resource map
564
- * @param endpointArray Array of resources that match request endpoint
565
- * @param httpMethod Http method of the request
566
- * @returns
567
- */
568
- matchScopesToEndpoint(protectedResourceMap, endpointArray, httpMethod) {
569
- const allMatchedScopes = [];
570
- // Check each matched endpoint for matching HttpMethod and scopes
571
- endpointArray.forEach((matchedEndpoint) => {
572
- const scopesForEndpoint = [];
573
- const methodAndScopesArray = protectedResourceMap.get(matchedEndpoint);
574
- // Return if resource is unprotected
575
- if (methodAndScopesArray === null) {
576
- allMatchedScopes.push(null);
577
- return;
578
- }
579
- methodAndScopesArray.forEach((entry) => {
580
- // Entry is either array of scopes or ProtectedResourceScopes object
581
- if (typeof entry === "string") {
582
- scopesForEndpoint.push(entry);
583
- }
584
- else {
585
- // Ensure methods being compared are normalized
586
- const normalizedRequestMethod = httpMethod.toLowerCase();
587
- const normalizedResourceMethod = entry.httpMethod.toLowerCase();
588
- // Method in protectedResourceMap matches request http method
589
- if (normalizedResourceMethod === normalizedRequestMethod) {
590
- // Validate if scopes comes null to unprotect the resource in a certain http method
591
- if (entry.scopes === null) {
592
- allMatchedScopes.push(null);
593
- }
594
- else {
595
- entry.scopes.forEach((scope) => {
596
- scopesForEndpoint.push(scope);
597
- });
598
- }
599
- }
600
- }
601
- });
602
- // Only add to all scopes if scopes for endpoint and method is found
603
- if (scopesForEndpoint.length > 0) {
604
- allMatchedScopes.push(scopesForEndpoint);
605
- }
606
- });
607
- if (allMatchedScopes.length > 0) {
608
- if (allMatchedScopes.length > 1) {
609
- this.authService
610
- .getLogger()
611
- .warning("Interceptor - More than 1 matching scopes for endpoint found.");
612
- }
613
- // Returns scopes for first matching endpoint
614
- return allMatchedScopes[0];
615
- }
616
- return null;
617
- }
618
- }
619
- MsalInterceptor.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MsalInterceptor, deps: [{ token: MSAL_INTERCEPTOR_CONFIG }, { token: MsalService }, { token: i3.Location }, { token: MsalBroadcastService }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable });
620
- MsalInterceptor.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MsalInterceptor });
621
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MsalInterceptor, decorators: [{
622
- type: Injectable
623
- }], ctorParameters: function () { return [{ type: undefined, decorators: [{
624
- type: Inject,
625
- args: [MSAL_INTERCEPTOR_CONFIG]
626
- }] }, { type: MsalService }, { type: i3.Location }, { type: MsalBroadcastService }, { type: undefined, decorators: [{
627
- type: Inject,
628
- args: [DOCUMENT]
629
- }] }]; } });
630
-
631
- /*
632
- * Copyright (c) Microsoft Corporation. All rights reserved.
633
- * Licensed under the MIT License.
634
- */
635
- /**
636
- * This is a dedicated redirect component to be added to Angular apps to
637
- * handle redirects when using @azure/msal-angular.
638
- * Import this component to use redirects in your app.
639
- */
640
- class MsalRedirectComponent {
641
- constructor(authService) {
642
- this.authService = authService;
643
- }
644
- ngOnInit() {
645
- this.authService.getLogger().verbose("MsalRedirectComponent activated");
646
- this.authService.handleRedirectObservable().subscribe();
647
- }
648
- }
649
- MsalRedirectComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MsalRedirectComponent, deps: [{ token: MsalService }], target: i0.ɵɵFactoryTarget.Component });
650
- MsalRedirectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: MsalRedirectComponent, selector: "app-redirect", ngImport: i0, template: "", isInline: true });
651
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MsalRedirectComponent, decorators: [{
652
- type: Component,
653
- args: [{
654
- selector: "app-redirect",
655
- template: "",
656
- }]
657
- }], ctorParameters: function () { return [{ type: MsalService }]; } });
658
-
659
- /*
660
- * Copyright (c) Microsoft Corporation. All rights reserved.
661
- * Licensed under the MIT License.
662
- */
663
- class MsalModule {
664
- static forRoot(msalInstance, guardConfig, interceptorConfig) {
665
- return {
666
- ngModule: MsalModule,
667
- providers: [
668
- {
669
- provide: MSAL_INSTANCE,
670
- useValue: msalInstance,
671
- },
672
- {
673
- provide: MSAL_GUARD_CONFIG,
674
- useValue: guardConfig,
675
- },
676
- {
677
- provide: MSAL_INTERCEPTOR_CONFIG,
678
- useValue: interceptorConfig,
679
- },
680
- MsalService,
681
- ],
682
- };
683
- }
684
- }
685
- MsalModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MsalModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
686
- MsalModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.10", ngImport: i0, type: MsalModule, declarations: [MsalRedirectComponent], imports: [CommonModule] });
687
- MsalModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MsalModule, providers: [MsalGuard, MsalBroadcastService], imports: [CommonModule] });
688
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MsalModule, decorators: [{
689
- type: NgModule,
690
- args: [{
691
- declarations: [MsalRedirectComponent],
692
- imports: [CommonModule],
693
- providers: [MsalGuard, MsalBroadcastService],
694
- }]
695
- }] });
696
-
697
- /*
698
- * Copyright (c) Microsoft Corporation. All rights reserved.
699
- * Licensed under the MIT License.
700
- */
701
- /**
702
- * Custom navigation used for Angular client-side navigation.
703
- * See performance doc for details:
704
- * https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/dev/lib/msal-angular/docs/performance.md
705
- */
706
- class MsalCustomNavigationClient extends NavigationClient {
707
- constructor(authService, router, location) {
708
- super();
709
- this.authService = authService;
710
- this.router = router;
711
- this.location = location;
712
- }
713
- async navigateInternal(url, options) {
714
- this.authService.getLogger().trace("MsalCustomNavigationClient called");
715
- this.authService
716
- .getLogger()
717
- .verbose("MsalCustomNavigationClient - navigating");
718
- this.authService
719
- .getLogger()
720
- .verbosePii(`MsalCustomNavigationClient - navigating to url: ${url}`);
721
- // Prevent hash clearing from causing an issue with Client-side navigation after redirect is handled
722
- if (options.noHistory) {
723
- return super.navigateInternal(url, options);
724
- }
725
- else {
726
- // Normalizing newUrl if no query string
727
- const urlComponents = new UrlString(url).getUrlComponents();
728
- const newUrl = urlComponents.QueryString
729
- ? `${urlComponents.AbsolutePath}?${urlComponents.QueryString}`
730
- : this.location.normalize(urlComponents.AbsolutePath);
731
- await this.router.navigateByUrl(newUrl, {
732
- replaceUrl: options.noHistory,
733
- });
734
- }
735
- return Promise.resolve(options.noHistory);
736
- }
737
- }
738
- MsalCustomNavigationClient.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MsalCustomNavigationClient, deps: [{ token: MsalService }, { token: i4.Router }, { token: i3.Location }], target: i0.ɵɵFactoryTarget.Injectable });
739
- MsalCustomNavigationClient.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MsalCustomNavigationClient });
740
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: MsalCustomNavigationClient, decorators: [{
741
- type: Injectable
742
- }], ctorParameters: function () { return [{ type: MsalService }, { type: i4.Router }, { type: i3.Location }]; } });
743
-
744
- /*
745
- * Copyright (c) Microsoft Corporation. All rights reserved.
746
- * Licensed under the MIT License.
747
- */
748
- /**
749
- * @packageDocumentation
750
- * @module @azure/msal-angular
751
- */
752
-
753
- /**
754
- * Generated bundle index. Do not edit.
755
- */
756
-
757
- export { MSAL_BROADCAST_CONFIG, MSAL_GUARD_CONFIG, MSAL_INSTANCE, MSAL_INTERCEPTOR_CONFIG, MsalBroadcastService, MsalCustomNavigationClient, MsalGuard, MsalInterceptor, MsalModule, MsalRedirectComponent, MsalService, version };
758
- //# sourceMappingURL=azure-msal-angular.mjs.map