@acorex/platform 20.2.0-next.1 → 20.2.0-next.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.
Files changed (95) hide show
  1. package/auth/index.d.ts +71 -17
  2. package/common/index.d.ts +25 -42
  3. package/core/index.d.ts +104 -9
  4. package/fesm2022/acorex-platform-auth.mjs +320 -121
  5. package/fesm2022/acorex-platform-auth.mjs.map +1 -1
  6. package/fesm2022/acorex-platform-common.mjs +133 -115
  7. package/fesm2022/acorex-platform-common.mjs.map +1 -1
  8. package/fesm2022/acorex-platform-core.mjs +276 -37
  9. package/fesm2022/acorex-platform-core.mjs.map +1 -1
  10. package/fesm2022/acorex-platform-domain.mjs +16 -16
  11. package/fesm2022/acorex-platform-domain.mjs.map +1 -1
  12. package/fesm2022/acorex-platform-layout-builder.mjs +88 -67
  13. package/fesm2022/acorex-platform-layout-builder.mjs.map +1 -1
  14. package/fesm2022/acorex-platform-layout-components.mjs +137 -83
  15. package/fesm2022/acorex-platform-layout-components.mjs.map +1 -1
  16. package/fesm2022/acorex-platform-layout-designer.mjs +262 -218
  17. package/fesm2022/acorex-platform-layout-designer.mjs.map +1 -1
  18. package/fesm2022/acorex-platform-layout-entity.mjs +1040 -104
  19. package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
  20. package/fesm2022/acorex-platform-layout-views.mjs +15 -15
  21. package/fesm2022/acorex-platform-layout-views.mjs.map +1 -1
  22. package/fesm2022/acorex-platform-native.mjs +7 -7
  23. package/fesm2022/acorex-platform-native.mjs.map +1 -1
  24. package/fesm2022/acorex-platform-runtime.mjs +40 -40
  25. package/fesm2022/acorex-platform-runtime.mjs.map +1 -1
  26. package/fesm2022/{acorex-platform-themes-default-create-entity-view.component-CzHp6G3a.mjs → acorex-platform-themes-default-create-entity-view.component-DBkuhSDb.mjs} +4 -4
  27. package/fesm2022/{acorex-platform-themes-default-create-entity-view.component-CzHp6G3a.mjs.map → acorex-platform-themes-default-create-entity-view.component-DBkuhSDb.mjs.map} +1 -1
  28. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-8S2CXBAi.mjs +115 -0
  29. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-8S2CXBAi.mjs.map +1 -0
  30. package/fesm2022/{acorex-platform-themes-default-entity-master-list-view.component-DJdedfa_.mjs → acorex-platform-themes-default-entity-master-list-view.component-Bf8N5e5h.mjs} +27 -25
  31. package/fesm2022/{acorex-platform-themes-default-entity-master-list-view.component-DJdedfa_.mjs.map → acorex-platform-themes-default-entity-master-list-view.component-Bf8N5e5h.mjs.map} +1 -1
  32. package/fesm2022/{acorex-platform-themes-default-entity-master-modify-view.component-Cn-0fTWn.mjs → acorex-platform-themes-default-entity-master-modify-view.component-DF0gS61P.mjs} +5 -5
  33. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-DF0gS61P.mjs.map +1 -0
  34. package/fesm2022/{acorex-platform-themes-default-entity-master-single-view.component-B8XrO58H.mjs → acorex-platform-themes-default-entity-master-single-view.component-CEnHe_cU.mjs} +8 -8
  35. package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-CEnHe_cU.mjs.map +1 -0
  36. package/fesm2022/{acorex-platform-themes-default-error-401.component-Ycd9latx.mjs → acorex-platform-themes-default-error-401.component-BYI4xP23.mjs} +4 -4
  37. package/fesm2022/{acorex-platform-themes-default-error-401.component-Ycd9latx.mjs.map → acorex-platform-themes-default-error-401.component-BYI4xP23.mjs.map} +1 -1
  38. package/fesm2022/{acorex-platform-themes-default-error-404.component-DHbzH27Q.mjs → acorex-platform-themes-default-error-404.component-1gM0Vlbv.mjs} +4 -4
  39. package/fesm2022/{acorex-platform-themes-default-error-404.component-DHbzH27Q.mjs.map → acorex-platform-themes-default-error-404.component-1gM0Vlbv.mjs.map} +1 -1
  40. package/fesm2022/{acorex-platform-themes-default-error-offline.component-BSdZOCbW.mjs → acorex-platform-themes-default-error-offline.component-Y3w3K60c.mjs} +4 -4
  41. package/fesm2022/{acorex-platform-themes-default-error-offline.component-BSdZOCbW.mjs.map → acorex-platform-themes-default-error-offline.component-Y3w3K60c.mjs.map} +1 -1
  42. package/fesm2022/acorex-platform-themes-default.mjs +66 -54
  43. package/fesm2022/acorex-platform-themes-default.mjs.map +1 -1
  44. package/fesm2022/{acorex-platform-themes-shared-color-chooser-column.component-EZGn900W.mjs → acorex-platform-themes-shared-color-chooser-column.component-BLFvyMvH.mjs} +4 -4
  45. package/fesm2022/{acorex-platform-themes-shared-color-chooser-column.component-EZGn900W.mjs.map → acorex-platform-themes-shared-color-chooser-column.component-BLFvyMvH.mjs.map} +1 -1
  46. package/fesm2022/{acorex-platform-themes-shared-color-chooser-view.component-DTLYX00a.mjs → acorex-platform-themes-shared-color-chooser-view.component-CN1lEEOY.mjs} +4 -4
  47. package/fesm2022/{acorex-platform-themes-shared-color-chooser-view.component-DTLYX00a.mjs.map → acorex-platform-themes-shared-color-chooser-view.component-CN1lEEOY.mjs.map} +1 -1
  48. package/fesm2022/{acorex-platform-themes-shared-icon-chooser-view.component-DMPET9Fu.mjs → acorex-platform-themes-shared-icon-chooser-view.component-UJ2abdzQ.mjs} +4 -4
  49. package/fesm2022/{acorex-platform-themes-shared-icon-chooser-view.component-DMPET9Fu.mjs.map → acorex-platform-themes-shared-icon-chooser-view.component-UJ2abdzQ.mjs.map} +1 -1
  50. package/fesm2022/acorex-platform-themes-shared.mjs +65 -52
  51. package/fesm2022/acorex-platform-themes-shared.mjs.map +1 -1
  52. package/fesm2022/{acorex-platform-widgets-button-widget-designer.component-BUx-nksc.mjs → acorex-platform-widgets-button-widget-designer.component-BMsEt6Lq.mjs} +4 -4
  53. package/fesm2022/{acorex-platform-widgets-button-widget-designer.component-BUx-nksc.mjs.map → acorex-platform-widgets-button-widget-designer.component-BMsEt6Lq.mjs.map} +1 -1
  54. package/fesm2022/acorex-platform-widgets-checkbox-widget-column.component-CezBQ0iO.mjs +85 -0
  55. package/fesm2022/acorex-platform-widgets-checkbox-widget-column.component-CezBQ0iO.mjs.map +1 -0
  56. package/fesm2022/{acorex-platform-widgets-checkbox-widget-designer.component-Dj3Go0tj.mjs → acorex-platform-widgets-checkbox-widget-designer.component-BkH4hBUc.mjs} +4 -4
  57. package/fesm2022/{acorex-platform-widgets-checkbox-widget-designer.component-Dj3Go0tj.mjs.map → acorex-platform-widgets-checkbox-widget-designer.component-BkH4hBUc.mjs.map} +1 -1
  58. package/fesm2022/{acorex-platform-widgets-checkbox-widget-view.component-Y12esByc.mjs → acorex-platform-widgets-checkbox-widget-view.component-BwlHVBRW.mjs} +19 -6
  59. package/fesm2022/acorex-platform-widgets-checkbox-widget-view.component-BwlHVBRW.mjs.map +1 -0
  60. package/fesm2022/{acorex-platform-widgets-color-box-widget-designer.component-CihtTd0F.mjs → acorex-platform-widgets-color-box-widget-designer.component-BPLG8mY4.mjs} +4 -4
  61. package/fesm2022/{acorex-platform-widgets-color-box-widget-designer.component-CihtTd0F.mjs.map → acorex-platform-widgets-color-box-widget-designer.component-BPLG8mY4.mjs.map} +1 -1
  62. package/fesm2022/{acorex-platform-widgets-file-list-popup.component-n3nuXZNq.mjs → acorex-platform-widgets-file-list-popup.component-Bwbrw1xo.mjs} +4 -4
  63. package/fesm2022/{acorex-platform-widgets-file-list-popup.component-n3nuXZNq.mjs.map → acorex-platform-widgets-file-list-popup.component-Bwbrw1xo.mjs.map} +1 -1
  64. package/fesm2022/{acorex-platform-widgets-file-rename-popup.component-DBRV6X7W.mjs → acorex-platform-widgets-file-rename-popup.component-CXRHtjFu.mjs} +4 -4
  65. package/fesm2022/{acorex-platform-widgets-file-rename-popup.component-DBRV6X7W.mjs.map → acorex-platform-widgets-file-rename-popup.component-CXRHtjFu.mjs.map} +1 -1
  66. package/fesm2022/{acorex-platform-widgets-page-widget-designer.component-D_970YBz.mjs → acorex-platform-widgets-page-widget-designer.component-Cf5bTu-k.mjs} +6 -6
  67. package/fesm2022/acorex-platform-widgets-page-widget-designer.component-Cf5bTu-k.mjs.map +1 -0
  68. package/fesm2022/{acorex-platform-widgets-rich-text-popup.component-DPuTM42n.mjs → acorex-platform-widgets-rich-text-popup.component-DOGwSrH1.mjs} +4 -4
  69. package/fesm2022/{acorex-platform-widgets-rich-text-popup.component-DPuTM42n.mjs.map → acorex-platform-widgets-rich-text-popup.component-DOGwSrH1.mjs.map} +1 -1
  70. package/fesm2022/{acorex-platform-widgets-tabular-data-edit-popup.component-BH1_BkJh.mjs → acorex-platform-widgets-tabular-data-edit-popup.component-CFg2-tyF.mjs} +4 -4
  71. package/fesm2022/{acorex-platform-widgets-tabular-data-edit-popup.component-BH1_BkJh.mjs.map → acorex-platform-widgets-tabular-data-edit-popup.component-CFg2-tyF.mjs.map} +1 -1
  72. package/fesm2022/{acorex-platform-widgets-tabular-data-view-popup.component-DCsLuXR9.mjs → acorex-platform-widgets-tabular-data-view-popup.component-BvVF-vJF.mjs} +4 -4
  73. package/fesm2022/{acorex-platform-widgets-tabular-data-view-popup.component-DCsLuXR9.mjs.map → acorex-platform-widgets-tabular-data-view-popup.component-BvVF-vJF.mjs.map} +1 -1
  74. package/fesm2022/{acorex-platform-widgets-text-block-widget-designer.component-C_iu3jCG.mjs → acorex-platform-widgets-text-block-widget-designer.component-BhXq3JZ1.mjs} +4 -4
  75. package/fesm2022/{acorex-platform-widgets-text-block-widget-designer.component-C_iu3jCG.mjs.map → acorex-platform-widgets-text-block-widget-designer.component-BhXq3JZ1.mjs.map} +1 -1
  76. package/fesm2022/acorex-platform-widgets.mjs +744 -701
  77. package/fesm2022/acorex-platform-widgets.mjs.map +1 -1
  78. package/fesm2022/acorex-platform-workflow.mjs +33 -25
  79. package/fesm2022/acorex-platform-workflow.mjs.map +1 -1
  80. package/layout/builder/index.d.ts +6 -29
  81. package/layout/components/index.d.ts +62 -2
  82. package/layout/designer/index.d.ts +11 -20
  83. package/layout/entity/index.d.ts +302 -7
  84. package/package.json +5 -5
  85. package/themes/default/index.d.ts +2 -1
  86. package/widgets/index.d.ts +14 -16
  87. package/workflow/index.d.ts +154 -18
  88. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-nzWNHDO7.mjs +0 -115
  89. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-nzWNHDO7.mjs.map +0 -1
  90. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-Cn-0fTWn.mjs.map +0 -1
  91. package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-B8XrO58H.mjs.map +0 -1
  92. package/fesm2022/acorex-platform-widgets-checkbox-widget-column.component-C7mpTEda.mjs +0 -56
  93. package/fesm2022/acorex-platform-widgets-checkbox-widget-column.component-C7mpTEda.mjs.map +0 -1
  94. package/fesm2022/acorex-platform-widgets-checkbox-widget-view.component-Y12esByc.mjs.map +0 -1
  95. package/fesm2022/acorex-platform-widgets-page-widget-designer.component-D_970YBz.mjs.map +0 -1
