@acorex-platform/module-auth-client 0.0.38 → 0.0.48

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 (107) hide show
  1. package/fesm2022/acorex-platform-module-auth-client-accept-invitation.component-Ct28GG3a.mjs +179 -0
  2. package/fesm2022/acorex-platform-module-auth-client-accept-invitation.component-Ct28GG3a.mjs.map +1 -0
  3. package/fesm2022/{acorex-platform-module-auth-client-acorex-platform-module-auth-client-CRl74b8g.mjs → acorex-platform-module-auth-client-acorex-platform-module-auth-client-C1oSPf12.mjs} +1154 -107
  4. package/fesm2022/acorex-platform-module-auth-client-acorex-platform-module-auth-client-C1oSPf12.mjs.map +1 -0
  5. package/fesm2022/{acorex-platform-module-auth-client-app-chooser.component-CjWofUGR.mjs → acorex-platform-module-auth-client-app-chooser.component-CLKLwWW8.mjs} +4 -4
  6. package/fesm2022/{acorex-platform-module-auth-client-app-chooser.component-CjWofUGR.mjs.map → acorex-platform-module-auth-client-app-chooser.component-CLKLwWW8.mjs.map} +1 -1
  7. package/fesm2022/{acorex-platform-module-auth-client-blank.layout-BCXNPgrp.mjs → acorex-platform-module-auth-client-blank.layout-xSXPWxyw.mjs} +3 -3
  8. package/fesm2022/acorex-platform-module-auth-client-blank.layout-xSXPWxyw.mjs.map +1 -0
  9. package/fesm2022/{acorex-platform-module-auth-client-change-password.command-BqU3jYV9.mjs → acorex-platform-module-auth-client-change-password.command-CknYaMZD.mjs} +2 -2
  10. package/fesm2022/{acorex-platform-module-auth-client-change-password.command-BqU3jYV9.mjs.map → acorex-platform-module-auth-client-change-password.command-CknYaMZD.mjs.map} +1 -1
  11. package/fesm2022/{acorex-platform-module-auth-client-change-photo.command-CzO3A7OG.mjs → acorex-platform-module-auth-client-change-photo.command-CML784Lg.mjs} +71 -21
  12. package/fesm2022/acorex-platform-module-auth-client-change-photo.command-CML784Lg.mjs.map +1 -0
  13. package/fesm2022/acorex-platform-module-auth-client-command-return-url.util-mBmtJ7T2.mjs +69 -0
  14. package/fesm2022/acorex-platform-module-auth-client-command-return-url.util-mBmtJ7T2.mjs.map +1 -0
  15. package/fesm2022/acorex-platform-module-auth-client-contracts.mjs +12 -7
  16. package/fesm2022/acorex-platform-module-auth-client-contracts.mjs.map +1 -1
  17. package/fesm2022/{acorex-platform-module-auth-client-edit-account-info.command-CD9IrimO.mjs → acorex-platform-module-auth-client-edit-account-info.command-DulLUfWs.mjs} +25 -4
  18. package/fesm2022/acorex-platform-module-auth-client-edit-account-info.command-DulLUfWs.mjs.map +1 -0
  19. package/fesm2022/{acorex-platform-module-auth-client-get-user-activity.query-B1bKcSVQ.mjs → acorex-platform-module-auth-client-get-user-activity.query-CV9mdOBi.mjs} +2 -2
  20. package/fesm2022/{acorex-platform-module-auth-client-get-user-activity.query-B1bKcSVQ.mjs.map → acorex-platform-module-auth-client-get-user-activity.query-CV9mdOBi.mjs.map} +1 -1
  21. package/fesm2022/{acorex-platform-module-auth-client-lock-screen.command-DKtlBzS7.mjs → acorex-platform-module-auth-client-lock-screen.command-BH3Q6lJE.mjs} +2 -2
  22. package/fesm2022/{acorex-platform-module-auth-client-lock-screen.command-DKtlBzS7.mjs.map → acorex-platform-module-auth-client-lock-screen.command-BH3Q6lJE.mjs.map} +1 -1
  23. package/fesm2022/{acorex-platform-module-auth-client-login.module-CXl61yOu.mjs → acorex-platform-module-auth-client-login.module-DtvnPpBH.mjs} +3 -3
  24. package/fesm2022/{acorex-platform-module-auth-client-login.module-CXl61yOu.mjs.map → acorex-platform-module-auth-client-login.module-DtvnPpBH.mjs.map} +1 -1
  25. package/fesm2022/acorex-platform-module-auth-client-manage-two-factor.command-BAg2W20W.mjs +445 -0
  26. package/fesm2022/acorex-platform-module-auth-client-manage-two-factor.command-BAg2W20W.mjs.map +1 -0
  27. package/fesm2022/{acorex-platform-module-auth-client-master.layout-D7zUm7aL.mjs → acorex-platform-module-auth-client-master.layout-B3krDskY.mjs} +5 -5
  28. package/fesm2022/{acorex-platform-module-auth-client-master.layout-D7zUm7aL.mjs.map → acorex-platform-module-auth-client-master.layout-B3krDskY.mjs.map} +1 -1
  29. package/fesm2022/{acorex-platform-module-auth-client-oauth-callback.component-fdWC08nA.mjs → acorex-platform-module-auth-client-oauth-callback.component-DWnljN18.mjs} +3 -3
  30. package/fesm2022/{acorex-platform-module-auth-client-oauth-callback.component-fdWC08nA.mjs.map → acorex-platform-module-auth-client-oauth-callback.component-DWnljN18.mjs.map} +1 -1
  31. package/fesm2022/{acorex-platform-module-auth-client-open-sessions.command-DKvyMkhl.mjs → acorex-platform-module-auth-client-open-sessions.command-CEpu6c7D.mjs} +6 -6
  32. package/fesm2022/{acorex-platform-module-auth-client-open-sessions.command-DKvyMkhl.mjs.map → acorex-platform-module-auth-client-open-sessions.command-CEpu6c7D.mjs.map} +1 -1
  33. package/fesm2022/acorex-platform-module-auth-client-open-waiting-room.command-CR-_ppYd.mjs +28 -0
  34. package/fesm2022/acorex-platform-module-auth-client-open-waiting-room.command-CR-_ppYd.mjs.map +1 -0
  35. package/fesm2022/{acorex-platform-module-auth-client-password.component-BE2JkYm_.mjs → acorex-platform-module-auth-client-password.component-Ci5Wy3rO.mjs} +5 -5
  36. package/fesm2022/{acorex-platform-module-auth-client-password.component-BE2JkYm_.mjs.map → acorex-platform-module-auth-client-password.component-Ci5Wy3rO.mjs.map} +1 -1
  37. package/fesm2022/{acorex-platform-module-auth-client-password.component-BoWDVby5.mjs → acorex-platform-module-auth-client-password.component-ddh-_0k3.mjs} +39 -9
  38. package/fesm2022/acorex-platform-module-auth-client-password.component-ddh-_0k3.mjs.map +1 -0
  39. package/fesm2022/{acorex-platform-module-auth-client-platform-settings-unavailable.component-BJMtsa99.mjs → acorex-platform-module-auth-client-platform-settings-unavailable.component-LwuokJiZ.mjs} +4 -4
  40. package/fesm2022/{acorex-platform-module-auth-client-platform-settings-unavailable.component-BJMtsa99.mjs.map → acorex-platform-module-auth-client-platform-settings-unavailable.component-LwuokJiZ.mjs.map} +1 -1
  41. package/fesm2022/{acorex-platform-module-auth-client-profile-activity-chart.component-CFaRGMKu.mjs → acorex-platform-module-auth-client-profile-activity-chart.component-D4bqeKCd.mjs} +5 -5
  42. package/fesm2022/{acorex-platform-module-auth-client-profile-activity-chart.component-CFaRGMKu.mjs.map → acorex-platform-module-auth-client-profile-activity-chart.component-D4bqeKCd.mjs.map} +1 -1
  43. package/fesm2022/{acorex-platform-module-auth-client-profile-delete-account-danger-zone.component-Dx2-o9XL.mjs → acorex-platform-module-auth-client-profile-delete-account-danger-zone.component-DWNbDzDd.mjs} +4 -4
  44. package/fesm2022/{acorex-platform-module-auth-client-profile-delete-account-danger-zone.component-Dx2-o9XL.mjs.map → acorex-platform-module-auth-client-profile-delete-account-danger-zone.component-DWNbDzDd.mjs.map} +1 -1
  45. package/fesm2022/{acorex-platform-module-auth-client-profile-page-component.provider-1Spuexhb.mjs → acorex-platform-module-auth-client-profile-page-component.provider-DLTbTEe6.mjs} +4 -4
  46. package/fesm2022/{acorex-platform-module-auth-client-profile-page-component.provider-1Spuexhb.mjs.map → acorex-platform-module-auth-client-profile-page-component.provider-DLTbTEe6.mjs.map} +1 -1
  47. package/fesm2022/{acorex-platform-module-auth-client-profile-page.component-CGs24n0j.mjs → acorex-platform-module-auth-client-profile-page.component-BhmMsO3g.mjs} +9 -7
  48. package/fesm2022/acorex-platform-module-auth-client-profile-page.component-BhmMsO3g.mjs.map +1 -0
  49. package/fesm2022/acorex-platform-module-auth-client-pwa-install.component-BJOvT0hW.mjs +84 -0
  50. package/fesm2022/acorex-platform-module-auth-client-pwa-install.component-BJOvT0hW.mjs.map +1 -0
  51. package/fesm2022/{acorex-platform-module-auth-client-register-password.component-BlOn9609.mjs → acorex-platform-module-auth-client-register-password.component-M-ayP7oO.mjs} +7 -7
  52. package/fesm2022/{acorex-platform-module-auth-client-register-password.component-BlOn9609.mjs.map → acorex-platform-module-auth-client-register-password.component-M-ayP7oO.mjs.map} +1 -1
  53. package/fesm2022/{acorex-platform-module-auth-client-register.module-CpoYf5uG.mjs → acorex-platform-module-auth-client-register.module-Qa3ovje0.mjs} +4 -4
  54. package/fesm2022/{acorex-platform-module-auth-client-register.module-CpoYf5uG.mjs.map → acorex-platform-module-auth-client-register.module-Qa3ovje0.mjs.map} +1 -1
  55. package/fesm2022/{acorex-platform-module-auth-client-remove-pin-code.command-Da7ryul6.mjs → acorex-platform-module-auth-client-remove-pin-code.command-BenNCyt6.mjs} +2 -2
  56. package/fesm2022/{acorex-platform-module-auth-client-remove-pin-code.command-Da7ryul6.mjs.map → acorex-platform-module-auth-client-remove-pin-code.command-BenNCyt6.mjs.map} +1 -1
  57. package/fesm2022/{acorex-platform-module-auth-client-reset-password.component-D0nxlhJm.mjs → acorex-platform-module-auth-client-reset-password.component-BQfKSqpW.mjs} +6 -6
  58. package/fesm2022/{acorex-platform-module-auth-client-reset-password.component-D0nxlhJm.mjs.map → acorex-platform-module-auth-client-reset-password.component-BQfKSqpW.mjs.map} +1 -1
  59. package/fesm2022/{acorex-platform-module-auth-client-result.component-Bo1QkwMu.mjs → acorex-platform-module-auth-client-result.component-PhPaEAgh.mjs} +3 -3
  60. package/fesm2022/{acorex-platform-module-auth-client-result.component-Bo1QkwMu.mjs.map → acorex-platform-module-auth-client-result.component-PhPaEAgh.mjs.map} +1 -1
  61. package/fesm2022/acorex-platform-module-auth-client-routes-90eFjxx8.mjs +17 -0
  62. package/fesm2022/acorex-platform-module-auth-client-routes-90eFjxx8.mjs.map +1 -0
  63. package/fesm2022/{acorex-platform-module-auth-client-session-limit.component-DH58dRba.mjs → acorex-platform-module-auth-client-session-limit.component-Dc6TIn-2.mjs} +3 -3
  64. package/fesm2022/{acorex-platform-module-auth-client-session-limit.component-DH58dRba.mjs.map → acorex-platform-module-auth-client-session-limit.component-Dc6TIn-2.mjs.map} +1 -1
  65. package/fesm2022/{acorex-platform-module-auth-client-session-lock-overlay.component-cDCrwNRV.mjs → acorex-platform-module-auth-client-session-lock-overlay.component-ChigSAI-.mjs} +7 -7
  66. package/fesm2022/{acorex-platform-module-auth-client-session-lock-overlay.component-cDCrwNRV.mjs.map → acorex-platform-module-auth-client-session-lock-overlay.component-ChigSAI-.mjs.map} +1 -1
  67. package/fesm2022/{acorex-platform-module-auth-client-set-pin-code.command-FjM1kzUj.mjs → acorex-platform-module-auth-client-set-pin-code.command-CefSbJz8.mjs} +3 -3
  68. package/fesm2022/{acorex-platform-module-auth-client-set-pin-code.command-FjM1kzUj.mjs.map → acorex-platform-module-auth-client-set-pin-code.command-CefSbJz8.mjs.map} +1 -1
  69. package/fesm2022/{acorex-platform-module-auth-client-set-pin-code.component-BgEgdFxQ.mjs → acorex-platform-module-auth-client-set-pin-code.component-DqFW_4rM.mjs} +6 -6
  70. package/fesm2022/{acorex-platform-module-auth-client-set-pin-code.component-BgEgdFxQ.mjs.map → acorex-platform-module-auth-client-set-pin-code.component-DqFW_4rM.mjs.map} +1 -1
  71. package/fesm2022/{acorex-platform-module-auth-client-settings.provider-DGiK-MmW.mjs → acorex-platform-module-auth-client-settings.provider-DsKsZrOC.mjs} +18 -13
  72. package/fesm2022/acorex-platform-module-auth-client-settings.provider-DsKsZrOC.mjs.map +1 -0
  73. package/fesm2022/{acorex-platform-module-auth-client-signout-command-B7n_Fn4P.mjs → acorex-platform-module-auth-client-signout-command-D4Qgv7q2.mjs} +7 -1
  74. package/fesm2022/acorex-platform-module-auth-client-signout-command-D4Qgv7q2.mjs.map +1 -0
  75. package/fesm2022/{acorex-platform-module-auth-client-tenant-chooser.component-B8CNqHx5.mjs → acorex-platform-module-auth-client-tenant-chooser.component-DCdRCf1m.mjs} +5 -5
  76. package/fesm2022/{acorex-platform-module-auth-client-tenant-chooser.component-B8CNqHx5.mjs.map → acorex-platform-module-auth-client-tenant-chooser.component-DCdRCf1m.mjs.map} +1 -1
  77. package/fesm2022/acorex-platform-module-auth-client-two-factor-challenge.storage-mi0UD7Sc.mjs +48 -0
  78. package/fesm2022/acorex-platform-module-auth-client-two-factor-challenge.storage-mi0UD7Sc.mjs.map +1 -0
  79. package/fesm2022/acorex-platform-module-auth-client-two-factor-code.component-CtSv3MQu.mjs +200 -0
  80. package/fesm2022/acorex-platform-module-auth-client-two-factor-code.component-CtSv3MQu.mjs.map +1 -0
  81. package/fesm2022/{acorex-platform-module-auth-client-two-factor.module-CI8KC5M_.mjs → acorex-platform-module-auth-client-two-factor.module-B7tETPbq.mjs} +10 -5
  82. package/fesm2022/acorex-platform-module-auth-client-two-factor.module-B7tETPbq.mjs.map +1 -0
  83. package/fesm2022/{acorex-platform-module-auth-client-view-login-history.command-Cqb27L-l.mjs → acorex-platform-module-auth-client-view-login-history.command-CKPbyVWd.mjs} +2 -2
  84. package/fesm2022/{acorex-platform-module-auth-client-view-login-history.command-Cqb27L-l.mjs.map → acorex-platform-module-auth-client-view-login-history.command-CKPbyVWd.mjs.map} +1 -1
  85. package/fesm2022/acorex-platform-module-auth-client-waiting-room.component-IAVIt1fY.mjs +165 -0
  86. package/fesm2022/acorex-platform-module-auth-client-waiting-room.component-IAVIt1fY.mjs.map +1 -0
  87. package/fesm2022/acorex-platform-module-auth-client-welcome-onboarding-page.component-C2WYgv4l.mjs +813 -0
  88. package/fesm2022/acorex-platform-module-auth-client-welcome-onboarding-page.component-C2WYgv4l.mjs.map +1 -0
  89. package/fesm2022/acorex-platform-module-auth-client-welcome-onboarding.command-Ck1A26BI.mjs +59 -0
  90. package/fesm2022/acorex-platform-module-auth-client-welcome-onboarding.command-Ck1A26BI.mjs.map +1 -0
  91. package/fesm2022/acorex-platform-module-auth-client.mjs +1 -1
  92. package/package.json +2 -2
  93. package/types/acorex-platform-module-auth-client-contracts.d.ts +13 -3
  94. package/types/acorex-platform-module-auth-client.d.ts +60 -2
  95. package/fesm2022/acorex-platform-module-auth-client-acorex-platform-module-auth-client-CRl74b8g.mjs.map +0 -1
  96. package/fesm2022/acorex-platform-module-auth-client-blank.layout-BCXNPgrp.mjs.map +0 -1
  97. package/fesm2022/acorex-platform-module-auth-client-change-photo.command-CzO3A7OG.mjs.map +0 -1
  98. package/fesm2022/acorex-platform-module-auth-client-edit-account-info.command-CD9IrimO.mjs.map +0 -1
  99. package/fesm2022/acorex-platform-module-auth-client-password.component-BoWDVby5.mjs.map +0 -1
  100. package/fesm2022/acorex-platform-module-auth-client-profile-page.component-CGs24n0j.mjs.map +0 -1
  101. package/fesm2022/acorex-platform-module-auth-client-routes-B6iJHJ60.mjs +0 -13
  102. package/fesm2022/acorex-platform-module-auth-client-routes-B6iJHJ60.mjs.map +0 -1
  103. package/fesm2022/acorex-platform-module-auth-client-settings.provider-DGiK-MmW.mjs.map +0 -1
  104. package/fesm2022/acorex-platform-module-auth-client-signout-command-B7n_Fn4P.mjs.map +0 -1
  105. package/fesm2022/acorex-platform-module-auth-client-two-factor-code.component-BrqfaY8i.mjs +0 -40
  106. package/fesm2022/acorex-platform-module-auth-client-two-factor-code.component-BrqfaY8i.mjs.map +0 -1
  107. package/fesm2022/acorex-platform-module-auth-client-two-factor.module-CI8KC5M_.mjs.map +0 -1
