@rolatech/angular-auth 20.2.9-beta.7 → 20.3.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,35 +1,35 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Component, signal, computed, Injectable, inject, output, model, PLATFORM_ID, InjectionToken, makeEnvironmentProviders } from '@angular/core';
|
|
2
|
+
import { Component, signal, computed, Injectable, inject, output, model, PLATFORM_ID, InjectionToken, APP_INITIALIZER, makeEnvironmentProviders } from '@angular/core';
|
|
3
3
|
import { MatDialogRef, MAT_DIALOG_DATA, MatDialogModule, MatDialog } from '@angular/material/dialog';
|
|
4
4
|
import { APP_CONFIG, AngularCommonModule } from '@rolatech/angular-common';
|
|
5
5
|
import { SnackBarService } from '@rolatech/angular-services';
|
|
6
6
|
import QRCode from 'qrcode';
|
|
7
7
|
import { MatButtonModule } from '@angular/material/button';
|
|
8
8
|
import { HttpClient, HttpErrorResponse, HTTP_INTERCEPTORS } from '@angular/common/http';
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
9
|
+
import { of, forkJoin, throwError, map as map$1, BehaviorSubject, catchError as catchError$1, NEVER, firstValueFrom } from 'rxjs';
|
|
10
|
+
import { switchMap, catchError, map, finalize, shareReplay, tap, filter } from 'rxjs/operators';
|
|
11
11
|
import { SpinnerComponent, AngularComponentsModule } from '@rolatech/angular-components';
|
|
12
12
|
import * as i1 from '@angular/forms';
|
|
13
13
|
import * as i2 from '@angular/material/form-field';
|
|
14
14
|
import * as i3 from '@angular/material/input';
|
|
15
15
|
import { isPlatformBrowser, CommonModule } from '@angular/common';
|
|
16
|
-
import {
|
|
16
|
+
import { Router, provideRouter, ROUTES } from '@angular/router';
|
|
17
17
|
import { MatSnackBar } from '@angular/material/snack-bar';
|
|
18
18
|
|
|
19
19
|
class ForbiddenComponent {
|
|
20
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.
|
|
21
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.
|
|
20
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ForbiddenComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
21
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.1", type: ForbiddenComponent, isStandalone: true, selector: "rolatech-forbidden", ngImport: i0, template: "<div class=\"p-6 max-w-lg h-auto max-h-32\">\n <div class=\"flex flex-col\">\n <b>403.</b>\n <p>Forbidden page.</p>\n </div>\n</div>\n", styles: [""] });
|
|
22
22
|
}
|
|
23
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.
|
|
23
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ForbiddenComponent, decorators: [{
|
|
24
24
|
type: Component,
|
|
25
25
|
args: [{ selector: 'rolatech-forbidden', template: "<div class=\"p-6 max-w-lg h-auto max-h-32\">\n <div class=\"flex flex-col\">\n <b>403.</b>\n <p>Forbidden page.</p>\n </div>\n</div>\n" }]
|
|
26
26
|
}] });
|
|
27
27
|
|
|
28
28
|
class UnauthorizedComponent {
|
|
29
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.
|
|
30
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.
|
|
29
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: UnauthorizedComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
30
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.1", type: UnauthorizedComponent, isStandalone: true, selector: "rolatech-unauthorized", ngImport: i0, template: "<div class=\"p-6 max-w-lg h-auto max-h-32\">\n <div class=\"flex flex-col\">\n <b>401.</b>\n <p>Unauthorized page.</p>\n </div>\n</div>\n", styles: [""] });
|
|
31
31
|
}
|
|
32
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.
|
|
32
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: UnauthorizedComponent, decorators: [{
|
|
33
33
|
type: Component,
|
|
34
34
|
args: [{ selector: 'rolatech-unauthorized', template: "<div class=\"p-6 max-w-lg h-auto max-h-32\">\n <div class=\"flex flex-col\">\n <b>401.</b>\n <p>Unauthorized page.</p>\n </div>\n</div>\n" }]
|
|
35
35
|
}] });
|
|
@@ -39,24 +39,71 @@ class AuthStore {
|
|
|
39
39
|
userId: '',
|
|
40
40
|
user: null,
|
|
41
41
|
roles: [],
|
|
42
|
+
username: null,
|
|
43
|
+
platformRoles: [],
|
|
44
|
+
applications: [],
|
|
45
|
+
organizations: [],
|
|
46
|
+
permissions: [],
|
|
42
47
|
authenticated: false,
|
|
43
48
|
loaded: false,
|
|
44
49
|
}, ...(ngDevMode ? [{ debugName: "_state" }] : []));
|
|
45
50
|
userId = computed(() => this._state().userId, ...(ngDevMode ? [{ debugName: "userId" }] : []));
|
|
46
51
|
user = computed(() => this._state().user, ...(ngDevMode ? [{ debugName: "user" }] : []));
|
|
47
52
|
roles = computed(() => this._state().roles, ...(ngDevMode ? [{ debugName: "roles" }] : []));
|
|
53
|
+
username = computed(() => this._state().username, ...(ngDevMode ? [{ debugName: "username" }] : []));
|
|
54
|
+
platformRoles = computed(() => this._state().platformRoles, ...(ngDevMode ? [{ debugName: "platformRoles" }] : []));
|
|
55
|
+
applications = computed(() => this._state().applications, ...(ngDevMode ? [{ debugName: "applications" }] : []));
|
|
56
|
+
organizations = computed(() => this._state().organizations, ...(ngDevMode ? [{ debugName: "organizations" }] : []));
|
|
57
|
+
permissions = computed(() => this._state().permissions, ...(ngDevMode ? [{ debugName: "permissions" }] : []));
|
|
48
58
|
authenticated = computed(() => this._state().authenticated, ...(ngDevMode ? [{ debugName: "authenticated" }] : []));
|
|
49
59
|
loaded = computed(() => this._state().loaded, ...(ngDevMode ? [{ debugName: "loaded" }] : []));
|
|
60
|
+
me = computed(() => {
|
|
61
|
+
if (!this.loaded() || !this.authenticated()) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
userId: this.userId(),
|
|
66
|
+
username: this.username() ?? this.user()?.username ?? '',
|
|
67
|
+
platformRoles: this.platformRoles(),
|
|
68
|
+
applications: this.applications(),
|
|
69
|
+
organizations: this.organizations(),
|
|
70
|
+
permissions: this.permissions(),
|
|
71
|
+
};
|
|
72
|
+
}, ...(ngDevMode ? [{ debugName: "me" }] : []));
|
|
73
|
+
primaryApplication = computed(() => this.applications()[0] ?? null, ...(ngDevMode ? [{ debugName: "primaryApplication" }] : []));
|
|
74
|
+
primaryOrganization = computed(() => this.organizations()[0] ?? null, ...(ngDevMode ? [{ debugName: "primaryOrganization" }] : []));
|
|
50
75
|
update(data) {
|
|
51
76
|
this._state.update((state) => {
|
|
52
77
|
state.authenticated = data.authenticated;
|
|
53
|
-
state.userId = data.userId;
|
|
54
|
-
state.roles = data.roles;
|
|
55
|
-
state.loaded = data.loaded;
|
|
56
|
-
state.user = data.user;
|
|
78
|
+
state.userId = data.userId ?? state.userId;
|
|
79
|
+
state.roles = data.roles ?? state.roles;
|
|
80
|
+
state.loaded = data.loaded ?? state.loaded;
|
|
81
|
+
state.user = data.user ?? state.user;
|
|
82
|
+
state.username = data.username ?? state.username;
|
|
83
|
+
state.platformRoles = data.platformRoles ?? state.platformRoles;
|
|
84
|
+
state.applications = data.applications ?? state.applications;
|
|
85
|
+
state.organizations = data.organizations ?? state.organizations;
|
|
86
|
+
state.permissions = data.permissions ?? state.permissions;
|
|
57
87
|
return { ...state };
|
|
58
88
|
});
|
|
59
89
|
}
|
|
90
|
+
clear() {
|
|
91
|
+
this._state.set({
|
|
92
|
+
userId: '',
|
|
93
|
+
user: null,
|
|
94
|
+
roles: [],
|
|
95
|
+
username: null,
|
|
96
|
+
platformRoles: [],
|
|
97
|
+
applications: [],
|
|
98
|
+
organizations: [],
|
|
99
|
+
permissions: [],
|
|
100
|
+
authenticated: false,
|
|
101
|
+
loaded: true,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
resetLoading() {
|
|
105
|
+
this._state.update((state) => ({ ...state, loaded: false }));
|
|
106
|
+
}
|
|
60
107
|
updateAuthenticated(authenticated) {
|
|
61
108
|
this._state.update((state) => {
|
|
62
109
|
state.authenticated = authenticated;
|
|
@@ -66,9 +113,21 @@ class AuthStore {
|
|
|
66
113
|
updateUser(user) {
|
|
67
114
|
this._state.update((state) => {
|
|
68
115
|
state.user = user;
|
|
116
|
+
state.username = user.username;
|
|
69
117
|
return { ...state };
|
|
70
118
|
});
|
|
71
119
|
}
|
|
120
|
+
updateContext(context) {
|
|
121
|
+
this._state.update((state) => ({
|
|
122
|
+
...state,
|
|
123
|
+
userId: context.userId,
|
|
124
|
+
username: context.username,
|
|
125
|
+
platformRoles: context.platformRoles ?? [],
|
|
126
|
+
applications: context.applications ?? [],
|
|
127
|
+
organizations: context.organizations ?? [],
|
|
128
|
+
permissions: context.permissions ?? [],
|
|
129
|
+
}));
|
|
130
|
+
}
|
|
72
131
|
updateEmail(email) {
|
|
73
132
|
this._state.update((state) => {
|
|
74
133
|
if (state.user) {
|
|
@@ -77,10 +136,81 @@ class AuthStore {
|
|
|
77
136
|
return { ...state };
|
|
78
137
|
});
|
|
79
138
|
}
|
|
80
|
-
|
|
81
|
-
|
|
139
|
+
hasAnyRole(...roles) {
|
|
140
|
+
if (!roles.length) {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
const roleSet = new Set(this.roles());
|
|
144
|
+
return roles.some((role) => roleSet.has(role));
|
|
145
|
+
}
|
|
146
|
+
hasPlatformRole(...roles) {
|
|
147
|
+
if (!roles.length) {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
const roleSet = new Set(this.platformRoles().length ? this.platformRoles() : this.roles());
|
|
151
|
+
return roles.some((role) => roleSet.has(role));
|
|
152
|
+
}
|
|
153
|
+
hasApplicationRole(appId, ...roles) {
|
|
154
|
+
if (!roles.length) {
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
return this.applications().some((membership) => {
|
|
158
|
+
if (appId && membership.appId !== appId) {
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
const roleSet = new Set(membership.roles);
|
|
162
|
+
return roles.some((role) => roleSet.has(role));
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
hasOrganizationRole(appId, orgId, ...roles) {
|
|
166
|
+
if (!roles.length) {
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
return this.organizations().some((membership) => {
|
|
170
|
+
if (appId && membership.appId !== appId) {
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
if (orgId && membership.orgId !== orgId) {
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
const roleSet = new Set(membership.roles);
|
|
177
|
+
return roles.some((role) => roleSet.has(role));
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
hasPermission(permission) {
|
|
181
|
+
return this.permissions().includes(permission);
|
|
182
|
+
}
|
|
183
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AuthStore, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
184
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AuthStore, providedIn: 'root' });
|
|
185
|
+
}
|
|
186
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AuthStore, decorators: [{
|
|
187
|
+
type: Injectable,
|
|
188
|
+
args: [{ providedIn: 'root' }]
|
|
189
|
+
}] });
|
|
190
|
+
|
|
191
|
+
class AuthContextStore {
|
|
192
|
+
state = signal({
|
|
193
|
+
appId: null,
|
|
194
|
+
orgId: null,
|
|
195
|
+
}, ...(ngDevMode ? [{ debugName: "state" }] : []));
|
|
196
|
+
appId = computed(() => this.state().appId, ...(ngDevMode ? [{ debugName: "appId" }] : []));
|
|
197
|
+
orgId = computed(() => this.state().orgId, ...(ngDevMode ? [{ debugName: "orgId" }] : []));
|
|
198
|
+
setContext(appId, orgId) {
|
|
199
|
+
this.state.set({ appId, orgId });
|
|
200
|
+
}
|
|
201
|
+
setAppId(appId) {
|
|
202
|
+
this.state.update((state) => ({ ...state, appId }));
|
|
203
|
+
}
|
|
204
|
+
setOrgId(orgId) {
|
|
205
|
+
this.state.update((state) => ({ ...state, orgId }));
|
|
206
|
+
}
|
|
207
|
+
clear() {
|
|
208
|
+
this.state.set({ appId: null, orgId: null });
|
|
209
|
+
}
|
|
210
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AuthContextStore, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
211
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AuthContextStore, providedIn: 'root' });
|
|
82
212
|
}
|
|
83
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.
|
|
213
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AuthContextStore, decorators: [{
|
|
84
214
|
type: Injectable,
|
|
85
215
|
args: [{ providedIn: 'root' }]
|
|
86
216
|
}] });
|
|
@@ -88,39 +218,81 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImpor
|
|
|
88
218
|
class AuthService {
|
|
89
219
|
environment = inject(APP_CONFIG);
|
|
90
220
|
http = inject(HttpClient);
|
|
91
|
-
route = inject(ActivatedRoute);
|
|
92
221
|
authStore = inject(AuthStore);
|
|
222
|
+
authContextStore = inject(AuthContextStore);
|
|
93
223
|
authenticated = this.authStore.authenticated;
|
|
94
224
|
userId = this.authStore.userId;
|
|
95
225
|
user = this.authStore.user;
|
|
96
226
|
roles = this.authStore.roles;
|
|
227
|
+
meContext = this.authStore.me;
|
|
228
|
+
platformRoles = this.authStore.platformRoles;
|
|
229
|
+
applications = this.authStore.applications;
|
|
230
|
+
organizations = this.authStore.organizations;
|
|
231
|
+
permissions = this.authStore.permissions;
|
|
97
232
|
loaded = this.authStore.loaded;
|
|
98
|
-
|
|
99
|
-
|
|
233
|
+
pendingIntrospect$;
|
|
234
|
+
introspect(force = false) {
|
|
235
|
+
if (!force && this.authStore.loaded()) {
|
|
236
|
+
return of(this.currentSession());
|
|
237
|
+
}
|
|
238
|
+
if (!force && this.pendingIntrospect$) {
|
|
239
|
+
return this.pendingIntrospect$;
|
|
240
|
+
}
|
|
241
|
+
const request$ = this.http
|
|
100
242
|
.get(`${this.environment.baseUrl}/auth/introspect`, {
|
|
101
243
|
withCredentials: true,
|
|
102
244
|
})
|
|
103
|
-
.pipe(
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
loaded: true,
|
|
109
|
-
});
|
|
110
|
-
if (res.authenticated) {
|
|
111
|
-
this.me().subscribe();
|
|
245
|
+
.pipe(switchMap((res) => {
|
|
246
|
+
if (!res.authenticated) {
|
|
247
|
+
this.authStore.clear();
|
|
248
|
+
this.authContextStore.clear();
|
|
249
|
+
return of(res);
|
|
112
250
|
}
|
|
113
|
-
return
|
|
114
|
-
|
|
251
|
+
return forkJoin({
|
|
252
|
+
user: this.me().pipe(catchError(() => of(null))),
|
|
253
|
+
context: this.getMeContext().pipe(catchError(() => of(this.emptyContext(res)))),
|
|
254
|
+
}).pipe(map(({ user, context }) => {
|
|
255
|
+
this.authStore.update({
|
|
256
|
+
authenticated: true,
|
|
257
|
+
userId: res.userId,
|
|
258
|
+
roles: res.roles ?? [],
|
|
259
|
+
loaded: true,
|
|
260
|
+
user,
|
|
261
|
+
username: context.username ?? res.username ?? user?.username ?? null,
|
|
262
|
+
platformRoles: context.platformRoles?.length ? context.platformRoles : (res.roles ?? []),
|
|
263
|
+
applications: context.applications ?? [],
|
|
264
|
+
organizations: context.organizations ?? [],
|
|
265
|
+
permissions: context.permissions ?? [],
|
|
266
|
+
});
|
|
267
|
+
this.syncContext(context);
|
|
268
|
+
return res;
|
|
269
|
+
}));
|
|
270
|
+
}), catchError((error) => {
|
|
271
|
+
this.authStore.clear();
|
|
272
|
+
this.authContextStore.clear();
|
|
273
|
+
return throwError(() => error);
|
|
274
|
+
}), finalize(() => {
|
|
275
|
+
this.pendingIntrospect$ = undefined;
|
|
276
|
+
}), shareReplay(1));
|
|
277
|
+
this.pendingIntrospect$ = request$;
|
|
278
|
+
return request$;
|
|
279
|
+
}
|
|
280
|
+
ensureLoaded(force = false) {
|
|
281
|
+
return this.introspect(force);
|
|
282
|
+
}
|
|
283
|
+
getMeContext() {
|
|
284
|
+
return this.http
|
|
285
|
+
.get(`${this.environment.baseUrl}/auth/me/context`)
|
|
286
|
+
.pipe(map((res) => res.data));
|
|
115
287
|
}
|
|
116
288
|
me() {
|
|
117
289
|
return this.http
|
|
118
|
-
.get(`${this.environment.baseUrl}/auth/
|
|
290
|
+
.get(`${this.environment.baseUrl}/auth/me`, {
|
|
119
291
|
withCredentials: true,
|
|
120
292
|
})
|
|
121
293
|
.pipe(map((res) => {
|
|
122
294
|
this.authStore.updateUser(res.data);
|
|
123
|
-
return res;
|
|
295
|
+
return res.data;
|
|
124
296
|
}));
|
|
125
297
|
}
|
|
126
298
|
wechatLogin(code, state) {
|
|
@@ -161,7 +333,7 @@ class AuthService {
|
|
|
161
333
|
withCredentials: true,
|
|
162
334
|
})
|
|
163
335
|
.pipe(map((res) => {
|
|
164
|
-
this.authStore.
|
|
336
|
+
this.authStore.resetLoading();
|
|
165
337
|
return res.data;
|
|
166
338
|
}));
|
|
167
339
|
}
|
|
@@ -171,7 +343,7 @@ class AuthService {
|
|
|
171
343
|
withCredentials: true,
|
|
172
344
|
})
|
|
173
345
|
.pipe(map((res) => {
|
|
174
|
-
this.authStore.
|
|
346
|
+
this.authStore.resetLoading();
|
|
175
347
|
return res;
|
|
176
348
|
}));
|
|
177
349
|
}
|
|
@@ -181,7 +353,8 @@ class AuthService {
|
|
|
181
353
|
withCredentials: true,
|
|
182
354
|
})
|
|
183
355
|
.pipe(map((res) => {
|
|
184
|
-
this.authStore.
|
|
356
|
+
this.authStore.clear();
|
|
357
|
+
this.authContextStore.clear();
|
|
185
358
|
return res;
|
|
186
359
|
}));
|
|
187
360
|
}
|
|
@@ -202,7 +375,7 @@ class AuthService {
|
|
|
202
375
|
.pipe(map((user) => {
|
|
203
376
|
return user;
|
|
204
377
|
}), tap((_) => {
|
|
205
|
-
this.authStore.
|
|
378
|
+
this.authStore.resetLoading();
|
|
206
379
|
}));
|
|
207
380
|
}
|
|
208
381
|
lookup(account, next) {
|
|
@@ -225,13 +398,60 @@ class AuthService {
|
|
|
225
398
|
.pipe(map((user) => {
|
|
226
399
|
return user;
|
|
227
400
|
}), tap((_) => {
|
|
228
|
-
this.authStore.
|
|
401
|
+
this.authStore.resetLoading();
|
|
229
402
|
}));
|
|
230
403
|
}
|
|
231
|
-
|
|
232
|
-
|
|
404
|
+
hasAnyRole(...roles) {
|
|
405
|
+
return this.authStore.hasAnyRole(...roles);
|
|
406
|
+
}
|
|
407
|
+
hasPlatformRole(...roles) {
|
|
408
|
+
return this.authStore.hasPlatformRole(...roles);
|
|
409
|
+
}
|
|
410
|
+
hasApplicationRole(appId, ...roles) {
|
|
411
|
+
return this.authStore.hasApplicationRole(appId, ...roles);
|
|
412
|
+
}
|
|
413
|
+
hasOrganizationRole(appId, orgId, ...roles) {
|
|
414
|
+
return this.authStore.hasOrganizationRole(appId, orgId, ...roles);
|
|
415
|
+
}
|
|
416
|
+
hasPermission(permission) {
|
|
417
|
+
return this.authStore.hasPermission(permission);
|
|
418
|
+
}
|
|
419
|
+
emptyContext(res) {
|
|
420
|
+
return {
|
|
421
|
+
userId: res.userId,
|
|
422
|
+
username: res.username ?? '',
|
|
423
|
+
platformRoles: [],
|
|
424
|
+
applications: [],
|
|
425
|
+
organizations: [],
|
|
426
|
+
permissions: [],
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
syncContext(context) {
|
|
430
|
+
if (this.authContextStore.appId() || this.authContextStore.orgId()) {
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
433
|
+
const primaryOrganization = context.organizations[0] ?? null;
|
|
434
|
+
if (primaryOrganization) {
|
|
435
|
+
this.authContextStore.setContext(primaryOrganization.appId, primaryOrganization.orgId);
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
438
|
+
const primaryApplication = context.applications[0] ?? null;
|
|
439
|
+
if (primaryApplication) {
|
|
440
|
+
this.authContextStore.setAppId(primaryApplication.appId);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
currentSession() {
|
|
444
|
+
return {
|
|
445
|
+
authenticated: !!this.authStore.authenticated(),
|
|
446
|
+
userId: this.authStore.userId(),
|
|
447
|
+
roles: this.authStore.roles(),
|
|
448
|
+
username: this.authStore.username() ?? this.authStore.user()?.username,
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AuthService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
452
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AuthService, providedIn: 'root' });
|
|
233
453
|
}
|
|
234
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.
|
|
454
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AuthService, decorators: [{
|
|
235
455
|
type: Injectable,
|
|
236
456
|
args: [{ providedIn: 'root' }]
|
|
237
457
|
}] });
|
|
@@ -290,10 +510,10 @@ class FaceidDetectDialogComponent {
|
|
|
290
510
|
console.error(err);
|
|
291
511
|
}
|
|
292
512
|
}
|
|
293
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.
|
|
294
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.
|
|
513
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: FaceidDetectDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
514
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: FaceidDetectDialogComponent, isStandalone: true, selector: "rolatech-faceid-detect-dialog", outputs: { output: "output" }, ngImport: i0, template: "<div class=\"flex flex-col p-3 max-w-[500px] mx-auto\">\n <div class=\"w-[256px] h-[256px] mx-auto flex justify-center items-center\">\n @if (loading) {\n <div>\n <rolatech-spinner></rolatech-spinner>\n </div>\n }\n <img [src]=\"qrcodeUrl\" alt />\n </div>\n</div>\n", styles: ["*{margin:0;padding:0}.normalPanel .panelContent{width:188px;height:188px}.normalPanel .wrp_code{position:relative;width:188px;height:188px;margin:0}.impowerBox .title,.normalPanel .info{display:none}.impowerBox .qrcode{margin-top:0;border:0;width:188px;height:188px}#MAXIM{content:\"veg20170418191511\"}mat-mdc-dialog-content mdc-dialog__content{padding:0}\n"], dependencies: [{ kind: "component", type: SpinnerComponent, selector: "rolatech-spinner", inputs: ["title"] }, { kind: "ngmodule", type: MatButtonModule }] });
|
|
295
515
|
}
|
|
296
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.
|
|
516
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: FaceidDetectDialogComponent, decorators: [{
|
|
297
517
|
type: Component,
|
|
298
518
|
args: [{ selector: 'rolatech-faceid-detect-dialog', imports: [SpinnerComponent, MatButtonModule], template: "<div class=\"flex flex-col p-3 max-w-[500px] mx-auto\">\n <div class=\"w-[256px] h-[256px] mx-auto flex justify-center items-center\">\n @if (loading) {\n <div>\n <rolatech-spinner></rolatech-spinner>\n </div>\n }\n <img [src]=\"qrcodeUrl\" alt />\n </div>\n</div>\n", styles: ["*{margin:0;padding:0}.normalPanel .panelContent{width:188px;height:188px}.normalPanel .wrp_code{position:relative;width:188px;height:188px;margin:0}.impowerBox .title,.normalPanel .info{display:none}.impowerBox .qrcode{margin-top:0;border:0;width:188px;height:188px}#MAXIM{content:\"veg20170418191511\"}mat-mdc-dialog-content mdc-dialog__content{padding:0}\n"] }]
|
|
299
519
|
}], ctorParameters: () => [], propDecorators: { output: [{ type: i0.Output, args: ["output"] }] } });
|
|
@@ -322,10 +542,10 @@ class AddressComponent {
|
|
|
322
542
|
ngDoCheck() {
|
|
323
543
|
this.output.emit(this.address());
|
|
324
544
|
}
|
|
325
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.
|
|
326
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.
|
|
545
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AddressComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
546
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: AddressComponent, isStandalone: true, selector: "rolatech-address", inputs: { address: { classPropertyName: "address", publicName: "address", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { address: "addressChange", output: "output" }, ngImport: i0, template: "<div>\n <mat-form-field appearance=\"fill\">\n <mat-label i18n> Name </mat-label>\n <input matInput [(ngModel)]=\"address().name\" />\n </mat-form-field>\n @if (address().type === addressType.BILLING) {\n <mat-form-field appearance=\"fill\">\n <mat-label i18n> Email </mat-label>\n <input matInput [(ngModel)]=\"address().email\" />\n </mat-form-field>\n }\n <mat-form-field appearance=\"fill\">\n <mat-label i18n> Phone </mat-label>\n <input matInput [(ngModel)]=\"address().phone\" />\n </mat-form-field>\n <mat-form-field appearance=\"fill\">\n <mat-label i18n> province </mat-label>\n <input matInput [(ngModel)]=\"address().province\" />\n </mat-form-field>\n <mat-form-field appearance=\"fill\">\n <mat-label i18n> City </mat-label>\n <input matInput [(ngModel)]=\"address().city\" />\n </mat-form-field>\n <mat-form-field appearance=\"fill\">\n <mat-label i18n> District </mat-label>\n <input matInput [(ngModel)]=\"address().district\" />\n </mat-form-field>\n <mat-form-field appearance=\"fill\">\n <mat-label i18n> Street </mat-label>\n <input matInput [(ngModel)]=\"address().street\" />\n </mat-form-field>\n <mat-form-field appearance=\"fill\">\n <mat-label i18n> Detail </mat-label>\n <input matInput [(ngModel)]=\"address().detail\" />\n </mat-form-field>\n</div>\n", styles: ["mat-form-field{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: AngularCommonModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AngularComponentsModule }, { kind: "component", type: i2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }] });
|
|
327
547
|
}
|
|
328
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.
|
|
548
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AddressComponent, decorators: [{
|
|
329
549
|
type: Component,
|
|
330
550
|
args: [{ selector: 'rolatech-address', imports: [AngularCommonModule, AngularComponentsModule], template: "<div>\n <mat-form-field appearance=\"fill\">\n <mat-label i18n> Name </mat-label>\n <input matInput [(ngModel)]=\"address().name\" />\n </mat-form-field>\n @if (address().type === addressType.BILLING) {\n <mat-form-field appearance=\"fill\">\n <mat-label i18n> Email </mat-label>\n <input matInput [(ngModel)]=\"address().email\" />\n </mat-form-field>\n }\n <mat-form-field appearance=\"fill\">\n <mat-label i18n> Phone </mat-label>\n <input matInput [(ngModel)]=\"address().phone\" />\n </mat-form-field>\n <mat-form-field appearance=\"fill\">\n <mat-label i18n> province </mat-label>\n <input matInput [(ngModel)]=\"address().province\" />\n </mat-form-field>\n <mat-form-field appearance=\"fill\">\n <mat-label i18n> City </mat-label>\n <input matInput [(ngModel)]=\"address().city\" />\n </mat-form-field>\n <mat-form-field appearance=\"fill\">\n <mat-label i18n> District </mat-label>\n <input matInput [(ngModel)]=\"address().district\" />\n </mat-form-field>\n <mat-form-field appearance=\"fill\">\n <mat-label i18n> Street </mat-label>\n <input matInput [(ngModel)]=\"address().street\" />\n </mat-form-field>\n <mat-form-field appearance=\"fill\">\n <mat-label i18n> Detail </mat-label>\n <input matInput [(ngModel)]=\"address().detail\" />\n </mat-form-field>\n</div>\n", styles: ["mat-form-field{width:100%}\n"] }]
|
|
331
551
|
}], propDecorators: { address: [{ type: i0.Input, args: [{ isSignal: true, alias: "address", required: false }] }, { type: i0.Output, args: ["addressChange"] }], output: [{ type: i0.Output, args: ["output"] }] } });
|
|
@@ -341,7 +561,7 @@ const AuthGuard = (route, state) => {
|
|
|
341
561
|
const isContinue = state.url.includes('continue');
|
|
342
562
|
const continueUrl = route.queryParams['continue'];
|
|
343
563
|
const isSignInPage = state.url.includes('/signin');
|
|
344
|
-
return authService.
|
|
564
|
+
return authService.ensureLoaded().pipe(map$1(({ roles, authenticated }) => {
|
|
345
565
|
const routeRoles = route.data['roles'];
|
|
346
566
|
const passRoled = routeRoles ? roles?.some((r) => routeRoles.indexOf(r) >= 0) : true;
|
|
347
567
|
if (authenticated && !passRoled) {
|
|
@@ -381,10 +601,10 @@ const AuthGuard = (route, state) => {
|
|
|
381
601
|
|
|
382
602
|
class AuthDialogComponent {
|
|
383
603
|
dialogRef = inject(MatDialogRef);
|
|
384
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.
|
|
385
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.
|
|
604
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AuthDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
605
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.1", type: AuthDialogComponent, isStandalone: true, selector: "rolatech-auth-dialog", ngImport: i0, template: "<p>auth-dialog works!</p>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatDialogModule }] });
|
|
386
606
|
}
|
|
387
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.
|
|
607
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AuthDialogComponent, decorators: [{
|
|
388
608
|
type: Component,
|
|
389
609
|
args: [{ selector: 'rolatech-auth-dialog', imports: [CommonModule, MatDialogModule], template: "<p>auth-dialog works!</p>\n" }]
|
|
390
610
|
}] });
|
|
@@ -419,6 +639,93 @@ const AuthDialogGuard = (route, state) => {
|
|
|
419
639
|
}));
|
|
420
640
|
};
|
|
421
641
|
|
|
642
|
+
function matchesRouteAccessPolicy(authStore, authContextStore, policy) {
|
|
643
|
+
if (!policy) {
|
|
644
|
+
return true;
|
|
645
|
+
}
|
|
646
|
+
if (policy.authenticated !== undefined && authStore.authenticated() !== policy.authenticated) {
|
|
647
|
+
return false;
|
|
648
|
+
}
|
|
649
|
+
const appId = authContextStore.appId() ?? authStore.primaryApplication()?.appId ?? authStore.primaryOrganization()?.appId ?? null;
|
|
650
|
+
const orgId = authContextStore.orgId() ?? authStore.primaryOrganization()?.orgId ?? null;
|
|
651
|
+
const groupMatches = [];
|
|
652
|
+
if (policy.anyRole?.length) {
|
|
653
|
+
groupMatches.push(authStore.hasAnyRole(...policy.anyRole));
|
|
654
|
+
}
|
|
655
|
+
if (policy.anyPlatformRole?.length) {
|
|
656
|
+
groupMatches.push(authStore.hasPlatformRole(...policy.anyPlatformRole));
|
|
657
|
+
}
|
|
658
|
+
if (policy.anyApplicationRole?.length) {
|
|
659
|
+
groupMatches.push(authStore.hasApplicationRole(appId, ...policy.anyApplicationRole));
|
|
660
|
+
}
|
|
661
|
+
if (policy.anyOrganizationRole?.length) {
|
|
662
|
+
groupMatches.push(authStore.hasOrganizationRole(appId, orgId, ...policy.anyOrganizationRole));
|
|
663
|
+
}
|
|
664
|
+
if (policy.anyPermission?.length) {
|
|
665
|
+
groupMatches.push(policy.anyPermission.some((permission) => authStore.hasPermission(permission)));
|
|
666
|
+
}
|
|
667
|
+
if (!groupMatches.length) {
|
|
668
|
+
return true;
|
|
669
|
+
}
|
|
670
|
+
return groupMatches.some(Boolean);
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
function accessGuard(policy, fallbackUrl = '/forbidden') {
|
|
674
|
+
return () => {
|
|
675
|
+
const router = inject(Router);
|
|
676
|
+
const authService = inject(AuthService);
|
|
677
|
+
const authStore = inject(AuthStore);
|
|
678
|
+
const authContextStore = inject(AuthContextStore);
|
|
679
|
+
return authService.ensureLoaded().pipe(map(() => (matchesRouteAccessPolicy(authStore, authContextStore, policy) ? true : router.parseUrl(fallbackUrl))));
|
|
680
|
+
};
|
|
681
|
+
}
|
|
682
|
+
function accessMatchGuard(policy, fallbackUrl = '/forbidden') {
|
|
683
|
+
return () => {
|
|
684
|
+
const router = inject(Router);
|
|
685
|
+
const authService = inject(AuthService);
|
|
686
|
+
const authStore = inject(AuthStore);
|
|
687
|
+
const authContextStore = inject(AuthContextStore);
|
|
688
|
+
return authService.ensureLoaded().pipe(map(() => (matchesRouteAccessPolicy(authStore, authContextStore, policy) ? true : router.parseUrl(fallbackUrl))));
|
|
689
|
+
};
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
const PLATFORM_ADMIN_ROLES = ['PLATFORM_ADMIN', 'ROLE_PLATFORM_ADMIN'];
|
|
693
|
+
const APPLICATION_OWNER_ROLES = ['APPLICATION_OWNER', 'APP_OWNER', 'ROLE_APPLICATION_OWNER', 'ROLE_APP_OWNER'];
|
|
694
|
+
const APPLICATION_ADMIN_ROLES = ['APPLICATION_ADMIN', 'APP_ADMIN', 'ROLE_APPLICATION_ADMIN', 'ROLE_APP_ADMIN'];
|
|
695
|
+
const ORGANIZATION_OWNER_ROLES = ['ORGANIZATION_OWNER', 'ORG_OWNER', 'ROLE_ORGANIZATION_OWNER', 'ROLE_ORG_OWNER'];
|
|
696
|
+
const ORGANIZATION_ADMIN_ROLES = ['ORGANIZATION_ADMIN', 'ORG_ADMIN', 'ROLE_ORGANIZATION_ADMIN', 'ROLE_ORG_ADMIN'];
|
|
697
|
+
const ORGANIZATION_MEMBER_ROLES = ['ORGANIZATION_MEMBER', 'ORG_MEMBER', 'ROLE_ORGANIZATION_MEMBER', 'ROLE_ORG_MEMBER'];
|
|
698
|
+
const ORGANIZATION_STAFF_ROLES = ['ORGANIZATION_STAFF', 'ORG_STAFF', 'ROLE_ORGANIZATION_STAFF', 'ROLE_ORG_STAFF'];
|
|
699
|
+
|
|
700
|
+
function landingRedirectGuard(targets = {}) {
|
|
701
|
+
const resolvedTargets = {
|
|
702
|
+
platform: targets.platform ?? '/platform',
|
|
703
|
+
application: targets.application ?? '/app',
|
|
704
|
+
organization: targets.organization ?? '/organization',
|
|
705
|
+
forbidden: targets.forbidden ?? '/forbidden',
|
|
706
|
+
};
|
|
707
|
+
return () => {
|
|
708
|
+
const router = inject(Router);
|
|
709
|
+
const authService = inject(AuthService);
|
|
710
|
+
const authStore = inject(AuthStore);
|
|
711
|
+
const authContextStore = inject(AuthContextStore);
|
|
712
|
+
return authService.ensureLoaded().pipe(map(() => {
|
|
713
|
+
const appId = authContextStore.appId() ?? authStore.primaryApplication()?.appId ?? authStore.primaryOrganization()?.appId ?? null;
|
|
714
|
+
const orgId = authContextStore.orgId() ?? authStore.primaryOrganization()?.orgId ?? null;
|
|
715
|
+
if (authStore.hasPlatformRole(...PLATFORM_ADMIN_ROLES)) {
|
|
716
|
+
return router.parseUrl(resolvedTargets.platform);
|
|
717
|
+
}
|
|
718
|
+
if (authStore.hasApplicationRole(appId, ...APPLICATION_OWNER_ROLES, ...APPLICATION_ADMIN_ROLES)) {
|
|
719
|
+
return router.parseUrl(resolvedTargets.application);
|
|
720
|
+
}
|
|
721
|
+
if (authStore.hasOrganizationRole(appId, orgId, ...ORGANIZATION_OWNER_ROLES, ...ORGANIZATION_ADMIN_ROLES, ...ORGANIZATION_MEMBER_ROLES, ...ORGANIZATION_STAFF_ROLES)) {
|
|
722
|
+
return router.parseUrl(resolvedTargets.organization);
|
|
723
|
+
}
|
|
724
|
+
return router.parseUrl(resolvedTargets.forbidden);
|
|
725
|
+
}));
|
|
726
|
+
};
|
|
727
|
+
}
|
|
728
|
+
|
|
422
729
|
const RoleGuard = (route, state) => {
|
|
423
730
|
const authService = inject(AuthService);
|
|
424
731
|
const environment = inject(APP_CONFIG);
|
|
@@ -434,7 +741,7 @@ const RoleGuard = (route, state) => {
|
|
|
434
741
|
// if (!routeRoles) {
|
|
435
742
|
// return of(false);
|
|
436
743
|
// }
|
|
437
|
-
return authService.
|
|
744
|
+
return authService.ensureLoaded().pipe(filter((res) => res.roles !== null && res.roles.length > 0), map$1(({ roles }) => {
|
|
438
745
|
const authed = roles.some((r) => routeRoles?.indexOf(r) >= 0);
|
|
439
746
|
if (!authed) {
|
|
440
747
|
router.navigate(['/forbidden']);
|
|
@@ -481,7 +788,7 @@ class AuthUserService {
|
|
|
481
788
|
}
|
|
482
789
|
me() {
|
|
483
790
|
return this.http
|
|
484
|
-
.get(`${this.environment.baseUrl}/auth/
|
|
791
|
+
.get(`${this.environment.baseUrl}/auth/me`, {
|
|
485
792
|
withCredentials: true,
|
|
486
793
|
})
|
|
487
794
|
.pipe(map$1((res) => {
|
|
@@ -506,6 +813,19 @@ class AuthUserService {
|
|
|
506
813
|
sendSMSCode(countryCode, phone) {
|
|
507
814
|
return this.http.post(`${this.environment.baseUrl}/auth/users/verification/phone/start`, { countryCode, phone });
|
|
508
815
|
}
|
|
816
|
+
verifyEmailByToken(token) {
|
|
817
|
+
return this.http
|
|
818
|
+
.post(`${this.environment.baseUrl}/auth/users/verification/email`, {}, {
|
|
819
|
+
params: { token },
|
|
820
|
+
withCredentials: true,
|
|
821
|
+
})
|
|
822
|
+
.pipe(map$1((response) => {
|
|
823
|
+
if (typeof response === 'boolean') {
|
|
824
|
+
return response;
|
|
825
|
+
}
|
|
826
|
+
return Boolean(response.data);
|
|
827
|
+
}));
|
|
828
|
+
}
|
|
509
829
|
findByUsername(username) {
|
|
510
830
|
return this.http.get(`${this.environment.baseUrl}/auth/users/info`, {
|
|
511
831
|
params: { username },
|
|
@@ -530,7 +850,7 @@ class AuthUserService {
|
|
|
530
850
|
});
|
|
531
851
|
}
|
|
532
852
|
changeName(name) {
|
|
533
|
-
return this.http.put(`${this.environment.baseUrl}/auth/
|
|
853
|
+
return this.http.put(`${this.environment.baseUrl}/auth/me`, { name }, {
|
|
534
854
|
withCredentials: true,
|
|
535
855
|
});
|
|
536
856
|
}
|
|
@@ -540,7 +860,7 @@ class AuthUserService {
|
|
|
540
860
|
});
|
|
541
861
|
}
|
|
542
862
|
update(data) {
|
|
543
|
-
return this.http.put(`${this.environment.baseUrl}/auth/
|
|
863
|
+
return this.http.put(`${this.environment.baseUrl}/auth/me`, data, {
|
|
544
864
|
withCredentials: true,
|
|
545
865
|
});
|
|
546
866
|
}
|
|
@@ -598,10 +918,10 @@ class AuthUserService {
|
|
|
598
918
|
deleteAddressById(id) {
|
|
599
919
|
return this.http.delete(`${this.environment.baseUrl}/auth/users/addresses/${id}`, { withCredentials: true });
|
|
600
920
|
}
|
|
601
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.
|
|
602
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.
|
|
921
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AuthUserService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
922
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AuthUserService, providedIn: 'root' });
|
|
603
923
|
}
|
|
604
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.
|
|
924
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AuthUserService, decorators: [{
|
|
605
925
|
type: Injectable,
|
|
606
926
|
args: [{
|
|
607
927
|
providedIn: 'root',
|
|
@@ -648,10 +968,10 @@ class AuthAgentService {
|
|
|
648
968
|
withCredentials: true,
|
|
649
969
|
});
|
|
650
970
|
}
|
|
651
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.
|
|
652
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.
|
|
971
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AuthAgentService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
972
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AuthAgentService, providedIn: 'root' });
|
|
653
973
|
}
|
|
654
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.
|
|
974
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AuthAgentService, decorators: [{
|
|
655
975
|
type: Injectable,
|
|
656
976
|
args: [{
|
|
657
977
|
providedIn: 'root',
|
|
@@ -695,10 +1015,10 @@ class LocalStorageService {
|
|
|
695
1015
|
setItem(key, value) {
|
|
696
1016
|
return this.storage.setItem(key, value);
|
|
697
1017
|
}
|
|
698
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.
|
|
699
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.
|
|
1018
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: LocalStorageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1019
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: LocalStorageService, providedIn: 'root' });
|
|
700
1020
|
}
|
|
701
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.
|
|
1021
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: LocalStorageService, decorators: [{
|
|
702
1022
|
type: Injectable,
|
|
703
1023
|
args: [{
|
|
704
1024
|
providedIn: 'root',
|
|
@@ -710,7 +1030,7 @@ class ErrorInterceptor {
|
|
|
710
1030
|
isRefreshingToken = false;
|
|
711
1031
|
authService = inject(AuthService);
|
|
712
1032
|
intercept(request, next) {
|
|
713
|
-
return next.handle(request).pipe(catchError((error) => {
|
|
1033
|
+
return next.handle(request).pipe(catchError$1((error) => {
|
|
714
1034
|
if (error instanceof HttpErrorResponse) {
|
|
715
1035
|
switch (error.status) {
|
|
716
1036
|
case 400:
|
|
@@ -753,13 +1073,12 @@ class ErrorInterceptor {
|
|
|
753
1073
|
return throwError(() => error.error);
|
|
754
1074
|
}
|
|
755
1075
|
handleDefaultError(error) {
|
|
756
|
-
return throwError(() => new Error('
|
|
757
|
-
// return throwError(() => error.error);
|
|
1076
|
+
return throwError(() => new Error('System error'));
|
|
758
1077
|
}
|
|
759
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.
|
|
760
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.
|
|
1078
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ErrorInterceptor, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1079
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ErrorInterceptor });
|
|
761
1080
|
}
|
|
762
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.
|
|
1081
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ErrorInterceptor, decorators: [{
|
|
763
1082
|
type: Injectable
|
|
764
1083
|
}] });
|
|
765
1084
|
|
|
@@ -777,7 +1096,7 @@ class AuthInterceptor {
|
|
|
777
1096
|
// // window.location.href = res.headers.get('Location') as string;
|
|
778
1097
|
// }
|
|
779
1098
|
return res;
|
|
780
|
-
}), catchError
|
|
1099
|
+
}), catchError((error) => {
|
|
781
1100
|
if (isPlatformBrowser(this.platformId)) {
|
|
782
1101
|
if (error.url?.includes('auth/introspect')) {
|
|
783
1102
|
// if (window.location.origin !== `${this.environment.accountsUrl}`) {
|
|
@@ -808,10 +1127,10 @@ class AuthInterceptor {
|
|
|
808
1127
|
},
|
|
809
1128
|
});
|
|
810
1129
|
}
|
|
811
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.
|
|
812
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.
|
|
1130
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AuthInterceptor, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1131
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AuthInterceptor });
|
|
813
1132
|
}
|
|
814
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.
|
|
1133
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AuthInterceptor, decorators: [{
|
|
815
1134
|
type: Injectable
|
|
816
1135
|
}], ctorParameters: () => [] });
|
|
817
1136
|
|
|
@@ -835,6 +1154,20 @@ function provideAngularAuth(config) {
|
|
|
835
1154
|
useClass: AuthInterceptor,
|
|
836
1155
|
multi: true,
|
|
837
1156
|
},
|
|
1157
|
+
{
|
|
1158
|
+
provide: APP_INITIALIZER,
|
|
1159
|
+
multi: true,
|
|
1160
|
+
useFactory: () => {
|
|
1161
|
+
const authService = inject(AuthService);
|
|
1162
|
+
const platformId = inject(PLATFORM_ID);
|
|
1163
|
+
return () => {
|
|
1164
|
+
if (config?.autoLoadSession === false || !isPlatformBrowser(platformId)) {
|
|
1165
|
+
return Promise.resolve();
|
|
1166
|
+
}
|
|
1167
|
+
return firstValueFrom(authService.ensureLoaded().pipe(catchError(() => of(null))));
|
|
1168
|
+
};
|
|
1169
|
+
},
|
|
1170
|
+
},
|
|
838
1171
|
];
|
|
839
1172
|
return makeEnvironmentProviders(providers);
|
|
840
1173
|
}
|
|
@@ -850,9 +1183,116 @@ const authRoutes = [
|
|
|
850
1183
|
},
|
|
851
1184
|
];
|
|
852
1185
|
|
|
1186
|
+
const ROLE_NAVIGATION_LINKS = new InjectionToken('ROLE_NAVIGATION_LINKS');
|
|
1187
|
+
function provideRoleNavigation(links) {
|
|
1188
|
+
const providers = [
|
|
1189
|
+
{
|
|
1190
|
+
provide: ROLE_NAVIGATION_LINKS,
|
|
1191
|
+
useValue: links,
|
|
1192
|
+
multi: true,
|
|
1193
|
+
},
|
|
1194
|
+
];
|
|
1195
|
+
return makeEnvironmentProviders(providers);
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
class AppNavigationService {
|
|
1199
|
+
authStore = inject(AuthStore);
|
|
1200
|
+
authContextStore = inject(AuthContextStore);
|
|
1201
|
+
linkGroups = inject(ROLE_NAVIGATION_LINKS, { optional: true }) ?? [];
|
|
1202
|
+
links = computed(() => {
|
|
1203
|
+
this.authStore.authenticated();
|
|
1204
|
+
this.authStore.loaded();
|
|
1205
|
+
this.authContextStore.appId();
|
|
1206
|
+
this.authContextStore.orgId();
|
|
1207
|
+
return this.linkGroups
|
|
1208
|
+
.flat()
|
|
1209
|
+
.sort((left, right) => (left.order ?? 0) - (right.order ?? 0))
|
|
1210
|
+
.map((link) => this.toNavLink(link))
|
|
1211
|
+
.filter((link) => link !== null);
|
|
1212
|
+
}, ...(ngDevMode ? [{ debugName: "links" }] : []));
|
|
1213
|
+
toNavLink(link) {
|
|
1214
|
+
if (link.visible === false || !matchesRouteAccessPolicy(this.authStore, this.authContextStore, link.access)) {
|
|
1215
|
+
return null;
|
|
1216
|
+
}
|
|
1217
|
+
const children = link.children
|
|
1218
|
+
?.map((child) => this.toNavLink(child))
|
|
1219
|
+
.filter((child) => child !== null);
|
|
1220
|
+
if (link.children?.length && !children?.length) {
|
|
1221
|
+
return null;
|
|
1222
|
+
}
|
|
1223
|
+
return {
|
|
1224
|
+
...link,
|
|
1225
|
+
children,
|
|
1226
|
+
};
|
|
1227
|
+
}
|
|
1228
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AppNavigationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1229
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AppNavigationService, providedIn: 'root' });
|
|
1230
|
+
}
|
|
1231
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AppNavigationService, decorators: [{
|
|
1232
|
+
type: Injectable,
|
|
1233
|
+
args: [{ providedIn: 'root' }]
|
|
1234
|
+
}] });
|
|
1235
|
+
|
|
1236
|
+
const ROLE_SHELL_CHILD_ROUTES = new InjectionToken('ROLE_SHELL_CHILD_ROUTES');
|
|
1237
|
+
function provideRoleShellRoutes(routes) {
|
|
1238
|
+
const providers = [
|
|
1239
|
+
{
|
|
1240
|
+
provide: ROLE_SHELL_CHILD_ROUTES,
|
|
1241
|
+
useValue: routes,
|
|
1242
|
+
multi: true,
|
|
1243
|
+
},
|
|
1244
|
+
];
|
|
1245
|
+
return makeEnvironmentProviders(providers);
|
|
1246
|
+
}
|
|
1247
|
+
function provideRoleAwareFeature(config) {
|
|
1248
|
+
const providers = [];
|
|
1249
|
+
if (config.routes?.length) {
|
|
1250
|
+
providers.push(provideRoleShellRoutes(config.routes));
|
|
1251
|
+
}
|
|
1252
|
+
if (config.navigation?.length) {
|
|
1253
|
+
providers.push(provideRoleNavigation(config.navigation));
|
|
1254
|
+
}
|
|
1255
|
+
return makeEnvironmentProviders(providers);
|
|
1256
|
+
}
|
|
1257
|
+
function provideRoleAwareShellRouter(config, ...features) {
|
|
1258
|
+
const providers = [
|
|
1259
|
+
provideRouter([], ...features),
|
|
1260
|
+
{
|
|
1261
|
+
provide: ROUTES,
|
|
1262
|
+
multi: true,
|
|
1263
|
+
useFactory: () => {
|
|
1264
|
+
const contributedRoutes = inject(ROLE_SHELL_CHILD_ROUTES, { optional: true }) ?? [];
|
|
1265
|
+
return [
|
|
1266
|
+
...(config.topLevelRoutes ?? []),
|
|
1267
|
+
{
|
|
1268
|
+
path: '',
|
|
1269
|
+
component: config.shellComponent,
|
|
1270
|
+
canActivate: config.shellCanActivate,
|
|
1271
|
+
canActivateChild: config.shellCanActivateChild,
|
|
1272
|
+
data: config.shellData,
|
|
1273
|
+
children: [...(config.shellChildren ?? []), ...contributedRoutes.flat()],
|
|
1274
|
+
},
|
|
1275
|
+
...(config.fallbackRoute ? [config.fallbackRoute] : []),
|
|
1276
|
+
];
|
|
1277
|
+
},
|
|
1278
|
+
},
|
|
1279
|
+
];
|
|
1280
|
+
return makeEnvironmentProviders(providers);
|
|
1281
|
+
}
|
|
1282
|
+
function provideRoleAwareConsoleShell(config, ...features) {
|
|
1283
|
+
return makeEnvironmentProviders([
|
|
1284
|
+
provideRoleAwareShellRouter({
|
|
1285
|
+
...config,
|
|
1286
|
+
shellCanActivate: config.shellCanActivate ?? [AuthGuard],
|
|
1287
|
+
shellCanActivateChild: config.shellCanActivateChild ?? [AuthGuard],
|
|
1288
|
+
}, ...features),
|
|
1289
|
+
...(config.navigation?.length ? [provideRoleNavigation(config.navigation)] : []),
|
|
1290
|
+
]);
|
|
1291
|
+
}
|
|
1292
|
+
|
|
853
1293
|
/**
|
|
854
1294
|
* Generated bundle index. Do not edit.
|
|
855
1295
|
*/
|
|
856
1296
|
|
|
857
|
-
export { AUTH_METHODS, AddressComponent, AddressType, AuthAgentService, AuthDialogGuard, AuthGuard, AuthInterceptor, AuthMethod, AuthService, AuthStore, AuthUserService, ErrorInterceptor, FaceidDetectDialogComponent, ForbiddenComponent, LocalStorageService, PermissionGuard, RoleGuard, UnauthorizedComponent, UserStatus, authRoutes, provideAngularAuth };
|
|
1297
|
+
export { APPLICATION_ADMIN_ROLES, APPLICATION_OWNER_ROLES, AUTH_METHODS, AddressComponent, AddressType, AppNavigationService, AuthAgentService, AuthContextStore, AuthDialogGuard, AuthGuard, AuthInterceptor, AuthMethod, AuthService, AuthStore, AuthUserService, ErrorInterceptor, FaceidDetectDialogComponent, ForbiddenComponent, LocalStorageService, ORGANIZATION_ADMIN_ROLES, ORGANIZATION_MEMBER_ROLES, ORGANIZATION_OWNER_ROLES, ORGANIZATION_STAFF_ROLES, PLATFORM_ADMIN_ROLES, PermissionGuard, ROLE_NAVIGATION_LINKS, ROLE_SHELL_CHILD_ROUTES, RoleGuard, UnauthorizedComponent, UserStatus, accessGuard, accessMatchGuard, authRoutes, landingRedirectGuard, provideAngularAuth, provideRoleAwareConsoleShell, provideRoleAwareFeature, provideRoleAwareShellRouter, provideRoleNavigation, provideRoleShellRoutes };
|
|
858
1298
|
//# sourceMappingURL=rolatech-angular-auth.mjs.map
|