@odx/auth 1.0.0-alpha.1 → 1.0.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2020/index.mjs +6 -3
- package/esm2020/lib/auth-error-handler.mjs +20 -0
- package/esm2020/lib/auth.component.mjs +13 -21
- package/esm2020/lib/auth.config.mjs +11 -3
- package/esm2020/lib/auth.directive.mjs +41 -0
- package/esm2020/lib/auth.guard.mjs +18 -0
- package/esm2020/lib/auth.module.mjs +10 -12
- package/esm2020/lib/auth.providers.mjs +53 -42
- package/esm2020/lib/auth.service.mjs +87 -21
- package/esm2020/lib/auth.typings.mjs +2 -0
- package/esm2020/lib/directives/sign-in.directive.mjs +6 -6
- package/esm2020/lib/directives/sign-out.directive.mjs +6 -6
- package/esm2020/lib/helpers/create-inititals.mjs +12 -0
- package/esm2020/lib/helpers/index.mjs +3 -3
- package/esm2020/lib/helpers/parse-identity-claims.mjs +10 -0
- package/esm2020/lib/models/authorized-handler.mjs +2 -0
- package/esm2020/lib/models/index.mjs +2 -2
- package/fesm2015/odx-auth.mjs +255 -134
- package/fesm2015/odx-auth.mjs.map +1 -1
- package/fesm2020/odx-auth.mjs +252 -135
- package/fesm2020/odx-auth.mjs.map +1 -1
- package/index.d.ts +5 -2
- package/lib/auth-error-handler.d.ts +12 -0
- package/lib/auth.component.d.ts +2 -3
- package/lib/auth.config.d.ts +10 -5
- package/lib/auth.directive.d.ts +15 -0
- package/lib/auth.guard.d.ts +3 -0
- package/lib/auth.module.d.ts +4 -4
- package/lib/auth.providers.d.ts +9 -6
- package/lib/auth.service.d.ts +27 -11
- package/lib/auth.typings.d.ts +19 -0
- package/lib/directives/sign-in.directive.d.ts +3 -3
- package/lib/directives/sign-out.directive.d.ts +3 -3
- package/lib/helpers/create-inititals.d.ts +1 -0
- package/lib/helpers/index.d.ts +2 -2
- package/lib/helpers/parse-identity-claims.d.ts +1 -0
- package/lib/models/auth-environment.d.ts +1 -1
- package/lib/models/authorized-handler.d.ts +4 -0
- package/lib/models/index.d.ts +1 -1
- package/package.json +3 -4
- package/esm2020/lib/auth.interceptor.mjs +0 -25
- package/esm2020/lib/helpers/get-user-initials.mjs +0 -12
- package/esm2020/lib/helpers/resolve-issuer.mjs +0 -13
- package/esm2020/lib/models/user.mjs +0 -2
- package/lib/auth.interceptor.d.ts +0 -11
- package/lib/helpers/get-user-initials.d.ts +0 -2
- package/lib/helpers/resolve-issuer.d.ts +0 -2
- package/lib/models/user.d.ts +0 -4
package/fesm2020/odx-auth.mjs
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
import { OKTA_AUTH, OktaAuthStateService, OktaCallbackComponent, OKTA_CONFIG, OktaAuthModule } from '@okta/okta-angular';
|
|
2
|
-
export { OktaAuthGuard as AuthGuard } from '@okta/okta-angular';
|
|
3
|
-
import { __decorate, __metadata } from 'tslib';
|
|
4
1
|
import * as i0 from '@angular/core';
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
7
|
-
import { CoreModule, WindowRef } from '@odx/angular';
|
|
2
|
+
import { Injectable, inject, EventEmitter, Directive, Output, HostListener, Component, ChangeDetectionStrategy, ViewEncapsulation, Input, makeEnvironmentProviders, APP_INITIALIZER, NgModule } from '@angular/core';
|
|
3
|
+
import { WindowRef, CoreModule } from '@odx/angular';
|
|
8
4
|
import * as i3 from '@odx/angular/components/area-header';
|
|
9
5
|
import { AreaHeaderModule } from '@odx/angular/components/area-header';
|
|
10
6
|
import * as i8 from '@odx/angular/components/dropdown';
|
|
@@ -12,58 +8,167 @@ import { DropdownModule } from '@odx/angular/components/dropdown';
|
|
|
12
8
|
import * as i9 from '@odx/angular/components/header';
|
|
13
9
|
import { HeaderModule } from '@odx/angular/components/header';
|
|
14
10
|
import { LogoDirective } from '@odx/angular/components/logo';
|
|
15
|
-
import { createModuleConfigTokens,
|
|
16
|
-
import {
|
|
11
|
+
import { createModuleConfigTokens, Position, untilDestroyed, isString, buildUrl, provideModuleConfig } from '@odx/angular/utils';
|
|
12
|
+
import { Router } from '@angular/router';
|
|
13
|
+
import { OAuthService, OAuthErrorEvent, provideOAuthClient, OAuthModuleConfig, OAuthStorage } from 'angular-oauth2-oidc';
|
|
14
|
+
import { BehaviorSubject, fromEvent, filter, startWith, share, combineLatest, switchMap, map, distinctUntilChanged, shareReplay, merge, tap, take } from 'rxjs';
|
|
17
15
|
import * as i1 from '@odx/angular/components/loading-spinner';
|
|
18
16
|
import { LoadingSpinnerDirective } from '@odx/angular/components/loading-spinner';
|
|
19
17
|
import * as i1$1 from '@angular/common';
|
|
18
|
+
import { NgIf } from '@angular/common';
|
|
19
|
+
import * as i2 from '@ngrx/component';
|
|
20
20
|
import * as i4 from '@odx/angular/components/avatar';
|
|
21
21
|
import * as i5 from '@odx/angular/components/action-group';
|
|
22
22
|
import * as i6 from '@odx/angular/components/button';
|
|
23
23
|
import * as i7 from '@odx/angular/components/icon';
|
|
24
|
-
import { HTTP_INTERCEPTORS } from '@angular/common/http';
|
|
25
|
-
import { Router } from '@angular/router';
|
|
26
|
-
import { OktaAuth } from '@okta/okta-auth-js';
|
|
27
24
|
|
|
28
|
-
|
|
25
|
+
class AuthErrorHandler {
|
|
26
|
+
}
|
|
27
|
+
AuthErrorHandler.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.1", ngImport: i0, type: AuthErrorHandler, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
28
|
+
AuthErrorHandler.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.1", ngImport: i0, type: AuthErrorHandler });
|
|
29
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.1", ngImport: i0, type: AuthErrorHandler, decorators: [{
|
|
30
|
+
type: Injectable
|
|
31
|
+
}] });
|
|
32
|
+
class NoopAuthErrorHandler extends AuthErrorHandler {
|
|
33
|
+
handleError(error) {
|
|
34
|
+
throw error;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
NoopAuthErrorHandler.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.1", ngImport: i0, type: NoopAuthErrorHandler, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
38
|
+
NoopAuthErrorHandler.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.1", ngImport: i0, type: NoopAuthErrorHandler });
|
|
39
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.1", ngImport: i0, type: NoopAuthErrorHandler, decorators: [{
|
|
40
|
+
type: Injectable
|
|
41
|
+
}] });
|
|
42
|
+
|
|
43
|
+
const DEFAULT_AUTH_SCOPES = ['openid', 'profile', 'email', 'offline_access'];
|
|
44
|
+
const DEFAULT_ISSUERS = {
|
|
45
|
+
dev: 'https://dev.login.draeger.com/oauth2/default',
|
|
46
|
+
stage: 'https://test.login.draeger.com/oauth2/default',
|
|
47
|
+
prod: 'https://login.draeger.com/oauth2/default',
|
|
48
|
+
};
|
|
29
49
|
const { AuthDefaultModuleConfig, AuthModuleConfig, injectAuthModuleConfig } = createModuleConfigTokens('Auth', '@odx/auth', {
|
|
30
50
|
environment: 'prod',
|
|
31
51
|
redirectPath: 'login/callback',
|
|
32
|
-
|
|
52
|
+
allowedUrls: [],
|
|
53
|
+
timeoutFactor: 0.75,
|
|
54
|
+
maxOfflineTime: 24 * 60 * 60,
|
|
55
|
+
loadUserProfile: false,
|
|
33
56
|
});
|
|
34
57
|
|
|
58
|
+
function createInititals(value) {
|
|
59
|
+
if (!value)
|
|
60
|
+
return '';
|
|
61
|
+
const parts = value.trim().split(' ');
|
|
62
|
+
return parts.reduce((initials, curr, index) => {
|
|
63
|
+
if (index === 0 || index === parts.length - 1) {
|
|
64
|
+
initials = `${initials}${curr.charAt(0).toUpperCase()}`;
|
|
65
|
+
}
|
|
66
|
+
return initials;
|
|
67
|
+
}, '');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
71
|
+
function parseIdentityClaims(identityClaims) {
|
|
72
|
+
return {
|
|
73
|
+
...identityClaims,
|
|
74
|
+
email: identityClaims?.email ?? identityClaims.email_address ?? identityClaims.emails?.[0],
|
|
75
|
+
initials: createInititals(identityClaims.name),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
35
79
|
class AuthService {
|
|
36
80
|
constructor() {
|
|
37
|
-
this.
|
|
38
|
-
this.
|
|
39
|
-
this.
|
|
40
|
-
this.
|
|
81
|
+
this.authConfig = injectAuthModuleConfig();
|
|
82
|
+
this.errorHandler = inject(AuthErrorHandler);
|
|
83
|
+
this.oauthService = inject(OAuthService);
|
|
84
|
+
this.router = inject(Router);
|
|
85
|
+
this.windowRef = inject(WindowRef);
|
|
86
|
+
this.isInitialized$$ = new BehaviorSubject(false);
|
|
87
|
+
this.onAccessTokenUpdate$ = fromEvent(this.windowRef.nativeWindow, 'storage').pipe(filter(({ key }) => key === 'access_token' || key === null), startWith(null), share());
|
|
88
|
+
this.onAuthStateChange$ = combineLatest([this.oauthService.events.pipe(startWith(null)), this.windowRef.isOnline$, this.onAccessTokenUpdate$]);
|
|
89
|
+
this.isAuthenticated$ = this.isInitialized$$.pipe(filter(Boolean), switchMap(() => this.onAuthStateChange$), map(() => this.isAuthenticated()), distinctUntilChanged(), shareReplay({ refCount: true }));
|
|
90
|
+
this.identityClaims$ = this.isAuthenticated$.pipe(map(() => this.getIdentityClaims()), shareReplay({ refCount: true }));
|
|
91
|
+
this.errors$ = this.oauthService.events.pipe(filter((event) => event instanceof OAuthErrorEvent), share());
|
|
92
|
+
this.subscription = merge(this.errors$.pipe(tap((error) => {
|
|
93
|
+
this.errorHandler.handleError(error);
|
|
94
|
+
})), this.windowRef.isOnline$.pipe(tap((isOnline) => {
|
|
95
|
+
if (isOnline) {
|
|
96
|
+
this.oauthService.setupAutomaticSilentRefresh();
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
this.oauthService.stopAutomaticRefresh();
|
|
100
|
+
}
|
|
101
|
+
}))).subscribe();
|
|
41
102
|
}
|
|
42
|
-
|
|
43
|
-
|
|
103
|
+
ngOnDestroy() {
|
|
104
|
+
this.subscription.unsubscribe();
|
|
44
105
|
}
|
|
45
|
-
async
|
|
46
|
-
|
|
106
|
+
async initialize(config) {
|
|
107
|
+
this.oauthService.configure(config);
|
|
108
|
+
try {
|
|
109
|
+
await this.oauthService.loadDiscoveryDocument(this.authConfig.discoveryUrl);
|
|
110
|
+
await this.oauthService.tryLoginCodeFlow();
|
|
111
|
+
if (this.getRefreshToken() && !this.isAuthenticated()) {
|
|
112
|
+
await this.oauthService.refreshToken();
|
|
113
|
+
}
|
|
114
|
+
this.isInitialized$$.next(true);
|
|
115
|
+
if (this.authConfig.loadUserProfile && this.oauthService.hasValidAccessToken()) {
|
|
116
|
+
await this.loadUserProfile();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
// ignore errors
|
|
121
|
+
}
|
|
122
|
+
if (this.oauthService.hasValidAccessToken()) {
|
|
123
|
+
await this.routeToRequestedUrl();
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
signIn(url) {
|
|
127
|
+
this.oauthService.initCodeFlow(url);
|
|
128
|
+
}
|
|
129
|
+
signOut() {
|
|
130
|
+
this.oauthService.logOut(!this.getAccessToken());
|
|
131
|
+
}
|
|
132
|
+
async loadUserProfile() {
|
|
133
|
+
await this.oauthService.loadUserProfile();
|
|
47
134
|
}
|
|
48
135
|
getAccessToken() {
|
|
49
|
-
return this.
|
|
136
|
+
return this.oauthService.getAccessToken() ?? null;
|
|
50
137
|
}
|
|
51
138
|
getRefreshToken() {
|
|
52
|
-
return this.
|
|
139
|
+
return this.oauthService.getRefreshToken() ?? null;
|
|
140
|
+
}
|
|
141
|
+
getIdToken() {
|
|
142
|
+
return this.oauthService.getIdToken() ?? null;
|
|
143
|
+
}
|
|
144
|
+
getIdentityClaims() {
|
|
145
|
+
return this.getIdToken() ? parseIdentityClaims(this.oauthService.getIdentityClaims()) : null;
|
|
146
|
+
}
|
|
147
|
+
isAuthenticated() {
|
|
148
|
+
if (this.windowRef.isOnline()) {
|
|
149
|
+
return this.oauthService.hasValidAccessToken() && this.oauthService.hasValidIdToken();
|
|
150
|
+
}
|
|
151
|
+
return this.hasValidOfflineToken();
|
|
152
|
+
}
|
|
153
|
+
isAuthorized(authorizedHandler) {
|
|
154
|
+
return this.isAuthenticated() && (authorizedHandler?.(this.getIdentityClaims(), this) ?? true);
|
|
53
155
|
}
|
|
54
|
-
|
|
55
|
-
|
|
156
|
+
async routeToRequestedUrl() {
|
|
157
|
+
if (this.oauthService.state) {
|
|
158
|
+
await this.router.navigateByUrl(decodeURIComponent(this.oauthService.state));
|
|
159
|
+
}
|
|
56
160
|
}
|
|
57
|
-
|
|
58
|
-
|
|
161
|
+
hasValidOfflineToken() {
|
|
162
|
+
const issuedAt = this.getIdentityClaims()?.iat ?? 0;
|
|
163
|
+
return Date.now() - issuedAt * 1000 <= this.authConfig.maxOfflineTime * 1000;
|
|
59
164
|
}
|
|
60
165
|
}
|
|
61
|
-
AuthService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.
|
|
62
|
-
AuthService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.
|
|
63
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.
|
|
166
|
+
AuthService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.1", ngImport: i0, type: AuthService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
167
|
+
AuthService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.1", ngImport: i0, type: AuthService, providedIn: 'root' });
|
|
168
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.1", ngImport: i0, type: AuthService, decorators: [{
|
|
64
169
|
type: Injectable,
|
|
65
170
|
args: [{ providedIn: 'root' }]
|
|
66
|
-
}] });
|
|
171
|
+
}], ctorParameters: function () { return []; } });
|
|
67
172
|
|
|
68
173
|
class SignInDirective {
|
|
69
174
|
constructor() {
|
|
@@ -72,18 +177,18 @@ class SignInDirective {
|
|
|
72
177
|
// eslint-disable-next-line @angular-eslint/no-output-rename
|
|
73
178
|
this.afterSignIn = new EventEmitter();
|
|
74
179
|
}
|
|
75
|
-
|
|
180
|
+
ngAfterViewInit() {
|
|
76
181
|
this.loadingSpinnerDirective.autoColor = true;
|
|
77
182
|
}
|
|
78
183
|
async signIn() {
|
|
79
184
|
this.loadingSpinnerDirective.isLoading = true;
|
|
80
|
-
|
|
185
|
+
this.authService.signIn();
|
|
81
186
|
this.afterSignIn.emit();
|
|
82
187
|
}
|
|
83
188
|
}
|
|
84
|
-
SignInDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.
|
|
85
|
-
SignInDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.
|
|
86
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.
|
|
189
|
+
SignInDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.1", ngImport: i0, type: SignInDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
190
|
+
SignInDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.1", type: SignInDirective, isStandalone: true, selector: "[odxButton][odxAuthSignIn]", outputs: { afterSignIn: "odxAuthSignIn" }, host: { listeners: { "click": "signIn()" } }, hostDirectives: [{ directive: i1.LoadingSpinnerDirective }], ngImport: i0 });
|
|
191
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.1", ngImport: i0, type: SignInDirective, decorators: [{
|
|
87
192
|
type: Directive,
|
|
88
193
|
args: [{
|
|
89
194
|
standalone: true,
|
|
@@ -105,18 +210,18 @@ class SignOutDirective {
|
|
|
105
210
|
// eslint-disable-next-line @angular-eslint/no-output-rename
|
|
106
211
|
this.afterSignOut = new EventEmitter();
|
|
107
212
|
}
|
|
108
|
-
|
|
213
|
+
ngAfterViewInit() {
|
|
109
214
|
this.loadingSpinnerDirective.autoColor = true;
|
|
110
215
|
}
|
|
111
216
|
async signIn() {
|
|
112
217
|
this.loadingSpinnerDirective.isLoading = true;
|
|
113
|
-
|
|
218
|
+
this.authService.signOut();
|
|
114
219
|
this.afterSignOut.emit();
|
|
115
220
|
}
|
|
116
221
|
}
|
|
117
|
-
SignOutDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.
|
|
118
|
-
SignOutDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.
|
|
119
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.
|
|
222
|
+
SignOutDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.1", ngImport: i0, type: SignOutDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
223
|
+
SignOutDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.1", type: SignOutDirective, isStandalone: true, selector: "[odxButton][odxAuthSignOut]", outputs: { afterSignOut: "odxAuthSignOut" }, host: { listeners: { "click": "signIn()" } }, hostDirectives: [{ directive: i1.LoadingSpinnerDirective }], ngImport: i0 });
|
|
224
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.1", ngImport: i0, type: SignOutDirective, decorators: [{
|
|
120
225
|
type: Directive,
|
|
121
226
|
args: [{
|
|
122
227
|
standalone: true,
|
|
@@ -131,137 +236,149 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.0", ngImpor
|
|
|
131
236
|
args: ['click']
|
|
132
237
|
}] } });
|
|
133
238
|
|
|
134
|
-
function getUserInitials(user) {
|
|
135
|
-
if (!user?.name)
|
|
136
|
-
return '';
|
|
137
|
-
const names = user.name.trim().split(' ');
|
|
138
|
-
return names.reduce((initials, curr, index) => {
|
|
139
|
-
if (index === 0 || index === names.length - 1) {
|
|
140
|
-
initials = `${initials}${curr.charAt(0).toUpperCase()}`;
|
|
141
|
-
}
|
|
142
|
-
return initials;
|
|
143
|
-
}, '');
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
function resolveIssuer(environment, issuerOverride) {
|
|
147
|
-
if (issuerOverride)
|
|
148
|
-
return issuerOverride;
|
|
149
|
-
switch (environment) {
|
|
150
|
-
case 'dev':
|
|
151
|
-
return 'https://dev.login.draeger.com/oauth2/default';
|
|
152
|
-
case 'stage':
|
|
153
|
-
return 'https://test.login.draeger.com/oauth2/default';
|
|
154
|
-
default:
|
|
155
|
-
return 'https://login.draeger.com/oauth2/default';
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
239
|
class AuthComponent {
|
|
160
240
|
constructor() {
|
|
161
|
-
this.config = injectAuthModuleConfig();
|
|
162
241
|
this.authService = inject(AuthService);
|
|
242
|
+
this.dropdownOptions = {
|
|
243
|
+
position: Position.BOTTOM_END,
|
|
244
|
+
enableFallback: false,
|
|
245
|
+
containerClass: 'odx-auth-user-profile',
|
|
246
|
+
};
|
|
163
247
|
this.signInButtonText = 'Sign in';
|
|
164
248
|
this.signOutButtonText = 'Sign out';
|
|
165
249
|
}
|
|
166
|
-
getInitials(user) {
|
|
167
|
-
return getUserInitials(user);
|
|
168
|
-
}
|
|
169
250
|
}
|
|
170
|
-
AuthComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.
|
|
171
|
-
AuthComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.
|
|
172
|
-
|
|
173
|
-
Pure,
|
|
174
|
-
__metadata("design:type", Function),
|
|
175
|
-
__metadata("design:paramtypes", [Object]),
|
|
176
|
-
__metadata("design:returntype", String)
|
|
177
|
-
], AuthComponent.prototype, "getInitials", null);
|
|
178
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.0", ngImport: i0, type: AuthComponent, decorators: [{
|
|
251
|
+
AuthComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.1", ngImport: i0, type: AuthComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
252
|
+
AuthComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.1", type: AuthComponent, isStandalone: true, selector: "odx-auth", inputs: { signInButtonText: "signInButtonText", signOutButtonText: "signOutButtonText" }, ngImport: i0, template: "<odx-action-group *ngrxLet=\"{ idClaims: authService.identityClaims$, isAuthenticated: authService.isAuthenticated$ } as vm\">\n <ng-template [ngIf]=\"vm.isAuthenticated\" [ngIfElse]=\"notAuthenticated\">\n <button odxButton odxHeaderAvatar [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?.name }}\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=\"primary\" 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</odx-action-group>\n", styles: [".odx-auth-user-profile .odx-dropdown__inner>.odx-area-header{max-width:max(360px,25vw);min-width:296px}\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: "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"] }, { kind: "ngmodule", type: DropdownModule }, { kind: "directive", type: i8.DropdownDirective, selector: "[odxDropdown]", inputs: ["odxDropdown", "odxDropdownDisabled", "odxDropdownShowLoader", "odxDropdownOptions", "odxDropdownReferenceElement", "odxDropdownTriggerElement", "odxDropdownHost", "odxDropdownOpenTrigger", "odxDropdownCloseTrigger"], outputs: ["odxDropdownBeforeOpen", "odxDropdownAfterOpen", "odxDropdownBeforeClose", "odxDropdownAfterClose"], exportAs: ["odxDropdown"] }, { kind: "ngmodule", type: HeaderModule }, { kind: "directive", type: i9.HeaderAvatarDirective, selector: "button[odxButton][odxHeaderAvatar]" }, { 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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
253
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.1", ngImport: i0, type: AuthComponent, decorators: [{
|
|
179
254
|
type: Component,
|
|
180
|
-
args: [{ standalone: true, selector: 'odx-auth', imports: [CoreModule, AreaHeaderModule, DropdownModule, HeaderModule, LogoDirective, SignInDirective, SignOutDirective], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<odx-action-group *
|
|
255
|
+
args: [{ standalone: true, selector: 'odx-auth', imports: [CoreModule, AreaHeaderModule, DropdownModule, HeaderModule, LogoDirective, SignInDirective, SignOutDirective], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<odx-action-group *ngrxLet=\"{ idClaims: authService.identityClaims$, isAuthenticated: authService.isAuthenticated$ } as vm\">\n <ng-template [ngIf]=\"vm.isAuthenticated\" [ngIfElse]=\"notAuthenticated\">\n <button odxButton odxHeaderAvatar [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?.name }}\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=\"primary\" 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</odx-action-group>\n", styles: [".odx-auth-user-profile .odx-dropdown__inner>.odx-area-header{max-width:max(360px,25vw);min-width:296px}\n"] }]
|
|
181
256
|
}], propDecorators: { signInButtonText: [{
|
|
182
257
|
type: Input
|
|
183
258
|
}], signOutButtonText: [{
|
|
184
259
|
type: Input
|
|
185
|
-
}]
|
|
260
|
+
}] } });
|
|
186
261
|
|
|
187
|
-
class
|
|
262
|
+
class AuthDirective {
|
|
188
263
|
constructor() {
|
|
189
|
-
this.config = injectAuthModuleConfig();
|
|
190
264
|
this.authService = inject(AuthService);
|
|
265
|
+
this.ngIfDirective = inject(NgIf, { host: true });
|
|
266
|
+
this.takeUntilDestroyed = untilDestroyed();
|
|
267
|
+
this.authorizationHandler = null;
|
|
191
268
|
}
|
|
192
|
-
|
|
193
|
-
|
|
269
|
+
// eslint-disable-next-line @angular-eslint/no-input-rename
|
|
270
|
+
set elseTemplate(value) {
|
|
271
|
+
this.ngIfDirective.ngIfElse = value;
|
|
194
272
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
273
|
+
ngAfterViewInit() {
|
|
274
|
+
this.authService.isAuthenticated$.pipe(this.takeUntilDestroyed()).subscribe(() => {
|
|
275
|
+
const handler = isString(this.authorizationHandler) ? null : this.authorizationHandler;
|
|
276
|
+
this.ngIfDirective.ngIf = this.authService.isAuthorized(handler);
|
|
277
|
+
});
|
|
200
278
|
}
|
|
201
279
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.
|
|
205
|
-
type:
|
|
206
|
-
|
|
280
|
+
AuthDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.1", ngImport: i0, type: AuthDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
281
|
+
AuthDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.1", type: AuthDirective, isStandalone: true, selector: "ng-template[odxAuth]", inputs: { authorizationHandler: ["odxAuth", "authorizationHandler"], elseTemplate: ["odxAuthElse", "elseTemplate"] }, hostDirectives: [{ directive: i1$1.NgIf }], ngImport: i0 });
|
|
282
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.1", ngImport: i0, type: AuthDirective, decorators: [{
|
|
283
|
+
type: Directive,
|
|
284
|
+
args: [{
|
|
285
|
+
standalone: true,
|
|
286
|
+
selector: 'ng-template[odxAuth]',
|
|
287
|
+
hostDirectives: [NgIf],
|
|
288
|
+
}]
|
|
289
|
+
}], propDecorators: { authorizationHandler: [{
|
|
290
|
+
type: Input,
|
|
291
|
+
args: ['odxAuth']
|
|
292
|
+
}], elseTemplate: [{
|
|
293
|
+
type: Input,
|
|
294
|
+
args: ['odxAuthElse']
|
|
295
|
+
}] } });
|
|
207
296
|
|
|
208
|
-
function
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
297
|
+
function authGuard(authorizedHandler) {
|
|
298
|
+
return (_, state) => {
|
|
299
|
+
const authService = inject(AuthService);
|
|
300
|
+
const router = inject(Router);
|
|
301
|
+
const isAuthorized = () => authorizedHandler?.(authService.getIdentityClaims(), router, authService);
|
|
302
|
+
return authService.isAuthenticated$.pipe(map((isAuthenticated) => {
|
|
303
|
+
if (!isAuthenticated) {
|
|
304
|
+
authService.signIn(state.url);
|
|
305
|
+
}
|
|
306
|
+
return isAuthorized() ?? isAuthenticated;
|
|
307
|
+
}), take(1));
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
function configureInterceptor() {
|
|
312
|
+
const { allowedUrls } = injectAuthModuleConfig();
|
|
313
|
+
return {
|
|
314
|
+
resourceServer: {
|
|
315
|
+
customUrlValidation: (url) => allowedUrls.some((allowedUrl) => !!url.match(allowedUrl)),
|
|
316
|
+
sendAccessToken: true,
|
|
317
|
+
},
|
|
213
318
|
};
|
|
214
319
|
}
|
|
215
320
|
function initalizeAuthConfig() {
|
|
216
|
-
const { clientId, scopes, redirectPath, environment, postLogoutRedirectPath,
|
|
321
|
+
const { clientId, scopes, redirectPath, environment, postLogoutRedirectPath, issuer, timeoutFactor, discoveryUrl } = injectAuthModuleConfig();
|
|
322
|
+
const authService = inject(AuthService);
|
|
217
323
|
const origin = inject(WindowRef).getOrigin();
|
|
218
|
-
const
|
|
324
|
+
const scope = Array.from(new Set(DEFAULT_AUTH_SCOPES.concat(scopes ?? []))).join(' ');
|
|
325
|
+
return () => authService.initialize({
|
|
326
|
+
clientId,
|
|
327
|
+
issuer: issuer ?? DEFAULT_ISSUERS[environment],
|
|
328
|
+
scope,
|
|
329
|
+
redirectUri: buildUrl(origin, redirectPath),
|
|
330
|
+
postLogoutRedirectUri: buildUrl(origin, postLogoutRedirectPath),
|
|
331
|
+
preserveRequestedRoute: true,
|
|
332
|
+
strictDiscoveryDocumentValidation: !discoveryUrl,
|
|
333
|
+
responseType: 'code',
|
|
334
|
+
showDebugInformation: environment === 'dev',
|
|
335
|
+
timeoutFactor,
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
function provideAuthErrorHandler(errorHandler) {
|
|
219
339
|
return {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
clientId,
|
|
223
|
-
redirectUri: buildUrl(origin, redirectPath),
|
|
224
|
-
scopes: Array.from(new Set(DEFAULT_AUTH_SCOPES.concat(scopes ?? []))),
|
|
225
|
-
pkce: true,
|
|
226
|
-
devMode: environment === 'dev',
|
|
227
|
-
postLogoutRedirectUri,
|
|
228
|
-
}),
|
|
340
|
+
provide: AuthErrorHandler,
|
|
341
|
+
useClass: errorHandler,
|
|
229
342
|
};
|
|
230
343
|
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
344
|
+
function provideAuth(config) {
|
|
345
|
+
return makeEnvironmentProviders([
|
|
346
|
+
provideModuleConfig(AuthModuleConfig, config),
|
|
347
|
+
provideOAuthClient(),
|
|
348
|
+
provideAuthErrorHandler(NoopAuthErrorHandler),
|
|
349
|
+
{
|
|
350
|
+
provide: OAuthModuleConfig,
|
|
351
|
+
useFactory: configureInterceptor,
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
provide: APP_INITIALIZER,
|
|
355
|
+
useFactory: initalizeAuthConfig,
|
|
356
|
+
multi: true,
|
|
357
|
+
},
|
|
358
|
+
{
|
|
359
|
+
provide: OAuthStorage,
|
|
360
|
+
useFactory: () => inject(WindowRef).nativeWindow.localStorage,
|
|
361
|
+
},
|
|
362
|
+
]);
|
|
363
|
+
}
|
|
247
364
|
|
|
248
|
-
const modules = [AuthComponent, SignInDirective, SignOutDirective];
|
|
365
|
+
const modules = [AuthComponent, AuthDirective, SignInDirective, SignOutDirective];
|
|
249
366
|
class AuthModule {
|
|
250
367
|
static forRoot(config) {
|
|
251
368
|
return {
|
|
252
369
|
ngModule: AuthModule,
|
|
253
|
-
providers: [
|
|
370
|
+
providers: [provideAuth(config)],
|
|
254
371
|
};
|
|
255
372
|
}
|
|
256
373
|
}
|
|
257
|
-
AuthModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.
|
|
258
|
-
AuthModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.
|
|
259
|
-
AuthModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.
|
|
260
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.
|
|
374
|
+
AuthModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.1", ngImport: i0, type: AuthModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
375
|
+
AuthModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.1", ngImport: i0, type: AuthModule, imports: [AuthComponent, AuthDirective, SignInDirective, SignOutDirective], exports: [AuthComponent, AuthDirective, SignInDirective, SignOutDirective] });
|
|
376
|
+
AuthModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.1", ngImport: i0, type: AuthModule, imports: [AuthComponent] });
|
|
377
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.1", ngImport: i0, type: AuthModule, decorators: [{
|
|
261
378
|
type: NgModule,
|
|
262
379
|
args: [{
|
|
263
380
|
imports: [...modules],
|
|
264
|
-
exports: [
|
|
381
|
+
exports: [...modules],
|
|
265
382
|
}]
|
|
266
383
|
}] });
|
|
267
384
|
|
|
@@ -269,5 +386,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.0", ngImpor
|
|
|
269
386
|
* Generated bundle index. Do not edit.
|
|
270
387
|
*/
|
|
271
388
|
|
|
272
|
-
export { AuthComponent, AuthDefaultModuleConfig,
|
|
389
|
+
export { AuthComponent, AuthDefaultModuleConfig, AuthDirective, AuthErrorHandler, AuthModule, AuthModuleConfig, AuthService, DEFAULT_AUTH_SCOPES, DEFAULT_ISSUERS, NoopAuthErrorHandler, SignInDirective, SignOutDirective, authGuard, configureInterceptor, createInititals, initalizeAuthConfig, injectAuthModuleConfig, parseIdentityClaims, provideAuth, provideAuthErrorHandler };
|
|
273
390
|
//# sourceMappingURL=odx-auth.mjs.map
|