@auth0/auth0-angular 2.2.3 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,736 +0,0 @@
1
- import * as i0 from '@angular/core';
2
- import { VERSION, InjectionToken, Injectable, Optional, Inject, NgModule, inject } from '@angular/core';
3
- import { BehaviorSubject, Subject, ReplaySubject, merge, defer, of, iif, from, throwError } from 'rxjs';
4
- import { scan, filter, distinctUntilChanged, switchMap, mergeMap, shareReplay, concatMap, catchError, tap, takeUntil, withLatestFrom, map, take, first, mapTo, pluck } from 'rxjs/operators';
5
- import * as i4 from '@auth0/auth0-spa-js';
6
- import { Auth0Client } from '@auth0/auth0-spa-js';
7
- export { AuthenticationError, GenericError, InMemoryCache, LocalStorageCache, MfaRequiredError, MissingRefreshTokenError, PopupCancelledError, PopupTimeoutError, TimeoutError, User } from '@auth0/auth0-spa-js';
8
- import { Router } from '@angular/router';
9
- import * as i1 from '@angular/common';
10
-
11
- var useragent = { name: '@auth0/auth0-angular', version: '2.2.3' };
12
-
13
- class Auth0ClientFactory {
14
- static createClient(configFactory) {
15
- const config = configFactory.get();
16
- if (!config) {
17
- throw new Error('Configuration must be specified either through AuthModule.forRoot or through AuthClientConfig.set');
18
- }
19
- return new Auth0Client(Object.assign(Object.assign({}, config), { auth0Client: {
20
- name: useragent.name,
21
- version: useragent.version,
22
- env: {
23
- 'angular/core': VERSION.full,
24
- },
25
- } }));
26
- }
27
- }
28
- const Auth0ClientService = new InjectionToken('auth0.client');
29
-
30
- /**
31
- * A custom type guard to help identify route definitions that are actually HttpInterceptorRouteConfig types.
32
- *
33
- * @param def The route definition type
34
- */
35
- function isHttpInterceptorRouteConfig(def) {
36
- return typeof def !== 'string';
37
- }
38
- /**
39
- * Injection token for accessing configuration.
40
- *
41
- * @usageNotes
42
- *
43
- * Use the `Inject` decorator to access the configuration from a service or component:
44
- *
45
- * ```
46
- * class MyService(@Inject(AuthConfigService) config: AuthConfig) {}
47
- * ```
48
- */
49
- const AuthConfigService = new InjectionToken('auth0-angular.config');
50
- /**
51
- * Gets and sets configuration for the internal Auth0 client. This can be
52
- * used to provide configuration outside of using AuthModule.forRoot, i.e. from
53
- * a factory provided by APP_INITIALIZER.
54
- *
55
- * @usage
56
- *
57
- * ```js
58
- * // app.module.ts
59
- * // ---------------------------
60
- * import { AuthModule, AuthClientConfig } from '@auth0/auth0-angular';
61
- *
62
- * // Provide an initializer function that returns a Promise
63
- * function configInitializer(
64
- * http: HttpClient,
65
- * config: AuthClientConfig
66
- * ) {
67
- * return () =>
68
- * http
69
- * .get('/config')
70
- * .toPromise()
71
- * .then((loadedConfig: any) => config.set(loadedConfig)); // Set the config that was loaded asynchronously here
72
- * }
73
- *
74
- * // Provide APP_INITIALIZER with this function. Note that there is no config passed to AuthModule.forRoot
75
- * imports: [
76
- * // other imports..
77
- *
78
- * HttpClientModule,
79
- * AuthModule.forRoot(), //<- don't pass any config here
80
- * ],
81
- * providers: [
82
- * {
83
- * provide: APP_INITIALIZER,
84
- * useFactory: configInitializer, // <- pass your initializer function here
85
- * deps: [HttpClient, AuthClientConfig],
86
- * multi: true,
87
- * },
88
- * ],
89
- * ```
90
- *
91
- */
92
- class AuthClientConfig {
93
- constructor(config) {
94
- if (config) {
95
- this.set(config);
96
- }
97
- }
98
- /**
99
- * Sets configuration to be read by other consumers of the service (see usage notes)
100
- *
101
- * @param config The configuration to set
102
- */
103
- set(config) {
104
- this.config = config;
105
- }
106
- /**
107
- * Gets the config that has been set by other consumers of the service
108
- */
109
- get() {
110
- return this.config;
111
- }
112
- }
113
- AuthClientConfig.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: AuthClientConfig, deps: [{ token: AuthConfigService, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
114
- AuthClientConfig.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: AuthClientConfig, providedIn: 'root' });
115
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: AuthClientConfig, decorators: [{
116
- type: Injectable,
117
- args: [{ providedIn: 'root' }]
118
- }], ctorParameters: function () {
119
- return [{ type: undefined, decorators: [{
120
- type: Optional
121
- }, {
122
- type: Inject,
123
- args: [AuthConfigService]
124
- }] }];
125
- } });
126
-
127
- class AbstractNavigator {
128
- constructor(location, injector) {
129
- this.location = location;
130
- try {
131
- this.router = injector.get(Router);
132
- }
133
- catch (_a) { }
134
- }
135
- /**
136
- * Navigates to the specified url. The router will be used if one is available, otherwise it falls back
137
- * to `window.history.replaceState`.
138
- *
139
- * @param url The url to navigate to
140
- */
141
- navigateByUrl(url) {
142
- if (this.router) {
143
- this.router.navigateByUrl(url);
144
- return;
145
- }
146
- this.location.replaceState(url);
147
- }
148
- }
149
- AbstractNavigator.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: AbstractNavigator, deps: [{ token: i1.Location }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable });
150
- AbstractNavigator.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: AbstractNavigator, providedIn: 'root' });
151
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: AbstractNavigator, decorators: [{
152
- type: Injectable,
153
- args: [{
154
- providedIn: 'root',
155
- }]
156
- }], ctorParameters: function () { return [{ type: i1.Location }, { type: i0.Injector }]; } });
157
-
158
- /**
159
- * Tracks the Authentication State for the SDK
160
- */
161
- class AuthState {
162
- constructor(auth0Client) {
163
- this.auth0Client = auth0Client;
164
- this.isLoadingSubject$ = new BehaviorSubject(true);
165
- this.refresh$ = new Subject();
166
- this.accessToken$ = new ReplaySubject(1);
167
- this.errorSubject$ = new ReplaySubject(1);
168
- /**
169
- * Emits boolean values indicating the loading state of the SDK.
170
- */
171
- this.isLoading$ = this.isLoadingSubject$.asObservable();
172
- /**
173
- * Trigger used to pull User information from the Auth0Client.
174
- * Triggers when the access token has changed.
175
- */
176
- this.accessTokenTrigger$ = this.accessToken$.pipe(scan((acc, current) => ({
177
- previous: acc.current,
178
- current,
179
- }), { current: null, previous: null }), filter(({ previous, current }) => previous !== current));
180
- /**
181
- * Trigger used to pull User information from the Auth0Client.
182
- * Triggers when an event occurs that needs to retrigger the User Profile information.
183
- * Events: Login, Access Token change and Logout
184
- */
185
- this.isAuthenticatedTrigger$ = this.isLoading$.pipe(filter((loading) => !loading), distinctUntilChanged(), switchMap(() =>
186
- // To track the value of isAuthenticated over time, we need to merge:
187
- // - the current value
188
- // - the value whenever the access token changes. (this should always be true of there is an access token
189
- // but it is safer to pass this through this.auth0Client.isAuthenticated() nevertheless)
190
- // - the value whenever refreshState$ emits
191
- merge(defer(() => this.auth0Client.isAuthenticated()), this.accessTokenTrigger$.pipe(mergeMap(() => this.auth0Client.isAuthenticated())), this.refresh$.pipe(mergeMap(() => this.auth0Client.isAuthenticated())))));
192
- /**
193
- * Emits boolean values indicating the authentication state of the user. If `true`, it means a user has authenticated.
194
- * This depends on the value of `isLoading$`, so there is no need to manually check the loading state of the SDK.
195
- */
196
- this.isAuthenticated$ = this.isAuthenticatedTrigger$.pipe(distinctUntilChanged(), shareReplay(1));
197
- /**
198
- * Emits details about the authenticated user, or null if not authenticated.
199
- */
200
- this.user$ = this.isAuthenticatedTrigger$.pipe(concatMap((authenticated) => authenticated ? this.auth0Client.getUser() : of(null)), distinctUntilChanged());
201
- /**
202
- * Emits ID token claims when authenticated, or null if not authenticated.
203
- */
204
- this.idTokenClaims$ = this.isAuthenticatedTrigger$.pipe(concatMap((authenticated) => authenticated ? this.auth0Client.getIdTokenClaims() : of(null)));
205
- /**
206
- * Emits errors that occur during login, or when checking for an active session on startup.
207
- */
208
- this.error$ = this.errorSubject$.asObservable();
209
- }
210
- /**
211
- * Update the isLoading state using the provided value
212
- *
213
- * @param isLoading The new value for isLoading
214
- */
215
- setIsLoading(isLoading) {
216
- this.isLoadingSubject$.next(isLoading);
217
- }
218
- /**
219
- * Refresh the state to ensure the `isAuthenticated`, `user$` and `idTokenClaims$`
220
- * reflect the most up-to-date values from Auth0Client.
221
- */
222
- refresh() {
223
- this.refresh$.next();
224
- }
225
- /**
226
- * Update the access token, doing so will also refresh the state.
227
- *
228
- * @param accessToken The new Access Token
229
- */
230
- setAccessToken(accessToken) {
231
- this.accessToken$.next(accessToken);
232
- }
233
- /**
234
- * Emits the error in the `error$` observable.
235
- *
236
- * @param error The new error
237
- */
238
- setError(error) {
239
- this.errorSubject$.next(error);
240
- }
241
- }
242
- AuthState.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: AuthState, deps: [{ token: Auth0ClientService }], target: i0.ɵɵFactoryTarget.Injectable });
243
- AuthState.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: AuthState, providedIn: 'root' });
244
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: AuthState, decorators: [{
245
- type: Injectable,
246
- args: [{ providedIn: 'root' }]
247
- }], ctorParameters: function () {
248
- return [{ type: i4.Auth0Client, decorators: [{
249
- type: Inject,
250
- args: [Auth0ClientService]
251
- }] }];
252
- } });
253
-
254
- class AuthService {
255
- constructor(auth0Client, configFactory, navigator, authState) {
256
- this.auth0Client = auth0Client;
257
- this.configFactory = configFactory;
258
- this.navigator = navigator;
259
- this.authState = authState;
260
- this.appStateSubject$ = new ReplaySubject(1);
261
- // https://stackoverflow.com/a/41177163
262
- this.ngUnsubscribe$ = new Subject();
263
- /**
264
- * Emits boolean values indicating the loading state of the SDK.
265
- */
266
- this.isLoading$ = this.authState.isLoading$;
267
- /**
268
- * Emits boolean values indicating the authentication state of the user. If `true`, it means a user has authenticated.
269
- * This depends on the value of `isLoading$`, so there is no need to manually check the loading state of the SDK.
270
- */
271
- this.isAuthenticated$ = this.authState.isAuthenticated$;
272
- /**
273
- * Emits details about the authenticated user, or null if not authenticated.
274
- */
275
- this.user$ = this.authState.user$;
276
- /**
277
- * Emits ID token claims when authenticated, or null if not authenticated.
278
- */
279
- this.idTokenClaims$ = this.authState.idTokenClaims$;
280
- /**
281
- * Emits errors that occur during login, or when checking for an active session on startup.
282
- */
283
- this.error$ = this.authState.error$;
284
- /**
285
- * Emits the value (if any) that was passed to the `loginWithRedirect` method call
286
- * but only **after** `handleRedirectCallback` is first called
287
- */
288
- this.appState$ = this.appStateSubject$.asObservable();
289
- const checkSessionOrCallback$ = (isCallback) => iif(() => isCallback, this.handleRedirectCallback(), defer(() => this.auth0Client.checkSession()));
290
- this.shouldHandleCallback()
291
- .pipe(switchMap((isCallback) => checkSessionOrCallback$(isCallback).pipe(catchError((error) => {
292
- const config = this.configFactory.get();
293
- this.navigator.navigateByUrl(config.errorPath || '/');
294
- this.authState.setError(error);
295
- return of(undefined);
296
- }))), tap(() => {
297
- this.authState.setIsLoading(false);
298
- }), takeUntil(this.ngUnsubscribe$))
299
- .subscribe();
300
- }
301
- /**
302
- * Called when the service is destroyed
303
- */
304
- ngOnDestroy() {
305
- // https://stackoverflow.com/a/41177163
306
- this.ngUnsubscribe$.next();
307
- this.ngUnsubscribe$.complete();
308
- }
309
- /**
310
- * ```js
311
- * loginWithRedirect(options);
312
- * ```
313
- *
314
- * Performs a redirect to `/authorize` using the parameters
315
- * provided as arguments. Random and secure `state` and `nonce`
316
- * parameters will be auto-generated.
317
- *
318
- * @param options The login options
319
- */
320
- loginWithRedirect(options) {
321
- return from(this.auth0Client.loginWithRedirect(options));
322
- }
323
- /**
324
- * ```js
325
- * await loginWithPopup(options);
326
- * ```
327
- *
328
- * Opens a popup with the `/authorize` URL using the parameters
329
- * provided as arguments. Random and secure `state` and `nonce`
330
- * parameters will be auto-generated. If the response is successful,
331
- * results will be valid according to their expiration times.
332
- *
333
- * IMPORTANT: This method has to be called from an event handler
334
- * that was started by the user like a button click, for example,
335
- * otherwise the popup will be blocked in most browsers.
336
- *
337
- * @param options The login options
338
- * @param config Configuration for the popup window
339
- */
340
- loginWithPopup(options, config) {
341
- return from(this.auth0Client.loginWithPopup(options, config).then(() => {
342
- this.authState.refresh();
343
- }));
344
- }
345
- /**
346
- * ```js
347
- * logout();
348
- * ```
349
- *
350
- * Clears the application session and performs a redirect to `/v2/logout`, using
351
- * the parameters provided as arguments, to clear the Auth0 session.
352
- * If the `federated` option is specified it also clears the Identity Provider session.
353
- * If the `openUrl` option is set to false, it only clears the application session.
354
- * It is invalid to set both the `federated` to true and `openUrl` to `false`,
355
- * and an error will be thrown if you do.
356
- * [Read more about how Logout works at Auth0](https://auth0.com/docs/logout).
357
- *
358
- * @param options The logout options
359
- */
360
- logout(options) {
361
- return from(this.auth0Client.logout(options).then(() => {
362
- if ((options === null || options === void 0 ? void 0 : options.openUrl) === false || (options === null || options === void 0 ? void 0 : options.openUrl)) {
363
- this.authState.refresh();
364
- }
365
- }));
366
- }
367
- /**
368
- * ```js
369
- * getAccessTokenSilently(options).subscribe(token => ...)
370
- * ```
371
- *
372
- * If there's a valid token stored, return it. Otherwise, opens an
373
- * iframe with the `/authorize` URL using the parameters provided
374
- * as arguments. Random and secure `state` and `nonce` parameters
375
- * will be auto-generated. If the response is successful, results
376
- * will be valid according to their expiration times.
377
- *
378
- * If refresh tokens are used, the token endpoint is called directly with the
379
- * 'refresh_token' grant. If no refresh token is available to make this call,
380
- * the SDK falls back to using an iframe to the '/authorize' URL.
381
- *
382
- * This method may use a web worker to perform the token call if the in-memory
383
- * cache is used.
384
- *
385
- * If an `audience` value is given to this function, the SDK always falls
386
- * back to using an iframe to make the token exchange.
387
- *
388
- * Note that in all cases, falling back to an iframe requires access to
389
- * the `auth0` cookie, and thus will not work in browsers that block third-party
390
- * cookies by default (Safari, Brave, etc).
391
- *
392
- * @param options The options for configuring the token fetch.
393
- */
394
- getAccessTokenSilently(options = {}) {
395
- return of(this.auth0Client).pipe(concatMap((client) => options.detailedResponse === true
396
- ? client.getTokenSilently(Object.assign(Object.assign({}, options), { detailedResponse: true }))
397
- : client.getTokenSilently(options)), tap((token) => {
398
- if (token) {
399
- this.authState.setAccessToken(typeof token === 'string' ? token : token.access_token);
400
- }
401
- }), catchError((error) => {
402
- this.authState.setError(error);
403
- this.authState.refresh();
404
- return throwError(error);
405
- }));
406
- }
407
- /**
408
- * ```js
409
- * getTokenWithPopup(options).subscribe(token => ...)
410
- * ```
411
- *
412
- * Get an access token interactively.
413
- *
414
- * Opens a popup with the `/authorize` URL using the parameters
415
- * provided as arguments. Random and secure `state` and `nonce`
416
- * parameters will be auto-generated. If the response is successful,
417
- * results will be valid according to their expiration times.
418
- */
419
- getAccessTokenWithPopup(options) {
420
- return of(this.auth0Client).pipe(concatMap((client) => client.getTokenWithPopup(options)), tap((token) => {
421
- if (token) {
422
- this.authState.setAccessToken(token);
423
- }
424
- }), catchError((error) => {
425
- this.authState.setError(error);
426
- this.authState.refresh();
427
- return throwError(error);
428
- }));
429
- }
430
- /**
431
- * ```js
432
- * handleRedirectCallback(url).subscribe(result => ...)
433
- * ```
434
- *
435
- * After the browser redirects back to the callback page,
436
- * call `handleRedirectCallback` to handle success and error
437
- * responses from Auth0. If the response is successful, results
438
- * will be valid according to their expiration times.
439
- *
440
- * Calling this method also refreshes the authentication and user states.
441
- *
442
- * @param url The URL to that should be used to retrieve the `state` and `code` values. Defaults to `window.location.href` if not given.
443
- */
444
- handleRedirectCallback(url) {
445
- return defer(() => this.auth0Client.handleRedirectCallback(url)).pipe(withLatestFrom(this.authState.isLoading$), tap(([result, isLoading]) => {
446
- var _a;
447
- if (!isLoading) {
448
- this.authState.refresh();
449
- }
450
- const appState = result === null || result === void 0 ? void 0 : result.appState;
451
- const target = (_a = appState === null || appState === void 0 ? void 0 : appState.target) !== null && _a !== void 0 ? _a : '/';
452
- if (appState) {
453
- this.appStateSubject$.next(appState);
454
- }
455
- this.navigator.navigateByUrl(target);
456
- }), map(([result]) => result));
457
- }
458
- shouldHandleCallback() {
459
- return of(location.search).pipe(map((search) => {
460
- const searchParams = new URLSearchParams(search);
461
- return ((searchParams.has('code') || searchParams.has('error')) &&
462
- searchParams.has('state') &&
463
- !this.configFactory.get().skipRedirectCallback);
464
- }));
465
- }
466
- }
467
- AuthService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: AuthService, deps: [{ token: Auth0ClientService }, { token: AuthClientConfig }, { token: AbstractNavigator }, { token: AuthState }], target: i0.ɵɵFactoryTarget.Injectable });
468
- AuthService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: AuthService, providedIn: 'root' });
469
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: AuthService, decorators: [{
470
- type: Injectable,
471
- args: [{
472
- providedIn: 'root',
473
- }]
474
- }], ctorParameters: function () {
475
- return [{ type: i4.Auth0Client, decorators: [{
476
- type: Inject,
477
- args: [Auth0ClientService]
478
- }] }, { type: AuthClientConfig }, { type: AbstractNavigator }, { type: AuthState }];
479
- } });
480
-
481
- class AuthGuard {
482
- constructor(auth) {
483
- this.auth = auth;
484
- }
485
- canLoad(route, segments) {
486
- return this.auth.isAuthenticated$.pipe(take(1));
487
- }
488
- canActivate(next, state) {
489
- return this.redirectIfUnauthenticated(state);
490
- }
491
- canActivateChild(childRoute, state) {
492
- return this.redirectIfUnauthenticated(state);
493
- }
494
- redirectIfUnauthenticated(state) {
495
- return this.auth.isAuthenticated$.pipe(tap((loggedIn) => {
496
- if (!loggedIn) {
497
- this.auth.loginWithRedirect({
498
- appState: { target: state.url },
499
- });
500
- }
501
- }));
502
- }
503
- }
504
- AuthGuard.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: AuthGuard, deps: [{ token: AuthService }], target: i0.ɵɵFactoryTarget.Injectable });
505
- AuthGuard.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: AuthGuard, providedIn: 'root' });
506
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: AuthGuard, decorators: [{
507
- type: Injectable,
508
- args: [{
509
- providedIn: 'root',
510
- }]
511
- }], ctorParameters: function () { return [{ type: AuthService }]; } });
512
-
513
- class AuthModule {
514
- /**
515
- * Initialize the authentication module system. Configuration can either be specified here,
516
- * or by calling AuthClientConfig.set (perhaps from an APP_INITIALIZER factory function).
517
- *
518
- * @param config The optional configuration for the SDK.
519
- */
520
- static forRoot(config) {
521
- return {
522
- ngModule: AuthModule,
523
- providers: [
524
- AuthService,
525
- AuthGuard,
526
- {
527
- provide: AuthConfigService,
528
- useValue: config,
529
- },
530
- {
531
- provide: Auth0ClientService,
532
- useFactory: Auth0ClientFactory.createClient,
533
- deps: [AuthClientConfig],
534
- },
535
- ],
536
- };
537
- }
538
- }
539
- AuthModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: AuthModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
540
- AuthModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: AuthModule });
541
- AuthModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: AuthModule });
542
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: AuthModule, decorators: [{
543
- type: NgModule
544
- }] });
545
-
546
- const waitUntil = (signal$) => (source$) => source$.pipe(mergeMap((value) => signal$.pipe(first(), mapTo(value))));
547
- class AuthHttpInterceptor {
548
- constructor(configFactory, auth0Client, authState, authService) {
549
- this.configFactory = configFactory;
550
- this.auth0Client = auth0Client;
551
- this.authState = authState;
552
- this.authService = authService;
553
- }
554
- intercept(req, next) {
555
- var _a;
556
- const config = this.configFactory.get();
557
- if (!((_a = config.httpInterceptor) === null || _a === void 0 ? void 0 : _a.allowedList)) {
558
- return next.handle(req);
559
- }
560
- const isLoaded$ = this.authService.isLoading$.pipe(filter((isLoading) => !isLoading));
561
- return this.findMatchingRoute(req, config.httpInterceptor).pipe(concatMap((route) => iif(
562
- // Check if a route was matched
563
- () => route !== null,
564
- // If we have a matching route, call getTokenSilently and attach the token to the
565
- // outgoing request
566
- of(route).pipe(waitUntil(isLoaded$), pluck('tokenOptions'), concatMap((options) => this.getAccessTokenSilently(options).pipe(catchError((err) => {
567
- if (this.allowAnonymous(route, err)) {
568
- return of('');
569
- }
570
- this.authState.setError(err);
571
- return throwError(err);
572
- }))), switchMap((token) => {
573
- // Clone the request and attach the bearer token
574
- const clone = token
575
- ? req.clone({
576
- headers: req.headers.set('Authorization', `Bearer ${token}`),
577
- })
578
- : req;
579
- return next.handle(clone);
580
- })),
581
- // If the URI being called was not found in our httpInterceptor config, simply
582
- // pass the request through without attaching a token
583
- next.handle(req))));
584
- }
585
- /**
586
- * Duplicate of AuthService.getAccessTokenSilently, but with a slightly different error handling.
587
- * Only used internally in the interceptor.
588
- *
589
- * @param options The options for configuring the token fetch.
590
- */
591
- getAccessTokenSilently(options) {
592
- return of(this.auth0Client).pipe(concatMap((client) => client.getTokenSilently(options)), tap((token) => this.authState.setAccessToken(token)), catchError((error) => {
593
- this.authState.refresh();
594
- return throwError(error);
595
- }));
596
- }
597
- /**
598
- * Strips the query and fragment from the given uri
599
- *
600
- * @param uri The uri to remove the query and fragment from
601
- */
602
- stripQueryFrom(uri) {
603
- if (uri.indexOf('?') > -1) {
604
- uri = uri.substr(0, uri.indexOf('?'));
605
- }
606
- if (uri.indexOf('#') > -1) {
607
- uri = uri.substr(0, uri.indexOf('#'));
608
- }
609
- return uri;
610
- }
611
- /**
612
- * Determines whether the specified route can have an access token attached to it, based on matching the HTTP request against
613
- * the interceptor route configuration.
614
- *
615
- * @param route The route to test
616
- * @param request The HTTP request
617
- */
618
- canAttachToken(route, request) {
619
- const testPrimitive = (value) => {
620
- if (!value) {
621
- return false;
622
- }
623
- const requestPath = this.stripQueryFrom(request.url);
624
- if (value === requestPath) {
625
- return true;
626
- }
627
- // If the URL ends with an asterisk, match using startsWith.
628
- return (value.indexOf('*') === value.length - 1 &&
629
- request.url.startsWith(value.substr(0, value.length - 1)));
630
- };
631
- if (isHttpInterceptorRouteConfig(route)) {
632
- if (route.httpMethod && route.httpMethod !== request.method) {
633
- return false;
634
- }
635
- /* istanbul ignore if */
636
- if (!route.uri && !route.uriMatcher) {
637
- console.warn('Either a uri or uriMatcher is required when configuring the HTTP interceptor.');
638
- }
639
- return route.uriMatcher
640
- ? route.uriMatcher(request.url)
641
- : testPrimitive(route.uri);
642
- }
643
- return testPrimitive(route);
644
- }
645
- /**
646
- * Tries to match a route from the SDK configuration to the HTTP request.
647
- * If a match is found, the route configuration is returned.
648
- *
649
- * @param request The Http request
650
- * @param config HttpInterceptorConfig
651
- */
652
- findMatchingRoute(request, config) {
653
- return from(config.allowedList).pipe(first((route) => this.canAttachToken(route, request), null));
654
- }
655
- allowAnonymous(route, err) {
656
- return (!!route &&
657
- isHttpInterceptorRouteConfig(route) &&
658
- !!route.allowAnonymous &&
659
- ['login_required', 'consent_required', 'missing_refresh_token'].includes(err.error));
660
- }
661
- }
662
- AuthHttpInterceptor.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: AuthHttpInterceptor, deps: [{ token: AuthClientConfig }, { token: Auth0ClientService }, { token: AuthState }, { token: AuthService }], target: i0.ɵɵFactoryTarget.Injectable });
663
- AuthHttpInterceptor.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: AuthHttpInterceptor });
664
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: AuthHttpInterceptor, decorators: [{
665
- type: Injectable
666
- }], ctorParameters: function () {
667
- return [{ type: AuthClientConfig }, { type: i4.Auth0Client, decorators: [{
668
- type: Inject,
669
- args: [Auth0ClientService]
670
- }] }, { type: AuthState }, { type: AuthService }];
671
- } });
672
-
673
- /**
674
- * Initialize the authentication system. Configuration can either be specified here,
675
- * or by calling AuthClientConfig.set (perhaps from an APP_INITIALIZER factory function).
676
- *
677
- * Note: Should only be used as of Angular 15, and should not be added to a component's providers.
678
- *
679
- * @param config The optional configuration for the SDK.
680
- *
681
- * @example
682
- * bootstrapApplication(AppComponent, {
683
- * providers: [
684
- * provideAuth0(),
685
- * ],
686
- * });
687
- */
688
- function provideAuth0(config) {
689
- return [
690
- AuthService,
691
- AuthHttpInterceptor,
692
- AuthGuard,
693
- {
694
- provide: AuthConfigService,
695
- useValue: config,
696
- },
697
- {
698
- provide: Auth0ClientService,
699
- useFactory: Auth0ClientFactory.createClient,
700
- deps: [AuthClientConfig],
701
- },
702
- ];
703
- }
704
-
705
- /**
706
- * Functional AuthGuard to ensure routes can only be accessed when authenticated.
707
- *
708
- * Note: Should only be used as of Angular 15
709
- *
710
- * @param route Contains the information about a route associated with a component loaded in an outlet at a particular moment in time.
711
- * @param state Represents the state of the router at a moment in time.
712
- * @returns An Observable, indicating if the route can be accessed or not
713
- */
714
- const authGuardFn = (route, state) => inject(AuthGuard).canActivate(route, state);
715
- /**
716
- * Functional AuthHttpInterceptor to include the access token in matching requests.
717
- *
718
- * Note: Should only be used as of Angular 15
719
- *
720
- * @param req An outgoing HTTP request with an optional typed body.
721
- * @param handle Represents the next interceptor in an interceptor chain, or the real backend if there are no
722
- * further interceptors.
723
- * @returns An Observable representing the intercepted HttpRequest
724
- */
725
- const authHttpInterceptorFn = (req, handle) => inject(AuthHttpInterceptor).intercept(req, { handle });
726
-
727
- /*
728
- * Public API Surface of auth0-angular
729
- */
730
-
731
- /**
732
- * Generated bundle index. Do not edit.
733
- */
734
-
735
- export { AbstractNavigator, Auth0ClientFactory, Auth0ClientService, AuthClientConfig, AuthConfigService, AuthGuard, AuthHttpInterceptor, AuthModule, AuthService, AuthState, authGuardFn, authHttpInterceptorFn, isHttpInterceptorRouteConfig, provideAuth0 };
736
- //# sourceMappingURL=auth0-auth0-angular.mjs.map