@@ -1,8 +1,8 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { InjectionToken, Injector, Injectable, signal, inject, Input, Directive, provideAppInitializer, Optional, Inject, NgModule } from '@angular/core';
3
- import { of, map, BehaviorSubject, shareReplay, defaultIfEmpty, firstValueFrom, first } from 'rxjs';
4
- import { AXPBroadcastEventService, AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER } from '@acorex/platform/core';
5
- import { merge, isEmpty } from 'lodash-es';
3
+ import { of, map, BehaviorSubject, shareReplay, defaultIfEmpty, switchMap, filter, firstValueFrom, first } from 'rxjs';
4
+ import { AXPBroadcastEventService } from '@acorex/platform/core';
5
+ import { isEmpty } from 'lodash-es';
6
6
 
7
7
  const AXP_APPLICATION_LOADER = new InjectionToken('AXP_APPLICATION_LOADER', {
8
8
  providedIn: 'root',
@@ -21,6 +21,14 @@ class AXPApplicationDefaultLoader {
21
21
  editionName: 'Standard',
22
22
  features: [],
23
23
  },
24
+ {
25
+ id: '2',
26
+ name: 'default-app',
27
+ title: 'Default Application',
28
+ version: '1.0.0',
29
+ editionName: 'Standard',
30
+ features: [],
31
+ },
24
32
  ]);
