@odx/auth 7.0.0 → 8.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/README.md +16 -10
- package/esm2022/index.mjs +2 -1
- package/esm2022/lib/auth.component.mjs +2 -2
- package/esm2022/lib/auth.config.mjs +6 -23
- package/esm2022/lib/auth.guard.mjs +10 -3
- package/esm2022/lib/auth.i18n.mjs +1 -1
- package/esm2022/lib/auth.interceptor.mjs +15 -0
- package/esm2022/lib/auth.logger.mjs +3 -0
- package/esm2022/lib/auth.providers.mjs +53 -36
- package/esm2022/lib/auth.service.mjs +29 -17
- package/esm2022/lib/auth.typings.mjs +1 -1
- package/esm2022/lib/components/auth-actions/auth-actions.component.mjs +2 -2
- package/esm2022/lib/components/auth-loading-screen/auth-loading-screen.component.mjs +6 -6
- package/esm2022/lib/helpers/create-auth-host-url.mjs +6 -0
- package/esm2022/lib/helpers/index.mjs +4 -1
- package/esm2022/lib/helpers/set-http-auth-header.mjs +13 -0
- package/esm2022/lib/helpers/user-language-loader.mjs +10 -0
- package/esm2022/lib/models/auth-environment.mjs +3 -2
- package/esm2022/lib/models/auth-http-cache.mjs +19 -23
- package/esm2022/lib/models/auth-plugin-manager.mjs +14 -9
- package/esm2022/lib/plugins/core-debug.plugin.mjs +20 -0
- package/esm2022/lib/plugins/index.mjs +2 -1
- package/esm2022/lib/plugins/user-profile-link.plugin.mjs +3 -3
- package/esm2022/lib/unauth.guard.mjs +10 -3
- package/esm2022/plugins/service-connect/index.mjs +2 -2
- package/esm2022/plugins/service-connect/lib/dtos/get-service-connect-user-response.dto.mjs +2 -0
- package/esm2022/plugins/service-connect/lib/dtos/index.mjs +2 -1
- package/esm2022/plugins/service-connect/lib/service-connect-rights.guard.mjs +3 -3
- package/esm2022/plugins/service-connect/lib/service-connect-rights.plugin.mjs +1 -2
- package/esm2022/plugins/service-connect/lib/service-connect-user-language.plugin.mjs +8 -0
- package/esm2022/plugins/service-connect/lib/service-connect.config.mjs +6 -4
- package/fesm2022/odx-auth-plugins-service-connect.mjs +15 -9
- package/fesm2022/odx-auth-plugins-service-connect.mjs.map +1 -1
- package/fesm2022/odx-auth.mjs +311 -243
- package/fesm2022/odx-auth.mjs.map +1 -1
- package/index.d.ts +1 -0
- package/lib/auth.config.d.ts +11 -10
- package/lib/auth.guard.d.ts +1 -1
- package/lib/auth.i18n.d.ts +2 -2
- package/lib/auth.interceptor.d.ts +2 -0
- package/lib/auth.logger.d.ts +3 -0
- package/lib/auth.providers.d.ts +7 -4
- package/lib/auth.service.d.ts +6 -2
- package/lib/auth.typings.d.ts +1 -1
- package/lib/helpers/create-auth-host-url.d.ts +2 -0
- package/lib/helpers/index.d.ts +3 -0
- package/lib/helpers/set-http-auth-header.d.ts +2 -0
- package/lib/helpers/user-language-loader.d.ts +4 -0
- package/lib/models/auth-environment.d.ts +6 -1
- package/lib/models/auth-http-cache.d.ts +3 -1
- package/lib/models/auth-plugin-manager.d.ts +2 -0
- package/lib/plugins/core-debug.plugin.d.ts +2 -0
- package/lib/plugins/index.d.ts +1 -0
- package/lib/unauth.guard.d.ts +1 -1
- package/package.json +2 -2
- package/plugins/service-connect/index.d.ts +1 -1
- package/plugins/service-connect/lib/dtos/get-service-connect-user-response.dto.d.ts +3 -0
- package/plugins/service-connect/lib/dtos/index.d.ts +1 -0
- package/plugins/service-connect/lib/service-connect-rights.guard.d.ts +1 -1
- package/plugins/service-connect/lib/service-connect-rights.plugin.d.ts +8 -1
- package/plugins/service-connect/lib/service-connect-user-language.plugin.d.ts +1 -0
- package/plugins/service-connect/lib/service-connect.config.d.ts +1 -0
- package/esm2022/plugins/service-connect/lib/service-connect.typings.mjs +0 -2
- package/plugins/service-connect/lib/service-connect.typings.d.ts +0 -9
package/fesm2022/odx-auth.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, EnvironmentInjector, InjectionToken,
|
|
3
|
-
import { WindowRef, CoreModule } from '@odx/angular';
|
|
2
|
+
import { inject, EnvironmentInjector, InjectionToken, Injector, Injectable, Component, ChangeDetectionStrategy, ViewEncapsulation, Input, DestroyRef, ENVIRONMENT_INITIALIZER, makeEnvironmentProviders, APP_INITIALIZER, ErrorHandler, Directive, EventEmitter, Output, HostListener, NgModule } from '@angular/core';
|
|
3
|
+
import { Environment, WindowRef, CoreModule } from '@odx/angular';
|
|
4
4
|
import * as i3$1 from '@odx/angular/components/area-header';
|
|
5
5
|
import { AreaHeaderModule } from '@odx/angular/components/area-header';
|
|
6
6
|
import * as i8 from '@odx/angular/components/dropdown';
|
|
@@ -10,30 +10,35 @@ import * as i1$1 from '@odx/angular/components/loading-spinner';
|
|
|
10
10
|
import { LoadingSpinnerDirective, LoadingSpinnerModule } from '@odx/angular/components/loading-spinner';
|
|
11
11
|
import { LogoDirective } from '@odx/angular/components/logo';
|
|
12
12
|
import { TranslatePipe, provideTranslations } from '@odx/angular/internal/translate';
|
|
13
|
-
import { isString,
|
|
14
|
-
import { OAuthErrorEvent, OAuthService, provideOAuthClient,
|
|
15
|
-
import { filter, switchMap,
|
|
16
|
-
import { HttpErrorResponse } from '@angular/common/http';
|
|
13
|
+
import { buildUrl, isString, CacheStorageClient, matchUrl, injectElement, isNumber, isNonEmptyString, createConfigTokens, untilDestroyed, Position } from '@odx/angular/utils';
|
|
14
|
+
import { OAuthErrorEvent, OAuthService, provideOAuthClient, OAuthStorage } from 'angular-oauth2-oidc';
|
|
15
|
+
import { filter, switchMap, firstValueFrom, mergeMap, map, of, tap, BehaviorSubject, distinctUntilChanged, share, combineLatest, take, timeout, catchError, fromEvent, startWith, shareReplay, merge, EMPTY } from 'rxjs';
|
|
16
|
+
import { HttpRequest, provideHttpClient, withInterceptors, HttpErrorResponse } from '@angular/common/http';
|
|
17
17
|
import { Router } from '@angular/router';
|
|
18
18
|
import { deepmerge } from 'deepmerge-ts';
|
|
19
|
+
import { DynamicViewDirective, DynamicViewService } from '@odx/angular/cdk/dynamic-view';
|
|
20
|
+
import { Logger, CSSComponent } from '@odx/angular/internal';
|
|
19
21
|
import { __decorate } from 'tslib';
|
|
20
22
|
import * as i2 from '@odx/angular/components/list';
|
|
21
23
|
import { ListModule } from '@odx/angular/components/list';
|
|
22
|
-
import { CSSComponent } from '@odx/angular/internal';
|
|
23
24
|
import * as i1 from '@angular/common';
|
|
24
25
|
import { CommonModule, NgIf } from '@angular/common';
|
|
25
26
|
import * as i3 from '@odx/angular/components/icon';
|
|
26
27
|
import { IconComponent } from '@odx/angular/components/icon';
|
|
27
28
|
import { trigger, transition, useAnimation } from '@angular/animations';
|
|
28
29
|
import { fadeOut } from '@odx/angular/animations';
|
|
29
|
-
import { DynamicViewDirective, DynamicViewService } from '@odx/angular/cdk/dynamic-view';
|
|
30
30
|
import * as i6 from '@odx/angular/components/button';
|
|
31
31
|
import { ButtonComponent } from '@odx/angular/components/button';
|
|
32
32
|
import { CircularProgressComponent } from '@odx/angular/components/circular-progress';
|
|
33
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
33
34
|
import * as i2$1 from '@ngrx/component';
|
|
34
35
|
import * as i4 from '@odx/angular/components/avatar';
|
|
35
36
|
import * as i5 from '@odx/angular/components/action-group';
|
|
36
37
|
|
|
38
|
+
function createAuthHostUrl(environment, ...segments) {
|
|
39
|
+
return buildUrl(ODX_AUTH_HOSTS[environment], ...segments);
|
|
40
|
+
}
|
|
41
|
+
|
|
37
42
|
function createInitials(value) {
|
|
38
43
|
if (!value)
|
|
39
44
|
return '';
|
|
@@ -101,103 +106,47 @@ function resolveUsername(claims) {
|
|
|
101
106
|
return '';
|
|
102
107
|
}
|
|
103
108
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
};
|
|
115
|
-
const ODX_AUTH_CORE_PLUGINS = new InjectionToken('@odx/auth::CorePlugins', {
|
|
116
|
-
providedIn: 'root',
|
|
117
|
-
factory: () => [],
|
|
118
|
-
});
|
|
119
|
-
const ODX_AUTH_ERROR_HANDLERS = new InjectionToken('@odx/auth::ErrorHandlers', {
|
|
120
|
-
providedIn: 'root',
|
|
121
|
-
factory: () => [],
|
|
122
|
-
});
|
|
123
|
-
const ODX_AUTH_PLUGINS = new InjectionToken('@odx/auth::Plugins', {
|
|
124
|
-
providedIn: 'root',
|
|
125
|
-
factory: () => {
|
|
126
|
-
const { plugins } = injectAuthConfig();
|
|
127
|
-
const corePlugins = inject(ODX_AUTH_CORE_PLUGINS);
|
|
128
|
-
return [...corePlugins, ...plugins].map((pluginFactory) => pluginFactory());
|
|
129
|
-
},
|
|
130
|
-
});
|
|
131
|
-
const { AuthDefaultConfig, AuthConfig, injectAuthConfig, provideAuthConfig } = createConfigTokens('Auth', '@odx/auth', {
|
|
132
|
-
environment: 'prod',
|
|
133
|
-
redirectPath: 'login/callback',
|
|
134
|
-
allowedUrls: [],
|
|
135
|
-
timeoutFactor: 0.75,
|
|
136
|
-
maxOfflineTime: 24 * 60 * 60,
|
|
137
|
-
loadUserProfile: false,
|
|
138
|
-
errorHandler: (error) => {
|
|
139
|
-
throw error;
|
|
140
|
-
},
|
|
141
|
-
createInitials,
|
|
142
|
-
resolveEmail,
|
|
143
|
-
resolveUsername,
|
|
144
|
-
plugins: [],
|
|
145
|
-
defaultAuthorizedHandler: null,
|
|
146
|
-
enableLoadingScreen: true,
|
|
147
|
-
loadingScreenMessage: null,
|
|
148
|
-
refreshTokenOnInit: true,
|
|
149
|
-
requireSignIn: false,
|
|
150
|
-
});
|
|
109
|
+
function setHttpAuthHeader(req, token) {
|
|
110
|
+
if (!token)
|
|
111
|
+
return req;
|
|
112
|
+
const header = `Bearer ${token}`;
|
|
113
|
+
if (req instanceof HttpRequest) {
|
|
114
|
+
return req.clone({ headers: req.headers.set(AUTH_HTTP_HEADER, header) });
|
|
115
|
+
}
|
|
116
|
+
req.headers.set(AUTH_HTTP_HEADER, header);
|
|
117
|
+
return req;
|
|
118
|
+
}
|
|
151
119
|
|
|
152
|
-
|
|
153
|
-
en: {
|
|
154
|
-
userProfileLink: 'My profile',
|
|
155
|
-
signInButtonText: 'Sign in',
|
|
156
|
-
signOutButtonText: 'Sign out',
|
|
157
|
-
},
|
|
158
|
-
de: {
|
|
159
|
-
userProfileLink: 'Mein Profil',
|
|
160
|
-
signInButtonText: 'Einloggen',
|
|
161
|
-
signOutButtonText: 'Ausloggen',
|
|
162
|
-
},
|
|
163
|
-
};
|
|
120
|
+
const AuthEnvironment = Environment;
|
|
164
121
|
|
|
165
122
|
const ODX_AUTH_HTTP_CACHE_STORAGE = new InjectionToken('@odx/auth::AuthHttpCacheStorage', {
|
|
166
123
|
providedIn: 'root',
|
|
167
124
|
factory: () => inject(WindowRef).nativeWindow.caches,
|
|
168
125
|
});
|
|
126
|
+
const ODX_AUTH_HTTP_CACHE_STORAGE_CLIENT = new InjectionToken('@odx/auth::AuthHttpCacheStorageClient', {
|
|
127
|
+
providedIn: 'root',
|
|
128
|
+
factory: () => new CacheStorageClient('@odx/auth/http-cache', inject(ODX_AUTH_HTTP_CACHE_STORAGE)),
|
|
129
|
+
});
|
|
169
130
|
class AuthHttpCache {
|
|
170
|
-
static { this.CACHE_KEY = '@odx/auth/http-cache'; }
|
|
171
131
|
constructor() {
|
|
172
|
-
this.cacheStorage = inject(
|
|
132
|
+
this.cacheStorage = inject(ODX_AUTH_HTTP_CACHE_STORAGE_CLIENT);
|
|
173
133
|
this.oauthService = inject(OAuthService);
|
|
134
|
+
this.injector = inject(Injector);
|
|
174
135
|
this.oauthService.events.pipe(handleOAuthEvent('logout', () => this.deleteAll())).subscribe();
|
|
175
136
|
}
|
|
176
137
|
async deleteAll() {
|
|
177
|
-
|
|
178
|
-
for (const key of await cache.keys()) {
|
|
179
|
-
await cache.delete(key);
|
|
180
|
-
}
|
|
138
|
+
await this.cacheStorage.deleteAll();
|
|
181
139
|
}
|
|
182
140
|
async delete(request) {
|
|
183
|
-
|
|
184
|
-
return cache.delete(request);
|
|
141
|
+
return this.cacheStorage.delete(request);
|
|
185
142
|
}
|
|
186
143
|
async request(requestInfo, authentication = false) {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
request.headers.
|
|
191
|
-
}
|
|
192
|
-
const cache = await this.cacheStorage.open(AuthHttpCache.CACHE_KEY);
|
|
193
|
-
const response = await fetch(request).catch(() => null);
|
|
194
|
-
if (response?.ok) {
|
|
195
|
-
await cache.put(request, response).catch(() => null);
|
|
196
|
-
}
|
|
197
|
-
if (authorizationHeader && response?.status === 401) {
|
|
198
|
-
await cache.delete(request);
|
|
144
|
+
if (authentication) {
|
|
145
|
+
const authService = this.injector.get(AuthService);
|
|
146
|
+
const request = await firstValueFrom(authService.prepareAuthRequest$(new Request(requestInfo)));
|
|
147
|
+
return this.cacheStorage.request(request, ({ status }) => request.headers.has(AUTH_HTTP_HEADER) && status === 401);
|
|
199
148
|
}
|
|
200
|
-
return
|
|
149
|
+
return this.cacheStorage.request(requestInfo, () => false);
|
|
201
150
|
}
|
|
202
151
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AuthHttpCache, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
203
152
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AuthHttpCache, providedIn: 'root' }); }
|
|
@@ -207,8 +156,183 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
207
156
|
args: [{ providedIn: 'root' }]
|
|
208
157
|
}], ctorParameters: function () { return []; } });
|
|
209
158
|
|
|
159
|
+
const authInterceptor = (req, next) => {
|
|
160
|
+
const { allowedUrls, requireSignInForRequests } = injectAuthConfig();
|
|
161
|
+
const isUrlAllowed = allowedUrls.some((allowedUrl) => matchUrl(req.url, allowedUrl));
|
|
162
|
+
if (!isUrlAllowed) {
|
|
163
|
+
return next(req);
|
|
164
|
+
}
|
|
165
|
+
const authService = inject(AuthService);
|
|
166
|
+
return authService.prepareAuthRequest$(req, requireSignInForRequests).pipe(mergeMap(next));
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
var logger = new Logger('@odx/auth');
|
|
170
|
+
|
|
171
|
+
let AuthActionsComponent = class AuthActionsComponent {
|
|
172
|
+
constructor() {
|
|
173
|
+
this.element = injectElement();
|
|
174
|
+
this.claims = null;
|
|
175
|
+
}
|
|
176
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AuthActionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
177
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: AuthActionsComponent, isStandalone: true, selector: "odx-auth-actions", inputs: { claims: "claims" }, ngImport: i0, template: "<odx-list>\n <a data-testid=\"odx-auth-user-profile-link\" odxListItem [href]=\"url\" rel=\"noopener\" target=\"_blank\" *ngIf=\"claims?.userProfileUrl as url\">\n <odx-icon name=\"user-administration\" iconSet=\"core\" odxListPrefix></odx-icon>\n {{ 'userProfileLink' | odxTranslate | async }}\n </a>\n</odx-list>\n", dependencies: [{ kind: "ngmodule", type: CoreModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "ngmodule", type: ListModule }, { kind: "component", type: i2.ListComponent, selector: "odx-list" }, { kind: "component", type: i2.ListItemComponent, selector: "odx-list-item, [odxListItem]", inputs: ["danger", "muted", "selected"] }, { kind: "component", type: i3.IconComponent, selector: "odx-icon", inputs: ["inline", "size", "name", "iconSet", "identifier"] }, { kind: "pipe", type: TranslatePipe, name: "odxTranslate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
178
|
+
};
|
|
179
|
+
AuthActionsComponent = __decorate([
|
|
180
|
+
CSSComponent('auth-actions')
|
|
181
|
+
], AuthActionsComponent);
|
|
182
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AuthActionsComponent, decorators: [{
|
|
183
|
+
type: Component,
|
|
184
|
+
args: [{ standalone: true, selector: 'odx-auth-actions', imports: [CoreModule, ListModule, TranslatePipe], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<odx-list>\n <a data-testid=\"odx-auth-user-profile-link\" odxListItem [href]=\"url\" rel=\"noopener\" target=\"_blank\" *ngIf=\"claims?.userProfileUrl as url\">\n <odx-icon name=\"user-administration\" iconSet=\"core\" odxListPrefix></odx-icon>\n {{ 'userProfileLink' | odxTranslate | async }}\n </a>\n</odx-list>\n" }]
|
|
185
|
+
}], propDecorators: { claims: [{
|
|
186
|
+
type: Input
|
|
187
|
+
}] } });
|
|
188
|
+
|
|
189
|
+
class AuthLoadingScreenComponent {
|
|
190
|
+
constructor() {
|
|
191
|
+
this.authConfig = injectAuthConfig();
|
|
192
|
+
this.icon$ = inject(AuthService).isRedirecting$.pipe(map((isRedirecting) => (isRedirecting ? 'link-external' : 'user')));
|
|
193
|
+
}
|
|
194
|
+
static { this.instance = null; }
|
|
195
|
+
static initialize(authService, dynamicViewService) {
|
|
196
|
+
authService.isLoading$.subscribe((isLoading) => {
|
|
197
|
+
if (isLoading) {
|
|
198
|
+
AuthLoadingScreenComponent.instance ??= dynamicViewService.createView(AuthLoadingScreenComponent);
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
AuthLoadingScreenComponent.instance?.destroy();
|
|
202
|
+
AuthLoadingScreenComponent.instance = null;
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AuthLoadingScreenComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
207
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: AuthLoadingScreenComponent, isStandalone: true, selector: "div.odx-auth-loading-screen", host: { properties: { "@hostAnimation": "true" } }, ngImport: i0, template: "<div class=\"odx-auth-loading-screen__content\" odxLayout=\"grid 12 horizontal-center vertical-center gap-small\">\n <odx-logo size=\"large\" />\n <odx-circular-progress class=\"odx-auth-loading-screen__spinner\" value=\"-1\" size=\"medium\" stroke=\"3\">\n <odx-icon [name]=\"icon$ | async\" iconSet=\"core\" />\n </odx-circular-progress>\n <p class=\"odx-auth-loading-screen__message\" *ngIf=\"authConfig.loadingScreenMessage as content\">\n <ng-template [odxDynamicView]=\"content\" />\n </p>\n</div>\n", styles: ["@keyframes odx-auth-loading-screen-animation{0%{opacity:0;transform:translate(-50%,-50%) scale(.9)}to{opacity:1;transform:translate(-50%,-50%)}}.odx-auth-loading-screen{--odx-c-highlight: var(--odx-c-primary);background-color:var(--odx-c-background-content);inset:0;position:fixed;z-index:var(--odx-v-layer-6)}.odx-auth-loading-screen__content{animation:odx-auth-loading-screen-animation .75s ease;left:50%;position:absolute;top:50%;transform:translate(-50%,-50%)}.odx-auth-loading-screen__message{text-align:center}.odx-auth-loading-screen__spinner{position:relative}.odx-auth-loading-screen__spinner .odx-icon{left:50%;position:absolute;top:50%;transform:translate(-50%,-50%)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "component", type: IconComponent, selector: "odx-icon", inputs: ["inline", "size", "name", "iconSet", "identifier"] }, { kind: "directive", type: LogoDirective, selector: "odx-logo", inputs: ["size", "variant"] }, { kind: "component", type: CircularProgressComponent, selector: "odx-circular-progress", inputs: ["stroke", "size", "value"] }, { kind: "directive", type: DynamicViewDirective, selector: "ng-template[odxDynamicView]", inputs: ["odxDynamicView", "odxDynamicViewInjector", "odxDynamicViewContext"] }], animations: [trigger('hostAnimation', [transition(':leave', useAnimation(fadeOut()))])], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
208
|
+
}
|
|
209
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AuthLoadingScreenComponent, decorators: [{
|
|
210
|
+
type: Component,
|
|
211
|
+
args: [{ standalone: true, selector: 'div.odx-auth-loading-screen', imports: [CommonModule, ButtonComponent, IconComponent, LogoDirective, CircularProgressComponent, DynamicViewDirective], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
|
|
212
|
+
'[@hostAnimation]': 'true',
|
|
213
|
+
}, animations: [trigger('hostAnimation', [transition(':leave', useAnimation(fadeOut()))])], template: "<div class=\"odx-auth-loading-screen__content\" odxLayout=\"grid 12 horizontal-center vertical-center gap-small\">\n <odx-logo size=\"large\" />\n <odx-circular-progress class=\"odx-auth-loading-screen__spinner\" value=\"-1\" size=\"medium\" stroke=\"3\">\n <odx-icon [name]=\"icon$ | async\" iconSet=\"core\" />\n </odx-circular-progress>\n <p class=\"odx-auth-loading-screen__message\" *ngIf=\"authConfig.loadingScreenMessage as content\">\n <ng-template [odxDynamicView]=\"content\" />\n </p>\n</div>\n", styles: ["@keyframes odx-auth-loading-screen-animation{0%{opacity:0;transform:translate(-50%,-50%) scale(.9)}to{opacity:1;transform:translate(-50%,-50%)}}.odx-auth-loading-screen{--odx-c-highlight: var(--odx-c-primary);background-color:var(--odx-c-background-content);inset:0;position:fixed;z-index:var(--odx-v-layer-6)}.odx-auth-loading-screen__content{animation:odx-auth-loading-screen-animation .75s ease;left:50%;position:absolute;top:50%;transform:translate(-50%,-50%)}.odx-auth-loading-screen__message{text-align:center}.odx-auth-loading-screen__spinner{position:relative}.odx-auth-loading-screen__spinner .odx-icon{left:50%;position:absolute;top:50%;transform:translate(-50%,-50%)}\n"] }]
|
|
214
|
+
}] });
|
|
215
|
+
|
|
216
|
+
const coreDebugPlugin = () => {
|
|
217
|
+
logger.warn('DEBUG MODE ENABLED - DO NOT USE IN PRODUCTION!');
|
|
218
|
+
const destroyRef = inject(DestroyRef);
|
|
219
|
+
let instance = null;
|
|
220
|
+
return (authService) => {
|
|
221
|
+
instance ??= authService.identityClaims$.pipe(takeUntilDestroyed(destroyRef)).subscribe((claims) => {
|
|
222
|
+
logger.info(`User: ${claims?.username} (${claims?.email})`);
|
|
223
|
+
logger.group('Identity claims', (log) => log(claims), false);
|
|
224
|
+
logger.group('Access token', (log) => log(authService.getAccessToken()));
|
|
225
|
+
logger.group('Refresh token', (log) => log(authService.getRefreshToken()));
|
|
226
|
+
logger.group('ID token', (log) => log(authService.getIdToken()));
|
|
227
|
+
});
|
|
228
|
+
return of({});
|
|
229
|
+
};
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
const coreIdentityPlugin = () => {
|
|
233
|
+
const { resolveEmail, resolveUsername, createInitials } = injectAuthConfig();
|
|
234
|
+
return (authService) => {
|
|
235
|
+
const claims = authService.getRawIdentityClaims();
|
|
236
|
+
if (!claims)
|
|
237
|
+
return of({});
|
|
238
|
+
const username = resolveUsername(claims);
|
|
239
|
+
return of({ email: resolveEmail(claims), username, initials: createInitials(username) });
|
|
240
|
+
};
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
const userProfileUrlPlugin = () => {
|
|
244
|
+
const { environment, userProfileUrl } = injectAuthConfig();
|
|
245
|
+
return () => {
|
|
246
|
+
return of({ userProfileUrl: userProfileUrl ?? ODX_AUTH_USER_PROFILE_HOSTS[environment] });
|
|
247
|
+
};
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
const ODX_AUTH_ERROR_HANDLERS = new InjectionToken('@odx/auth::ErrorHandlers', {
|
|
251
|
+
providedIn: 'root',
|
|
252
|
+
factory: () => {
|
|
253
|
+
const { errorHandler } = injectAuthConfig();
|
|
254
|
+
return [offlineAuthErrorHandler, errorHandler];
|
|
255
|
+
},
|
|
256
|
+
});
|
|
257
|
+
const ODX_AUTH_CORE_PLUGINS = new InjectionToken('@odx/auth::CorePlugins', {
|
|
258
|
+
providedIn: 'root',
|
|
259
|
+
factory: () => {
|
|
260
|
+
const { showDebugInformation } = injectAuthConfig();
|
|
261
|
+
const plugins = [coreIdentityPlugin, userProfileUrlPlugin];
|
|
262
|
+
if (showDebugInformation) {
|
|
263
|
+
plugins.push(coreDebugPlugin);
|
|
264
|
+
}
|
|
265
|
+
return plugins;
|
|
266
|
+
},
|
|
267
|
+
});
|
|
268
|
+
const ODX_AUTH_PLUGINS = new InjectionToken('@odx/auth::Plugins', {
|
|
269
|
+
providedIn: 'root',
|
|
270
|
+
factory: () => {
|
|
271
|
+
const { plugins } = injectAuthConfig();
|
|
272
|
+
const corePlugins = inject(ODX_AUTH_CORE_PLUGINS);
|
|
273
|
+
return [...corePlugins, ...plugins].map((pluginFactory) => pluginFactory());
|
|
274
|
+
},
|
|
275
|
+
});
|
|
276
|
+
function provideAuthLogger() {
|
|
277
|
+
return {
|
|
278
|
+
provide: ENVIRONMENT_INITIALIZER,
|
|
279
|
+
useFactory: () => {
|
|
280
|
+
const { showDebugInformation } = injectAuthConfig();
|
|
281
|
+
if (!showDebugInformation)
|
|
282
|
+
logger.disable();
|
|
283
|
+
return () => void 0;
|
|
284
|
+
},
|
|
285
|
+
multi: true,
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
function initializeAuthErrorHandlers() {
|
|
289
|
+
const authService = inject(AuthService);
|
|
290
|
+
const handler = handleAuthError(inject(ODX_AUTH_ERROR_HANDLERS));
|
|
291
|
+
authService.errors$.pipe(tap((error) => handler(error))).subscribe();
|
|
292
|
+
}
|
|
293
|
+
function initalizeAuthConfig() {
|
|
294
|
+
const { clientId, scopes, redirectPath, environment, postLogoutRedirectUrl, issuer, timeoutFactor, discoveryUrl, enableLoadingScreen } = injectAuthConfig();
|
|
295
|
+
const authService = inject(AuthService);
|
|
296
|
+
const redirectUri = buildUrl(inject(WindowRef).getOrigin(), redirectPath);
|
|
297
|
+
const scope = Array.from(new Set(ODX_AUTH_DEFAULT_SCOPES.concat(scopes ?? []))).join(' ');
|
|
298
|
+
if (enableLoadingScreen) {
|
|
299
|
+
AuthLoadingScreenComponent.initialize(authService, inject(DynamicViewService));
|
|
300
|
+
}
|
|
301
|
+
return () => authService.initialize({
|
|
302
|
+
clientId,
|
|
303
|
+
issuer: issuer ?? createAuthHostUrl(environment, 'oauth2/default'),
|
|
304
|
+
scope,
|
|
305
|
+
redirectUri,
|
|
306
|
+
postLogoutRedirectUri: postLogoutRedirectUrl,
|
|
307
|
+
preserveRequestedRoute: true,
|
|
308
|
+
strictDiscoveryDocumentValidation: !discoveryUrl,
|
|
309
|
+
responseType: 'code',
|
|
310
|
+
showDebugInformation: false,
|
|
311
|
+
timeoutFactor,
|
|
312
|
+
waitForTokenInMsec: 1000,
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
function provideAuth(config) {
|
|
316
|
+
return makeEnvironmentProviders([
|
|
317
|
+
provideAuthConfig(config),
|
|
318
|
+
provideAuthLogger(),
|
|
319
|
+
provideOAuthClient({ resourceServer: { sendAccessToken: false, allowedUrls: [] } }),
|
|
320
|
+
provideHttpClient(withInterceptors([authInterceptor])),
|
|
321
|
+
{
|
|
322
|
+
provide: APP_INITIALIZER,
|
|
323
|
+
useFactory: initalizeAuthConfig,
|
|
324
|
+
multi: true,
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
provide: OAuthStorage,
|
|
328
|
+
useFactory: () => injectAuthConfig().storage ?? inject(WindowRef).nativeWindow.localStorage,
|
|
329
|
+
},
|
|
330
|
+
]);
|
|
331
|
+
}
|
|
332
|
+
|
|
210
333
|
class AuthPluginManager {
|
|
211
334
|
constructor() {
|
|
335
|
+
this.authConfig = injectAuthConfig();
|
|
212
336
|
this.errorHandler = inject(ErrorHandler, { optional: true });
|
|
213
337
|
this.plugins = inject(ODX_AUTH_PLUGINS);
|
|
214
338
|
this.result$$ = new BehaviorSubject(null);
|
|
@@ -219,12 +343,11 @@ class AuthPluginManager {
|
|
|
219
343
|
if (this.plugins.length < 1) {
|
|
220
344
|
return of({});
|
|
221
345
|
}
|
|
222
|
-
return authService.
|
|
223
|
-
if (!
|
|
224
|
-
return of({});
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
}), tap((result) => this.result$$.next(result)), take(1));
|
|
346
|
+
return authService.waitForAccessToken$(false).pipe(switchMap((token) => {
|
|
347
|
+
if (!token)
|
|
348
|
+
return of([{}]);
|
|
349
|
+
return combineLatest(this.plugins.map((plugin) => this.runPlugin(authService, plugin)));
|
|
350
|
+
}), map((results) => deepmerge(...results)), tap((result) => this.result$$.next(result)), take(1));
|
|
228
351
|
}
|
|
229
352
|
getResult() {
|
|
230
353
|
return this.result$$.getValue() ?? {};
|
|
@@ -233,6 +356,9 @@ class AuthPluginManager {
|
|
|
233
356
|
this.errorHandler?.handleError(error);
|
|
234
357
|
return of({});
|
|
235
358
|
}
|
|
359
|
+
runPlugin(authService, plugin) {
|
|
360
|
+
return plugin(authService).pipe(isNumber(this.authConfig.pluginTimeout) ? timeout(this.authConfig.pluginTimeout) : tap(), catchError(this.handlePluginError.bind(this)));
|
|
361
|
+
}
|
|
236
362
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AuthPluginManager, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
237
363
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AuthPluginManager, providedIn: 'root' }); }
|
|
238
364
|
}
|
|
@@ -261,12 +387,13 @@ class AuthService {
|
|
|
261
387
|
this.silentRefreshHandler$ = this.isInitialized$$.pipe(filter(Boolean), switchMap(() => this.windowRef.isOnline$), tap((isOnline) => this.updateSilentRefresh(isOnline)));
|
|
262
388
|
this.onAuthStateChange$ = combineLatest([this.oauthService.events.pipe(startWith(null)), this.windowRef.isOnline$, this.onAccessTokenUpdate$]);
|
|
263
389
|
this.isInitialized$ = this.isInitialized$$.pipe(filter(Boolean), distinctUntilChanged());
|
|
264
|
-
this.isRedirecting$ = this.isRedirecting$$.pipe(distinctUntilChanged(), shareReplay({ refCount: true }));
|
|
390
|
+
this.isRedirecting$ = this.isRedirecting$$.pipe(distinctUntilChanged(), shareReplay({ bufferSize: 1, refCount: true }));
|
|
265
391
|
this.isLoading$ = merge(this.isRedirecting$, this.authPluginManager.pluginsLoading$).pipe(distinctUntilChanged());
|
|
266
|
-
this.isAuthenticated$ = this.isInitialized$.pipe(switchMap(() => this.authPluginManager.pluginsReady$), switchMap(() => this.onAuthStateChange$), map(() => this.isAuthenticated()), shareReplay({ refCount: true }));
|
|
267
|
-
this.identityClaims$ = this.isAuthenticated$.pipe(map(() => this.getIdentityClaims()), shareReplay({ refCount: true }));
|
|
392
|
+
this.isAuthenticated$ = this.isInitialized$.pipe(switchMap(() => this.authPluginManager.pluginsReady$), switchMap(() => this.onAuthStateChange$), map(() => this.isAuthenticated()), distinctUntilChanged(), shareReplay({ bufferSize: 1, refCount: true }));
|
|
393
|
+
this.identityClaims$ = this.isAuthenticated$.pipe(map(() => this.getIdentityClaims()), shareReplay({ bufferSize: 1, refCount: true }));
|
|
268
394
|
this.errors$ = this.oauthService.events.pipe(filter((event) => event instanceof OAuthErrorEvent), share());
|
|
269
|
-
this.
|
|
395
|
+
this.onTokenReceived$ = this.oauthService.events.pipe(filter((event) => event.type === 'token_received'), share());
|
|
396
|
+
this.runPlugins();
|
|
270
397
|
this.silentRefreshHandler$.subscribe();
|
|
271
398
|
}
|
|
272
399
|
async initialize(config) {
|
|
@@ -275,7 +402,9 @@ class AuthService {
|
|
|
275
402
|
try {
|
|
276
403
|
await this.oauthService.loadDiscoveryDocument(this.authConfig.discoveryUrl);
|
|
277
404
|
await this.oauthService.tryLogin();
|
|
278
|
-
|
|
405
|
+
if (this.authConfig.refreshTokenOnInit) {
|
|
406
|
+
await this.tryRefreshToken();
|
|
407
|
+
}
|
|
279
408
|
}
|
|
280
409
|
catch (error) {
|
|
281
410
|
if (!(error instanceof HttpErrorResponse || error instanceof OAuthErrorEvent)) {
|
|
@@ -293,6 +422,9 @@ class AuthService {
|
|
|
293
422
|
await this.tryLoadUserProfile();
|
|
294
423
|
await this.routeToRequestedUrl();
|
|
295
424
|
}
|
|
425
|
+
runPlugins() {
|
|
426
|
+
this.authPluginManager.runPlugins(this).subscribe();
|
|
427
|
+
}
|
|
296
428
|
getIssuer() {
|
|
297
429
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
298
430
|
return new URL(this.oauthService.issuer);
|
|
@@ -303,9 +435,6 @@ class AuthService {
|
|
|
303
435
|
signOut(noRedirect) {
|
|
304
436
|
this.oauthService.logOut(noRedirect || !this.getAccessToken());
|
|
305
437
|
}
|
|
306
|
-
async loadUserProfile() {
|
|
307
|
-
await this.oauthService.loadUserProfile();
|
|
308
|
-
}
|
|
309
438
|
async refreshTokens() {
|
|
310
439
|
return this.oauthService.refreshToken();
|
|
311
440
|
}
|
|
@@ -341,6 +470,14 @@ class AuthService {
|
|
|
341
470
|
isAuthorized$(authorizedHandler) {
|
|
342
471
|
return this.isAuthenticated$.pipe(map(() => this.isAuthorized(authorizedHandler)));
|
|
343
472
|
}
|
|
473
|
+
prepareAuthRequest$(req, requireSignIn = false) {
|
|
474
|
+
return this.waitForAccessToken$(requireSignIn).pipe(map((token) => setHttpAuthHeader(req, token)));
|
|
475
|
+
}
|
|
476
|
+
waitForAccessToken$(requireSignIn) {
|
|
477
|
+
const accessToken$ = of(this.getAccessToken()).pipe(filter((token) => !!token && this.isAuthenticated()));
|
|
478
|
+
const waitForAccessToken$ = this.onTokenReceived$.pipe(timeout(this.authConfig.waitForTokenInMs ?? 0), catchError(async () => this.tryRefreshToken().catch(() => null)));
|
|
479
|
+
return this.isInitialized$.pipe(switchMap(() => merge(accessToken$, waitForAccessToken$)), take(1), map(() => this.getAccessToken()), tap((token) => !token && requireSignIn && this.signIn(this.windowRef.location.pathname)));
|
|
480
|
+
}
|
|
344
481
|
async routeToRequestedUrl() {
|
|
345
482
|
if (!this.oauthService.state || !this.oauthService.hasValidAccessToken())
|
|
346
483
|
return;
|
|
@@ -354,15 +491,15 @@ class AuthService {
|
|
|
354
491
|
this.windowRef.location.assign(uri);
|
|
355
492
|
this.isRedirecting$$.next(true);
|
|
356
493
|
}
|
|
357
|
-
async
|
|
358
|
-
if (!this.authConfig.
|
|
494
|
+
async tryLoadUserProfile() {
|
|
495
|
+
if (!this.authConfig.loadUserProfile || !this.isAuthenticated())
|
|
359
496
|
return;
|
|
360
|
-
await this.oauthService.
|
|
497
|
+
await this.oauthService.loadUserProfile().catch(() => null);
|
|
361
498
|
}
|
|
362
|
-
async
|
|
363
|
-
if (!this.
|
|
499
|
+
async tryRefreshToken() {
|
|
500
|
+
if (!this.getRefreshToken())
|
|
364
501
|
return;
|
|
365
|
-
await this.
|
|
502
|
+
await this.oauthService.refreshToken();
|
|
366
503
|
}
|
|
367
504
|
assertAudience(clientId) {
|
|
368
505
|
const tokenClientId = this.getIdentityClaims()?.aud;
|
|
@@ -386,50 +523,56 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
386
523
|
args: [{ providedIn: 'root' }]
|
|
387
524
|
}], ctorParameters: function () { return []; } });
|
|
388
525
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
526
|
+
function userLanguageLoader(languageSelector = (claims) => claims?.preferredLanguage) {
|
|
527
|
+
return () => {
|
|
528
|
+
return inject(AuthService).identityClaims$.pipe(map(languageSelector), map((value) => (isNonEmptyString(value) ? value : undefined)));
|
|
529
|
+
};
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
const AUTH_HTTP_HEADER = 'Authorization';
|
|
533
|
+
const ODX_AUTH_DEFAULT_SCOPES = ['openid', 'profile', 'email', 'offline_access'];
|
|
534
|
+
const ODX_AUTH_HOSTS = {
|
|
535
|
+
dev: 'https://dev.login.draeger.com',
|
|
536
|
+
stage: 'https://test.login.draeger.com',
|
|
537
|
+
prod: 'https://login.draeger.com',
|
|
396
538
|
};
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
539
|
+
const ODX_AUTH_USER_PROFILE_HOSTS = {
|
|
540
|
+
dev: 'https://lemon-ocean-04a922703.3.azurestaticapps.net',
|
|
541
|
+
stage: 'https://purple-cliff-0e61c5703.3.azurestaticapps.net',
|
|
542
|
+
prod: 'https://id.draeger.com',
|
|
543
|
+
};
|
|
544
|
+
const { AuthDefaultConfig, AuthConfig, injectAuthConfig, provideAuthConfig } = createConfigTokens('Auth', '@odx/auth', {
|
|
545
|
+
environment: 'prod',
|
|
546
|
+
redirectPath: 'login/callback',
|
|
547
|
+
allowedUrls: [],
|
|
548
|
+
timeoutFactor: 0.75,
|
|
549
|
+
maxOfflineTime: 24 * 60 * 60,
|
|
550
|
+
loadUserProfile: false,
|
|
551
|
+
errorHandler: (error) => {
|
|
552
|
+
throw error;
|
|
553
|
+
},
|
|
554
|
+
createInitials,
|
|
555
|
+
resolveEmail,
|
|
556
|
+
resolveUsername,
|
|
557
|
+
plugins: [],
|
|
558
|
+
defaultAuthorizedHandler: null,
|
|
559
|
+
enableLoadingScreen: true,
|
|
560
|
+
loadingScreenMessage: null,
|
|
561
|
+
waitForTokenInMs: 1000,
|
|
562
|
+
});
|
|
406
563
|
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
AuthLoadingScreenComponent.instance?.destroy();
|
|
420
|
-
AuthLoadingScreenComponent.instance = null;
|
|
421
|
-
}
|
|
422
|
-
});
|
|
423
|
-
}
|
|
424
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AuthLoadingScreenComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
425
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: AuthLoadingScreenComponent, isStandalone: true, selector: "div.odx-auth-loading-screen", host: { properties: { "@hostAnimation": "true" } }, ngImport: i0, template: "<div class=\"odx-auth-loading-screen__content\" odxLayout=\"grid 12 horizontal-center vertical-center gap-small\">\n <odx-logo size=\"large\"></odx-logo>\n <odx-circular-progress class=\"odx-auth-loading-screen__spinner\" value=\"-1\" size=\"medium\" stroke=\"3\">\n <odx-icon [name]=\"icon$ | async\" iconSet=\"core\"></odx-icon>\n </odx-circular-progress>\n <p class=\"odx-auth-loading-screen__message\" *ngIf=\"authConfig.loadingScreenMessage as content\">\n <ng-template [odxDynamicView]=\"content\"></ng-template>\n </p>\n</div>\n", styles: ["@keyframes odx-auth-loading-screen-animation{0%{opacity:0;transform:translate(-50%,-50%) scale(.9)}to{opacity:1;transform:translate(-50%,-50%)}}.odx-auth-loading-screen{--odx-c-highlight: var(--odx-c-primary);background-color:var(--odx-c-background-content);position:fixed;z-index:var(--odx-v-layer-5);inset:0}.odx-auth-loading-screen__content{top:50%;left:50%;transform:translate(-50%,-50%);position:absolute;animation:odx-auth-loading-screen-animation .75s ease}.odx-auth-loading-screen__message{text-align:center}.odx-auth-loading-screen__spinner{position:relative}.odx-auth-loading-screen__spinner .odx-icon{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "component", type: IconComponent, selector: "odx-icon", inputs: ["inline", "size", "name", "iconSet"] }, { kind: "directive", type: LogoDirective, selector: "odx-logo", inputs: ["size", "variant"] }, { kind: "component", type: CircularProgressComponent, selector: "odx-circular-progress", inputs: ["stroke", "size", "value"] }, { kind: "directive", type: DynamicViewDirective, selector: "ng-template[odxDynamicView]", inputs: ["odxDynamicView", "odxDynamicViewInjector", "odxDynamicViewContext"] }], animations: [trigger('hostAnimation', [transition(':leave', useAnimation(fadeOut()))])], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
426
|
-
}
|
|
427
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AuthLoadingScreenComponent, decorators: [{
|
|
428
|
-
type: Component,
|
|
429
|
-
args: [{ standalone: true, selector: 'div.odx-auth-loading-screen', imports: [CommonModule, ButtonComponent, IconComponent, LogoDirective, CircularProgressComponent, DynamicViewDirective], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
|
|
430
|
-
'[@hostAnimation]': 'true',
|
|
431
|
-
}, animations: [trigger('hostAnimation', [transition(':leave', useAnimation(fadeOut()))])], template: "<div class=\"odx-auth-loading-screen__content\" odxLayout=\"grid 12 horizontal-center vertical-center gap-small\">\n <odx-logo size=\"large\"></odx-logo>\n <odx-circular-progress class=\"odx-auth-loading-screen__spinner\" value=\"-1\" size=\"medium\" stroke=\"3\">\n <odx-icon [name]=\"icon$ | async\" iconSet=\"core\"></odx-icon>\n </odx-circular-progress>\n <p class=\"odx-auth-loading-screen__message\" *ngIf=\"authConfig.loadingScreenMessage as content\">\n <ng-template [odxDynamicView]=\"content\"></ng-template>\n </p>\n</div>\n", styles: ["@keyframes odx-auth-loading-screen-animation{0%{opacity:0;transform:translate(-50%,-50%) scale(.9)}to{opacity:1;transform:translate(-50%,-50%)}}.odx-auth-loading-screen{--odx-c-highlight: var(--odx-c-primary);background-color:var(--odx-c-background-content);position:fixed;z-index:var(--odx-v-layer-5);inset:0}.odx-auth-loading-screen__content{top:50%;left:50%;transform:translate(-50%,-50%);position:absolute;animation:odx-auth-loading-screen-animation .75s ease}.odx-auth-loading-screen__message{text-align:center}.odx-auth-loading-screen__spinner{position:relative}.odx-auth-loading-screen__spinner .odx-icon{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}\n"] }]
|
|
432
|
-
}] });
|
|
564
|
+
var translations = {
|
|
565
|
+
en: {
|
|
566
|
+
userProfileLink: 'My profile',
|
|
567
|
+
signInButtonText: 'Sign in',
|
|
568
|
+
signOutButtonText: 'Sign out',
|
|
569
|
+
},
|
|
570
|
+
de: {
|
|
571
|
+
userProfileLink: 'Mein Profil',
|
|
572
|
+
signInButtonText: 'Einloggen',
|
|
573
|
+
signOutButtonText: 'Ausloggen',
|
|
574
|
+
},
|
|
575
|
+
};
|
|
433
576
|
|
|
434
577
|
class AuthActionDirective {
|
|
435
578
|
constructor() {
|
|
@@ -517,7 +660,7 @@ class AuthComponent {
|
|
|
517
660
|
};
|
|
518
661
|
}
|
|
519
662
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AuthComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
520
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: AuthComponent, isStandalone: true, selector: "odx-auth", providers: [provideTranslations(translations)], ngImport: i0, template: "<odx-action-group>\n <ng-template [ngrxLet]=\"{ idClaims: authService.identityClaims$, isAuthenticated: authService.isAuthenticated$ }\" let-vm>\n <ng-template [ngIf]=\"vm.isAuthenticated\" [ngIfElse]=\"notAuthenticated\">\n <button odxButton [odxDropdown]=\"userProfileMenu\" [odxDropdownOptions]=\"dropdownOptions\" data-testid=\"odx-auth-user-profile-button\">\n <ng-template [ngTemplateOutlet]=\"userAvatar\"></ng-template>\n </button>\n <ng-template #userProfileMenu>\n <odx-area-header class=\"odx-padding-x-12\" size=\"small\">\n <ng-template [ngTemplateOutlet]=\"userAvatar\" ngProjectAs=\"odx-avatar\"></ng-template>\n {{ vm.idClaims?.username }}\n <odx-area-header-subtitle>\n {{ vm.idClaims?.email }}\n </odx-area-header-subtitle>\n </odx-area-header>\n <ng-content></ng-content>\n <odx-auth-actions [claims]=\"vm.idClaims\"></odx-auth-actions>\n <div class=\"odx-margin-top-12\" odxLayout=\"flex vertical-center\">\n <odx-logo odxLayout=\"auto\" class=\"odx-margin-left-12 odx-margin-right-auto\"></odx-logo>\n <button odxButton odxAuthSignOut variant=\"ghost\" data-testid=\"odx-auth-sign-out-button\">\n {{ 'signOutButtonText' | odxTranslate | async }}\n <odx-icon name=\"logout\" alignRight></odx-icon>\n </button>\n </div>\n </ng-template>\n </ng-template>\n <ng-template #notAuthenticated>\n <button class=\"odx-auth-sign-in\" odxButton odxAuthSignIn variant=\"secondary\" data-testid=\"odx-auth-sign-in-button\">\n <odx-icon name=\"user\" alignLeft></odx-icon>\n {{ 'signInButtonText' | odxTranslate | async }}\n </button>\n </ng-template>\n <ng-template #userAvatar>\n <odx-avatar class=\"odx-auth-user-avatar\">\n {{ vm.idClaims?.initials ?? '' }}\n </odx-avatar>\n </ng-template>\n </ng-template>\n</odx-action-group>\n", styles: [".odx-auth-user-profile .odx-dropdown__inner>.odx-area-header{max-width:max(360px,25vw);min-width:296px}.odx-auth-actions{display:block;margin-top:calc(var(--odx-vertical-rythm-base-size) * .5);margin-bottom:calc(var(--odx-vertical-rythm-base-size) * .5);margin-right:calc(var(--odx-vertical-rythm-base-size) * .25);margin-left:calc(var(--odx-vertical-rythm-base-size) * .25)}\n"], dependencies: [{ kind: "ngmodule", type: CoreModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "directive", type: i2$1.LetDirective, selector: "[ngrxLet]", inputs: ["ngrxLet", "ngrxLetSuspenseTpl"] }, { kind: "ngmodule", type: AreaHeaderModule }, { kind: "component", type: i3$1.AreaHeaderComponent, selector: "odx-area-header", inputs: ["size"] }, { kind: "directive", type: i3$1.AreaHeaderSubtitleDirective, selector: "odx-area-header-subtitle" }, { kind: "component", type: i4.AvatarComponent, selector: "odx-avatar", inputs: ["size", "variant"] }, { kind: "component", type: i5.ActionGroupComponent, selector: "odx-action-group", inputs: ["reverse"] }, { kind: "component", type: i6.ButtonComponent, selector: "button[odxButton], a[odxButton]", inputs: ["variant", "size"] }, { kind: "component", type: i3.IconComponent, selector: "odx-icon", inputs: ["inline", "size", "name", "iconSet"] }, { kind: "ngmodule", type: DropdownModule }, { kind: "directive", type: i8.DropdownDirective, selector: "[odxDropdown]", inputs: ["odxDropdown", "odxDropdownDisabled", "odxDropdownShowLoader", "odxDropdownClickOutsideActive", "odxDropdownOptions", "odxDropdownReferenceElement", "odxDropdownTriggerElement", "odxDropdownHost", "odxDropdownOpenTrigger", "odxDropdownCloseTrigger"], outputs: ["odxDropdownBeforeOpen", "odxDropdownAfterOpen", "odxDropdownBeforeClose", "odxDropdownAfterClose"], exportAs: ["odxDropdown"] }, { kind: "ngmodule", type: HeaderModule }, { kind: "directive", type: LogoDirective, selector: "odx-logo", inputs: ["size", "variant"] }, { kind: "directive", type: SignInDirective, selector: "[odxButton][odxAuthSignIn]", outputs: ["odxAuthSignIn"] }, { kind: "directive", type: SignOutDirective, selector: "[odxButton][odxAuthSignOut]", outputs: ["odxAuthSignOut"] }, { kind: "ngmodule", type: LoadingSpinnerModule }, { kind: "component", type: AuthActionsComponent, selector: "odx-auth-actions", inputs: ["claims"] }, { kind: "pipe", type: TranslatePipe, name: "odxTranslate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
663
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: AuthComponent, isStandalone: true, selector: "odx-auth", providers: [provideTranslations(translations)], ngImport: i0, template: "<odx-action-group>\n <ng-template [ngrxLet]=\"{ idClaims: authService.identityClaims$, isAuthenticated: authService.isAuthenticated$ }\" let-vm>\n <ng-template [ngIf]=\"vm.isAuthenticated\" [ngIfElse]=\"notAuthenticated\">\n <button odxButton [odxDropdown]=\"userProfileMenu\" [odxDropdownOptions]=\"dropdownOptions\" data-testid=\"odx-auth-user-profile-button\">\n <ng-template [ngTemplateOutlet]=\"userAvatar\"></ng-template>\n </button>\n <ng-template #userProfileMenu>\n <odx-area-header class=\"odx-padding-x-12\" size=\"small\">\n <ng-template [ngTemplateOutlet]=\"userAvatar\" ngProjectAs=\"odx-avatar\"></ng-template>\n {{ vm.idClaims?.username }}\n <odx-area-header-subtitle>\n {{ vm.idClaims?.email }}\n </odx-area-header-subtitle>\n </odx-area-header>\n <ng-content></ng-content>\n <odx-auth-actions [claims]=\"vm.idClaims\"></odx-auth-actions>\n <div class=\"odx-margin-top-12\" odxLayout=\"flex vertical-center\">\n <odx-logo odxLayout=\"auto\" class=\"odx-margin-left-12 odx-margin-right-auto\"></odx-logo>\n <button odxButton odxAuthSignOut variant=\"ghost\" data-testid=\"odx-auth-sign-out-button\">\n {{ 'signOutButtonText' | odxTranslate | async }}\n <odx-icon name=\"logout\" alignRight></odx-icon>\n </button>\n </div>\n </ng-template>\n </ng-template>\n <ng-template #notAuthenticated>\n <button class=\"odx-auth-sign-in\" odxButton odxAuthSignIn variant=\"secondary\" data-testid=\"odx-auth-sign-in-button\">\n <odx-icon name=\"user\" alignLeft></odx-icon>\n {{ 'signInButtonText' | odxTranslate | async }}\n </button>\n </ng-template>\n <ng-template #userAvatar>\n <odx-avatar class=\"odx-auth-user-avatar\">\n {{ vm.idClaims?.initials ?? '' }}\n </odx-avatar>\n </ng-template>\n </ng-template>\n</odx-action-group>\n", styles: [".odx-auth-user-profile .odx-dropdown__inner>.odx-area-header{max-width:max(360px,25vw);min-width:296px}.odx-auth-actions{display:block;margin-top:calc(var(--odx-vertical-rythm-base-size) * .5);margin-bottom:calc(var(--odx-vertical-rythm-base-size) * .5);margin-right:calc(var(--odx-vertical-rythm-base-size) * .25);margin-left:calc(var(--odx-vertical-rythm-base-size) * .25)}\n"], dependencies: [{ kind: "ngmodule", type: CoreModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "directive", type: i2$1.LetDirective, selector: "[ngrxLet]", inputs: ["ngrxLet", "ngrxLetSuspenseTpl"] }, { kind: "ngmodule", type: AreaHeaderModule }, { kind: "component", type: i3$1.AreaHeaderComponent, selector: "odx-area-header", inputs: ["size"] }, { kind: "directive", type: i3$1.AreaHeaderSubtitleDirective, selector: "odx-area-header-subtitle" }, { kind: "component", type: i4.AvatarComponent, selector: "odx-avatar", inputs: ["size", "variant"] }, { kind: "component", type: i5.ActionGroupComponent, selector: "odx-action-group", inputs: ["reverse"] }, { kind: "component", type: i6.ButtonComponent, selector: "button[odxButton], a[odxButton]", inputs: ["variant", "size"] }, { kind: "component", type: i3.IconComponent, selector: "odx-icon", inputs: ["inline", "size", "name", "iconSet", "identifier"] }, { kind: "ngmodule", type: DropdownModule }, { kind: "directive", type: i8.DropdownDirective, selector: "[odxDropdown]", inputs: ["odxDropdown", "odxDropdownDisabled", "odxDropdownShowLoader", "odxDropdownClickOutsideActive", "odxDropdownOptions", "odxDropdownReferenceElement", "odxDropdownTriggerElement", "odxDropdownHost", "odxDropdownOpenTrigger", "odxDropdownCloseTrigger"], outputs: ["odxDropdownBeforeOpen", "odxDropdownAfterOpen", "odxDropdownBeforeClose", "odxDropdownAfterClose"], exportAs: ["odxDropdown"] }, { kind: "ngmodule", type: HeaderModule }, { kind: "directive", type: LogoDirective, selector: "odx-logo", inputs: ["size", "variant"] }, { kind: "directive", type: SignInDirective, selector: "[odxButton][odxAuthSignIn]", outputs: ["odxAuthSignIn"] }, { kind: "directive", type: SignOutDirective, selector: "[odxButton][odxAuthSignOut]", outputs: ["odxAuthSignOut"] }, { kind: "ngmodule", type: LoadingSpinnerModule }, { kind: "component", type: AuthActionsComponent, selector: "odx-auth-actions", inputs: ["claims"] }, { kind: "pipe", type: TranslatePipe, name: "odxTranslate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
521
664
|
}
|
|
522
665
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AuthComponent, decorators: [{
|
|
523
666
|
type: Component,
|
|
@@ -571,9 +714,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
571
714
|
}] } });
|
|
572
715
|
|
|
573
716
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
574
|
-
function authGuard(authorizedHandler, redirectTo) {
|
|
717
|
+
function authGuard(authorizedHandler, redirectTo, isExternal = false) {
|
|
575
718
|
return (_, state) => {
|
|
576
719
|
const authService = inject(AuthService);
|
|
720
|
+
const windowRef = inject(WindowRef);
|
|
577
721
|
const router = inject(Router, { optional: true });
|
|
578
722
|
return authService.isAuthenticated$.pipe(switchMap((isAuthenticated) => {
|
|
579
723
|
if (!isAuthenticated) {
|
|
@@ -585,7 +729,12 @@ function authGuard(authorizedHandler, redirectTo) {
|
|
|
585
729
|
if (isAuthorized || !router)
|
|
586
730
|
return;
|
|
587
731
|
if (isString(redirectTo)) {
|
|
588
|
-
|
|
732
|
+
if (isExternal) {
|
|
733
|
+
windowRef.location.assign(redirectTo);
|
|
734
|
+
}
|
|
735
|
+
else {
|
|
736
|
+
router.navigateByUrl(redirectTo);
|
|
737
|
+
}
|
|
589
738
|
}
|
|
590
739
|
else if (Array.isArray(redirectTo)) {
|
|
591
740
|
router.navigate(redirectTo);
|
|
@@ -608,103 +757,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
608
757
|
}]
|
|
609
758
|
}] });
|
|
610
759
|
|
|
611
|
-
const coreIdentityPlugin = () => {
|
|
612
|
-
const { resolveEmail, resolveUsername, createInitials } = injectAuthConfig();
|
|
613
|
-
return (authService) => {
|
|
614
|
-
const claims = authService.getRawIdentityClaims();
|
|
615
|
-
if (!claims)
|
|
616
|
-
return of({});
|
|
617
|
-
const username = resolveUsername(claims);
|
|
618
|
-
return of({ email: resolveEmail(claims), username, initials: createInitials(username) });
|
|
619
|
-
};
|
|
620
|
-
};
|
|
621
|
-
|
|
622
|
-
const userProfileUrlPlugin = () => {
|
|
623
|
-
const { environment, userProfileUrl } = injectAuthConfig();
|
|
624
|
-
return () => {
|
|
625
|
-
return of({ userProfileUrl: userProfileUrl ?? DEFAULT_USER_PROFILE_URLS[environment] });
|
|
626
|
-
};
|
|
627
|
-
};
|
|
628
|
-
|
|
629
|
-
function configureInterceptor() {
|
|
630
|
-
const { allowedUrls } = injectAuthConfig();
|
|
631
|
-
const urls = allowedUrls.filter(Boolean);
|
|
632
|
-
return {
|
|
633
|
-
resourceServer: {
|
|
634
|
-
customUrlValidation: (url) => urls.some((allowedUrl) => (isString(allowedUrl) ? url.startsWith(allowedUrl) : !!url.match(allowedUrl))),
|
|
635
|
-
sendAccessToken: true,
|
|
636
|
-
},
|
|
637
|
-
};
|
|
638
|
-
}
|
|
639
|
-
function initializeAuthErrorHandlers() {
|
|
640
|
-
const authService = inject(AuthService);
|
|
641
|
-
const handler = handleAuthError(inject(ODX_AUTH_ERROR_HANDLERS));
|
|
642
|
-
authService.errors$.pipe(tap((error) => handler(error))).subscribe();
|
|
643
|
-
}
|
|
644
|
-
function initalizeAuthConfig() {
|
|
645
|
-
const { clientId, scopes, redirectPath, environment, postLogoutRedirectUrl, issuer, timeoutFactor, discoveryUrl, enableLoadingScreen } = injectAuthConfig();
|
|
646
|
-
const authService = inject(AuthService);
|
|
647
|
-
const origin = inject(WindowRef).getOrigin();
|
|
648
|
-
const scope = Array.from(new Set(DEFAULT_AUTH_SCOPES.concat(scopes ?? []))).join(' ');
|
|
649
|
-
if (enableLoadingScreen) {
|
|
650
|
-
AuthLoadingScreenComponent.initialize(authService, inject(DynamicViewService));
|
|
651
|
-
}
|
|
652
|
-
return () => authService.initialize({
|
|
653
|
-
clientId,
|
|
654
|
-
issuer: issuer ?? `${DEFAULT_OKTA_URLS[environment]}/oauth2/default`,
|
|
655
|
-
scope,
|
|
656
|
-
redirectUri: buildUrl(origin, redirectPath),
|
|
657
|
-
postLogoutRedirectUri: postLogoutRedirectUrl,
|
|
658
|
-
preserveRequestedRoute: true,
|
|
659
|
-
strictDiscoveryDocumentValidation: !discoveryUrl,
|
|
660
|
-
responseType: 'code',
|
|
661
|
-
showDebugInformation: environment === 'dev',
|
|
662
|
-
timeoutFactor,
|
|
663
|
-
});
|
|
664
|
-
}
|
|
665
|
-
function provideAuth(config) {
|
|
666
|
-
return makeEnvironmentProviders([
|
|
667
|
-
provideAuthConfig(config),
|
|
668
|
-
provideOAuthClient(),
|
|
669
|
-
{
|
|
670
|
-
provide: OAuthModuleConfig,
|
|
671
|
-
useFactory: configureInterceptor,
|
|
672
|
-
},
|
|
673
|
-
{
|
|
674
|
-
provide: ENVIRONMENT_INITIALIZER,
|
|
675
|
-
useValue: initializeAuthErrorHandlers,
|
|
676
|
-
multi: true,
|
|
677
|
-
},
|
|
678
|
-
{
|
|
679
|
-
provide: ODX_AUTH_ERROR_HANDLERS,
|
|
680
|
-
useFactory: () => [offlineAuthErrorHandler, injectAuthConfig().errorHandler],
|
|
681
|
-
},
|
|
682
|
-
{
|
|
683
|
-
provide: APP_INITIALIZER,
|
|
684
|
-
useFactory: initalizeAuthConfig,
|
|
685
|
-
multi: true,
|
|
686
|
-
},
|
|
687
|
-
{
|
|
688
|
-
provide: OAuthStorage,
|
|
689
|
-
useFactory: () => injectAuthConfig().storage ?? inject(WindowRef).nativeWindow.localStorage,
|
|
690
|
-
},
|
|
691
|
-
{
|
|
692
|
-
provide: ODX_AUTH_CORE_PLUGINS,
|
|
693
|
-
useValue: [coreIdentityPlugin, userProfileUrlPlugin],
|
|
694
|
-
},
|
|
695
|
-
]);
|
|
696
|
-
}
|
|
697
|
-
|
|
698
760
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
699
|
-
function unauthGuard(authorizedHandler, redirectTo) {
|
|
761
|
+
function unauthGuard(authorizedHandler, redirectTo, isExternal = false) {
|
|
700
762
|
return (_) => {
|
|
701
763
|
const authService = inject(AuthService);
|
|
702
764
|
const router = inject(Router, { optional: true });
|
|
765
|
+
const windowRef = inject(WindowRef);
|
|
703
766
|
return authService.isAuthenticated$.pipe(map(() => !authService.isAuthorized(authorizedHandler)), tap((isUnauthorized) => {
|
|
704
767
|
if (isUnauthorized || !router)
|
|
705
768
|
return;
|
|
706
769
|
if (isString(redirectTo)) {
|
|
707
|
-
|
|
770
|
+
if (isExternal) {
|
|
771
|
+
windowRef.location.assign(redirectTo);
|
|
772
|
+
}
|
|
773
|
+
else {
|
|
774
|
+
router.navigateByUrl(redirectTo);
|
|
775
|
+
}
|
|
708
776
|
}
|
|
709
777
|
else if (Array.isArray(redirectTo)) {
|
|
710
778
|
router.navigate(redirectTo);
|
|
@@ -717,5 +785,5 @@ function unauthGuard(authorizedHandler, redirectTo) {
|
|
|
717
785
|
* Generated bundle index. Do not edit.
|
|
718
786
|
*/
|
|
719
787
|
|
|
720
|
-
export { AuthActionDirective, AuthActionsComponent, AuthComponent, AuthConfig, AuthDefaultConfig, AuthDirective, AuthHttpCache, AuthLoadingScreenComponent, AuthModule, AuthPluginManager, AuthService,
|
|
788
|
+
export { AUTH_HTTP_HEADER, AuthActionDirective, AuthActionsComponent, AuthComponent, AuthConfig, AuthDefaultConfig, AuthDirective, AuthEnvironment, AuthHttpCache, AuthLoadingScreenComponent, AuthModule, AuthPluginManager, AuthService, ODX_AUTH_CORE_PLUGINS, ODX_AUTH_DEFAULT_SCOPES, ODX_AUTH_ERROR_HANDLERS, ODX_AUTH_HOSTS, ODX_AUTH_HTTP_CACHE_STORAGE, ODX_AUTH_HTTP_CACHE_STORAGE_CLIENT, ODX_AUTH_PLUGINS, ODX_AUTH_USER_PROFILE_HOSTS, SignInDirective, SignOutDirective, authGuard, authInterceptor, coreDebugPlugin, coreIdentityPlugin, createAuthHostUrl, createInitials, handleAuthError, handleOAuthEvent, initalizeAuthConfig, initializeAuthErrorHandlers, injectAuthConfig, offlineAuthErrorHandler, provideAuth, provideAuthConfig, provideAuthLogger, resolveEmail, resolveUsername, setHttpAuthHeader, unauthGuard, userLanguageLoader, userProfileUrlPlugin };
|
|
721
789
|
//# sourceMappingURL=odx-auth.mjs.map
|