@acorex/platform 21.0.0-next.1 → 21.0.0-next.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.
Files changed (69) hide show
  1. package/auth/index.d.ts +238 -92
  2. package/common/index.d.ts +42 -606
  3. package/core/index.d.ts +432 -574
  4. package/fesm2022/acorex-platform-auth.mjs +200 -153
  5. package/fesm2022/acorex-platform-auth.mjs.map +1 -1
  6. package/fesm2022/acorex-platform-common.mjs +112 -1009
  7. package/fesm2022/acorex-platform-common.mjs.map +1 -1
  8. package/fesm2022/acorex-platform-core.mjs +416 -694
  9. package/fesm2022/acorex-platform-core.mjs.map +1 -1
  10. package/fesm2022/acorex-platform-domain.mjs +11 -54
  11. package/fesm2022/acorex-platform-domain.mjs.map +1 -1
  12. package/fesm2022/acorex-platform-layout-builder.mjs +272 -414
  13. package/fesm2022/acorex-platform-layout-builder.mjs.map +1 -1
  14. package/fesm2022/acorex-platform-layout-components.mjs +3105 -2064
  15. package/fesm2022/acorex-platform-layout-components.mjs.map +1 -1
  16. package/fesm2022/acorex-platform-layout-designer.mjs +7 -7
  17. package/fesm2022/acorex-platform-layout-designer.mjs.map +1 -1
  18. package/fesm2022/acorex-platform-layout-entity.mjs +648 -756
  19. package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
  20. package/fesm2022/acorex-platform-layout-views.mjs +4 -4
  21. package/fesm2022/acorex-platform-layout-views.mjs.map +1 -1
  22. package/fesm2022/acorex-platform-layout-widget-core.mjs +174 -248
  23. package/fesm2022/acorex-platform-layout-widget-core.mjs.map +1 -1
  24. package/fesm2022/acorex-platform-layout-widgets-extra-properties-schema-widget-edit.component-fhhZOWul.mjs +50 -0
  25. package/fesm2022/acorex-platform-layout-widgets-extra-properties-schema-widget-edit.component-fhhZOWul.mjs.map +1 -0
  26. package/fesm2022/acorex-platform-layout-widgets-extra-properties-schema-widget-view.component-C3Qbs0fz.mjs +42 -0
  27. package/fesm2022/acorex-platform-layout-widgets-extra-properties-schema-widget-view.component-C3Qbs0fz.mjs.map +1 -0
  28. package/fesm2022/acorex-platform-layout-widgets-extra-properties-values-widget-edit.component-CngQBUlN.mjs +55 -0
  29. package/fesm2022/acorex-platform-layout-widgets-extra-properties-values-widget-edit.component-CngQBUlN.mjs.map +1 -0
  30. package/fesm2022/acorex-platform-layout-widgets-extra-properties-values-widget-view.component-DSNo9e4W.mjs +50 -0
  31. package/fesm2022/acorex-platform-layout-widgets-extra-properties-values-widget-view.component-DSNo9e4W.mjs.map +1 -0
  32. package/fesm2022/acorex-platform-layout-widgets-extra-properties-widget-edit.component-CL0CwEHX.mjs +48 -0
  33. package/fesm2022/acorex-platform-layout-widgets-extra-properties-widget-edit.component-CL0CwEHX.mjs.map +1 -0
  34. package/fesm2022/acorex-platform-layout-widgets-extra-properties-widget-view.component-B6Fi0xTw.mjs +42 -0
  35. package/fesm2022/acorex-platform-layout-widgets-extra-properties-widget-view.component-B6Fi0xTw.mjs.map +1 -0
  36. package/fesm2022/{acorex-platform-layout-widgets-file-list-popup.component-CxrsI6Hn.mjs → acorex-platform-layout-widgets-file-list-popup.component-D0y-9nE5.mjs} +2 -2
  37. package/fesm2022/acorex-platform-layout-widgets-file-list-popup.component-D0y-9nE5.mjs.map +1 -0
  38. package/fesm2022/{acorex-platform-layout-widgets-tabular-data-edit-popup.component-Ck7-wpT2.mjs → acorex-platform-layout-widgets-tabular-data-edit-popup.component-m8rHZP8L.mjs} +2 -2
  39. package/fesm2022/acorex-platform-layout-widgets-tabular-data-edit-popup.component-m8rHZP8L.mjs.map +1 -0
  40. package/fesm2022/acorex-platform-layout-widgets.mjs +974 -2994
  41. package/fesm2022/acorex-platform-layout-widgets.mjs.map +1 -1
  42. package/fesm2022/{acorex-platform-themes-default-entity-master-create-view.component-VIGuU5M4.mjs → acorex-platform-themes-default-entity-master-create-view.component-mARj77Mr.mjs} +5 -26
  43. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-mARj77Mr.mjs.map +1 -0
  44. package/fesm2022/{acorex-platform-themes-default-entity-master-list-view.component-DyDa_hyd.mjs → acorex-platform-themes-default-entity-master-list-view.component-Cym8pq0v.mjs} +5 -4
  45. package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-Cym8pq0v.mjs.map +1 -0
  46. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-BTA6h7Xd.mjs +101 -0
  47. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-BTA6h7Xd.mjs.map +1 -0
  48. package/fesm2022/{acorex-platform-themes-default-entity-master-single-view.component-eMBby9k4.mjs → acorex-platform-themes-default-entity-master-single-view.component-B_P0a5KW.mjs} +3 -3
  49. package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-B_P0a5KW.mjs.map +1 -0
  50. package/fesm2022/acorex-platform-themes-default.mjs +30 -166
  51. package/fesm2022/acorex-platform-themes-default.mjs.map +1 -1
  52. package/fesm2022/acorex-platform-themes-shared.mjs +27 -27
  53. package/fesm2022/acorex-platform-themes-shared.mjs.map +1 -1
  54. package/layout/builder/index.d.ts +1 -4
  55. package/layout/components/index.d.ts +327 -405
  56. package/layout/designer/index.d.ts +3 -3
  57. package/layout/entity/index.d.ts +108 -163
  58. package/layout/widget-core/index.d.ts +49 -39
  59. package/layout/widgets/index.d.ts +54 -368
  60. package/package.json +5 -5
  61. package/themes/default/index.d.ts +2 -15
  62. package/themes/shared/index.d.ts +10 -10
  63. package/fesm2022/acorex-platform-layout-widgets-file-list-popup.component-CxrsI6Hn.mjs.map +0 -1
  64. package/fesm2022/acorex-platform-layout-widgets-tabular-data-edit-popup.component-Ck7-wpT2.mjs.map +0 -1
  65. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-VIGuU5M4.mjs.map +0 -1
  66. package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-DyDa_hyd.mjs.map +0 -1
  67. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-Ua3ZA5hk.mjs +0 -101
  68. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-Ua3ZA5hk.mjs.map +0 -1
  69. package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-eMBby9k4.mjs.map +0 -1
