@open-mercato/core 0.10.1-develop.7983.1.fd91207efe → 0.10.1-develop.7994.1.c9f31972aa

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 (40) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/modules/auth/commands/users.js +27 -23
  3. package/dist/modules/auth/commands/users.js.map +2 -2
  4. package/dist/modules/customers/commands/companies.js +10 -1
  5. package/dist/modules/customers/commands/companies.js.map +2 -2
  6. package/dist/modules/customers/docs/issue-8675-ownership-assessment.md +30 -0
  7. package/dist/modules/promotions/backend/promotions/[id]/page.js +3 -2
  8. package/dist/modules/promotions/backend/promotions/[id]/page.js.map +2 -2
  9. package/dist/modules/promotions/backend/promotions/page.js +3 -7
  10. package/dist/modules/promotions/backend/promotions/page.js.map +2 -2
  11. package/dist/modules/promotions/components/promotionDates.js +19 -0
  12. package/dist/modules/promotions/components/promotionDates.js.map +7 -0
  13. package/dist/modules/promotions/data/validators.js +8 -1
  14. package/dist/modules/promotions/data/validators.js.map +2 -2
  15. package/dist/modules/wms/components/backend/CompletePutawayTaskDialog.js +2 -2
  16. package/dist/modules/wms/components/backend/CompletePutawayTaskDialog.js.map +2 -2
  17. package/dist/modules/wms/components/backend/CreateAsnDialog.js +5 -5
  18. package/dist/modules/wms/components/backend/CreateAsnDialog.js.map +2 -2
  19. package/dist/modules/wms/components/backend/ReceiveAsnLineDialog.js +1 -1
  20. package/dist/modules/wms/components/backend/ReceiveAsnLineDialog.js.map +2 -2
  21. package/package.json +7 -7
  22. package/src/modules/auth/commands/users.ts +28 -25
  23. package/src/modules/customers/commands/companies.ts +11 -1
  24. package/src/modules/customers/docs/issue-8675-ownership-assessment.md +30 -0
  25. package/src/modules/promotions/backend/promotions/[id]/page.tsx +3 -2
  26. package/src/modules/promotions/backend/promotions/page.tsx +3 -8
  27. package/src/modules/promotions/components/promotionDates.ts +19 -0
  28. package/src/modules/promotions/data/validators.ts +9 -1
  29. package/src/modules/promotions/i18n/de.json +6 -6
  30. package/src/modules/promotions/i18n/es.json +6 -6
  31. package/src/modules/promotions/i18n/ko.json +6 -6
  32. package/src/modules/promotions/i18n/pl.json +6 -6
  33. package/src/modules/wms/components/backend/CompletePutawayTaskDialog.tsx +2 -2
  34. package/src/modules/wms/components/backend/CreateAsnDialog.tsx +5 -5
  35. package/src/modules/wms/components/backend/ReceiveAsnLineDialog.tsx +1 -1
  36. package/src/modules/wms/i18n/de.json +173 -165
  37. package/src/modules/wms/i18n/en.json +8 -0
  38. package/src/modules/wms/i18n/es.json +175 -167
  39. package/src/modules/wms/i18n/ko.json +175 -167
  40. package/src/modules/wms/i18n/pl.json +172 -164
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/auth/commands/users.ts"],
4
- "sourcesContent": ["import type { CommandHandler, CommandReplayAuthorizationArgs, CommandUndoLogEntry } from '@open-mercato/shared/lib/commands'\nimport { registerCommand } from '@open-mercato/shared/lib/commands'\nimport {\n parseWithCustomFields,\n setCustomFieldsIfAny,\n emitCrudSideEffects,\n emitCrudUndoSideEffects,\n buildChanges,\n requireId,\n} from '@open-mercato/shared/lib/commands/helpers'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport type { CrudEventsConfig, CrudIndexerConfig } from '@open-mercato/shared/lib/crud/types'\nimport type { DataEngine } from '@open-mercato/shared/lib/data/engine'\nimport type { CommandRuntimeContext } from '@open-mercato/shared/lib/commands'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { UniqueConstraintViolationException, LockMode } from '@mikro-orm/core'\nimport type { EntityManager, FilterQuery } from '@mikro-orm/postgresql'\nimport {\n User,\n UserRole,\n Role,\n UserAcl,\n Session,\n PasswordReset,\n UserSidebarPreference,\n SidebarVariant,\n} from '@open-mercato/core/modules/auth/data/entities'\nimport { Organization } from '@open-mercato/core/modules/directory/data/entities'\nimport { resolveOrganizationScope } from '@open-mercato/core/modules/directory/utils/organizationScope'\nimport { E } from '#generated/entities.ids.generated'\nimport { z } from 'zod'\nimport {\n loadCustomFieldSnapshot,\n buildCustomFieldResetMap,\n diffCustomFieldChanges,\n} from '@open-mercato/shared/lib/commands/customFieldSnapshots'\nimport { extractUndoPayload, type UndoPayload } from '@open-mercato/shared/lib/commands/undo'\nimport { resolveRedoSnapshot } from '@open-mercato/shared/lib/commands/redo'\nimport { withAtomicFlush } from '@open-mercato/shared/lib/commands/flush'\nimport {\n getTransactionLifetime,\n onTransactionLifetimeComplete,\n} from '@open-mercato/shared/lib/commands/transaction-lifetime'\nimport { normalizeTenantId } from '@open-mercato/core/modules/auth/lib/tenantAccess'\nimport { computeEmailHash, emailHashLookupValues } from '@open-mercato/core/modules/auth/lib/emailHash'\nimport { findOneWithDecryption, findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport { buildNotificationFromType } from '@open-mercato/core/modules/notifications/lib/notificationBuilder'\nimport { resolveNotificationService } from '@open-mercato/core/modules/notifications/lib/notificationService'\nimport notificationTypes from '@open-mercato/core/modules/auth/notifications'\nimport { buildPasswordSchema } from '@open-mercato/shared/lib/auth/passwordPolicy'\nimport { emitAuthEvent } from '@open-mercato/core/modules/auth/events'\nimport { sendEmail } from '@open-mercato/shared/lib/email/send'\nimport InviteUserEmail from '@open-mercato/core/modules/auth/emails/InviteUserEmail'\nimport { INVITE_TOKEN_TTL_MS } from '@open-mercato/core/modules/auth/lib/inviteToken'\nimport { getSecurityEmailBaseUrl } from '@open-mercato/shared/lib/url'\nimport { generateAuthToken, hashAuthToken } from '@open-mercato/core/modules/auth/lib/tokenHash'\nimport { normalizeDisplayNameInput } from '@open-mercato/core/modules/auth/lib/displayName'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\nimport {\n assertActorCanAssignUserDestination,\n assertActorCanAccessUserTarget,\n assertActorCanGrantAcl,\n assertActorCanGrantRoleTokens,\n assertActorCanModifySuperAdminUserTarget,\n resolveUserDestinationRoles,\n throwUserDestinationOrganizationNotFound,\n} from '@open-mercato/core/modules/auth/lib/grantChecks'\nimport type { RbacService } from '@open-mercato/core/modules/auth/services/rbacService'\nimport {\n assertReplaySnapshotMatches,\n denyCredentialReplay,\n extractStoredReplayInput,\n hasStoredPasswordInput,\n lockReplayAuthorizationState,\n rerunReplayTransactionGuardAfterLocks,\n requireCurrentReplayFeature,\n requireTransactionalReplayEntityManager,\n} from '@open-mercato/core/modules/auth/lib/commandReplay'\nimport { lockUserRoleWriterAuthorizationState } from '@open-mercato/core/modules/auth/lib/authorizationStateLocks'\n\nconst logger = createLogger('auth').child({ component: 'users-commands' })\nconst USER_REDO_LOG = Symbol('auth.users.redoLog')\nconst replayProtectedRoleIdsByTenant = new WeakMap<object, ReadonlyMap<string, readonly string[]>>()\n\ntype UserReplayRuntimeContext = CommandRuntimeContext & {\n [USER_REDO_LOG]?: CommandUndoLogEntry\n}\n\nfunction withUserRedoLog(\n ctx: CommandRuntimeContext,\n logEntry: CommandUndoLogEntry,\n): UserReplayRuntimeContext {\n return { ...ctx, [USER_REDO_LOG]: logEntry }\n}\n\nfunction resolveCommandEm(ctx: CommandRuntimeContext, forkWhenUnbound = false): EntityManager {\n if (ctx.transactionalEm) return ctx.transactionalEm\n const em = ctx.container.resolve('em') as EntityManager\n return forkWhenUnbound ? em.fork() : em\n}\n\ntype SerializedUser = {\n email: string\n organizationId: string | null\n tenantId: string | null\n roles: string[]\n name: string | null\n isConfirmed: boolean\n custom?: Record<string, unknown>\n}\n\ntype UserAclSnapshot = {\n tenantId: string\n features: string[] | null\n isSuperAdmin: boolean\n organizations: string[] | null\n}\n\ntype UserUndoSnapshot = {\n id: string\n email: string\n organizationId: string | null\n tenantId: string | null\n passwordHash?: string | null\n name: string | null\n isConfirmed: boolean\n roles: string[]\n acls: UserAclSnapshot[]\n custom?: Record<string, unknown>\n}\n\ntype UserSnapshots = {\n view: SerializedUser\n undo: UserUndoSnapshot\n}\n\nfunction resolveActorTenantScope(ctx: CommandRuntimeContext): string | null {\n if (ctx.systemActor === true) return null\n const auth = ctx.auth\n if (!auth) return null\n if ((auth as { isSuperAdmin?: boolean }).isSuperAdmin === true) return null\n const actorTenantId = normalizeTenantId(auth.tenantId ?? null) ?? null\n return actorTenantId\n}\n\nfunction assertTargetTenantInScope(actorTenantScope: string | null, targetTenantId: unknown, notFoundError: string): void {\n if (!actorTenantScope) return\n const targetTenant = normalizeTenantId(targetTenantId) ?? null\n if (!targetTenant || targetTenant !== actorTenantScope) {\n throw new CrudHttpError(404, { error: notFoundError })\n }\n}\n\nasync function assertCommandActorCanAssignUserDestination(\n ctx: CommandRuntimeContext,\n em: EntityManager,\n destination: { destinationTenantId: string | null; destinationOrganizationId: string; roles: Role[] },\n): Promise<void> {\n const rbacService = ctx.container.resolve('rbacService') as RbacService\n const actorIsSuperAdmin = ctx.systemActor === true || ctx.auth?.isSuperAdmin === true\n const organizationScope = ctx.organizationScope?.tenantId === destination.destinationTenantId\n ? ctx.organizationScope\n : !actorIsSuperAdmin && ctx.auth?.sub && destination.destinationTenantId\n ? await resolveOrganizationScope({\n em,\n rbac: rbacService,\n auth: ctx.auth,\n tenantId: destination.destinationTenantId,\n })\n : null\n await assertActorCanAssignUserDestination({\n em,\n rbacService,\n actorUserId: ctx.auth?.sub,\n actorIsSuperAdmin,\n tenantId: ctx.auth?.tenantId ?? null,\n organizationId: ctx.auth?.orgId ?? null,\n allowedOrganizationIds: organizationScope?.allowedIds,\n destinationTenantId: destination.destinationTenantId,\n destinationOrganizationId: destination.destinationOrganizationId,\n roles: destination.roles,\n })\n}\n\nconst passwordSchema = buildPasswordSchema()\n\nconst displayNameSchema = z.preprocess(\n normalizeDisplayNameInput,\n z.string().trim().min(1).max(120).nullable().optional(),\n)\n\nconst createSchema = z.object({\n email: z.string().email(),\n name: displayNameSchema,\n password: passwordSchema.optional(),\n sendInviteEmail: z.boolean().optional(),\n organizationId: z.string().uuid(),\n roles: z.array(z.string()).optional(),\n}).refine(\n (data) => data.password || data.sendInviteEmail,\n { message: 'Either password or sendInviteEmail is required', path: ['password'] },\n)\n\nconst updateSchema = z.object({\n id: z.string().uuid(),\n email: z.string().email().optional(),\n name: displayNameSchema,\n password: passwordSchema.optional(),\n organizationId: z.string().uuid().optional(),\n roles: z.array(z.string()).optional(),\n isConfirmed: z.boolean().optional(),\n})\n\nexport const userCrudEvents: CrudEventsConfig = {\n module: 'auth',\n entity: 'user',\n persistent: true,\n buildPayload: (ctx) => ({\n id: ctx.identifiers.id,\n organizationId: ctx.identifiers.organizationId,\n tenantId: ctx.identifiers.tenantId,\n }),\n}\n\nexport const userCrudIndexer: CrudIndexerConfig = {\n entityType: E.auth.user,\n buildUpsertPayload: (ctx) => ({\n entityType: E.auth.user,\n recordId: ctx.identifiers.id,\n organizationId: ctx.identifiers.organizationId,\n tenantId: ctx.identifiers.tenantId,\n }),\n buildDeletePayload: (ctx) => ({\n entityType: E.auth.user,\n recordId: ctx.identifiers.id,\n organizationId: ctx.identifiers.organizationId,\n tenantId: ctx.identifiers.tenantId,\n }),\n}\n\nasync function notifyRoleChanges(\n ctx: CommandRuntimeContext,\n user: User,\n assignedRoles: string[],\n revokedRoles: string[],\n): Promise<void> {\n const tenantId = user.tenantId ? String(user.tenantId) : null\n if (!tenantId) return\n const organizationId = user.organizationId ? String(user.organizationId) : null\n\n const createNotifications = async () => {\n const notificationService = resolveNotificationService(ctx.container)\n if (assignedRoles.length) {\n const assignedType = notificationTypes.find((type) => type.type === 'auth.role.assigned')\n if (assignedType) {\n const notificationInput = buildNotificationFromType(assignedType, {\n recipientUserId: String(user.id),\n sourceEntityType: 'auth:user',\n sourceEntityId: String(user.id),\n })\n await notificationService.create(notificationInput, { tenantId, organizationId })\n }\n }\n\n if (revokedRoles.length) {\n const revokedType = notificationTypes.find((type) => type.type === 'auth.role.revoked')\n if (revokedType) {\n const notificationInput = buildNotificationFromType(revokedType, {\n recipientUserId: String(user.id),\n sourceEntityType: 'auth:user',\n sourceEntityId: String(user.id),\n })\n await notificationService.create(notificationInput, { tenantId, organizationId })\n }\n }\n }\n const safelyCreateNotifications = async () => {\n try {\n await createNotifications()\n } catch (err) {\n logger.error('Failed to create notification', { err })\n }\n }\n\n const transactionalEm = ctx.transactionalEm\n if (transactionalEm && getTransactionLifetime(transactionalEm)) {\n onTransactionLifetimeComplete(transactionalEm, async (outcome) => {\n if (outcome === 'committed') await safelyCreateNotifications()\n })\n return\n }\n\n await safelyCreateNotifications()\n}\n\ntype CreateUserResult = { user: User; warning?: 'invite_email_failed' }\n\nconst createUserCommand: CommandHandler<Record<string, unknown>, CreateUserResult> = {\n id: 'auth.users.create',\n atomicReplay: true,\n stabilizeReplay: (params) => stabilizeUserReplay('create', params),\n authorizeReplay: (params) => authorizeUserReplay('create', params),\n async execute(rawInput, ctx) {\n const { parsed, custom } = parseWithCustomFields(createSchema, rawInput)\n const em = resolveCommandEm(ctx)\n\n const organization = await findOneWithDecryption(\n em,\n Organization,\n { id: parsed.organizationId },\n { populate: ['tenant'] },\n { tenantId: null, organizationId: parsed.organizationId },\n )\n if (!organization) throw new CrudHttpError(400, { error: 'Organization not found' })\n const tenantId = organization.tenant?.id ? String(organization.tenant.id) : null\n assertTargetTenantInScope(resolveActorTenantScope(ctx), tenantId, 'Organization not found')\n await assertCommandActorCanAssignUserDestination(ctx, em, {\n destinationTenantId: tenantId,\n destinationOrganizationId: parsed.organizationId,\n roles: await resolveUserDestinationRoles({\n em,\n destinationTenantId: tenantId,\n roleTokens: parsed.roles ?? [],\n }),\n })\n\n const emailHash = computeEmailHash(parsed.email)\n // Email is unique per-tenant, not globally (see Migration20260610120000:\n // users_tenant_email_hash_uniq). Scope the duplicate check to the target tenant so the same\n // email may legitimately exist in other tenants without blocking creation or leaking\n // cross-tenant account existence (#2934).\n const duplicate = await findOneWithDecryption(em, User, { $or: [{ email: parsed.email }, { emailHash: { $in: emailHashLookupValues(parsed.email) } }], deletedAt: null, tenantId } as any, {}, { tenantId: null, organizationId: null })\n if (duplicate) await throwDuplicateEmailError()\n\n let passwordHash: string | null = null\n if (parsed.password) {\n const { hash } = await import('bcryptjs')\n passwordHash = await hash(parsed.password, 10)\n }\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n let user: User\n try {\n user = await de.createOrmEntity({\n entity: User,\n data: {\n email: parsed.email,\n name: parsed.name,\n emailHash,\n passwordHash,\n isConfirmed: true,\n organizationId: parsed.organizationId,\n tenantId,\n },\n })\n } catch (error) {\n if (isUniqueViolation(error)) await throwDuplicateEmailError()\n throw error\n }\n\n let assignedRoles: string[] = []\n if (Array.isArray(parsed.roles) && parsed.roles.length) {\n await withAtomicFlush(em, [\n async () => syncUserRoles(em, user, parsed.roles ?? [], tenantId),\n ], { transaction: true, label: 'auth.users.create.roles' })\n assignedRoles = await loadUserRoleNames(em, String(user.id))\n }\n\n await setCustomFieldsIfAny({\n dataEngine: de,\n entityId: E.auth.user,\n recordId: String(user.id),\n organizationId: user.organizationId ? String(user.organizationId) : null,\n tenantId: tenantId,\n values: custom,\n })\n\n let inviteEmailSent = false\n if (parsed.sendInviteEmail) {\n const inviteResult = await sendInviteToUser(em, user)\n inviteEmailSent = inviteResult.emailSent\n }\n\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'created',\n entity: user,\n identifiers: {\n id: String(user.id),\n organizationId: user.organizationId ? String(user.organizationId) : null,\n tenantId,\n },\n events: userCrudEvents,\n indexer: userCrudIndexer,\n })\n\n if (assignedRoles.length && !parsed.sendInviteEmail) {\n await notifyRoleChanges(ctx, user, assignedRoles, [])\n }\n\n const warning = (parsed.sendInviteEmail && !inviteEmailSent) ? 'invite_email_failed' as const : undefined\n\n return { user, warning }\n },\n captureAfter: async (_input, { user }, ctx) => {\n const em = resolveCommandEm(ctx, true)\n const roles = await loadUserRoleNames(em, String(user.id))\n const custom = await loadUserCustomSnapshot(\n em,\n String(user.id),\n user.tenantId ? String(user.tenantId) : null,\n user.organizationId ? String(user.organizationId) : null\n )\n return serializeUser(user, roles, custom)\n },\n buildLog: async ({ input, result: { user }, ctx }) => {\n const { translate } = await resolveTranslations()\n const em = resolveCommandEm(ctx, true)\n const roles = await loadUserRoleNames(em, String(user.id))\n const custom = await loadUserCustomSnapshot(\n em,\n String(user.id),\n user.tenantId ? String(user.tenantId) : null,\n user.organizationId ? String(user.organizationId) : null\n )\n const snapshot = captureUserSnapshots(user, roles, undefined, custom)\n // Creating a user is undoable no matter how the account got its credentials \u2014\n // the undo only deletes the row, and it needs no secret to do so. What must\n // never reach `action_logs` is the credential itself: the plaintext `password`\n // the caller sent (dropped from the redo input) and the derived `passwordHash`\n // (dropped from the undo snapshot). A redo therefore restores the original row\n // and id WITHOUT a password, and the account needs a reset to sign in again.\n const { password: _plaintextPassword, ...redoInput } = input\n return {\n redoInput,\n actionLabel: translate('auth.audit.users.create', 'Create user'),\n resourceKind: 'auth.user',\n resourceId: String(user.id),\n tenantId: user.tenantId ? String(user.tenantId) : null,\n organizationId: user.organizationId ? String(user.organizationId) : null,\n snapshotAfter: snapshot.view,\n payload: {\n undo: {\n after: withoutPasswordHash(snapshot.undo),\n },\n },\n }\n },\n undo: async ({ input, logEntry, ctx }) => {\n const userId = typeof logEntry?.resourceId === 'string' ? logEntry.resourceId : null\n if (!userId) return\n const snapshot = logEntry?.snapshotAfter as SerializedUser | undefined\n const em = resolveCommandEm(ctx)\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n\n // Evaluate the floor against the user's CURRENT tenant, not the one recorded at\n // creation. A user moved to another tenant after being created would otherwise be\n // checked against the origin tenant \u2014 where they no longer hold anything \u2014 and the\n // undo would hard-delete the destination tenant's last administrator unchecked.\n // The create snapshot is only a fallback for a row that is already gone.\n let removed: User | null = null\n await withAtomicFlush(em, [\n async () => {\n await authorizeUserReplayAtMutation('create', {\n operation: 'undo',\n input,\n ctx,\n logEntry,\n })\n const current = await findOneWithDecryption(em, User, { id: userId, deletedAt: null }, {}, { tenantId: null, organizationId: null })\n const floorTenantId = current?.tenantId ? String(current.tenantId) : (snapshot?.tenantId ?? null)\n\n // Undoing a create hard-deletes the user, so it can strip a tenant's last active\n // admin exactly like `auth.users.delete` can \u2014 promote a second admin, delete the\n // first, then undo the promotion's create. Same guard applies.\n await enforceProtectedRoleFloor(\n em,\n floorTenantId,\n userId,\n { deleting: true },\n ctx,\n requireReplayProtectedRoleIds(em, floorTenantId),\n )\n\n await lockUserRoleWriterAuthorizationState(em, { userIds: [userId], roleIds: [] })\n await em.nativeDelete(UserAcl, { user: userId })\n await em.nativeDelete(UserRole, { user: userId })\n await em.nativeDelete(Session, { user: userId })\n await em.nativeDelete(PasswordReset, { user: userId })\n await em.nativeDelete(UserSidebarPreference, { user: userId })\n await em.nativeDelete(SidebarVariant, { user: userId })\n\n if (snapshot?.custom && Object.keys(snapshot.custom).length) {\n const reset = buildCustomFieldResetMap(undefined, snapshot.custom)\n if (Object.keys(reset).length) {\n await setCustomFieldsIfAny({\n dataEngine: de,\n entityId: E.auth.user,\n recordId: userId,\n organizationId: snapshot.organizationId,\n tenantId: snapshot.tenantId,\n values: reset,\n notify: false,\n })\n }\n }\n removed = await de.deleteOrmEntity({\n entity: User,\n where: { id: userId, deletedAt: null } as FilterQuery<User>,\n soft: false,\n })\n },\n ], { transaction: true, label: 'auth.users.create.undo' })\n\n await emitCrudUndoSideEffects({\n dataEngine: de,\n action: 'deleted',\n entity: removed,\n identifiers: {\n id: userId,\n organizationId: snapshot?.organizationId ?? null,\n tenantId: snapshot?.tenantId ?? null,\n },\n events: userCrudEvents,\n indexer: userCrudIndexer,\n })\n\n await invalidateUserCache(ctx, userId)\n },\n // Restores the original stable id (#2506). The after-snapshot deliberately\n // carries no `passwordHash` (see buildLog), so a redone account comes back\n // without a credential and needs a password reset \u2014 redo never fabricates one\n // and never resurrects a hash from the audit log.\n redo: async ({ input, logEntry, ctx }) => {\n const after = resolveRedoSnapshot<UserUndoSnapshot>(logEntry)\n if (!after) throw new CrudHttpError(400, { error: '[internal] redo snapshot unavailable for user create' })\n const em = resolveCommandEm(ctx)\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n const emailHash = computeEmailHash(after.email)\n\n let user: User | null = null\n await withAtomicFlush(em, [\n async () => {\n await authorizeUserReplayAtMutation('create', {\n operation: 'redo',\n input,\n ctx,\n logEntry,\n })\n user = await findOneWithDecryption(em, User, { id: after.id }, {}, { tenantId: null, organizationId: null })\n if (user) {\n user.deletedAt = null\n user.email = after.email\n user.emailHash = emailHash\n user.organizationId = after.organizationId ?? null\n user.tenantId = after.tenantId ?? null\n // Only overwrite the credential when the snapshot actually recorded one;\n // an absent key means \"not captured\", never \"clear the password\".\n if ('passwordHash' in after) user.passwordHash = after.passwordHash ?? null\n user.name = after.name ?? null\n user.isConfirmed = after.isConfirmed\n await em.flush()\n } else {\n user = await de.createOrmEntity({\n entity: User,\n data: {\n id: after.id,\n email: after.email,\n emailHash,\n organizationId: after.organizationId ?? null,\n tenantId: after.tenantId ?? null,\n passwordHash: after.passwordHash ?? null,\n name: after.name ?? null,\n isConfirmed: after.isConfirmed,\n },\n })\n }\n\n if (!user) return\n\n await lockUserRoleWriterAuthorizationState(em, { userIds: [after.id], roleIds: [] })\n await em.nativeDelete(UserRole, { user: after.id })\n await syncUserRoles(em, user, after.roles, after.tenantId)\n await restoreUserAcls(em, user, after.acls)\n\n if (after.custom && Object.keys(after.custom).length) {\n const reset = buildCustomFieldResetMap(after.custom, undefined)\n if (Object.keys(reset).length) {\n await setCustomFieldsIfAny({\n dataEngine: de,\n entityId: E.auth.user,\n recordId: after.id,\n organizationId: after.organizationId ?? null,\n tenantId: after.tenantId ?? null,\n values: reset,\n notify: false,\n })\n }\n }\n },\n ], { transaction: true })\n\n if (!user) throw new CrudHttpError(400, { error: '[internal] redo failed to restore user row' })\n\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'created',\n entity: user,\n identifiers: {\n id: after.id,\n organizationId: after.organizationId ?? null,\n tenantId: after.tenantId ?? null,\n },\n events: userCrudEvents,\n indexer: userCrudIndexer,\n })\n\n await invalidateUserCache(ctx, after.id)\n\n return { user }\n },\n}\n\nasync function sendInviteToUser(\n em: EntityManager,\n user: User,\n): Promise<{ emailSent: boolean }> {\n const rawToken = generateAuthToken()\n const tokenHash = hashAuthToken(rawToken)\n const expiresAt = new Date(Date.now() + INVITE_TOKEN_TTL_MS)\n const row = em.create(PasswordReset, { user, token: tokenHash, expiresAt, createdAt: new Date() })\n await em.persist(row).flush()\n\n const base = getSecurityEmailBaseUrl()\n const inviteUrl = `${base}/reset/${rawToken}`\n\n const { translate } = await resolveTranslations()\n const subject = translate('auth.email.invite.subject', 'You have been invited')\n const copy = {\n preview: translate('auth.email.invite.preview', 'Set up your account'),\n title: translate('auth.email.invite.title', 'You have been invited'),\n body: translate('auth.email.invite.body', 'An administrator has created an account for you. Click the link below to set your password. This link will expire in 48 hours.'),\n cta: translate('auth.email.invite.cta', 'Set up your password'),\n hint: translate('auth.email.invite.hint', 'If you did not expect this invitation, you can safely ignore this email.'),\n }\n\n let emailSent = true\n try {\n await sendEmail({\n to: user.email,\n subject,\n react: InviteUserEmail({ inviteUrl, copy }),\n tenantId: user.tenantId ? String(user.tenantId) : undefined,\n organizationId: user.organizationId ? String(user.organizationId) : null,\n })\n } catch (err) {\n logger.error('Failed to send invitation email', { err })\n emailSent = false\n }\n\n return { emailSent }\n}\n\nfunction isUniqueViolation(error: unknown): boolean {\n if (error instanceof UniqueConstraintViolationException) return true\n if (!error || typeof error !== 'object') return false\n const code = (error as { code?: string }).code\n if (code === '23505') return true\n const messageRaw = (error as { message?: string })?.message\n const message = typeof messageRaw === 'string' ? messageRaw : ''\n return message.toLowerCase().includes('duplicate key')\n}\n\nconst updateUserCommand: CommandHandler<Record<string, unknown>, User> = {\n id: 'auth.users.update',\n atomicReplay: true,\n stabilizeReplay: (params) => stabilizeUserReplay('update', params),\n authorizeReplay: (params) => authorizeUserReplay('update', params),\n async prepare(rawInput, ctx) {\n const { parsed } = parseWithCustomFields(updateSchema, rawInput)\n const em = resolveCommandEm(ctx)\n const existing = await findOneWithDecryption(em, User, { id: parsed.id, deletedAt: null }, {}, { tenantId: null, organizationId: null })\n if (!existing) throw new CrudHttpError(404, { error: 'User not found' })\n assertTargetTenantInScope(resolveActorTenantScope(ctx), existing.tenantId, 'User not found')\n const roles = await loadUserRoleNames(em, parsed.id)\n const acls = await loadUserAclSnapshots(em, parsed.id)\n const custom = await loadUserCustomSnapshot(\n em,\n parsed.id,\n existing.tenantId ? String(existing.tenantId) : null,\n existing.organizationId ? String(existing.organizationId) : null\n )\n return { before: captureUserSnapshots(existing, roles, acls, custom) }\n },\n async execute(rawInput, ctx) {\n const { parsed, custom } = parseWithCustomFields(updateSchema, rawInput)\n const em = resolveCommandEm(ctx)\n const actorTenantScope = resolveActorTenantScope(ctx)\n const existing = await findOneWithDecryption(em, User, { id: parsed.id, deletedAt: null }, {}, { tenantId: null, organizationId: null })\n if (!existing) throw new CrudHttpError(404, { error: 'User not found' })\n if (actorTenantScope && existing.tenantId && String(existing.tenantId) !== actorTenantScope) {\n throw new CrudHttpError(404, { error: 'User not found' })\n }\n\n const rolesBefore = Array.isArray(parsed.roles)\n ? await loadUserRoleNames(em, parsed.id)\n : null\n\n let tenantId: string | null | undefined\n let destinationChanged = false\n if (parsed.organizationId !== undefined) {\n const organization = await findOneWithDecryption(\n em,\n Organization,\n { id: parsed.organizationId },\n { populate: ['tenant'] },\n { tenantId: null, organizationId: parsed.organizationId ?? null },\n )\n if (!organization) return throwUserDestinationOrganizationNotFound(400)\n tenantId = organization.tenant?.id ? String(organization.tenant.id) : null\n if (!tenantId) return throwUserDestinationOrganizationNotFound(400)\n const currentUser = await findOneWithDecryption(\n em,\n User,\n { id: parsed.id, deletedAt: null },\n {},\n { tenantId: null, organizationId: null },\n )\n if (!currentUser) throw new CrudHttpError(404, { error: 'User not found' })\n const currentOrganizationId = currentUser.organizationId ? String(currentUser.organizationId) : null\n const currentTenantId = currentUser.tenantId ? String(currentUser.tenantId) : null\n destinationChanged = currentOrganizationId !== parsed.organizationId || currentTenantId !== tenantId\n if (destinationChanged) {\n const destinationRoles = await resolveUserDestinationRoles({\n em,\n targetUserId: parsed.id,\n destinationTenantId: tenantId,\n roleTokens: parsed.roles,\n })\n await assertCommandActorCanAssignUserDestination(ctx, em, {\n destinationTenantId: tenantId,\n destinationOrganizationId: parsed.organizationId,\n roles: destinationRoles,\n })\n }\n }\n\n const userTenantId = existing.tenantId ? String(existing.tenantId) : null\n const targetTenantId = tenantId !== undefined ? tenantId : userTenantId\n const isTenantChanging = targetTenantId !== userTenantId\n\n // Hash password BEFORE transaction begins to avoid holding locks during CPU-heavy tasks\n let hashed: string | null = null\n let emailHash: string | null = null\n if (parsed.password) {\n const { hash } = await import('bcryptjs')\n hashed = await hash(parsed.password, 10)\n }\n if (parsed.email !== undefined) {\n emailHash = computeEmailHash(parsed.email)\n }\n\n const updateWhere: Record<string, unknown> = { id: parsed.id, deletedAt: null }\n if (actorTenantScope) updateWhere.tenantId = actorTenantScope\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n let user!: User\n\n await withAtomicFlush(em, [\n async () => {\n const redoLogEntry = (ctx as UserReplayRuntimeContext)[USER_REDO_LOG]\n if (redoLogEntry) {\n await authorizeUserReplayAtMutation('update', {\n operation: 'redo',\n input: rawInput,\n ctx,\n logEntry: redoLogEntry,\n })\n }\n const destinationRoles = parsed.roles\n ? await Promise.all(parsed.roles.map((role) => resolveRole(em, role, targetTenantId)))\n : []\n const floorOptions = {\n deactivating: parsed.isConfirmed === false || isTenantChanging,\n newRoles: parsed.roles,\n }\n const protectedRoleIds = redoLogEntry\n ? requireReplayProtectedRoleIds(em, userTenantId)\n : await discoverProtectedRoleIds(em, userTenantId, floorOptions, ctx)\n await lockUserRoleWriterAuthorizationState(em, {\n userIds: [parsed.id],\n roleIds: [\n ...destinationRoles\n .filter((role): role is Role => role !== null)\n .map((role) => String(role.id)),\n ...protectedRoleIds,\n ],\n })\n await enforceProtectedRoleFloor(\n em,\n userTenantId,\n parsed.id,\n floorOptions,\n ctx,\n protectedRoleIds,\n )\n\n // Email is unique per-tenant, not globally (see Migration20260610120000:\n // users_tenant_email_hash_uniq) \u2014 a matching email in another tenant must not block\n // the update or leak cross-tenant account existence (#2934). `targetTenantId` is the\n // tenant the user will belong to after this update, so the check follows a move.\n if (parsed.email !== undefined) {\n const duplicate = await findOneWithDecryption(\n em,\n User,\n {\n $or: [{ email: parsed.email }, { emailHash: { $in: emailHashLookupValues(parsed.email) } }],\n deletedAt: null,\n tenantId: targetTenantId,\n id: { $ne: parsed.id } as any,\n } as FilterQuery<User>,\n {},\n { tenantId: null, organizationId: null },\n )\n if (duplicate) await throwDuplicateEmailError()\n }\n\n try {\n const updated = await de.updateOrmEntity({\n entity: User,\n where: updateWhere as FilterQuery<User>,\n apply: (entity) => {\n if (parsed.email !== undefined) {\n entity.email = parsed.email\n entity.emailHash = emailHash\n }\n if (parsed.name !== undefined) {\n entity.name = parsed.name\n }\n if (parsed.organizationId !== undefined) {\n entity.organizationId = parsed.organizationId\n entity.tenantId = tenantId ?? null\n }\n if (parsed.isConfirmed !== undefined) {\n entity.isConfirmed = parsed.isConfirmed\n }\n if (hashed) entity.passwordHash = hashed\n },\n })\n if (updated) user = updated\n } catch (error) {\n if (isUniqueViolation(error)) await throwDuplicateEmailError()\n throw error\n }\n if (!user) throw new CrudHttpError(404, { error: 'User not found' })\n\n if (hashed || parsed.isConfirmed === false) {\n await em.nativeDelete(Session, { user: parsed.id })\n }\n\n if (Array.isArray(parsed.roles)) {\n await syncUserRoles(\n em,\n user,\n parsed.roles,\n user.tenantId ? String(user.tenantId) : tenantId ?? null,\n { authorizationStateLocked: true },\n )\n }\n\n await setCustomFieldsIfAny({\n dataEngine: de,\n entityId: E.auth.user,\n recordId: String(user.id),\n organizationId: user.organizationId ? String(user.organizationId) : null,\n tenantId: user.tenantId ? String(user.tenantId) : tenantId ?? null,\n values: custom,\n })\n }\n ], { transaction: true, label: destinationChanged ? 'auth.users.update.destination' : 'auth.users.update' })\n\n const identifiers = {\n id: String(user.id),\n organizationId: user.organizationId ? String(user.organizationId) : null,\n tenantId: user.tenantId ? String(user.tenantId) : tenantId ?? null,\n }\n\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'updated',\n entity: user,\n identifiers,\n events: userCrudEvents,\n indexer: userCrudIndexer,\n })\n\n if (hashed) {\n const actorId = ctx.auth?.sub ? String(ctx.auth.sub) : null\n // `system` covers a command invocation with no auth context and one running under\n // `ctx.systemActor`. Without it those writes would be indistinguishable from an\n // administrator setting someone else's password, which is exactly the case security\n // alerting escalates on. Password writes that never reach this command \u2014 `mercato\n // auth set-password`, tenant provisioning \u2014 set `passwordHash` directly and emit\n // nothing, so a subscriber cannot treat this event as covering every credential change.\n const changedBy = ctx.systemActor === true || !actorId\n ? 'system'\n : actorId === identifiers.id ? 'self' : 'admin'\n void emitAuthEvent('auth.password.changed', {\n id: identifiers.id,\n tenantId: identifiers.tenantId,\n organizationId: identifiers.organizationId,\n changedBy,\n changedById: actorId,\n at: new Date().toISOString(),\n }, { persistent: true }).catch(() => undefined)\n }\n\n if (Array.isArray(parsed.roles) && rolesBefore) {\n const rolesAfter = await loadUserRoleNames(em, String(user.id))\n const { assigned, revoked } = diffRoleChanges(rolesBefore, rolesAfter)\n if (assigned.length || revoked.length) {\n await notifyRoleChanges(ctx, user, assigned, revoked)\n }\n }\n\n await invalidateUserCache(ctx, parsed.id)\n\n return user\n },\n captureAfter: async (_input, result, ctx) => {\n const em = resolveCommandEm(ctx, true)\n const roles = await loadUserRoleNames(em, String(result.id))\n const custom = await loadUserCustomSnapshot(\n em,\n String(result.id),\n result.tenantId ? String(result.tenantId) : null,\n result.organizationId ? String(result.organizationId) : null\n )\n return serializeUser(result, roles, custom)\n },\n buildLog: async ({ input, result, snapshots, ctx }) => {\n const { translate } = await resolveTranslations()\n const beforeSnapshots = snapshots.before as UserSnapshots | undefined\n const before = beforeSnapshots?.view\n const beforeUndo = beforeSnapshots?.undo ?? null\n const em = resolveCommandEm(ctx, true)\n const afterRoles = await loadUserRoleNames(em, String(result.id))\n const afterCustom = await loadUserCustomSnapshot(\n em,\n String(result.id),\n result.tenantId ? String(result.tenantId) : null,\n result.organizationId ? String(result.organizationId) : null\n )\n const afterSnapshots = captureUserSnapshots(result, afterRoles, undefined, afterCustom)\n const after = afterSnapshots.view\n const changes = buildChanges(before ?? null, after as Record<string, unknown>, ['email', 'organizationId', 'tenantId', 'name', 'isConfirmed'])\n if (before && !arrayEquals(before.roles, afterRoles)) {\n changes.roles = { from: before.roles, to: afterRoles }\n }\n const customDiff = diffCustomFieldChanges(before?.custom, afterCustom)\n for (const [key, diff] of Object.entries(customDiff)) {\n changes[`cf_${key}`] = diff\n }\n const replayable = typeof input.password !== 'string' || input.password.length === 0\n return {\n replayable,\n actionLabel: translate('auth.audit.users.update', 'Update user'),\n resourceKind: 'auth.user',\n resourceId: String(result.id),\n tenantId: result.tenantId ? String(result.tenantId) : null,\n organizationId: result.organizationId ? String(result.organizationId) : null,\n changes,\n snapshotBefore: before ?? null,\n snapshotAfter: after,\n payload: replayable\n ? {\n undo: {\n before: withoutPasswordHash(beforeUndo),\n after: withoutPasswordHash(afterSnapshots.undo),\n },\n }\n : undefined,\n }\n },\n undo: async ({ input, logEntry, ctx }) => {\n const payload = extractUndoPayload<UndoPayload<UserUndoSnapshot>>(logEntry)\n const before = payload?.before\n const after = payload?.after\n if (!before) return\n const userId = before.id\n const storedReplayInput = extractStoredReplayInput(logEntry.commandPayload, logEntry)\n const replayInput = Object.keys(storedReplayInput).length\n ? storedReplayInput\n : deriveUserUpdateReplayInput(before, after ?? null)\n const em = resolveCommandEm(ctx)\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n\n // Reverting an update can drop the tenant below a protected role's floor just as the\n // forward path can \u2014 restoring an empty `before.roles` on what is now the last admin,\n // or restoring `isConfirmed: false`. Undo is reachable from the audit-log UI, so the\n // guard has to run here too, inside a transaction so the row lock is valid.\n const restoredTenantId = before.tenantId ? String(before.tenantId) : null\n\n let updated: User | null = null\n await withAtomicFlush(em, [\n async () => {\n await authorizeUserReplayAtMutation('update', {\n operation: 'undo',\n input,\n ctx,\n logEntry,\n })\n const current = await findOneWithDecryption(em, User, { id: userId, deletedAt: null }, {}, { tenantId: null, organizationId: null })\n const currentTenantId = current?.tenantId ? String(current.tenantId) : null\n\n await enforceProtectedRoleFloor(\n em,\n currentTenantId,\n userId,\n {\n deactivating:\n ('isConfirmed' in replayInput && before.isConfirmed === false)\n || ('organizationId' in replayInput && restoredTenantId !== currentTenantId),\n newRoles: Array.isArray(replayInput.roles) ? before.roles : undefined,\n },\n ctx,\n requireReplayProtectedRoleIds(em, currentTenantId),\n )\n\n updated = await de.updateOrmEntity({\n entity: User,\n where: { id: userId, deletedAt: null } as FilterQuery<User>,\n apply: (entity) => {\n if ('email' in replayInput) entity.email = before.email\n if ('organizationId' in replayInput) {\n entity.organizationId = before.organizationId ?? null\n entity.tenantId = before.tenantId ?? null\n }\n if ('name' in replayInput) entity.name = before.name ?? null\n if ('isConfirmed' in replayInput) entity.isConfirmed = before.isConfirmed\n },\n })\n\n if (updated && Array.isArray(replayInput.roles)) {\n await syncUserRoles(em, updated, before.roles, before.tenantId)\n }\n\n const reset = buildCustomFieldResetMap(before.custom, after?.custom)\n if (Object.keys(reset).length) {\n await setCustomFieldsIfAny({\n dataEngine: de,\n entityId: E.auth.user,\n recordId: before.id,\n organizationId: before.organizationId ?? null,\n tenantId: before.tenantId ?? null,\n values: reset,\n notify: false,\n })\n }\n },\n ], { transaction: true, label: 'auth.users.update.undo' })\n\n await emitCrudUndoSideEffects({\n dataEngine: de,\n action: 'updated',\n entity: updated,\n identifiers: {\n id: before.id,\n organizationId: before.organizationId ?? null,\n tenantId: before.tenantId ?? null,\n },\n events: userCrudEvents,\n indexer: userCrudIndexer,\n })\n\n await invalidateUserCache(ctx, userId)\n },\n redo: ({ input, ctx, logEntry }) => updateUserCommand.execute(\n input,\n withUserRedoLog(ctx, logEntry),\n ),\n}\n\nconst deleteUserCommand: CommandHandler<{ body?: Record<string, unknown>; query?: Record<string, unknown> }, User> = {\n id: 'auth.users.delete',\n atomicReplay: true,\n stabilizeReplay: (params) => stabilizeUserReplay('delete', params),\n authorizeReplay: (params) => authorizeUserReplay('delete', params),\n async prepare(input, ctx) {\n const id = requireId(input, 'User id required')\n const em = resolveCommandEm(ctx)\n const existing = await findOneWithDecryption(em, User, { id, deletedAt: null }, {}, { tenantId: null, organizationId: null })\n if (!existing) return {}\n const actorTenantScope = resolveActorTenantScope(ctx)\n if (actorTenantScope) {\n const targetTenant = normalizeTenantId(existing.tenantId) ?? null\n if (!targetTenant || targetTenant !== actorTenantScope) return {}\n }\n const roles = await loadUserRoleNames(em, id)\n const acls = await loadUserAclSnapshots(em, id)\n const custom = await loadUserCustomSnapshot(\n em,\n id,\n existing.tenantId ? String(existing.tenantId) : null,\n existing.organizationId ? String(existing.organizationId) : null\n )\n return { before: captureUserSnapshots(existing, roles, acls, custom) }\n },\n async execute(input, ctx) {\n const id = requireId(input, 'User id required')\n const em = resolveCommandEm(ctx)\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n const actorTenantScope = resolveActorTenantScope(ctx)\n\n const existing = await findOneWithDecryption(em, User, { id, deletedAt: null }, {}, { tenantId: null, organizationId: null })\n if (!existing) throw new CrudHttpError(404, { error: 'User not found' })\n if (actorTenantScope && existing.tenantId && String(existing.tenantId) !== actorTenantScope) {\n throw new CrudHttpError(404, { error: 'User not found' })\n }\n\n const deleteWhere: Record<string, unknown> = { id, deletedAt: null }\n if (actorTenantScope) deleteWhere.tenantId = actorTenantScope\n\n let user!: User\n await withAtomicFlush(em, [\n async () => {\n const redoLogEntry = (ctx as UserReplayRuntimeContext)[USER_REDO_LOG]\n if (redoLogEntry) {\n await authorizeUserReplayAtMutation('delete', {\n operation: 'redo',\n input,\n ctx,\n logEntry: redoLogEntry,\n })\n }\n const userTenantId = existing.tenantId ? String(existing.tenantId) : null\n const floorOptions = { deleting: true }\n const protectedRoleIds = redoLogEntry\n ? requireReplayProtectedRoleIds(em, userTenantId)\n : await discoverProtectedRoleIds(em, userTenantId, floorOptions, ctx)\n await lockUserRoleWriterAuthorizationState(em, {\n userIds: [id],\n roleIds: protectedRoleIds,\n })\n await enforceProtectedRoleFloor(\n em,\n userTenantId,\n id,\n floorOptions,\n ctx,\n protectedRoleIds,\n )\n\n await em.nativeDelete(UserAcl, { user: id })\n await em.nativeDelete(UserRole, { user: id })\n await em.nativeDelete(Session, { user: id })\n await em.nativeDelete(PasswordReset, { user: id })\n await em.nativeDelete(UserSidebarPreference, { user: id })\n await em.nativeDelete(SidebarVariant, { user: id })\n const removed = await de.deleteOrmEntity({\n entity: User,\n where: deleteWhere as FilterQuery<User>,\n soft: false,\n })\n if (!removed) throw new CrudHttpError(404, { error: 'User not found' })\n user = removed\n },\n ], { transaction: true })\n\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'deleted',\n entity: user,\n identifiers: {\n id: String(id),\n organizationId: user.organizationId ? String(user.organizationId) : null,\n tenantId: user.tenantId ? String(user.tenantId) : null,\n },\n events: userCrudEvents,\n indexer: userCrudIndexer,\n })\n\n await invalidateUserCache(ctx, id)\n\n return user\n },\n buildLog: async ({ snapshots, input, ctx }) => {\n const { translate } = await resolveTranslations()\n const beforeSnapshots = snapshots.before as UserSnapshots | undefined\n const before = beforeSnapshots?.view\n const beforeUndo = beforeSnapshots?.undo ?? null\n const id = requireId(input, 'User id required')\n return {\n actionLabel: translate('auth.audit.users.delete', 'Delete user'),\n resourceKind: 'auth.user',\n resourceId: id,\n snapshotBefore: before ?? null,\n tenantId: before?.tenantId ?? null,\n organizationId: before?.organizationId ?? null,\n payload: {\n undo: {\n before: beforeUndo,\n },\n },\n }\n },\n undo: async ({ input, logEntry, ctx }) => {\n const payload = extractUndoPayload<UndoPayload<UserUndoSnapshot>>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = resolveCommandEm(ctx)\n let user: User | null = null\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n\n await withAtomicFlush(em, [\n async () => {\n await authorizeUserReplayAtMutation('delete', {\n operation: 'undo',\n input,\n ctx,\n logEntry,\n })\n user = await findOneWithDecryption(em, User, { id: before.id }, {}, { tenantId: null, organizationId: null })\n if (user) {\n if (user.deletedAt) {\n user.deletedAt = null\n }\n user.email = before.email\n user.organizationId = before.organizationId ?? null\n user.tenantId = before.tenantId ?? null\n user.passwordHash = before.passwordHash ?? null\n user.name = before.name ?? null\n user.isConfirmed = before.isConfirmed\n await em.flush()\n } else {\n user = await de.createOrmEntity({\n entity: User,\n data: {\n id: before.id,\n email: before.email,\n organizationId: before.organizationId ?? null,\n tenantId: before.tenantId ?? null,\n passwordHash: before.passwordHash ?? null,\n name: before.name ?? null,\n isConfirmed: before.isConfirmed,\n },\n })\n }\n\n if (!user) return\n\n await lockUserRoleWriterAuthorizationState(em, { userIds: [before.id], roleIds: [] })\n await em.nativeDelete(UserRole, { user: before.id })\n await syncUserRoles(em, user, before.roles, before.tenantId)\n\n await restoreUserAcls(em, user, before.acls)\n\n const reset = buildCustomFieldResetMap(before.custom, undefined)\n if (Object.keys(reset).length) {\n await setCustomFieldsIfAny({\n dataEngine: de,\n entityId: E.auth.user,\n recordId: before.id,\n organizationId: before.organizationId ?? null,\n tenantId: before.tenantId ?? null,\n values: reset,\n notify: false,\n })\n }\n },\n ], { transaction: true })\n\n await invalidateUserCache(ctx, before.id)\n },\n redo: ({ input, ctx, logEntry }) => deleteUserCommand.execute(\n input,\n withUserRedoLog(ctx, logEntry),\n ),\n}\n\ntype UserReplayCommandKind = 'create' | 'update' | 'delete'\n\nfunction withoutPasswordHash(snapshot: UserUndoSnapshot | null): UserUndoSnapshot | null {\n if (!snapshot) return null\n const safeSnapshot = { ...snapshot }\n delete safeSnapshot.passwordHash\n return safeSnapshot\n}\n\nfunction normalizeUserAclSnapshots(acls: UserAclSnapshot[]): UserAclSnapshot[] {\n return acls\n .map((acl) => ({\n ...acl,\n features: acl.features ? [...acl.features].sort((left, right) => left.localeCompare(right)) : null,\n organizations: acl.organizations ? [...acl.organizations].sort((left, right) => left.localeCompare(right)) : null,\n }))\n .sort((left, right) => left.tenantId.localeCompare(right.tenantId))\n}\n\nfunction normalizeUserReplaySnapshot(snapshot: UserUndoSnapshot): UserUndoSnapshot {\n // The credential never takes part in the \"has the target changed?\" comparison.\n // A create's stored snapshot deliberately omits `passwordHash` (it must not sit\n // in `action_logs`), so comparing it against a live snapshot that still carries\n // the hash would report every password-bearing account as changed and refuse\n // the replay.\n return withoutPasswordHash({\n ...snapshot,\n roles: [...snapshot.roles].sort((left, right) => left.localeCompare(right)),\n acls: normalizeUserAclSnapshots(snapshot.acls),\n }) as UserUndoSnapshot\n}\n\nfunction toUserUpdateReplayState(snapshot: UserUndoSnapshot): SerializedUser {\n return {\n email: snapshot.email,\n organizationId: snapshot.organizationId,\n tenantId: snapshot.tenantId,\n roles: [...snapshot.roles].sort((left, right) => left.localeCompare(right)),\n name: snapshot.name,\n isConfirmed: snapshot.isConfirmed,\n ...(snapshot.custom && Object.keys(snapshot.custom).length ? { custom: snapshot.custom } : {}),\n }\n}\n\nfunction deriveUserUpdateReplayInput(\n before: UserUndoSnapshot | null,\n after: UserUndoSnapshot | null,\n): Record<string, unknown> {\n if (!before) return {}\n if (!after) {\n return {\n id: before.id,\n email: before.email,\n organizationId: before.organizationId,\n name: before.name,\n isConfirmed: before.isConfirmed,\n roles: before.roles,\n }\n }\n const input: Record<string, unknown> = { id: after.id }\n if (before.email !== after.email) input.email = after.email\n if (before.organizationId !== after.organizationId || before.tenantId !== after.tenantId) {\n input.organizationId = after.organizationId\n }\n if (before.name !== after.name) input.name = after.name\n if (before.isConfirmed !== after.isConfirmed) input.isConfirmed = after.isConfirmed\n if (!arrayEquals(before.roles, after.roles)) input.roles = after.roles\n return input\n}\n\nfunction isSelfProfileReplay(\n input: Record<string, unknown>,\n ctx: CommandRuntimeContext,\n userId: string,\n): boolean {\n if (!ctx.auth?.sub || ctx.auth.sub !== userId) return false\n const allowedKeys = new Set(['id', 'email', 'password'])\n return Object.keys(input).every((key) => allowedKeys.has(key) || input[key] === undefined)\n}\n\nasync function authorizeUserReplay(\n commandKind: UserReplayCommandKind,\n params: CommandReplayAuthorizationArgs<unknown>,\n): Promise<void> {\n const { operation, ctx, logEntry } = params\n const undoPayload = extractUndoPayload<UndoPayload<UserUndoSnapshot>>(logEntry)\n const before = undoPayload?.before ?? null\n const after = undoPayload?.after ?? null\n const passwordHashChanged = Boolean(\n commandKind === 'update'\n && before\n && after\n && 'passwordHash' in before\n && 'passwordHash' in after\n && before.passwordHash !== after.passwordHash,\n )\n const createdWithPassword = commandKind === 'create' && Boolean(\n hasStoredPasswordInput(params.input, logEntry)\n || (after && typeof after.passwordHash === 'string' && after.passwordHash.length > 0),\n )\n if (\n createdWithPassword\n || (commandKind === 'update' && (hasStoredPasswordInput(params.input, logEntry) || passwordHashChanged))\n ) {\n await denyCredentialReplay()\n }\n const userId = logEntry.resourceId ?? before?.id ?? after?.id ?? null\n if (!userId) {\n await assertReplaySnapshotMatches(null, { required: 'user replay snapshot' })\n return\n }\n\n const storedReplayInput = extractStoredReplayInput(params.input, logEntry)\n const replayInput = Object.keys(storedReplayInput).length\n ? storedReplayInput\n : deriveUserUpdateReplayInput(before, after)\n const requiredFeature = commandKind === 'create'\n ? operation === 'undo' ? 'auth.users.delete' : 'auth.users.create'\n : commandKind === 'delete'\n ? operation === 'undo' ? 'auth.users.create' : 'auth.users.delete'\n : 'auth.users.edit'\n const em = requireTransactionalReplayEntityManager(ctx)\n if (commandKind !== 'update' || !isSelfProfileReplay(replayInput, ctx, userId)) {\n await requireCurrentReplayFeature(ctx, requiredFeature)\n }\n\n const currentUser = await findOneWithDecryption(\n em,\n User,\n { id: userId, deletedAt: null },\n {},\n { tenantId: null, organizationId: null },\n )\n const rbacService = ctx.systemActor === true\n ? null\n : ctx.container.resolve('rbacService') as RbacService\n\n if (rbacService && currentUser) {\n const allowedIds = ctx.organizationScope?.allowedIds\n ?? ctx.organizationIds\n ?? (ctx.auth?.orgId ? [ctx.auth.orgId] : null)\n await assertActorCanAccessUserTarget({\n em,\n rbacService,\n requireBoundRbac: true,\n actorUserId: ctx.auth?.sub,\n tenantId: ctx.auth?.tenantId ?? null,\n organizationId: ctx.auth?.orgId ?? null,\n organizationScope: { allowedIds },\n targetUserId: userId,\n })\n await assertActorCanModifySuperAdminUserTarget({\n em,\n rbacService,\n requireBoundRbac: true,\n actorUserId: ctx.auth?.sub,\n tenantId: ctx.auth?.tenantId ?? null,\n organizationId: ctx.auth?.orgId ?? null,\n targetUserId: userId,\n })\n }\n\n let currentSnapshot: UserUndoSnapshot | null = null\n if (currentUser) {\n const currentTenantId = currentUser.tenantId ? String(currentUser.tenantId) : null\n const currentOrganizationId = currentUser.organizationId ? String(currentUser.organizationId) : null\n const [roles, acls, custom] = await Promise.all([\n loadUserRoleNames(em, userId),\n loadUserAclSnapshots(em, userId),\n loadUserCustomSnapshot(em, userId, currentTenantId, currentOrganizationId),\n ])\n currentSnapshot = captureUserSnapshots(currentUser, roles, acls, custom).undo\n }\n\n const expectedCurrent = operation === 'undo'\n ? commandKind === 'create' ? after : commandKind === 'update' ? after : null\n : commandKind === 'create' ? null : before\n\n if (commandKind === 'update') {\n if (!currentSnapshot || !expectedCurrent) {\n await assertReplaySnapshotMatches(currentSnapshot, expectedCurrent)\n } else {\n await assertReplaySnapshotMatches(\n toUserUpdateReplayState(currentSnapshot),\n toUserUpdateReplayState(expectedCurrent),\n )\n }\n } else {\n await assertReplaySnapshotMatches(\n currentSnapshot ? normalizeUserReplaySnapshot(currentSnapshot) : null,\n expectedCurrent ? normalizeUserReplaySnapshot(expectedCurrent) : null,\n )\n }\n\n const desiredState = operation === 'undo'\n ? commandKind === 'create' ? null : before\n : commandKind === 'delete' ? null : after\n if (!desiredState || !rbacService) return\n\n const restoresMembership = commandKind !== 'update'\n || Array.isArray(replayInput.roles)\n || 'organizationId' in replayInput\n if (restoresMembership) {\n const roles = await assertActorCanGrantRoleTokens({\n em,\n rbacService,\n requireBoundRbac: true,\n actorUserId: ctx.auth?.sub,\n tenantId: desiredState.tenantId,\n organizationId: desiredState.organizationId,\n roleTokens: desiredState.roles,\n })\n await assertActorCanAssignUserDestination({\n em,\n rbacService,\n requireBoundRbac: true,\n actorUserId: ctx.auth?.sub,\n tenantId: ctx.auth?.tenantId ?? null,\n organizationId: ctx.auth?.orgId ?? null,\n allowedOrganizationIds: ctx.organizationScope?.allowedIds ?? ctx.organizationIds,\n destinationTenantId: desiredState.tenantId,\n destinationOrganizationId: desiredState.organizationId,\n roles,\n })\n }\n\n const restoresAcls = commandKind !== 'update' && desiredState.acls.length > 0\n if (!restoresAcls) return\n await requireCurrentReplayFeature(ctx, 'auth.acl.manage')\n for (const acl of desiredState.acls) {\n await assertActorCanGrantAcl({\n em,\n rbacService,\n requireBoundRbac: true,\n actorUserId: ctx.auth?.sub,\n tenantId: acl.tenantId,\n organizationId: desiredState.organizationId,\n features: acl.features,\n isSuperAdmin: acl.isSuperAdmin,\n organizations: acl.organizations,\n })\n }\n}\n\nasync function authorizeUserReplayAtMutation(\n commandKind: UserReplayCommandKind,\n params: CommandReplayAuthorizationArgs<unknown>,\n): Promise<void> {\n const em = params.ctx.transactionalEm\n ?? params.ctx.container.resolve('em') as EntityManager\n const boundParams = params.ctx.transactionalEm\n ? params\n : { ...params, ctx: { ...params.ctx, transactionalEm: em } }\n await stabilizeUserReplay(commandKind, boundParams)\n await rerunReplayTransactionGuardAfterLocks(boundParams, em)\n await authorizeUserReplay(commandKind, boundParams)\n}\n\nasync function stabilizeUserReplay(\n commandKind: UserReplayCommandKind,\n params: CommandReplayAuthorizationArgs<unknown>,\n): Promise<void> {\n const undoPayload = extractUndoPayload<UndoPayload<UserUndoSnapshot>>(params.logEntry)\n const before = undoPayload?.before ?? null\n const after = undoPayload?.after ?? null\n const passwordHashChanged = Boolean(\n commandKind === 'update'\n && before\n && after\n && 'passwordHash' in before\n && 'passwordHash' in after\n && before.passwordHash !== after.passwordHash,\n )\n const createdWithPassword = commandKind === 'create' && Boolean(\n hasStoredPasswordInput(params.input, params.logEntry)\n || (after && typeof after.passwordHash === 'string' && after.passwordHash.length > 0),\n )\n if (\n createdWithPassword\n || (commandKind === 'update' && (hasStoredPasswordInput(params.input, params.logEntry) || passwordHashChanged))\n ) {\n await denyCredentialReplay()\n }\n const targetUserId = params.logEntry.resourceId ?? before?.id ?? after?.id ?? null\n const em = requireTransactionalReplayEntityManager(params.ctx)\n const transactionLifetime = getTransactionLifetime(em)\n if (!transactionLifetime) {\n throw new Error('[internal] Replay protected-role locks require an explicit transaction lifetime')\n }\n const existingProtectedRoleIdsByTenant = replayProtectedRoleIdsByTenant.get(transactionLifetime)\n const currentTarget = targetUserId\n ? await findOneWithDecryption(\n em,\n User,\n { id: targetUserId },\n {},\n { tenantId: null, organizationId: null },\n )\n : null\n const currentTargetTenantId = normalizeTenantId(currentTarget?.tenantId) ?? null\n const relevantTenantIds = existingProtectedRoleIdsByTenant\n ? Array.from(existingProtectedRoleIdsByTenant.keys()).sort((left, right) => left.localeCompare(right))\n : Array.from(new Set([\n normalizeTenantId(params.ctx.auth?.tenantId) ?? null,\n normalizeTenantId(before?.tenantId) ?? null,\n normalizeTenantId(after?.tenantId) ?? null,\n normalizeTenantId(params.logEntry.tenantId) ?? null,\n currentTargetTenantId,\n ].filter((tenantId): tenantId is string => tenantId !== null))).sort((left, right) => left.localeCompare(right))\n const protectedRoleIdsByTenant = new Map(existingProtectedRoleIdsByTenant ?? [])\n if (!existingProtectedRoleIdsByTenant) {\n for (const tenantId of relevantTenantIds) {\n protectedRoleIdsByTenant.set(\n tenantId,\n await discoverProtectedRoleIds(em, tenantId, { deleting: true }, params.ctx),\n )\n }\n }\n const roleIds: string[] = []\n const seenRoleTokens = new Set<string>()\n for (const snapshot of [before, after]) {\n if (!snapshot?.tenantId) continue\n for (const token of snapshot.roles) {\n const key = `${snapshot.tenantId}:${token}`\n if (seenRoleTokens.has(key)) continue\n seenRoleTokens.add(key)\n const role = await resolveRole(em, token, snapshot.tenantId)\n if (role?.id) roleIds.push(String(role.id))\n }\n }\n await lockReplayAuthorizationState(em, params.ctx, {\n targetUserIds: targetUserId ? [targetUserId] : [],\n targetRoleIds: [\n ...roleIds,\n ...Array.from(protectedRoleIdsByTenant.values()).flat(),\n ],\n targetTenantIds: relevantTenantIds,\n })\n replayProtectedRoleIdsByTenant.set(transactionLifetime, protectedRoleIdsByTenant)\n}\n\nregisterCommand(createUserCommand)\nregisterCommand(updateUserCommand)\nregisterCommand(deleteUserCommand)\n\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i\n\nasync function resolveRole(\n em: EntityManager,\n value: string,\n normalizedTenantId: string | null,\n): Promise<Role | null> {\n if (UUID_RE.test(value)) {\n const where: Record<string, unknown> = { id: value }\n if (normalizedTenantId !== null) {\n where.tenantId = normalizedTenantId\n }\n return findOneWithDecryption(em, Role, where as any, {}, { tenantId: normalizedTenantId, organizationId: null })\n }\n return findOneWithDecryption(em, Role, { name: value, tenantId: normalizedTenantId }, {}, { tenantId: normalizedTenantId, organizationId: null })\n}\n\nasync function syncUserRoles(\n em: EntityManager,\n user: User,\n desiredRoles: string[],\n tenantId: string | null,\n options: { authorizationStateLocked?: boolean } = {},\n) {\n const userId = String(user.id)\n const unique = Array.from(new Set(desiredRoles.map((role) => role.trim()).filter(Boolean)))\n const normalizedTenantId = normalizeTenantId(tenantId ?? null) ?? null\n\n const resolvedRoles: Role[] = []\n const missingRoles: string[] = []\n for (const value of unique) {\n const role = await resolveRole(em, value, normalizedTenantId)\n if (!role) {\n missingRoles.push(value)\n } else {\n resolvedRoles.push(role)\n }\n }\n\n if (missingRoles.length) {\n const labels = missingRoles.map((n) => `\"${n}\"`).join(', ')\n throw new CrudHttpError(400, { error: `Role(s) not found: ${labels}` })\n }\n\n const discoveredLinks = await findWithDecryption(\n em,\n UserRole,\n { user },\n { orderBy: { id: 'ASC' } },\n { tenantId: null, organizationId: null },\n )\n const discoveredRoleIds = discoveredLinks\n .map((link) => String(link.role?.id ?? (link.role as unknown as string) ?? ''))\n .filter(Boolean)\n const desiredIds = new Set(resolvedRoles.map((role) => String(role.id)))\n if (!options.authorizationStateLocked) {\n await lockUserRoleWriterAuthorizationState(em, {\n userIds: [userId],\n roleIds: [...desiredIds, ...discoveredRoleIds],\n })\n }\n const currentLinks = await findWithDecryption(\n em,\n UserRole,\n { user, deletedAt: null, role: { deletedAt: null } } as FilterQuery<UserRole>,\n { lockMode: LockMode.PESSIMISTIC_WRITE, orderBy: { id: 'ASC' }, refresh: true },\n { tenantId: null, organizationId: null },\n )\n const currentRoleIds = new Map(\n currentLinks.map((link) => {\n const roleId = String(link.role?.id ?? (link.role as unknown as string) ?? '')\n return [roleId, link] as const\n }),\n )\n\n for (const [roleId, link] of currentRoleIds.entries()) {\n if (!desiredIds.has(roleId) && link) {\n em.remove(link)\n }\n }\n\n for (const role of resolvedRoles) {\n if (!currentRoleIds.has(String(role.id))) {\n em.persist(em.create(UserRole, { user, role, createdAt: new Date() }))\n }\n }\n\n await em.flush()\n}\n\nasync function loadUserRoleNames(em: EntityManager, userId: string): Promise<string[]> {\n const links = await findWithDecryption(\n em,\n UserRole,\n {\n user: userId as unknown as User,\n deletedAt: null,\n role: { deletedAt: null },\n } as FilterQuery<UserRole>,\n { populate: ['role'] },\n { tenantId: null, organizationId: null },\n )\n const names = links\n .map((link) => link.role?.name ?? '')\n .filter((name): name is string => !!name)\n return Array.from(new Set(names)).sort((a, b) => a.localeCompare(b))\n}\n\nfunction serializeUser(user: User, roles: string[], custom?: Record<string, unknown> | null): SerializedUser {\n const payload: SerializedUser = {\n email: String(user.email ?? ''),\n organizationId: user.organizationId ? String(user.organizationId) : null,\n tenantId: user.tenantId ? String(user.tenantId) : null,\n roles,\n name: user.name ? String(user.name) : null,\n isConfirmed: Boolean(user.isConfirmed),\n }\n if (custom && Object.keys(custom).length) payload.custom = custom\n return payload\n}\n\nfunction captureUserSnapshots(\n user: User,\n roles: string[],\n acls: UserAclSnapshot[] = [],\n custom?: Record<string, unknown> | null\n): UserSnapshots {\n return {\n view: serializeUser(user, roles, custom),\n undo: {\n id: String(user.id),\n email: String(user.email ?? ''),\n organizationId: user.organizationId ? String(user.organizationId) : null,\n tenantId: user.tenantId ? String(user.tenantId) : null,\n passwordHash: user.passwordHash ? String(user.passwordHash) : null,\n name: user.name ? String(user.name) : null,\n isConfirmed: Boolean(user.isConfirmed),\n roles: [...roles],\n acls,\n ...(custom && Object.keys(custom).length ? { custom } : {}),\n },\n }\n}\n\nasync function loadUserAclSnapshots(em: EntityManager, userId: string): Promise<UserAclSnapshot[]> {\n const list = await findWithDecryption(em, UserAcl, { user: userId as unknown as User, deletedAt: null }, {}, { tenantId: null, organizationId: null })\n return list.map((acl) => ({\n tenantId: String(acl.tenantId),\n features: Array.isArray(acl.featuresJson) ? [...acl.featuresJson] : null,\n isSuperAdmin: Boolean(acl.isSuperAdmin),\n organizations: Array.isArray(acl.organizationsJson) ? [...acl.organizationsJson] : null,\n }))\n}\n\nasync function restoreUserAcls(em: EntityManager, user: User, acls: UserAclSnapshot[]) {\n await lockUserRoleWriterAuthorizationState(em, { userIds: [String(user.id)], roleIds: [] })\n await em.nativeDelete(UserAcl, { user: String(user.id) })\n for (const acl of acls) {\n const entity = em.create(UserAcl, {\n user,\n tenantId: acl.tenantId,\n featuresJson: acl.features ?? null,\n isSuperAdmin: acl.isSuperAdmin,\n organizationsJson: acl.organizations ?? null,\n createdAt: new Date(),\n })\n em.persist(entity)\n }\n await em.flush()\n}\n\nasync function loadUserCustomSnapshot(\n em: EntityManager,\n id: string,\n tenantId: string | null,\n organizationId: string | null\n): Promise<Record<string, unknown>> {\n return await loadCustomFieldSnapshot(em, {\n entityId: E.auth.user,\n recordId: id,\n tenantId,\n organizationId,\n })\n}\n\nasync function invalidateUserCache(ctx: CommandRuntimeContext, userId: string) {\n try {\n const rbacService = ctx.container.resolve('rbacService') as { invalidateUserCache: (uid: string) => Promise<void> }\n await rbacService.invalidateUserCache(userId)\n } catch {\n // RBAC not available\n }\n\n try {\n const cache = ctx.container.resolve('cache') as { deleteByTags?: (tags: string[]) => Promise<void> }\n if (cache?.deleteByTags) await cache.deleteByTags([`rbac:user:${userId}`])\n } catch {\n // cache not available\n }\n}\n\nfunction diffRoleChanges(before: string[], after: string[]) {\n const beforeSet = new Set(before)\n const afterSet = new Set(after)\n const assigned = after.filter((role) => !beforeSet.has(role))\n const revoked = before.filter((role) => !afterSet.has(role))\n return { assigned, revoked }\n}\n\nfunction arrayEquals(left: string[] | undefined, right: string[]): boolean {\n if (!left) return false\n if (left.length !== right.length) return false\n return left.every((value, idx) => value === right[idx])\n}\n\nasync function throwDuplicateEmailError(): Promise<never> {\n const { translate } = await resolveTranslations()\n const message = translate('auth.users.errors.emailExists', 'Email already in use')\n throw new CrudHttpError(400, {\n error: message,\n fieldErrors: { email: message },\n details: [{ path: ['email'], message, code: 'duplicate', origin: 'validation' }],\n })\n}\n\ntype ProtectedRoleFloorOptions = {\n deactivating?: boolean\n newRoles?: string[]\n deleting?: boolean\n}\n\n/**\n * True when the requested mutation can lower a role's active holder count. Guards the\n * floor check so that ordinary edits (display name, password, email) never take the\n * tenant-wide role lock \u2014 `PUT /api/auth/profile` routes every self-service password\n * change through `auth.users.update`, so an unconditional lock would serialize them.\n */\nfunction couldReduceActiveHolders(options: ProtectedRoleFloorOptions): boolean {\n return options.deleting === true || options.deactivating === true || options.newRoles !== undefined\n}\n\nasync function discoverProtectedRoleIds(\n em: EntityManager,\n tenantId: string | null,\n options: ProtectedRoleFloorOptions,\n ctx?: CommandRuntimeContext,\n): Promise<string[]> {\n if (ctx?.systemActor === true || !couldReduceActiveHolders(options)) return []\n const normalizedTenantId = normalizeTenantId(tenantId) ?? null\n if (!normalizedTenantId) return []\n const roles = await findWithDecryption(em, Role, {\n tenantId: normalizedTenantId,\n minActiveHolders: { $gt: 0 },\n deletedAt: null,\n }, { orderBy: { id: 'ASC' } }, { tenantId: normalizedTenantId, organizationId: null })\n return roles.map((role) => String(role.id))\n}\n\nfunction requireReplayProtectedRoleIds(\n em: EntityManager,\n tenantId: string | null,\n): readonly string[] {\n const normalizedTenantId = normalizeTenantId(tenantId) ?? null\n if (!normalizedTenantId) return []\n const transactionLifetime = getTransactionLifetime(em)\n const roleIds = transactionLifetime\n ? replayProtectedRoleIdsByTenant.get(transactionLifetime)?.get(normalizedTenantId)\n : undefined\n if (!roleIds) {\n throw new Error(`[internal] Replay protected-role lock footprint is missing tenant ${normalizedTenantId}`)\n }\n return roleIds\n}\n\nasync function enforceProtectedRoleFloor(\n em: EntityManager,\n tenantId: string | null,\n userId: string,\n options: ProtectedRoleFloorOptions,\n ctx?: CommandRuntimeContext,\n lockedProtectedRoleIds?: readonly string[],\n): Promise<void> {\n // Internal automation (CLI, migrations, tenant teardown) must never be blocked by the\n // floor. Superadmins are deliberately NOT exempt \u2014 see the spec's Risks section.\n if (ctx?.systemActor === true) return\n if (!couldReduceActiveHolders(options)) return\n\n const normalizedTenantId = normalizeTenantId(tenantId) ?? null\n if (!normalizedTenantId) return\n\n const protectedRoles = lockedProtectedRoleIds\n ? await findWithDecryption(em, Role, {\n id: { $in: [...lockedProtectedRoleIds] },\n tenantId: normalizedTenantId,\n minActiveHolders: { $gt: 0 },\n deletedAt: null,\n }, {\n orderBy: { id: 'ASC' },\n refresh: true,\n }, { tenantId: normalizedTenantId, organizationId: null })\n : await findWithDecryption(em, Role, {\n tenantId: normalizedTenantId,\n minActiveHolders: { $gt: 0 },\n deletedAt: null,\n }, {\n lockMode: LockMode.PESSIMISTIC_WRITE,\n orderBy: { id: 'ASC' },\n }, { tenantId: normalizedTenantId, organizationId: null })\n\n if (protectedRoles.length === 0) return\n\n const { translate } = await resolveTranslations()\n\n for (const role of protectedRoles) {\n const minFloor = role.minActiveHolders ?? 0\n if (minFloor <= 0) continue\n\n // Active links for this role, scoped to the tenant by the nested user filter so the\n // database \u2014 not a post-filter \u2014 enforces isolation. Deliberately NOT populated:\n // `findWithDecryption` runs `decryptEntityGraph` over loaded relations, which would\n // decrypt every admin's email and name on each check just to read their ids.\n const activeLinks = await findWithDecryption(em, UserRole, {\n role: role.id,\n deletedAt: null,\n user: {\n deletedAt: null,\n isConfirmed: true,\n tenantId: normalizedTenantId\n }\n }, {}, { tenantId: null, organizationId: null })\n\n // Count distinct user IDs in the tenant holding this role to prevent overcounting due to duplicate links\n const activeUserIds = Array.from(\n new Set(\n activeLinks\n .map((link) => {\n const userRef = link.user as unknown as { id?: string } | string | null | undefined\n const linkedUserId = typeof userRef === 'string' ? userRef : userRef?.id\n return linkedUserId ? String(linkedUserId) : null\n })\n .filter((id): id is string => !!id)\n )\n )\n\n // Is the target user currently one of the active holders?\n if (activeUserIds.includes(userId)) {\n // Determine if they will remain an active holder\n let willStillBeActiveHolder = true\n\n if (options.deleting || options.deactivating) {\n willStillBeActiveHolder = false\n } else if (options.newRoles !== undefined) {\n // Checking role list\n const desiredUnique = Array.from(new Set(options.newRoles.map((r) => r.trim().toLowerCase()).filter(Boolean)))\n const roleNameLower = role.name.toLowerCase()\n const hasRoleByName = desiredUnique.includes(roleNameLower) || desiredUnique.includes(String(role.id).toLowerCase())\n if (!hasRoleByName) {\n willStillBeActiveHolder = false\n }\n }\n\n if (!willStillBeActiveHolder) {\n const remaining = activeUserIds.length - 1\n if (remaining < minFloor) {\n throw new CrudHttpError(400, {\n error: translate('auth.users.errors.lastHolderOfCriticalRole', 'Cannot remove the last active holder of role \"{roleName}\"', { roleName: role.name })\n })\n }\n }\n }\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { CommandHandler, CommandReplayAuthorizationArgs, CommandUndoLogEntry } from '@open-mercato/shared/lib/commands'\nimport { registerCommand } from '@open-mercato/shared/lib/commands'\nimport {\n parseWithCustomFields,\n setCustomFieldsIfAny,\n emitCrudSideEffects,\n emitCrudUndoSideEffects,\n buildChanges,\n requireId,\n} from '@open-mercato/shared/lib/commands/helpers'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport type { CrudEventsConfig, CrudIndexerConfig } from '@open-mercato/shared/lib/crud/types'\nimport type { DataEngine } from '@open-mercato/shared/lib/data/engine'\nimport type { CommandRuntimeContext } from '@open-mercato/shared/lib/commands'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { UniqueConstraintViolationException, LockMode } from '@mikro-orm/core'\nimport type { EntityManager, FilterQuery } from '@mikro-orm/postgresql'\nimport {\n User,\n UserRole,\n Role,\n UserAcl,\n Session,\n PasswordReset,\n UserSidebarPreference,\n SidebarVariant,\n} from '@open-mercato/core/modules/auth/data/entities'\nimport { Organization } from '@open-mercato/core/modules/directory/data/entities'\nimport { resolveOrganizationScope } from '@open-mercato/core/modules/directory/utils/organizationScope'\nimport { E } from '#generated/entities.ids.generated'\nimport { z } from 'zod'\nimport {\n loadCustomFieldSnapshot,\n buildCustomFieldResetMap,\n diffCustomFieldChanges,\n} from '@open-mercato/shared/lib/commands/customFieldSnapshots'\nimport { extractUndoPayload, type UndoPayload } from '@open-mercato/shared/lib/commands/undo'\nimport { resolveRedoSnapshot } from '@open-mercato/shared/lib/commands/redo'\nimport { withAtomicFlush } from '@open-mercato/shared/lib/commands/flush'\nimport {\n getTransactionLifetime,\n onTransactionLifetimeComplete,\n} from '@open-mercato/shared/lib/commands/transaction-lifetime'\nimport { normalizeTenantId } from '@open-mercato/core/modules/auth/lib/tenantAccess'\nimport { computeEmailHash, emailHashLookupValues } from '@open-mercato/core/modules/auth/lib/emailHash'\nimport { findOneWithDecryption, findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport { buildNotificationFromType } from '@open-mercato/core/modules/notifications/lib/notificationBuilder'\nimport { resolveNotificationService } from '@open-mercato/core/modules/notifications/lib/notificationService'\nimport notificationTypes from '@open-mercato/core/modules/auth/notifications'\nimport { buildPasswordSchema } from '@open-mercato/shared/lib/auth/passwordPolicy'\nimport { emitAuthEvent } from '@open-mercato/core/modules/auth/events'\nimport { sendEmail } from '@open-mercato/shared/lib/email/send'\nimport InviteUserEmail from '@open-mercato/core/modules/auth/emails/InviteUserEmail'\nimport { INVITE_TOKEN_TTL_MS } from '@open-mercato/core/modules/auth/lib/inviteToken'\nimport { getSecurityEmailBaseUrl } from '@open-mercato/shared/lib/url'\nimport { generateAuthToken, hashAuthToken } from '@open-mercato/core/modules/auth/lib/tokenHash'\nimport { normalizeDisplayNameInput } from '@open-mercato/core/modules/auth/lib/displayName'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\nimport {\n assertActorCanAssignUserDestination,\n assertActorCanAccessUserTarget,\n assertActorCanGrantAcl,\n assertActorCanGrantRoleTokens,\n assertActorCanModifySuperAdminUserTarget,\n resolveUserDestinationRoles,\n throwUserDestinationOrganizationNotFound,\n} from '@open-mercato/core/modules/auth/lib/grantChecks'\nimport type { RbacService } from '@open-mercato/core/modules/auth/services/rbacService'\nimport {\n assertReplaySnapshotMatches,\n denyCredentialReplay,\n extractStoredReplayInput,\n hasStoredPasswordInput,\n lockReplayAuthorizationState,\n rerunReplayTransactionGuardAfterLocks,\n requireCurrentReplayFeature,\n requireTransactionalReplayEntityManager,\n} from '@open-mercato/core/modules/auth/lib/commandReplay'\nimport { lockUserRoleWriterAuthorizationState } from '@open-mercato/core/modules/auth/lib/authorizationStateLocks'\n\nconst logger = createLogger('auth').child({ component: 'users-commands' })\nconst USER_REDO_LOG = Symbol('auth.users.redoLog')\nconst replayProtectedRoleIdsByTenant = new WeakMap<object, ReadonlyMap<string, readonly string[]>>()\n\ntype UserReplayRuntimeContext = CommandRuntimeContext & {\n [USER_REDO_LOG]?: CommandUndoLogEntry\n}\n\nfunction withUserRedoLog(\n ctx: CommandRuntimeContext,\n logEntry: CommandUndoLogEntry,\n): UserReplayRuntimeContext {\n return { ...ctx, [USER_REDO_LOG]: logEntry }\n}\n\nfunction resolveCommandEm(ctx: CommandRuntimeContext, forkWhenUnbound = false): EntityManager {\n if (ctx.transactionalEm) return ctx.transactionalEm\n const em = ctx.container.resolve('em') as EntityManager\n return forkWhenUnbound ? em.fork() : em\n}\n\ntype SerializedUser = {\n email: string\n organizationId: string | null\n tenantId: string | null\n roles: string[]\n name: string | null\n isConfirmed: boolean\n custom?: Record<string, unknown>\n}\n\ntype UserAclSnapshot = {\n tenantId: string\n features: string[] | null\n isSuperAdmin: boolean\n organizations: string[] | null\n}\n\ntype UserUndoSnapshot = {\n id: string\n email: string\n organizationId: string | null\n tenantId: string | null\n passwordHash?: string | null\n name: string | null\n isConfirmed: boolean\n roles: string[]\n acls: UserAclSnapshot[]\n custom?: Record<string, unknown>\n}\n\ntype UserSnapshots = {\n view: SerializedUser\n undo: UserUndoSnapshot\n}\n\nfunction resolveActorTenantScope(ctx: CommandRuntimeContext): string | null {\n if (ctx.systemActor === true) return null\n const auth = ctx.auth\n if (!auth) return null\n if ((auth as { isSuperAdmin?: boolean }).isSuperAdmin === true) return null\n const actorTenantId = normalizeTenantId(auth.tenantId ?? null) ?? null\n return actorTenantId\n}\n\nfunction assertTargetTenantInScope(actorTenantScope: string | null, targetTenantId: unknown, notFoundError: string): void {\n if (!actorTenantScope) return\n const targetTenant = normalizeTenantId(targetTenantId) ?? null\n if (!targetTenant || targetTenant !== actorTenantScope) {\n throw new CrudHttpError(404, { error: notFoundError })\n }\n}\n\nasync function assertCommandActorCanAssignUserDestination(\n ctx: CommandRuntimeContext,\n em: EntityManager,\n destination: { destinationTenantId: string | null; destinationOrganizationId: string; roles: Role[] },\n): Promise<void> {\n const rbacService = ctx.container.resolve('rbacService') as RbacService\n const actorIsSuperAdmin = ctx.systemActor === true || ctx.auth?.isSuperAdmin === true\n const organizationScope = ctx.organizationScope?.tenantId === destination.destinationTenantId\n ? ctx.organizationScope\n : !actorIsSuperAdmin && ctx.auth?.sub && destination.destinationTenantId\n ? await resolveOrganizationScope({\n em,\n rbac: rbacService,\n auth: ctx.auth,\n tenantId: destination.destinationTenantId,\n })\n : null\n await assertActorCanAssignUserDestination({\n em,\n rbacService,\n actorUserId: ctx.auth?.sub,\n actorIsSuperAdmin,\n tenantId: ctx.auth?.tenantId ?? null,\n organizationId: ctx.auth?.orgId ?? null,\n allowedOrganizationIds: organizationScope?.allowedIds,\n destinationTenantId: destination.destinationTenantId,\n destinationOrganizationId: destination.destinationOrganizationId,\n roles: destination.roles,\n })\n}\n\nconst passwordSchema = buildPasswordSchema()\n\nconst displayNameSchema = z.preprocess(\n normalizeDisplayNameInput,\n z.string().trim().min(1).max(120).nullable().optional(),\n)\n\nconst createSchema = z.object({\n email: z.string().email(),\n name: displayNameSchema,\n password: passwordSchema.optional(),\n sendInviteEmail: z.boolean().optional(),\n organizationId: z.string().uuid(),\n roles: z.array(z.string()).optional(),\n}).refine(\n (data) => data.password || data.sendInviteEmail,\n { message: 'Either password or sendInviteEmail is required', path: ['password'] },\n)\n\nconst updateSchema = z.object({\n id: z.string().uuid(),\n email: z.string().email().optional(),\n name: displayNameSchema,\n password: passwordSchema.optional(),\n organizationId: z.string().uuid().optional(),\n roles: z.array(z.string()).optional(),\n isConfirmed: z.boolean().optional(),\n})\n\nexport const userCrudEvents: CrudEventsConfig = {\n module: 'auth',\n entity: 'user',\n persistent: true,\n buildPayload: (ctx) => ({\n id: ctx.identifiers.id,\n organizationId: ctx.identifiers.organizationId,\n tenantId: ctx.identifiers.tenantId,\n }),\n}\n\nexport const userCrudIndexer: CrudIndexerConfig = {\n entityType: E.auth.user,\n buildUpsertPayload: (ctx) => ({\n entityType: E.auth.user,\n recordId: ctx.identifiers.id,\n organizationId: ctx.identifiers.organizationId,\n tenantId: ctx.identifiers.tenantId,\n }),\n buildDeletePayload: (ctx) => ({\n entityType: E.auth.user,\n recordId: ctx.identifiers.id,\n organizationId: ctx.identifiers.organizationId,\n tenantId: ctx.identifiers.tenantId,\n }),\n}\n\nasync function notifyRoleChanges(\n ctx: CommandRuntimeContext,\n user: User,\n assignedRoles: string[],\n revokedRoles: string[],\n): Promise<void> {\n const tenantId = user.tenantId ? String(user.tenantId) : null\n if (!tenantId) return\n const organizationId = user.organizationId ? String(user.organizationId) : null\n\n const createNotifications = async () => {\n const notificationService = resolveNotificationService(ctx.container)\n if (assignedRoles.length) {\n const assignedType = notificationTypes.find((type) => type.type === 'auth.role.assigned')\n if (assignedType) {\n const notificationInput = buildNotificationFromType(assignedType, {\n recipientUserId: String(user.id),\n sourceEntityType: 'auth:user',\n sourceEntityId: String(user.id),\n })\n await notificationService.create(notificationInput, { tenantId, organizationId })\n }\n }\n\n if (revokedRoles.length) {\n const revokedType = notificationTypes.find((type) => type.type === 'auth.role.revoked')\n if (revokedType) {\n const notificationInput = buildNotificationFromType(revokedType, {\n recipientUserId: String(user.id),\n sourceEntityType: 'auth:user',\n sourceEntityId: String(user.id),\n })\n await notificationService.create(notificationInput, { tenantId, organizationId })\n }\n }\n }\n const safelyCreateNotifications = async () => {\n try {\n await createNotifications()\n } catch (err) {\n logger.error('Failed to create notification', { err })\n }\n }\n\n const transactionalEm = ctx.transactionalEm\n if (transactionalEm && getTransactionLifetime(transactionalEm)) {\n onTransactionLifetimeComplete(transactionalEm, async (outcome) => {\n if (outcome === 'committed') await safelyCreateNotifications()\n })\n return\n }\n\n await safelyCreateNotifications()\n}\n\ntype CreateUserResult = { user: User; warning?: 'invite_email_failed' }\n\nconst createUserCommand: CommandHandler<Record<string, unknown>, CreateUserResult> = {\n id: 'auth.users.create',\n atomicReplay: true,\n stabilizeReplay: (params) => stabilizeUserReplay('create', params),\n authorizeReplay: (params) => authorizeUserReplay('create', params),\n async execute(rawInput, ctx) {\n const { parsed, custom } = parseWithCustomFields(createSchema, rawInput)\n const em = resolveCommandEm(ctx)\n\n const organization = await findOneWithDecryption(\n em,\n Organization,\n { id: parsed.organizationId },\n { populate: ['tenant'] },\n { tenantId: null, organizationId: parsed.organizationId },\n )\n if (!organization) throw new CrudHttpError(400, { error: 'Organization not found' })\n const tenantId = organization.tenant?.id ? String(organization.tenant.id) : null\n assertTargetTenantInScope(resolveActorTenantScope(ctx), tenantId, 'Organization not found')\n await assertCommandActorCanAssignUserDestination(ctx, em, {\n destinationTenantId: tenantId,\n destinationOrganizationId: parsed.organizationId,\n roles: await resolveUserDestinationRoles({\n em,\n destinationTenantId: tenantId,\n roleTokens: parsed.roles ?? [],\n }),\n })\n\n const emailHash = computeEmailHash(parsed.email)\n // Email is unique per-tenant, not globally (see Migration20260610120000:\n // users_tenant_email_hash_uniq). Scope the duplicate check to the target tenant so the same\n // email may legitimately exist in other tenants without blocking creation or leaking\n // cross-tenant account existence (#2934).\n const duplicate = await findOneWithDecryption(em, User, { $or: [{ email: parsed.email }, { emailHash: { $in: emailHashLookupValues(parsed.email) } }], deletedAt: null, tenantId } as any, {}, { tenantId: null, organizationId: null })\n if (duplicate) await throwDuplicateEmailError()\n\n let passwordHash: string | null = null\n if (parsed.password) {\n const { hash } = await import('bcryptjs')\n passwordHash = await hash(parsed.password, 10)\n }\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n let user!: User\n let assignedRoles: string[] = []\n await withAtomicFlush(em, [\n async () => {\n try {\n user = await de.createOrmEntity({\n entity: User,\n data: {\n email: parsed.email,\n name: parsed.name,\n emailHash,\n passwordHash,\n isConfirmed: true,\n organizationId: parsed.organizationId,\n tenantId,\n },\n })\n } catch (error) {\n if (isUniqueViolation(error)) await throwDuplicateEmailError()\n throw error\n }\n },\n async () => {\n if (Array.isArray(parsed.roles) && parsed.roles.length) {\n await syncUserRoles(em, user, parsed.roles, tenantId)\n assignedRoles = await loadUserRoleNames(em, String(user.id))\n }\n },\n ], { transaction: true, label: 'auth.users.create' })\n\n await setCustomFieldsIfAny({\n dataEngine: de,\n entityId: E.auth.user,\n recordId: String(user.id),\n organizationId: user.organizationId ? String(user.organizationId) : null,\n tenantId: tenantId,\n values: custom,\n })\n\n let inviteEmailSent = false\n if (parsed.sendInviteEmail) {\n const inviteResult = await sendInviteToUser(em, user)\n inviteEmailSent = inviteResult.emailSent\n }\n\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'created',\n entity: user,\n identifiers: {\n id: String(user.id),\n organizationId: user.organizationId ? String(user.organizationId) : null,\n tenantId,\n },\n events: userCrudEvents,\n indexer: userCrudIndexer,\n })\n\n if (assignedRoles.length && !parsed.sendInviteEmail) {\n await notifyRoleChanges(ctx, user, assignedRoles, [])\n }\n\n const warning = (parsed.sendInviteEmail && !inviteEmailSent) ? 'invite_email_failed' as const : undefined\n\n return { user, warning }\n },\n captureAfter: async (_input, { user }, ctx) => {\n const em = resolveCommandEm(ctx, true)\n const roles = await loadUserRoleNames(em, String(user.id))\n const custom = await loadUserCustomSnapshot(\n em,\n String(user.id),\n user.tenantId ? String(user.tenantId) : null,\n user.organizationId ? String(user.organizationId) : null\n )\n return serializeUser(user, roles, custom)\n },\n buildLog: async ({ input, result: { user }, ctx }) => {\n const { translate } = await resolveTranslations()\n const em = resolveCommandEm(ctx, true)\n const roles = await loadUserRoleNames(em, String(user.id))\n const custom = await loadUserCustomSnapshot(\n em,\n String(user.id),\n user.tenantId ? String(user.tenantId) : null,\n user.organizationId ? String(user.organizationId) : null\n )\n const snapshot = captureUserSnapshots(user, roles, undefined, custom)\n // Creating a user is undoable no matter how the account got its credentials \u2014\n // the undo only deletes the row, and it needs no secret to do so. What must\n // never reach `action_logs` is the credential itself: the plaintext `password`\n // the caller sent (dropped from the redo input) and the derived `passwordHash`\n // (dropped from the undo snapshot). A redo therefore restores the original row\n // and id WITHOUT a password, and the account needs a reset to sign in again.\n const { password: _plaintextPassword, ...redoInput } = input\n return {\n redoInput,\n actionLabel: translate('auth.audit.users.create', 'Create user'),\n resourceKind: 'auth.user',\n resourceId: String(user.id),\n tenantId: user.tenantId ? String(user.tenantId) : null,\n organizationId: user.organizationId ? String(user.organizationId) : null,\n snapshotAfter: snapshot.view,\n payload: {\n undo: {\n after: withoutPasswordHash(snapshot.undo),\n },\n },\n }\n },\n undo: async ({ input, logEntry, ctx }) => {\n const userId = typeof logEntry?.resourceId === 'string' ? logEntry.resourceId : null\n if (!userId) return\n const snapshot = logEntry?.snapshotAfter as SerializedUser | undefined\n const em = resolveCommandEm(ctx)\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n\n // Evaluate the floor against the user's CURRENT tenant, not the one recorded at\n // creation. A user moved to another tenant after being created would otherwise be\n // checked against the origin tenant \u2014 where they no longer hold anything \u2014 and the\n // undo would hard-delete the destination tenant's last administrator unchecked.\n // The create snapshot is only a fallback for a row that is already gone.\n let removed: User | null = null\n await withAtomicFlush(em, [\n async () => {\n await authorizeUserReplayAtMutation('create', {\n operation: 'undo',\n input,\n ctx,\n logEntry,\n })\n const current = await findOneWithDecryption(em, User, { id: userId, deletedAt: null }, {}, { tenantId: null, organizationId: null })\n const floorTenantId = current?.tenantId ? String(current.tenantId) : (snapshot?.tenantId ?? null)\n\n // Undoing a create hard-deletes the user, so it can strip a tenant's last active\n // admin exactly like `auth.users.delete` can \u2014 promote a second admin, delete the\n // first, then undo the promotion's create. Same guard applies.\n await enforceProtectedRoleFloor(\n em,\n floorTenantId,\n userId,\n { deleting: true },\n ctx,\n requireReplayProtectedRoleIds(em, floorTenantId),\n )\n\n await lockUserRoleWriterAuthorizationState(em, { userIds: [userId], roleIds: [] })\n await em.nativeDelete(UserAcl, { user: userId })\n await em.nativeDelete(UserRole, { user: userId })\n await em.nativeDelete(Session, { user: userId })\n await em.nativeDelete(PasswordReset, { user: userId })\n await em.nativeDelete(UserSidebarPreference, { user: userId })\n await em.nativeDelete(SidebarVariant, { user: userId })\n\n if (snapshot?.custom && Object.keys(snapshot.custom).length) {\n const reset = buildCustomFieldResetMap(undefined, snapshot.custom)\n if (Object.keys(reset).length) {\n await setCustomFieldsIfAny({\n dataEngine: de,\n entityId: E.auth.user,\n recordId: userId,\n organizationId: snapshot.organizationId,\n tenantId: snapshot.tenantId,\n values: reset,\n notify: false,\n })\n }\n }\n removed = await de.deleteOrmEntity({\n entity: User,\n where: { id: userId, deletedAt: null } as FilterQuery<User>,\n soft: false,\n })\n },\n ], { transaction: true, label: 'auth.users.create.undo' })\n\n await emitCrudUndoSideEffects({\n dataEngine: de,\n action: 'deleted',\n entity: removed,\n identifiers: {\n id: userId,\n organizationId: snapshot?.organizationId ?? null,\n tenantId: snapshot?.tenantId ?? null,\n },\n events: userCrudEvents,\n indexer: userCrudIndexer,\n })\n\n await invalidateUserCache(ctx, userId)\n },\n // Restores the original stable id (#2506). The after-snapshot deliberately\n // carries no `passwordHash` (see buildLog), so a redone account comes back\n // without a credential and needs a password reset \u2014 redo never fabricates one\n // and never resurrects a hash from the audit log.\n redo: async ({ input, logEntry, ctx }) => {\n const after = resolveRedoSnapshot<UserUndoSnapshot>(logEntry)\n if (!after) throw new CrudHttpError(400, { error: '[internal] redo snapshot unavailable for user create' })\n const em = resolveCommandEm(ctx)\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n const emailHash = computeEmailHash(after.email)\n\n let user: User | null = null\n await withAtomicFlush(em, [\n async () => {\n await authorizeUserReplayAtMutation('create', {\n operation: 'redo',\n input,\n ctx,\n logEntry,\n })\n user = await findOneWithDecryption(em, User, { id: after.id }, {}, { tenantId: null, organizationId: null })\n if (user) {\n user.deletedAt = null\n user.email = after.email\n user.emailHash = emailHash\n user.organizationId = after.organizationId ?? null\n user.tenantId = after.tenantId ?? null\n // Only overwrite the credential when the snapshot actually recorded one;\n // an absent key means \"not captured\", never \"clear the password\".\n if ('passwordHash' in after) user.passwordHash = after.passwordHash ?? null\n user.name = after.name ?? null\n user.isConfirmed = after.isConfirmed\n await em.flush()\n } else {\n user = await de.createOrmEntity({\n entity: User,\n data: {\n id: after.id,\n email: after.email,\n emailHash,\n organizationId: after.organizationId ?? null,\n tenantId: after.tenantId ?? null,\n passwordHash: after.passwordHash ?? null,\n name: after.name ?? null,\n isConfirmed: after.isConfirmed,\n },\n })\n }\n\n if (!user) return\n\n await lockUserRoleWriterAuthorizationState(em, { userIds: [after.id], roleIds: [] })\n await em.nativeDelete(UserRole, { user: after.id })\n await syncUserRoles(em, user, after.roles, after.tenantId)\n await restoreUserAcls(em, user, after.acls)\n\n if (after.custom && Object.keys(after.custom).length) {\n const reset = buildCustomFieldResetMap(after.custom, undefined)\n if (Object.keys(reset).length) {\n await setCustomFieldsIfAny({\n dataEngine: de,\n entityId: E.auth.user,\n recordId: after.id,\n organizationId: after.organizationId ?? null,\n tenantId: after.tenantId ?? null,\n values: reset,\n notify: false,\n })\n }\n }\n },\n ], { transaction: true })\n\n if (!user) throw new CrudHttpError(400, { error: '[internal] redo failed to restore user row' })\n\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'created',\n entity: user,\n identifiers: {\n id: after.id,\n organizationId: after.organizationId ?? null,\n tenantId: after.tenantId ?? null,\n },\n events: userCrudEvents,\n indexer: userCrudIndexer,\n })\n\n await invalidateUserCache(ctx, after.id)\n\n return { user }\n },\n}\n\nasync function sendInviteToUser(\n em: EntityManager,\n user: User,\n): Promise<{ emailSent: boolean }> {\n const rawToken = generateAuthToken()\n const tokenHash = hashAuthToken(rawToken)\n const expiresAt = new Date(Date.now() + INVITE_TOKEN_TTL_MS)\n const row = em.create(PasswordReset, { user, token: tokenHash, expiresAt, createdAt: new Date() })\n await em.persist(row).flush()\n\n const base = getSecurityEmailBaseUrl()\n const inviteUrl = `${base}/reset/${rawToken}`\n\n const { translate } = await resolveTranslations()\n const subject = translate('auth.email.invite.subject', 'You have been invited')\n const copy = {\n preview: translate('auth.email.invite.preview', 'Set up your account'),\n title: translate('auth.email.invite.title', 'You have been invited'),\n body: translate('auth.email.invite.body', 'An administrator has created an account for you. Click the link below to set your password. This link will expire in 48 hours.'),\n cta: translate('auth.email.invite.cta', 'Set up your password'),\n hint: translate('auth.email.invite.hint', 'If you did not expect this invitation, you can safely ignore this email.'),\n }\n\n let emailSent = true\n try {\n await sendEmail({\n to: user.email,\n subject,\n react: InviteUserEmail({ inviteUrl, copy }),\n tenantId: user.tenantId ? String(user.tenantId) : undefined,\n organizationId: user.organizationId ? String(user.organizationId) : null,\n })\n } catch (err) {\n logger.error('Failed to send invitation email', { err })\n emailSent = false\n }\n\n return { emailSent }\n}\n\nfunction isUniqueViolation(error: unknown): boolean {\n if (error instanceof UniqueConstraintViolationException) return true\n if (!error || typeof error !== 'object') return false\n const code = (error as { code?: string }).code\n if (code === '23505') return true\n const messageRaw = (error as { message?: string })?.message\n const message = typeof messageRaw === 'string' ? messageRaw : ''\n return message.toLowerCase().includes('duplicate key')\n}\n\nconst updateUserCommand: CommandHandler<Record<string, unknown>, User> = {\n id: 'auth.users.update',\n atomicReplay: true,\n stabilizeReplay: (params) => stabilizeUserReplay('update', params),\n authorizeReplay: (params) => authorizeUserReplay('update', params),\n async prepare(rawInput, ctx) {\n const { parsed } = parseWithCustomFields(updateSchema, rawInput)\n const em = resolveCommandEm(ctx)\n const existing = await findOneWithDecryption(em, User, { id: parsed.id, deletedAt: null }, {}, { tenantId: null, organizationId: null })\n if (!existing) throw new CrudHttpError(404, { error: 'User not found' })\n assertTargetTenantInScope(resolveActorTenantScope(ctx), existing.tenantId, 'User not found')\n const roles = await loadUserRoleNames(em, parsed.id)\n const acls = await loadUserAclSnapshots(em, parsed.id)\n const custom = await loadUserCustomSnapshot(\n em,\n parsed.id,\n existing.tenantId ? String(existing.tenantId) : null,\n existing.organizationId ? String(existing.organizationId) : null\n )\n return { before: captureUserSnapshots(existing, roles, acls, custom) }\n },\n async execute(rawInput, ctx) {\n const { parsed, custom } = parseWithCustomFields(updateSchema, rawInput)\n const em = resolveCommandEm(ctx)\n const actorTenantScope = resolveActorTenantScope(ctx)\n const existing = await findOneWithDecryption(em, User, { id: parsed.id, deletedAt: null }, {}, { tenantId: null, organizationId: null })\n if (!existing) throw new CrudHttpError(404, { error: 'User not found' })\n if (actorTenantScope && existing.tenantId && String(existing.tenantId) !== actorTenantScope) {\n throw new CrudHttpError(404, { error: 'User not found' })\n }\n\n const rolesBefore = Array.isArray(parsed.roles)\n ? await loadUserRoleNames(em, parsed.id)\n : null\n\n let tenantId: string | null | undefined\n let destinationChanged = false\n if (parsed.organizationId !== undefined) {\n const organization = await findOneWithDecryption(\n em,\n Organization,\n { id: parsed.organizationId },\n { populate: ['tenant'] },\n { tenantId: null, organizationId: parsed.organizationId ?? null },\n )\n if (!organization) return throwUserDestinationOrganizationNotFound(400)\n tenantId = organization.tenant?.id ? String(organization.tenant.id) : null\n if (!tenantId) return throwUserDestinationOrganizationNotFound(400)\n const currentUser = await findOneWithDecryption(\n em,\n User,\n { id: parsed.id, deletedAt: null },\n {},\n { tenantId: null, organizationId: null },\n )\n if (!currentUser) throw new CrudHttpError(404, { error: 'User not found' })\n const currentOrganizationId = currentUser.organizationId ? String(currentUser.organizationId) : null\n const currentTenantId = currentUser.tenantId ? String(currentUser.tenantId) : null\n destinationChanged = currentOrganizationId !== parsed.organizationId || currentTenantId !== tenantId\n if (destinationChanged) {\n const destinationRoles = await resolveUserDestinationRoles({\n em,\n targetUserId: parsed.id,\n destinationTenantId: tenantId,\n roleTokens: parsed.roles,\n })\n await assertCommandActorCanAssignUserDestination(ctx, em, {\n destinationTenantId: tenantId,\n destinationOrganizationId: parsed.organizationId,\n roles: destinationRoles,\n })\n }\n }\n\n const userTenantId = existing.tenantId ? String(existing.tenantId) : null\n const targetTenantId = tenantId !== undefined ? tenantId : userTenantId\n const isTenantChanging = targetTenantId !== userTenantId\n\n // Hash password BEFORE transaction begins to avoid holding locks during CPU-heavy tasks\n let hashed: string | null = null\n let emailHash: string | null = null\n if (parsed.password) {\n const { hash } = await import('bcryptjs')\n hashed = await hash(parsed.password, 10)\n }\n if (parsed.email !== undefined) {\n emailHash = computeEmailHash(parsed.email)\n }\n\n const updateWhere: Record<string, unknown> = { id: parsed.id, deletedAt: null }\n if (actorTenantScope) updateWhere.tenantId = actorTenantScope\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n let user!: User\n\n await withAtomicFlush(em, [\n async () => {\n const redoLogEntry = (ctx as UserReplayRuntimeContext)[USER_REDO_LOG]\n if (redoLogEntry) {\n await authorizeUserReplayAtMutation('update', {\n operation: 'redo',\n input: rawInput,\n ctx,\n logEntry: redoLogEntry,\n })\n }\n const destinationRoles = parsed.roles\n ? await Promise.all(parsed.roles.map((role) => resolveRole(em, role, targetTenantId)))\n : []\n const floorOptions = {\n deactivating: parsed.isConfirmed === false || isTenantChanging,\n newRoles: parsed.roles,\n }\n const protectedRoleIds = redoLogEntry\n ? requireReplayProtectedRoleIds(em, userTenantId)\n : await discoverProtectedRoleIds(em, userTenantId, floorOptions, ctx)\n await lockUserRoleWriterAuthorizationState(em, {\n userIds: [parsed.id],\n roleIds: [\n ...destinationRoles\n .filter((role): role is Role => role !== null)\n .map((role) => String(role.id)),\n ...protectedRoleIds,\n ],\n })\n await enforceProtectedRoleFloor(\n em,\n userTenantId,\n parsed.id,\n floorOptions,\n ctx,\n protectedRoleIds,\n )\n\n // Email is unique per-tenant, not globally (see Migration20260610120000:\n // users_tenant_email_hash_uniq) \u2014 a matching email in another tenant must not block\n // the update or leak cross-tenant account existence (#2934). `targetTenantId` is the\n // tenant the user will belong to after this update, so the check follows a move.\n if (parsed.email !== undefined) {\n const duplicate = await findOneWithDecryption(\n em,\n User,\n {\n $or: [{ email: parsed.email }, { emailHash: { $in: emailHashLookupValues(parsed.email) } }],\n deletedAt: null,\n tenantId: targetTenantId,\n id: { $ne: parsed.id } as any,\n } as FilterQuery<User>,\n {},\n { tenantId: null, organizationId: null },\n )\n if (duplicate) await throwDuplicateEmailError()\n }\n\n try {\n const updated = await de.updateOrmEntity({\n entity: User,\n where: updateWhere as FilterQuery<User>,\n apply: (entity) => {\n if (parsed.email !== undefined) {\n entity.email = parsed.email\n entity.emailHash = emailHash\n }\n if (parsed.name !== undefined) {\n entity.name = parsed.name\n }\n if (parsed.organizationId !== undefined) {\n entity.organizationId = parsed.organizationId\n entity.tenantId = tenantId ?? null\n }\n if (parsed.isConfirmed !== undefined) {\n entity.isConfirmed = parsed.isConfirmed\n }\n if (hashed) entity.passwordHash = hashed\n },\n })\n if (updated) user = updated\n } catch (error) {\n if (isUniqueViolation(error)) await throwDuplicateEmailError()\n throw error\n }\n if (!user) throw new CrudHttpError(404, { error: 'User not found' })\n\n if (hashed || parsed.isConfirmed === false) {\n await em.nativeDelete(Session, { user: parsed.id })\n }\n\n if (Array.isArray(parsed.roles)) {\n await syncUserRoles(\n em,\n user,\n parsed.roles,\n user.tenantId ? String(user.tenantId) : tenantId ?? null,\n { authorizationStateLocked: true },\n )\n }\n\n await setCustomFieldsIfAny({\n dataEngine: de,\n entityId: E.auth.user,\n recordId: String(user.id),\n organizationId: user.organizationId ? String(user.organizationId) : null,\n tenantId: user.tenantId ? String(user.tenantId) : tenantId ?? null,\n values: custom,\n })\n }\n ], { transaction: true, label: destinationChanged ? 'auth.users.update.destination' : 'auth.users.update' })\n\n const identifiers = {\n id: String(user.id),\n organizationId: user.organizationId ? String(user.organizationId) : null,\n tenantId: user.tenantId ? String(user.tenantId) : tenantId ?? null,\n }\n\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'updated',\n entity: user,\n identifiers,\n events: userCrudEvents,\n indexer: userCrudIndexer,\n })\n\n if (hashed) {\n const actorId = ctx.auth?.sub ? String(ctx.auth.sub) : null\n // `system` covers a command invocation with no auth context and one running under\n // `ctx.systemActor`. Without it those writes would be indistinguishable from an\n // administrator setting someone else's password, which is exactly the case security\n // alerting escalates on. Password writes that never reach this command \u2014 `mercato\n // auth set-password`, tenant provisioning \u2014 set `passwordHash` directly and emit\n // nothing, so a subscriber cannot treat this event as covering every credential change.\n const changedBy = ctx.systemActor === true || !actorId\n ? 'system'\n : actorId === identifiers.id ? 'self' : 'admin'\n void emitAuthEvent('auth.password.changed', {\n id: identifiers.id,\n tenantId: identifiers.tenantId,\n organizationId: identifiers.organizationId,\n changedBy,\n changedById: actorId,\n at: new Date().toISOString(),\n }, { persistent: true }).catch(() => undefined)\n }\n\n if (Array.isArray(parsed.roles) && rolesBefore) {\n const rolesAfter = await loadUserRoleNames(em, String(user.id))\n const { assigned, revoked } = diffRoleChanges(rolesBefore, rolesAfter)\n if (assigned.length || revoked.length) {\n await notifyRoleChanges(ctx, user, assigned, revoked)\n }\n }\n\n await invalidateUserCache(ctx, parsed.id)\n\n return user\n },\n captureAfter: async (_input, result, ctx) => {\n const em = resolveCommandEm(ctx, true)\n const roles = await loadUserRoleNames(em, String(result.id))\n const custom = await loadUserCustomSnapshot(\n em,\n String(result.id),\n result.tenantId ? String(result.tenantId) : null,\n result.organizationId ? String(result.organizationId) : null\n )\n return serializeUser(result, roles, custom)\n },\n buildLog: async ({ input, result, snapshots, ctx }) => {\n const { translate } = await resolveTranslations()\n const beforeSnapshots = snapshots.before as UserSnapshots | undefined\n const before = beforeSnapshots?.view\n const beforeUndo = beforeSnapshots?.undo ?? null\n const em = resolveCommandEm(ctx, true)\n const afterRoles = await loadUserRoleNames(em, String(result.id))\n const afterCustom = await loadUserCustomSnapshot(\n em,\n String(result.id),\n result.tenantId ? String(result.tenantId) : null,\n result.organizationId ? String(result.organizationId) : null\n )\n const afterSnapshots = captureUserSnapshots(result, afterRoles, undefined, afterCustom)\n const after = afterSnapshots.view\n const changes = buildChanges(before ?? null, after as Record<string, unknown>, ['email', 'organizationId', 'tenantId', 'name', 'isConfirmed'])\n if (before && !arrayEquals(before.roles, afterRoles)) {\n changes.roles = { from: before.roles, to: afterRoles }\n }\n const customDiff = diffCustomFieldChanges(before?.custom, afterCustom)\n for (const [key, diff] of Object.entries(customDiff)) {\n changes[`cf_${key}`] = diff\n }\n const replayable = typeof input.password !== 'string' || input.password.length === 0\n return {\n replayable,\n actionLabel: translate('auth.audit.users.update', 'Update user'),\n resourceKind: 'auth.user',\n resourceId: String(result.id),\n tenantId: result.tenantId ? String(result.tenantId) : null,\n organizationId: result.organizationId ? String(result.organizationId) : null,\n changes,\n snapshotBefore: before ?? null,\n snapshotAfter: after,\n payload: replayable\n ? {\n undo: {\n before: withoutPasswordHash(beforeUndo),\n after: withoutPasswordHash(afterSnapshots.undo),\n },\n }\n : undefined,\n }\n },\n undo: async ({ input, logEntry, ctx }) => {\n const payload = extractUndoPayload<UndoPayload<UserUndoSnapshot>>(logEntry)\n const before = payload?.before\n const after = payload?.after\n if (!before) return\n const userId = before.id\n const storedReplayInput = extractStoredReplayInput(logEntry.commandPayload, logEntry)\n const replayInput = Object.keys(storedReplayInput).length\n ? storedReplayInput\n : deriveUserUpdateReplayInput(before, after ?? null)\n const em = resolveCommandEm(ctx)\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n\n // Reverting an update can drop the tenant below a protected role's floor just as the\n // forward path can \u2014 restoring an empty `before.roles` on what is now the last admin,\n // or restoring `isConfirmed: false`. Undo is reachable from the audit-log UI, so the\n // guard has to run here too, inside a transaction so the row lock is valid.\n const restoredTenantId = before.tenantId ? String(before.tenantId) : null\n\n let updated: User | null = null\n await withAtomicFlush(em, [\n async () => {\n await authorizeUserReplayAtMutation('update', {\n operation: 'undo',\n input,\n ctx,\n logEntry,\n })\n const current = await findOneWithDecryption(em, User, { id: userId, deletedAt: null }, {}, { tenantId: null, organizationId: null })\n const currentTenantId = current?.tenantId ? String(current.tenantId) : null\n\n await enforceProtectedRoleFloor(\n em,\n currentTenantId,\n userId,\n {\n deactivating:\n ('isConfirmed' in replayInput && before.isConfirmed === false)\n || ('organizationId' in replayInput && restoredTenantId !== currentTenantId),\n newRoles: Array.isArray(replayInput.roles) ? before.roles : undefined,\n },\n ctx,\n requireReplayProtectedRoleIds(em, currentTenantId),\n )\n\n updated = await de.updateOrmEntity({\n entity: User,\n where: { id: userId, deletedAt: null } as FilterQuery<User>,\n apply: (entity) => {\n if ('email' in replayInput) entity.email = before.email\n if ('organizationId' in replayInput) {\n entity.organizationId = before.organizationId ?? null\n entity.tenantId = before.tenantId ?? null\n }\n if ('name' in replayInput) entity.name = before.name ?? null\n if ('isConfirmed' in replayInput) entity.isConfirmed = before.isConfirmed\n },\n })\n\n if (updated && Array.isArray(replayInput.roles)) {\n await syncUserRoles(em, updated, before.roles, before.tenantId)\n }\n\n const reset = buildCustomFieldResetMap(before.custom, after?.custom)\n if (Object.keys(reset).length) {\n await setCustomFieldsIfAny({\n dataEngine: de,\n entityId: E.auth.user,\n recordId: before.id,\n organizationId: before.organizationId ?? null,\n tenantId: before.tenantId ?? null,\n values: reset,\n notify: false,\n })\n }\n },\n ], { transaction: true, label: 'auth.users.update.undo' })\n\n await emitCrudUndoSideEffects({\n dataEngine: de,\n action: 'updated',\n entity: updated,\n identifiers: {\n id: before.id,\n organizationId: before.organizationId ?? null,\n tenantId: before.tenantId ?? null,\n },\n events: userCrudEvents,\n indexer: userCrudIndexer,\n })\n\n await invalidateUserCache(ctx, userId)\n },\n redo: ({ input, ctx, logEntry }) => updateUserCommand.execute(\n input,\n withUserRedoLog(ctx, logEntry),\n ),\n}\n\nconst deleteUserCommand: CommandHandler<{ body?: Record<string, unknown>; query?: Record<string, unknown> }, User> = {\n id: 'auth.users.delete',\n atomicReplay: true,\n stabilizeReplay: (params) => stabilizeUserReplay('delete', params),\n authorizeReplay: (params) => authorizeUserReplay('delete', params),\n async prepare(input, ctx) {\n const id = requireId(input, 'User id required')\n const em = resolveCommandEm(ctx)\n const existing = await findOneWithDecryption(em, User, { id, deletedAt: null }, {}, { tenantId: null, organizationId: null })\n if (!existing) return {}\n const actorTenantScope = resolveActorTenantScope(ctx)\n if (actorTenantScope) {\n const targetTenant = normalizeTenantId(existing.tenantId) ?? null\n if (!targetTenant || targetTenant !== actorTenantScope) return {}\n }\n const roles = await loadUserRoleNames(em, id)\n const acls = await loadUserAclSnapshots(em, id)\n const custom = await loadUserCustomSnapshot(\n em,\n id,\n existing.tenantId ? String(existing.tenantId) : null,\n existing.organizationId ? String(existing.organizationId) : null\n )\n return { before: captureUserSnapshots(existing, roles, acls, custom) }\n },\n async execute(input, ctx) {\n const id = requireId(input, 'User id required')\n const em = resolveCommandEm(ctx)\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n const actorTenantScope = resolveActorTenantScope(ctx)\n\n const existing = await findOneWithDecryption(em, User, { id, deletedAt: null }, {}, { tenantId: null, organizationId: null })\n if (!existing) throw new CrudHttpError(404, { error: 'User not found' })\n if (actorTenantScope && existing.tenantId && String(existing.tenantId) !== actorTenantScope) {\n throw new CrudHttpError(404, { error: 'User not found' })\n }\n\n const deleteWhere: Record<string, unknown> = { id, deletedAt: null }\n if (actorTenantScope) deleteWhere.tenantId = actorTenantScope\n\n let user!: User\n await withAtomicFlush(em, [\n async () => {\n const redoLogEntry = (ctx as UserReplayRuntimeContext)[USER_REDO_LOG]\n if (redoLogEntry) {\n await authorizeUserReplayAtMutation('delete', {\n operation: 'redo',\n input,\n ctx,\n logEntry: redoLogEntry,\n })\n }\n const userTenantId = existing.tenantId ? String(existing.tenantId) : null\n const floorOptions = { deleting: true }\n const protectedRoleIds = redoLogEntry\n ? requireReplayProtectedRoleIds(em, userTenantId)\n : await discoverProtectedRoleIds(em, userTenantId, floorOptions, ctx)\n await lockUserRoleWriterAuthorizationState(em, {\n userIds: [id],\n roleIds: protectedRoleIds,\n })\n await enforceProtectedRoleFloor(\n em,\n userTenantId,\n id,\n floorOptions,\n ctx,\n protectedRoleIds,\n )\n\n await em.nativeDelete(UserAcl, { user: id })\n await em.nativeDelete(UserRole, { user: id })\n await em.nativeDelete(Session, { user: id })\n await em.nativeDelete(PasswordReset, { user: id })\n await em.nativeDelete(UserSidebarPreference, { user: id })\n await em.nativeDelete(SidebarVariant, { user: id })\n const removed = await de.deleteOrmEntity({\n entity: User,\n where: deleteWhere as FilterQuery<User>,\n soft: false,\n })\n if (!removed) throw new CrudHttpError(404, { error: 'User not found' })\n user = removed\n },\n ], { transaction: true })\n\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'deleted',\n entity: user,\n identifiers: {\n id: String(id),\n organizationId: user.organizationId ? String(user.organizationId) : null,\n tenantId: user.tenantId ? String(user.tenantId) : null,\n },\n events: userCrudEvents,\n indexer: userCrudIndexer,\n })\n\n await invalidateUserCache(ctx, id)\n\n return user\n },\n buildLog: async ({ snapshots, input, ctx }) => {\n const { translate } = await resolveTranslations()\n const beforeSnapshots = snapshots.before as UserSnapshots | undefined\n const before = beforeSnapshots?.view\n const beforeUndo = beforeSnapshots?.undo ?? null\n const id = requireId(input, 'User id required')\n return {\n actionLabel: translate('auth.audit.users.delete', 'Delete user'),\n resourceKind: 'auth.user',\n resourceId: id,\n snapshotBefore: before ?? null,\n tenantId: before?.tenantId ?? null,\n organizationId: before?.organizationId ?? null,\n payload: {\n undo: {\n before: beforeUndo,\n },\n },\n }\n },\n undo: async ({ input, logEntry, ctx }) => {\n const payload = extractUndoPayload<UndoPayload<UserUndoSnapshot>>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = resolveCommandEm(ctx)\n let user: User | null = null\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n\n await withAtomicFlush(em, [\n async () => {\n await authorizeUserReplayAtMutation('delete', {\n operation: 'undo',\n input,\n ctx,\n logEntry,\n })\n user = await findOneWithDecryption(em, User, { id: before.id }, {}, { tenantId: null, organizationId: null })\n if (user) {\n if (user.deletedAt) {\n user.deletedAt = null\n }\n user.email = before.email\n user.organizationId = before.organizationId ?? null\n user.tenantId = before.tenantId ?? null\n user.passwordHash = before.passwordHash ?? null\n user.name = before.name ?? null\n user.isConfirmed = before.isConfirmed\n await em.flush()\n } else {\n user = await de.createOrmEntity({\n entity: User,\n data: {\n id: before.id,\n email: before.email,\n organizationId: before.organizationId ?? null,\n tenantId: before.tenantId ?? null,\n passwordHash: before.passwordHash ?? null,\n name: before.name ?? null,\n isConfirmed: before.isConfirmed,\n },\n })\n }\n\n if (!user) return\n\n await lockUserRoleWriterAuthorizationState(em, { userIds: [before.id], roleIds: [] })\n await em.nativeDelete(UserRole, { user: before.id })\n await syncUserRoles(em, user, before.roles, before.tenantId)\n\n await restoreUserAcls(em, user, before.acls)\n\n const reset = buildCustomFieldResetMap(before.custom, undefined)\n if (Object.keys(reset).length) {\n await setCustomFieldsIfAny({\n dataEngine: de,\n entityId: E.auth.user,\n recordId: before.id,\n organizationId: before.organizationId ?? null,\n tenantId: before.tenantId ?? null,\n values: reset,\n notify: false,\n })\n }\n },\n ], { transaction: true })\n\n await invalidateUserCache(ctx, before.id)\n },\n redo: ({ input, ctx, logEntry }) => deleteUserCommand.execute(\n input,\n withUserRedoLog(ctx, logEntry),\n ),\n}\n\ntype UserReplayCommandKind = 'create' | 'update' | 'delete'\n\nfunction withoutPasswordHash(snapshot: UserUndoSnapshot | null): UserUndoSnapshot | null {\n if (!snapshot) return null\n const safeSnapshot = { ...snapshot }\n delete safeSnapshot.passwordHash\n return safeSnapshot\n}\n\nfunction normalizeUserAclSnapshots(acls: UserAclSnapshot[]): UserAclSnapshot[] {\n return acls\n .map((acl) => ({\n ...acl,\n features: acl.features ? [...acl.features].sort((left, right) => left.localeCompare(right)) : null,\n organizations: acl.organizations ? [...acl.organizations].sort((left, right) => left.localeCompare(right)) : null,\n }))\n .sort((left, right) => left.tenantId.localeCompare(right.tenantId))\n}\n\nfunction normalizeUserReplaySnapshot(snapshot: UserUndoSnapshot): UserUndoSnapshot {\n // The credential never takes part in the \"has the target changed?\" comparison.\n // A create's stored snapshot deliberately omits `passwordHash` (it must not sit\n // in `action_logs`), so comparing it against a live snapshot that still carries\n // the hash would report every password-bearing account as changed and refuse\n // the replay.\n return withoutPasswordHash({\n ...snapshot,\n roles: [...snapshot.roles].sort((left, right) => left.localeCompare(right)),\n acls: normalizeUserAclSnapshots(snapshot.acls),\n }) as UserUndoSnapshot\n}\n\nfunction toUserUpdateReplayState(snapshot: UserUndoSnapshot): SerializedUser {\n return {\n email: snapshot.email,\n organizationId: snapshot.organizationId,\n tenantId: snapshot.tenantId,\n roles: [...snapshot.roles].sort((left, right) => left.localeCompare(right)),\n name: snapshot.name,\n isConfirmed: snapshot.isConfirmed,\n ...(snapshot.custom && Object.keys(snapshot.custom).length ? { custom: snapshot.custom } : {}),\n }\n}\n\nfunction deriveUserUpdateReplayInput(\n before: UserUndoSnapshot | null,\n after: UserUndoSnapshot | null,\n): Record<string, unknown> {\n if (!before) return {}\n if (!after) {\n return {\n id: before.id,\n email: before.email,\n organizationId: before.organizationId,\n name: before.name,\n isConfirmed: before.isConfirmed,\n roles: before.roles,\n }\n }\n const input: Record<string, unknown> = { id: after.id }\n if (before.email !== after.email) input.email = after.email\n if (before.organizationId !== after.organizationId || before.tenantId !== after.tenantId) {\n input.organizationId = after.organizationId\n }\n if (before.name !== after.name) input.name = after.name\n if (before.isConfirmed !== after.isConfirmed) input.isConfirmed = after.isConfirmed\n if (!arrayEquals(before.roles, after.roles)) input.roles = after.roles\n return input\n}\n\nfunction isSelfProfileReplay(\n input: Record<string, unknown>,\n ctx: CommandRuntimeContext,\n userId: string,\n): boolean {\n if (!ctx.auth?.sub || ctx.auth.sub !== userId) return false\n const allowedKeys = new Set(['id', 'email', 'password'])\n return Object.keys(input).every((key) => allowedKeys.has(key) || input[key] === undefined)\n}\n\nasync function authorizeUserReplay(\n commandKind: UserReplayCommandKind,\n params: CommandReplayAuthorizationArgs<unknown>,\n): Promise<void> {\n const { operation, ctx, logEntry } = params\n const undoPayload = extractUndoPayload<UndoPayload<UserUndoSnapshot>>(logEntry)\n const before = undoPayload?.before ?? null\n const after = undoPayload?.after ?? null\n const passwordHashChanged = Boolean(\n commandKind === 'update'\n && before\n && after\n && 'passwordHash' in before\n && 'passwordHash' in after\n && before.passwordHash !== after.passwordHash,\n )\n const createdWithPassword = commandKind === 'create' && Boolean(\n hasStoredPasswordInput(params.input, logEntry)\n || (after && typeof after.passwordHash === 'string' && after.passwordHash.length > 0),\n )\n if (\n createdWithPassword\n || (commandKind === 'update' && (hasStoredPasswordInput(params.input, logEntry) || passwordHashChanged))\n ) {\n await denyCredentialReplay()\n }\n const userId = logEntry.resourceId ?? before?.id ?? after?.id ?? null\n if (!userId) {\n await assertReplaySnapshotMatches(null, { required: 'user replay snapshot' })\n return\n }\n\n const storedReplayInput = extractStoredReplayInput(params.input, logEntry)\n const replayInput = Object.keys(storedReplayInput).length\n ? storedReplayInput\n : deriveUserUpdateReplayInput(before, after)\n const requiredFeature = commandKind === 'create'\n ? operation === 'undo' ? 'auth.users.delete' : 'auth.users.create'\n : commandKind === 'delete'\n ? operation === 'undo' ? 'auth.users.create' : 'auth.users.delete'\n : 'auth.users.edit'\n const em = requireTransactionalReplayEntityManager(ctx)\n if (commandKind !== 'update' || !isSelfProfileReplay(replayInput, ctx, userId)) {\n await requireCurrentReplayFeature(ctx, requiredFeature)\n }\n\n const currentUser = await findOneWithDecryption(\n em,\n User,\n { id: userId, deletedAt: null },\n {},\n { tenantId: null, organizationId: null },\n )\n const rbacService = ctx.systemActor === true\n ? null\n : ctx.container.resolve('rbacService') as RbacService\n\n if (rbacService && currentUser) {\n const allowedIds = ctx.organizationScope?.allowedIds\n ?? ctx.organizationIds\n ?? (ctx.auth?.orgId ? [ctx.auth.orgId] : null)\n await assertActorCanAccessUserTarget({\n em,\n rbacService,\n requireBoundRbac: true,\n actorUserId: ctx.auth?.sub,\n tenantId: ctx.auth?.tenantId ?? null,\n organizationId: ctx.auth?.orgId ?? null,\n organizationScope: { allowedIds },\n targetUserId: userId,\n })\n await assertActorCanModifySuperAdminUserTarget({\n em,\n rbacService,\n requireBoundRbac: true,\n actorUserId: ctx.auth?.sub,\n tenantId: ctx.auth?.tenantId ?? null,\n organizationId: ctx.auth?.orgId ?? null,\n targetUserId: userId,\n })\n }\n\n let currentSnapshot: UserUndoSnapshot | null = null\n if (currentUser) {\n const currentTenantId = currentUser.tenantId ? String(currentUser.tenantId) : null\n const currentOrganizationId = currentUser.organizationId ? String(currentUser.organizationId) : null\n const [roles, acls, custom] = await Promise.all([\n loadUserRoleNames(em, userId),\n loadUserAclSnapshots(em, userId),\n loadUserCustomSnapshot(em, userId, currentTenantId, currentOrganizationId),\n ])\n currentSnapshot = captureUserSnapshots(currentUser, roles, acls, custom).undo\n }\n\n const expectedCurrent = operation === 'undo'\n ? commandKind === 'create' ? after : commandKind === 'update' ? after : null\n : commandKind === 'create' ? null : before\n\n if (commandKind === 'update') {\n if (!currentSnapshot || !expectedCurrent) {\n await assertReplaySnapshotMatches(currentSnapshot, expectedCurrent)\n } else {\n await assertReplaySnapshotMatches(\n toUserUpdateReplayState(currentSnapshot),\n toUserUpdateReplayState(expectedCurrent),\n )\n }\n } else {\n await assertReplaySnapshotMatches(\n currentSnapshot ? normalizeUserReplaySnapshot(currentSnapshot) : null,\n expectedCurrent ? normalizeUserReplaySnapshot(expectedCurrent) : null,\n )\n }\n\n const desiredState = operation === 'undo'\n ? commandKind === 'create' ? null : before\n : commandKind === 'delete' ? null : after\n if (!desiredState || !rbacService) return\n\n const restoresMembership = commandKind !== 'update'\n || Array.isArray(replayInput.roles)\n || 'organizationId' in replayInput\n if (restoresMembership) {\n const roles = await assertActorCanGrantRoleTokens({\n em,\n rbacService,\n requireBoundRbac: true,\n actorUserId: ctx.auth?.sub,\n tenantId: desiredState.tenantId,\n organizationId: desiredState.organizationId,\n roleTokens: desiredState.roles,\n })\n await assertActorCanAssignUserDestination({\n em,\n rbacService,\n requireBoundRbac: true,\n actorUserId: ctx.auth?.sub,\n tenantId: ctx.auth?.tenantId ?? null,\n organizationId: ctx.auth?.orgId ?? null,\n allowedOrganizationIds: ctx.organizationScope?.allowedIds ?? ctx.organizationIds,\n destinationTenantId: desiredState.tenantId,\n destinationOrganizationId: desiredState.organizationId,\n roles,\n })\n }\n\n const restoresAcls = commandKind !== 'update' && desiredState.acls.length > 0\n if (!restoresAcls) return\n await requireCurrentReplayFeature(ctx, 'auth.acl.manage')\n for (const acl of desiredState.acls) {\n await assertActorCanGrantAcl({\n em,\n rbacService,\n requireBoundRbac: true,\n actorUserId: ctx.auth?.sub,\n tenantId: acl.tenantId,\n organizationId: desiredState.organizationId,\n features: acl.features,\n isSuperAdmin: acl.isSuperAdmin,\n organizations: acl.organizations,\n })\n }\n}\n\nasync function authorizeUserReplayAtMutation(\n commandKind: UserReplayCommandKind,\n params: CommandReplayAuthorizationArgs<unknown>,\n): Promise<void> {\n const em = params.ctx.transactionalEm\n ?? params.ctx.container.resolve('em') as EntityManager\n const boundParams = params.ctx.transactionalEm\n ? params\n : { ...params, ctx: { ...params.ctx, transactionalEm: em } }\n await stabilizeUserReplay(commandKind, boundParams)\n await rerunReplayTransactionGuardAfterLocks(boundParams, em)\n await authorizeUserReplay(commandKind, boundParams)\n}\n\nasync function stabilizeUserReplay(\n commandKind: UserReplayCommandKind,\n params: CommandReplayAuthorizationArgs<unknown>,\n): Promise<void> {\n const undoPayload = extractUndoPayload<UndoPayload<UserUndoSnapshot>>(params.logEntry)\n const before = undoPayload?.before ?? null\n const after = undoPayload?.after ?? null\n const passwordHashChanged = Boolean(\n commandKind === 'update'\n && before\n && after\n && 'passwordHash' in before\n && 'passwordHash' in after\n && before.passwordHash !== after.passwordHash,\n )\n const createdWithPassword = commandKind === 'create' && Boolean(\n hasStoredPasswordInput(params.input, params.logEntry)\n || (after && typeof after.passwordHash === 'string' && after.passwordHash.length > 0),\n )\n if (\n createdWithPassword\n || (commandKind === 'update' && (hasStoredPasswordInput(params.input, params.logEntry) || passwordHashChanged))\n ) {\n await denyCredentialReplay()\n }\n const targetUserId = params.logEntry.resourceId ?? before?.id ?? after?.id ?? null\n const em = requireTransactionalReplayEntityManager(params.ctx)\n const transactionLifetime = getTransactionLifetime(em)\n if (!transactionLifetime) {\n throw new Error('[internal] Replay protected-role locks require an explicit transaction lifetime')\n }\n const existingProtectedRoleIdsByTenant = replayProtectedRoleIdsByTenant.get(transactionLifetime)\n const currentTarget = targetUserId\n ? await findOneWithDecryption(\n em,\n User,\n { id: targetUserId },\n {},\n { tenantId: null, organizationId: null },\n )\n : null\n const currentTargetTenantId = normalizeTenantId(currentTarget?.tenantId) ?? null\n const relevantTenantIds = existingProtectedRoleIdsByTenant\n ? Array.from(existingProtectedRoleIdsByTenant.keys()).sort((left, right) => left.localeCompare(right))\n : Array.from(new Set([\n normalizeTenantId(params.ctx.auth?.tenantId) ?? null,\n normalizeTenantId(before?.tenantId) ?? null,\n normalizeTenantId(after?.tenantId) ?? null,\n normalizeTenantId(params.logEntry.tenantId) ?? null,\n currentTargetTenantId,\n ].filter((tenantId): tenantId is string => tenantId !== null))).sort((left, right) => left.localeCompare(right))\n const protectedRoleIdsByTenant = new Map(existingProtectedRoleIdsByTenant ?? [])\n if (!existingProtectedRoleIdsByTenant) {\n for (const tenantId of relevantTenantIds) {\n protectedRoleIdsByTenant.set(\n tenantId,\n await discoverProtectedRoleIds(em, tenantId, { deleting: true }, params.ctx),\n )\n }\n }\n const roleIds: string[] = []\n const seenRoleTokens = new Set<string>()\n for (const snapshot of [before, after]) {\n if (!snapshot?.tenantId) continue\n for (const token of snapshot.roles) {\n const key = `${snapshot.tenantId}:${token}`\n if (seenRoleTokens.has(key)) continue\n seenRoleTokens.add(key)\n const role = await resolveRole(em, token, snapshot.tenantId)\n if (role?.id) roleIds.push(String(role.id))\n }\n }\n await lockReplayAuthorizationState(em, params.ctx, {\n targetUserIds: targetUserId ? [targetUserId] : [],\n targetRoleIds: [\n ...roleIds,\n ...Array.from(protectedRoleIdsByTenant.values()).flat(),\n ],\n targetTenantIds: relevantTenantIds,\n })\n replayProtectedRoleIdsByTenant.set(transactionLifetime, protectedRoleIdsByTenant)\n}\n\nregisterCommand(createUserCommand)\nregisterCommand(updateUserCommand)\nregisterCommand(deleteUserCommand)\n\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i\n\nasync function resolveRole(\n em: EntityManager,\n value: string,\n normalizedTenantId: string | null,\n): Promise<Role | null> {\n if (UUID_RE.test(value)) {\n const where: Record<string, unknown> = { id: value }\n if (normalizedTenantId !== null) {\n where.tenantId = normalizedTenantId\n }\n return findOneWithDecryption(em, Role, where as any, {}, { tenantId: normalizedTenantId, organizationId: null })\n }\n return findOneWithDecryption(em, Role, { name: value, tenantId: normalizedTenantId }, {}, { tenantId: normalizedTenantId, organizationId: null })\n}\n\nasync function syncUserRoles(\n em: EntityManager,\n user: User,\n desiredRoles: string[],\n tenantId: string | null,\n options: { authorizationStateLocked?: boolean } = {},\n) {\n const userId = String(user.id)\n const unique = Array.from(new Set(desiredRoles.map((role) => role.trim()).filter(Boolean)))\n const normalizedTenantId = normalizeTenantId(tenantId ?? null) ?? null\n\n const resolvedRoles: Role[] = []\n const missingRoles: string[] = []\n for (const value of unique) {\n const role = await resolveRole(em, value, normalizedTenantId)\n if (!role) {\n missingRoles.push(value)\n } else {\n resolvedRoles.push(role)\n }\n }\n\n if (missingRoles.length) {\n const labels = missingRoles.map((n) => `\"${n}\"`).join(', ')\n throw new CrudHttpError(400, { error: `Role(s) not found: ${labels}` })\n }\n\n const discoveredLinks = await findWithDecryption(\n em,\n UserRole,\n { user },\n { orderBy: { id: 'ASC' } },\n { tenantId: null, organizationId: null },\n )\n const discoveredRoleIds = discoveredLinks\n .map((link) => String(link.role?.id ?? (link.role as unknown as string) ?? ''))\n .filter(Boolean)\n const desiredIds = new Set(resolvedRoles.map((role) => String(role.id)))\n if (!options.authorizationStateLocked) {\n await lockUserRoleWriterAuthorizationState(em, {\n userIds: [userId],\n roleIds: [...desiredIds, ...discoveredRoleIds],\n })\n }\n const currentLinks = await findWithDecryption(\n em,\n UserRole,\n { user, deletedAt: null, role: { deletedAt: null } } as FilterQuery<UserRole>,\n { lockMode: LockMode.PESSIMISTIC_WRITE, orderBy: { id: 'ASC' }, refresh: true },\n { tenantId: null, organizationId: null },\n )\n const currentRoleIds = new Map(\n currentLinks.map((link) => {\n const roleId = String(link.role?.id ?? (link.role as unknown as string) ?? '')\n return [roleId, link] as const\n }),\n )\n\n for (const [roleId, link] of currentRoleIds.entries()) {\n if (!desiredIds.has(roleId) && link) {\n em.remove(link)\n }\n }\n\n for (const role of resolvedRoles) {\n if (!currentRoleIds.has(String(role.id))) {\n em.persist(em.create(UserRole, { user, role, createdAt: new Date() }))\n }\n }\n\n await em.flush()\n}\n\nasync function loadUserRoleNames(em: EntityManager, userId: string): Promise<string[]> {\n const links = await findWithDecryption(\n em,\n UserRole,\n {\n user: userId as unknown as User,\n deletedAt: null,\n role: { deletedAt: null },\n } as FilterQuery<UserRole>,\n { populate: ['role'] },\n { tenantId: null, organizationId: null },\n )\n const names = links\n .map((link) => link.role?.name ?? '')\n .filter((name): name is string => !!name)\n return Array.from(new Set(names)).sort((a, b) => a.localeCompare(b))\n}\n\nfunction serializeUser(user: User, roles: string[], custom?: Record<string, unknown> | null): SerializedUser {\n const payload: SerializedUser = {\n email: String(user.email ?? ''),\n organizationId: user.organizationId ? String(user.organizationId) : null,\n tenantId: user.tenantId ? String(user.tenantId) : null,\n roles,\n name: user.name ? String(user.name) : null,\n isConfirmed: Boolean(user.isConfirmed),\n }\n if (custom && Object.keys(custom).length) payload.custom = custom\n return payload\n}\n\nfunction captureUserSnapshots(\n user: User,\n roles: string[],\n acls: UserAclSnapshot[] = [],\n custom?: Record<string, unknown> | null\n): UserSnapshots {\n return {\n view: serializeUser(user, roles, custom),\n undo: {\n id: String(user.id),\n email: String(user.email ?? ''),\n organizationId: user.organizationId ? String(user.organizationId) : null,\n tenantId: user.tenantId ? String(user.tenantId) : null,\n passwordHash: user.passwordHash ? String(user.passwordHash) : null,\n name: user.name ? String(user.name) : null,\n isConfirmed: Boolean(user.isConfirmed),\n roles: [...roles],\n acls,\n ...(custom && Object.keys(custom).length ? { custom } : {}),\n },\n }\n}\n\nasync function loadUserAclSnapshots(em: EntityManager, userId: string): Promise<UserAclSnapshot[]> {\n const list = await findWithDecryption(em, UserAcl, { user: userId as unknown as User, deletedAt: null }, {}, { tenantId: null, organizationId: null })\n return list.map((acl) => ({\n tenantId: String(acl.tenantId),\n features: Array.isArray(acl.featuresJson) ? [...acl.featuresJson] : null,\n isSuperAdmin: Boolean(acl.isSuperAdmin),\n organizations: Array.isArray(acl.organizationsJson) ? [...acl.organizationsJson] : null,\n }))\n}\n\nasync function restoreUserAcls(em: EntityManager, user: User, acls: UserAclSnapshot[]) {\n await lockUserRoleWriterAuthorizationState(em, { userIds: [String(user.id)], roleIds: [] })\n await em.nativeDelete(UserAcl, { user: String(user.id) })\n for (const acl of acls) {\n const entity = em.create(UserAcl, {\n user,\n tenantId: acl.tenantId,\n featuresJson: acl.features ?? null,\n isSuperAdmin: acl.isSuperAdmin,\n organizationsJson: acl.organizations ?? null,\n createdAt: new Date(),\n })\n em.persist(entity)\n }\n await em.flush()\n}\n\nasync function loadUserCustomSnapshot(\n em: EntityManager,\n id: string,\n tenantId: string | null,\n organizationId: string | null\n): Promise<Record<string, unknown>> {\n return await loadCustomFieldSnapshot(em, {\n entityId: E.auth.user,\n recordId: id,\n tenantId,\n organizationId,\n })\n}\n\nasync function invalidateUserCache(ctx: CommandRuntimeContext, userId: string) {\n try {\n const rbacService = ctx.container.resolve('rbacService') as { invalidateUserCache: (uid: string) => Promise<void> }\n await rbacService.invalidateUserCache(userId)\n } catch {\n // RBAC not available\n }\n\n try {\n const cache = ctx.container.resolve('cache') as { deleteByTags?: (tags: string[]) => Promise<void> }\n if (cache?.deleteByTags) await cache.deleteByTags([`rbac:user:${userId}`])\n } catch {\n // cache not available\n }\n}\n\nfunction diffRoleChanges(before: string[], after: string[]) {\n const beforeSet = new Set(before)\n const afterSet = new Set(after)\n const assigned = after.filter((role) => !beforeSet.has(role))\n const revoked = before.filter((role) => !afterSet.has(role))\n return { assigned, revoked }\n}\n\nfunction arrayEquals(left: string[] | undefined, right: string[]): boolean {\n if (!left) return false\n if (left.length !== right.length) return false\n return left.every((value, idx) => value === right[idx])\n}\n\nasync function throwDuplicateEmailError(): Promise<never> {\n const { translate } = await resolveTranslations()\n const message = translate('auth.users.errors.emailExists', 'Email already in use')\n throw new CrudHttpError(400, {\n error: message,\n fieldErrors: { email: message },\n details: [{ path: ['email'], message, code: 'duplicate', origin: 'validation' }],\n })\n}\n\ntype ProtectedRoleFloorOptions = {\n deactivating?: boolean\n newRoles?: string[]\n deleting?: boolean\n}\n\n/**\n * True when the requested mutation can lower a role's active holder count. Guards the\n * floor check so that ordinary edits (display name, password, email) never take the\n * tenant-wide role lock \u2014 `PUT /api/auth/profile` routes every self-service password\n * change through `auth.users.update`, so an unconditional lock would serialize them.\n */\nfunction couldReduceActiveHolders(options: ProtectedRoleFloorOptions): boolean {\n return options.deleting === true || options.deactivating === true || options.newRoles !== undefined\n}\n\nasync function discoverProtectedRoleIds(\n em: EntityManager,\n tenantId: string | null,\n options: ProtectedRoleFloorOptions,\n ctx?: CommandRuntimeContext,\n): Promise<string[]> {\n if (ctx?.systemActor === true || !couldReduceActiveHolders(options)) return []\n const normalizedTenantId = normalizeTenantId(tenantId) ?? null\n if (!normalizedTenantId) return []\n const roles = await findWithDecryption(em, Role, {\n tenantId: normalizedTenantId,\n minActiveHolders: { $gt: 0 },\n deletedAt: null,\n }, { orderBy: { id: 'ASC' } }, { tenantId: normalizedTenantId, organizationId: null })\n return roles.map((role) => String(role.id))\n}\n\nfunction requireReplayProtectedRoleIds(\n em: EntityManager,\n tenantId: string | null,\n): readonly string[] {\n const normalizedTenantId = normalizeTenantId(tenantId) ?? null\n if (!normalizedTenantId) return []\n const transactionLifetime = getTransactionLifetime(em)\n const roleIds = transactionLifetime\n ? replayProtectedRoleIdsByTenant.get(transactionLifetime)?.get(normalizedTenantId)\n : undefined\n if (!roleIds) {\n throw new Error(`[internal] Replay protected-role lock footprint is missing tenant ${normalizedTenantId}`)\n }\n return roleIds\n}\n\nasync function enforceProtectedRoleFloor(\n em: EntityManager,\n tenantId: string | null,\n userId: string,\n options: ProtectedRoleFloorOptions,\n ctx?: CommandRuntimeContext,\n lockedProtectedRoleIds?: readonly string[],\n): Promise<void> {\n // Internal automation (CLI, migrations, tenant teardown) must never be blocked by the\n // floor. Superadmins are deliberately NOT exempt \u2014 see the spec's Risks section.\n if (ctx?.systemActor === true) return\n if (!couldReduceActiveHolders(options)) return\n\n const normalizedTenantId = normalizeTenantId(tenantId) ?? null\n if (!normalizedTenantId) return\n\n const protectedRoles = lockedProtectedRoleIds\n ? await findWithDecryption(em, Role, {\n id: { $in: [...lockedProtectedRoleIds] },\n tenantId: normalizedTenantId,\n minActiveHolders: { $gt: 0 },\n deletedAt: null,\n }, {\n orderBy: { id: 'ASC' },\n refresh: true,\n }, { tenantId: normalizedTenantId, organizationId: null })\n : await findWithDecryption(em, Role, {\n tenantId: normalizedTenantId,\n minActiveHolders: { $gt: 0 },\n deletedAt: null,\n }, {\n lockMode: LockMode.PESSIMISTIC_WRITE,\n orderBy: { id: 'ASC' },\n }, { tenantId: normalizedTenantId, organizationId: null })\n\n if (protectedRoles.length === 0) return\n\n const { translate } = await resolveTranslations()\n\n for (const role of protectedRoles) {\n const minFloor = role.minActiveHolders ?? 0\n if (minFloor <= 0) continue\n\n // Active links for this role, scoped to the tenant by the nested user filter so the\n // database \u2014 not a post-filter \u2014 enforces isolation. Deliberately NOT populated:\n // `findWithDecryption` runs `decryptEntityGraph` over loaded relations, which would\n // decrypt every admin's email and name on each check just to read their ids.\n const activeLinks = await findWithDecryption(em, UserRole, {\n role: role.id,\n deletedAt: null,\n user: {\n deletedAt: null,\n isConfirmed: true,\n tenantId: normalizedTenantId\n }\n }, {}, { tenantId: null, organizationId: null })\n\n // Count distinct user IDs in the tenant holding this role to prevent overcounting due to duplicate links\n const activeUserIds = Array.from(\n new Set(\n activeLinks\n .map((link) => {\n const userRef = link.user as unknown as { id?: string } | string | null | undefined\n const linkedUserId = typeof userRef === 'string' ? userRef : userRef?.id\n return linkedUserId ? String(linkedUserId) : null\n })\n .filter((id): id is string => !!id)\n )\n )\n\n // Is the target user currently one of the active holders?\n if (activeUserIds.includes(userId)) {\n // Determine if they will remain an active holder\n let willStillBeActiveHolder = true\n\n if (options.deleting || options.deactivating) {\n willStillBeActiveHolder = false\n } else if (options.newRoles !== undefined) {\n // Checking role list\n const desiredUnique = Array.from(new Set(options.newRoles.map((r) => r.trim().toLowerCase()).filter(Boolean)))\n const roleNameLower = role.name.toLowerCase()\n const hasRoleByName = desiredUnique.includes(roleNameLower) || desiredUnique.includes(String(role.id).toLowerCase())\n if (!hasRoleByName) {\n willStillBeActiveHolder = false\n }\n }\n\n if (!willStillBeActiveHolder) {\n const remaining = activeUserIds.length - 1\n if (remaining < minFloor) {\n throw new CrudHttpError(400, {\n error: translate('auth.users.errors.lastHolderOfCriticalRole', 'Cannot remove the last active holder of role \"{roleName}\"', { roleName: role.name })\n })\n }\n }\n }\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }