@acorex-platform/module-security-management-client 0.0.58 → 0.0.60

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 (61) hide show
  1. package/fesm2022/{acorex-platform-module-security-management-client-acorex-platform-module-security-management-client-BSGZRsGz.mjs → acorex-platform-module-security-management-client-acorex-platform-module-security-management-client-B61j_cJF.mjs} +212 -13
  2. package/fesm2022/acorex-platform-module-security-management-client-acorex-platform-module-security-management-client-B61j_cJF.mjs.map +1 -0
  3. package/fesm2022/acorex-platform-module-security-management-client-approve-join-request.command-BSvK59LV.mjs +322 -0
  4. package/fesm2022/acorex-platform-module-security-management-client-approve-join-request.command-BSvK59LV.mjs.map +1 -0
  5. package/fesm2022/acorex-platform-module-security-management-client-contracts-entities-device-sessions.mjs +21 -2
  6. package/fesm2022/acorex-platform-module-security-management-client-contracts-entities-device-sessions.mjs.map +1 -1
  7. package/fesm2022/acorex-platform-module-security-management-client-contracts-entities-users.mjs +173 -14
  8. package/fesm2022/acorex-platform-module-security-management-client-contracts-entities-users.mjs.map +1 -1
  9. package/fesm2022/{acorex-platform-module-security-management-client-contracts-entity-catalog-acorex-platform-module-security-management-client-contracts-entity-catalog-B4oiF8FO.mjs → acorex-platform-module-security-management-client-contracts-entity-catalog-acorex-platform-module-security-management-client-contracts-entity-catalog-JP3zTrun.mjs} +10 -10
  10. package/fesm2022/{acorex-platform-module-security-management-client-contracts-entity-catalog-acorex-platform-module-security-management-client-contracts-entity-catalog-B4oiF8FO.mjs.map → acorex-platform-module-security-management-client-contracts-entity-catalog-acorex-platform-module-security-management-client-contracts-entity-catalog-JP3zTrun.mjs.map} +1 -1
  11. package/fesm2022/{acorex-platform-module-security-management-client-contracts-entity-catalog-device-sessions.entity-CU-5X-qu.mjs → acorex-platform-module-security-management-client-contracts-entity-catalog-device-sessions.entity-lwQtCJoy.mjs} +23 -4
  12. package/fesm2022/acorex-platform-module-security-management-client-contracts-entity-catalog-device-sessions.entity-lwQtCJoy.mjs.map +1 -0
  13. package/fesm2022/{acorex-platform-module-security-management-client-contracts-entity-catalog-identity-provider.entity-Bld1buTd.mjs → acorex-platform-module-security-management-client-contracts-entity-catalog-identity-provider.entity-DZfizo-n.mjs} +2 -2
  14. package/fesm2022/{acorex-platform-module-security-management-client-contracts-entity-catalog-identity-provider.entity-Bld1buTd.mjs.map → acorex-platform-module-security-management-client-contracts-entity-catalog-identity-provider.entity-DZfizo-n.mjs.map} +1 -1
  15. package/fesm2022/{acorex-platform-module-security-management-client-contracts-entity-catalog-policy.entity-DZVzHzVM.mjs → acorex-platform-module-security-management-client-contracts-entity-catalog-policy.entity-Dkl_6Iio.mjs} +2 -2
  16. package/fesm2022/{acorex-platform-module-security-management-client-contracts-entity-catalog-policy.entity-DZVzHzVM.mjs.map → acorex-platform-module-security-management-client-contracts-entity-catalog-policy.entity-Dkl_6Iio.mjs.map} +1 -1
  17. package/fesm2022/{acorex-platform-module-security-management-client-contracts-entity-catalog-profile.entity-BCy5fNc9.mjs → acorex-platform-module-security-management-client-contracts-entity-catalog-profile.entity-Ddbd-rAG.mjs} +2 -2
  18. package/fesm2022/{acorex-platform-module-security-management-client-contracts-entity-catalog-profile.entity-BCy5fNc9.mjs.map → acorex-platform-module-security-management-client-contracts-entity-catalog-profile.entity-Ddbd-rAG.mjs.map} +1 -1
  19. package/fesm2022/{acorex-platform-module-security-management-client-contracts-entity-catalog-role-permission.entity-DcvYjfZm.mjs → acorex-platform-module-security-management-client-contracts-entity-catalog-role-permission.entity-WCgik8MV.mjs} +2 -2
  20. package/fesm2022/{acorex-platform-module-security-management-client-contracts-entity-catalog-role-permission.entity-DcvYjfZm.mjs.map → acorex-platform-module-security-management-client-contracts-entity-catalog-role-permission.entity-WCgik8MV.mjs.map} +1 -1
  21. package/fesm2022/{acorex-platform-module-security-management-client-contracts-entity-catalog-roles.entity-lNKDIDry.mjs → acorex-platform-module-security-management-client-contracts-entity-catalog-roles.entity-CRZftClq.mjs} +2 -2
  22. package/fesm2022/{acorex-platform-module-security-management-client-contracts-entity-catalog-roles.entity-lNKDIDry.mjs.map → acorex-platform-module-security-management-client-contracts-entity-catalog-roles.entity-CRZftClq.mjs.map} +1 -1
  23. package/fesm2022/{acorex-platform-module-security-management-client-contracts-entity-catalog-user-role.entity-DKII6o5N.mjs → acorex-platform-module-security-management-client-contracts-entity-catalog-user-role.entity-9QpoRCOF.mjs} +2 -2
  24. package/fesm2022/{acorex-platform-module-security-management-client-contracts-entity-catalog-user-role.entity-DKII6o5N.mjs.map → acorex-platform-module-security-management-client-contracts-entity-catalog-user-role.entity-9QpoRCOF.mjs.map} +1 -1
  25. package/fesm2022/{acorex-platform-module-security-management-client-contracts-entity-catalog-user-two-factor.entity-ge21b3mE.mjs → acorex-platform-module-security-management-client-contracts-entity-catalog-user-two-factor.entity-C34VzcYk.mjs} +2 -2
  26. package/fesm2022/{acorex-platform-module-security-management-client-contracts-entity-catalog-user-two-factor.entity-ge21b3mE.mjs.map → acorex-platform-module-security-management-client-contracts-entity-catalog-user-two-factor.entity-C34VzcYk.mjs.map} +1 -1
  27. package/fesm2022/{acorex-platform-module-security-management-client-contracts-entity-catalog-users.entity-CJ7x5rjC.mjs → acorex-platform-module-security-management-client-contracts-entity-catalog-users.entity-DuC5cfIb.mjs} +175 -16
  28. package/fesm2022/acorex-platform-module-security-management-client-contracts-entity-catalog-users.entity-DuC5cfIb.mjs.map +1 -0
  29. package/fesm2022/acorex-platform-module-security-management-client-contracts-entity-catalog.mjs +1 -1
  30. package/fesm2022/acorex-platform-module-security-management-client-contracts.mjs +342 -4
  31. package/fesm2022/acorex-platform-module-security-management-client-contracts.mjs.map +1 -1
  32. package/fesm2022/acorex-platform-module-security-management-client-create-user-in-tenant.command-BFnZRmh9.mjs +376 -0
  33. package/fesm2022/acorex-platform-module-security-management-client-create-user-in-tenant.command-BFnZRmh9.mjs.map +1 -0
  34. package/fesm2022/{acorex-platform-module-security-management-client-index-DKk9lEIl.mjs → acorex-platform-module-security-management-client-index-B6qo6qLT.mjs} +5 -156
  35. package/fesm2022/acorex-platform-module-security-management-client-index-B6qo6qLT.mjs.map +1 -0
  36. package/fesm2022/acorex-platform-module-security-management-client-invite-user.command-ClQ6WxxN.mjs +370 -0
  37. package/fesm2022/acorex-platform-module-security-management-client-invite-user.command-ClQ6WxxN.mjs.map +1 -0
  38. package/fesm2022/acorex-platform-module-security-management-client-reject-join-request.command-B3kiok6b.mjs +76 -0
  39. package/fesm2022/acorex-platform-module-security-management-client-reject-join-request.command-B3kiok6b.mjs.map +1 -0
  40. package/fesm2022/{acorex-platform-module-security-management-client-reset-two-factor.command-psTDKoNf.mjs → acorex-platform-module-security-management-client-reset-two-factor.command-C27mUZ1-.mjs} +7 -2
  41. package/fesm2022/acorex-platform-module-security-management-client-reset-two-factor.command-C27mUZ1-.mjs.map +1 -0
  42. package/fesm2022/{acorex-platform-module-security-management-client-send-password-reset-email.command-CoQgWdya.mjs → acorex-platform-module-security-management-client-send-password-reset-email.command-DFxm2T_x.mjs} +7 -2
  43. package/fesm2022/acorex-platform-module-security-management-client-send-password-reset-email.command-DFxm2T_x.mjs.map +1 -0
  44. package/fesm2022/acorex-platform-module-security-management-client-settings.provider-CwDiU-C8.mjs +54 -0
  45. package/fesm2022/acorex-platform-module-security-management-client-settings.provider-CwDiU-C8.mjs.map +1 -0
  46. package/fesm2022/acorex-platform-module-security-management-client-user-role-grant.service-6U17jzjq.mjs +231 -0
  47. package/fesm2022/acorex-platform-module-security-management-client-user-role-grant.service-6U17jzjq.mjs.map +1 -0
  48. package/fesm2022/acorex-platform-module-security-management-client.mjs +1 -1
  49. package/i18n/en-AU/security-management.json +91 -4
  50. package/i18n/en-US/security-management.json +91 -4
  51. package/i18n/fa-IR/security-management.json +91 -4
  52. package/package.json +1 -1
  53. package/types/acorex-platform-module-security-management-client-contracts.d.ts +288 -8
  54. package/fesm2022/acorex-platform-module-security-management-client-acorex-platform-module-security-management-client-BSGZRsGz.mjs.map +0 -1
  55. package/fesm2022/acorex-platform-module-security-management-client-contracts-entity-catalog-device-sessions.entity-CU-5X-qu.mjs.map +0 -1
  56. package/fesm2022/acorex-platform-module-security-management-client-contracts-entity-catalog-users.entity-CJ7x5rjC.mjs.map +0 -1
  57. package/fesm2022/acorex-platform-module-security-management-client-index-DKk9lEIl.mjs.map +0 -1
  58. package/fesm2022/acorex-platform-module-security-management-client-invite-user.command-kFXjLdxy.mjs +0 -143
  59. package/fesm2022/acorex-platform-module-security-management-client-invite-user.command-kFXjLdxy.mjs.map +0 -1
  60. package/fesm2022/acorex-platform-module-security-management-client-reset-two-factor.command-psTDKoNf.mjs.map +0 -1
  61. package/fesm2022/acorex-platform-module-security-management-client-send-password-reset-email.command-CoQgWdya.mjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acorex-platform-module-security-management-client-reset-two-factor.command-C27mUZ1-.mjs","sources":["../../../../libs/modules/security-management/client/src/lib/commands/reset-two-factor.command.ts"],"sourcesContent":["import { AXDialogService } from '@acorex/components/dialog';\nimport { AXToastService } from '@acorex/components/toast';\nimport { AXTranslationService } from '@acorex/core/translation';\nimport { AXPCommandService } from '@acorex-platform/framework-client/runtime';\nimport { AXPCommand, type AXPCommandExecuteResultPromise } from '@acorex-platform/framework-shared/runtime';\nimport {\n AXM_TWO_FACTOR_ERROR_CODES,\n AXM_USER_RESET_TWO_FACTOR_COMMAND,\n AXMSecurityManagementServerCommands,\n} from '@acorex-platform/module-security-management-client/contracts';\nimport { inject, Injectable } from '@angular/core';\n\n//#region ----- Types -----\n\nexport interface AXPResetTwoFactorCommandInput {\n userId?: string;\n data?: {\n id?: string;\n /** Present on TenantUser rows — prefer over `id` (membership id). */\n userId?: string;\n displayName?: string;\n username?: string;\n email?: string;\n user?: { displayName?: string; username?: string; email?: string };\n };\n}\n\n//#endregion\n\n//#region ----- Constants -----\n\nconst I18N = '@security-management:users.entities.user.actions.reset-two-factor';\n\nconst TWO_FACTOR_ERROR_I18N: Record<string, string> = {\n [AXM_TWO_FACTOR_ERROR_CODES.InvalidInput]: `${I18N}.errors.invalid-input`,\n [AXM_TWO_FACTOR_ERROR_CODES.UserNotFound]: `${I18N}.errors.user-not-found`,\n [AXM_TWO_FACTOR_ERROR_CODES.Forbidden]: `${I18N}.errors.forbidden`,\n [AXM_TWO_FACTOR_ERROR_CODES.NotEnabled]: `${I18N}.errors.not-enabled`,\n};\n\n//#endregion\n\n//#region ----- Client command -----\n\n/**\n * Admin Action on User detail: if 2FA is not enabled, warn and stop;\n * otherwise confirm, then call server AdminResetTwoFactor.\n */\n@Injectable({ providedIn: 'root' })\nexport class AXPResetTwoFactorCommand implements AXPCommand<AXPResetTwoFactorCommandInput> {\n //#region ----- Services & Dependencies -----\n\n private readonly dialogService = inject(AXDialogService);\n private readonly toastService = inject(AXToastService);\n private readonly translationService = inject(AXTranslationService);\n private readonly commandService = inject(AXPCommandService);\n\n //#endregion\n\n //#region ----- Command -----\n\n async execute(input: AXPResetTwoFactorCommandInput = {}): AXPCommandExecuteResultPromise {\n // Users row: data.id is User id. TenantUser row: data.userId is User id.\n const userId = input.userId ?? input.data?.userId ?? input.data?.id;\n if (!userId) {\n return { success: false, message: { text: `${I18N}.errors.invalid-input` } };\n }\n\n const nested = input.data?.user;\n const who =\n input.data?.displayName ||\n nested?.displayName ||\n input.data?.username ||\n nested?.username ||\n input.data?.email ||\n nested?.email ||\n String(userId);\n\n // Preflight: stop before confirm when 2FA was never enabled for this user.\n const preflight = await this.commandService.executeRemote(\n AXMSecurityManagementServerCommands.AdminResetTwoFactor,\n { userId: String(userId), dryRun: true },\n );\n if (!preflight?.success) {\n await this.showFailureToast(preflight?.message?.code);\n return { success: false };\n }\n\n const confirmTitle = await this.translationService.translateAsync(`${I18N}.confirm-title`);\n const confirmMessage = await this.translationService.translateAsync(`${I18N}.confirm-message`, {\n params: { user: who },\n });\n\n const confirmed = await this.dialogService.confirm(confirmTitle, confirmMessage, 'danger', 'horizontal');\n if (!confirmed.result) {\n return { success: false };\n }\n\n const result = await this.commandService.executeRemote(\n AXMSecurityManagementServerCommands.AdminResetTwoFactor,\n { userId: String(userId) },\n );\n\n if (result?.success) {\n const [toastTitle, toastContent] = await Promise.all([\n this.translationService.translateAsync(`${I18N}.success.title`),\n this.translationService.translateAsync(`${I18N}.success.description`),\n ]);\n this.toastService.show({ color: 'success', title: toastTitle, content: toastContent, timeOut: 3000 });\n return { success: true, kind: 'object', data: undefined };\n }\n\n await this.showFailureToast(result?.message?.code);\n return { success: false };\n }\n\n //#endregion\n\n //#region ----- Helpers -----\n\n private async showFailureToast(code: unknown): Promise<void> {\n const codeKey = typeof code === 'string' ? code : '';\n const errorKey = TWO_FACTOR_ERROR_I18N[codeKey] || `${I18N}.error.description`;\n const isNotEnabled = codeKey === AXM_TWO_FACTOR_ERROR_CODES.NotEnabled;\n const [toastTitle, toastContent] = await Promise.all([\n this.translationService.translateAsync(\n isNotEnabled ? `${I18N}.errors.not-enabled-title` : `${I18N}.error.title`,\n ),\n this.translationService.translateAsync(errorKey),\n ]);\n this.toastService.show({\n color: isNotEnabled ? 'warning' : 'danger',\n title: toastTitle,\n content: toastContent,\n timeOut: 4000,\n });\n }\n\n //#endregion\n}\n\nexport { AXM_USER_RESET_TWO_FACTOR_COMMAND };\n\n//#endregion\n"],"names":[],"mappings":"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"}