@@ -1,8 +1,8 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, Injector, Injectable, signal, inject, Input, Directive, provideAppInitializer, Optional, Inject, NgModule } from '@angular/core';
3
- import { AXPBroadcastEventService, AXP_MODULE_PROVIDER_LOADER, AXPModuleProviderRegistry, AXP_SESSION_SERVICE } from '@acorex/platform/core';
2
+ import { InjectionToken, Injector, Injectable, signal, inject, Input, Directive, provideAppInitializer, Optional, Inject, NgModule, input, output, Component } from '@angular/core';
3
+ import { of, map, BehaviorSubject, shareReplay, defaultIfEmpty, switchMap, filter, firstValueFrom, first } from 'rxjs';
4
+ import { AXPBroadcastEventService } from '@acorex/platform/core';
4
5
  import { isEmpty } from 'lodash-es';
5
- import { map, BehaviorSubject, shareReplay, defaultIfEmpty, switchMap, filter, from, first } from 'rxjs';
6
6
 
7
7
  const AXP_APPLICATION_LOADER = new InjectionToken('AXP_APPLICATION_LOADER', {
8
8
  providedIn: 'root',
@@ -11,29 +11,25 @@ const AXP_APPLICATION_LOADER = new InjectionToken('AXP_APPLICATION_LOADER', {
11
11
  },
12
12
  });
13
13
  class AXPApplicationDefaultLoader {
14
- async getList(context) {
15
- return [
14
+ getList(context) {
15
+ return of([
16
16
  {
17
17
  id: '1',
18
18
  name: 'default-app',
19
19
  title: 'Default Application',
20
20
  version: '1.0.0',
21
- edition: {
22
- id: 'default-edition-1',
23
- title: 'Standard',
24
- },
21
+ editionName: 'Standard',
22
+ features: [],
25
23
  },
26
24
  {
27
25
  id: '2',
28
26
  name: 'default-app',
29
27
  title: 'Default Application',
30
28
  version: '1.0.0',
31
- edition: {
32
- id: 'default-edition-2',
33
- title: 'Standard',
34
- },
29
+ editionName: 'Standard',
30
+ features: [],
35
31
  },
36
- ];
32
+ ]);
37
33
  }
38
34
  }
39
35
 
@@ -44,14 +40,14 @@ const AXP_TENANT_LOADER = new InjectionToken('AXP_TENANT_LOADER', {
44
40
  },
45
41
  });
46
42
  class AXPTenantDefaultLoader {
47
- async getList(context) {
48
- return [
43
+ getList(context) {
44
+ return of([
49
45
  {
50
46
  id: '1',
51
47
  name: 'default-tenant',
52
48
  title: 'Default Tenant',
53
49
  },
54
- ];
50
+ ]);
55
51
  }
56
52
  }
57
53
 
@@ -89,8 +85,8 @@ const AXP_FEATURE_LOADER = new InjectionToken('AXP_FEATURE_LOADER', {
89
85
  },
90
86
  });
91
87
  class AXPFeatureDefaultLoader {
92
- async getList(context) {
93
- return [];
88
+ getList(context) {
89
+ return of([]);
94
90
  }
95
91
  }
96
92
 
@@ -177,13 +173,6 @@ const AXPFeatureGuard = (route, state) => {
177
173
  }));
