@rolatech/angular-auth 20.2.9-beta.7 → 20.3.0-beta.2

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 { map, tap, filter, catchError as catchError$1 } from 'rxjs/operators';
10
- import { ActivatedRoute, Router } from '@angular/router';
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 { of, map as map$1, BehaviorSubject, catchError, throwError, NEVER } from 'rxjs';
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.1.1", ngImport: i0, type: ForbiddenComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
21
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.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: [""] });
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.1.1", ngImport: i0, type: ForbiddenComponent, decorators: [{
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.1.1", ngImport: i0, type: UnauthorizedComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
30
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.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: [""] });
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.1.1", ngImport: i0, type: UnauthorizedComponent, decorators: [{
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
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: AuthStore, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
81
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: AuthStore, providedIn: 'root' });
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' });
82
185
  }
83
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: AuthStore, decorators: [{
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' });
212
+ }
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
- introspect() {
99
- return this.http
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(map((res) => {
104
- this.authStore.update({
105
- authenticated: res.authenticated,
106
- userId: res.userId,
107
- roles: res.roles,
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 res;
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/users/me`, {
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.updateAuthenticated(true);
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.updateAuthenticated(true);
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.updateAuthenticated(false);
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.updateAuthenticated(true);
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.updateAuthenticated(true);
401
+ this.authStore.resetLoading();
229
402
  }));
230
403
  }
231
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: AuthService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
232
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: AuthService, providedIn: 'root' });
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.1.1", ngImport: i0, type: AuthService, decorators: [{
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.1.1", ngImport: i0, type: FaceidDetectDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
294
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.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 }] });
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.1.1", ngImport: i0, type: FaceidDetectDialogComponent, decorators: [{
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.1.1", ngImport: i0, type: AddressComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
326
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.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"] }] });
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.1.1", ngImport: i0, type: AddressComponent, decorators: [{
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.introspect().pipe(map$1(({ roles, authenticated }) => {
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.1.1", ngImport: i0, type: AuthDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
385
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.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 }] });
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.1.1", ngImport: i0, type: AuthDialogComponent, decorators: [{
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.introspect().pipe(filter((res) => res.roles !== null && res.roles.length > 0), map$1(({ roles }) => {
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/users/me`, {
791
+ .get(`${this.environment.baseUrl}/auth/me`, {
485
792
  withCredentials: true,
486
793
  })
487
794
  .pipe(map$1((res) => {
@@ -530,7 +837,7 @@ class AuthUserService {
530
837
  });
531
838
  }
532
839
  changeName(name) {
533
- return this.http.put(`${this.environment.baseUrl}/auth/users/me`, { name }, {
840
+ return this.http.put(`${this.environment.baseUrl}/auth/me`, { name }, {
534
841
  withCredentials: true,
535
842
  });
536
843
  }
@@ -540,7 +847,7 @@ class AuthUserService {
540
847
  });
541
848
  }
542
849
  update(data) {
543
- return this.http.put(`${this.environment.baseUrl}/auth/users/me`, data, {
850
+ return this.http.put(`${this.environment.baseUrl}/auth/me`, data, {
544
851
  withCredentials: true,
545
852
  });
546
853
  }
@@ -598,10 +905,10 @@ class AuthUserService {
598
905
  deleteAddressById(id) {
599
906
  return this.http.delete(`${this.environment.baseUrl}/auth/users/addresses/${id}`, { withCredentials: true });
600
907
  }
601
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: AuthUserService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
602
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: AuthUserService, providedIn: 'root' });
908
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AuthUserService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
909
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AuthUserService, providedIn: 'root' });
603
910
  }
604
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: AuthUserService, decorators: [{
911
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AuthUserService, decorators: [{
605
912
  type: Injectable,
606
913
  args: [{
607
914
  providedIn: 'root',
@@ -648,10 +955,10 @@ class AuthAgentService {
648
955
  withCredentials: true,
649
956
  });
650
957
  }
651
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: AuthAgentService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
652
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: AuthAgentService, providedIn: 'root' });
958
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AuthAgentService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
959
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AuthAgentService, providedIn: 'root' });
653
960
  }
654
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: AuthAgentService, decorators: [{
961
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AuthAgentService, decorators: [{
655
962
  type: Injectable,
656
963
  args: [{
657
964
  providedIn: 'root',
@@ -695,10 +1002,10 @@ class LocalStorageService {
695
1002
  setItem(key, value) {
696
1003
  return this.storage.setItem(key, value);
697
1004
  }
698
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: LocalStorageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
699
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: LocalStorageService, providedIn: 'root' });
1005
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: LocalStorageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1006
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: LocalStorageService, providedIn: 'root' });
700
1007
  }
701
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: LocalStorageService, decorators: [{
1008
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: LocalStorageService, decorators: [{
702
1009
  type: Injectable,
703
1010
  args: [{
704
1011
  providedIn: 'root',
@@ -710,7 +1017,7 @@ class ErrorInterceptor {
710
1017
  isRefreshingToken = false;
711
1018
  authService = inject(AuthService);
712
1019
  intercept(request, next) {
713
- return next.handle(request).pipe(catchError((error) => {
1020
+ return next.handle(request).pipe(catchError$1((error) => {
714
1021
  if (error instanceof HttpErrorResponse) {
715
1022
  switch (error.status) {
716
1023
  case 400:
@@ -756,10 +1063,10 @@ class ErrorInterceptor {
756
1063
  return throwError(() => new Error('系统错误'));
757
1064
  // return throwError(() => error.error);
758
1065
  }
759
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: ErrorInterceptor, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
760
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: ErrorInterceptor });
1066
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ErrorInterceptor, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1067
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ErrorInterceptor });
761
1068
  }
762
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: ErrorInterceptor, decorators: [{
1069
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ErrorInterceptor, decorators: [{
763
1070
  type: Injectable
764
1071
  }] });
765
1072
 
@@ -777,7 +1084,7 @@ class AuthInterceptor {
777
1084
  // // window.location.href = res.headers.get('Location') as string;
778
1085
  // }
779
1086
  return res;
780
- }), catchError$1((error) => {
1087
+ }), catchError((error) => {
781
1088
  if (isPlatformBrowser(this.platformId)) {
782
1089
  if (error.url?.includes('auth/introspect')) {
783
1090
  // if (window.location.origin !== `${this.environment.accountsUrl}`) {
@@ -808,10 +1115,10 @@ class AuthInterceptor {
808
1115
  },
809
1116
  });
810
1117
  }
811
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: AuthInterceptor, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
812
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: AuthInterceptor });
1118
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AuthInterceptor, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1119
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AuthInterceptor });
813
1120
  }
814
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: AuthInterceptor, decorators: [{
1121
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AuthInterceptor, decorators: [{
815
1122
  type: Injectable
816
1123
  }], ctorParameters: () => [] });
817
1124
 
@@ -835,6 +1142,20 @@ function provideAngularAuth(config) {
835
1142
  useClass: AuthInterceptor,
836
1143
  multi: true,
837
1144
  },
1145
+ {
1146
+ provide: APP_INITIALIZER,
1147
+ multi: true,
1148
+ useFactory: () => {
1149
+ const authService = inject(AuthService);
1150
+ const platformId = inject(PLATFORM_ID);
1151
+ return () => {
1152
+ if (config?.autoLoadSession === false || !isPlatformBrowser(platformId)) {
1153
+ return Promise.resolve();
1154
+ }
1155
+ return firstValueFrom(authService.ensureLoaded().pipe(catchError(() => of(null))));
1156
+ };
1157
+ },
1158
+ },
838
1159
  ];
839
1160
  return makeEnvironmentProviders(providers);
840
1161
  }
@@ -850,9 +1171,116 @@ const authRoutes = [
850
1171
  },
851
1172
  ];
852
1173
 
1174
+ const ROLE_NAVIGATION_LINKS = new InjectionToken('ROLE_NAVIGATION_LINKS');
1175
+ function provideRoleNavigation(links) {
1176
+ const providers = [
1177
+ {
1178
+ provide: ROLE_NAVIGATION_LINKS,
1179
+ useValue: links,
1180
+ multi: true,
1181
+ },
1182
+ ];
1183
+ return makeEnvironmentProviders(providers);
1184
+ }
1185
+
1186
+ class AppNavigationService {
1187
+ authStore = inject(AuthStore);
1188
+ authContextStore = inject(AuthContextStore);
1189
+ linkGroups = inject(ROLE_NAVIGATION_LINKS, { optional: true }) ?? [];
1190
+ links = computed(() => {
1191
+ this.authStore.authenticated();
1192
+ this.authStore.loaded();
1193
+ this.authContextStore.appId();
1194
+ this.authContextStore.orgId();
1195
+ return this.linkGroups
1196
+ .flat()
1197
+ .sort((left, right) => (left.order ?? 0) - (right.order ?? 0))
1198
+ .map((link) => this.toNavLink(link))
1199
+ .filter((link) => link !== null);
1200
+ }, ...(ngDevMode ? [{ debugName: "links" }] : []));
1201
+ toNavLink(link) {
1202
+ if (link.visible === false || !matchesRouteAccessPolicy(this.authStore, this.authContextStore, link.access)) {
1203
+ return null;
1204
+ }
1205
+ const children = link.children
1206
+ ?.map((child) => this.toNavLink(child))
1207
+ .filter((child) => child !== null);
1208
+ if (link.children?.length && !children?.length) {
1209
+ return null;
1210
+ }
1211
+ return {
1212
+ ...link,
1213
+ children,
1214
+ };
1215
+ }
1216
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AppNavigationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1217
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AppNavigationService, providedIn: 'root' });
1218
+ }
1219
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: AppNavigationService, decorators: [{
1220
+ type: Injectable,
1221
+ args: [{ providedIn: 'root' }]
1222
+ }] });
1223
+
1224
+ const ROLE_SHELL_CHILD_ROUTES = new InjectionToken('ROLE_SHELL_CHILD_ROUTES');
1225
+ function provideRoleShellRoutes(routes) {
1226
+ const providers = [
1227
+ {
1228
+ provide: ROLE_SHELL_CHILD_ROUTES,
1229
+ useValue: routes,
1230
+ multi: true,
1231
+ },
1232
+ ];
1233
+ return makeEnvironmentProviders(providers);
1234
+ }
1235
+ function provideRoleAwareFeature(config) {
1236
+ const providers = [];
1237
+ if (config.routes?.length) {
1238
+ providers.push(provideRoleShellRoutes(config.routes));
1239
+ }
1240
+ if (config.navigation?.length) {
1241
+ providers.push(provideRoleNavigation(config.navigation));
1242
+ }
1243
+ return makeEnvironmentProviders(providers);
1244
+ }
1245
+ function provideRoleAwareShellRouter(config, ...features) {
1246
+ const providers = [
1247
+ provideRouter([], ...features),
1248
+ {
1249
+ provide: ROUTES,
1250
+ multi: true,
1251
+ useFactory: () => {
1252
+ const contributedRoutes = inject(ROLE_SHELL_CHILD_ROUTES, { optional: true }) ?? [];
1253
+ return [
1254
+ ...(config.topLevelRoutes ?? []),
1255
+ {
1256
+ path: '',
1257
+ component: config.shellComponent,
1258
+ canActivate: config.shellCanActivate,
1259
+ canActivateChild: config.shellCanActivateChild,
1260
+ data: config.shellData,
1261
+ children: [...(config.shellChildren ?? []), ...contributedRoutes.flat()],
1262
+ },
1263
+ ...(config.fallbackRoute ? [config.fallbackRoute] : []),
1264
+ ];
1265
+ },
1266
+ },
1267
+ ];
1268
+ return makeEnvironmentProviders(providers);
1269
+ }
1270
+ function provideRoleAwareConsoleShell(config, ...features) {
1271
+ return makeEnvironmentProviders([
1272
+ provideRoleAwareShellRouter({
1273
+ ...config,
1274
+ shellCanActivate: config.shellCanActivate ?? [AuthGuard],
1275
+ shellCanActivateChild: config.shellCanActivateChild ?? [AuthGuard],
1276
+ }, ...features),
1277
+ ...(config.navigation?.length ? [provideRoleNavigation(config.navigation)] : []),
1278
+ ]);
1279
+ }
1280
+
853
1281
  /**
854
1282
  * Generated bundle index. Do not edit.
855
1283
  */
856
1284
 
857
- export { AUTH_METHODS, AddressComponent, AddressType, AuthAgentService, AuthDialogGuard, AuthGuard, AuthInterceptor, AuthMethod, AuthService, AuthStore, AuthUserService, ErrorInterceptor, FaceidDetectDialogComponent, ForbiddenComponent, LocalStorageService, PermissionGuard, RoleGuard, UnauthorizedComponent, UserStatus, authRoutes, provideAngularAuth };
1285
+ 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
1286
  //# sourceMappingURL=rolatech-angular-auth.mjs.map