@acorex-platform/module-auth-client 0.0.18 → 0.0.20

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 (123) hide show
  1. package/fesm2022/{acorex-platform-module-auth-client-acorex-platform-module-auth-client-mW7tx8C0.mjs → acorex-platform-module-auth-client-acorex-platform-module-auth-client-CYmUn-lw.mjs} +940 -608
  2. package/fesm2022/acorex-platform-module-auth-client-acorex-platform-module-auth-client-CYmUn-lw.mjs.map +1 -0
  3. package/fesm2022/acorex-platform-module-auth-client-app-chooser.component-BVbu-f8h.mjs +75 -0
  4. package/fesm2022/acorex-platform-module-auth-client-app-chooser.component-BVbu-f8h.mjs.map +1 -0
  5. package/fesm2022/{acorex-platform-module-auth-client-blank.layout-BRGgntib.mjs → acorex-platform-module-auth-client-blank.layout-BCXNPgrp.mjs} +6 -6
  6. package/fesm2022/acorex-platform-module-auth-client-blank.layout-BCXNPgrp.mjs.map +1 -0
  7. package/fesm2022/{acorex-platform-module-auth-client-change-password.command-O8Mgxoqj.mjs → acorex-platform-module-auth-client-change-password.command-DIM_d7RO.mjs} +51 -41
  8. package/fesm2022/acorex-platform-module-auth-client-change-password.command-DIM_d7RO.mjs.map +1 -0
  9. package/fesm2022/acorex-platform-module-auth-client-change-photo.command-CYGqrJV0.mjs +257 -0
  10. package/fesm2022/acorex-platform-module-auth-client-change-photo.command-CYGqrJV0.mjs.map +1 -0
  11. package/fesm2022/acorex-platform-module-auth-client-contracts.mjs +46 -10
  12. package/fesm2022/acorex-platform-module-auth-client-contracts.mjs.map +1 -1
  13. package/fesm2022/{acorex-platform-module-auth-client-edit-account-info.command-B-mVlXxg.mjs → acorex-platform-module-auth-client-edit-account-info.command-CD9IrimO.mjs} +5 -5
  14. package/fesm2022/acorex-platform-module-auth-client-edit-account-info.command-CD9IrimO.mjs.map +1 -0
  15. package/fesm2022/{acorex-platform-module-auth-client-edit-signature.command-CcTJJwAX.mjs → acorex-platform-module-auth-client-edit-signature.command-TjOLhvKL.mjs} +5 -5
  16. package/fesm2022/acorex-platform-module-auth-client-edit-signature.command-TjOLhvKL.mjs.map +1 -0
  17. package/fesm2022/acorex-platform-module-auth-client-get-user-activity.query-BTpibxe9.mjs +80 -0
  18. package/fesm2022/acorex-platform-module-auth-client-get-user-activity.query-BTpibxe9.mjs.map +1 -0
  19. package/fesm2022/{acorex-platform-module-auth-client-lock-screen.command-PMoJJxe7.mjs → acorex-platform-module-auth-client-lock-screen.command-Br9O4b5c.mjs} +6 -6
  20. package/fesm2022/acorex-platform-module-auth-client-lock-screen.command-Br9O4b5c.mjs.map +1 -0
  21. package/fesm2022/{acorex-platform-module-auth-client-login.module-C4S0RjM7.mjs → acorex-platform-module-auth-client-login.module-DJVL3bAF.mjs} +8 -21
  22. package/fesm2022/acorex-platform-module-auth-client-login.module-DJVL3bAF.mjs.map +1 -0
  23. package/fesm2022/acorex-platform-module-auth-client-master.layout-DZUYm22p.mjs +39 -0
  24. package/fesm2022/acorex-platform-module-auth-client-master.layout-DZUYm22p.mjs.map +1 -0
  25. package/fesm2022/{acorex-platform-module-auth-client-oauth-callback.component-CEMvfjj4.mjs → acorex-platform-module-auth-client-oauth-callback.component-DnQzPUxF.mjs} +11 -15
  26. package/fesm2022/acorex-platform-module-auth-client-oauth-callback.component-DnQzPUxF.mjs.map +1 -0
  27. package/fesm2022/acorex-platform-module-auth-client-open-sessions.command-LZKM9fgo.mjs +200 -0
  28. package/fesm2022/acorex-platform-module-auth-client-open-sessions.command-LZKM9fgo.mjs.map +1 -0
  29. package/fesm2022/{acorex-platform-module-auth-client-password.component-CIr6IBG6.mjs → acorex-platform-module-auth-client-password.component-CNKRWfuG.mjs} +86 -45
  30. package/fesm2022/acorex-platform-module-auth-client-password.component-CNKRWfuG.mjs.map +1 -0
  31. package/fesm2022/acorex-platform-module-auth-client-password.component-CW0t9fEn.mjs +87 -0
  32. package/fesm2022/acorex-platform-module-auth-client-password.component-CW0t9fEn.mjs.map +1 -0
  33. package/fesm2022/acorex-platform-module-auth-client-platform-settings-unavailable.component-BEVkQ3jh.mjs +47 -0
  34. package/fesm2022/acorex-platform-module-auth-client-platform-settings-unavailable.component-BEVkQ3jh.mjs.map +1 -0
  35. package/fesm2022/{acorex-platform-module-auth-client-profile-activity-chart.component-DTY1eEI_.mjs → acorex-platform-module-auth-client-profile-activity-chart.component-CtSrYARX.mjs} +38 -46
  36. package/fesm2022/acorex-platform-module-auth-client-profile-activity-chart.component-CtSrYARX.mjs.map +1 -0
  37. package/fesm2022/{acorex-platform-module-auth-client-profile-coming-soon.command-DBbFbzAx.mjs → acorex-platform-module-auth-client-profile-coming-soon.command-Crh2GsRA.mjs} +5 -5
  38. package/fesm2022/acorex-platform-module-auth-client-profile-coming-soon.command-Crh2GsRA.mjs.map +1 -0
  39. package/fesm2022/{acorex-platform-module-auth-client-profile-delete-account-danger-zone.component-C6u3AB4N.mjs → acorex-platform-module-auth-client-profile-delete-account-danger-zone.component-D0QS8joQ.mjs} +18 -13
  40. package/fesm2022/{acorex-platform-module-auth-client-profile-delete-account-danger-zone.component-C6u3AB4N.mjs.map → acorex-platform-module-auth-client-profile-delete-account-danger-zone.component-D0QS8joQ.mjs.map} +1 -1
  41. package/fesm2022/{acorex-platform-module-auth-client-profile-page-component.provider-Dhmzo4ME.mjs → acorex-platform-module-auth-client-profile-page-component.provider-6lNx6bKI.mjs} +7 -7
  42. package/fesm2022/{acorex-platform-module-auth-client-profile-page-component.provider-Dhmzo4ME.mjs.map → acorex-platform-module-auth-client-profile-page-component.provider-6lNx6bKI.mjs.map} +1 -1
  43. package/fesm2022/acorex-platform-module-auth-client-profile-page.component-CdxseoJX.mjs +650 -0
  44. package/fesm2022/acorex-platform-module-auth-client-profile-page.component-CdxseoJX.mjs.map +1 -0
  45. package/fesm2022/{acorex-platform-module-auth-client-register-password.component-ia6tdvTc.mjs → acorex-platform-module-auth-client-register-password.component-D-tBrCJv.mjs} +15 -14
  46. package/fesm2022/acorex-platform-module-auth-client-register-password.component-D-tBrCJv.mjs.map +1 -0
  47. package/fesm2022/{acorex-platform-module-auth-client-register.module--DG9m8iC.mjs → acorex-platform-module-auth-client-register.module-BrXqva0B.mjs} +23 -23
  48. package/fesm2022/acorex-platform-module-auth-client-register.module-BrXqva0B.mjs.map +1 -0
  49. package/fesm2022/{acorex-platform-module-auth-client-remove-pin-code.command-qtswigkv.mjs → acorex-platform-module-auth-client-remove-pin-code.command-uK04-h15.mjs} +7 -7
  50. package/fesm2022/acorex-platform-module-auth-client-remove-pin-code.command-uK04-h15.mjs.map +1 -0
  51. package/fesm2022/acorex-platform-module-auth-client-reset-password.component-CcwDb6Wb.mjs +115 -0
  52. package/fesm2022/acorex-platform-module-auth-client-reset-password.component-CcwDb6Wb.mjs.map +1 -0
  53. package/fesm2022/{acorex-platform-module-auth-client-result.component-DYJaB-FD.mjs → acorex-platform-module-auth-client-result.component-DWv1hmQR.mjs} +6 -6
  54. package/fesm2022/acorex-platform-module-auth-client-result.component-DWv1hmQR.mjs.map +1 -0
  55. package/fesm2022/{acorex-platform-module-auth-client-routes-DVN2Y2Ps.mjs → acorex-platform-module-auth-client-routes-IX2qmeqU.mjs} +3 -3
  56. package/fesm2022/{acorex-platform-module-auth-client-routes-DVN2Y2Ps.mjs.map → acorex-platform-module-auth-client-routes-IX2qmeqU.mjs.map} +1 -1
  57. package/fesm2022/acorex-platform-module-auth-client-session-lock-overlay.component-BhsTAmVe.mjs +361 -0
  58. package/fesm2022/acorex-platform-module-auth-client-session-lock-overlay.component-BhsTAmVe.mjs.map +1 -0
  59. package/fesm2022/acorex-platform-module-auth-client-set-pin-code.command-BJT7F-xz.mjs +116 -0
  60. package/fesm2022/acorex-platform-module-auth-client-set-pin-code.command-BJT7F-xz.mjs.map +1 -0
  61. package/fesm2022/{acorex-platform-module-auth-client-set-pin-code.component-BHVqbYFv.mjs → acorex-platform-module-auth-client-set-pin-code.component-Cq4skm_3.mjs} +29 -20
  62. package/fesm2022/acorex-platform-module-auth-client-set-pin-code.component-Cq4skm_3.mjs.map +1 -0
  63. package/fesm2022/{acorex-platform-module-auth-client-settings.provider-n1qbs6e1.mjs → acorex-platform-module-auth-client-settings.provider-Yaoz8yp3.mjs} +139 -11
  64. package/fesm2022/acorex-platform-module-auth-client-settings.provider-Yaoz8yp3.mjs.map +1 -0
  65. package/fesm2022/{acorex-platform-module-auth-client-show-profile-command-CxMz1yy-.mjs → acorex-platform-module-auth-client-show-profile-command-BWoDxIdx.mjs} +5 -6
  66. package/fesm2022/acorex-platform-module-auth-client-show-profile-command-BWoDxIdx.mjs.map +1 -0
  67. package/fesm2022/{acorex-platform-module-auth-client-signout-command-DqqrP5pk.mjs → acorex-platform-module-auth-client-signout-command-B7n_Fn4P.mjs} +5 -5
  68. package/fesm2022/acorex-platform-module-auth-client-signout-command-B7n_Fn4P.mjs.map +1 -0
  69. package/fesm2022/acorex-platform-module-auth-client-tenant-chooser.component-CHmg7D5H.mjs +67 -0
  70. package/fesm2022/acorex-platform-module-auth-client-tenant-chooser.component-CHmg7D5H.mjs.map +1 -0
  71. package/fesm2022/acorex-platform-module-auth-client-two-factor-code.component-nsB4v25Z.mjs +40 -0
  72. package/fesm2022/acorex-platform-module-auth-client-two-factor-code.component-nsB4v25Z.mjs.map +1 -0
  73. package/fesm2022/{acorex-platform-module-auth-client-two-factor.module-FAqKbmBb.mjs → acorex-platform-module-auth-client-two-factor.module-_jYo6xXr.mjs} +8 -11
  74. package/fesm2022/acorex-platform-module-auth-client-two-factor.module-_jYo6xXr.mjs.map +1 -0
  75. package/fesm2022/{acorex-platform-module-auth-client-view-login-history.command-B42BHIAL.mjs → acorex-platform-module-auth-client-view-login-history.command-ovj5rdHL.mjs} +13 -11
  76. package/fesm2022/acorex-platform-module-auth-client-view-login-history.command-ovj5rdHL.mjs.map +1 -0
  77. package/fesm2022/acorex-platform-module-auth-client.mjs +1 -1
  78. package/package.json +1 -1
  79. package/types/acorex-platform-module-auth-client-contracts.d.ts +43 -9
  80. package/types/acorex-platform-module-auth-client.d.ts +63 -56
  81. package/fesm2022/acorex-platform-module-auth-client-acorex-platform-module-auth-client-mW7tx8C0.mjs.map +0 -1
  82. package/fesm2022/acorex-platform-module-auth-client-app-chooser.component-IPLp1kVv.mjs +0 -67
  83. package/fesm2022/acorex-platform-module-auth-client-app-chooser.component-IPLp1kVv.mjs.map +0 -1
  84. package/fesm2022/acorex-platform-module-auth-client-blank.layout-BRGgntib.mjs.map +0 -1
  85. package/fesm2022/acorex-platform-module-auth-client-change-password.command-O8Mgxoqj.mjs.map +0 -1
  86. package/fesm2022/acorex-platform-module-auth-client-change-photo.command-BcNq9mTU.mjs +0 -192
  87. package/fesm2022/acorex-platform-module-auth-client-change-photo.command-BcNq9mTU.mjs.map +0 -1
  88. package/fesm2022/acorex-platform-module-auth-client-edit-account-info.command-B-mVlXxg.mjs.map +0 -1
  89. package/fesm2022/acorex-platform-module-auth-client-edit-signature.command-CcTJJwAX.mjs.map +0 -1
  90. package/fesm2022/acorex-platform-module-auth-client-lock-screen.command-PMoJJxe7.mjs.map +0 -1
  91. package/fesm2022/acorex-platform-module-auth-client-login.module-C4S0RjM7.mjs.map +0 -1
  92. package/fesm2022/acorex-platform-module-auth-client-master.layout-DXwb5VSr.mjs +0 -24
  93. package/fesm2022/acorex-platform-module-auth-client-master.layout-DXwb5VSr.mjs.map +0 -1
  94. package/fesm2022/acorex-platform-module-auth-client-oauth-callback.component-CEMvfjj4.mjs.map +0 -1
  95. package/fesm2022/acorex-platform-module-auth-client-open-sessions.command-BsS9b6Xk.mjs +0 -196
  96. package/fesm2022/acorex-platform-module-auth-client-open-sessions.command-BsS9b6Xk.mjs.map +0 -1
  97. package/fesm2022/acorex-platform-module-auth-client-password.component-CIr6IBG6.mjs.map +0 -1
  98. package/fesm2022/acorex-platform-module-auth-client-password.component-DnFItGdA.mjs +0 -88
  99. package/fesm2022/acorex-platform-module-auth-client-password.component-DnFItGdA.mjs.map +0 -1
  100. package/fesm2022/acorex-platform-module-auth-client-profile-activity-chart.component-DTY1eEI_.mjs.map +0 -1
  101. package/fesm2022/acorex-platform-module-auth-client-profile-coming-soon.command-DBbFbzAx.mjs.map +0 -1
  102. package/fesm2022/acorex-platform-module-auth-client-profile-page.component-CJ9AA3ZN.mjs +0 -446
  103. package/fesm2022/acorex-platform-module-auth-client-profile-page.component-CJ9AA3ZN.mjs.map +0 -1
  104. package/fesm2022/acorex-platform-module-auth-client-register-password.component-ia6tdvTc.mjs.map +0 -1
  105. package/fesm2022/acorex-platform-module-auth-client-register.module--DG9m8iC.mjs.map +0 -1
  106. package/fesm2022/acorex-platform-module-auth-client-remove-pin-code.command-qtswigkv.mjs.map +0 -1
  107. package/fesm2022/acorex-platform-module-auth-client-reset-password.component-CTlrt_18.mjs +0 -115
  108. package/fesm2022/acorex-platform-module-auth-client-reset-password.component-CTlrt_18.mjs.map +0 -1
  109. package/fesm2022/acorex-platform-module-auth-client-result.component-DYJaB-FD.mjs.map +0 -1
  110. package/fesm2022/acorex-platform-module-auth-client-session-lock-overlay.component-CN1JqPBW.mjs +0 -346
  111. package/fesm2022/acorex-platform-module-auth-client-session-lock-overlay.component-CN1JqPBW.mjs.map +0 -1
  112. package/fesm2022/acorex-platform-module-auth-client-set-pin-code.command-mBEdso1T.mjs +0 -33
  113. package/fesm2022/acorex-platform-module-auth-client-set-pin-code.command-mBEdso1T.mjs.map +0 -1
  114. package/fesm2022/acorex-platform-module-auth-client-set-pin-code.component-BHVqbYFv.mjs.map +0 -1
  115. package/fesm2022/acorex-platform-module-auth-client-settings.provider-n1qbs6e1.mjs.map +0 -1
  116. package/fesm2022/acorex-platform-module-auth-client-show-profile-command-CxMz1yy-.mjs.map +0 -1
  117. package/fesm2022/acorex-platform-module-auth-client-signout-command-DqqrP5pk.mjs.map +0 -1
  118. package/fesm2022/acorex-platform-module-auth-client-tenant-chooser.component-B_9s4F36.mjs +0 -59
  119. package/fesm2022/acorex-platform-module-auth-client-tenant-chooser.component-B_9s4F36.mjs.map +0 -1
  120. package/fesm2022/acorex-platform-module-auth-client-two-factor-code.component-DAxlYlhM.mjs +0 -40
  121. package/fesm2022/acorex-platform-module-auth-client-two-factor-code.component-DAxlYlhM.mjs.map +0 -1
  122. package/fesm2022/acorex-platform-module-auth-client-two-factor.module-FAqKbmBb.mjs.map +0 -1
  123. package/fesm2022/acorex-platform-module-auth-client-view-login-history.command-B42BHIAL.mjs.map +0 -1