@@ -0,0 +1,445 @@
1
+ import { AXDialogService } from '@acorex/components/dialog';
2
+ import { AXToastService } from '@acorex/components/toast';
3
+ import { AXTranslationService } from '@acorex/core/translation';
4
+ import { AXPSessionService } from '@acorex-platform/framework-client/auth';
5
+ import { AXPLayoutBuilderService, resolveLayoutBuilderDialogResult } from '@acorex-platform/framework-client/layout/builder';
6
+ import { AXPCommandService } from '@acorex-platform/framework-client/runtime';
7
+ import { runtimeCommandPayloadData } from '@acorex-platform/framework-shared/core';
8
+ import { AXM_TWO_FACTOR_ERROR_CODES, AXMSecurityManagementServerCommands } from '@acorex-platform/module-security-management-client/contracts';
9
+ import * as i0 from '@angular/core';
10
+ import { inject, Injectable } from '@angular/core';
11
+ import { T as TWO_FACTOR_SECTION_ID, d as PROFILE_SECTION_INSIGHTS_PATCH_METADATA_KEY, s as buildTwoFactorStatusInsights } from './acorex-platform-module-auth-client-acorex-platform-module-auth-client-C1oSPf12.mjs';
12
+
13
+ //#region ----- Constants -----
14
+ const I18N = '@auth:profile-page.commands.manage-two-factor';
15
+ const TWO_FACTOR_ERROR_I18N = {
16
+ [AXM_TWO_FACTOR_ERROR_CODES.NotSignedIn]: `${I18N}.messages.not-signed-in`,
17
+ [AXM_TWO_FACTOR_ERROR_CODES.InvalidInput]: `${I18N}.messages.invalid-input`,
18
+ [AXM_TWO_FACTOR_ERROR_CODES.IncorrectPassword]: `${I18N}.messages.incorrect-password`,
19
+ [AXM_TWO_FACTOR_ERROR_CODES.IncorrectCode]: `${I18N}.messages.incorrect-code`,
20
+ [AXM_TWO_FACTOR_ERROR_CODES.AlreadyEnabled]: `${I18N}.messages.already-enabled`,
21
+ [AXM_TWO_FACTOR_ERROR_CODES.NotEnabled]: `${I18N}.messages.not-enabled`,
22
+ [AXM_TWO_FACTOR_ERROR_CODES.EnrollmentExpired]: `${I18N}.messages.enrollment-expired`,
23
+ [AXM_TWO_FACTOR_ERROR_CODES.RateLimited]: `${I18N}.messages.rate-limited`,
24
+ [AXM_TWO_FACTOR_ERROR_CODES.InvalidConfiguration]: `${I18N}.messages.invalid-configuration`,
25
+ [AXM_TWO_FACTOR_ERROR_CODES.ProofRequired]: `${I18N}.messages.proof-required`,
26
+ };
27
+ //#endregion
28
+ //#region ----- Helpers -----
29
+ /** Groups Base32 secret in fours for Authenticator manual-entry UX (apps ignore spaces). */
30
+ function formatTotpManualSecret(secretBase32) {
31
+ const cleaned = String(secretBase32 ?? '')
32
+ .replace(/\s+/g, '')
33
+ .toUpperCase();
34
+ return cleaned.replace(/(.{4})(?=.)/g, '$1 ');
35
+ }
36
+ //#endregion
37
+ //#region ----- Manage two-factor command -----
38
+ /** Opens profile dialogs to enroll, disable, or regenerate recovery codes for 2FA. */
39
+ class AXPManageTwoFactorCommand {
40
+ constructor() {
41
+ //#region ----- Services & Dependencies -----
42
+ this.layoutBuilder = inject(AXPLayoutBuilderService);
43
+ this.commandService = inject(AXPCommandService);
44
+ this.sessionService = inject(AXPSessionService);
45
+ this.dialogService = inject(AXDialogService);
46
+ this.toastService = inject(AXToastService);
47
+ this.translateService = inject(AXTranslationService);
48
+ }
49
+ //#endregion
50
+ //#region ----- Command -----
51
+ async execute() {
52
+ if (!this.sessionService.user?.id) {
53
+ await this.showErrorToast(`${I18N}.messages.not-signed-in`);
54
+ return { success: false };
55
+ }
56
+ const status = await this.loadStatus();
57
+ if (!status) {
58
+ return { success: false };
59
+ }
60
+ // Prefer manage/disable whenever enrollment exists (even if setting briefly drifted).
61
+ if (status.enabled || status.enrolled) {
62
+ return this.runEnabledFlow(status);
63
+ }
64
+ return this.runEnrollmentFlow();
65
+ }
66
+ //#endregion
67
+ //#region ----- Enrollment -----
68
+ async runEnrollmentFlow() {
69
+ const enrollment = await this.promptStartEnrollment();
70
+ if (!enrollment) {
71
+ return { success: false };
72
+ }
73
+ // Let the password dialog finish teardown before opening the QR dialog
74
+ // (avoids RxJS ObjectUnsubscribedError on overlapping popup subjects).
75
+ await this.waitForDialogTeardown();
76
+ const confirmed = await this.promptConfirmEnrollment(enrollment);
77
+ if (!confirmed) {
78
+ return { success: false };
79
+ }
80
+ // Success feedback comes from the realtime security alert (avoid duplicate toasts).
81
+ await this.waitForDialogTeardown();
82
+ const generateCodes = await this.dialogService.confirm(await this.translateService.translateAsync(`${I18N}.recovery.offer-title`), await this.translateService.translateAsync(`${I18N}.recovery.offer-message`), 'primary', 'horizontal');
83
+ if (generateCodes.result) {
84
+ await this.generateAndShowRecoveryCodes({ password: enrollment.password });
85
+ }
86
+ return this.successWithStatusInsights(true);
87
+ }
88
+ /**
89
+ * Password re-auth + start enrollment in one dialog (same pattern as change-password).
90
+ * Returns enrollment payload plus the password for optional recovery generation.
91
+ */
92
+ async promptStartEnrollment() {
93
+ const result = await this.layoutBuilder
94
+ .create()
95
+ .dialog((dialog) => {
96
+ dialog
97
+ .setTitle(`${I18N}.enable.password-dialog.title`)
98
+ .setSize('sm')
99
+ .setCloseButton(true)
100
+ .setContext({ password: '' })
101
+ .content((layout) => {
102
+ layout.flex((flex) => {
103
+ flex
104
+ .setDirection('column')
105
+ .setGap('1rem')
106
+ .formField(`${I18N}.fields.password.title`, (field) => {
107
+ field.setOptions({
108
+ hint: `${I18N}.fields.password.hint`,
109
+ hintDisplayMode: 'note',
110
+ });
111
+ field.path('password');
112
+ field.passwordBox({
113
+ revealToggle: true,
114
+ placeholder: `${I18N}.fields.password.placeholder`,
115
+ validations: [{ rule: 'required' }],
116
+ });
117
+ });
118
+ });
119
+ })
120
+ .setActions((actions) => {
121
+ actions.cancel('@general:actions.cancel.title');
122
+ actions.submit(`${I18N}.actions.continue`);
123
+ })
124
+ .onAction(async (dialogRef) => {
125
+ if (dialogRef.action() === 'cancel') {
126
+ return null;
127
+ }
128
+ const form = dialogRef.context();
129
+ const password = String(form.password ?? '');
130
+ if (!password) {
131
+ throw new Error(`${I18N}.messages.incorrect-password`);
132
+ }
133
+ dialogRef.setLoading(true);
134
+ try {
135
+ const startResult = await this.commandService.execute(AXMSecurityManagementServerCommands.StartTwoFactorEnrollment, { password });
136
+ if (!startResult?.success) {
137
+ throw new Error(this.resolveServerErrorKey(startResult?.message?.code));
138
+ }
139
+ const enrollment = runtimeCommandPayloadData(startResult);
140
+ if (!enrollment?.enrollmentId || !enrollment.otpauthUri) {
141
+ throw new Error(`${I18N}.messages.save-failed`);
142
+ }
143
+ // Do not call dialogRef.close() here — the layout-builder closes after onAction returns.
144
+ // A second close throws ObjectUnsubscribedError and surfaces as "object unsubscribed".
145
+ return { ...enrollment, password };
146
+ }
147
+ catch (error) {
148
+ dialogRef.setLoading(false);
149
+ throw error;
150
+ }
151
+ });
152
+ })
153
+ .show();
154
+ return resolveLayoutBuilderDialogResult(result);
155
+ }
156
+ async promptConfirmEnrollment(enrollment) {
157
+ const result = await this.layoutBuilder
158
+ .create()
159
+ .dialog((dialog) => {
160
+ dialog
161
+ .setTitle(`${I18N}.enable.confirm-dialog.title`)
162
+ .setSize('md')
163
+ .setCloseButton(true)
164
+ .setContext({
165
+ otpauthUri: enrollment.otpauthUri,
166
+ // Authenticator apps expect Base32; spaced groups are easier to enter and widely accepted.
167
+ secretBase32: formatTotpManualSecret(enrollment.secretBase32),
168
+ code: '',
169
+ })
170
+ .content((layout) => {
171
+ layout.flex((flex) => {
172
+ flex
173
+ .setDirection('column')
174
+ .setGap('0.75rem')
175
+ .setAlignItems('center')
176
+ .customWidget('text-block-layout', {
177
+ content: `${I18N}.enable.confirm-dialog.instructions`,
178
+ })
179
+ .customWidget('qrcode', {
180
+ path: 'otpauthUri',
181
+ size: 160,
182
+ readonly: true,
183
+ showContent: false,
184
+ })
185
+ .formField(`${I18N}.enable.confirm-dialog.fields.manual-secret.title`, (field) => {
186
+ field.path('secretBase32');
187
+ field.readonly(true);
188
+ field.textBox({});
189
+ })
190
+ .formField(`${I18N}.enable.confirm-dialog.fields.code.title`, (field) => {
191
+ field.path('code');
192
+ field.textBox({
193
+ placeholder: `${I18N}.enable.confirm-dialog.fields.code.placeholder`,
194
+ validations: [{ rule: 'required' }],
195
+ });
196
+ });
197
+ });
198
+ })
199
+ .setActions((actions) => {
200
+ actions.cancel('@general:actions.cancel.title');
201
+ actions.submit(`${I18N}.enable.confirm-dialog.actions.confirm`);
202
+ })
203
+ .onAction(async (dialogRef) => {
204
+ if (dialogRef.action() === 'cancel') {
205
+ return null;
206
+ }
207
+ const form = dialogRef.context();
208
+ const code = String(form.code ?? '').trim();
209
+ if (!code) {
210
+ throw new Error(`${I18N}.messages.incorrect-code`);
211
+ }
212
+ dialogRef.setLoading(true);
213
+ try {
214
+ const confirmResult = await this.commandService.execute(AXMSecurityManagementServerCommands.ConfirmTwoFactorEnrollment, { enrollmentId: enrollment.enrollmentId, code });
215
+ if (!confirmResult?.success) {
216
+ throw new Error(this.resolveServerErrorKey(confirmResult?.message?.code));
217
+ }
218
+ const payload = runtimeCommandPayloadData(confirmResult);
219
+ if (!payload?.enabled) {
220
+ throw new Error(`${I18N}.messages.save-failed`);
221
+ }
222
+ return true;
223
+ }
224
+ catch (error) {
225
+ dialogRef.setLoading(false);
226
+ throw error;
227
+ }
228
+ });
229
+ })
230
+ .show();
231
+ return resolveLayoutBuilderDialogResult(result) === true;
232
+ }
233
+ //#endregion
234
+ //#region ----- Enabled management -----
235
+ async runEnabledFlow(status) {
236
+ const choice = await this.dialogService.show({
237
+ title: `${I18N}.manage.dialog.title`,
238
+ content: await this.translateService.translateAsync(`${I18N}.manage.dialog.description`, {
239
+ params: {
240
+ recoveryCount: status.unusedRecoveryCodeCount ?? 0,
241
+ },
242
+ }),
243
+ type: 'primary',
244
+ orientation: 'vertical',
245
+ buttons: [
246
+ {
247
+ name: 'regenerate',
248
+ text: `${I18N}.manage.actions.regenerate-recovery`,
249
+ color: 'primary',
250
+ autofocus: true,
251
+ },
252
+ {
253
+ name: 'disable',
254
+ text: `${I18N}.manage.actions.disable`,
255
+ color: 'danger',
256
+ },
257
+ {
258
+ name: 'cancel',
259
+ text: '@general:actions.cancel.title',
260
+ color: 'default',
261
+ },
262
+ ],
263
+ });
264
+ if (choice?.name === 'disable') {
265
+ const proof = await this.promptProof(`${I18N}.disable.dialog.title`);
266
+ if (!proof) {
267
+ return { success: false };
268
+ }
269
+ const disableResult = await this.commandService.execute(AXMSecurityManagementServerCommands.DisableTwoFactor, proof);
270
+ if (!disableResult?.success) {
271
+ await this.showErrorToast(this.resolveServerErrorKey(disableResult?.message?.code));
272
+ return { success: false };
273
+ }
274
+ // Success feedback comes from the realtime security alert (avoid duplicate toasts).
275
+ return this.successWithStatusInsights(false);
276
+ }
277
+ if (choice?.name === 'regenerate') {
278
+ const proof = await this.promptProof(`${I18N}.recovery.regenerate-dialog.title`);
279
+ if (!proof) {
280
+ return { success: false };
281
+ }
282
+ const shown = await this.generateAndShowRecoveryCodes(proof);
283
+ if (!shown) {
284
+ return { success: false };
285
+ }
286
+ return this.successWithStatusInsights(true);
287
+ }
288
+ return { success: false };
289
+ }
290
+ //#endregion
291
+ //#region ----- Shared dialogs -----
292
+ /** Yields so popup teardown can finish before opening another dialog. */
293
+ async waitForDialogTeardown() {
294
+ await new Promise((resolve) => setTimeout(resolve, 50));
295
+ }
296
+ async promptProof(titleKey) {
297
+ const result = await this.layoutBuilder
298
+ .create()
299
+ .dialog((dialog) => {
300
+ dialog
301
+ .setTitle(titleKey)
302
+ .setSize('sm')
303
+ .setCloseButton(true)
304
+ .setContext({ password: '', totpCode: '' })
305
+ .content((layout) => {
306
+ layout.flex((flex) => {
307
+ flex
308
+ .setDirection('column')
309
+ .setGap('1rem')
310
+ .customWidget('text-block-layout', {
311
+ content: `${I18N}.fields.proof.hint`,
312
+ })
313
+ .formField(`${I18N}.fields.password.title`, (field) => {
314
+ field.path('password');
315
+ field.passwordBox({
316
+ revealToggle: true,
317
+ placeholder: `${I18N}.fields.password.placeholder`,
318
+ });
319
+ })
320
+ .formField(`${I18N}.fields.totp-code.title`, (field) => {
321
+ field.path('totpCode');
322
+ field.textBox({
323
+ placeholder: `${I18N}.fields.totp-code.placeholder`,
324
+ });
325
+ });
326
+ });
327
+ })
328
+ .setActions((actions) => {
329
+ actions.cancel('@general:actions.cancel.title');
330
+ actions.submit(`${I18N}.actions.continue`);
331
+ })
332
+ .onAction(async (dialogRef) => {
333
+ if (dialogRef.action() === 'cancel') {
334
+ return null;
335
+ }
336
+ const form = dialogRef.context();
337
+ const password = String(form.password ?? '').trim();
338
+ const totpCode = String(form.totpCode ?? '').trim();
339
+ if (!password && !totpCode) {
340
+ throw new Error(`${I18N}.messages.proof-required`);
341
+ }
342
+ return {
343
+ ...(password ? { password } : {}),
344
+ ...(totpCode ? { totpCode } : {}),
345
+ };
346
+ });
347
+ })
348
+ .show();
349
+ return resolveLayoutBuilderDialogResult(result) ?? null;
350
+ }
351
+ async generateAndShowRecoveryCodes(proof) {
352
+ const generateResult = await this.commandService.execute(AXMSecurityManagementServerCommands.GenerateTwoFactorRecoveryCodes, proof);
353
+ if (!generateResult?.success) {
354
+ await this.showErrorToast(this.resolveServerErrorKey(generateResult?.message?.code));
355
+ return false;
356
+ }
357
+ const payload = runtimeCommandPayloadData(generateResult);
358
+ const codes = payload?.codes ?? [];
359
+ if (!codes.length) {
360
+ await this.showErrorToast(`${I18N}.messages.save-failed`);
361
+ return false;
362
+ }
363
+ const codesText = codes.join('\n');
364
+ await this.layoutBuilder
365
+ .create()
366
+ .dialog((dialog) => {
367
+ dialog
368
+ .setTitle(`${I18N}.recovery.codes-dialog.title`)
369
+ .setSize('md')
370
+ .setCloseButton(true)
371
+ .setContext({ codesText })
372
+ .content((layout) => {
373
+ layout.flex((flex) => {
374
+ flex
375
+ .setDirection('column')
376
+ .setGap('1rem')
377
+ .customWidget('text-block-layout', {
378
+ content: `${I18N}.recovery.codes-dialog.warning`,
379
+ })
380
+ .formField(`${I18N}.recovery.codes-dialog.fields.codes.title`, (field) => {
381
+ field.path('codesText');
382
+ field.readonly(true);
383
+ field.largeTextBox({
384
+ rows: Math.min(codes.length + 1, 12),
385
+ });
386
+ });
387
+ });
388
+ })
389
+ .setActions((actions) => {
390
+ actions.submit(`${I18N}.recovery.codes-dialog.actions.done`);
391
+ })
392
+ .onAction(async () => null);
393
+ })
394
+ .show();
395
+ return true;
396
+ }
397
+ //#endregion
398
+ //#region ----- Status & messaging -----
399
+ async loadStatus() {
400
+ const result = await this.commandService.execute(AXMSecurityManagementServerCommands.GetTwoFactorStatus, {});
401
+ if (!result?.success) {
402
+ await this.showErrorToast(this.resolveServerErrorKey(result?.message?.code));
403
+ return null;
404
+ }
405
+ return runtimeCommandPayloadData(result) ?? {
406
+ enabled: false,
407
+ enrolled: false,
408
+ hasRecoveryCodes: false,
409
+ unusedRecoveryCodeCount: 0,
410
+ };
411
+ }
412
+ successWithStatusInsights(enabled) {
413
+ return {
414
+ success: true,
415
+ kind: 'object',
416
+ data: undefined,
417
+ metadata: {
418
+ refresh: false,
419
+ [PROFILE_SECTION_INSIGHTS_PATCH_METADATA_KEY]: {
420
+ sectionId: TWO_FACTOR_SECTION_ID,
421
+ insights: buildTwoFactorStatusInsights(enabled),
422
+ },
423
+ },
424
+ };
425
+ }
426
+ resolveServerErrorKey(code) {
427
+ if (code && TWO_FACTOR_ERROR_I18N[code]) {
428
+ return TWO_FACTOR_ERROR_I18N[code];
429
+ }
430
+ return `${I18N}.messages.save-failed`;
431
+ }
432
+ async showErrorToast(key) {
433
+ const content = await this.translateService.translateAsync(key);
434
+ this.toastService.show({ color: 'danger', content, timeOut: 4000 });
435
+ }
436
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPManageTwoFactorCommand, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
437
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPManageTwoFactorCommand, providedIn: 'root' }); }
438
+ }
439
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPManageTwoFactorCommand, decorators: [{
440
+ type: Injectable,
441
+ args: [{ providedIn: 'root' }]
442
+ }] });
443
+
444
+ export { AXPManageTwoFactorCommand };
445
+ //# sourceMappingURL=acorex-platform-module-auth-client-manage-two-factor.command-BAg2W20W.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acorex-platform-module-auth-client-manage-two-factor.command-BAg2W20W.mjs","sources":["../../../../libs/modules/auth/client/src/lib/commands/manage-two-factor.command.ts"],"sourcesContent":["import { AXDialogService } from '@acorex/components/dialog';\nimport { AXToastService } from '@acorex/components/toast';\nimport { AXTranslationService } from '@acorex/core/translation';\nimport { AXPSessionService } from '@acorex-platform/framework-client/auth';\nimport {\n AXPLayoutBuilderService,\n resolveLayoutBuilderDialogResult,\n} from '@acorex-platform/framework-client/layout/builder';\nimport { AXPCommandService } from '@acorex-platform/framework-client/runtime';\nimport { AXPRuntimeCommandResult, runtimeCommandPayloadData } from '@acorex-platform/framework-shared/core';\nimport { AXPCommand, type AXPCommandExecuteResultPromise } from '@acorex-platform/framework-shared/runtime';\nimport {\n AXM_TWO_FACTOR_ERROR_CODES,\n AXMSecurityManagementServerCommands,\n type AXMConfirmTwoFactorEnrollmentResult,\n type AXMGenerateTwoFactorRecoveryCodesResult,\n type AXMGetTwoFactorStatusResult,\n type AXMStartTwoFactorEnrollmentResult,\n} from '@acorex-platform/module-security-management-client/contracts';\nimport { inject, Injectable } from '@angular/core';\n\nimport {\n PROFILE_SECTION_INSIGHTS_PATCH_METADATA_KEY,\n} from '../pages/account/profile-page/profile-password-insight.util';\nimport {\n TWO_FACTOR_SECTION_ID,\n buildTwoFactorStatusInsights,\n} from '../pages/account/profile-page/profile-two-factor-insight.util';\n\n//#region ----- Constants -----\n\nconst I18N = '@auth:profile-page.commands.manage-two-factor';\n\nconst TWO_FACTOR_ERROR_I18N: Record<string, string> = {\n [AXM_TWO_FACTOR_ERROR_CODES.NotSignedIn]: `${I18N}.messages.not-signed-in`,\n [AXM_TWO_FACTOR_ERROR_CODES.InvalidInput]: `${I18N}.messages.invalid-input`,\n [AXM_TWO_FACTOR_ERROR_CODES.IncorrectPassword]: `${I18N}.messages.incorrect-password`,\n [AXM_TWO_FACTOR_ERROR_CODES.IncorrectCode]: `${I18N}.messages.incorrect-code`,\n [AXM_TWO_FACTOR_ERROR_CODES.AlreadyEnabled]: `${I18N}.messages.already-enabled`,\n [AXM_TWO_FACTOR_ERROR_CODES.NotEnabled]: `${I18N}.messages.not-enabled`,\n [AXM_TWO_FACTOR_ERROR_CODES.EnrollmentExpired]: `${I18N}.messages.enrollment-expired`,\n [AXM_TWO_FACTOR_ERROR_CODES.RateLimited]: `${I18N}.messages.rate-limited`,\n [AXM_TWO_FACTOR_ERROR_CODES.InvalidConfiguration]: `${I18N}.messages.invalid-configuration`,\n [AXM_TWO_FACTOR_ERROR_CODES.ProofRequired]: `${I18N}.messages.proof-required`,\n};\n\n//#endregion\n\n//#region ----- Types -----\n\ntype TwoFactorProofForm = {\n password?: string;\n totpCode?: string;\n};\n\n//#endregion\n\n//#region ----- Helpers -----\n\n/** Groups Base32 secret in fours for Authenticator manual-entry UX (apps ignore spaces). */\nfunction formatTotpManualSecret(secretBase32: string): string {\n const cleaned = String(secretBase32 ?? '')\n .replace(/\\s+/g, '')\n .toUpperCase();\n return cleaned.replace(/(.{4})(?=.)/g, '$1 ');\n}\n\n//#endregion\n\n//#region ----- Manage two-factor command -----\n\n/** Opens profile dialogs to enroll, disable, or regenerate recovery codes for 2FA. */\n@Injectable({ providedIn: 'root' })\nexport class AXPManageTwoFactorCommand implements AXPCommand {\n //#region ----- Services & Dependencies -----\n\n private readonly layoutBuilder = inject(AXPLayoutBuilderService);\n private readonly commandService = inject(AXPCommandService);\n private readonly sessionService = inject(AXPSessionService);\n private readonly dialogService = inject(AXDialogService);\n private readonly toastService = inject(AXToastService);\n private readonly translateService = inject(AXTranslationService);\n\n //#endregion\n\n //#region ----- Command -----\n\n async execute(): AXPCommandExecuteResultPromise<void> {\n if (!this.sessionService.user?.id) {\n await this.showErrorToast(`${I18N}.messages.not-signed-in`);\n return { success: false };\n }\n\n const status = await this.loadStatus();\n if (!status) {\n return { success: false };\n }\n\n // Prefer manage/disable whenever enrollment exists (even if setting briefly drifted).\n if (status.enabled || status.enrolled) {\n return this.runEnabledFlow(status);\n }\n\n return this.runEnrollmentFlow();\n }\n\n //#endregion\n\n //#region ----- Enrollment -----\n\n private async runEnrollmentFlow(): AXPCommandExecuteResultPromise<void> {\n const enrollment = await this.promptStartEnrollment();\n if (!enrollment) {\n return { success: false };\n }\n\n // Let the password dialog finish teardown before opening the QR dialog\n // (avoids RxJS ObjectUnsubscribedError on overlapping popup subjects).\n await this.waitForDialogTeardown();\n\n const confirmed = await this.promptConfirmEnrollment(enrollment);\n if (!confirmed) {\n return { success: false };\n }\n\n // Success feedback comes from the realtime security alert (avoid duplicate toasts).\n\n await this.waitForDialogTeardown();\n\n const generateCodes = await this.dialogService.confirm(\n await this.translateService.translateAsync(`${I18N}.recovery.offer-title`),\n await this.translateService.translateAsync(`${I18N}.recovery.offer-message`),\n 'primary',\n 'horizontal',\n );\n\n if (generateCodes.result) {\n await this.generateAndShowRecoveryCodes({ password: enrollment.password });\n }\n\n return this.successWithStatusInsights(true);\n }\n\n /**\n * Password re-auth + start enrollment in one dialog (same pattern as change-password).\n * Returns enrollment payload plus the password for optional recovery generation.\n */\n private async promptStartEnrollment(): Promise<\n (AXMStartTwoFactorEnrollmentResult & { password: string }) | null\n > {\n const result = await this.layoutBuilder\n .create()\n .dialog<(AXMStartTwoFactorEnrollmentResult & { password: string }) | null>((dialog) => {\n dialog\n .setTitle(`${I18N}.enable.password-dialog.title`)\n .setSize('sm')\n .setCloseButton(true)\n .setContext({ password: '' })\n .content((layout) => {\n layout.flex((flex) => {\n flex\n .setDirection('column')\n .setGap('1rem')\n .formField(`${I18N}.fields.password.title`, (field) => {\n field.setOptions({\n hint: `${I18N}.fields.password.hint`,\n hintDisplayMode: 'note',\n });\n field.path('password');\n field.passwordBox({\n revealToggle: true,\n placeholder: `${I18N}.fields.password.placeholder`,\n validations: [{ rule: 'required' }],\n });\n });\n });\n })\n .setActions((actions) => {\n actions.cancel('@general:actions.cancel.title');\n actions.submit(`${I18N}.actions.continue`);\n })\n .onAction(async (dialogRef) => {\n if (dialogRef.action() === 'cancel') {\n return null;\n }\n\n const form = dialogRef.context() as { password?: string };\n const password = String(form.password ?? '');\n if (!password) {\n throw new Error(`${I18N}.messages.incorrect-password`);\n }\n\n dialogRef.setLoading(true);\n try {\n const startResult = await this.commandService.execute(\n AXMSecurityManagementServerCommands.StartTwoFactorEnrollment,\n { password },\n );\n if (!startResult?.success) {\n throw new Error(this.resolveServerErrorKey(startResult?.message?.code));\n }\n\n const enrollment = runtimeCommandPayloadData(startResult) as\n | AXMStartTwoFactorEnrollmentResult\n | undefined;\n if (!enrollment?.enrollmentId || !enrollment.otpauthUri) {\n throw new Error(`${I18N}.messages.save-failed`);\n }\n\n // Do not call dialogRef.close() here — the layout-builder closes after onAction returns.\n // A second close throws ObjectUnsubscribedError and surfaces as \"object unsubscribed\".\n return { ...enrollment, password };\n } catch (error) {\n dialogRef.setLoading(false);\n throw error;\n }\n });\n })\n .show();\n\n return resolveLayoutBuilderDialogResult<AXMStartTwoFactorEnrollmentResult & { password: string }>(\n result,\n );\n }\n\n private async promptConfirmEnrollment(\n enrollment: AXMStartTwoFactorEnrollmentResult,\n ): Promise<boolean> {\n const result = await this.layoutBuilder\n .create()\n .dialog<boolean | null>((dialog) => {\n dialog\n .setTitle(`${I18N}.enable.confirm-dialog.title`)\n .setSize('md')\n .setCloseButton(true)\n .setContext({\n otpauthUri: enrollment.otpauthUri,\n // Authenticator apps expect Base32; spaced groups are easier to enter and widely accepted.\n secretBase32: formatTotpManualSecret(enrollment.secretBase32),\n code: '',\n })\n .content((layout) => {\n layout.flex((flex) => {\n flex\n .setDirection('column')\n .setGap('0.75rem')\n .setAlignItems('center')\n .customWidget('text-block-layout', {\n content: `${I18N}.enable.confirm-dialog.instructions`,\n })\n .customWidget('qrcode', {\n path: 'otpauthUri',\n size: 160,\n readonly: true,\n showContent: false,\n })\n .formField(`${I18N}.enable.confirm-dialog.fields.manual-secret.title`, (field) => {\n field.path('secretBase32');\n field.readonly(true);\n field.textBox({});\n })\n .formField(`${I18N}.enable.confirm-dialog.fields.code.title`, (field) => {\n field.path('code');\n field.textBox({\n placeholder: `${I18N}.enable.confirm-dialog.fields.code.placeholder`,\n validations: [{ rule: 'required' }],\n });\n });\n });\n })\n .setActions((actions) => {\n actions.cancel('@general:actions.cancel.title');\n actions.submit(`${I18N}.enable.confirm-dialog.actions.confirm`);\n })\n .onAction(async (dialogRef) => {\n if (dialogRef.action() === 'cancel') {\n return null;\n }\n\n const form = dialogRef.context() as { code?: string };\n const code = String(form.code ?? '').trim();\n if (!code) {\n throw new Error(`${I18N}.messages.incorrect-code`);\n }\n\n dialogRef.setLoading(true);\n try {\n const confirmResult = await this.commandService.execute(\n AXMSecurityManagementServerCommands.ConfirmTwoFactorEnrollment,\n { enrollmentId: enrollment.enrollmentId, code },\n );\n if (!confirmResult?.success) {\n throw new Error(this.resolveServerErrorKey(confirmResult?.message?.code));\n }\n\n const payload = runtimeCommandPayloadData(confirmResult) as\n | AXMConfirmTwoFactorEnrollmentResult\n | undefined;\n if (!payload?.enabled) {\n throw new Error(`${I18N}.messages.save-failed`);\n }\n\n return true;\n } catch (error) {\n dialogRef.setLoading(false);\n throw error;\n }\n });\n })\n .show();\n\n return resolveLayoutBuilderDialogResult<boolean>(result) === true;\n }\n\n //#endregion\n\n //#region ----- Enabled management -----\n\n private async runEnabledFlow(\n status: AXMGetTwoFactorStatusResult,\n ): AXPCommandExecuteResultPromise<void> {\n const choice = await this.dialogService.show({\n title: `${I18N}.manage.dialog.title`,\n content: await this.translateService.translateAsync(`${I18N}.manage.dialog.description`, {\n params: {\n recoveryCount: status.unusedRecoveryCodeCount ?? 0,\n },\n }),\n type: 'primary',\n orientation: 'vertical',\n buttons: [\n {\n name: 'regenerate',\n text: `${I18N}.manage.actions.regenerate-recovery`,\n color: 'primary',\n autofocus: true,\n },\n {\n name: 'disable',\n text: `${I18N}.manage.actions.disable`,\n color: 'danger',\n },\n {\n name: 'cancel',\n text: '@general:actions.cancel.title',\n color: 'default',\n },\n ],\n });\n\n if (choice?.name === 'disable') {\n const proof = await this.promptProof(`${I18N}.disable.dialog.title`);\n if (!proof) {\n return { success: false };\n }\n\n const disableResult = await this.commandService.execute(\n AXMSecurityManagementServerCommands.DisableTwoFactor,\n proof,\n );\n if (!disableResult?.success) {\n await this.showErrorToast(this.resolveServerErrorKey(disableResult?.message?.code));\n return { success: false };\n }\n\n // Success feedback comes from the realtime security alert (avoid duplicate toasts).\n return this.successWithStatusInsights(false);\n }\n\n if (choice?.name === 'regenerate') {\n const proof = await this.promptProof(`${I18N}.recovery.regenerate-dialog.title`);\n if (!proof) {\n return { success: false };\n }\n\n const shown = await this.generateAndShowRecoveryCodes(proof);\n if (!shown) {\n return { success: false };\n }\n\n return this.successWithStatusInsights(true);\n }\n\n return { success: false };\n }\n\n //#endregion\n\n //#region ----- Shared dialogs -----\n\n /** Yields so popup teardown can finish before opening another dialog. */\n private async waitForDialogTeardown(): Promise<void> {\n await new Promise<void>((resolve) => setTimeout(resolve, 50));\n }\n\n private async promptProof(titleKey: string): Promise<TwoFactorProofForm | null> {\n const result = await this.layoutBuilder\n .create()\n .dialog<TwoFactorProofForm | null>((dialog) => {\n dialog\n .setTitle(titleKey)\n .setSize('sm')\n .setCloseButton(true)\n .setContext({ password: '', totpCode: '' })\n .content((layout) => {\n layout.flex((flex) => {\n flex\n .setDirection('column')\n .setGap('1rem')\n .customWidget('text-block-layout', {\n content: `${I18N}.fields.proof.hint`,\n })\n .formField(`${I18N}.fields.password.title`, (field) => {\n field.path('password');\n field.passwordBox({\n revealToggle: true,\n placeholder: `${I18N}.fields.password.placeholder`,\n });\n })\n .formField(`${I18N}.fields.totp-code.title`, (field) => {\n field.path('totpCode');\n field.textBox({\n placeholder: `${I18N}.fields.totp-code.placeholder`,\n });\n });\n });\n })\n .setActions((actions) => {\n actions.cancel('@general:actions.cancel.title');\n actions.submit(`${I18N}.actions.continue`);\n })\n .onAction(async (dialogRef) => {\n if (dialogRef.action() === 'cancel') {\n return null;\n }\n\n const form = dialogRef.context() as TwoFactorProofForm;\n const password = String(form.password ?? '').trim();\n const totpCode = String(form.totpCode ?? '').trim();\n if (!password && !totpCode) {\n throw new Error(`${I18N}.messages.proof-required`);\n }\n\n return {\n ...(password ? { password } : {}),\n ...(totpCode ? { totpCode } : {}),\n };\n });\n })\n .show();\n\n return resolveLayoutBuilderDialogResult<TwoFactorProofForm>(result) ?? null;\n }\n\n private async generateAndShowRecoveryCodes(proof: TwoFactorProofForm): Promise<boolean> {\n const generateResult = await this.commandService.execute(\n AXMSecurityManagementServerCommands.GenerateTwoFactorRecoveryCodes,\n proof,\n );\n if (!generateResult?.success) {\n await this.showErrorToast(this.resolveServerErrorKey(generateResult?.message?.code));\n return false;\n }\n\n const payload = runtimeCommandPayloadData(generateResult) as\n | AXMGenerateTwoFactorRecoveryCodesResult\n | undefined;\n const codes = payload?.codes ?? [];\n if (!codes.length) {\n await this.showErrorToast(`${I18N}.messages.save-failed`);\n return false;\n }\n\n const codesText = codes.join('\\n');\n await this.layoutBuilder\n .create()\n .dialog<null>((dialog) => {\n dialog\n .setTitle(`${I18N}.recovery.codes-dialog.title`)\n .setSize('md')\n .setCloseButton(true)\n .setContext({ codesText })\n .content((layout) => {\n layout.flex((flex) => {\n flex\n .setDirection('column')\n .setGap('1rem')\n .customWidget('text-block-layout', {\n content: `${I18N}.recovery.codes-dialog.warning`,\n })\n .formField(`${I18N}.recovery.codes-dialog.fields.codes.title`, (field) => {\n field.path('codesText');\n field.readonly(true);\n field.largeTextBox({\n rows: Math.min(codes.length + 1, 12),\n });\n });\n });\n })\n .setActions((actions) => {\n actions.submit(`${I18N}.recovery.codes-dialog.actions.done`);\n })\n .onAction(async () => null);\n })\n .show();\n\n return true;\n }\n\n //#endregion\n\n //#region ----- Status & messaging -----\n\n private async loadStatus(): Promise<AXMGetTwoFactorStatusResult | null> {\n const result = await this.commandService.execute(\n AXMSecurityManagementServerCommands.GetTwoFactorStatus,\n {},\n );\n if (!result?.success) {\n await this.showErrorToast(this.resolveServerErrorKey(result?.message?.code));\n return null;\n }\n\n return (runtimeCommandPayloadData(result) as AXMGetTwoFactorStatusResult | undefined) ?? {\n enabled: false,\n enrolled: false,\n hasRecoveryCodes: false,\n unusedRecoveryCodeCount: 0,\n };\n }\n\n private successWithStatusInsights(enabled: boolean): AXPRuntimeCommandResult<void> {\n return {\n success: true,\n kind: 'object',\n data: undefined,\n metadata: {\n refresh: false,\n [PROFILE_SECTION_INSIGHTS_PATCH_METADATA_KEY]: {\n sectionId: TWO_FACTOR_SECTION_ID,\n insights: buildTwoFactorStatusInsights(enabled),\n },\n },\n };\n }\n\n private resolveServerErrorKey(code: string | undefined): string {\n if (code && TWO_FACTOR_ERROR_I18N[code]) {\n return TWO_FACTOR_ERROR_I18N[code];\n }\n\n return `${I18N}.messages.save-failed`;\n }\n\n private async showErrorToast(key: string): Promise<void> {\n const content = await this.translateService.translateAsync(key);\n this.toastService.show({ color: 'danger', content, timeOut: 4000 });\n }\n\n //#endregion\n}\n\n//#endregion\n"],"names":[],"mappings":"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"}
@@ -1,14 +1,14 @@
1
1
  import * as i5 from '@acorex/core/translation';