@@ -20,13 +20,18 @@ class AXPSendPasswordResetEmailCommand {
20
20
  this.commandService = inject(AXPCommandService);
21
21
  }
22
22
  async execute(input = {}) {
23
- const userId = input.userId ?? input.data?.id;
23
+ // Users row: data.id is User id. TenantUser row: data.userId is User id.
24
+ const userId = input.userId ?? input.data?.userId ?? input.data?.id;
24
25
  if (!userId) {
25
26
  return { success: false, message: { text: 'User id is required.' } };
26
27
  }
28
+ const nested = input.data?.user;
27
29
  const who = input.data?.displayName ||
30
+ nested?.displayName ||
28
31
  input.data?.username ||
32
+ nested?.username ||
29
33
  input.data?.email ||
34
+ nested?.email ||
30
35
  String(userId);
31
36
  const confirmTitle = await this.translationService
32
37
  .translateAsync('@security-management:users.entities.user.actions.send-password-reset.confirm-title')
@@ -78,4 +83,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
78
83
  }] });
79
84
 
80
85
  export { AXPSendPasswordResetEmailCommand };
81
- //# sourceMappingURL=acorex-platform-module-security-management-client-send-password-reset-email.command-CoQgWdya.mjs.map
86
+ //# sourceMappingURL=acorex-platform-module-security-management-client-send-password-reset-email.command-DFxm2T_x.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acorex-platform-module-security-management-client-send-password-reset-email.command-DFxm2T_x.mjs","sources":["../../../../libs/modules/security-management/client/src/lib/commands/send-password-reset-email.command.ts"],"sourcesContent":["import { AXDialogService } from '@acorex/components/dialog';\nimport { AXToastService } from '@acorex/components/toast';\nimport { AXTranslationService } from '@acorex/core/translation';\nimport { AXPCommandService } from '@acorex-platform/framework-client/runtime';\nimport { AXPRuntimeCommandResult } from '@acorex-platform/framework-shared/core';\nimport { AXPCommand, type AXPCommandExecuteResultPromise } from '@acorex-platform/framework-shared/runtime';\nimport {\n AXM_USER_SEND_PASSWORD_RESET_COMMAND,\n AXMSecurityManagementServerCommands,\n} from '@acorex-platform/module-security-management-client/contracts';\nimport { inject, Injectable } from '@angular/core';\n\n//#region ---- Types ----\n\nexport interface AXPSendPasswordResetEmailCommandInput {\n userId?: string;\n data?: {\n id?: string;\n /** Present on TenantUser rows — prefer over `id` (membership id). */\n userId?: string;\n displayName?: string;\n username?: string;\n email?: string;\n user?: { displayName?: string; username?: string; email?: string };\n };\n}\n\n//#endregion\n\n//#region ---- Client command ----\n\n/**\n * Admin Action on User detail: confirm, then call server SendPasswordResetEmail.\n */\n@Injectable({ providedIn: 'root' })\nexport class AXPSendPasswordResetEmailCommand\n implements AXPCommand<AXPSendPasswordResetEmailCommandInput>\n{\n private readonly dialogService = inject(AXDialogService);\n private readonly toastService = inject(AXToastService);\n private readonly translationService = inject(AXTranslationService);\n private readonly commandService = inject(AXPCommandService);\n\n async execute(input: AXPSendPasswordResetEmailCommandInput = {}): AXPCommandExecuteResultPromise {\n // Users row: data.id is User id. TenantUser row: data.userId is User id.\n const userId = input.userId ?? input.data?.userId ?? input.data?.id;\n if (!userId) {\n return { success: false, message: { text: 'User id is required.' } };\n }\n\n const nested = input.data?.user;\n const who =\n input.data?.displayName ||\n nested?.displayName ||\n input.data?.username ||\n nested?.username ||\n input.data?.email ||\n nested?.email ||\n String(userId);\n\n const confirmTitle = await this.translationService\n .translateAsync('@security-management:users.entities.user.actions.send-password-reset.confirm-title')\n .catch(() => 'Send Password Reset Email');\n const confirmMessage = await this.translationService\n .translateAsync('@security-management:users.entities.user.actions.send-password-reset.confirm-message', {\n params: { user: who },\n })\n .catch(() => `Send a password reset email to ${who}?`);\n\n const confirmed = await this.dialogService.confirm(confirmTitle, confirmMessage, 'primary', 'horizontal');\n if (!confirmed.result) {\n return { success: false };\n }\n\n const webOrigin = typeof window !== 'undefined' ? window.location.origin : undefined;\n const result = await this.commandService.execute(AXMSecurityManagementServerCommands.SendPasswordResetEmail, {\n userId: String(userId),\n webOrigin,\n });\n\n if (result?.success) {\n const [toastTitle, toastContent] = await Promise.all([\n this.translationService\n .translateAsync(\n '@security-management:users.entities.user.actions.send-password-reset.success.title',\n )\n .catch(() => 'Email Sent'),\n this.translationService\n .translateAsync(\n '@security-management:users.entities.user.actions.send-password-reset.success.description',\n )\n .catch(() => 'Password reset email sent.'),\n ]);\n this.toastService.show({ color: 'success', title: toastTitle, content: toastContent, timeOut: 3000 });\n return { success: true, kind: 'object', data: undefined };\n }\n\n const [toastTitle, fallbackContent] = await Promise.all([\n this.translationService\n .translateAsync(\n '@security-management:users.entities.user.actions.send-password-reset.error.title',\n )\n .catch(() => 'Send Failed'),\n this.translationService\n .translateAsync(\n '@security-management:users.entities.user.actions.send-password-reset.error.description',\n )\n .catch(() => 'Failed to send password reset email.'),\n ]);\n const toastContent =\n (typeof result?.message?.text === 'string' && result.message.text) || fallbackContent;\n this.toastService.show({ color: 'danger', title: toastTitle, content: toastContent, timeOut: 4000 });\n return { success: false, message: { text: toastContent } };\n }\n}\n\nexport { AXM_USER_SEND_PASSWORD_RESET_COMMAND };\n\n//#endregion\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ import { objectKeyValueTransforms } from '@acorex-platform/framework-client/core';
2
+ import { AXPWidgetsCatalog, AXPPlatformScope } from '@acorex-platform/framework-shared/core';
3
+ import { RootConfig, AXMUserProvisioningMode, AXM_USER_PROVISIONING_MODE_DEFAULT, AXMSecurityManagementSettings } from '@acorex-platform/module-security-management-client/contracts';
4
+
5
+ //#region ----- Imports -----
6
+ //#endregion
7
+ //#region ----- Constants -----
8
+ const I18N = '@security-management:settings';
9
+ //#endregion
10
+ //#region ----- Setting provider -----
11
+ class AXMSecurityManagementSettingProvider {
12
+ async provide(context) {
13
+ context
14
+ .addGroup('security-management', `${I18N}.group.title`, `${I18N}.group.description`, RootConfig.module.icon, undefined, 96)
15
+ .addSection('users', `${I18N}.users.title`, `${I18N}.users.description`)
16
+ .addSetting({
17
+ key: AXMSecurityManagementSettings.UserProvisioningMode,
18
+ title: `${I18N}.users.provisioning-mode.title`,
19
+ description: `${I18N}.users.provisioning-mode.description`,
20
+ scope: AXPPlatformScope.Platform,
21
+ overridableAt: [],
22
+ isInherited: false,
23
+ defaultValue: AXM_USER_PROVISIONING_MODE_DEFAULT,
24
+ valueTransforms: objectKeyValueTransforms('value'),
25
+ widget: {
26
+ type: AXPWidgetsCatalog.select,
27
+ options: {
28
+ valueField: 'value',
29
+ textField: 'text',
30
+ dataSource: [
31
+ {
32
+ text: `${I18N}.users.provisioning-mode.options.create`,
33
+ value: AXMUserProvisioningMode.Create,
34
+ },
35
+ {
36
+ text: `${I18N}.users.provisioning-mode.options.invite`,
37
+ value: AXMUserProvisioningMode.Invite,
38
+ },
39
+ {
40
+ text: `${I18N}.users.provisioning-mode.options.both`,
41
+ value: AXMUserProvisioningMode.Both,
42
+ },
43
+ ],
44
+ },
45
+ },
46
+ })
47
+ .endSection()
48
+ .endGroup();
49
+ }
50
+ }
51
+ //#endregion
52
+
53
+ export { AXMSecurityManagementSettingProvider };
54
+ //# sourceMappingURL=acorex-platform-module-security-management-client-settings.provider-CwDiU-C8.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acorex-platform-module-security-management-client-settings.provider-CwDiU-C8.mjs","sources":["../../../../libs/modules/security-management/client/src/lib/settings.provider.ts"],"sourcesContent":["//#region ----- Imports -----\n\nimport {\n AXPSettingDefinitionProvider,\n AXPSettingDefinitionProviderContext,\n} from '@acorex-platform/framework-client/common';\nimport { objectKeyValueTransforms } from '@acorex-platform/framework-client/core';\nimport { AXPPlatformScope, AXPWidgetsCatalog } from '@acorex-platform/framework-shared/core';\nimport {\n AXM_USER_PROVISIONING_MODE_DEFAULT,\n AXMSecurityManagementSettings,\n AXMUserProvisioningMode,\n RootConfig,\n} from '@acorex-platform/module-security-management-client/contracts';\n\n//#endregion\n\n//#region ----- Constants -----\n\nconst I18N = '@security-management:settings';\n\n//#endregion\n\n//#region ----- Setting provider -----\n\nexport class AXMSecurityManagementSettingProvider implements AXPSettingDefinitionProvider {\n async provide(context: AXPSettingDefinitionProviderContext): Promise<void> {\n context\n .addGroup(\n 'security-management',\n `${I18N}.group.title`,\n `${I18N}.group.description`,\n RootConfig.module.icon,\n undefined,\n 96,\n )\n .addSection('users', `${I18N}.users.title`, `${I18N}.users.description`)\n .addSetting({\n key: AXMSecurityManagementSettings.UserProvisioningMode,\n title: `${I18N}.users.provisioning-mode.title`,\n description: `${I18N}.users.provisioning-mode.description`,\n scope: AXPPlatformScope.Platform,\n overridableAt: [],\n isInherited: false,\n defaultValue: AXM_USER_PROVISIONING_MODE_DEFAULT,\n valueTransforms: objectKeyValueTransforms('value'),\n widget: {\n type: AXPWidgetsCatalog.select,\n options: {\n valueField: 'value',\n textField: 'text',\n dataSource: [\n {\n text: `${I18N}.users.provisioning-mode.options.create`,\n value: AXMUserProvisioningMode.Create,\n },\n {\n text: `${I18N}.users.provisioning-mode.options.invite`,\n value: AXMUserProvisioningMode.Invite,\n },\n {\n text: `${I18N}.users.provisioning-mode.options.both`,\n value: AXMUserProvisioningMode.Both,\n },\n ],\n },\n },\n })\n .endSection()\n .endGroup();\n }\n}\n\n//#endregion\n"],"names":[],"mappings":";;;;AAAA;AAeA;AAEA;AAEA,MAAM,IAAI,GAAG,+BAA+B;AAE5C;AAEA;MAEa,oCAAoC,CAAA;IAC/C,MAAM,OAAO,CAAC,OAA4C,EAAA;QACxD;aACG,QAAQ,CACP,qBAAqB,EACrB,CAAA,EAAG,IAAI,CAAA,YAAA,CAAc,EACrB,GAAG,IAAI,CAAA,kBAAA,CAAoB,EAC3B,UAAU,CAAC,MAAM,CAAC,IAAI,EACtB,SAAS,EACT,EAAE;aAEH,UAAU,CAAC,OAAO,EAAE,CAAA,EAAG,IAAI,cAAc,EAAE,CAAA,EAAG,IAAI,CAAA,kBAAA,CAAoB;AACtE,aAAA,UAAU,CAAC;YACV,GAAG,EAAE,6BAA6B,CAAC,oBAAoB;YACvD,KAAK,EAAE,CAAA,EAAG,IAAI,CAAA,8BAAA,CAAgC;YAC9C,WAAW,EAAE,CAAA,EAAG,IAAI,CAAA,oCAAA,CAAsC;YAC1D,KAAK,EAAE,gBAAgB,CAAC,QAAQ;AAChC,YAAA,aAAa,EAAE,EAAE;AACjB,YAAA,WAAW,EAAE,KAAK;AAClB,YAAA,YAAY,EAAE,kCAAkC;AAChD,YAAA,eAAe,EAAE,wBAAwB,CAAC,OAAO,CAAC;AAClD,YAAA,MAAM,EAAE;gBACN,IAAI,EAAE,iBAAiB,CAAC,MAAM;AAC9B,gBAAA,OAAO,EAAE;AACP,oBAAA,UAAU,EAAE,OAAO;AACnB,oBAAA,SAAS,EAAE,MAAM;AACjB,oBAAA,UAAU,EAAE;AACV,wBAAA;4BACE,IAAI,EAAE,CAAA,EAAG,IAAI,CAAA,uCAAA,CAAyC;4BACtD,KAAK,EAAE,uBAAuB,CAAC,MAAM;AACtC,yBAAA;AACD,wBAAA;4BACE,IAAI,EAAE,CAAA,EAAG,IAAI,CAAA,uCAAA,CAAyC;4BACtD,KAAK,EAAE,uBAAuB,CAAC,MAAM;AACtC,yBAAA;AACD,wBAAA;4BACE,IAAI,EAAE,CAAA,EAAG,IAAI,CAAA,qCAAA,CAAuC;4BACpD,KAAK,EAAE,uBAAuB,CAAC,IAAI;AACpC,yBAAA;AACF,qBAAA;AACF,iBAAA;AACF,aAAA;SACF;AACA,aAAA,UAAU;AACV,aAAA,QAAQ,EAAE;IACf;AACD;AAED;;"}
@@ -0,0 +1,231 @@
1
+ import { AXPSessionService } from '@acorex-platform/framework-client/auth';
2
+ import { AXPEntityBroadcastService } from '@acorex-platform/framework-client/core';
3
+ import { AXPEntityDefinitionRegistryService, AXPEntityService, dispatchEntityModifiedSideEffects } from '@acorex-platform/framework-client/layout/entity';
4
+ import { RootConfig, isRoleAssignableForInvite } from '@acorex-platform/module-security-management-client/contracts';
5
+ import * as i0 from '@angular/core';
6
+ import { inject, Injectable } from '@angular/core';
7
+
8
+ //#region ----- Imports -----
9
+ //#endregion
10
+ //#region ----- Service -----
11
+ /**
12
+ * Loads and persists scoped UserRole assignments for a user.
13
+ * Shared by the User roles detail page.
14
+ */
15
+ class AXMUserRoleGrantService {
16
+ constructor() {
17
+ //#region ----- Services & Dependencies -----
18
+ this.entityRegistry = inject(AXPEntityDefinitionRegistryService);
19
+ this.entityService = inject(AXPEntityService);
20
+ this.sessionService = inject(AXPSessionService);
21
+ this.entityEvents = inject(AXPEntityBroadcastService);
22
+ }
23
+ //#endregion
24
+ //#region ----- Scope -----
25
+ resolveSessionScope() {
26
+ const tenantId = this.sessionService.tenant?.id;
27
+ if (!tenantId) {
28
+ return null;
29
+ }
30
+ return {
31
+ tenantId,
32
+ applicationId: this.sessionService.application?.id,
33
+ };
34
+ }
35
+ //#endregion
36
+ //#region ----- Query -----
37
+ userRoleData() {
38
+ return this.entityService
39
+ .withEntity(RootConfig.module.name, RootConfig.entities.userRole.name)
40
+ .data();
41
+ }
42
+ /**
43
+ * Roles available to assign in the current workspace.
44
+ * Also loads any already-assigned role ids that list queries hide (`stateInfo.isHidden`).
45
+ */
46
+ async listRoleOptions(includeRoleIds = []) {
47
+ const byId = await this.loadRoleOptionMap(includeRoleIds);
48
+ return [...byId.values()].sort((a, b) => a.title.localeCompare(b.title));
49
+ }
50
+ /**
51
+ * Roles selectable on Invite — filtered by invite surface scope only.
52
+ * Does not change Role RLS / EntityAccessPolicy; query + client filter narrow the picker.
53
+ * - application → current tenant + current application Role overlays
54
+ * - tenant → current tenant-wide Roles (no applicationId)
55
+ */
56
+ async listInviteRoleOptions(mode) {
57
+ const scope = this.resolveSessionScope();
58
+ if (!scope) {
59
+ return [];
60
+ }
61
+ if (mode === 'application') {
62
+ const applicationId = scope.applicationId?.trim();
63
+ if (!applicationId) {
64
+ return [];
65
+ }
66
+ const byId = await this.loadRoleOptionMap([], this.buildApplicationInviteRoleFilter(scope.tenantId, applicationId));
67
+ return [...byId.values()]
68
+ .filter((role) => isRoleAssignableForInvite(role, 'application', {
69
+ tenantId: scope.tenantId,
70
+ applicationId,
71
+ }))
72
+ .sort((a, b) => a.title.localeCompare(b.title));
73
+ }
74
+ const byId = await this.loadRoleOptionMap([], this.buildTenantInviteRoleFilter(scope.tenantId));
75
+ return [...byId.values()]
76
+ .filter((role) => isRoleAssignableForInvite(role, 'tenant', {
77
+ tenantId: scope.tenantId,
78
+ applicationId: scope.applicationId,
79
+ }))
80
+ .sort((a, b) => a.title.localeCompare(b.title));
81
+ }
82
+ /** Exact application overlay rows for the current tenant + application. */
83
+ buildApplicationInviteRoleFilter(tenantId, applicationId) {
84
+ return {
85
+ logic: 'and',
86
+ filters: [
87
+ { field: 'scopeInfo.tenantId', operator: { type: 'equal' }, value: tenantId },
88
+ { field: 'scopeInfo.applicationId', operator: { type: 'equal' }, value: applicationId },
89
+ ],
90
+ };
91
+ }
92
+ /** Tenant-wide Role rows for the current tenant (no applicationId). */
93
+ buildTenantInviteRoleFilter(tenantId) {
94
+ return {
95
+ logic: 'and',
96
+ filters: [
97
+ { field: 'scopeInfo.tenantId', operator: { type: 'equal' }, value: tenantId },
98
+ {
99
+ logic: 'or',
100
+ filters: [
101
+ { field: 'scopeInfo.applicationId', operator: { type: 'isNull' } },
102
+ { field: 'scopeInfo.applicationId', operator: { type: 'isEmpty' } },
103
+ ],
104
+ },
105
+ ],
106
+ };
107
+ }
108
+ async loadRoleOptionMap(includeRoleIds = [], filter) {
109
+ const roleData = this.entityService
110
+ .withEntity(RootConfig.module.name, RootConfig.entities.roles.name)
111
+ .data();
112
+ const result = await roleData.query({
113
+ skip: 0,
114
+ take: 500,
115
+ ...(filter ? { filter } : {}),
116
+ });
117
+ const byId = new Map();
118
+ const items = (result?.items ?? []);
119
+ for (const item of items) {
120
+ const option = this.toRoleOption(item);
121
+ if (option) {
122
+ byId.set(option.id, option);
123
+ }
124
+ }
125
+ const missingIds = includeRoleIds.filter((id) => id && !byId.has(id));
126
+ await Promise.all(missingIds.map(async (id) => {
127
+ try {
128
+ const row = (await roleData.byKey(id));
129
+ const option = this.toRoleOption(row);
130
+ if (option) {
131
+ byId.set(option.id, option);
132
+ }
133
+ }
134
+ catch {
135
+ /* role missing or inaccessible */
136
+ }
137
+ }));
138
+ return byId;
139
+ }
140
+ toRoleOption(item) {
141
+ const id = String(item?.['id'] ?? '').trim();
142
+ if (!id) {
143
+ return null;
144
+ }
145
+ const scopeRaw = item?.['scopeInfo'];
146
+ const scope = scopeRaw && typeof scopeRaw === 'object' ? scopeRaw : undefined;
147
+ return {
148
+ id,
149
+ title: String(item?.['title'] ?? item?.['name'] ?? ''),
150
+ name: typeof item?.['name'] === 'string' ? item['name'] : undefined,
151
+ scopeInfo: scope
152
+ ? {
153
+ tenantId: typeof scope['tenantId'] === 'string' ? scope['tenantId'] : undefined,
154
+ applicationId: typeof scope['applicationId'] === 'string' ? scope['applicationId'] : undefined,
155
+ }
156
+ : undefined,
157
+ };
158
+ }
159
+ async findGrant(userId, tenantId, applicationId) {
160
+ const result = await this.userRoleData().query({
161
+ skip: 0,
162
+ take: 50,
163
+ filter: {
164
+ logic: 'and',
165
+ filters: [
166
+ { field: 'userId', operator: { type: 'equal' }, value: userId },
167
+ { field: 'scopeInfo.tenantId', operator: { type: 'equal' }, value: tenantId },
168
+ ],
169
+ },
170
+ });
171
+ const items = (result?.items ?? []);
172
+ if (items.length === 0) {
173
+ return null;
174
+ }
175
+ if (applicationId) {
176
+ const appMatch = items.find((item) => item.scopeInfo?.applicationId === applicationId);
177
+ if (appMatch) {
178
+ return appMatch;
179
+ }
180
+ }
181
+ const tenantWide = items.find((item) => !item.scopeInfo?.applicationId);
182
+ return tenantWide ?? items[0] ?? null;
183
+ }
184
+ //#endregion
185
+ //#region ----- Persist -----
186
+ async saveGrant(options) {
187
+ const existingState = options.existing?.stateInfo;
188
+ if (existingState?.isSystem === true || existingState?.isImmutable === true) {
189
+ throw new Error('System user role grants are readonly.');
190
+ }
191
+ const entityKey = `${RootConfig.module.name}.${RootConfig.entities.userRole.name}`;
192
+ const [moduleName, entityName] = entityKey.split('.');
193
+ const entityRef = await this.entityRegistry.resolve(moduleName, entityName);
194
+ const scopeInfo = {
195
+ tenantId: options.tenantId,
196
+ ...(options.existing?.scopeInfo?.applicationId
197
+ ? { applicationId: options.existing.scopeInfo.applicationId }
198
+ : options.applicationId
199
+ ? { applicationId: options.applicationId }
200
+ : {}),
201
+ };
202
+ if (options.existing?.id) {
203
+ const updatePayload = {
204
+ ...options.existing,
205
+ userId: options.userId,
206
+ roleIds: options.roleIds,
207
+ scopeInfo,
208
+ };
209
+ return (entityRef.commands?.update?.execute)(updatePayload);
210
+ }
211
+ const createPayload = {
212
+ userId: options.userId,
213
+ roleIds: options.roleIds,
214
+ scopeInfo,
215
+ };
216
+ return (entityRef.commands?.create?.execute)(createPayload);
217
+ }
218
+ notifyGrantModified(saved) {
219
+ const entityKey = `${RootConfig.module.name}.${RootConfig.entities.userRole.name}`;
220
+ dispatchEntityModifiedSideEffects(this.entityEvents, entityKey, saved);
221
+ }
222
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMUserRoleGrantService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
223
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMUserRoleGrantService, providedIn: 'root' }); }
224
+ }
225
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMUserRoleGrantService, decorators: [{
226
+ type: Injectable,
227
+ args: [{ providedIn: 'root' }]
228
+ }] });
229
+
230
+ export { AXMUserRoleGrantService as A };
231
+ //# sourceMappingURL=acorex-platform-module-security-management-client-user-role-grant.service-6U17jzjq.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acorex-platform-module-security-management-client-user-role-grant.service-6U17jzjq.mjs","sources":["../../../../libs/modules/security-management/client/src/lib/features/user-roles/user-role-grant.service.ts"],"sourcesContent":["//#region ----- Imports -----\n\nimport { AXPSessionService } from '@acorex-platform/framework-client/auth';\nimport { AXPEntityBroadcastService } from '@acorex-platform/framework-client/core';\nimport {\n AXPEntityDefinitionRegistryService,\n AXPEntityService,\n dispatchEntityModifiedSideEffects,\n} from '@acorex-platform/framework-client/layout/entity';\nimport {\n isRoleAssignableForInvite,\n RootConfig,\n type AXMInviteRoleAssignmentMode,\n} from '@acorex-platform/module-security-management-client/contracts';\nimport { Injectable, inject } from '@angular/core';\nimport type {\n SaveUserRoleGrantOptions,\n UserRoleGrantRow,\n UserRoleOption,\n} from './user-role-grant.types';\n\n//#endregion\n\n//#region ----- Service -----\n\n/**\n * Loads and persists scoped UserRole assignments for a user.\n * Shared by the User roles detail page.\n */\n@Injectable({ providedIn: 'root' })\nexport class AXMUserRoleGrantService {\n //#region ----- Services & Dependencies -----\n\n private readonly entityRegistry = inject(AXPEntityDefinitionRegistryService);\n private readonly entityService = inject(AXPEntityService);\n private readonly sessionService = inject(AXPSessionService);\n private readonly entityEvents = inject(AXPEntityBroadcastService);\n\n //#endregion\n\n //#region ----- Scope -----\n\n resolveSessionScope(): { tenantId: string; applicationId: string | undefined } | null {\n const tenantId = this.sessionService.tenant?.id;\n if (!tenantId) {\n return null;\n }\n return {\n tenantId,\n applicationId: this.sessionService.application?.id,\n };\n }\n\n //#endregion\n\n //#region ----- Query -----\n\n private userRoleData() {\n return this.entityService\n .withEntity(RootConfig.module.name, RootConfig.entities.userRole.name)\n .data<string, UserRoleGrantRow, UserRoleGrantRow>();\n }\n\n /**\n * Roles available to assign in the current workspace.\n * Also loads any already-assigned role ids that list queries hide (`stateInfo.isHidden`).\n */\n async listRoleOptions(includeRoleIds: readonly string[] = []): Promise<UserRoleOption[]> {\n const byId = await this.loadRoleOptionMap(includeRoleIds);\n return [...byId.values()].sort((a, b) => a.title.localeCompare(b.title));\n }\n\n /**\n * Roles selectable on Invite — filtered by invite surface scope only.\n * Does not change Role RLS / EntityAccessPolicy; query + client filter narrow the picker.\n * - application → current tenant + current application Role overlays\n * - tenant → current tenant-wide Roles (no applicationId)\n */\n async listInviteRoleOptions(mode: AXMInviteRoleAssignmentMode): Promise<UserRoleOption[]> {\n const scope = this.resolveSessionScope();\n if (!scope) {\n return [];\n }\n\n if (mode === 'application') {\n const applicationId = scope.applicationId?.trim();\n if (!applicationId) {\n return [];\n }\n const byId = await this.loadRoleOptionMap(\n [],\n this.buildApplicationInviteRoleFilter(scope.tenantId, applicationId),\n );\n return [...byId.values()]\n .filter((role) =>\n isRoleAssignableForInvite(role, 'application', {\n tenantId: scope.tenantId,\n applicationId,\n }),\n )\n .sort((a, b) => a.title.localeCompare(b.title));\n }\n\n const byId = await this.loadRoleOptionMap([], this.buildTenantInviteRoleFilter(scope.tenantId));\n return [...byId.values()]\n .filter((role) =>\n isRoleAssignableForInvite(role, 'tenant', {\n tenantId: scope.tenantId,\n applicationId: scope.applicationId,\n }),\n )\n .sort((a, b) => a.title.localeCompare(b.title));\n }\n\n /** Exact application overlay rows for the current tenant + application. */\n private buildApplicationInviteRoleFilter(\n tenantId: string,\n applicationId: string,\n ): Record<string, unknown> {\n return {\n logic: 'and',\n filters: [\n { field: 'scopeInfo.tenantId', operator: { type: 'equal' }, value: tenantId },\n { field: 'scopeInfo.applicationId', operator: { type: 'equal' }, value: applicationId },\n ],\n };\n }\n\n /** Tenant-wide Role rows for the current tenant (no applicationId). */\n private buildTenantInviteRoleFilter(tenantId: string): Record<string, unknown> {\n return {\n logic: 'and',\n filters: [\n { field: 'scopeInfo.tenantId', operator: { type: 'equal' }, value: tenantId },\n {\n logic: 'or',\n filters: [\n { field: 'scopeInfo.applicationId', operator: { type: 'isNull' } },\n { field: 'scopeInfo.applicationId', operator: { type: 'isEmpty' } },\n ],\n },\n ],\n };\n }\n\n private async loadRoleOptionMap(\n includeRoleIds: readonly string[] = [],\n filter?: Record<string, unknown>,\n ): Promise<Map<string, UserRoleOption>> {\n const roleData = this.entityService\n .withEntity(RootConfig.module.name, RootConfig.entities.roles.name)\n .data<string, UserRoleOption, UserRoleOption>();\n\n const result = await roleData.query({\n skip: 0,\n take: 500,\n ...(filter ? { filter } : {}),\n } as never);\n\n const byId = new Map<string, UserRoleOption>();\n const items = (result?.items ?? []) as unknown as Array<Record<string, unknown>>;\n for (const item of items) {\n const option = this.toRoleOption(item);\n if (option) {\n byId.set(option.id, option);\n }\n }\n\n const missingIds = includeRoleIds.filter((id) => id && !byId.has(id));\n await Promise.all(\n missingIds.map(async (id) => {\n try {\n const row = (await roleData.byKey(id)) as Record<string, unknown> | null;\n const option = this.toRoleOption(row);\n if (option) {\n byId.set(option.id, option);\n }\n } catch {\n /* role missing or inaccessible */\n }\n }),\n );\n\n return byId;\n }\n\n private toRoleOption(item: Record<string, unknown> | null | undefined): UserRoleOption | null {\n const id = String(item?.['id'] ?? '').trim();\n if (!id) {\n return null;\n }\n const scopeRaw = item?.['scopeInfo'];\n const scope =\n scopeRaw && typeof scopeRaw === 'object' ? (scopeRaw as Record<string, unknown>) : undefined;\n return {\n id,\n title: String(item?.['title'] ?? item?.['name'] ?? ''),\n name: typeof item?.['name'] === 'string' ? item['name'] : undefined,\n scopeInfo: scope\n ? {\n tenantId: typeof scope['tenantId'] === 'string' ? scope['tenantId'] : undefined,\n applicationId:\n typeof scope['applicationId'] === 'string' ? scope['applicationId'] : undefined,\n }\n : undefined,\n };\n }\n\n async findGrant(\n userId: string,\n tenantId: string,\n applicationId: string | undefined,\n ): Promise<UserRoleGrantRow | null> {\n const result = await this.userRoleData().query({\n skip: 0,\n take: 50,\n filter: {\n logic: 'and',\n filters: [\n { field: 'userId', operator: { type: 'equal' }, value: userId },\n { field: 'scopeInfo.tenantId', operator: { type: 'equal' }, value: tenantId },\n ],\n },\n } as never);\n\n const items = (result?.items ?? []) as UserRoleGrantRow[];\n if (items.length === 0) {\n return null;\n }\n\n if (applicationId) {\n const appMatch = items.find((item) => item.scopeInfo?.applicationId === applicationId);\n if (appMatch) {\n return appMatch;\n }\n }\n\n const tenantWide = items.find((item) => !item.scopeInfo?.applicationId);\n return tenantWide ?? items[0] ?? null;\n }\n\n //#endregion\n\n //#region ----- Persist -----\n\n async saveGrant(options: SaveUserRoleGrantOptions): Promise<Record<string, unknown>> {\n const existingState = options.existing?.stateInfo;\n if (existingState?.isSystem === true || existingState?.isImmutable === true) {\n throw new Error('System user role grants are readonly.');\n }\n\n const entityKey = `${RootConfig.module.name}.${RootConfig.entities.userRole.name}`;\n const [moduleName, entityName] = entityKey.split('.');\n const entityRef = await this.entityRegistry.resolve(moduleName, entityName);\n\n const scopeInfo = {\n tenantId: options.tenantId,\n ...(options.existing?.scopeInfo?.applicationId\n ? { applicationId: options.existing.scopeInfo.applicationId }\n : options.applicationId\n ? { applicationId: options.applicationId }\n : {}),\n };\n\n if (options.existing?.id) {\n const updatePayload = {\n ...options.existing,\n userId: options.userId,\n roleIds: options.roleIds,\n scopeInfo,\n };\n return (\n entityRef.commands?.update?.execute as (data: Record<string, unknown>) => Promise<Record<string, unknown>>\n )(updatePayload);\n }\n\n const createPayload = {\n userId: options.userId,\n roleIds: options.roleIds,\n scopeInfo,\n };\n return (\n entityRef.commands?.create?.execute as (data: Record<string, unknown>) => Promise<Record<string, unknown>>\n )(createPayload);\n }\n\n notifyGrantModified(saved: Record<string, unknown>): void {\n const entityKey = `${RootConfig.module.name}.${RootConfig.entities.userRole.name}`;\n dispatchEntityModifiedSideEffects(this.entityEvents, entityKey, saved);\n }\n\n //#endregion\n}\n\n//#endregion\n"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- export { A as AXMAssignPermissionsCommand, a as AXMDeviceSessionsService, b as AXMPermissionsModule, c as AXMRolePermissionGrantService, d as AXMRolePermissionsPageComponent, e as AXMRolePermissionsPageComponentProvider, f as AXMSecurityManagementModule, g as AXPPermissionsEditorComponent, h as AXPPermissionsWidget, i as AXPPermissionsWidgetColumnComponent, j as AXPPermissionsWidgetEditComponent, k as AXPPermissionsWidgetViewComponent } from './acorex-platform-module-security-management-client-acorex-platform-module-security-management-client-BSGZRsGz.mjs';
1
+ export { A as AXMAssignPermissionsCommand, a as AXMDeviceSessionsService, b as AXMPermissionsModule, c as AXMRolePermissionGrantService, d as AXMRolePermissionsPageComponent, e as AXMRolePermissionsPageComponentProvider, f as AXMSecurityManagementModule, g as AXPPermissionsEditorComponent, h as AXPPermissionsWidget, i as AXPPermissionsWidgetColumnComponent, j as AXPPermissionsWidgetEditComponent, k as AXPPermissionsWidgetViewComponent } from './acorex-platform-module-security-management-client-acorex-platform-module-security-management-client-B61j_cJF.mjs';
2
2
  //# sourceMappingURL=acorex-platform-module-security-management-client.mjs.map