178
174
  };
179
175
 
180
- /**
181
- * Optional injection token for feature checker.
182
- * If provided, the checker will be called to potentially override
183
- * feature enablement results based on custom logic.
184
- */
185
- const AXP_FEATURE_CHECKER = new InjectionToken('AXP_FEATURE_CHECKER');
186
-
187
176
  const AXP_PERMISSION_LOADER = new InjectionToken('AXP_PERMISSION_LOADER', {
188
177
  providedIn: 'root',
189
178
  factory: () => {
@@ -191,18 +180,11 @@ const AXP_PERMISSION_LOADER = new InjectionToken('AXP_PERMISSION_LOADER', {
191
180
  }
192
181
  });
193
182
  class AXPPermissionDefaultLoader {
194
- async getList(context) {
195
- return [];
183
+ getList(context) {
184
+ return of([]);
196
185
  }
197
186
  }
198
187
 
199
- /**
200
- * Optional injection token for permission checker.
201
- * If provided, the checker will be called to potentially override
202
- * authorization results based on custom logic.
203
- */
204
- const AXP_PERMISSION_CHECKER = new InjectionToken('AXP_PERMISSION_CHECKER');
205
-
206
188
  class AXPSessionContext {
207
189
  get user() {
208
190
  return this._user;
@@ -240,9 +222,6 @@ class AXPSessionService {
240
222
  this.featureLoader = inject(AXP_FEATURE_LOADER);
241
223
  this.tenantLoader = inject(AXP_TENANT_LOADER);
242
224
  this.applicationLoader = inject(AXP_APPLICATION_LOADER);
243
- this.moduleProviderLoader = inject(AXP_MODULE_PROVIDER_LOADER);
244
- this.permissionChecker = inject(AXP_PERMISSION_CHECKER, { optional: true });
245
- this.featureChecker = inject(AXP_FEATURE_CHECKER, { optional: true });
246
225
  this.status = new BehaviorSubject(AXPSessionStatus.Unauthenticated);
247
226
  this.status$ = this.status.asObservable().pipe(shareReplay(1));
248
227
  // Add loading state to prevent premature redirects
@@ -265,10 +244,8 @@ class AXPSessionService {
265
244
  // Add a new observable that considers loading state
266
245
  this.isAuthenticatedWithLoading$ = this.isLoading$.pipe(switchMap((loading) => {
267
246
  if (loading) {
268
- // Wait for loading to complete, then return authentication status
269
247
  return this.isLoading$.pipe(filter((isLoading) => !isLoading), switchMap(() => this.isAuthenticated$));
270
248
  }
271
- // If not loading, return current authentication status
272
249
  return this.isAuthenticated$;
273
250
  }), shareReplay(1));
274
251
  this.isAuthorized$ = this.status$.pipe(map((status) => status === AXPSessionStatus.Authorized), shareReplay(1));
@@ -289,7 +266,7 @@ class AXPSessionService {
289
266
  return this.currentTenantSubject.value;
290
267
  }
291
268
  get tenants$() {
292
- return from(this.tenantLoader.getList(this.getContext()));
269
+ return this.tenantLoader.getList(this.getContext());
293
270
  }
294
271
  get application() {
295
272
  const session = this.getSessionData();
@@ -299,7 +276,7 @@ class AXPSessionService {
299
276
  return this.currentApplicationSubject.value;
300
277
  }
301
278
  get applications$() {
302
- return from(this.applicationLoader.getList(this.getContext()));
279
+ return this.applicationLoader.getList(this.getContext());
303
280
  }
304
281
  get permissions() {
305
282
  return this.permissionsSubject.value ?? [];
@@ -314,18 +291,7 @@ class AXPSessionService {
314
291
  if (sessionData) {
315
292
  if (sessionData.user) {
316
293
  this.currentUserSubject.next(sessionData.user);
317
- // Restore tenant and application from session data
318
- if (sessionData.tenant) {
319
- this.currentTenantSubject.next(sessionData.tenant);
320
- }
321
- if (sessionData.application) {
322
- this.currentApplicationSubject.next(sessionData.application);
323
- }
324
294
  this.status.next(AXPSessionStatus.Authenticated);
325
- // Load required modules first to ensure entities are available for loaders
326
- // This is critical because loaders (like application.loader) need entities
327
- // from required modules (ApplicationManagement, TenantManagement, SecurityManagement)
328
- await this.moduleProviderLoader.loadRequiredModules();
329
295
  await this.loadPermissions();
330
296
  await this.loadFeatures();
331
297
  await this.signInComplete();
@@ -443,9 +409,6 @@ class AXPSessionService {
443
409
  }
444
410
  //
445
411
  const userId = this.user?.id;
446
- // Clear module provider loader cache before clearing session
447
- // This ensures modules and providers from previous user are not cached
448
- await this.moduleProviderLoader.clear();
449
412
  this.clearSession();
450
413
  this.eventService.publish(AXPSessionStatus.SignedOut, { id: userId });
451
414
  this.isLoading.next(false);
@@ -494,7 +457,7 @@ class AXPSessionService {
494
457
  }
495
458
  async loadPermissions() {
496
459
  try {
497
- const permissions = await this.permissionLoader.getList(this.getContext());
460
+ const permissions = await firstValueFrom(this.permissionLoader.getList(this.getContext()));
498
461
  this.permissionsSubject.next(permissions ?? []);
499
462
  }
500
463
  catch (error) {
@@ -504,7 +467,7 @@ class AXPSessionService {
504
467
  }
505
468
  async loadFeatures() {
506
469
  try {
507
- const features = await this.featureLoader.getList(this.getContext());
470
+ const features = await firstValueFrom(this.featureLoader.getList(this.getContext()));
508
471
  this.featuresSubject.next(features ?? []);
509
472
  }
510
473
  catch (error) {
@@ -584,39 +547,26 @@ class AXPSessionService {
584
547
  localStorage.removeItem(AXPSessionService.SESSION_KEY);
585
548
  }
586
549
  authorize(...keys) {
587
- // Calculate base result
588
- const baseResult = keys.every((k) => {
589
- if (isEmpty(k))
590
- return true;
591
- // Check if user has the permission
592
- const hasPermission = this.permissions.indexOf(k) > -1;
593
- if (!hasPermission)
594
- return false;
595
- // Check if permission has required features (if permission definition service is available)
596
- // Note: This is a lightweight check. Full feature validation happens in permission definition service.
597
- return true;
598
- });
599
- // If permission checker is provided, use it to potentially override the result
600
- if (this.permissionChecker) {
601
- const context = this.getContext();
602
- return this.permissionChecker.check(keys, context, baseResult);
603
- }
604
- return baseResult;
550
+ return keys.every((k) => isEmpty(k) || this.permissions.indexOf(k) > -1 || this.user?.name == 'root');
605
551
  }
606
552
  isFeatureEnabled(...keys) {
607
- // Calculate base result
608
- const baseResult = keys.every((k) => isEmpty(k) || this.features.some((c) => c.name == k && c.value == true));
609
- // If feature checker is provided, use it to potentially override the result
610
- if (this.featureChecker) {
611
- const context = this.getContext();
612
- return this.featureChecker.check(keys, context, baseResult);
613
- }
614
- return baseResult;
553
+ return keys.every((k) => isEmpty(k) || this.features.some((c) => c.name == k && c.value == true));
615
554
  }
616
555
  getToken() {
617
556
  const sessionData = this.getSessionData();
618
557
  return sessionData?.accessToken;
619
558
  }
559
+ checkTokenValidation() {
560
+ let sessionData = this.getSessionData();
561
+ if (sessionData && sessionData?.accessToken && sessionData.expiresIn) {
562
+ const expiresInDate = new Date(sessionData.expiresIn);
563
+ if (expiresInDate > new Date()) {
564
+ // Token is still valid
565
+ return true;
566
+ }
567
+ }
568
+ return false;
569
+ }
620
570
  getContext() {
621
571
  return new AXPSessionContext({
622
572
  user: this.user,
@@ -737,13 +687,12 @@ class AXPPermissionDefinitionGroupBuilder {
737
687
  this.context = context;
738
688
  this._group = group;
739
689
  }
740
- addPermission(name, title, description, requiredFeatures) {
690
+ addPermission(name, title, description) {
741
691
  const permission = {
742
692
  name,
743
693
  title,
744
694
  description,
745
- children: [],
746
- requiredFeatures
695
+ children: []
747
696
  };
748
697
  this._group.permissions.push(permission);
749
698
  return new AXPPermissionDefinitionBuilder(this, permission);
@@ -763,25 +712,16 @@ class AXPPermissionDefinitionBuilder {
763
712
  this.groupBuilder = groupBuilder;
764
713
  this.permission = permission;
765
714
  }
766
- addChild(name, title, description, requiredFeatures) {
715
+ addChild(name, title, description) {
767
716
  const permission = {
768
717
  name,
769
718
  title,
770
719
  description,
771
- children: [],
772
- requiredFeatures
720
+ children: []
773
721
  };
774
722
  this.permission.children.push(permission);
775
723
  return this;
776
724
  }
777
- /**
778
- * Set required features for this permission.
779
- * @param features - Array of feature names (e.g., ['PlatformManagement.menu-customization'])
780
- */
781
- requireFeatures(...features) {
782
- this.permission.requiredFeatures = features;
783
- return this;
784
- }
785
725
  endPermission() {
786
726
  return this.groupBuilder;
787
727
  }
@@ -796,8 +736,6 @@ const AXP_PERMISSION_DEFINITION_PROVIDER = new InjectionToken('AXP_PERMISSION_DE
796
736
  class AXPPermissionDefinitionService {
797
737
  constructor() {
798
738
  this.providers = inject(AXP_PERMISSION_DEFINITION_PROVIDER, { optional: true });
799
- this.providerRegistry = inject(AXPModuleProviderRegistry);
800
- this.sessionService = inject(AXPSessionService);
801
739
  this.cache = null;
802
740
  }
803
741
  async load() {
@@ -805,7 +743,6 @@ class AXPPermissionDefinitionService {
805
743
  return;
806
744
  }
807
745
  const context = new AXPPermissionDefinitionProviderContext();
808
- // Load providers from DI tokens (backward compatibility)
809
746
  if (Array.isArray(this.providers)) {
810
747
  for (const provider of this.providers) {
811
748
  if (provider instanceof Promise) {
@@ -819,49 +756,7 @@ class AXPPermissionDefinitionService {
819
756
  }
820
757
  }
821
758
  }
822
- // Load providers from registry (manifest-based, conditionally loaded)
823
- const registryProviders = this.providerRegistry.getPermissionProviders();
824
- for (const provider of registryProviders) {
825
- await provider.define(context);
826
- }
827
- // Filter permissions based on required features
828
- const allGroups = context.getGroupDefinitions();
829
- this.cache = this.filterByFeatures(allGroups);
830
- }
831
- /**
832
- * Filter permissions based on required features.
833
- * Removes permissions that have required features that are not enabled.
834
- */
835
- filterByFeatures(groups) {
836
- return groups.map(group => ({
837
- ...group,
838
- permissions: this.filterPermissions(group.permissions)
839
- })).filter(group => group.permissions.length > 0);
840
- }
841
- /**
842
- * Recursively filter permissions and their children based on required features.
843
- */
844
- filterPermissions(permissions) {
845
- return permissions
846
- .filter(permission => {
847
- // Check if required features are enabled
848
- if (permission.requiredFeatures && permission.requiredFeatures.length > 0) {
849
- const allFeaturesEnabled = permission.requiredFeatures.every(featureName => this.sessionService.isFeatureEnabled(featureName));
850
- if (!allFeaturesEnabled) {
851
- return false; // Filter out this permission
852
- }
853
- }
854
- return true;
855
- })
856
- .map(permission => ({
857
- ...permission,
858
- children: this.filterPermissions(permission.children)
859
- }))
860
- .filter(permission => {
861
- // Remove permissions that have no children if they were only containers
862
- // (This is optional - you might want to keep parent permissions even without children)
863
- return true;
864
- });
759
+ this.cache = context.getGroupDefinitions();
865
760
  }
866
761
  async reload() {
867
762
  this.cache = null;
@@ -987,10 +882,6 @@ class AXPAuthModule {
987
882
  const initializerFn = initializeAppState(inject(AXPSessionService));
988
883
  return initializerFn();
989
884
  }),
990
- {
991
- provide: AXP_SESSION_SERVICE,
992
- useExisting: AXPSessionService,
993
- },
994
885
  ] }); }
995
886
  }
996
887
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPAuthModule, decorators: [{
@@ -1004,10 +895,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
1004
895
  const initializerFn = initializeAppState(inject(AXPSessionService));
1005
896
  return initializerFn();
1006
897
  }),
1007
- {
1008
- provide: AXP_SESSION_SERVICE,
1009
- useExisting: AXPSessionService,
1010
- },
1011
898
  ],
1012
899
  }]
1013
900
  }], ctorParameters: () => [{ type: undefined, decorators: [{
@@ -1097,9 +984,169 @@ class TimeUtil {
1097
984
  }
1098
985
  //#endregion
1099
986
 
987
+ //#region ---- Challenge Data Types ----
988
+ //#endregion
989
+
990
+ //#region ---- Abstract Challenge Provider ----
991
+ /**
992
+ * Abstract base class for login challenge providers
993
+ *
994
+ * Implement this class to create custom challenge mechanisms like:
995
+ * - Image CAPTCHA
996
+ * - reCAPTCHA
997
+ * - SMS verification
998
+ * - Email verification
999
+ *
1000
+ * @example
1001
+ * ```typescript
1002
+ * @Injectable()
1003
+ * export class MyImageCaptchaProvider extends AXPLoginChallengeProvider {
1004
+ * readonly name = 'image-captcha';
1005
+ *
1006
+ * checkResponse(error: unknown): AXPChallengeCheckResult | null {
1007
+ * if (error instanceof HttpErrorResponse) {
1008
+ * if (error.error?.requiresCaptcha) {
1009
+ * return { required: true };
1010
+ * }
1011
+ * }
1012
+ * return null;
1013
+ * }
1014
+ *
1015
+ * async getChallenge(): Promise<AXPLoginChallengeData> {
1016
+ * const response = await this.http.get('/api/captcha').toPromise();
1017
+ * return {
1018
+ * id: response.id,
1019
+ * content: response.image,
1020
+ * contentType: 'image-base64'
1021
+ * };
1022
+ * }
1023
+ *
1024
+ * async refreshChallenge(): Promise<AXPLoginChallengeData> {
1025
+ * return this.getChallenge();
1026
+ * }
1027
+ *
1028
+ * getChallengeComponent(): Type<AXPLoginChallengeComponentBase> {
1029
+ * return MyCaptchaChallengeComponent;
1030
+ * }
1031
+ * }
1032
+ * ```
1033
+ */
1034
+ class AXPLoginChallengeProvider {
1035
+ /**
1036
+ * Returns the component type for rendering the challenge UI
1037
+ *
1038
+ * Override this method to provide a custom challenge UI component.
1039
+ * If not overridden (returns null), the login component will use
1040
+ * a default built-in UI.
1041
+ *
1042
+ * @returns Component type extending AXPLoginChallengeComponentBase, or null for default UI
1043
+ */
1044
+ getChallengeComponent() {
1045
+ return null;
1046
+ }
1047
+ }
1048
+ //#endregion
1049
+
1050
+ //#region ---- Injection Token ----
1051
+ /**
1052
+ * Injection token for the login challenge provider
1053
+ *
1054
+ * This token is optional - if not provided, no challenge mechanism will be used.
1055
+ *
1056
+ * @example
1057
+ * ```typescript
1058
+ * // In your app module or provider configuration:
1059
+ * providers: [
1060
+ * {
1061
+ * provide: AXP_LOGIN_CHALLENGE_PROVIDER,
1062
+ * useClass: MyImageCaptchaProvider
1063
+ * }
1064
+ * ]
1065
+ *
1066
+ * // In a component:
1067
+ * private challengeProvider = inject(AXP_LOGIN_CHALLENGE_PROVIDER, { optional: true });
1068
+ * ```
1069
+ */
1070
+ const AXP_LOGIN_CHALLENGE_PROVIDER = new InjectionToken('AXP_LOGIN_CHALLENGE_PROVIDER');
1071
+ //#endregion
1072
+
1073
+ //#region ---- Base Challenge Component ----
1074
+ /**
1075
+ * Base class for login challenge UI components
1076
+ *
1077
+ * Providers can extend this class to create custom challenge UIs.
1078
+ * The login component will render this component and listen to its outputs.
1079
+ *
1080
+ * @example
1081
+ * ```typescript
1082
+ * @Component({
1083
+ * selector: 'my-captcha-challenge',
1084
+ * template: `
1085
+ * <div class="captcha-container">
1086
+ * <img [src]="'data:image/png;base64,' + challengeData().content" />
1087
+ * <input
1088
+ * type="text"
1089
+ * [value]="response()"
1090
+ * (input)="onResponseChange($event)"
1091
+ * />
1092
+ * <button (click)="onRefreshClick()">Refresh</button>
1093
+ * </div>
1094
+ * `
1095
+ * })
1096
+ * export class MyCaptchaChallengeComponent extends AXPLoginChallengeComponentBase {
1097
+ * response = signal('');
1098
+ *
1099
+ * onResponseChange(event: Event) {
1100
+ * const value = (event.target as HTMLInputElement).value;
1101
+ * this.response.set(value);
1102
+ * this.responseChange.emit(value);
1103
+ * }
1104
+ *
1105
+ * onRefreshClick() {
1106
+ * this.refreshRequest.emit();
1107
+ * }
1108
+ * }
1109
+ * ```
1110
+ */
1111
+ class AXPLoginChallengeComponentBase {
1112
+ constructor() {
1113
+ //#region ---- Inputs ----
1114
+ /**
1115
+ * Challenge data to display
1116
+ * Contains the image/content and metadata from the server
1117
+ */
1118
+ this.challengeData = input.required(...(ngDevMode ? [{ debugName: "challengeData" }] : []));
1119
+ /**
1120
+ * Whether the challenge is currently loading (e.g., refreshing)
1121
+ */
1122
+ this.isLoading = input(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
1123
+ //#endregion
1124
+ //#region ---- Outputs ----
1125
+ /**
1126
+ * Emits when the user enters or changes their response
1127
+ * The login component will capture this value and include it in credentials
1128
+ */
1129
+ this.responseChange = output();
1130
+ /**
1131
+ * Emits when the user requests a new challenge (e.g., clicks refresh button)
1132
+ * The login component will call provider.refreshChallenge()
1133
+ */
1134
+ this.refreshRequest = output();
1135
+ }
1136
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPLoginChallengeComponentBase, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1137
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.12", type: AXPLoginChallengeComponentBase, isStandalone: true, selector: "ng-component", inputs: { challengeData: { classPropertyName: "challengeData", publicName: "challengeData", isSignal: true, isRequired: true, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { responseChange: "responseChange", refreshRequest: "refreshRequest" }, ngImport: i0, template: '', isInline: true }); }
1138
+ }
1139
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPLoginChallengeComponentBase, decorators: [{
1140
+ type: Component,
1141
+ args: [{
1142
+ template: '',
1143
+ standalone: true,
1144
+ }]
1145
+ }], propDecorators: { challengeData: [{ type: i0.Input, args: [{ isSignal: true, alias: "challengeData", required: true }] }], isLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "isLoading", required: false }] }], responseChange: [{ type: i0.Output, args: ["responseChange"] }], refreshRequest: [{ type: i0.Output, args: ["refreshRequest"] }] } });
1146
+
1100
1147
  /**
1101
1148
  * Generated bundle index. Do not edit.
1102
1149
  */
1103
1150
 
1104
- export { AXPAuthGuard, AXPAuthModule, AXPAuthStrategy, AXPAuthStrategyRegistryService, AXPFeatureDirective, AXPFeatureGuard, AXPPermissionDefinitionBuilder, AXPPermissionDefinitionGroupBuilder, AXPPermissionDefinitionProviderContext, AXPPermissionDefinitionService, AXPPermissionDirective, AXPPermissionEvaluatorScopeProvider, AXPPermissionGuard, AXPSessionContext, AXPSessionService, AXPSessionStatus, AXPUnauthenticatedError, AXPUnauthorizedError, AXP_APPLICATION_LOADER, AXP_FEATURE_CHECKER, AXP_FEATURE_LOADER, AXP_PERMISSION_CHECKER, AXP_PERMISSION_DEFINITION_PROVIDER, AXP_PERMISSION_LOADER, AXP_TENANT_LOADER, JwtUtil, PkceUtil, TimeUtil, initializeAppState };
1151
+ export { AXPAuthGuard, AXPAuthModule, AXPAuthStrategy, AXPAuthStrategyRegistryService, AXPFeatureDirective, AXPFeatureGuard, AXPLoginChallengeComponentBase, AXPLoginChallengeProvider, AXPPermissionDefinitionBuilder, AXPPermissionDefinitionGroupBuilder, AXPPermissionDefinitionProviderContext, AXPPermissionDefinitionService, AXPPermissionDirective, AXPPermissionEvaluatorScopeProvider, AXPPermissionGuard, AXPSessionContext, AXPSessionService, AXPSessionStatus, AXPUnauthenticatedError, AXPUnauthorizedError, AXP_APPLICATION_LOADER, AXP_FEATURE_LOADER, AXP_LOGIN_CHALLENGE_PROVIDER, AXP_PERMISSION_DEFINITION_PROVIDER, AXP_PERMISSION_LOADER, AXP_TENANT_LOADER, JwtUtil, PkceUtil, TimeUtil, initializeAppState };
1105
1152
  //# sourceMappingURL=acorex-platform-auth.mjs.map