@@ -1,18 +1,17 @@
1
1
  import * as i1 from '@acorex/components/button';
2
2
  import { AXButtonModule } from '@acorex/components/button';
3
3
  import { AXLoadingModule } from '@acorex/components/loading';
4
- import * as i7 from '@acorex/core/translation';
4
+ import * as i5 from '@acorex/core/translation';
5
5
  import { AXTranslationModule } from '@acorex/core/translation';
6
- import { AXPSessionService, AXPAuthStrategyRegistryService } from '@acorex-platform/framework-client/auth';
6
+ import { AXPSessionService, resolvePlatformOAuthRedirectUri } from '@acorex-platform/framework-client/auth';
7
7
  import { AXPHomePageService } from '@acorex-platform/framework-client/common';
8
8
  import { AXPStateMessageComponent } from '@acorex-platform/framework-client/layout/components';
9
- import * as i6 from '@angular/common';
9
+ import * as i3 from '@angular/common';
10
10
  import { CommonModule } from '@angular/common';
11
11
  import * as i0 from '@angular/core';
12
- import { inject, Component } from '@angular/core';
12
+ import { inject, ChangeDetectionStrategy, Component } from '@angular/core';
13
13
  import { Router, ActivatedRoute } from '@angular/router';
14
14
  import { BehaviorSubject } from 'rxjs';