@@ -109,6 +109,10 @@
109
109
  "title": "Invitation Scope",
110
110
  "description": "Internal filter marker for the Users Invitations view."
111
111
  },
112
+ "membership-invitation-source": {
113
+ "title": "Invitation Source",
114
+ "description": "Whether the current-tenant membership is an invite or a join request (read from TenantUser)."
115
+ },
112
116
  "password-changed-at": {
113
117
  "title": "Password Changed At",
114
118
  "description": "When the password was last changed."
@@ -176,7 +180,10 @@
176
180
  "fields": {
177
181
  "email": "Email",
178
182
  "display-name": "Display Name",
179
- "applications": "Applications"
183
+ "applications": "Applications",
184
+ "application": "Application",
185
+ "application-roles": "Applications And Roles",
186
+ "roles": "Roles"
180
187
  },
181
188
  "existing-warning-title": "User Already Exists",
182
189
  "existing-warning-message": "A user with email {{email}} already exists. Send an invitation to join this tenant?",
@@ -189,7 +196,9 @@
189
196
  "description": "Failed to invite the user."
190
197
  },
191
198
  "errors": {
192
- "email-required": "Email is required."
199
+ "email-required": "Email is required.",
200
+ "application-required": "Select at least one application.",
201
+ "roles-required": "Each selected application must include at least one role."
193
202
  }