2
2
  import { AXTranslationModule } from '@acorex/core/translation';
3
3
  import { AXPPlatformBrandingService } from '@acorex-platform/framework-client/common';
4
- import * as i1$1 from '@acorex-platform/framework-client/core';
4
+ import * as i1 from '@acorex-platform/framework-client/core';
5
5
  import { AXPLogoComponent, AXPComponentSlotModule, AXPContextStore } from '@acorex-platform/framework-client/core';
6
6
  import { AsyncPipe } from '@angular/common';
7
7
  import * as i0 from '@angular/core';
8
8
  import { inject, signal, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
9
- import * as i1 from '@angular/router';
9
+ import * as i6 from '@angular/router';
10
10
  import { RouterModule } from '@angular/router';
11
- import { t as AXMAuthPlatformSettingsService } from './acorex-platform-module-auth-client-acorex-platform-module-auth-client-CRl74b8g.mjs';
11
+ import { w as AXMAuthPlatformSettingsService } from './acorex-platform-module-auth-client-acorex-platform-module-auth-client-C1oSPf12.mjs';
12
12
 
13
13
  //#region ----- Auth master layout -----
14
14
  class AXPAuthMasterLayoutComponent {
@@ -28,7 +28,7 @@ class AXPAuthMasterLayoutComponent {
28
28
  void this.platformBranding.resolvePlatformTitle().then((title) => this.platformTitle.set(title));
29
29
  }
30
30
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPAuthMasterLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
31
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.8", type: AXPAuthMasterLayoutComponent, isStandalone: true, selector: "ng-component", providers: [AXPContextStore], ngImport: i0, template: "<div class=\"w-full h-full flex overflow-hidden\">\n <div\n class=\"axp-auth-master__form-pane flex-1 min-h-0 lightest-surface dark:darker-surface overflow-y-auto px-6 sm:px-8 md:px-10 lg:px-0\"\n >\n <!-- ----- Stack: logo + form vertically centered; footer pinned below ----- -->\n <div\n class=\"axp-auth-master__stack w-full min-h-full flex flex-col items-center\"\n >\n <div\n class=\"axp-auth-master__main w-full grow flex flex-col items-center justify-center gap-5 pt-6 pb-4 sm:pt-8 lg:pt-0 lg:gap-0\"\n >\n <!-- ----- Platform branding on viewports without the side panel ----- -->\n <div class=\"axp-auth-master__brand lg:hidden shrink-0 w-full flex justify-center\">\n <axp-logo\n logoKey=\"platform\"\n appearance=\"onLight\"\n format=\"full\"\n [size]=\"240\"\n [attr.alt]=\"platformTitle()\"\n class=\"axp-auth-master__logo\"\n ></axp-logo>\n </div>\n <div class=\"axp-auth-master__form-body w-full flex flex-col items-center\">\n <router-outlet></router-outlet>\n </div>\n </div>\n <div class=\"flex justify-between shrink-0 pt-2 pb-1\">\n <div class=\"auth-footer-links\">\n <axp-component-slot name=\"auth-footer-links\"></axp-component-slot>\n </div>\n </div>\n </div>\n </div>\n <div class=\"hidden lg:flex bg-primary-500 flex-1 axp-auth-bk text-white\">\n <div class=\"flex w-full flex-col justify-between px-48 py-20 text-center \">\n <div>\n <axp-logo\n logoKey=\"platform\"\n appearance=\"onDark\"\n format=\"full\"\n [size]=\"280\"\n [attr.alt]=\"platformTitle()\"\n class=\"w-[280px] max-w-full mx-auto\"\n ></axp-logo>\n </div>\n <div>\n <p class=\"font-black text-4xl mb-4\">{{ slogan | translate | async }}</p>\n <p>{{ description | translate | async }}</p>\n </div>\n </div>\n </div>\n</div>\n", styles: ["@layer properties;.axp-auth-master__form-pane{-webkit-overflow-scrolling:touch;padding-top:max(1.75rem,calc(env(safe-area-inset-top,0px) + 1.25rem));padding-bottom:max(1.5rem,env(safe-area-inset-bottom,0px))}@media(min-width:1024px){.axp-auth-master__form-pane{padding-top:3rem;padding-bottom:3rem}}.axp-auth-master__brand{padding-top:.5rem;margin-bottom:.25rem}.axp-auth-master__logo{width:min(15rem,85vw);max-width:100%}@media(min-width:640px){.axp-auth-master__logo{width:min(16.25rem,90vw)}}.axp-auth-master__form-body>*:not(router-outlet){display:block;width:100%}.auth-footer-links{gap:calc(var(--spacing, .25rem) * 5);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}.auth-footer-links a{background-color:transparent;color:var(--ax-comp-ink, var(--ax-comp-bg, var(--color-on-surface)))}.auth-footer-links a.ax-state-selected{color:var(--ax-comp-ink-darker, var(--ax-comp-bg-darker, var(--color-on-surface)))}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1.RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "component", type: AXPLogoComponent, selector: "axp-logo", inputs: ["logoKey", "appearance", "size", "format"] }, { kind: "ngmodule", type: AXPComponentSlotModule }, { kind: "directive", type: i1$1.AXPComponentSlotDirective, selector: "axp-component-slot", inputs: ["name", "host", "context"], exportAs: ["slot"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.Eager, encapsulation: i0.ViewEncapsulation.None }); }
31
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.8", type: AXPAuthMasterLayoutComponent, isStandalone: true, selector: "ng-component", providers: [AXPContextStore], ngImport: i0, template: "<div class=\"w-full h-full flex overflow-hidden\">\n <div\n class=\"axp-auth-master__form-pane flex-1 min-h-0 lightest-surface dark:darker-surface overflow-y-auto px-6 sm:px-8 md:px-10 lg:px-0\"\n >\n <!-- ----- Stack: logo + form vertically centered; footer pinned below ----- -->\n <div\n class=\"axp-auth-master__stack w-full min-h-full flex flex-col items-center\"\n >\n <div\n class=\"axp-auth-master__main w-full grow flex flex-col items-center justify-center gap-5 pt-6 pb-4 sm:pt-8 lg:pt-0 lg:gap-0\"\n >\n <!-- ----- Platform branding on viewports without the side panel ----- -->\n <div class=\"axp-auth-master__brand lg:hidden shrink-0 w-full flex justify-center\">\n <axp-logo\n logoKey=\"platform\"\n appearance=\"onLight\"\n format=\"full\"\n [size]=\"240\"\n [attr.alt]=\"platformTitle()\"\n class=\"axp-auth-master__logo\"\n ></axp-logo>\n </div>\n <div class=\"axp-auth-master__form-body w-full flex flex-col items-center\">\n <router-outlet></router-outlet>\n </div>\n </div>\n <div class=\"flex justify-between shrink-0 pt-2 pb-1\">\n <div class=\"auth-footer-links\">\n <axp-component-slot name=\"auth-footer-links\"></axp-component-slot>\n </div>\n </div>\n </div>\n </div>\n <div class=\"hidden lg:flex bg-primary-500 flex-1 axp-auth-bk text-white\">\n <div class=\"flex w-full flex-col justify-between px-48 py-20 text-center \">\n <div>\n <axp-logo\n logoKey=\"platform\"\n appearance=\"onDark\"\n format=\"full\"\n [size]=\"280\"\n [attr.alt]=\"platformTitle()\"\n class=\"w-[280px] max-w-full mx-auto\"\n ></axp-logo>\n </div>\n <div>\n <p class=\"font-black text-4xl mb-4\">{{ slogan | translate | async }}</p>\n <p>{{ description | translate | async }}</p>\n </div>\n </div>\n </div>\n</div>\n", styles: ["@layer properties;.axp-auth-master__form-pane{-webkit-overflow-scrolling:touch;padding-top:max(1.75rem,calc(env(safe-area-inset-top,0px) + 1.25rem));padding-bottom:max(1.5rem,env(safe-area-inset-bottom,0px))}@media(min-width:1024px){.axp-auth-master__form-pane{padding-top:3rem;padding-bottom:3rem}}.axp-auth-master__brand{padding-top:.5rem;margin-bottom:.25rem}.axp-auth-master__logo{width:min(15rem,85vw);max-width:100%}@media(min-width:640px){.axp-auth-master__logo{width:min(16.25rem,90vw)}}.axp-auth-master__form-body>*:not(router-outlet){display:block;width:100%}.auth-footer-links{gap:calc(var(--spacing, .25rem) * 5);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}.auth-footer-links a{background-color:transparent;color:var(--ax-comp-ink, var(--ax-comp-bg, var(--color-on-surface)))}.auth-footer-links a.ax-state-selected{color:var(--ax-comp-ink-darker, var(--ax-comp-bg-darker, var(--color-on-surface)))}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i6.RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "component", type: AXPLogoComponent, selector: "axp-logo", inputs: ["logoKey", "appearance", "size", "format"] }, { kind: "ngmodule", type: AXPComponentSlotModule }, { kind: "directive", type: i1.AXPComponentSlotDirective, selector: "axp-component-slot", inputs: ["name", "host", "context"], exportAs: ["slot"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.Eager, encapsulation: i0.ViewEncapsulation.None }); }
32
32
  }
33
33
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPAuthMasterLayoutComponent, decorators: [{
34
34
  type: Component,
@@ -36,4 +36,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
36
36
  }], ctorParameters: () => [] });
37
37
 
38
38
  export { AXPAuthMasterLayoutComponent };
39
- //# sourceMappingURL=acorex-platform-module-auth-client-master.layout-D7zUm7aL.mjs.map
39
+ //# sourceMappingURL=acorex-platform-module-auth-client-master.layout-B3krDskY.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"acorex-platform-module-auth-client-master.layout-D7zUm7aL.mjs","sources":["../../../../libs/modules/auth/client/src/lib/shared/layouts/master/master.layout.ts","../../../../libs/modules/auth/client/src/lib/shared/layouts/master/master.layout.html"],"sourcesContent":["import { AXTranslationModule } from '@acorex/core/translation';\nimport { AXPPlatformBrandingService } from '@acorex-platform/framework-client/common';\nimport { AXPComponentSlotModule, AXPContextStore, AXPLogoComponent } from '@acorex-platform/framework-client/core';\nimport { AsyncPipe } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, ViewEncapsulation, inject, signal } from '@angular/core';\nimport { RouterModule } from '@angular/router';\nimport { AXMAuthPlatformSettingsService } from '../../../auth-platform-settings.service';\n\n//#region ----- Auth master layout -----\n\n@Component({\n templateUrl: 'master.layout.html',\n styleUrls: ['master.layout.css'],\n imports: [RouterModule, AXPLogoComponent, AXPComponentSlotModule, AXTranslationModule, AsyncPipe],\n providers: [AXPContextStore],\n changeDetection: ChangeDetectionStrategy.Eager,\n encapsulation: ViewEncapsulation.None,\n})\nexport class AXPAuthMasterLayoutComponent {\n //#region ----- Services & Dependencies -----\n\n private readonly authPlatformSettings = inject(AXMAuthPlatformSettingsService);\n private readonly platformBranding = inject(AXPPlatformBrandingService);\n\n protected readonly platformTitle = signal('');\n\n //#endregion\n\n //#region ----- Lifecycle -----\n\n constructor() {\n void this.platformBranding.resolvePlatformTitle().then((title) => this.platformTitle.set(title));\n }\n\n //#endregion\n\n //#region ----- Computed Properties -----\n\n /** Plain string or MLS map — rendered via translate pipe. */\n protected readonly slogan = this.authPlatformSettings.slogan();\n protected readonly description = this.authPlatformSettings.description();\n\n //#endregion\n}\n\n//#endregion\n","<div class=\"w-full h-full flex overflow-hidden\">\n <div\n class=\"axp-auth-master__form-pane flex-1 min-h-0 lightest-surface dark:darker-surface overflow-y-auto px-6 sm:px-8 md:px-10 lg:px-0\"\n >\n <!-- ----- Stack: logo + form vertically centered; footer pinned below ----- -->\n <div\n class=\"axp-auth-master__stack w-full min-h-full flex flex-col items-center\"\n >\n <div\n class=\"axp-auth-master__main w-full grow flex flex-col items-center justify-center gap-5 pt-6 pb-4 sm:pt-8 lg:pt-0 lg:gap-0\"\n >\n <!-- ----- Platform branding on viewports without the side panel ----- -->\n <div class=\"axp-auth-master__brand lg:hidden shrink-0 w-full flex justify-center\">\n <axp-logo\n logoKey=\"platform\"\n appearance=\"onLight\"\n format=\"full\"\n [size]=\"240\"\n [attr.alt]=\"platformTitle()\"\n class=\"axp-auth-master__logo\"\n ></axp-logo>\n </div>\n <div class=\"axp-auth-master__form-body w-full flex flex-col items-center\">\n <router-outlet></router-outlet>\n </div>\n </div>\n <div class=\"flex justify-between shrink-0 pt-2 pb-1\">\n <div class=\"auth-footer-links\">\n <axp-component-slot name=\"auth-footer-links\"></axp-component-slot>\n </div>\n </div>\n </div>\n </div>\n <div class=\"hidden lg:flex bg-primary-500 flex-1 axp-auth-bk text-white\">\n <div class=\"flex w-full flex-col justify-between px-48 py-20 text-center \">\n <div>\n <axp-logo\n logoKey=\"platform\"\n appearance=\"onDark\"\n format=\"full\"\n [size]=\"280\"\n [attr.alt]=\"platformTitle()\"\n class=\"w-[280px] max-w-full mx-auto\"\n ></axp-logo>\n </div>\n <div>\n <p class=\"font-black text-4xl mb-4\">{{ slogan | translate | async }}</p>\n <p>{{ description | translate | async }}</p>\n </div>\n </div>\n </div>\n</div>\n"],"names":["i2"],"mappings":";;;;;;;;;;;;AAQA;MAUa,4BAA4B,CAAA;;;AAYvC,IAAA,WAAA,GAAA;;AATiB,QAAA,IAAA,CAAA,oBAAoB,GAAG,MAAM,CAAC,8BAA8B,CAAC;AAC7D,QAAA,IAAA,CAAA,gBAAgB,GAAG,MAAM,CAAC,0BAA0B,CAAC;QAEnD,IAAA,CAAA,aAAa,GAAG,MAAM,CAAC,EAAE;0FAAC;;;;AAe1B,QAAA,IAAA,CAAA,MAAM,GAAG,IAAI,CAAC,oBAAoB,CAAC,MAAM,EAAE;AAC3C,QAAA,IAAA,CAAA,WAAW,GAAG,IAAI,CAAC,oBAAoB,CAAC,WAAW,EAAE;QATtE,KAAK,IAAI,CAAC,gBAAgB,CAAC,oBAAoB,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAClG;8GAdW,4BAA4B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAA5B,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,4BAA4B,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,cAAA,EAAA,SAAA,EAJ5B,CAAC,eAAe,CAAC,0BCd9B,u/DAoDA,EAAA,MAAA,EAAA,CAAA,m4CAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EDvCY,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,YAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,kBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,QAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,gBAAgB,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,YAAA,EAAA,MAAA,EAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAE,sBAAsB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,yBAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,MAAA,EAAA,SAAA,CAAA,EAAA,QAAA,EAAA,CAAA,MAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAE,mBAAmB,0FAAE,SAAS,EAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,KAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA,CAAA;;2FAKrF,4BAA4B,EAAA,UAAA,EAAA,CAAA;kBARxC,SAAS;8BAGC,CAAC,YAAY,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,SAAS,CAAC,aACtF,CAAC,eAAe,CAAC,EAAA,eAAA,EACX,uBAAuB,CAAC,KAAK,EAAA,aAAA,EAC/B,iBAAiB,CAAC,IAAI,EAAA,QAAA,EAAA,u/DAAA,EAAA,MAAA,EAAA,CAAA,m4CAAA,CAAA,EAAA;;;"}
1
+ {"version":3,"file":"acorex-platform-module-auth-client-master.layout-B3krDskY.mjs","sources":["../../../../libs/modules/auth/client/src/lib/shared/layouts/master/master.layout.ts","../../../../libs/modules/auth/client/src/lib/shared/layouts/master/master.layout.html"],"sourcesContent":["import { AXTranslationModule } from '@acorex/core/translation';\nimport { AXPPlatformBrandingService } from '@acorex-platform/framework-client/common';\nimport { AXPComponentSlotModule, AXPContextStore, AXPLogoComponent } from '@acorex-platform/framework-client/core';\nimport { AsyncPipe } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, ViewEncapsulation, inject, signal } from '@angular/core';\nimport { RouterModule } from '@angular/router';\nimport { AXMAuthPlatformSettingsService } from '../../../auth-platform-settings.service';\n\n//#region ----- Auth master layout -----\n\n@Component({\n templateUrl: 'master.layout.html',\n styleUrls: ['master.layout.css'],\n imports: [RouterModule, AXPLogoComponent, AXPComponentSlotModule, AXTranslationModule, AsyncPipe],\n providers: [AXPContextStore],\n changeDetection: ChangeDetectionStrategy.Eager,\n encapsulation: ViewEncapsulation.None,\n})\nexport class AXPAuthMasterLayoutComponent {\n //#region ----- Services & Dependencies -----\n\n private readonly authPlatformSettings = inject(AXMAuthPlatformSettingsService);\n private readonly platformBranding = inject(AXPPlatformBrandingService);\n\n protected readonly platformTitle = signal('');\n\n //#endregion\n\n //#region ----- Lifecycle -----\n\n constructor() {\n void this.platformBranding.resolvePlatformTitle().then((title) => this.platformTitle.set(title));\n }\n\n //#endregion\n\n //#region ----- Computed Properties -----\n\n /** Plain string or MLS map — rendered via translate pipe. */\n protected readonly slogan = this.authPlatformSettings.slogan();\n protected readonly description = this.authPlatformSettings.description();\n\n //#endregion\n}\n\n//#endregion\n","<div class=\"w-full h-full flex overflow-hidden\">\n <div\n class=\"axp-auth-master__form-pane flex-1 min-h-0 lightest-surface dark:darker-surface overflow-y-auto px-6 sm:px-8 md:px-10 lg:px-0\"\n >\n <!-- ----- Stack: logo + form vertically centered; footer pinned below ----- -->\n <div\n class=\"axp-auth-master__stack w-full min-h-full flex flex-col items-center\"\n >\n <div\n class=\"axp-auth-master__main w-full grow flex flex-col items-center justify-center gap-5 pt-6 pb-4 sm:pt-8 lg:pt-0 lg:gap-0\"\n >\n <!-- ----- Platform branding on viewports without the side panel ----- -->\n <div class=\"axp-auth-master__brand lg:hidden shrink-0 w-full flex justify-center\">\n <axp-logo\n logoKey=\"platform\"\n appearance=\"onLight\"\n format=\"full\"\n [size]=\"240\"\n [attr.alt]=\"platformTitle()\"\n class=\"axp-auth-master__logo\"\n ></axp-logo>\n </div>\n <div class=\"axp-auth-master__form-body w-full flex flex-col items-center\">\n <router-outlet></router-outlet>\n </div>\n </div>\n <div class=\"flex justify-between shrink-0 pt-2 pb-1\">\n <div class=\"auth-footer-links\">\n <axp-component-slot name=\"auth-footer-links\"></axp-component-slot>\n </div>\n </div>\n </div>\n </div>\n <div class=\"hidden lg:flex bg-primary-500 flex-1 axp-auth-bk text-white\">\n <div class=\"flex w-full flex-col justify-between px-48 py-20 text-center \">\n <div>\n <axp-logo\n logoKey=\"platform\"\n appearance=\"onDark\"\n format=\"full\"\n [size]=\"280\"\n [attr.alt]=\"platformTitle()\"\n class=\"w-[280px] max-w-full mx-auto\"\n ></axp-logo>\n </div>\n <div>\n <p class=\"font-black text-4xl mb-4\">{{ slogan | translate | async }}</p>\n <p>{{ description | translate | async }}</p>\n </div>\n </div>\n </div>\n</div>\n"],"names":["i1","i2"],"mappings":";;;;;;;;;;;;AAQA;MAUa,4BAA4B,CAAA;;;AAYvC,IAAA,WAAA,GAAA;;AATiB,QAAA,IAAA,CAAA,oBAAoB,GAAG,MAAM,CAAC,8BAA8B,CAAC;AAC7D,QAAA,IAAA,CAAA,gBAAgB,GAAG,MAAM,CAAC,0BAA0B,CAAC;QAEnD,IAAA,CAAA,aAAa,GAAG,MAAM,CAAC,EAAE;0FAAC;;;;AAe1B,QAAA,IAAA,CAAA,MAAM,GAAG,IAAI,CAAC,oBAAoB,CAAC,MAAM,EAAE;AAC3C,QAAA,IAAA,CAAA,WAAW,GAAG,IAAI,CAAC,oBAAoB,CAAC,WAAW,EAAE;QATtE,KAAK,IAAI,CAAC,gBAAgB,CAAC,oBAAoB,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAClG;8GAdW,4BAA4B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAA5B,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,4BAA4B,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,cAAA,EAAA,SAAA,EAJ5B,CAAC,eAAe,CAAC,0BCd9B,u/DAoDA,EAAA,MAAA,EAAA,CAAA,m4CAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EDvCY,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,EAAA,CAAA,YAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,kBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,QAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,gBAAgB,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,YAAA,EAAA,MAAA,EAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAE,sBAAsB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAC,EAAA,CAAA,yBAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,MAAA,EAAA,SAAA,CAAA,EAAA,QAAA,EAAA,CAAA,MAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAE,mBAAmB,0FAAE,SAAS,EAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,KAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA,CAAA;;2FAKrF,4BAA4B,EAAA,UAAA,EAAA,CAAA;kBARxC,SAAS;8BAGC,CAAC,YAAY,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,SAAS,CAAC,aACtF,CAAC,eAAe,CAAC,EAAA,eAAA,EACX,uBAAuB,CAAC,KAAK,EAAA,aAAA,EAC/B,iBAAiB,CAAC,IAAI,EAAA,QAAA,EAAA,u/DAAA,EAAA,MAAA,EAAA,CAAA,m4CAAA,CAAA,EAAA;;;"}