@azure/msal-angular 3.0.23 → 3.0.25

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