194
203
  },
195
204
  "create-in-tenant": {
@@ -203,7 +212,10 @@
203
212
  "username": "Username",
204
213
  "display-name": "Display Name",
205
214
  "password": "Password",
206
- "applications": "Applications"
215
+ "applications": "Applications",
216
+ "application": "Application",
217
+ "application-roles": "Applications And Roles",
218
+ "roles": "Roles"
207
219
  },
208
220
  "success": {
209
221
  "title": "User Created",
@@ -214,7 +226,9 @@
214
226
  "description": "Failed to create the user."
215
227
  },
216
228
  "errors": {
217
- "identity-required": "Email or username is required."
229
+ "identity-required": "Email or username is required.",
230
+ "application-required": "Select at least one application.",
231
+ "roles-required": "Each selected application must include at least one role."
218
232
  }
219
233
  },
220
234
  "resend-invitation": {
@@ -242,6 +256,47 @@
242
256
  "title": "Cancel Failed",
243
257
  "description": "Failed to cancel the invitation."
244
258
  }
259
+ },
260
+ "approve-join-request": {
261
+ "title": "Approve Join Request",
262
+ "confirm-title": "Approve Join Request",
263
+ "confirm-message": "Approve the membership request for {{user}}?",
264
+ "dialog": {
265
+ "title": "Approve Join Request",
266
+ "submit": "Approve"
267
+ },
268
+ "fields": {
269
+ "application": "Application",
270
+ "application-roles": "Applications And Roles",
271
+ "roles": "Roles"
272
+ },
273
+ "errors": {
274
+ "application-required": "Select at least one application.",
275
+ "roles-required": "Each selected application must include at least one role."
276
+ },
277
+ "success": {
278
+ "title": "Request Approved",
279
+ "description": "The membership request was approved."
280
+ },
281
+ "error": {
282
+ "title": "Approve Failed",
283
+ "description": "Failed to approve the membership request.",
284
+ "not-pending": "This membership request is no longer pending."
285
+ }
286
+ },
287
+ "reject-join-request": {
288
+ "title": "Reject Join Request",
289
+ "confirm-title": "Reject Join Request",
290
+ "confirm-message": "Reject the membership request for {{user}}?",
291
+ "success": {
292
+ "title": "Request Rejected",
293
+ "description": "The membership request was rejected."
294
+ },
295
+ "error": {
296
+ "title": "Reject Failed",
297
+ "description": "Failed to reject the membership request.",
298
+ "not-pending": "This membership request is no longer pending."
299
+ }
245
300
  }