15
- import { n as AXM_AUTH_CONFIG_TOKEN } from './acorex-platform-module-auth-client-acorex-platform-module-auth-client-mW7tx8C0.mjs';
16
15
 
17
16
  class AXPOAuthCallbackComponent {
18
17
  constructor() {
@@ -21,10 +20,6 @@ class AXPOAuthCallbackComponent {
21
20
  this.router = inject(Router);
22
21
  this.route = inject(ActivatedRoute);
23
22
  this.homePageService = inject(AXPHomePageService);
24
- this.configs = inject(AXM_AUTH_CONFIG_TOKEN);
25
- this.authStrategyRegistry = inject(AXPAuthStrategyRegistryService);
26
- this.strategyName = this.sessionService.getSessionData()?.strategy;
27
- this.strategy = this.authStrategyRegistry.get(this.strategyName);
28
23
  //#endregion
29
24
  //#region ---- Properties ----
30
25
  this.isLoading$ = new BehaviorSubject(true);
@@ -52,7 +47,8 @@ class AXPOAuthCallbackComponent {
52
47
  throw new Error('No authorization code received from OAuth provider');
53
48
  }
54
49
  this.status$.next('Exchanging authorization code for tokens...');
55
- const redirectUri = `${window.location.origin}/auth/axp-oauth-callback`;
50
+ const redirectUri = resolvePlatformOAuthRedirectUri();
51
+ // Strategy is resolved inside updateToken (session + pending OAuth key).
56
52
  await this.sessionService.updateToken({ code, redirectUri });
57
53
  this.status$.next('Authentication successful! Redirecting...');
58
54
  await this.navigateAfterSuccess();
@@ -93,13 +89,13 @@ class AXPOAuthCallbackComponent {
93
89
  handleGoHome() {
94
90
  this.router.navigate(['/']);
95
91
  }
96
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPOAuthCallbackComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
97
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPOAuthCallbackComponent, isStandalone: true, selector: "axp-oauth-callback", ngImport: i0, template: "<ng-container *translate=\"let t\">\n <div class=\"h-full flex flex-col items-center justify-center p-8\">\n <div class=\"w-96 text-center\">\n <!-- Loading State -->\n @if (isLoading$ | async) {\n <axp-state-message\n mode=\"loading\"\n icon=\"fa-solid fa-spinner fa-spin\"\n [title]=\"(status$ | async) || '@auth:state-message.loading.title'\"\n [description]=\"'@auth:state-message.loading.description'\"\n >\n </axp-state-message>\n }\n\n <!-- Error State -->\n @if ((error$ | async) && !(isLoading$ | async)) {\n <axp-state-message\n mode=\"error\"\n icon=\"fa-solid fa-exclamation-triangle\"\n [title]=\"'@auth:state-message.error.title'\"\n [description]=\"(error$ | async) || '@auth:state-message.error.description'\"\n >\n <div slot=\"actions\" class=\"flex flex-col gap-2 sm:flex-row sm:justify-center\">\n <ax-button color=\"primary\" text=\"Try Again\" (onClick)=\"handleRetry()\" class=\"w-full sm:w-auto\">\n </ax-button>\n <ax-button color=\"default\" text=\"Go Home\" (onClick)=\"handleGoHome()\" class=\"w-full sm:w-auto\">\n </ax-button>\n </div>\n </axp-state-message>\n }\n\n <!-- Success State (briefly shown before redirect) -->\n @if (!(isLoading$ | async) && !(error$ | async)) {\n <axp-state-message\n mode=\"success\"\n icon=\"fa-solid fa-check\"\n [title]=\"'@auth:state-message.success.title'\"\n [description]=\"'@auth:state-message.success.description'\"\n >\n </axp-state-message>\n }\n </div>\n </div>\n</ng-container>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: i7.AXTranslatorDirective, selector: "[translate]" }, { kind: "component", type: AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "titleParams", "descriptionParams", "look"] }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }] }); }
92
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPOAuthCallbackComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
93
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPOAuthCallbackComponent, isStandalone: true, selector: "axp-oauth-callback", ngImport: i0, template: "<ng-container *translate=\"let t\">\n <div class=\"h-full flex flex-col items-center justify-center p-8\">\n <div class=\"w-96 text-center\">\n <!-- Loading State -->\n @if (isLoading$ | async) {\n <axp-state-message\n mode=\"loading\"\n icon=\"fa-solid fa-spinner fa-spin\"\n [title]=\"(status$ | async) || '@auth:state-message.loading.title'\"\n [description]=\"'@auth:state-message.loading.description'\"\n >\n </axp-state-message>\n }\n\n <!-- Error State -->\n @if ((error$ | async) && !(isLoading$ | async)) {\n <axp-state-message\n mode=\"error\"\n icon=\"fa-solid fa-exclamation-triangle\"\n [title]=\"'@auth:state-message.error.title'\"\n [description]=\"(error$ | async) || '@auth:state-message.error.description'\"\n >\n <div slot=\"actions\" class=\"flex flex-col gap-2 sm:flex-row sm:justify-center\">\n <ax-button color=\"primary\" text=\"Try Again\" (onClick)=\"handleRetry()\" class=\"w-full sm:w-auto\">\n </ax-button>\n <ax-button color=\"default\" text=\"Go Home\" (onClick)=\"handleGoHome()\" class=\"w-full sm:w-auto\">\n </ax-button>\n </div>\n </axp-state-message>\n }\n\n <!-- Success State (briefly shown before redirect) -->\n @if (!(isLoading$ | async) && !(error$ | async)) {\n <axp-state-message\n mode=\"success\"\n icon=\"fa-solid fa-check\"\n [title]=\"'@auth:state-message.success.title'\"\n [description]=\"'@auth:state-message.success.description'\"\n >\n </axp-state-message>\n }\n </div>\n </div>\n</ng-container>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: i5.AXTranslatorDirective, selector: "[translate]" }, { kind: "component", type: AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "titleParams", "descriptionParams", "look"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
98
94
  }
99
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPOAuthCallbackComponent, decorators: [{
95
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPOAuthCallbackComponent, decorators: [{
100
96
  type: Component,
101
- args: [{ selector: 'axp-oauth-callback', imports: [CommonModule, AXButtonModule, AXLoadingModule, AXTranslationModule, AXPStateMessageComponent], standalone: true, template: "<ng-container *translate=\"let t\">\n <div class=\"h-full flex flex-col items-center justify-center p-8\">\n <div class=\"w-96 text-center\">\n <!-- Loading State -->\n @if (isLoading$ | async) {\n <axp-state-message\n mode=\"loading\"\n icon=\"fa-solid fa-spinner fa-spin\"\n [title]=\"(status$ | async) || '@auth:state-message.loading.title'\"\n [description]=\"'@auth:state-message.loading.description'\"\n >\n </axp-state-message>\n }\n\n <!-- Error State -->\n @if ((error$ | async) && !(isLoading$ | async)) {\n <axp-state-message\n mode=\"error\"\n icon=\"fa-solid fa-exclamation-triangle\"\n [title]=\"'@auth:state-message.error.title'\"\n [description]=\"(error$ | async) || '@auth:state-message.error.description'\"\n >\n <div slot=\"actions\" class=\"flex flex-col gap-2 sm:flex-row sm:justify-center\">\n <ax-button color=\"primary\" text=\"Try Again\" (onClick)=\"handleRetry()\" class=\"w-full sm:w-auto\">\n </ax-button>\n <ax-button color=\"default\" text=\"Go Home\" (onClick)=\"handleGoHome()\" class=\"w-full sm:w-auto\">\n </ax-button>\n </div>\n </axp-state-message>\n }\n\n <!-- Success State (briefly shown before redirect) -->\n @if (!(isLoading$ | async) && !(error$ | async)) {\n <axp-state-message\n mode=\"success\"\n icon=\"fa-solid fa-check\"\n [title]=\"'@auth:state-message.success.title'\"\n [description]=\"'@auth:state-message.success.description'\"\n >\n </axp-state-message>\n }\n </div>\n </div>\n</ng-container>\n" }]
97
+ args: [{ selector: 'axp-oauth-callback', imports: [CommonModule, AXButtonModule, AXLoadingModule, AXTranslationModule, AXPStateMessageComponent], changeDetection: ChangeDetectionStrategy.Eager, standalone: true, template: "<ng-container *translate=\"let t\">\n <div class=\"h-full flex flex-col items-center justify-center p-8\">\n <div class=\"w-96 text-center\">\n <!-- Loading State -->\n @if (isLoading$ | async) {\n <axp-state-message\n mode=\"loading\"\n icon=\"fa-solid fa-spinner fa-spin\"\n [title]=\"(status$ | async) || '@auth:state-message.loading.title'\"\n [description]=\"'@auth:state-message.loading.description'\"\n >\n </axp-state-message>\n }\n\n <!-- Error State -->\n @if ((error$ | async) && !(isLoading$ | async)) {\n <axp-state-message\n mode=\"error\"\n icon=\"fa-solid fa-exclamation-triangle\"\n [title]=\"'@auth:state-message.error.title'\"\n [description]=\"(error$ | async) || '@auth:state-message.error.description'\"\n >\n <div slot=\"actions\" class=\"flex flex-col gap-2 sm:flex-row sm:justify-center\">\n <ax-button color=\"primary\" text=\"Try Again\" (onClick)=\"handleRetry()\" class=\"w-full sm:w-auto\">\n </ax-button>\n <ax-button color=\"default\" text=\"Go Home\" (onClick)=\"handleGoHome()\" class=\"w-full sm:w-auto\">\n </ax-button>\n </div>\n </axp-state-message>\n }\n\n <!-- Success State (briefly shown before redirect) -->\n @if (!(isLoading$ | async) && !(error$ | async)) {\n <axp-state-message\n mode=\"success\"\n icon=\"fa-solid fa-check\"\n [title]=\"'@auth:state-message.success.title'\"\n [description]=\"'@auth:state-message.success.description'\"\n >\n </axp-state-message>\n }\n </div>\n </div>\n</ng-container>\n" }]
102
98
  }] });
103
99
 
104
100
  export { AXPOAuthCallbackComponent };
105
- //# sourceMappingURL=acorex-platform-module-auth-client-oauth-callback.component-CEMvfjj4.mjs.map
101
+ //# sourceMappingURL=acorex-platform-module-auth-client-oauth-callback.component-DnQzPUxF.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acorex-platform-module-auth-client-oauth-callback.component-DnQzPUxF.mjs","sources":["../../../../libs/modules/auth/client/src/lib/pages/callback/oauth-callback.component.ts","../../../../libs/modules/auth/client/src/lib/pages/callback/oauth-callback.component.html"],"sourcesContent":["import { AXButtonModule } from '@acorex/components/button';\nimport { AXLoadingModule } from '@acorex/components/loading';\nimport { AXTranslationModule } from '@acorex/core/translation';\nimport { AXPSessionService, resolvePlatformOAuthRedirectUri } from '@acorex-platform/framework-client/auth';\nimport { AXPHomePageService } from '@acorex-platform/framework-client/common';\nimport { AXPStateMessageComponent } from '@acorex-platform/framework-client/layout/components';\nimport { CommonModule } from '@angular/common';\nimport { Component, OnInit, inject, ChangeDetectionStrategy } from '@angular/core';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { BehaviorSubject } from 'rxjs';\n@Component({\n selector: 'axp-oauth-callback',\n templateUrl: './oauth-callback.component.html',\n imports: [CommonModule, AXButtonModule, AXLoadingModule, AXTranslationModule, AXPStateMessageComponent],\n changeDetection: ChangeDetectionStrategy.Eager,\n standalone: true,\n})\nexport class AXPOAuthCallbackComponent implements OnInit {\n //#region ---- Services & Dependencies ----\n\n private sessionService = inject(AXPSessionService);\n private router = inject(Router);\n private route = inject(ActivatedRoute);\n private homePageService = inject(AXPHomePageService);\n\n //#endregion\n\n //#region ---- Properties ----\n\n protected isLoading$ = new BehaviorSubject<boolean>(true);\n protected error$ = new BehaviorSubject<string | null>(null);\n protected status$ = new BehaviorSubject<string>('Processing authorization...');\n private exchangeStarted = false;\n // Removed: @Input() flow\n\n //#endregion\n\n //#region ---- Lifecycle Methods ----\n\n async ngOnInit(): Promise<void> {\n if (this.exchangeStarted) {\n return;\n }\n this.exchangeStarted = true;\n\n try {\n const queryParams = this.route.snapshot.queryParams;\n const code = queryParams['code'];\n const error = queryParams['error'];\n // Removed: flowParam and its assignment\n if (error) {\n throw new Error(`OAuth error: ${error} - ${queryParams['error_description'] || 'Unknown error'}`);\n }\n if (!code) {\n throw new Error('No authorization code received from OAuth provider');\n }\n this.status$.next('Exchanging authorization code for tokens...');\n\n const redirectUri = resolvePlatformOAuthRedirectUri();\n // Strategy is resolved inside updateToken (session + pending OAuth key).\n await this.sessionService.updateToken({ code, redirectUri });\n this.status$.next('Authentication successful! Redirecting...');\n await this.navigateAfterSuccess();\n } catch (error) {\n console.error('OAuth callback error:', error);\n const message =\n error instanceof Error && error.message.trim()\n ? error.message\n : 'Authentication failed. Please try again.';\n this.error$.next(message);\n await this.sessionService.signout();\n this.isLoading$.next(false);\n } finally {\n this.isLoading$.next(false);\n }\n }\n\n //#endregion\n\n //#region ---- Navigation ----\n\n private async navigateAfterSuccess(): Promise<void> {\n // Use await with router.navigate to ensure navigation completes\n if (this.sessionService.tenant?.id == null) {\n await this.router.navigate(['/auth/account/tenant-chooser']);\n return;\n }\n if (this.sessionService.application?.id == null) {\n await this.router.navigate(['/auth/account/app-chooser']);\n return;\n }\n // Navigate to home page\n await this.homePageService.navigateTo();\n }\n\n //#endregion\n\n //#region ---- UI Handlers ----\n\n protected handleRetry(): void {\n this.router.navigate(['/auth/login']);\n }\n\n protected handleGoHome(): void {\n this.router.navigate(['/']);\n }\n\n //#endregion\n}\n","<ng-container *translate=\"let t\">\n <div class=\"h-full flex flex-col items-center justify-center p-8\">\n <div class=\"w-96 text-center\">\n <!-- Loading State -->\n @if (isLoading$ | async) {\n <axp-state-message\n mode=\"loading\"\n icon=\"fa-solid fa-spinner fa-spin\"\n [title]=\"(status$ | async) || '@auth:state-message.loading.title'\"\n [description]=\"'@auth:state-message.loading.description'\"\n >\n </axp-state-message>\n }\n\n <!-- Error State -->\n @if ((error$ | async) && !(isLoading$ | async)) {\n <axp-state-message\n mode=\"error\"\n icon=\"fa-solid fa-exclamation-triangle\"\n [title]=\"'@auth:state-message.error.title'\"\n [description]=\"(error$ | async) || '@auth:state-message.error.description'\"\n >\n <div slot=\"actions\" class=\"flex flex-col gap-2 sm:flex-row sm:justify-center\">\n <ax-button color=\"primary\" text=\"Try Again\" (onClick)=\"handleRetry()\" class=\"w-full sm:w-auto\">\n </ax-button>\n <ax-button color=\"default\" text=\"Go Home\" (onClick)=\"handleGoHome()\" class=\"w-full sm:w-auto\">\n </ax-button>\n </div>\n </axp-state-message>\n }\n\n <!-- Success State (briefly shown before redirect) -->\n @if (!(isLoading$ | async) && !(error$ | async)) {\n <axp-state-message\n mode=\"success\"\n icon=\"fa-solid fa-check\"\n [title]=\"'@auth:state-message.success.title'\"\n [description]=\"'@auth:state-message.success.description'\"\n >\n </axp-state-message>\n }\n </div>\n </div>\n</ng-container>\n"],"names":["i2"],"mappings":"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"}
@@ -0,0 +1,200 @@
1
+ import { AXPopupService } from '@acorex/components/popup';
2
+ import * as i5$1 from '@acorex/core/translation';
3
+ import { AXTranslationService, AXTranslationModule } from '@acorex/core/translation';
4
+ import * as i0 from '@angular/core';
5
+ import { signal, inject, ChangeDetectorRef, computed, ViewEncapsulation, ChangeDetectionStrategy, Component, Injectable } from '@angular/core';
6
+ import { AXButtonModule } from '@acorex/components/button';
7
+ import { AXDataSource } from '@acorex/cdk/common';
8
+ import * as i3 from '@acorex/components/decorators';
9
+ import { AXDecoratorModule } from '@acorex/components/decorators';
10
+ import { AXDropdownModule } from '@acorex/components/dropdown';
11
+ import { AXPopoverModule } from '@acorex/components/popover';
12
+ import * as i4 from '@acorex/components/select-box';
13
+ import { AXSelectBoxModule } from '@acorex/components/select-box';
14
+ import { AXBasePageComponent } from '@acorex/components/page';
15
+ import * as i5 from '@acorex/core/format';
16
+ import { AXFormatModule } from '@acorex/core/format';
17
+ import { AXPSettingsService } from '@acorex-platform/framework-client/common';
18
+ import * as i3$1 from '@angular/common';
19
+ import { CommonModule } from '@angular/common';
20
+ import * as i1 from '@angular/forms';
21
+ import { FormsModule } from '@angular/forms';
22
+ import { AXPAuthInactiveSessionTerminationOptions, AXPAuthSettings } from '@acorex-platform/module-auth-client/contracts';
23
+ import { A as AXMUserDeviceSessionsService } from './acorex-platform-module-auth-client-acorex-platform-module-auth-client-CYmUn-lw.mjs';
24
+
25
+ //#endregion
26
+ class AXMUserSessionsComponent extends AXBasePageComponent {
27
+ //#endregion
28
+ //#region ---- Lifecycle ----
29
+ constructor() {
30
+ super();
31
+ //#region ---- State ----
32
+ this.items = signal([], /* @ts-ignore */
33
+ ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
34
+ this.activeSession = signal(undefined, /* @ts-ignore */
35
+ ...(ngDevMode ? [{ debugName: "activeSession" }] : /* istanbul ignore next */ []));
36
+ this.expireTime = signal(null, /* @ts-ignore */
37
+ ...(ngDevMode ? [{ debugName: "expireTime" }] : /* istanbul ignore next */ []));
38
+ //#endregion
39
+ //#region ---- Services & Dependencies ----
40
+ this.userDeviceSessionsService = inject(AXMUserDeviceSessionsService);
41
+ this.settingsService = inject(AXPSettingsService);
42
+ this.translateService = inject(AXTranslationService);
43
+ this.cdRef = inject(ChangeDetectorRef);
44
+ //#endregion
45
+ //#region ---- Data Sources ----
46
+ this.terminationOptionDefinitions = [
47
+ {
48
+ id: AXPAuthInactiveSessionTerminationOptions.OneWeek,
49
+ titleKey: '@auth:sessions.inactive-termination.options.one-week',
50
+ },
51
+ {
52
+ id: AXPAuthInactiveSessionTerminationOptions.OneMonth,
53
+ titleKey: '@auth:sessions.inactive-termination.options.one-month',
54
+ },
55
+ {
56
+ id: AXPAuthInactiveSessionTerminationOptions.ThreeMonths,
57
+ titleKey: '@auth:sessions.inactive-termination.options.three-months',
58
+ },
59
+ {
60
+ id: AXPAuthInactiveSessionTerminationOptions.SixMonths,
61
+ titleKey: '@auth:sessions.inactive-termination.options.six-months',
62
+ },
63
+ ];
64
+ this.expirationItems = [];
65
+ this.dataSource = new AXDataSource({
66
+ pageSize: 10,
67
+ key: 'id',
68
+ load: async () => ({
69
+ items: this.expirationItems,
70
+ total: this.expirationItems.length,
71
+ }),
72
+ });
73
+ //#endregion
74
+ //#region ---- Computed Properties ----
75
+ this.itemsWithIcons = computed(() => this.items().map((item) => ({
76
+ ...item,
77
+ icon: this.getDeviceIcon(item.deviceName),
78
+ })), /* @ts-ignore */
79
+ ...(ngDevMode ? [{ debugName: "itemsWithIcons" }] : /* istanbul ignore next */ []));
80
+ void this.loadUserSessions();
81
+ }
82
+ //#endregion
83
+ //#region ---- UI Handlers ----
84
+ getDeviceIcon(deviceName) {
85
+ if (!deviceName) {
86
+ return 'fa-solid fa-question';
87
+ }
88
+ const lowerCaseName = deviceName.toLowerCase();
89
+ if (lowerCaseName.includes('windows')) {
90
+ return 'fa-brands fa-windows';
91
+ }
92
+ if (lowerCaseName.includes('macbook') || lowerCaseName.includes('mac')) {
93
+ return 'fa-brands fa-apple';
94
+ }
95
+ if (lowerCaseName.includes('linux')) {
96
+ return 'fa-brands fa-linux';
97
+ }
98
+ if (lowerCaseName.includes('android')) {
99
+ return 'fa-brands fa-android';
100
+ }
101
+ if (lowerCaseName.includes('ios') || lowerCaseName.includes('iphone') || lowerCaseName.includes('ipad')) {
102
+ return 'fa-brands fa-apple';
103
+ }
104
+ return 'fa-solid fa-desktop';
105
+ }
106
+ onChangeSessionExpireTime(e) {
107
+ const selectedId = e.component.selectedItems[0]?.id;
108
+ if (!selectedId) {
109
+ return;
110
+ }
111
+ this.expireTime.set(selectedId);
112
+ void this.userDeviceSessionsService.setInactiveSessionTermination(selectedId);
113
+ }
114
+ async onTerminate(sessionId) {
115
+ if (!sessionId) {
116
+ console.error('No item to terminate');
117
+ return;
118
+ }
119
+ await this.userDeviceSessionsService.terminateSession(sessionId);
120
+ await this.loadUserSessions();
121
+ }
122
+ async onTerminateAll() {
123
+ await this.userDeviceSessionsService.terminateAllSession();
124
+ await this.loadUserSessions();
125
+ }
126
+ //#endregion
127
+ //#region ---- Private Methods ----
128
+ async loadUserSessions() {
129
+ try {
130
+ this.expirationItems = await Promise.all(this.terminationOptionDefinitions.map(async (option) => ({
131
+ id: option.id,
132
+ name: await this.translateService.translateAsync(option.titleKey),
133
+ })));
134
+ const sessions = await this.userDeviceSessionsService.getSessions();
135
+ this.items.set(sessions);
136
+ try {
137
+ const activeSession = await this.userDeviceSessionsService.getCurrentActiveSessions();
138
+ this.activeSession.set(activeSession);
139
+ }
140
+ catch (error) {
141
+ console.warn('No active session found:', error);
142
+ this.activeSession.set(undefined);
143
+ }
144
+ const inactiveSessionTermination = await this.settingsService.get(AXPAuthSettings.InactiveSessionTermination);
145
+ if (inactiveSessionTermination &&
146
+ Object.values(AXPAuthInactiveSessionTerminationOptions).includes(inactiveSessionTermination)) {
147
+ this.expireTime.set(inactiveSessionTermination);
148
+ }
149
+ await this.dataSource.refresh();
150
+ this.cdRef.markForCheck();
151
+ }
152
+ catch (error) {
153
+ console.error('Error loading user sessions', error);
154
+ }
155
+ }
156
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMUserSessionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
157
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXMUserSessionsComponent, isStandalone: true, selector: "axm-user-sessions", usesInheritance: true, ngImport: i0, template: "<ax-content>\n <div class=\"axm-user-sessions__content flex flex-col gap-4 p-6 w-full min-w-0 box-border\">\n <p class=\"font-semibold text-base text-on-lightest text-start m-0\">\n {{ '@auth:sessions.this-device.title' | translate | async }}\n </p>\n <div\n class=\"axm-user-sessions__row flex w-full min-w-0 items-center gap-3 rounded-lg border border-lightest bg-lightest p-3 text-on-lightest\"\n >\n <div class=\"axm-user-sessions__icon axm-user-sessions__icon--primary shrink-0 rounded-lg border border-primary-200 bg-primary-50\">\n <i class=\"{{ getDeviceIcon($safeNavigationMigration(activeSession()?.deviceName)) }} m-3 text-primary-500\"></i>\n </div>\n @if (activeSession()) {\n <div class=\"flex min-w-0 flex-1 flex-col text-start\">\n <div class=\"font-medium text-base\">{{ activeSession()?.deviceName }}</div>\n <div class=\"font-normal text-sm\">{{ activeSession()?.operatingSystem }}</div>\n <p class=\"axm-user-sessions__meta m-0 font-normal text-xs\">\n {{ activeSession()?.location }}\n @if (activeSession()?.lastLoginDate) {\n <span>{{ $safeNavigationMigration(activeSession()?.lastLoginDate) | format: 'datetime' : 'short' | async }}</span>\n }\n </p>\n </div>\n }\n </div>\n\n @if (itemsWithIcons().length > 0) {\n <div\n class=\"axm-user-sessions__row flex w-full min-w-0 cursor-pointer items-center gap-3 rounded-lg border border-lightest bg-lightest p-3 text-on-lightest\"\n (click)=\"onTerminateAll()\"\n >\n <div class=\"axm-user-sessions__icon axm-user-sessions__icon--danger shrink-0 rounded-lg border border-danger-200 bg-danger-50\">\n <i class=\"icon icon-clear m-3 text-danger-500\"></i>\n </div>\n <div class=\"flex min-w-0 flex-1 flex-col text-start\">\n <div class=\"font-medium text-base\">\n {{ '@auth:sessions.terminate-all.title' | translate | async }}\n </div>\n <p class=\"axm-user-sessions__meta m-0 font-normal text-sm\">\n {{ '@auth:sessions.terminate-all.description' | translate | async }}\n </p>\n </div>\n </div>\n\n <p class=\"font-semibold text-base text-on-lightest text-start m-0\">\n {{ '@auth:sessions.active-devices.title' | translate | async }}\n </p>\n @for (item of itemsWithIcons(); track item.id) {\n <div\n class=\"axm-user-sessions__row flex w-full min-w-0 items-center gap-3 rounded-lg border border-lightest bg-lightest p-3 text-on-lightest\"\n >\n <div class=\"axm-user-sessions__icon shrink-0 rounded-lg border\">\n <i class=\"{{ item.icon }} m-3\"></i>\n </div>\n <div class=\"flex min-w-0 flex-1 flex-col text-start\">\n <div class=\"font-medium text-base\">{{ item.deviceName }}</div>\n <div class=\"font-normal text-sm\">{{ item.operatingSystem }}</div>\n <p class=\"axm-user-sessions__meta m-0 font-normal text-xs\">\n {{ item.location }}\n @if (item.lastLoginDate) {\n <span>{{ item.lastLoginDate | format: 'datetime' : 'short' | async }}</span>\n }\n </p>\n </div>\n <button\n type=\"button\"\n class=\"axm-user-sessions__action shrink-0 border-0 bg-transparent p-1 cursor-pointer\"\n [attr.aria-label]=\"('@general:actions.remove.title' | translate | async) ?? ''\"\n (click)=\"onTerminate(item.id); $event.stopPropagation()\"\n >\n <i class=\"ax-icon ax-icon-close\"></i>\n </button>\n </div>\n }\n }\n </div>\n</ax-content>\n<ax-footer>\n <ax-suffix>\n <div class=\"axm-user-sessions__footer flex w-full min-w-0 flex-col gap-1 px-4 py-2 box-border\">\n <p class=\"m-0 text-start font-medium text-base text-danger-500\">\n {{ '@auth:sessions.terminate-old.title' | translate | async }}\n </p>\n <div class=\"axm-user-sessions__footer-setting w-full min-w-0\">\n <div class=\"axm-user-sessions__footer-label font-normal text-base text-on-lightest text-start\">\n {{ '@auth:sessions.terminate-old.inactive-for' | translate | async }}\n </div>\n <div class=\"axm-user-sessions__footer-select min-w-0\">\n <ax-select-box\n [ngModel]=\"expireTime()\"\n (onValueChanged)=\"onChangeSessionExpireTime($event)\"\n [dataSource]=\"dataSource\"\n textField=\"name\"\n valueField=\"id\"\n [placeholder]=\"('@auth:sessions.terminate-old.placeholder' | translate | async) ?? ''\"\n >\n </ax-select-box>\n </div>\n </div>\n </div>\n </ax-suffix>\n</ax-footer>\n", styles: [".axm-user-sessions .axm-user-sessions__content,.axm-user-sessions .axm-user-sessions__footer{box-sizing:border-box}.axm-user-sessions .axm-user-sessions__meta{color:rgb(var(--ax-sys-color-on-lighter-surface))}.axm-user-sessions .axm-user-sessions__action{color:rgb(var(--ax-sys-color-on-lightest-surface))}.axm-user-sessions .axm-user-sessions__footer-setting{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 3)}.axm-user-sessions .axm-user-sessions__footer-label{flex-shrink:0}.axm-user-sessions .axm-user-sessions__footer-select{margin-inline-start:auto;min-width:calc(var(--spacing, .25rem) * 48);flex:0 1 18rem}@media(max-width:640px){.axm-user-sessions .axm-user-sessions__footer-setting{flex-wrap:wrap}.axm-user-sessions .axm-user-sessions__footer-select{margin-inline-start:0px;max-width:none;flex:1 1 100%}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: AXButtonModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { 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: AXFormatModule }, { kind: "ngmodule", type: AXSelectBoxModule }, { kind: "component", type: i4.AXSelectBoxComponent, selector: "ax-select-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "minValue", "maxValue", "value", "state", "name", "id", "type", "look", "multiple", "valueField", "textField", "disabledField", "textTemplate", "selectedItems", "isItemTruncated", "showItemTooltip", "itemHeight", "maxVisibleItems", "dataSource", "minRecordsForSearch", "caption", "itemTemplate", "selectedTemplate", "emptyTemplate", "loadingTemplate", "dropdownWidth", "searchBoxAutoFocus"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onOpened", "onClosed", "onItemSelected", "onItemClick"] }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i3$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXFormatPipe, name: "format" }, { kind: "pipe", type: i5$1.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
158
+ }
159
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMUserSessionsComponent, decorators: [{
160
+ type: Component,
161
+ args: [{ selector: 'axm-user-sessions', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [
162
+ AXButtonModule,
163
+ AXDecoratorModule,
164
+ CommonModule,
165
+ FormsModule,
166
+ AXFormatModule,
167
+ AXSelectBoxModule,
168
+ AXDropdownModule,
169
+ AXPopoverModule,
170
+ AXTranslationModule,
171
+ ], template: "<ax-content>\n <div class=\"axm-user-sessions__content flex flex-col gap-4 p-6 w-full min-w-0 box-border\">\n <p class=\"font-semibold text-base text-on-lightest text-start m-0\">\n {{ '@auth:sessions.this-device.title' | translate | async }}\n </p>\n <div\n class=\"axm-user-sessions__row flex w-full min-w-0 items-center gap-3 rounded-lg border border-lightest bg-lightest p-3 text-on-lightest\"\n >\n <div class=\"axm-user-sessions__icon axm-user-sessions__icon--primary shrink-0 rounded-lg border border-primary-200 bg-primary-50\">\n <i class=\"{{ getDeviceIcon($safeNavigationMigration(activeSession()?.deviceName)) }} m-3 text-primary-500\"></i>\n </div>\n @if (activeSession()) {\n <div class=\"flex min-w-0 flex-1 flex-col text-start\">\n <div class=\"font-medium text-base\">{{ activeSession()?.deviceName }}</div>\n <div class=\"font-normal text-sm\">{{ activeSession()?.operatingSystem }}</div>\n <p class=\"axm-user-sessions__meta m-0 font-normal text-xs\">\n {{ activeSession()?.location }}\n @if (activeSession()?.lastLoginDate) {\n <span>{{ $safeNavigationMigration(activeSession()?.lastLoginDate) | format: 'datetime' : 'short' | async }}</span>\n }\n </p>\n </div>\n }\n </div>\n\n @if (itemsWithIcons().length > 0) {\n <div\n class=\"axm-user-sessions__row flex w-full min-w-0 cursor-pointer items-center gap-3 rounded-lg border border-lightest bg-lightest p-3 text-on-lightest\"\n (click)=\"onTerminateAll()\"\n >\n <div class=\"axm-user-sessions__icon axm-user-sessions__icon--danger shrink-0 rounded-lg border border-danger-200 bg-danger-50\">\n <i class=\"icon icon-clear m-3 text-danger-500\"></i>\n </div>\n <div class=\"flex min-w-0 flex-1 flex-col text-start\">\n <div class=\"font-medium text-base\">\n {{ '@auth:sessions.terminate-all.title' | translate | async }}\n </div>\n <p class=\"axm-user-sessions__meta m-0 font-normal text-sm\">\n {{ '@auth:sessions.terminate-all.description' | translate | async }}\n </p>\n </div>\n </div>\n\n <p class=\"font-semibold text-base text-on-lightest text-start m-0\">\n {{ '@auth:sessions.active-devices.title' | translate | async }}\n </p>\n @for (item of itemsWithIcons(); track item.id) {\n <div\n class=\"axm-user-sessions__row flex w-full min-w-0 items-center gap-3 rounded-lg border border-lightest bg-lightest p-3 text-on-lightest\"\n >\n <div class=\"axm-user-sessions__icon shrink-0 rounded-lg border\">\n <i class=\"{{ item.icon }} m-3\"></i>\n </div>\n <div class=\"flex min-w-0 flex-1 flex-col text-start\">\n <div class=\"font-medium text-base\">{{ item.deviceName }}</div>\n <div class=\"font-normal text-sm\">{{ item.operatingSystem }}</div>\n <p class=\"axm-user-sessions__meta m-0 font-normal text-xs\">\n {{ item.location }}\n @if (item.lastLoginDate) {\n <span>{{ item.lastLoginDate | format: 'datetime' : 'short' | async }}</span>\n }\n </p>\n </div>\n <button\n type=\"button\"\n class=\"axm-user-sessions__action shrink-0 border-0 bg-transparent p-1 cursor-pointer\"\n [attr.aria-label]=\"('@general:actions.remove.title' | translate | async) ?? ''\"\n (click)=\"onTerminate(item.id); $event.stopPropagation()\"\n >\n <i class=\"ax-icon ax-icon-close\"></i>\n </button>\n </div>\n }\n }\n </div>\n</ax-content>\n<ax-footer>\n <ax-suffix>\n <div class=\"axm-user-sessions__footer flex w-full min-w-0 flex-col gap-1 px-4 py-2 box-border\">\n <p class=\"m-0 text-start font-medium text-base text-danger-500\">\n {{ '@auth:sessions.terminate-old.title' | translate | async }}\n </p>\n <div class=\"axm-user-sessions__footer-setting w-full min-w-0\">\n <div class=\"axm-user-sessions__footer-label font-normal text-base text-on-lightest text-start\">\n {{ '@auth:sessions.terminate-old.inactive-for' | translate | async }}\n </div>\n <div class=\"axm-user-sessions__footer-select min-w-0\">\n <ax-select-box\n [ngModel]=\"expireTime()\"\n (onValueChanged)=\"onChangeSessionExpireTime($event)\"\n [dataSource]=\"dataSource\"\n textField=\"name\"\n valueField=\"id\"\n [placeholder]=\"('@auth:sessions.terminate-old.placeholder' | translate | async) ?? ''\"\n >\n </ax-select-box>\n </div>\n </div>\n </div>\n </ax-suffix>\n</ax-footer>\n", styles: [".axm-user-sessions .axm-user-sessions__content,.axm-user-sessions .axm-user-sessions__footer{box-sizing:border-box}.axm-user-sessions .axm-user-sessions__meta{color:rgb(var(--ax-sys-color-on-lighter-surface))}.axm-user-sessions .axm-user-sessions__action{color:rgb(var(--ax-sys-color-on-lightest-surface))}.axm-user-sessions .axm-user-sessions__footer-setting{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 3)}.axm-user-sessions .axm-user-sessions__footer-label{flex-shrink:0}.axm-user-sessions .axm-user-sessions__footer-select{margin-inline-start:auto;min-width:calc(var(--spacing, .25rem) * 48);flex:0 1 18rem}@media(max-width:640px){.axm-user-sessions .axm-user-sessions__footer-setting{flex-wrap:wrap}.axm-user-sessions .axm-user-sessions__footer-select{margin-inline-start:0px;max-width:none;flex:1 1 100%}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
172
+ }], ctorParameters: () => [] });
173
+
174
+ //#region ---- Open sessions command ----
175
+ /** Opens the active sessions popup for the current user. */
176
+ class AXPOpenSessionsCommand {
177
+ constructor() {
178
+ //#region ---- Services & Dependencies ----
179
+ this.popupService = inject(AXPopupService);
180
+ this.translateService = inject(AXTranslationService);
181
+ }
182
+ //#endregion
183
+ //#region ---- Command ----
184
+ async execute() {
185
+ await this.popupService.open(AXMUserSessionsComponent, {
186
+ title: await this.translateService.translateAsync('@auth:profile.sessions'),
187
+ size: 'md',
188
+ });
189
+ return { success: true, kind: 'object', data: undefined };
190
+ }
191
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPOpenSessionsCommand, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
192
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPOpenSessionsCommand, providedIn: 'root' }); }
193
+ }
194
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPOpenSessionsCommand, decorators: [{
195
+ type: Injectable,
196
+ args: [{ providedIn: 'root' }]
197
+ }] });
198
+
199
+ export { AXPOpenSessionsCommand };
200
+ //# sourceMappingURL=acorex-platform-module-auth-client-open-sessions.command-LZKM9fgo.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acorex-platform-module-auth-client-open-sessions.command-LZKM9fgo.mjs","sources":["../../../../libs/modules/auth/client/src/lib/pages/account/user-sessions/user-sessions.component.ts","../../../../libs/modules/auth/client/src/lib/pages/account/user-sessions/user-sessions.component.html","../../../../libs/modules/auth/client/src/lib/commands/open-sessions.command.ts"],"sourcesContent":["import { AXButtonModule } from '@acorex/components/button';\nimport { AXDataSource, AXValueChangedEvent } from '@acorex/cdk/common';\nimport { AXDecoratorModule } from '@acorex/components/decorators';\nimport { AXDropdownModule } from '@acorex/components/dropdown';\nimport { AXPopoverModule } from '@acorex/components/popover';\nimport { AXSelectBoxModule } from '@acorex/components/select-box';\nimport { AXBasePageComponent } from '@acorex/components/page';\nimport { AXFormatModule } from '@acorex/core/format';\nimport { AXTranslationModule, AXTranslationService } from '@acorex/core/translation';\nimport { AXPSettingsService } from '@acorex-platform/framework-client/common';\nimport { CommonModule } from '@angular/common';\nimport { ChangeDetectionStrategy, ChangeDetectorRef, Component, computed, inject, signal, ViewEncapsulation } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport {\n AXPAuthInactiveSessionTerminationOptions,\n AXPAuthInactiveSessionTerminationValue,\n AXPAuthSettings,\n} from '@acorex-platform/module-auth-client/contracts';\nimport { AXMSecurityManagementDeviceSessionsEntityModel } from '@acorex-platform/module-security-management-client/contracts';\nimport { AXMUserDeviceSessionsService } from './user-sessions.service';\n\n//#region ---- Types ----\n\ninterface InactiveSessionTerminationOption {\n id: AXPAuthInactiveSessionTerminationValue;\n titleKey: string;\n}\n\ninterface TranslatedInactiveSessionTerminationOption {\n id: AXPAuthInactiveSessionTerminationValue;\n name: string;\n}\n\n//#endregion\n\n@Component({\n selector: 'axm-user-sessions',\n templateUrl: './user-sessions.component.html',\n styleUrl: './user-sessions.component.css',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n AXButtonModule,\n AXDecoratorModule,\n CommonModule,\n FormsModule,\n AXFormatModule,\n AXSelectBoxModule,\n AXDropdownModule,\n AXPopoverModule,\n AXTranslationModule,\n ],\n})\nexport class AXMUserSessionsComponent extends AXBasePageComponent {\n //#region ---- State ----\n\n items = signal<AXMSecurityManagementDeviceSessionsEntityModel[]>([]);\n activeSession = signal<AXMSecurityManagementDeviceSessionsEntityModel | undefined>(undefined);\n expireTime = signal<AXPAuthInactiveSessionTerminationValue | null>(null);\n\n //#endregion\n\n //#region ---- Services & Dependencies ----\n\n private readonly userDeviceSessionsService = inject(AXMUserDeviceSessionsService);\n private readonly settingsService = inject(AXPSettingsService);\n private readonly translateService = inject(AXTranslationService);\n private readonly cdRef = inject(ChangeDetectorRef);\n\n //#endregion\n\n //#region ---- Data Sources ----\n\n private readonly terminationOptionDefinitions: InactiveSessionTerminationOption[] = [\n {\n id: AXPAuthInactiveSessionTerminationOptions.OneWeek,\n titleKey: '@auth:sessions.inactive-termination.options.one-week',\n },\n {\n id: AXPAuthInactiveSessionTerminationOptions.OneMonth,\n titleKey: '@auth:sessions.inactive-termination.options.one-month',\n },\n {\n id: AXPAuthInactiveSessionTerminationOptions.ThreeMonths,\n titleKey: '@auth:sessions.inactive-termination.options.three-months',\n },\n {\n id: AXPAuthInactiveSessionTerminationOptions.SixMonths,\n titleKey: '@auth:sessions.inactive-termination.options.six-months',\n },\n ];\n\n protected expirationItems: TranslatedInactiveSessionTerminationOption[] = [];\n\n protected dataSource = new AXDataSource<TranslatedInactiveSessionTerminationOption>({\n pageSize: 10,\n key: 'id',\n load: async () => ({\n items: this.expirationItems,\n total: this.expirationItems.length,\n }),\n });\n\n //#endregion\n\n //#region ---- Computed Properties ----\n\n itemsWithIcons = computed(() =>\n this.items().map((item) => ({\n ...item,\n icon: this.getDeviceIcon(item.deviceName),\n })),\n );\n\n //#endregion\n\n //#region ---- Lifecycle ----\n\n constructor() {\n super();\n void this.loadUserSessions();\n }\n\n //#endregion\n\n //#region ---- UI Handlers ----\n\n getDeviceIcon(deviceName: string | undefined): string {\n if (!deviceName) {\n return 'fa-solid fa-question';\n }\n\n const lowerCaseName = deviceName.toLowerCase();\n\n if (lowerCaseName.includes('windows')) {\n return 'fa-brands fa-windows';\n }\n if (lowerCaseName.includes('macbook') || lowerCaseName.includes('mac')) {\n return 'fa-brands fa-apple';\n }\n if (lowerCaseName.includes('linux')) {\n return 'fa-brands fa-linux';\n }\n if (lowerCaseName.includes('android')) {\n return 'fa-brands fa-android';\n }\n if (lowerCaseName.includes('ios') || lowerCaseName.includes('iphone') || lowerCaseName.includes('ipad')) {\n return 'fa-brands fa-apple';\n }\n\n return 'fa-solid fa-desktop';\n }\n\n protected onChangeSessionExpireTime(e: AXValueChangedEvent): void {\n const selectedId = e.component.selectedItems[0]?.id as AXPAuthInactiveSessionTerminationValue | undefined;\n if (!selectedId) {\n return;\n }\n\n this.expireTime.set(selectedId);\n void this.userDeviceSessionsService.setInactiveSessionTermination(selectedId);\n }\n\n async onTerminate(sessionId: string | undefined): Promise<void> {\n if (!sessionId) {\n console.error('No item to terminate');\n return;\n }\n\n await this.userDeviceSessionsService.terminateSession(sessionId);\n await this.loadUserSessions();\n }\n\n async onTerminateAll(): Promise<void> {\n await this.userDeviceSessionsService.terminateAllSession();\n await this.loadUserSessions();\n }\n\n //#endregion\n\n //#region ---- Private Methods ----\n\n private async loadUserSessions(): Promise<void> {\n try {\n this.expirationItems = await Promise.all(\n this.terminationOptionDefinitions.map(async (option) => ({\n id: option.id,\n name: await this.translateService.translateAsync(option.titleKey),\n })),\n );\n\n const sessions = await this.userDeviceSessionsService.getSessions();\n this.items.set(sessions);\n\n try {\n const activeSession = await this.userDeviceSessionsService.getCurrentActiveSessions();\n this.activeSession.set(activeSession);\n } catch (error) {\n console.warn('No active session found:', error);\n this.activeSession.set(undefined);\n }\n\n const inactiveSessionTermination = await this.settingsService.get<AXPAuthInactiveSessionTerminationValue>(\n AXPAuthSettings.InactiveSessionTermination,\n );\n\n if (\n inactiveSessionTermination &&\n Object.values(AXPAuthInactiveSessionTerminationOptions).includes(inactiveSessionTermination)\n ) {\n this.expireTime.set(inactiveSessionTermination);\n }\n\n await this.dataSource.refresh();\n this.cdRef.markForCheck();\n } catch (error) {\n console.error('Error loading user sessions', error);\n }\n }\n\n //#endregion\n}\n","<ax-content>\n <div class=\"axm-user-sessions__content flex flex-col gap-4 p-6 w-full min-w-0 box-border\">\n <p class=\"font-semibold text-base text-on-lightest text-start m-0\">\n {{ '@auth:sessions.this-device.title' | translate | async }}\n </p>\n <div\n class=\"axm-user-sessions__row flex w-full min-w-0 items-center gap-3 rounded-lg border border-lightest bg-lightest p-3 text-on-lightest\"\n >\n <div class=\"axm-user-sessions__icon axm-user-sessions__icon--primary shrink-0 rounded-lg border border-primary-200 bg-primary-50\">\n <i class=\"{{ getDeviceIcon($safeNavigationMigration(activeSession()?.deviceName)) }} m-3 text-primary-500\"></i>\n </div>\n @if (activeSession()) {\n <div class=\"flex min-w-0 flex-1 flex-col text-start\">\n <div class=\"font-medium text-base\">{{ activeSession()?.deviceName }}</div>\n <div class=\"font-normal text-sm\">{{ activeSession()?.operatingSystem }}</div>\n <p class=\"axm-user-sessions__meta m-0 font-normal text-xs\">\n {{ activeSession()?.location }}\n @if (activeSession()?.lastLoginDate) {\n <span>{{ $safeNavigationMigration(activeSession()?.lastLoginDate) | format: 'datetime' : 'short' | async }}</span>\n }\n </p>\n </div>\n }\n </div>\n\n @if (itemsWithIcons().length > 0) {\n <div\n class=\"axm-user-sessions__row flex w-full min-w-0 cursor-pointer items-center gap-3 rounded-lg border border-lightest bg-lightest p-3 text-on-lightest\"\n (click)=\"onTerminateAll()\"\n >\n <div class=\"axm-user-sessions__icon axm-user-sessions__icon--danger shrink-0 rounded-lg border border-danger-200 bg-danger-50\">\n <i class=\"icon icon-clear m-3 text-danger-500\"></i>\n </div>\n <div class=\"flex min-w-0 flex-1 flex-col text-start\">\n <div class=\"font-medium text-base\">\n {{ '@auth:sessions.terminate-all.title' | translate | async }}\n </div>\n <p class=\"axm-user-sessions__meta m-0 font-normal text-sm\">\n {{ '@auth:sessions.terminate-all.description' | translate | async }}\n </p>\n </div>\n </div>\n\n <p class=\"font-semibold text-base text-on-lightest text-start m-0\">\n {{ '@auth:sessions.active-devices.title' | translate | async }}\n </p>\n @for (item of itemsWithIcons(); track item.id) {\n <div\n class=\"axm-user-sessions__row flex w-full min-w-0 items-center gap-3 rounded-lg border border-lightest bg-lightest p-3 text-on-lightest\"\n >\n <div class=\"axm-user-sessions__icon shrink-0 rounded-lg border\">\n <i class=\"{{ item.icon }} m-3\"></i>\n </div>\n <div class=\"flex min-w-0 flex-1 flex-col text-start\">\n <div class=\"font-medium text-base\">{{ item.deviceName }}</div>\n <div class=\"font-normal text-sm\">{{ item.operatingSystem }}</div>\n <p class=\"axm-user-sessions__meta m-0 font-normal text-xs\">\n {{ item.location }}\n @if (item.lastLoginDate) {\n <span>{{ item.lastLoginDate | format: 'datetime' : 'short' | async }}</span>\n }\n </p>\n </div>\n <button\n type=\"button\"\n class=\"axm-user-sessions__action shrink-0 border-0 bg-transparent p-1 cursor-pointer\"\n [attr.aria-label]=\"('@general:actions.remove.title' | translate | async) ?? ''\"\n (click)=\"onTerminate(item.id); $event.stopPropagation()\"\n >\n <i class=\"ax-icon ax-icon-close\"></i>\n </button>\n </div>\n }\n }\n </div>\n</ax-content>\n<ax-footer>\n <ax-suffix>\n <div class=\"axm-user-sessions__footer flex w-full min-w-0 flex-col gap-1 px-4 py-2 box-border\">\n <p class=\"m-0 text-start font-medium text-base text-danger-500\">\n {{ '@auth:sessions.terminate-old.title' | translate | async }}\n </p>\n <div class=\"axm-user-sessions__footer-setting w-full min-w-0\">\n <div class=\"axm-user-sessions__footer-label font-normal text-base text-on-lightest text-start\">\n {{ '@auth:sessions.terminate-old.inactive-for' | translate | async }}\n </div>\n <div class=\"axm-user-sessions__footer-select min-w-0\">\n <ax-select-box\n [ngModel]=\"expireTime()\"\n (onValueChanged)=\"onChangeSessionExpireTime($event)\"\n [dataSource]=\"dataSource\"\n textField=\"name\"\n valueField=\"id\"\n [placeholder]=\"('@auth:sessions.terminate-old.placeholder' | translate | async) ?? ''\"\n >\n </ax-select-box>\n </div>\n </div>\n </div>\n </ax-suffix>\n</ax-footer>\n","import { AXPCommand, type AXPCommandExecuteResultPromise } from '@acorex-platform/framework-shared/runtime';\nimport { AXPopupService } from '@acorex/components/popup';\nimport { AXTranslationService } from '@acorex/core/translation';\nimport { AXPRuntimeCommandResult } from '@acorex-platform/framework-shared/core';\n\nimport { inject, Injectable } from '@angular/core';\nimport { AXMUserSessionsComponent } from '../pages/account/user-sessions/user-sessions.component';\n\n//#region ---- Open sessions command ----\n\n/** Opens the active sessions popup for the current user. */\n@Injectable({ providedIn: 'root' })\nexport class AXPOpenSessionsCommand implements AXPCommand {\n //#region ---- Services & Dependencies ----\n\n private readonly popupService = inject(AXPopupService);\n private readonly translateService = inject(AXTranslationService);\n\n //#endregion\n\n //#region ---- Command ----\n\n async execute(): AXPCommandExecuteResultPromise<void> {\n await this.popupService.open(AXMUserSessionsComponent, {\n title: await this.translateService.translateAsync('@auth:profile.sessions'),\n size: 'md',\n });\n\n return { success: true, kind: 'object', data: undefined };\n }\n\n //#endregion\n}\n\n//#endregion\n"],"names":["i2","i3","i4","i6"],"mappings":"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"}