25
33
  }
26
34
  }
@@ -60,10 +68,10 @@ class AXPAuthStrategyRegistryService {
60
68
  get(strategyKey) {
61
69
  return this.strategies.get(strategyKey);
62
70
  }
63
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXPAuthStrategyRegistryService, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); }
64
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXPAuthStrategyRegistryService, providedIn: 'root' }); }
71
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: AXPAuthStrategyRegistryService, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); }
72
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: AXPAuthStrategyRegistryService, providedIn: 'root' }); }
65
73
  }
66
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXPAuthStrategyRegistryService, decorators: [{
74
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: AXPAuthStrategyRegistryService, decorators: [{
67
75
  type: Injectable,
68
76
  args: [{
69
77
  providedIn: 'root'
@@ -120,10 +128,10 @@ class AXPFeatureDirective {
120
128
  ngOnDestroy() {
121
129
  this.subscription?.unsubscribe();
122
130
  }
123
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXPFeatureDirective, deps: [{ token: i0.TemplateRef }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive }); }
124
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.1.3", type: AXPFeatureDirective, isStandalone: false, selector: "[feature]", inputs: { feature: "feature", featureElse: "featureElse" }, ngImport: i0 }); }
131
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: AXPFeatureDirective, deps: [{ token: i0.TemplateRef }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive }); }
132
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.1.4", type: AXPFeatureDirective, isStandalone: false, selector: "[feature]", inputs: { feature: "feature", featureElse: "featureElse" }, ngImport: i0 }); }
125
133
  }
126
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXPFeatureDirective, decorators: [{
134
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: AXPFeatureDirective, decorators: [{
127
135
  type: Directive,
128
136
  args: [{
129
137
  selector: '[feature]',
@@ -216,6 +224,9 @@ class AXPSessionService {
216
224
  this.applicationLoader = inject(AXP_APPLICATION_LOADER);
217
225
  this.status = new BehaviorSubject(AXPSessionStatus.Unauthenticated);
218
226
  this.status$ = this.status.asObservable().pipe(shareReplay(1));
227
+ // Add loading state to prevent premature redirects
228
+ this.isLoading = new BehaviorSubject(true);
229
+ this.isLoading$ = this.isLoading.asObservable().pipe(shareReplay(1));
219
230
  this.currentUserSubject = new BehaviorSubject(null);
220
231
  this.user$ = this.currentUserSubject.asObservable().pipe(shareReplay(1));
221
232
  this.currentTenantSubject = new BehaviorSubject(null);
@@ -226,7 +237,17 @@ class AXPSessionService {
226
237
  this.permissions$ = this.permissionsSubject.asObservable().pipe(shareReplay(1), defaultIfEmpty([]));
227
238
  this.featuresSubject = new BehaviorSubject([]);
228
239
  this.features$ = this.featuresSubject.asObservable().pipe(shareReplay(1), defaultIfEmpty([]));
229
- this.isAuthenticated$ = this.status$.pipe(map((status) => status === AXPSessionStatus.Authenticated || status === AXPSessionStatus.Authorized), shareReplay(1));
240
+ this.isAuthenticated$ = this.status$.pipe(map((status) => {
241
+ const isAuth = status === AXPSessionStatus.Authenticated || status === AXPSessionStatus.Authorized;
242
+ return isAuth;
243
+ }), shareReplay(1));
244
+ // Add a new observable that considers loading state
245
+ this.isAuthenticatedWithLoading$ = this.isLoading$.pipe(switchMap((loading) => {
246
+ if (loading) {
247
+ return this.isLoading$.pipe(filter((isLoading) => !isLoading), switchMap(() => this.isAuthenticated$));
248
+ }
249
+ return this.isAuthenticated$;
250
+ }), shareReplay(1));
230
251
  this.isAuthorized$ = this.status$.pipe(map((status) => status === AXPSessionStatus.Authorized), shareReplay(1));
231
252
  }
232
253
  static { this.SESSION_KEY = 'AXP_SESSION'; }
@@ -264,108 +285,184 @@ class AXPSessionService {
264
285
  return this.featuresSubject.value ?? [];
265
286
  }
266
287
  async restoreSession() {
267
- const sessionData = this.getSessionData();
268
- if (sessionData) {
269
- if (sessionData.user) {
270
- this.currentUserSubject.next(sessionData.user);
271
- this.status.next(AXPSessionStatus.Authenticated);
288
+ this.isLoading.next(true);
289
+ try {
290
+ const sessionData = this.getSessionData();
291
+ if (sessionData) {
292
+ if (sessionData.user) {
293
+ this.currentUserSubject.next(sessionData.user);
294
+ this.status.next(AXPSessionStatus.Authenticated);
295
+ await this.loadPermissions();
296
+ await this.loadFeatures();
297
+ await this.signInComplete();
298
+ }
299
+ }
300
+ else {
301
+ this.status.next(AXPSessionStatus.Unauthorized);
272
302
  }
273
- // if (sessionData.tenant) {
274
- // this.setTenant(sessionData.tenant);
275
- // }
276
- // if (sessionData.application) {
277
- // this.setApplication(sessionData.application);
278
- // }
279
- await this.loadPermissions();
280
- await this.loadFeatures();
281
- await this.signInComplete();
282
- }
283
- else {
303
+ }
304
+ catch (error) {
284
305
  this.status.next(AXPSessionStatus.Unauthorized);
285
306
  }
307
+ finally {
308
+ this.isLoading.next(false);
309
+ }
286
310
  }
287
311
  async signin(credentials) {
288
- //
289
- this.clearSession();
290
- //
291
- const strategy = this.authStrategyRegistry.get(credentials.strategy);
292
- if (!strategy) {
293
- throw new Error(`Authentication strategy '${credentials.strategy}' is not supported`);
294
- }
295
- const result = await strategy.signin(credentials);
296
- if (result.succeed) {
297
- this.currentUserSubject.next(result.data.user);
298
- this.setSession({
299
- accessToken: result.data.accessToken,
300
- refreshToken: result.data.refreshToken,
301
- strategy: credentials.strategy,
302
- user: result.data.user,
303
- application: result.data?.application,
304
- tenant: result.data?.tenant,
305
- expiresIn: result.data?.expiresIn,
306
- idToken: result.data?.idToken ?? null,
307
- });
308
- this.status.next(AXPSessionStatus.Authenticated);
309
- if (this.application && this.tenant)
310
- await this.signInComplete();
312
+ this.isLoading.next(true);
313
+ try {
314
+ //
315
+ // this.clearSession();
316
+ //
317
+ const strategy = this.authStrategyRegistry.get(credentials.strategy);
318
+ if (!strategy) {
319
+ throw new Error(`Authentication strategy '${credentials.strategy}' is not supported`);
320
+ }
321
+ const result = await strategy.signin(credentials);
322
+ if (!result)
323
+ return;
324
+ if (result?.succeed) {
325
+ this.currentUserSubject.next(result.data.user);
326
+ this.setSession({
327
+ accessToken: result.data.accessToken,
328
+ refreshToken: result.data.refreshToken,
329
+ strategy: credentials.strategy,
330
+ user: result.data.user,
331
+ application: result.data?.application,
332
+ tenant: result.data?.tenant,
333
+ expiresIn: result.data?.expiresIn,
334
+ idToken: result.data?.idToken ?? null,
335
+ });
336
+ this.status.next(AXPSessionStatus.Authenticated);
337
+ // Load permissions and features
338
+ await this.loadPermissions();
339
+ await this.loadFeatures();
340
+ // If we have both tenant and application, complete the sign-in
341
+ if (this.application && this.tenant) {
342
+ await this.signInComplete();
343
+ }
344
+ }
345
+ else {
346
+ this.status.next(AXPSessionStatus.Unauthenticated);
347
+ throw new Error(`Invalid Username or Password`);
348
+ }
311
349
  }
312
- else {
350
+ catch (error) {
351
+ console.error('Signin error:', error);
313
352
  this.status.next(AXPSessionStatus.Unauthenticated);
314
- throw new Error(`Invalid Username or Password`);
353
+ throw error;
354
+ }
355
+ finally {
356
+ this.isLoading.next(false);
357
+ console.log('Signin process completed');
358
+ }
359
+ }
360
+ async updateToken(params) {
361
+ this.isLoading.next(true);
362
+ try {
363
+ const strategyName = this.getSessionData()?.strategy;
364
+ if (!strategyName) {
365
+ throw new Error('Strategy not found');
366
+ }
367
+ const strategy = this.authStrategyRegistry.get(strategyName);
368
+ if (!strategy) {
369
+ throw new Error(`Authentication strategy '${this.getSessionData()?.strategy}' is not supported`);
370
+ }
371
+ const result = await strategy.updateToken(params);
372
+ if (result?.succeed) {
373
+ this.currentUserSubject.next(result.data.user);
374
+ this.setSession({
375
+ accessToken: result.data.accessToken,
376
+ refreshToken: result.data.refreshToken,
377
+ strategy: strategyName,
378
+ user: result.data.user,
379
+ application: result.data?.application,
380
+ tenant: result.data?.tenant,
381
+ expiresIn: result.data?.expiresIn,
382
+ idToken: result.data?.idToken ?? null,
383
+ });
384
+ this.status.next(AXPSessionStatus.Authenticated);
385
+ // If we have both tenant and application, complete the sign-in
386
+ if (this.application && this.tenant) {
387
+ await this.signInComplete();
388
+ }
389
+ }
390
+ else {
391
+ this.status.next(AXPSessionStatus.Unauthenticated);
392
+ throw new Error(`Invalid Username or Password`);
393
+ }
394
+ }
395
+ catch (error) {
396
+ console.error('Update token error:', error);
397
+ throw error;
398
+ }
399
+ finally {
400
+ this.isLoading.next(false);
401
+ console.log('Update token process completed');
315
402
  }
316
403
  }
317
404
  async signout() {
318
- const sessionData = this.getSessionData();
319
- if (sessionData?.strategy) {
320
- const strategy = this.authStrategyRegistry.get(sessionData?.strategy);
321
- if (strategy) {
322
- await strategy.signout();
405
+ console.log('Signing out...');
406
+ this.isLoading.next(true);
407
+ try {
408
+ const sessionData = this.getSessionData();
409
+ if (sessionData?.strategy) {
410
+ const strategy = this.authStrategyRegistry.get(sessionData?.strategy);
411
+ if (strategy) {
412
+ try {
413
+ await strategy.signout();
414
+ }
415
+ catch (error) { }
416
+ }
323
417
  }
418
+ //
419
+ const userId = this.user?.id;
420
+ this.clearSession();
421
+ this.eventService.publish(AXPSessionStatus.SignedOut, { id: userId });
422
+ this.isLoading.next(false);
423
+ this.status.next(AXPSessionStatus.SignedOut);
424
+ }
425
+ finally {
426
+ this.isLoading.next(false);
324
427
  }
325
- //
326
- const userId = this.user?.id;
327
- this.clearSession();
328
- this.status.next(AXPSessionStatus.SignedOut);
329
- this.eventService.publish(AXPSessionStatus.SignedOut, { id: userId });
330
428
  }
331
429
  async refreshToken() {
430
+ console.log('Refreshing token...');
332
431
  return new Promise(async (resolve, reject) => {
333
432
  const sessionData = this.getSessionData();
334
433
  if (!sessionData || !sessionData?.refreshToken) {
434
+ console.log('No session data or refresh token found');
435
+ reject(new Error('No refresh token available'));
335
436
  return;
336
437
  }
337
438
  const strategy = this.authStrategyRegistry.get(sessionData.strategy);
338
439
  if (!strategy) {
339
- reject();
340
- throw new Error(`Authentication strategy '${sessionData.strategy}' is not found`);
440
+ console.error('Authentication strategy not found:', sessionData.strategy);
441
+ reject(new Error(`Authentication strategy '${sessionData.strategy}' is not found`));
442
+ return;
341
443
  }
342
- const result = await strategy.refreshToken(this.getContext());
343
- if (result.succeed) {
344
- this.setSession(result.data);
345
- resolve(result.data?.accessToken);
444
+ try {
445
+ const result = await strategy.refreshToken(this.getContext());
446
+ if (result.succeed) {
447
+ console.log('Token refresh successful');
448
+ this.setSession(result.data);
449
+ resolve(result.data?.accessToken);
450
+ }
451
+ else {
452
+ console.error('Token refresh failed');
453
+ this.clearSession();
454
+ this.status.next(AXPSessionStatus.Expired);
455
+ reject(new Error('Token refresh failed'));
456
+ }
346
457
  }
347
- else {
458
+ catch (error) {
459
+ console.error('Error during token refresh:', error);
348
460
  this.clearSession();
349
461
  this.status.next(AXPSessionStatus.Expired);
462
+ reject(error);
350
463
  }
351
464
  });
352
465
  }
353
- async setTenant(tenant) {
354
- this.currentTenantSubject.next(tenant);
355
- if (tenant) {
356
- this.updateSession({ tenant: tenant });
357
- await this.refreshToken();
358
- }
359
- }
360
- async setApplication(application) {
361
- this.currentApplicationSubject.next(application);
362
- if (application) {
363
- this.updateSession({ application: application });
364
- await this.refreshToken();
365
- await this.loadPermissions();
366
- await this.loadFeatures();
367
- }
368
- }
369
466
  async loadPermissions() {
370
467
  try {
371
468
  const permissions = await firstValueFrom(this.permissionLoader.getList(this.getContext()));
@@ -387,37 +484,69 @@ class AXPSessionService {
387
484
  }
388
485
  }
389
486
  async signInComplete() {
487
+ // Ensure we have the required data
488
+ if (!this.user) {
489
+ this.status.next(AXPSessionStatus.Unauthenticated);
490
+ return;
491
+ }
492
+ // Set status to Authorized
390
493
  this.status.next(AXPSessionStatus.Authorized);
494
+ // Double-check the status was set correctly
495
+ setTimeout(() => {
496
+ console.log('Status after timeout:', this.status.value);
497
+ }, 100);
391
498
  }
392
499
  setSession(tokens) {
393
500
  const sessionData = {
394
501
  accessToken: tokens.accessToken,
395
502
  refreshToken: tokens.refreshToken,
396
503
  strategy: tokens.strategy,
397
- user: this.user,
504
+ user: tokens.user,
398
505
  application: tokens.application,
399
506
  tenant: tokens.tenant,
400
507
  expiresIn: tokens.expiresIn,
401
508
  idToken: tokens.idToken,
402
509
  };
403
- this.updateSession(sessionData);
510
+ // Update subjects
511
+ if (tokens.user) {
512
+ this.currentUserSubject.next(tokens.user);
513
+ }
514
+ if (tokens.tenant) {
515
+ this.currentTenantSubject.next(tokens.tenant);
516
+ }
517
+ if (tokens.application) {
518
+ this.currentApplicationSubject.next(tokens.application);
519
+ }
520
+ localStorage.setItem(AXPSessionService.SESSION_KEY, JSON.stringify(sessionData));
404
521
  }
405
- updateSession(update) {
406
- const currentSession = this.getSessionData() ?? {};
407
- const updatedSession = merge({}, currentSession, update);
408
- localStorage.setItem(AXPSessionService.SESSION_KEY, JSON.stringify(updatedSession));
522
+ setStrategy(strategy) {
523
+ const sessionData = this.getSessionData();
524
+ const newSessionData = { ...sessionData, strategy };
525
+ this.setSession(newSessionData);
409
526
  }
410
527
  getSessionData() {
411
- const sessionDataString = localStorage.getItem(AXPSessionService.SESSION_KEY);
412
- return sessionDataString ? JSON.parse(sessionDataString) : null;
528
+ try {
529
+ const sessionDataString = localStorage.getItem(AXPSessionService.SESSION_KEY);
530
+ if (sessionDataString) {
531
+ const sessionData = JSON.parse(sessionDataString);
532
+ return sessionData;
533
+ }
534
+ else {
535
+ return null;
536
+ }
537
+ }
538
+ catch (error) {
539
+ localStorage.removeItem(AXPSessionService.SESSION_KEY);
540
+ return null;
541
+ }
413
542
  }
414
543
  clearSession() {
415
544
  //
416
545
  this.currentUserSubject.next(null);
417
546
  //
418
- this.setTenant(null);
547
+ this.currentTenantSubject.next(null);
419
548
  //
420
- this.setApplication(null);
549
+ this.currentApplicationSubject.next(null);
421
550
  //
422
551
  this.permissionsSubject.next([]);
423
552
  //
@@ -453,10 +582,10 @@ class AXPSessionService {
453
582
  application: this.application,
454
583
  });
455
584
  }
456
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXPSessionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
457
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXPSessionService, providedIn: 'root' }); }
585
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: AXPSessionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
586
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: AXPSessionService, providedIn: 'root' }); }
458
587
  }
459
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXPSessionService, decorators: [{
588
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: AXPSessionService, decorators: [{
460
589
  type: Injectable,
461
590
  args: [{
462
591
  providedIn: 'root',
@@ -500,10 +629,10 @@ class AXPPermissionDirective {
500
629
  ngOnDestroy() {
501
630
  this.subscription?.unsubscribe();
502
631
  }
503
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXPPermissionDirective, deps: [{ token: i0.TemplateRef }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive }); }
504
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.1.3", type: AXPPermissionDirective, isStandalone: false, selector: "[permission]", inputs: { permission: "permission", permissionElse: "permissionElse" }, ngImport: i0 }); }
632
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: AXPPermissionDirective, deps: [{ token: i0.TemplateRef }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive }); }
633
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.1.4", type: AXPPermissionDirective, isStandalone: false, selector: "[permission]", inputs: { permission: "permission", permissionElse: "permissionElse" }, ngImport: i0 }); }
505
634
  }
506
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXPPermissionDirective, decorators: [{
635
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: AXPPermissionDirective, decorators: [{
507
636
  type: Directive,
508
637
  args: [{
509
638
  selector: '[permission]',
@@ -657,10 +786,10 @@ class AXPPermissionDefinitionService {
657
786
  await this.load();
658
787
  return this.cache?.find(g => g.permissions.find(p => p.name === name))?.permissions.find(p => p.name === name) ?? null;
659
788
  }
660
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXPPermissionDefinitionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
661
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXPPermissionDefinitionService, providedIn: 'root' }); }
789
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: AXPPermissionDefinitionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
790
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: AXPPermissionDefinitionService, providedIn: 'root' }); }
662
791
  }
663
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXPPermissionDefinitionService, decorators: [{
792
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: AXPPermissionDefinitionService, decorators: [{
664
793
  type: Injectable,
665
794
  args: [{ providedIn: 'root' }]
666
795
  }] });
@@ -693,7 +822,7 @@ class AXPPermissionEvaluatorScopeProvider {
693
822
 
694
823
  const AXPAuthGuard = (route, state) => {
695
824
  const sessionService = inject(AXPSessionService);
696
- return sessionService.isAuthenticated$.pipe(first(), map((value) => {
825
+ return sessionService.isAuthenticatedWithLoading$.pipe(first(), map((value) => {
697
826
  if (value) {
698
827
  return true;
699
828
  }
@@ -754,21 +883,16 @@ class AXPAuthModule {
754
883
  f();
755
884
  });
756
885
  }
757
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXPAuthModule, deps: [{ token: 'AXPAuthModuleFactory', optional: true }], target: i0.ɵɵFactoryTarget.NgModule }); }
758
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.1.3", ngImport: i0, type: AXPAuthModule, declarations: [AXPPermissionDirective, AXPFeatureDirective], exports: [AXPPermissionDirective, AXPFeatureDirective] }); }
759
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXPAuthModule, providers: [
886
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: AXPAuthModule, deps: [{ token: 'AXPAuthModuleFactory', optional: true }], target: i0.ɵɵFactoryTarget.NgModule }); }
887
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.1.4", ngImport: i0, type: AXPAuthModule, declarations: [AXPPermissionDirective, AXPFeatureDirective], exports: [AXPPermissionDirective, AXPFeatureDirective] }); }
888
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: AXPAuthModule, providers: [
760
889
  provideAppInitializer(() => {
761
- const initializerFn = (initializeAppState)(inject(AXPSessionService));
890
+ const initializerFn = initializeAppState(inject(AXPSessionService));
762
891
  return initializerFn();
763
892
  }),
764
- {
765
- provide: AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER,
766
- useClass: AXPPermissionEvaluatorScopeProvider,
767
- multi: true,
768
- },
769
893
  ] }); }
770
894
  }
771
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AXPAuthModule, decorators: [{
895
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: AXPAuthModule, decorators: [{
772
896
  type: NgModule,
773
897
  args: [{
774
898
  imports: [],
@@ -776,14 +900,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImpor
776
900
  declarations: [AXPPermissionDirective, AXPFeatureDirective],
777
901
  providers: [
778
902
  provideAppInitializer(() => {
779
- const initializerFn = (initializeAppState)(inject(AXPSessionService));
903
+ const initializerFn = initializeAppState(inject(AXPSessionService));
780
904
  return initializerFn();
781
905
  }),
782
- {
783
- provide: AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER,
784
- useClass: AXPPermissionEvaluatorScopeProvider,
785
- multi: true,
786
- },
787
906
  ],
788
907
  }]
789
908
  }], ctorParameters: () => [{ type: undefined, decorators: [{
@@ -793,9 +912,89 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImpor
793
912
  args: ['AXPAuthModuleFactory']
794
913
  }] }] });
795
914
 
915
+ class AXPAuthStrategy {
916
+ }
917
+
918
+ //#region ---- JWT Utility ----
919
+ /**
920
+ * Utility class for JWT token operations
921
+ */
922
+ class JwtUtil {
923
+ /**
924
+ * Parses a JWT token and returns the payload
925
+ */
926
+ static parseJwt(token) {
927
+ try {
928
+ const base64Url = token.split('.')[1];
929
+ const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
930
+ const jsonPayload = decodeURIComponent(atob(base64)
931
+ .split('')
932
+ .map(c => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2))
933
+ .join(''));
934
+ return JSON.parse(jsonPayload);
935
+ }
936
+ catch (error) {
937
+ throw new Error('Invalid JWT token');
938
+ }
939
+ }
940
+ }
941
+ //#endregion
942
+ //#region ---- PKCE Utility ----
943
+ /**
944
+ * Utility class for PKCE (Proof Key for Code Exchange) operations
945
+ */
946
+ class PkceUtil {
947
+ /**
948
+ * Generates a random string for PKCE code verifier
949
+ */
950
+ static generateRandomString(length) {
951
+ const array = new Uint8Array(length);
952
+ crypto.getRandomValues(array);
953
+ return this.base64UrlEncode(array);
954
+ }
955
+ /**
956
+ * Generates PKCE code challenge from verifier
957
+ */
958
+ static async generateCodeChallenge(codeVerifier) {
959
+ const encoder = new TextEncoder();
960
+ const data = encoder.encode(codeVerifier);
961
+ const digest = await crypto.subtle.digest('SHA-256', data);
962
+ return this.base64UrlEncode(new Uint8Array(digest));
963
+ }
964
+ /**
965
+ * Base64 URL encoding for PKCE
966
+ */
967
+ static base64UrlEncode(array) {
968
+ return btoa(String.fromCharCode(...array))
969
+ .replace(/\+/g, '-')
970
+ .replace(/\//g, '_')
971
+ .replace(/=/g, '');
972
+ }
973
+ }
974
+ //#endregion
975
+ //#region ---- Time Utility ----
976
+ /**
977
+ * Utility class for time and date operations
978
+ */
979
+ class TimeUtil {
980
+ /**
981
+ * Calculates the time difference in milliseconds between a future date and now
982
+ */
983
+ static expiresInMilliseconds(expiresInDate) {
984
+ return new Date(expiresInDate).getTime() - new Date().getTime();
985
+ }
986
+ /**
987
+ * Calculates expiration date from seconds
988
+ */
989
+ static calculateExpireInDate(expireInSeconds) {
990
+ return new Date(Date.now() + expireInSeconds * 1000).toISOString();
991
+ }
992
+ }
993
+ //#endregion
994
+
796
995
  /**
797
996
  * Generated bundle index. Do not edit.
798
997
  */
799
998
 
800
- export { AXPAuthGuard, AXPAuthModule, AXPFeatureDirective, AXPFeatureGuard, AXPPermissionDefinitionBuilder, AXPPermissionDefinitionGroupBuilder, AXPPermissionDefinitionProviderContext, AXPPermissionDefinitionService, AXPPermissionDirective, AXPPermissionEvaluatorScopeProvider, AXPPermissionGuard, AXPSessionContext, AXPSessionService, AXPSessionStatus, AXPUnauthenticatedError, AXPUnauthorizedError, AXP_APPLICATION_LOADER, AXP_FEATURE_LOADER, AXP_PERMISSION_DEFINITION_PROVIDER, AXP_PERMISSION_LOADER, AXP_TENANT_LOADER, initializeAppState };
999
+ export { AXPAuthGuard, AXPAuthModule, AXPAuthStrategy, AXPAuthStrategyRegistryService, AXPFeatureDirective, AXPFeatureGuard, AXPPermissionDefinitionBuilder, AXPPermissionDefinitionGroupBuilder, AXPPermissionDefinitionProviderContext, AXPPermissionDefinitionService, AXPPermissionDirective, AXPPermissionEvaluatorScopeProvider, AXPPermissionGuard, AXPSessionContext, AXPSessionService, AXPSessionStatus, AXPUnauthenticatedError, AXPUnauthorizedError, AXP_APPLICATION_LOADER, AXP_FEATURE_LOADER, AXP_PERMISSION_DEFINITION_PROVIDER, AXP_PERMISSION_LOADER, AXP_TENANT_LOADER, JwtUtil, PkceUtil, TimeUtil, initializeAppState };
801
1000
  //# sourceMappingURL=acorex-platform-auth.mjs.map