@odx/auth 2.0.0 → 3.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/README.md +27 -1
- package/esm2020/index.mjs +2 -1
- package/esm2020/lib/auth.component.mjs +4 -4
- package/esm2020/lib/auth.config.mjs +19 -4
- package/esm2020/lib/auth.directive.mjs +2 -2
- package/esm2020/lib/auth.guard.mjs +17 -6
- package/esm2020/lib/auth.providers.mjs +7 -2
- package/esm2020/lib/auth.service.mjs +22 -15
- package/esm2020/lib/auth.typings.mjs +1 -1
- package/esm2020/lib/directives/auth-action.directive.mjs +24 -0
- package/esm2020/lib/directives/index.mjs +2 -1
- package/esm2020/lib/directives/sign-in.directive.mjs +10 -19
- package/esm2020/lib/directives/sign-out.directive.mjs +10 -19
- package/esm2020/lib/helpers/create-inititals.mjs +3 -3
- package/esm2020/lib/helpers/index.mjs +3 -2
- package/esm2020/lib/helpers/resolve-email.mjs +14 -0
- package/esm2020/lib/helpers/resolve-username.mjs +14 -0
- package/esm2020/lib/models/auth-http-cache.mjs +34 -0
- package/esm2020/lib/models/auth-plugin-manager.mjs +29 -0
- package/esm2020/lib/models/authorized-handler.mjs +1 -1
- package/esm2020/lib/models/index.mjs +3 -1
- package/esm2020/lib/plugins/core-identity.plugin.mjs +13 -0
- package/esm2020/lib/plugins/index.mjs +2 -0
- package/esm2020/plugins/service-connect/index.mjs +8 -0
- package/esm2020/plugins/service-connect/lib/dtos/get-service-connect-rights-response.dto.mjs +2 -0
- package/esm2020/plugins/service-connect/lib/dtos/index.mjs +2 -0
- package/esm2020/plugins/service-connect/lib/helpers/build-service-connect-url.mjs +9 -0
- package/esm2020/plugins/service-connect/lib/helpers/has-roles-or-rights-handler.mjs +5 -0
- package/esm2020/plugins/service-connect/lib/helpers/has-roles-or-rights.mjs +5 -0
- package/esm2020/plugins/service-connect/lib/helpers/index.mjs +4 -0
- package/esm2020/plugins/service-connect/lib/service-connect-rights.directive.mjs +32 -0
- package/esm2020/plugins/service-connect/lib/service-connect-rights.guard.mjs +7 -0
- package/esm2020/plugins/service-connect/lib/service-connect-rights.plugin.mjs +29 -0
- package/esm2020/plugins/service-connect/lib/service-connect.config.mjs +14 -0
- package/esm2020/plugins/service-connect/lib/service-connect.typings.mjs +2 -0
- package/esm2020/plugins/service-connect/odx-auth-plugins-service-connect.mjs +5 -0
- package/fesm2015/odx-auth-plugins-service-connect.mjs +99 -0
- package/fesm2015/odx-auth-plugins-service-connect.mjs.map +1 -0
- package/fesm2015/odx-auth.mjs +196 -73
- package/fesm2015/odx-auth.mjs.map +1 -1
- package/fesm2020/odx-auth-plugins-service-connect.mjs +97 -0
- package/fesm2020/odx-auth-plugins-service-connect.mjs.map +1 -0
- package/fesm2020/odx-auth.mjs +188 -71
- package/fesm2020/odx-auth.mjs.map +1 -1
- package/index.d.ts +1 -0
- package/lib/auth.component.d.ts +1 -1
- package/lib/auth.config.d.ts +11 -3
- package/lib/auth.guard.d.ts +2 -2
- package/lib/auth.service.d.ts +9 -9
- package/lib/auth.typings.d.ts +5 -1
- package/lib/directives/auth-action.directive.d.ts +12 -0
- package/lib/directives/index.d.ts +1 -0
- package/lib/directives/sign-in.directive.d.ts +4 -7
- package/lib/directives/sign-out.directive.d.ts +4 -7
- package/lib/helpers/create-inititals.d.ts +1 -1
- package/lib/helpers/index.d.ts +2 -1
- package/lib/helpers/resolve-email.d.ts +1 -0
- package/lib/helpers/resolve-username.d.ts +1 -0
- package/lib/models/auth-http-cache.d.ts +11 -0
- package/lib/models/auth-plugin-manager.d.ts +15 -0
- package/lib/models/authorized-handler.d.ts +1 -2
- package/lib/models/index.d.ts +2 -0
- package/lib/plugins/core-identity.plugin.d.ts +11 -0
- package/lib/plugins/index.d.ts +1 -0
- package/package.json +11 -2
- package/plugins/service-connect/README.md +3 -0
- package/plugins/service-connect/index.d.ts +7 -0
- package/plugins/service-connect/lib/dtos/get-service-connect-rights-response.dto.d.ts +3 -0
- package/plugins/service-connect/lib/dtos/index.d.ts +1 -0
- package/plugins/service-connect/lib/helpers/build-service-connect-url.d.ts +3 -0
- package/plugins/service-connect/lib/helpers/has-roles-or-rights-handler.d.ts +3 -0
- package/plugins/service-connect/lib/helpers/has-roles-or-rights.d.ts +5 -0
- package/plugins/service-connect/lib/helpers/index.d.ts +3 -0
- package/plugins/service-connect/lib/service-connect-rights.directive.d.ts +9 -0
- package/plugins/service-connect/lib/service-connect-rights.guard.d.ts +3 -0
- package/plugins/service-connect/lib/service-connect-rights.plugin.d.ts +7 -0
- package/plugins/service-connect/lib/service-connect.config.d.ts +11 -0
- package/plugins/service-connect/lib/service-connect.typings.d.ts +9 -0
- package/esm2020/lib/helpers/parse-identity-claims.mjs +0 -13
- package/lib/helpers/parse-identity-claims.d.ts +0 -2
package/fesm2020/odx-auth.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, Injectable,
|
|
2
|
+
import { InjectionToken, inject, Injectable, Directive, EventEmitter, Output, HostListener, Component, ChangeDetectionStrategy, ViewEncapsulation, Input, NgModule, EnvironmentInjector, makeEnvironmentProviders, ENVIRONMENT_INITIALIZER, APP_INITIALIZER } from '@angular/core';
|
|
3
3
|
import { WindowRef, CoreModule } from '@odx/angular';
|
|
4
4
|
import * as i3 from '@odx/angular/components/area-header';
|
|
5
5
|
import { AreaHeaderModule } from '@odx/angular/components/area-header';
|
|
@@ -9,13 +9,14 @@ import { HeaderModule } from '@odx/angular/components/header';
|
|
|
9
9
|
import * as i1 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
|
-
import { createConfigTokens, untilDestroyed, Position,
|
|
12
|
+
import { isString, createConfigTokens, untilDestroyed, Position, buildUrl } from '@odx/angular/utils';
|
|
13
13
|
import { HttpErrorResponse } from '@angular/common/http';
|
|
14
14
|
import { Router } from '@angular/router';
|
|
15
15
|
import { fromEvents } from '@odx/angular/rxjs';
|
|
16
16
|
import { OAuthService, OAuthErrorEvent, provideOAuthClient, OAuthModuleConfig, OAuthStorage } from 'angular-oauth2-oidc';
|
|
17
|
+
import { deepmerge } from 'deepmerge-ts';
|
|
17
18
|
import jwtDecode from 'jwt-decode';
|
|
18
|
-
import { BehaviorSubject,
|
|
19
|
+
import { BehaviorSubject, filter, map, distinctUntilChanged, share, of, switchMap, combineLatest, tap, take, fromEvent, startWith, shareReplay, merge } from 'rxjs';
|
|
19
20
|
import * as i1$1 from '@angular/common';
|
|
20
21
|
import { NgIf } from '@angular/common';
|
|
21
22
|
import * as i2 from '@ngrx/component';
|
|
@@ -24,12 +25,62 @@ import * as i5 from '@odx/angular/components/action-group';
|
|
|
24
25
|
import * as i6 from '@odx/angular/components/button';
|
|
25
26
|
import * as i7 from '@odx/angular/components/icon';
|
|
26
27
|
|
|
28
|
+
function createInitials(value) {
|
|
29
|
+
if (!value)
|
|
30
|
+
return '';
|
|
31
|
+
const parts = value.trim().split(' ');
|
|
32
|
+
return parts.reduce((initials, curr, index) => {
|
|
33
|
+
if (index === 0 || index === parts.length - 1) {
|
|
34
|
+
initials += curr[0].toUpperCase();
|
|
35
|
+
}
|
|
36
|
+
return initials;
|
|
37
|
+
}, '');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function resolveEmail(claims) {
|
|
41
|
+
if (isString(claims['email'])) {
|
|
42
|
+
return claims['email'];
|
|
43
|
+
}
|
|
44
|
+
if (isString(claims['email_address'])) {
|
|
45
|
+
return claims['email_address'];
|
|
46
|
+
}
|
|
47
|
+
if (Array.isArray(claims['emails']) && isString(claims['emails'][0])) {
|
|
48
|
+
return claims['emails'][0];
|
|
49
|
+
}
|
|
50
|
+
return '';
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function resolveUsername(claims) {
|
|
54
|
+
if (isString(claims['firstname']) && isString(claims['lastname'])) {
|
|
55
|
+
return `${claims['firstname']} ${claims['lastname']}`;
|
|
56
|
+
}
|
|
57
|
+
if (isString(claims['displayname'])) {
|
|
58
|
+
return claims['displayname'];
|
|
59
|
+
}
|
|
60
|
+
if (isString(claims['name'])) {
|
|
61
|
+
return claims['name'];
|
|
62
|
+
}
|
|
63
|
+
return '';
|
|
64
|
+
}
|
|
65
|
+
|
|
27
66
|
const DEFAULT_AUTH_SCOPES = ['openid', 'profile', 'email', 'offline_access'];
|
|
28
67
|
const DEFAULT_ISSUERS = {
|
|
29
68
|
dev: 'https://dev.login.draeger.com/oauth2/default',
|
|
30
69
|
stage: 'https://test.login.draeger.com/oauth2/default',
|
|
31
70
|
prod: 'https://login.draeger.com/oauth2/default',
|
|
32
71
|
};
|
|
72
|
+
const ODX_AUTH_CORE_PLUGINS = new InjectionToken('@odx/auth::CorePlugins', {
|
|
73
|
+
providedIn: 'root',
|
|
74
|
+
factory: () => [],
|
|
75
|
+
});
|
|
76
|
+
const ODX_AUTH_PLUGINS = new InjectionToken('@odx/auth::Plugins', {
|
|
77
|
+
providedIn: 'root',
|
|
78
|
+
factory: () => {
|
|
79
|
+
const { plugins } = injectAuthConfig();
|
|
80
|
+
const corePlugins = inject(ODX_AUTH_CORE_PLUGINS);
|
|
81
|
+
return [...corePlugins, ...plugins].map((pluginFactory) => pluginFactory());
|
|
82
|
+
},
|
|
83
|
+
});
|
|
33
84
|
const { AuthDefaultConfig, AuthConfig, injectAuthConfig, provideAuthConfig } = createConfigTokens('Auth', '@odx/auth', {
|
|
34
85
|
environment: 'prod',
|
|
35
86
|
redirectPath: 'login/callback',
|
|
@@ -40,62 +91,93 @@ const { AuthDefaultConfig, AuthConfig, injectAuthConfig, provideAuthConfig } = c
|
|
|
40
91
|
errorHandler: (error) => {
|
|
41
92
|
throw error;
|
|
42
93
|
},
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
94
|
+
createInitials,
|
|
95
|
+
resolveEmail,
|
|
96
|
+
resolveUsername,
|
|
46
97
|
showRedirectOverlay: false,
|
|
98
|
+
plugins: [],
|
|
47
99
|
});
|
|
48
100
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
101
|
+
const ODX_AUTH_HTTP_CACHE_STORAGE = new InjectionToken('@odx/auth::AuthHttpCacheStorage', {
|
|
102
|
+
providedIn: 'root',
|
|
103
|
+
factory: () => inject(WindowRef).nativeWindow.caches,
|
|
104
|
+
});
|
|
105
|
+
class AuthHttpCache {
|
|
106
|
+
constructor() {
|
|
107
|
+
this.cacheStorage = inject(ODX_AUTH_HTTP_CACHE_STORAGE);
|
|
108
|
+
}
|
|
109
|
+
async delete(request) {
|
|
110
|
+
const cache = await this.cacheStorage.open(AuthHttpCache.CACHE_KEY);
|
|
111
|
+
return cache.delete(request);
|
|
112
|
+
}
|
|
113
|
+
async request(request) {
|
|
114
|
+
const cache = await this.cacheStorage.open(AuthHttpCache.CACHE_KEY);
|
|
115
|
+
try {
|
|
116
|
+
await cache.add(request);
|
|
56
117
|
}
|
|
57
|
-
|
|
58
|
-
|
|
118
|
+
catch {
|
|
119
|
+
// ignore request errors
|
|
120
|
+
}
|
|
121
|
+
return cache.match(request, { ignoreVary: true, ignoreSearch: false }).then((res) => res?.json() ?? null);
|
|
122
|
+
}
|
|
59
123
|
}
|
|
124
|
+
AuthHttpCache.CACHE_KEY = '@odx/auth/http-cache';
|
|
125
|
+
AuthHttpCache.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: AuthHttpCache, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
126
|
+
AuthHttpCache.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: AuthHttpCache, providedIn: 'root' });
|
|
127
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: AuthHttpCache, decorators: [{
|
|
128
|
+
type: Injectable,
|
|
129
|
+
args: [{ providedIn: 'root' }]
|
|
130
|
+
}] });
|
|
60
131
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
132
|
+
class AuthPluginManager {
|
|
133
|
+
constructor() {
|
|
134
|
+
this.plugins = inject(ODX_AUTH_PLUGINS);
|
|
135
|
+
this.result$$ = new BehaviorSubject(null);
|
|
136
|
+
this.pluginsReady$ = this.result$$.pipe(filter(Boolean), map(Boolean), distinctUntilChanged(), share());
|
|
137
|
+
this.pluginsLoading$ = this.result$$.pipe(map((result) => !result), distinctUntilChanged(), share());
|
|
138
|
+
}
|
|
139
|
+
runPlugins(authService) {
|
|
140
|
+
if (this.plugins.length < 1) {
|
|
141
|
+
return of({});
|
|
142
|
+
}
|
|
143
|
+
return authService.isInitialized$.pipe(switchMap(() => combineLatest(this.plugins.map((plugin) => plugin(authService)))), map((results) => deepmerge(...results)), tap((result) => this.result$$.next(result)), take(1));
|
|
144
|
+
}
|
|
145
|
+
getResult() {
|
|
146
|
+
return this.result$$.getValue() ?? {};
|
|
147
|
+
}
|
|
71
148
|
}
|
|
149
|
+
AuthPluginManager.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: AuthPluginManager, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
150
|
+
AuthPluginManager.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: AuthPluginManager, providedIn: 'root' });
|
|
151
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: AuthPluginManager, decorators: [{
|
|
152
|
+
type: Injectable,
|
|
153
|
+
args: [{ providedIn: 'root' }]
|
|
154
|
+
}] });
|
|
72
155
|
|
|
73
156
|
class AuthService {
|
|
74
157
|
constructor() {
|
|
75
158
|
this.authConfig = injectAuthConfig();
|
|
159
|
+
this.authPluginManager = inject(AuthPluginManager);
|
|
76
160
|
this.oauthService = inject(OAuthService);
|
|
77
161
|
this.router = inject(Router);
|
|
78
162
|
this.windowRef = inject(WindowRef);
|
|
79
163
|
this.isInitialized$$ = new BehaviorSubject(false);
|
|
80
164
|
this.onAccessTokenUpdate$ = fromEvent(this.windowRef.nativeWindow, 'storage').pipe(filter(({ key }) => key === 'access_token' || key === null), startWith(null), share());
|
|
81
165
|
this.onAuthStateChange$ = combineLatest([this.oauthService.events.pipe(startWith(null)), this.windowRef.isOnline$, this.onAccessTokenUpdate$]);
|
|
82
|
-
this.
|
|
166
|
+
this.isInitialized$ = this.isInitialized$$.pipe(filter(Boolean), distinctUntilChanged());
|
|
167
|
+
this.isAuthenticated$ = this.isInitialized$.pipe(switchMap(() => this.authPluginManager.pluginsReady$), switchMap(() => this.onAuthStateChange$), map(() => this.isAuthenticated()), shareReplay({ refCount: true }));
|
|
83
168
|
this.identityClaims$ = this.isAuthenticated$.pipe(map(() => this.getIdentityClaims()), shareReplay({ refCount: true }));
|
|
84
169
|
this.errors$ = this.oauthService.events.pipe(filter((event) => event instanceof OAuthErrorEvent), share());
|
|
85
170
|
this.isRedirecting$ = fromEvents(this.windowRef.nativeWindow, 'beforeunload').pipe(map(Boolean), distinctUntilChanged(), share());
|
|
86
|
-
this.
|
|
87
|
-
|
|
171
|
+
this.isLoading$ = merge(this.isRedirecting$, this.authPluginManager.pluginsLoading$).pipe(distinctUntilChanged());
|
|
172
|
+
this.windowRef.isOnline$.subscribe((isOnline) => {
|
|
88
173
|
if (isOnline) {
|
|
89
174
|
this.oauthService.setupAutomaticSilentRefresh();
|
|
90
175
|
}
|
|
91
176
|
else {
|
|
92
177
|
this.oauthService.stopAutomaticRefresh();
|
|
93
178
|
}
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
}
|
|
97
|
-
ngOnDestroy() {
|
|
98
|
-
this.subscription.unsubscribe();
|
|
179
|
+
});
|
|
180
|
+
this.authPluginManager.runPlugins(this).subscribe();
|
|
99
181
|
}
|
|
100
182
|
async initialize(config) {
|
|
101
183
|
this.oauthService.configure(config);
|
|
@@ -158,7 +240,14 @@ class AuthService {
|
|
|
158
240
|
return this.oauthService.getIdToken() ?? null;
|
|
159
241
|
}
|
|
160
242
|
getIdentityClaims() {
|
|
161
|
-
|
|
243
|
+
if (!this.getIdToken())
|
|
244
|
+
return null;
|
|
245
|
+
return deepmerge(this.oauthService.getIdentityClaims(), this.authPluginManager.getResult());
|
|
246
|
+
}
|
|
247
|
+
getRawIdentityClaims() {
|
|
248
|
+
if (!this.getIdToken())
|
|
249
|
+
return null;
|
|
250
|
+
return this.oauthService.getIdentityClaims();
|
|
162
251
|
}
|
|
163
252
|
isAuthenticated() {
|
|
164
253
|
if (this.windowRef.isOnline()) {
|
|
@@ -170,9 +259,9 @@ class AuthService {
|
|
|
170
259
|
return this.isAuthenticated() && (authorizedHandler?.(this.getIdentityClaims(), this) ?? true);
|
|
171
260
|
}
|
|
172
261
|
async routeToRequestedUrl() {
|
|
173
|
-
if (this.oauthService.state)
|
|
174
|
-
|
|
175
|
-
|
|
262
|
+
if (!this.oauthService.state)
|
|
263
|
+
return;
|
|
264
|
+
await this.router.navigateByUrl(decodeURIComponent(this.oauthService.state));
|
|
176
265
|
}
|
|
177
266
|
hasValidOfflineToken() {
|
|
178
267
|
const issuedAt = this.getIdentityClaims()?.iat ?? 0;
|
|
@@ -186,13 +275,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
|
|
|
186
275
|
args: [{ providedIn: 'root' }]
|
|
187
276
|
}], ctorParameters: function () { return []; } });
|
|
188
277
|
|
|
189
|
-
class
|
|
278
|
+
class AuthActionDirective {
|
|
190
279
|
constructor() {
|
|
191
|
-
this.authService = inject(AuthService);
|
|
192
|
-
this.loadingSpinnerDirective = inject(LoadingSpinnerDirective, { self: true });
|
|
193
280
|
this.takeUntilDestroyed = untilDestroyed();
|
|
194
|
-
|
|
195
|
-
this.
|
|
281
|
+
this.loadingSpinnerDirective = inject(LoadingSpinnerDirective, { self: true });
|
|
282
|
+
this.authService = inject(AuthService);
|
|
196
283
|
}
|
|
197
284
|
ngAfterViewInit() {
|
|
198
285
|
this.loadingSpinnerDirective.autoColor = true;
|
|
@@ -200,13 +287,26 @@ class SignInDirective {
|
|
|
200
287
|
this.loadingSpinnerDirective.isLoading = true;
|
|
201
288
|
});
|
|
202
289
|
}
|
|
203
|
-
|
|
290
|
+
}
|
|
291
|
+
AuthActionDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: AuthActionDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
292
|
+
AuthActionDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.9", type: AuthActionDirective, ngImport: i0 });
|
|
293
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: AuthActionDirective, decorators: [{
|
|
294
|
+
type: Directive
|
|
295
|
+
}] });
|
|
296
|
+
|
|
297
|
+
class SignInDirective extends AuthActionDirective {
|
|
298
|
+
constructor() {
|
|
299
|
+
super(...arguments);
|
|
300
|
+
// eslint-disable-next-line @angular-eslint/no-output-rename
|
|
301
|
+
this.afterSignIn = new EventEmitter();
|
|
302
|
+
}
|
|
303
|
+
handleClick() {
|
|
204
304
|
this.authService.signIn();
|
|
205
|
-
this.afterSignIn.
|
|
305
|
+
this.afterSignIn.next();
|
|
206
306
|
}
|
|
207
307
|
}
|
|
208
|
-
SignInDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SignInDirective, deps:
|
|
209
|
-
SignInDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.9", type: SignInDirective, isStandalone: true, selector: "[odxButton][odxAuthSignIn]", outputs: { afterSignIn: "odxAuthSignIn" }, host: { listeners: { "click": "
|
|
308
|
+
SignInDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SignInDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive });
|
|
309
|
+
SignInDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.9", type: SignInDirective, isStandalone: true, selector: "[odxButton][odxAuthSignIn]", outputs: { afterSignIn: "odxAuthSignIn" }, host: { listeners: { "click": "handleClick()" } }, usesInheritance: true, hostDirectives: [{ directive: i1.LoadingSpinnerDirective }], ngImport: i0 });
|
|
210
310
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SignInDirective, decorators: [{
|
|
211
311
|
type: Directive,
|
|
212
312
|
args: [{
|
|
@@ -217,32 +317,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
|
|
|
217
317
|
}], propDecorators: { afterSignIn: [{
|
|
218
318
|
type: Output,
|
|
219
319
|
args: ['odxAuthSignIn']
|
|
220
|
-
}],
|
|
320
|
+
}], handleClick: [{
|
|
221
321
|
type: HostListener,
|
|
222
322
|
args: ['click']
|
|
223
323
|
}] } });
|
|
224
324
|
|
|
225
|
-
class SignOutDirective {
|
|
325
|
+
class SignOutDirective extends AuthActionDirective {
|
|
226
326
|
constructor() {
|
|
227
|
-
|
|
228
|
-
this.loadingSpinnerDirective = inject(LoadingSpinnerDirective, { self: true });
|
|
229
|
-
this.takeUntilDestroyed = untilDestroyed();
|
|
327
|
+
super(...arguments);
|
|
230
328
|
// eslint-disable-next-line @angular-eslint/no-output-rename
|
|
231
329
|
this.afterSignOut = new EventEmitter();
|
|
232
330
|
}
|
|
233
|
-
|
|
234
|
-
this.loadingSpinnerDirective.autoColor = true;
|
|
235
|
-
this.authService.isRedirecting$.pipe(this.takeUntilDestroyed()).subscribe(() => {
|
|
236
|
-
this.loadingSpinnerDirective.isLoading = true;
|
|
237
|
-
});
|
|
238
|
-
}
|
|
239
|
-
async signOut() {
|
|
331
|
+
handleClick() {
|
|
240
332
|
this.authService.signOut();
|
|
241
|
-
this.afterSignOut.
|
|
333
|
+
this.afterSignOut.next();
|
|
242
334
|
}
|
|
243
335
|
}
|
|
244
|
-
SignOutDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SignOutDirective, deps:
|
|
245
|
-
SignOutDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.9", type: SignOutDirective, isStandalone: true, selector: "[odxButton][odxAuthSignOut]", outputs: { afterSignOut: "odxAuthSignOut" }, host: { listeners: { "click": "
|
|
336
|
+
SignOutDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SignOutDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive });
|
|
337
|
+
SignOutDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.9", type: SignOutDirective, isStandalone: true, selector: "[odxButton][odxAuthSignOut]", outputs: { afterSignOut: "odxAuthSignOut" }, host: { listeners: { "click": "handleClick()" } }, usesInheritance: true, hostDirectives: [{ directive: i1.LoadingSpinnerDirective }], ngImport: i0 });
|
|
246
338
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: SignOutDirective, decorators: [{
|
|
247
339
|
type: Directive,
|
|
248
340
|
args: [{
|
|
@@ -253,15 +345,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
|
|
|
253
345
|
}], propDecorators: { afterSignOut: [{
|
|
254
346
|
type: Output,
|
|
255
347
|
args: ['odxAuthSignOut']
|
|
256
|
-
}],
|
|
348
|
+
}], handleClick: [{
|
|
257
349
|
type: HostListener,
|
|
258
350
|
args: ['click']
|
|
259
351
|
}] } });
|
|
260
352
|
|
|
261
353
|
class AuthComponent {
|
|
262
354
|
constructor() {
|
|
263
|
-
this.authService = inject(AuthService);
|
|
264
355
|
this.authConfig = injectAuthConfig();
|
|
356
|
+
this.authService = inject(AuthService);
|
|
265
357
|
this.dropdownOptions = {
|
|
266
358
|
position: Position.BOTTOM_END,
|
|
267
359
|
enableFallback: false,
|
|
@@ -272,10 +364,10 @@ class AuthComponent {
|
|
|
272
364
|
}
|
|
273
365
|
}
|
|
274
366
|
AuthComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: AuthComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
275
|
-
AuthComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: AuthComponent, isStandalone: true, selector: "odx-auth", inputs: { signInButtonText: "signInButtonText", signOutButtonText: "signOutButtonText" }, ngImport: i0, template: "<odx-action-group
|
|
367
|
+
AuthComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: AuthComponent, isStandalone: true, selector: "odx-auth", inputs: { signInButtonText: "signInButtonText", signOutButtonText: "signOutButtonText" }, 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 <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 }}\n <odx-icon name=\"arrow-right\" 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 }}\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 <ng-template [ngIf]=\"authConfig.showRedirectOverlay\">\n <div class=\"odx-auth-overlay\" [odxLoadingSpinner]=\"true\" *ngIf=\"authService.isLoading$ | async\"></div>\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-overlay{position:fixed;z-index:var(--odx-v-layer-5);inset:0}\n"], dependencies: [{ kind: "ngmodule", type: CoreModule }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "directive", type: i2.LetDirective, selector: "[ngrxLet]", inputs: ["ngrxLet", "ngrxLetSuspenseTpl"] }, { kind: "ngmodule", type: AreaHeaderModule }, { kind: "component", type: i3.AreaHeaderComponent, selector: "odx-area-header", inputs: ["size"] }, { kind: "directive", type: i3.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: i7.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: "directive", type: i1.LoadingSpinnerDirective, selector: "[odxLoadingSpinner]", inputs: ["odxLoadingSpinnerAutoColor", "odxLoadingSpinner", "odxLoadingSpinnerMinHeight"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
276
368
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: AuthComponent, decorators: [{
|
|
277
369
|
type: Component,
|
|
278
|
-
args: [{ standalone: true, selector: 'odx-auth', imports: [CoreModule, AreaHeaderModule, DropdownModule, HeaderModule, LogoDirective, SignInDirective, SignOutDirective, LoadingSpinnerModule], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<odx-action-group
|
|
370
|
+
args: [{ standalone: true, selector: 'odx-auth', imports: [CoreModule, AreaHeaderModule, DropdownModule, HeaderModule, LogoDirective, SignInDirective, SignOutDirective, LoadingSpinnerModule], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, 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 <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 }}\n <odx-icon name=\"arrow-right\" 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 }}\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 <ng-template [ngIf]=\"authConfig.showRedirectOverlay\">\n <div class=\"odx-auth-overlay\" [odxLoadingSpinner]=\"true\" *ngIf=\"authService.isLoading$ | async\"></div>\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-overlay{position:fixed;z-index:var(--odx-v-layer-5);inset:0}\n"] }]
|
|
279
371
|
}], propDecorators: { signInButtonText: [{
|
|
280
372
|
type: Input
|
|
281
373
|
}], signOutButtonText: [{
|
|
@@ -294,7 +386,7 @@ class AuthDirective {
|
|
|
294
386
|
this.ngIfDirective.ngIfElse = value;
|
|
295
387
|
}
|
|
296
388
|
ngAfterViewInit() {
|
|
297
|
-
this.authService.
|
|
389
|
+
this.authService.identityClaims$.pipe(this.takeUntilDestroyed()).subscribe(() => {
|
|
298
390
|
const handler = isString(this.authorizationHandler) ? null : this.authorizationHandler;
|
|
299
391
|
this.ngIfDirective.ngIf = this.authService.isAuthorized(handler);
|
|
300
392
|
});
|
|
@@ -317,16 +409,26 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
|
|
|
317
409
|
args: ['odxAuthElse']
|
|
318
410
|
}] } });
|
|
319
411
|
|
|
320
|
-
|
|
412
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
413
|
+
function authGuard(authorizedHandler, redirectTo) {
|
|
321
414
|
return (_, state) => {
|
|
322
415
|
const authService = inject(AuthService);
|
|
323
|
-
const router = inject(Router);
|
|
324
|
-
const isAuthorized = () => authorizedHandler?.(authService.getIdentityClaims(), router, authService);
|
|
416
|
+
const router = inject(Router, { optional: true });
|
|
325
417
|
return authService.isAuthenticated$.pipe(map((isAuthenticated) => {
|
|
326
418
|
if (!isAuthenticated) {
|
|
327
419
|
authService.signIn(state.url);
|
|
420
|
+
return false;
|
|
421
|
+
}
|
|
422
|
+
return authorizedHandler?.(authService.getIdentityClaims(), authService, router) ?? isAuthenticated;
|
|
423
|
+
}), tap((isAuthorized) => {
|
|
424
|
+
if (isAuthorized || !router)
|
|
425
|
+
return;
|
|
426
|
+
if (isString(redirectTo)) {
|
|
427
|
+
router.navigateByUrl(redirectTo);
|
|
428
|
+
}
|
|
429
|
+
else if (Array.isArray(redirectTo)) {
|
|
430
|
+
router.navigate(redirectTo);
|
|
328
431
|
}
|
|
329
|
-
return isAuthorized() ?? isAuthenticated;
|
|
330
432
|
}), take(1));
|
|
331
433
|
};
|
|
332
434
|
}
|
|
@@ -345,6 +447,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
|
|
|
345
447
|
}]
|
|
346
448
|
}] });
|
|
347
449
|
|
|
450
|
+
const coreIdentityPlugin = () => {
|
|
451
|
+
const { resolveEmail, resolveUsername, createInitials } = injectAuthConfig();
|
|
452
|
+
return (authService) => {
|
|
453
|
+
const claims = authService.getRawIdentityClaims();
|
|
454
|
+
if (!claims)
|
|
455
|
+
return of({});
|
|
456
|
+
const username = resolveUsername(claims);
|
|
457
|
+
return of({ email: resolveEmail(claims), username, initials: createInitials(username) });
|
|
458
|
+
};
|
|
459
|
+
};
|
|
460
|
+
|
|
348
461
|
function configureInterceptor() {
|
|
349
462
|
const { allowedUrls } = injectAuthConfig();
|
|
350
463
|
return {
|
|
@@ -400,6 +513,10 @@ function provideAuth(config) {
|
|
|
400
513
|
provide: OAuthStorage,
|
|
401
514
|
useFactory: () => inject(AuthConfig).storage ?? inject(WindowRef).nativeWindow.localStorage,
|
|
402
515
|
},
|
|
516
|
+
{
|
|
517
|
+
provide: ODX_AUTH_CORE_PLUGINS,
|
|
518
|
+
useValue: [coreIdentityPlugin],
|
|
519
|
+
},
|
|
403
520
|
]);
|
|
404
521
|
}
|
|
405
522
|
|
|
@@ -407,5 +524,5 @@ function provideAuth(config) {
|
|
|
407
524
|
* Generated bundle index. Do not edit.
|
|
408
525
|
*/
|
|
409
526
|
|
|
410
|
-
export { AuthComponent, AuthConfig, AuthDefaultConfig, AuthDirective, AuthModule, AuthService, DEFAULT_AUTH_SCOPES, DEFAULT_ISSUERS, SignInDirective, SignOutDirective, authGuard, configureInterceptor,
|
|
527
|
+
export { AuthActionDirective, AuthComponent, AuthConfig, AuthDefaultConfig, AuthDirective, AuthHttpCache, AuthModule, AuthPluginManager, AuthService, DEFAULT_AUTH_SCOPES, DEFAULT_ISSUERS, ODX_AUTH_CORE_PLUGINS, ODX_AUTH_HTTP_CACHE_STORAGE, ODX_AUTH_PLUGINS, SignInDirective, SignOutDirective, authGuard, configureInterceptor, coreIdentityPlugin, createInitials, initalizeAuthConfig, initializeAuthErrorHandler, injectAuthConfig, provideAuth, provideAuthConfig, resolveEmail, resolveUsername };
|
|
411
528
|
//# sourceMappingURL=odx-auth.mjs.map
|