246
301
  },
247
302
  "groups": {
@@ -440,6 +495,11 @@
440
495
  "sessions": "Sessions",
441
496
  "device-sessions": "Device Sessions"
442
497
  },
498
+ "views": {
499
+ "tenant-sessions": {
500
+ "title": "Sessions"
501
+ }
502
+ },
443
503
  "entities": {
444
504
  "session": {
445
505
  "title": "Session",
@@ -503,6 +563,14 @@
503
563
  "manage": {
504
564
  "title": "Manage Device Sessions",
505
565
  "description": "Full device session management access"
566
+ },
567
+ "device-sessions": {
568
+ "actions": {
569
+ "terminate": {
570
+ "title": "Terminate Device Session",
571
+ "description": "Terminate active device sessions"
572
+ }
573
+ }
506
574
  }
507
575
  }
508
576
  },
@@ -764,5 +832,24 @@
764
832
  "title": "Verified At"
765
833
  }
766
834
  }
835
+ },
836
+ "settings": {
837
+ "group": {
838
+ "title": "Security Management",
839
+ "description": "Platform settings for users, roles, and access."
840
+ },
841
+ "users": {
842
+ "title": "Users",
843
+ "description": "How new users are added from the Users list.",
844
+ "provisioning-mode": {
845
+ "title": "Add User Actions",
846
+ "description": "Choose Create, Invite, or both. When both are enabled, they appear in the secondary actions menu.",
847
+ "options": {
848
+ "create": "Create",
849
+ "invite": "Invite",
850
+ "both": "Both"
851
+ }
852
+ }
853
+ }
767
854
  }
768
855
  }