@open-mercato/core 0.5.1-develop.2691.d8a0934b37 → 0.5.1-develop.2694.732417c5ec
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.
- package/dist/modules/api_keys/data/entities.js +1 -1
- package/dist/modules/api_keys/data/entities.js.map +1 -1
- package/dist/modules/api_keys/services/apiKeyService.js +5 -5
- package/dist/modules/api_keys/services/apiKeyService.js.map +2 -2
- package/dist/modules/attachments/api/library/[id]/route.js +1 -1
- package/dist/modules/attachments/api/library/[id]/route.js.map +2 -2
- package/dist/modules/attachments/api/library/route.js +7 -9
- package/dist/modules/attachments/api/library/route.js.map +2 -2
- package/dist/modules/attachments/api/partitions/route.js +3 -3
- package/dist/modules/attachments/api/partitions/route.js.map +2 -2
- package/dist/modules/attachments/api/route.js +6 -5
- package/dist/modules/attachments/api/route.js.map +2 -2
- package/dist/modules/attachments/api/transfer/route.js +1 -1
- package/dist/modules/attachments/api/transfer/route.js.map +2 -2
- package/dist/modules/attachments/data/entities.js +2 -1
- package/dist/modules/attachments/data/entities.js.map +2 -2
- package/dist/modules/attachments/lib/ocrQueue.js +1 -1
- package/dist/modules/attachments/lib/ocrQueue.js.map +2 -2
- package/dist/modules/audit_logs/api/audit-logs/actions/export/route.js.map +2 -2
- package/dist/modules/audit_logs/api/audit-logs/actions/route.js.map +2 -2
- package/dist/modules/audit_logs/data/entities.js +1 -1
- package/dist/modules/audit_logs/data/entities.js.map +1 -1
- package/dist/modules/audit_logs/services/actionLogService.js +77 -70
- package/dist/modules/audit_logs/services/actionLogService.js.map +2 -2
- package/dist/modules/auth/api/roles/acl/route.js +1 -1
- package/dist/modules/auth/api/roles/acl/route.js.map +2 -2
- package/dist/modules/auth/api/users/acl/route.js +2 -2
- package/dist/modules/auth/api/users/acl/route.js.map +2 -2
- package/dist/modules/auth/api/users/resend-invite/route.js +1 -1
- package/dist/modules/auth/api/users/resend-invite/route.js.map +2 -2
- package/dist/modules/auth/cli.js +12 -6
- package/dist/modules/auth/cli.js.map +2 -2
- package/dist/modules/auth/commands/users.js +1 -1
- package/dist/modules/auth/commands/users.js.map +2 -2
- package/dist/modules/auth/data/entities.js +1 -1
- package/dist/modules/auth/data/entities.js.map +2 -2
- package/dist/modules/auth/lib/setup-app.js +3 -3
- package/dist/modules/auth/lib/setup-app.js.map +2 -2
- package/dist/modules/auth/services/authService.js +2 -2
- package/dist/modules/auth/services/authService.js.map +2 -2
- package/dist/modules/business_rules/api/rules/route.js +3 -3
- package/dist/modules/business_rules/api/rules/route.js.map +2 -2
- package/dist/modules/business_rules/api/sets/[id]/members/route.js +7 -4
- package/dist/modules/business_rules/api/sets/[id]/members/route.js.map +2 -2
- package/dist/modules/business_rules/api/sets/route.js +3 -3
- package/dist/modules/business_rules/api/sets/route.js.map +2 -2
- package/dist/modules/business_rules/cli.js +1 -1
- package/dist/modules/business_rules/cli.js.map +2 -2
- package/dist/modules/business_rules/data/entities.js +2 -9
- package/dist/modules/business_rules/data/entities.js.map +2 -2
- package/dist/modules/business_rules/lib/rule-engine.js +1 -1
- package/dist/modules/business_rules/lib/rule-engine.js.map +2 -2
- package/dist/modules/catalog/api/option-schemas/route.js +0 -1
- package/dist/modules/catalog/api/option-schemas/route.js.map +2 -2
- package/dist/modules/catalog/data/entities.js +2 -11
- package/dist/modules/catalog/data/entities.js.map +2 -2
- package/dist/modules/configs/data/entities.js +2 -1
- package/dist/modules/configs/data/entities.js.map +2 -2
- package/dist/modules/currencies/commands/fetch-configs.js +3 -3
- package/dist/modules/currencies/commands/fetch-configs.js.map +2 -2
- package/dist/modules/currencies/data/entities.js +1 -1
- package/dist/modules/currencies/data/entities.js.map +2 -2
- package/dist/modules/customer_accounts/api/signup.js +1 -1
- package/dist/modules/customer_accounts/api/signup.js.map +2 -2
- package/dist/modules/customer_accounts/data/entities.js +1 -1
- package/dist/modules/customer_accounts/data/entities.js.map +2 -2
- package/dist/modules/customer_accounts/services/customerInvitationService.js +1 -1
- package/dist/modules/customer_accounts/services/customerInvitationService.js.map +2 -2
- package/dist/modules/customer_accounts/services/customerSessionService.js +1 -1
- package/dist/modules/customer_accounts/services/customerSessionService.js.map +2 -2
- package/dist/modules/customer_accounts/services/customerTokenService.js +12 -7
- package/dist/modules/customer_accounts/services/customerTokenService.js.map +2 -2
- package/dist/modules/customers/api/interactions/conflicts/route.js +19 -17
- package/dist/modules/customers/api/interactions/conflicts/route.js.map +2 -2
- package/dist/modules/customers/api/interactions/counts/route.js +7 -6
- package/dist/modules/customers/api/interactions/counts/route.js.map +2 -2
- package/dist/modules/customers/api/interactions/route.js +28 -42
- package/dist/modules/customers/api/interactions/route.js.map +2 -2
- package/dist/modules/customers/api/utils.js +29 -24
- package/dist/modules/customers/api/utils.js.map +2 -2
- package/dist/modules/customers/cli.js +45 -40
- package/dist/modules/customers/cli.js.map +2 -2
- package/dist/modules/customers/commands/dictionaries.js +1 -1
- package/dist/modules/customers/commands/dictionaries.js.map +2 -2
- package/dist/modules/customers/commands/tags.js +1 -1
- package/dist/modules/customers/commands/tags.js.map +2 -2
- package/dist/modules/customers/data/entities.js +2 -12
- package/dist/modules/customers/data/entities.js.map +2 -2
- package/dist/modules/customers/lib/interactionProjection.js +18 -15
- package/dist/modules/customers/lib/interactionProjection.js.map +2 -2
- package/dist/modules/customers/lib/personCompanyLinkTable.js +6 -8
- package/dist/modules/customers/lib/personCompanyLinkTable.js.map +2 -2
- package/dist/modules/dashboards/api/roles/widgets/route.js +1 -1
- package/dist/modules/dashboards/api/roles/widgets/route.js.map +2 -2
- package/dist/modules/dashboards/api/users/widgets/route.js +1 -1
- package/dist/modules/dashboards/api/users/widgets/route.js.map +2 -2
- package/dist/modules/dashboards/data/entities.js +1 -1
- package/dist/modules/dashboards/data/entities.js.map +1 -1
- package/dist/modules/data_sync/api/mappings/route.js +1 -1
- package/dist/modules/data_sync/api/mappings/route.js.map +2 -2
- package/dist/modules/data_sync/data/entities.js +2 -1
- package/dist/modules/data_sync/data/entities.js.map +2 -2
- package/dist/modules/data_sync/lib/id-mapping.js +1 -1
- package/dist/modules/data_sync/lib/id-mapping.js.map +2 -2
- package/dist/modules/data_sync/lib/sync-run-service.js +1 -1
- package/dist/modules/data_sync/lib/sync-run-service.js.map +2 -2
- package/dist/modules/dictionaries/commands/factory.js +1 -1
- package/dist/modules/dictionaries/commands/factory.js.map +2 -2
- package/dist/modules/dictionaries/data/entities.js +2 -9
- package/dist/modules/dictionaries/data/entities.js.map +2 -2
- package/dist/modules/directory/commands/organizations.js +4 -4
- package/dist/modules/directory/commands/organizations.js.map +2 -2
- package/dist/modules/directory/data/entities.js +2 -1
- package/dist/modules/directory/data/entities.js.map +2 -2
- package/dist/modules/entities/api/definitions.js +2 -2
- package/dist/modules/entities/api/definitions.js.map +2 -2
- package/dist/modules/entities/api/encryption.js +2 -2
- package/dist/modules/entities/api/encryption.js.map +2 -2
- package/dist/modules/entities/api/relations/options.js +2 -2
- package/dist/modules/entities/api/relations/options.js.map +2 -2
- package/dist/modules/entities/cli.js +4 -4
- package/dist/modules/entities/cli.js.map +2 -2
- package/dist/modules/entities/data/entities.js +1 -1
- package/dist/modules/entities/data/entities.js.map +2 -2
- package/dist/modules/entities/lib/field-definitions.js +2 -2
- package/dist/modules/entities/lib/field-definitions.js.map +2 -2
- package/dist/modules/entities/lib/register.js +1 -1
- package/dist/modules/entities/lib/register.js.map +2 -2
- package/dist/modules/feature_toggles/data/entities.js +2 -9
- package/dist/modules/feature_toggles/data/entities.js.map +2 -2
- package/dist/modules/inbox_ops/api/proposals/counts/route.js +3 -6
- package/dist/modules/inbox_ops/api/proposals/counts/route.js.map +2 -2
- package/dist/modules/inbox_ops/data/entities.js +2 -8
- package/dist/modules/inbox_ops/data/entities.js.map +2 -2
- package/dist/modules/inbox_ops/lib/messagesIntegration.js +6 -6
- package/dist/modules/inbox_ops/lib/messagesIntegration.js.map +2 -2
- package/dist/modules/integrations/data/entities.js +2 -1
- package/dist/modules/integrations/data/entities.js.map +2 -2
- package/dist/modules/integrations/lib/credentials-service.js +1 -1
- package/dist/modules/integrations/lib/credentials-service.js.map +2 -2
- package/dist/modules/integrations/lib/log-service.js +1 -1
- package/dist/modules/integrations/lib/log-service.js.map +2 -2
- package/dist/modules/integrations/lib/state-service.js +1 -1
- package/dist/modules/integrations/lib/state-service.js.map +2 -2
- package/dist/modules/messages/api/route.js +90 -93
- package/dist/modules/messages/api/route.js.map +2 -2
- package/dist/modules/messages/api/unread-count/route.js +8 -7
- package/dist/modules/messages/api/unread-count/route.js.map +2 -2
- package/dist/modules/messages/commands/confirmations.js +1 -1
- package/dist/modules/messages/commands/confirmations.js.map +2 -2
- package/dist/modules/messages/commands/messages.js +3 -3
- package/dist/modules/messages/commands/messages.js.map +2 -2
- package/dist/modules/messages/data/entities.js +2 -1
- package/dist/modules/messages/data/entities.js.map +2 -2
- package/dist/modules/messages/lib/email-sender.js +1 -1
- package/dist/modules/messages/lib/email-sender.js.map +2 -2
- package/dist/modules/messages/lib/searchLookup.js +8 -8
- package/dist/modules/messages/lib/searchLookup.js.map +2 -2
- package/dist/modules/messages/lib/tokenConsumption.js +9 -4
- package/dist/modules/messages/lib/tokenConsumption.js.map +2 -2
- package/dist/modules/notifications/data/entities.js +2 -1
- package/dist/modules/notifications/data/entities.js.map +2 -2
- package/dist/modules/notifications/lib/notificationRecipients.js +15 -5
- package/dist/modules/notifications/lib/notificationRecipients.js.map +2 -2
- package/dist/modules/notifications/lib/notificationService.js +39 -34
- package/dist/modules/notifications/lib/notificationService.js.map +2 -2
- package/dist/modules/notifications/workers/create-notification.worker.js +14 -13
- package/dist/modules/notifications/workers/create-notification.worker.js.map +2 -2
- package/dist/modules/payment_gateways/api/transactions/route.js +2 -2
- package/dist/modules/payment_gateways/api/transactions/route.js.map +2 -2
- package/dist/modules/payment_gateways/data/entities.js +2 -1
- package/dist/modules/payment_gateways/data/entities.js.map +2 -2
- package/dist/modules/payment_gateways/lib/gateway-service.js +1 -1
- package/dist/modules/payment_gateways/lib/gateway-service.js.map +2 -2
- package/dist/modules/payment_gateways/lib/webhook-utils.js +2 -2
- package/dist/modules/payment_gateways/lib/webhook-utils.js.map +2 -2
- package/dist/modules/perspectives/data/entities.js +1 -1
- package/dist/modules/perspectives/data/entities.js.map +2 -2
- package/dist/modules/planner/data/entities.js +1 -1
- package/dist/modules/planner/data/entities.js.map +2 -2
- package/dist/modules/progress/data/entities.js +2 -1
- package/dist/modules/progress/data/entities.js.map +2 -2
- package/dist/modules/progress/lib/progressServiceImpl.js +1 -1
- package/dist/modules/progress/lib/progressServiceImpl.js.map +2 -2
- package/dist/modules/query_index/api/status.js +66 -57
- package/dist/modules/query_index/api/status.js.map +2 -2
- package/dist/modules/query_index/cli.js +39 -24
- package/dist/modules/query_index/cli.js.map +2 -2
- package/dist/modules/query_index/data/entities.js +1 -1
- package/dist/modules/query_index/data/entities.js.map +2 -2
- package/dist/modules/query_index/di.js +25 -13
- package/dist/modules/query_index/di.js.map +2 -2
- package/dist/modules/query_index/lib/batch.js +31 -33
- package/dist/modules/query_index/lib/batch.js.map +2 -2
- package/dist/modules/query_index/lib/coverage.js +63 -50
- package/dist/modules/query_index/lib/coverage.js.map +2 -2
- package/dist/modules/query_index/lib/engine.js +592 -588
- package/dist/modules/query_index/lib/engine.js.map +2 -2
- package/dist/modules/query_index/lib/indexer.js +74 -47
- package/dist/modules/query_index/lib/indexer.js.map +2 -2
- package/dist/modules/query_index/lib/jobs.js +37 -24
- package/dist/modules/query_index/lib/jobs.js.map +2 -2
- package/dist/modules/query_index/lib/purge.js +19 -11
- package/dist/modules/query_index/lib/purge.js.map +2 -2
- package/dist/modules/query_index/lib/reindexer.js +47 -44
- package/dist/modules/query_index/lib/reindexer.js.map +2 -2
- package/dist/modules/query_index/lib/search-tokens.js +47 -25
- package/dist/modules/query_index/lib/search-tokens.js.map +2 -2
- package/dist/modules/query_index/lib/stale.js +14 -12
- package/dist/modules/query_index/lib/stale.js.map +2 -2
- package/dist/modules/query_index/lib/subscriber-scope.js +2 -2
- package/dist/modules/query_index/lib/subscriber-scope.js.map +2 -2
- package/dist/modules/query_index/subscribers/delete_one.js +3 -2
- package/dist/modules/query_index/subscribers/delete_one.js.map +2 -2
- package/dist/modules/resources/commands/tag-assignments.js +1 -1
- package/dist/modules/resources/commands/tag-assignments.js.map +2 -2
- package/dist/modules/resources/commands/tags.js +1 -1
- package/dist/modules/resources/commands/tags.js.map +2 -2
- package/dist/modules/resources/data/entities.js +2 -1
- package/dist/modules/resources/data/entities.js.map +2 -2
- package/dist/modules/sales/commands/documentAddresses.js +2 -2
- package/dist/modules/sales/commands/documentAddresses.js.map +2 -2
- package/dist/modules/sales/commands/notes.js.map +2 -2
- package/dist/modules/sales/commands/tags.js +1 -1
- package/dist/modules/sales/commands/tags.js.map +2 -2
- package/dist/modules/sales/data/enrichers.js +9 -8
- package/dist/modules/sales/data/enrichers.js.map +2 -2
- package/dist/modules/sales/data/entities.js +2 -11
- package/dist/modules/sales/data/entities.js.map +2 -2
- package/dist/modules/shipping_carriers/data/entities.js +2 -1
- package/dist/modules/shipping_carriers/data/entities.js.map +2 -2
- package/dist/modules/shipping_carriers/lib/shipping-service.js +1 -1
- package/dist/modules/shipping_carriers/lib/shipping-service.js.map +2 -2
- package/dist/modules/shipping_carriers/lib/webhook-utils.js +2 -2
- package/dist/modules/shipping_carriers/lib/webhook-utils.js.map +2 -2
- package/dist/modules/staff/data/entities.js +1 -1
- package/dist/modules/staff/data/entities.js.map +2 -2
- package/dist/modules/translations/api/[entityType]/[entityId]/route.js +3 -5
- package/dist/modules/translations/api/[entityType]/[entityId]/route.js.map +2 -2
- package/dist/modules/translations/api/context.js +2 -2
- package/dist/modules/translations/api/context.js.map +2 -2
- package/dist/modules/translations/commands/translations.js +46 -39
- package/dist/modules/translations/commands/translations.js.map +2 -2
- package/dist/modules/translations/components/TranslationManager.js +19 -10
- package/dist/modules/translations/components/TranslationManager.js.map +2 -2
- package/dist/modules/translations/data/entities.js +1 -1
- package/dist/modules/translations/data/entities.js.map +2 -2
- package/dist/modules/translations/lib/apply.js +4 -4
- package/dist/modules/translations/lib/apply.js.map +2 -2
- package/dist/modules/translations/lib/batch.js +3 -2
- package/dist/modules/translations/lib/batch.js.map +2 -2
- package/dist/modules/translations/subscribers/cleanup.js +3 -5
- package/dist/modules/translations/subscribers/cleanup.js.map +2 -2
- package/dist/modules/workflows/api/definitions/route.js +1 -1
- package/dist/modules/workflows/api/definitions/route.js.map +2 -2
- package/dist/modules/workflows/cli.js +5 -5
- package/dist/modules/workflows/cli.js.map +2 -2
- package/dist/modules/workflows/data/entities.js +2 -1
- package/dist/modules/workflows/data/entities.js.map +2 -2
- package/dist/modules/workflows/lib/event-logger.js +2 -2
- package/dist/modules/workflows/lib/event-logger.js.map +2 -2
- package/dist/modules/workflows/lib/seeds.js +16 -1
- package/dist/modules/workflows/lib/seeds.js.map +2 -2
- package/dist/modules/workflows/lib/step-handler.js +3 -3
- package/dist/modules/workflows/lib/step-handler.js.map +2 -2
- package/dist/modules/workflows/lib/task-handler.js +1 -1
- package/dist/modules/workflows/lib/task-handler.js.map +2 -2
- package/dist/modules/workflows/lib/transition-handler.js +1 -1
- package/dist/modules/workflows/lib/transition-handler.js.map +2 -2
- package/dist/modules/workflows/lib/workflow-executor.js +2 -2
- package/dist/modules/workflows/lib/workflow-executor.js.map +2 -2
- package/jest.config.cjs +4 -2
- package/package.json +3 -3
- package/src/modules/api_keys/data/entities.ts +1 -1
- package/src/modules/api_keys/services/apiKeyService.ts +5 -5
- package/src/modules/attachments/api/library/[id]/route.ts +1 -1
- package/src/modules/attachments/api/library/route.ts +10 -12
- package/src/modules/attachments/api/partitions/route.ts +3 -3
- package/src/modules/attachments/api/route.ts +10 -8
- package/src/modules/attachments/api/transfer/route.ts +1 -1
- package/src/modules/attachments/data/entities.ts +2 -1
- package/src/modules/attachments/lib/ocrQueue.ts +1 -1
- package/src/modules/audit_logs/api/audit-logs/actions/export/route.ts +4 -4
- package/src/modules/audit_logs/api/audit-logs/actions/route.ts +4 -4
- package/src/modules/audit_logs/data/entities.ts +1 -1
- package/src/modules/audit_logs/services/actionLogService.ts +96 -87
- package/src/modules/auth/api/roles/acl/route.ts +1 -1
- package/src/modules/auth/api/users/acl/route.ts +2 -2
- package/src/modules/auth/api/users/resend-invite/route.ts +1 -1
- package/src/modules/auth/cli.ts +46 -40
- package/src/modules/auth/commands/users.ts +1 -1
- package/src/modules/auth/data/entities.ts +1 -1
- package/src/modules/auth/lib/setup-app.ts +3 -3
- package/src/modules/auth/services/authService.ts +2 -2
- package/src/modules/business_rules/api/rules/route.ts +3 -3
- package/src/modules/business_rules/api/sets/[id]/members/route.ts +7 -4
- package/src/modules/business_rules/api/sets/route.ts +3 -3
- package/src/modules/business_rules/cli.ts +1 -1
- package/src/modules/business_rules/data/entities.ts +2 -9
- package/src/modules/business_rules/lib/rule-engine.ts +1 -1
- package/src/modules/catalog/api/option-schemas/route.ts +0 -1
- package/src/modules/catalog/data/entities.ts +2 -11
- package/src/modules/configs/data/entities.ts +2 -1
- package/src/modules/currencies/commands/fetch-configs.ts +3 -3
- package/src/modules/currencies/data/entities.ts +1 -1
- package/src/modules/customer_accounts/api/signup.ts +1 -1
- package/src/modules/customer_accounts/data/entities.ts +1 -1
- package/src/modules/customer_accounts/services/customerInvitationService.ts +1 -1
- package/src/modules/customer_accounts/services/customerSessionService.ts +1 -1
- package/src/modules/customer_accounts/services/customerTokenService.ts +26 -15
- package/src/modules/customers/api/interactions/conflicts/route.ts +26 -23
- package/src/modules/customers/api/interactions/counts/route.ts +13 -11
- package/src/modules/customers/api/interactions/route.ts +32 -44
- package/src/modules/customers/api/utils.ts +45 -37
- package/src/modules/customers/cli.ts +88 -67
- package/src/modules/customers/commands/dictionaries.ts +1 -1
- package/src/modules/customers/commands/tags.ts +1 -1
- package/src/modules/customers/data/entities.ts +2 -12
- package/src/modules/customers/lib/interactionProjection.ts +36 -25
- package/src/modules/customers/lib/personCompanyLinkTable.ts +13 -18
- package/src/modules/dashboards/api/roles/widgets/route.ts +1 -1
- package/src/modules/dashboards/api/users/widgets/route.ts +1 -1
- package/src/modules/dashboards/data/entities.ts +1 -1
- package/src/modules/data_sync/api/mappings/route.ts +1 -1
- package/src/modules/data_sync/data/entities.ts +2 -1
- package/src/modules/data_sync/lib/id-mapping.ts +1 -1
- package/src/modules/data_sync/lib/sync-run-service.ts +1 -1
- package/src/modules/dictionaries/commands/factory.ts +1 -1
- package/src/modules/dictionaries/data/entities.ts +2 -9
- package/src/modules/directory/commands/organizations.ts +4 -4
- package/src/modules/directory/data/entities.ts +2 -1
- package/src/modules/entities/api/definitions.ts +2 -2
- package/src/modules/entities/api/encryption.ts +2 -2
- package/src/modules/entities/api/relations/options.ts +8 -3
- package/src/modules/entities/cli.ts +4 -4
- package/src/modules/entities/data/entities.ts +1 -1
- package/src/modules/entities/lib/field-definitions.ts +2 -2
- package/src/modules/entities/lib/register.ts +1 -1
- package/src/modules/feature_toggles/data/entities.ts +2 -9
- package/src/modules/inbox_ops/api/proposals/counts/route.ts +10 -10
- package/src/modules/inbox_ops/data/entities.ts +2 -8
- package/src/modules/inbox_ops/lib/messagesIntegration.ts +12 -11
- package/src/modules/integrations/data/entities.ts +2 -1
- package/src/modules/integrations/lib/credentials-service.ts +1 -1
- package/src/modules/integrations/lib/log-service.ts +1 -1
- package/src/modules/integrations/lib/state-service.ts +1 -1
- package/src/modules/messages/api/route.ts +134 -123
- package/src/modules/messages/api/unread-count/route.ts +19 -16
- package/src/modules/messages/commands/confirmations.ts +1 -1
- package/src/modules/messages/commands/messages.ts +3 -3
- package/src/modules/messages/data/entities.ts +2 -1
- package/src/modules/messages/lib/email-sender.ts +1 -1
- package/src/modules/messages/lib/searchLookup.ts +16 -13
- package/src/modules/messages/lib/tokenConsumption.ts +16 -8
- package/src/modules/notifications/data/entities.ts +2 -1
- package/src/modules/notifications/lib/notificationRecipients.ts +42 -26
- package/src/modules/notifications/lib/notificationService.ts +53 -42
- package/src/modules/notifications/workers/create-notification.worker.ts +20 -17
- package/src/modules/payment_gateways/api/transactions/route.ts +2 -2
- package/src/modules/payment_gateways/data/entities.ts +2 -1
- package/src/modules/payment_gateways/lib/gateway-service.ts +1 -1
- package/src/modules/payment_gateways/lib/webhook-utils.ts +2 -2
- package/src/modules/perspectives/data/entities.ts +1 -1
- package/src/modules/planner/data/entities.ts +1 -1
- package/src/modules/progress/data/entities.ts +2 -1
- package/src/modules/progress/lib/progressServiceImpl.ts +1 -1
- package/src/modules/query_index/api/status.ts +85 -71
- package/src/modules/query_index/cli.ts +51 -31
- package/src/modules/query_index/data/entities.ts +1 -1
- package/src/modules/query_index/di.ts +41 -16
- package/src/modules/query_index/lib/batch.ts +68 -55
- package/src/modules/query_index/lib/coverage.ts +115 -88
- package/src/modules/query_index/lib/engine.ts +1036 -1096
- package/src/modules/query_index/lib/indexer.ts +115 -79
- package/src/modules/query_index/lib/jobs.ts +51 -31
- package/src/modules/query_index/lib/purge.ts +25 -19
- package/src/modules/query_index/lib/reindexer.ts +97 -84
- package/src/modules/query_index/lib/search-tokens.ts +67 -36
- package/src/modules/query_index/lib/stale.ts +14 -17
- package/src/modules/query_index/lib/subscriber-scope.ts +6 -5
- package/src/modules/query_index/subscribers/delete_one.ts +9 -6
- package/src/modules/resources/commands/tag-assignments.ts +1 -1
- package/src/modules/resources/commands/tags.ts +1 -1
- package/src/modules/resources/data/entities.ts +2 -1
- package/src/modules/sales/commands/documentAddresses.ts +2 -2
- package/src/modules/sales/commands/notes.ts +1 -1
- package/src/modules/sales/commands/tags.ts +1 -1
- package/src/modules/sales/data/enrichers.ts +17 -13
- package/src/modules/sales/data/entities.ts +2 -11
- package/src/modules/shipping_carriers/data/entities.ts +2 -1
- package/src/modules/shipping_carriers/lib/shipping-service.ts +1 -1
- package/src/modules/shipping_carriers/lib/webhook-utils.ts +2 -2
- package/src/modules/staff/data/entities.ts +1 -1
- package/src/modules/translations/api/[entityType]/[entityId]/route.ts +14 -11
- package/src/modules/translations/api/context.ts +4 -4
- package/src/modules/translations/commands/translations.ts +116 -81
- package/src/modules/translations/components/TranslationManager.tsx +23 -14
- package/src/modules/translations/data/entities.ts +1 -1
- package/src/modules/translations/i18n/de.json +1 -0
- package/src/modules/translations/i18n/en.json +1 -0
- package/src/modules/translations/i18n/es.json +1 -0
- package/src/modules/translations/i18n/pl.json +1 -0
- package/src/modules/translations/lib/apply.ts +6 -6
- package/src/modules/translations/lib/batch.ts +9 -7
- package/src/modules/translations/subscribers/cleanup.ts +10 -11
- package/src/modules/workflows/api/definitions/route.ts +1 -1
- package/src/modules/workflows/cli.ts +5 -5
- package/src/modules/workflows/data/entities.ts +2 -1
- package/src/modules/workflows/lib/event-logger.ts +2 -2
- package/src/modules/workflows/lib/seeds.ts +16 -1
- package/src/modules/workflows/lib/step-handler.ts +3 -3
- package/src/modules/workflows/lib/task-handler.ts +1 -1
- package/src/modules/workflows/lib/transition-handler.ts +1 -1
- package/src/modules/workflows/lib/workflow-executor.ts +2 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/auth/commands/users.ts"],
|
|
4
|
-
"sourcesContent": ["import type { CommandHandler } 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 } from '@mikro-orm/core'\nimport type { EntityManager, FilterQuery } from '@mikro-orm/postgresql'\nimport { User, UserRole, Role, UserAcl, Session, PasswordReset } from '@open-mercato/core/modules/auth/data/entities'\nimport { Organization } from '@open-mercato/core/modules/directory/data/entities'\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 { normalizeTenantId } from '@open-mercato/core/modules/auth/lib/tenantAccess'\nimport { computeEmailHash } 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 { 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'\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\nconst passwordSchema = buildPasswordSchema()\n\nconst createSchema = z.object({\n email: z.string().email(),\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 password: passwordSchema.optional(),\n organizationId: z.string().uuid().optional(),\n roles: z.array(z.string()).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 try {\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 } catch (err) {\n console.error('[auth.users.roles] Failed to create notification:', err)\n }\n}\n\ntype CreateUserResult = { user: User; warning?: 'invite_email_failed' }\n\nconst createUserCommand: CommandHandler<Record<string, unknown>, CreateUserResult> = {\n id: 'auth.users.create',\n async execute(rawInput, ctx) {\n const { parsed, custom } = parseWithCustomFields(createSchema, rawInput)\n const em = (ctx.container.resolve('em') as EntityManager)\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\n const emailHash = computeEmailHash(parsed.email)\n const duplicate = await findOneWithDecryption(em, User, { $or: [{ email: parsed.email }, { emailHash }], deletedAt: null } 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 const tenantId = organization.tenant?.id ? String(organization.tenant.id) : null\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 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 syncUserRoles(em, user, parsed.roles, tenantId)\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 = (ctx.container.resolve('em') as EntityManager).fork()\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 ({ result: { user }, ctx }) => {\n const { translate } = await resolveTranslations()\n const em = (ctx.container.resolve('em') as EntityManager).fork()\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 return {\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 snapshotAfter: snapshot.view,\n payload: {\n undo: {\n after: snapshot.undo,\n },\n },\n }\n },\n undo: async ({ 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 = (ctx.container.resolve('em') as EntityManager)\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\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\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 const removed = await de.deleteOrmEntity({\n entity: User,\n where: { id: userId, deletedAt: null } as FilterQuery<User>,\n soft: false,\n })\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}\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.persistAndFlush(row)\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({ to: user.email, subject, react: InviteUserEmail({ inviteUrl, copy }) })\n } catch (err) {\n console.error('[auth.users.invite] 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 async prepare(rawInput, ctx) {\n const { parsed } = parseWithCustomFields(updateSchema, rawInput)\n const em = (ctx.container.resolve('em') as EntityManager)\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 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 = (ctx.container.resolve('em') as EntityManager)\n const rolesBefore = Array.isArray(parsed.roles)\n ? await loadUserRoleNames(em, parsed.id)\n : null\n\n if (parsed.email !== undefined) {\n const emailHash = computeEmailHash(parsed.email)\n const duplicate = await findOneWithDecryption(\n em,\n User,\n {\n $or: [{ email: parsed.email }, { emailHash }],\n deletedAt: null,\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 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 let tenantId: string | null | undefined\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) throw new CrudHttpError(400, { error: 'Organization not found' })\n tenantId = organization.tenant?.id ? String(organization.tenant.id) : null\n }\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n let user: User | null\n try {\n user = await de.updateOrmEntity({\n entity: User,\n where: { id: parsed.id, deletedAt: null } as FilterQuery<User>,\n apply: (entity) => {\n if (parsed.email !== undefined) {\n entity.email = parsed.email\n entity.emailHash = emailHash\n }\n if (parsed.organizationId !== undefined) {\n entity.organizationId = parsed.organizationId\n entity.tenantId = tenantId ?? null\n }\n if (hashed) entity.passwordHash = hashed\n },\n })\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) {\n await em.nativeDelete(Session, { user: parsed.id })\n }\n\n if (Array.isArray(parsed.roles)) {\n await syncUserRoles(em, user, parsed.roles, user.tenantId ? String(user.tenantId) : tenantId ?? null)\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 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 (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 = (ctx.container.resolve('em') as EntityManager).fork()\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 ({ 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 = (ctx.container.resolve('em') as EntityManager).fork()\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 return {\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 changes,\n snapshotBefore: before ?? null,\n snapshotAfter: after,\n payload: {\n undo: {\n before: beforeUndo,\n after: afterSnapshots.undo,\n },\n },\n }\n },\n undo: async ({ 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 em = (ctx.container.resolve('em') as EntityManager)\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n const updated = await de.updateOrmEntity({\n entity: User,\n where: { id: userId, deletedAt: null } as FilterQuery<User>,\n apply: (entity) => {\n entity.email = before.email\n entity.organizationId = before.organizationId ?? null\n entity.tenantId = before.tenantId ?? null\n entity.passwordHash = before.passwordHash ?? null\n entity.name = before.name ?? undefined\n entity.isConfirmed = before.isConfirmed\n },\n })\n\n if (updated) {\n await syncUserRoles(em, updated, before.roles, before.tenantId)\n await em.flush()\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 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}\n\nconst deleteUserCommand: CommandHandler<{ body?: Record<string, unknown>; query?: Record<string, unknown> }, User> = {\n id: 'auth.users.delete',\n async prepare(input, ctx) {\n const id = requireId(input, 'User id required')\n const em = (ctx.container.resolve('em') as EntityManager)\n const existing = await findOneWithDecryption(em, User, { id, deletedAt: null }, {}, { tenantId: null, organizationId: null })\n if (!existing) return {}\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 = (ctx.container.resolve('em') as EntityManager)\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\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n const user = await de.deleteOrmEntity({\n entity: User,\n where: { id, deletedAt: null } as FilterQuery<User>,\n soft: false,\n })\n if (!user) throw new CrudHttpError(404, { error: 'User not found' })\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 payload: {\n undo: {\n before: beforeUndo,\n },\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<UndoPayload<UserUndoSnapshot>>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager)\n let user = await findOneWithDecryption(em, User, { id: before.id }, {}, { tenantId: null, organizationId: null })\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n\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 ?? undefined\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 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 await invalidateUserCache(ctx, before.id)\n },\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(em: EntityManager, user: User, desiredRoles: string[], tenantId: string | null) {\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 desiredIds = new Set(resolvedRoles.map((r) => String(r.id)))\n const currentLinks = await findWithDecryption(em, UserRole, { user }, {}, { tenantId: null, organizationId: null })\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 { user: userId as unknown as User },\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 }, {}, { 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 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"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import type { CommandHandler } 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 } from '@mikro-orm/core'\nimport type { EntityManager, FilterQuery } from '@mikro-orm/postgresql'\nimport { User, UserRole, Role, UserAcl, Session, PasswordReset } from '@open-mercato/core/modules/auth/data/entities'\nimport { Organization } from '@open-mercato/core/modules/directory/data/entities'\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 { normalizeTenantId } from '@open-mercato/core/modules/auth/lib/tenantAccess'\nimport { computeEmailHash } 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 { 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'\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\nconst passwordSchema = buildPasswordSchema()\n\nconst createSchema = z.object({\n email: z.string().email(),\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 password: passwordSchema.optional(),\n organizationId: z.string().uuid().optional(),\n roles: z.array(z.string()).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 try {\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 } catch (err) {\n console.error('[auth.users.roles] Failed to create notification:', err)\n }\n}\n\ntype CreateUserResult = { user: User; warning?: 'invite_email_failed' }\n\nconst createUserCommand: CommandHandler<Record<string, unknown>, CreateUserResult> = {\n id: 'auth.users.create',\n async execute(rawInput, ctx) {\n const { parsed, custom } = parseWithCustomFields(createSchema, rawInput)\n const em = (ctx.container.resolve('em') as EntityManager)\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\n const emailHash = computeEmailHash(parsed.email)\n const duplicate = await findOneWithDecryption(em, User, { $or: [{ email: parsed.email }, { emailHash }], deletedAt: null } 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 const tenantId = organization.tenant?.id ? String(organization.tenant.id) : null\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 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 syncUserRoles(em, user, parsed.roles, tenantId)\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 = (ctx.container.resolve('em') as EntityManager).fork()\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 ({ result: { user }, ctx }) => {\n const { translate } = await resolveTranslations()\n const em = (ctx.container.resolve('em') as EntityManager).fork()\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 return {\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 snapshotAfter: snapshot.view,\n payload: {\n undo: {\n after: snapshot.undo,\n },\n },\n }\n },\n undo: async ({ 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 = (ctx.container.resolve('em') as EntityManager)\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\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\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 const removed = await de.deleteOrmEntity({\n entity: User,\n where: { id: userId, deletedAt: null } as FilterQuery<User>,\n soft: false,\n })\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}\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({ to: user.email, subject, react: InviteUserEmail({ inviteUrl, copy }) })\n } catch (err) {\n console.error('[auth.users.invite] 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 async prepare(rawInput, ctx) {\n const { parsed } = parseWithCustomFields(updateSchema, rawInput)\n const em = (ctx.container.resolve('em') as EntityManager)\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 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 = (ctx.container.resolve('em') as EntityManager)\n const rolesBefore = Array.isArray(parsed.roles)\n ? await loadUserRoleNames(em, parsed.id)\n : null\n\n if (parsed.email !== undefined) {\n const emailHash = computeEmailHash(parsed.email)\n const duplicate = await findOneWithDecryption(\n em,\n User,\n {\n $or: [{ email: parsed.email }, { emailHash }],\n deletedAt: null,\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 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 let tenantId: string | null | undefined\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) throw new CrudHttpError(400, { error: 'Organization not found' })\n tenantId = organization.tenant?.id ? String(organization.tenant.id) : null\n }\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n let user: User | null\n try {\n user = await de.updateOrmEntity({\n entity: User,\n where: { id: parsed.id, deletedAt: null } as FilterQuery<User>,\n apply: (entity) => {\n if (parsed.email !== undefined) {\n entity.email = parsed.email\n entity.emailHash = emailHash\n }\n if (parsed.organizationId !== undefined) {\n entity.organizationId = parsed.organizationId\n entity.tenantId = tenantId ?? null\n }\n if (hashed) entity.passwordHash = hashed\n },\n })\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) {\n await em.nativeDelete(Session, { user: parsed.id })\n }\n\n if (Array.isArray(parsed.roles)) {\n await syncUserRoles(em, user, parsed.roles, user.tenantId ? String(user.tenantId) : tenantId ?? null)\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 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 (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 = (ctx.container.resolve('em') as EntityManager).fork()\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 ({ 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 = (ctx.container.resolve('em') as EntityManager).fork()\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 return {\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 changes,\n snapshotBefore: before ?? null,\n snapshotAfter: after,\n payload: {\n undo: {\n before: beforeUndo,\n after: afterSnapshots.undo,\n },\n },\n }\n },\n undo: async ({ 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 em = (ctx.container.resolve('em') as EntityManager)\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n const updated = await de.updateOrmEntity({\n entity: User,\n where: { id: userId, deletedAt: null } as FilterQuery<User>,\n apply: (entity) => {\n entity.email = before.email\n entity.organizationId = before.organizationId ?? null\n entity.tenantId = before.tenantId ?? null\n entity.passwordHash = before.passwordHash ?? null\n entity.name = before.name ?? undefined\n entity.isConfirmed = before.isConfirmed\n },\n })\n\n if (updated) {\n await syncUserRoles(em, updated, before.roles, before.tenantId)\n await em.flush()\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 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}\n\nconst deleteUserCommand: CommandHandler<{ body?: Record<string, unknown>; query?: Record<string, unknown> }, User> = {\n id: 'auth.users.delete',\n async prepare(input, ctx) {\n const id = requireId(input, 'User id required')\n const em = (ctx.container.resolve('em') as EntityManager)\n const existing = await findOneWithDecryption(em, User, { id, deletedAt: null }, {}, { tenantId: null, organizationId: null })\n if (!existing) return {}\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 = (ctx.container.resolve('em') as EntityManager)\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\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n const user = await de.deleteOrmEntity({\n entity: User,\n where: { id, deletedAt: null } as FilterQuery<User>,\n soft: false,\n })\n if (!user) throw new CrudHttpError(404, { error: 'User not found' })\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 payload: {\n undo: {\n before: beforeUndo,\n },\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<UndoPayload<UserUndoSnapshot>>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager)\n let user = await findOneWithDecryption(em, User, { id: before.id }, {}, { tenantId: null, organizationId: null })\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n\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 ?? undefined\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 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 await invalidateUserCache(ctx, before.id)\n },\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(em: EntityManager, user: User, desiredRoles: string[], tenantId: string | null) {\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 desiredIds = new Set(resolvedRoles.map((r) => String(r.id)))\n const currentLinks = await findWithDecryption(em, UserRole, { user }, {}, { tenantId: null, organizationId: null })\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 { user: userId as unknown as User },\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 }, {}, { 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 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"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["emailHash"]
|
|
7
7
|
}
|
|
@@ -8,7 +8,7 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
8
8
|
if (kind && result) __defProp(target, key, result);
|
|
9
9
|
return result;
|
|
10
10
|
};
|
|
11
|
-
import { Entity,
|
|
11
|
+
import { Entity, Index, ManyToOne, PrimaryKey, Property, Unique } from "@mikro-orm/decorators/legacy";
|
|
12
12
|
let User = class {
|
|
13
13
|
constructor() {
|
|
14
14
|
this.isConfirmed = true;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/auth/data/entities.ts"],
|
|
4
|
-
"sourcesContent": ["import { Entity,
|
|
5
|
-
"mappings": ";;;;;;;;;;AAAA,SAAS,QAAQ,YAAY,UAAU,
|
|
4
|
+
"sourcesContent": ["import { Entity, Index, ManyToOne, PrimaryKey, Property, Unique } from '@mikro-orm/decorators/legacy'\n\n@Entity({ tableName: 'users' })\nexport class User {\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ name: 'tenant_id', type: 'uuid', nullable: true })\n tenantId?: string | null\n\n @Property({ name: 'organization_id', type: 'uuid', nullable: true })\n organizationId?: string | null\n\n @Property({ type: 'text', unique: true })\n email!: string\n\n @Property({ name: 'email_hash', type: 'text', nullable: true })\n @Index({ name: 'users_email_hash_idx' })\n emailHash?: string | null\n\n @Property({ type: 'text', nullable: true })\n name?: string\n\n @Property({ name: 'password_hash', type: 'text', nullable: true })\n passwordHash?: string | null\n\n @Property({ name: 'is_confirmed', type: 'boolean', default: true })\n isConfirmed: boolean = true\n\n @Property({ name: 'last_login_at', type: Date, nullable: true })\n lastLoginAt?: Date\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n@Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n\n@Entity({ tableName: 'roles' })\n@Unique({ properties: ['tenantId', 'name'] })\nexport class Role {\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ type: 'text' })\n name!: string\n\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n\n@Entity({ tableName: 'user_sidebar_preferences' })\n@Unique({ properties: ['user', 'tenantId', 'organizationId', 'locale'] })\nexport class UserSidebarPreference {\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @ManyToOne(() => User)\n user!: User\n\n @Property({ name: 'tenant_id', type: 'uuid', nullable: true })\n tenantId?: string | null\n\n @Property({ name: 'organization_id', type: 'uuid', nullable: true })\n organizationId?: string | null\n\n @Property({ type: 'text' })\n locale!: string\n\n @Property({ name: 'settings_json', type: 'json', nullable: true })\n settingsJson?: unknown\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date(), nullable: true })\n updatedAt?: Date\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n\n@Entity({ tableName: 'role_sidebar_preferences' })\n@Unique({ properties: ['role', 'tenantId', 'locale'] })\nexport class RoleSidebarPreference {\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @ManyToOne(() => Role)\n role!: Role\n\n @Property({ name: 'tenant_id', type: 'uuid', nullable: true })\n tenantId?: string | null\n\n @Property({ type: 'text' })\n locale!: string\n\n @Property({ name: 'settings_json', type: 'json', nullable: true })\n settingsJson?: unknown\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date(), nullable: true })\n updatedAt?: Date\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n\n@Entity({ tableName: 'user_roles' })\nexport class UserRole {\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @ManyToOne(() => User)\n user!: User\n\n @ManyToOne(() => Role)\n role!: Role\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n\n@Entity({ tableName: 'sessions' })\nexport class Session {\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @ManyToOne(() => User)\n user!: User\n\n @Property({ type: 'text', unique: true })\n token!: string\n\n @Property({ name: 'expires_at', type: Date })\n expiresAt!: Date\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'last_used_at', type: Date, nullable: true })\n lastUsedAt?: Date\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n\n@Entity({ tableName: 'password_resets' })\nexport class PasswordReset {\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @ManyToOne(() => User)\n user!: User\n\n @Property({ type: 'text', unique: true })\n token!: string\n\n @Property({ name: 'expires_at', type: Date })\n expiresAt!: Date\n\n @Property({ name: 'used_at', type: Date, nullable: true })\n usedAt?: Date\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n\n// RBAC: Role-level ACL\n@Entity({ tableName: 'role_acls' })\nexport class RoleAcl {\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @ManyToOne(() => Role)\n role!: Role\n\n // Tenant scope is mandatory for ACL evaluation\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n // Feature list (string-based). Use JSON array to preserve order and allow wildcards like \"example.*\".\n @Property({ name: 'features_json', type: 'json', nullable: true })\n featuresJson?: string[] | null\n\n // If true, user with this role can do everything regardless of features\n @Property({ name: 'is_super_admin', type: 'boolean', default: false })\n isSuperAdmin: boolean = false\n\n // Visible organizations within the tenant; null/empty means all organizations\n @Property({ name: 'organizations_json', type: 'json', nullable: true })\n organizationsJson?: string[] | null\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date(), nullable: true })\n updatedAt?: Date\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n\n// RBAC: Per-user ACL override\n@Entity({ tableName: 'user_acls' })\nexport class UserAcl {\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @ManyToOne(() => User)\n user!: User\n\n // Tenant scope is mandatory for ACL evaluation\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n // Feature list (string-based). Use JSON array to preserve order and allow wildcards like \"example.*\".\n @Property({ name: 'features_json', type: 'json', nullable: true })\n featuresJson?: string[] | null\n\n // If true, this user can do everything regardless of features\n @Property({ name: 'is_super_admin', type: 'boolean', default: false })\n isSuperAdmin: boolean = false\n\n // Visible organizations within the tenant; null/empty means all organizations\n @Property({ name: 'organizations_json', type: 'json', nullable: true })\n organizationsJson?: string[] | null\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date(), nullable: true })\n updatedAt?: Date\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n\n@Entity({ tableName: 'user_consents' })\n@Unique({ properties: ['userId', 'tenantId', 'consentType'] })\nexport class UserConsent {\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ name: 'user_id', type: 'uuid' })\n userId!: string\n\n @Property({ name: 'tenant_id', type: 'uuid', nullable: true })\n tenantId?: string | null\n\n @Property({ name: 'organization_id', type: 'uuid', nullable: true })\n organizationId?: string | null\n\n @Property({ name: 'consent_type', type: 'text' })\n consentType!: string\n\n @Property({ name: 'is_granted', type: 'boolean', default: false })\n isGranted: boolean = false\n\n @Property({ name: 'granted_at', type: Date, nullable: true })\n grantedAt?: Date | null\n\n @Property({ name: 'withdrawn_at', type: Date, nullable: true })\n withdrawnAt?: Date | null\n\n @Property({ type: 'text', nullable: true })\n source?: string | null\n\n @Property({ name: 'ip_address', type: 'text', nullable: true })\n ipAddress?: string | null\n\n @Property({ name: 'integrity_hash', type: 'text', nullable: true })\n integrityHash?: string | null\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date(), nullable: true })\n updatedAt?: Date\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -376,7 +376,7 @@ async function ensureRoleAclFor(em, role, tenantId, features, options = {}) {
|
|
|
376
376
|
isSuperAdmin: !!options.isSuperAdmin,
|
|
377
377
|
createdAt: /* @__PURE__ */ new Date()
|
|
378
378
|
});
|
|
379
|
-
await em.
|
|
379
|
+
await em.persist(acl).flush();
|
|
380
380
|
return;
|
|
381
381
|
}
|
|
382
382
|
const currentFeatures = Array.isArray(existing.featuresJson) ? existing.featuresJson : [];
|
|
@@ -387,7 +387,7 @@ async function ensureRoleAclFor(em, role, tenantId, features, options = {}) {
|
|
|
387
387
|
existing.isSuperAdmin = true;
|
|
388
388
|
}
|
|
389
389
|
if (changed || options.isSuperAdmin) {
|
|
390
|
-
await em.
|
|
390
|
+
await em.persist(existing).flush();
|
|
391
391
|
}
|
|
392
392
|
}
|
|
393
393
|
async function deactivateDemoSuperAdminIfSelfOnboardingEnabled(em) {
|
|
@@ -406,7 +406,7 @@ async function deactivateDemoSuperAdminIfSelfOnboardingEnabled(em) {
|
|
|
406
406
|
dirty = true;
|
|
407
407
|
}
|
|
408
408
|
if (dirty) {
|
|
409
|
-
await em.
|
|
409
|
+
await em.persist(user).flush();
|
|
410
410
|
}
|
|
411
411
|
} catch (error) {
|
|
412
412
|
console.error("[auth.setup] failed to deactivate demo superadmin user", error);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/auth/lib/setup-app.ts"],
|
|
4
|
-
"sourcesContent": ["import { hash } from 'bcryptjs'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { Role, RoleAcl, User, UserRole } from '@open-mercato/core/modules/auth/data/entities'\nimport { Tenant, Organization } from '@open-mercato/core/modules/directory/data/entities'\nimport { rebuildHierarchyForTenant } from '@open-mercato/core/modules/directory/lib/hierarchy'\nimport { normalizeTenantId } from './tenantAccess'\nimport { computeEmailHash } from '@open-mercato/core/modules/auth/lib/emailHash'\nimport { getDefaultEncryptionMaps, type Module } from '@open-mercato/shared/modules/registry'\nimport { isEncryptionDebugEnabled, isTenantDataEncryptionEnabled } from '@open-mercato/shared/lib/encryption/toggles'\nimport { EncryptionMap } from '@open-mercato/core/modules/entities/data/entities'\nimport { createKmsService } from '@open-mercato/shared/lib/encryption/kms'\nimport { TenantDataEncryptionService } from '@open-mercato/shared/lib/encryption/tenantDataEncryptionService'\nimport { findOneWithDecryption, findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport { parseBooleanToken } from '@open-mercato/shared/lib/boolean'\n\nconst DEFAULT_ROLE_NAMES = ['employee', 'admin', 'superadmin'] as const\nconst DEMO_SUPERADMIN_EMAIL = 'superadmin@acme.com'\nconst DEFAULT_DERIVED_EMAIL_DOMAIN = DEMO_SUPERADMIN_EMAIL.split('@')[1] ?? 'acme.com'\n\nexport type EnsureRolesOptions = {\n roleNames?: string[]\n tenantId?: string\n}\n\nasync function ensureRolesInContext(\n em: EntityManager,\n roleNames: string[],\n tenantId: string,\n) {\n for (const name of roleNames) {\n const existing = await findOneWithDecryption(em, Role, { name, tenantId }, {}, { tenantId, organizationId: null })\n if (existing) continue\n em.persist(em.create(Role, { name, tenantId, createdAt: new Date() }))\n }\n}\n\nexport async function ensureRoles(em: EntityManager, options: EnsureRolesOptions = {}) {\n const roleNames = options.roleNames ?? [...DEFAULT_ROLE_NAMES]\n const tenantId = normalizeTenantId(options.tenantId ?? null)\n if (!tenantId) {\n throw new Error('ensureRoles requires a tenantId \u2014 global roles are not supported')\n }\n await em.transactional(async (tem) => {\n await ensureRolesInContext(tem, roleNames, tenantId)\n await tem.flush()\n })\n}\n\nasync function findRoleByName(\n em: EntityManager,\n name: string,\n tenantId: string | null,\n): Promise<Role | null> {\n const normalizedTenant = normalizeTenantId(tenantId ?? null) ?? null\n return findOneWithDecryption(em, Role, { name, tenantId: normalizedTenant }, {}, { tenantId: normalizedTenant, organizationId: null })\n}\n\nasync function findRoleByNameOrFail(\n em: EntityManager,\n name: string,\n tenantId: string | null,\n): Promise<Role> {\n const role = await findRoleByName(em, name, tenantId)\n if (!role) throw new Error(`ROLE_NOT_FOUND:${name}`)\n return role\n}\n\ntype PrimaryUserInput = {\n email: string\n password?: string\n hashedPassword?: string | null\n firstName?: string | null\n lastName?: string | null\n displayName?: string | null\n confirm?: boolean\n}\n\nconst DERIVED_EMAIL_ENV = {\n admin: 'OM_INIT_ADMIN_EMAIL',\n employee: 'OM_INIT_EMPLOYEE_EMAIL',\n} as const\n\nexport type SetupInitialTenantOptions = {\n orgName: string\n primaryUser: PrimaryUserInput\n roleNames?: string[]\n includeDerivedUsers?: boolean\n failIfUserExists?: boolean\n primaryUserRoles?: string[]\n includeSuperadminRole?: boolean\n /** Optional list of enabled modules. When provided, module setup hooks are called. */\n modules?: Module[]\n}\n\nexport type SetupInitialTenantResult = {\n tenantId: string\n organizationId: string\n users: Array<{ user: User; roles: string[]; created: boolean }>\n reusedExistingUser: boolean\n}\n\nexport async function setupInitialTenant(\n em: EntityManager,\n options: SetupInitialTenantOptions,\n): Promise<SetupInitialTenantResult> {\n const {\n primaryUser,\n includeDerivedUsers = true,\n failIfUserExists = false,\n primaryUserRoles,\n includeSuperadminRole = true,\n } = options\n const primaryRolesInput = primaryUserRoles && primaryUserRoles.length ? primaryUserRoles : ['superadmin']\n const primaryRoles = includeSuperadminRole\n ? primaryRolesInput\n : primaryRolesInput.filter((role) => role !== 'superadmin')\n if (primaryRoles.length === 0) {\n throw new Error('PRIMARY_ROLES_REQUIRED')\n }\n const defaultRoleNames = options.roleNames ?? [...DEFAULT_ROLE_NAMES]\n const resolvedRoleNames = includeSuperadminRole\n ? defaultRoleNames\n : defaultRoleNames.filter((role) => role !== 'superadmin')\n const roleNames = Array.from(new Set([...resolvedRoleNames, ...primaryRoles]))\n const resolvedModules = options.modules ?? tryGetModules()\n const defaultEncryptionMaps = getDefaultEncryptionMaps(resolvedModules)\n\n const mainEmail = primaryUser.email\n const existingUser = await findOneWithDecryption(em, User, { email: mainEmail }, {}, { tenantId: null, organizationId: null })\n if (existingUser && failIfUserExists) {\n throw new Error('USER_EXISTS')\n }\n\n let tenantId: string | undefined\n let organizationId: string | undefined\n let reusedExistingUser = false\n const userSnapshots: Array<{ user: User; roles: string[]; created: boolean }> = []\n\n await em.transactional(async (tem) => {\n if (!existingUser) return\n reusedExistingUser = true\n tenantId = existingUser.tenantId ? String(existingUser.tenantId) : undefined\n organizationId = existingUser.organizationId ? String(existingUser.organizationId) : undefined\n const roleTenantId = normalizeTenantId(existingUser.tenantId ?? null) ?? null\n if (!roleTenantId) {\n throw new Error('Cannot reuse a user without a tenantId \u2014 global roles are not supported')\n }\n\n await ensureRolesInContext(tem, roleNames, roleTenantId)\n await tem.flush()\n\n const requiredRoleSet = new Set([...roleNames, ...primaryRoles])\n const links = await findWithDecryption(\n tem,\n UserRole,\n { user: existingUser },\n { populate: ['role'] },\n { tenantId: roleTenantId, organizationId: null },\n )\n const currentRoles = new Set(links.map((link) => link.role.name))\n for (const roleName of requiredRoleSet) {\n if (!currentRoles.has(roleName)) {\n const role = await findRoleByNameOrFail(tem, roleName, roleTenantId)\n tem.persist(tem.create(UserRole, { user: existingUser, role, createdAt: new Date() }))\n }\n }\n await tem.flush()\n const roles = Array.from(new Set([...currentRoles, ...roleNames]))\n userSnapshots.push({ user: existingUser, roles, created: false })\n })\n\n if (!existingUser) {\n const baseUsers: Array<{\n email: string\n roles: string[]\n name?: string | null\n passwordHash?: string | null\n }> = [\n { email: primaryUser.email, roles: primaryRoles, name: resolvePrimaryName(primaryUser) },\n ]\n if (includeDerivedUsers) {\n const adminOverride = readEnvValue(DERIVED_EMAIL_ENV.admin)\n const employeeOverride = readEnvValue(DERIVED_EMAIL_ENV.employee)\n const adminEmail = adminOverride ?? `admin@${DEFAULT_DERIVED_EMAIL_DOMAIN}`\n const employeeEmail = employeeOverride ?? `employee@${DEFAULT_DERIVED_EMAIL_DOMAIN}`\n const adminPassword = readEnvValue('OM_INIT_ADMIN_PASSWORD') || 'secret'\n const employeePassword = readEnvValue('OM_INIT_EMPLOYEE_PASSWORD') || 'secret'\n const adminPasswordHash = adminPassword ? await resolvePasswordHash({ email: adminEmail, password: adminPassword }) : null\n const employeePasswordHash = employeePassword\n ? await resolvePasswordHash({ email: employeeEmail, password: employeePassword })\n : null\n addUniqueBaseUser(baseUsers, { email: adminEmail, roles: ['admin'], passwordHash: adminPasswordHash })\n addUniqueBaseUser(baseUsers, { email: employeeEmail, roles: ['employee'], passwordHash: employeePasswordHash })\n }\n const passwordHash = await resolvePasswordHash(primaryUser)\n\n await em.transactional(async (tem) => {\n const tenant = tem.create(Tenant, {\n name: `${options.orgName} Tenant`,\n isActive: true,\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n tem.persist(tenant)\n await tem.flush()\n\n const organization = tem.create(Organization, {\n name: options.orgName,\n tenant,\n isActive: true,\n depth: 0,\n ancestorIds: [],\n childIds: [],\n descendantIds: [],\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n tem.persist(organization)\n await tem.flush()\n\n tenantId = String(tenant.id)\n organizationId = String(organization.id)\n const roleTenantId = tenantId\n\n if (isTenantDataEncryptionEnabled()) {\n try {\n const kms = createKmsService()\n if (kms.isHealthy()) {\n if (isEncryptionDebugEnabled()) {\n console.info('\uD83D\uDD11 [encryption][setup] provisioning tenant DEK', { tenantId: String(tenant.id) })\n }\n await kms.createTenantDek(String(tenant.id))\n if (isEncryptionDebugEnabled()) {\n console.info('\uD83D\uDD11 [encryption][setup] created tenant DEK during setup', { tenantId: String(tenant.id) })\n }\n } else {\n if (isEncryptionDebugEnabled()) {\n console.warn('\u26A0\uFE0F [encryption][setup] KMS not healthy, skipping tenant DEK creation', { tenantId: String(tenant.id) })\n }\n }\n } catch (err) {\n if (isEncryptionDebugEnabled()) {\n console.warn('\u26A0\uFE0F [encryption][setup] Failed to create tenant DEK', err)\n }\n }\n }\n\n await ensureRolesInContext(tem, roleNames, roleTenantId)\n await tem.flush()\n\n if (isTenantDataEncryptionEnabled()) {\n for (const spec of defaultEncryptionMaps) {\n const existing = await findOneWithDecryption(tem, EncryptionMap, { entityId: spec.entityId, tenantId: tenant.id, organizationId: organization.id, deletedAt: null }, {}, { tenantId: String(tenant.id), organizationId: String(organization.id) })\n if (!existing) {\n tem.persist(tem.create(EncryptionMap, {\n entityId: spec.entityId,\n tenantId: tenant.id,\n organizationId: organization.id,\n fieldsJson: spec.fields,\n isActive: true,\n createdAt: new Date(),\n updatedAt: new Date(),\n }))\n } else {\n existing.fieldsJson = spec.fields\n existing.isActive = true\n }\n }\n await tem.flush()\n }\n })\n\n await em.transactional(async (tem) => {\n if (!tenantId || !organizationId) return\n const roleTenantId = tenantId\n const encryptionService = isTenantDataEncryptionEnabled()\n ? new TenantDataEncryptionService(tem as any, { kms: createKmsService() })\n : null\n if (encryptionService) {\n await encryptionService.invalidateMap('auth:user', String(tenantId), String(organizationId))\n await encryptionService.invalidateMap('auth:user', String(tenantId), null)\n }\n\n for (const base of baseUsers) {\n const resolvedPasswordHash = base.passwordHash ?? passwordHash\n let user = await findOneWithDecryption(tem, User, { email: base.email }, {}, { tenantId: tenantId ?? null, organizationId: organizationId ?? null })\n const confirm = primaryUser.confirm ?? true\n const encryptedPayload = encryptionService\n ? await encryptionService.encryptEntityPayload('auth:user', { email: base.email }, tenantId, organizationId)\n : { email: base.email, emailHash: computeEmailHash(base.email) }\n if (user) {\n user.passwordHash = resolvedPasswordHash\n user.organizationId = organizationId\n user.tenantId = tenantId\n if (isTenantDataEncryptionEnabled()) {\n user.email = encryptedPayload.email as any\n user.emailHash = (encryptedPayload as any).emailHash ?? computeEmailHash(base.email)\n }\n if (base.name) user.name = base.name\n if (confirm) user.isConfirmed = true\n tem.persist(user)\n userSnapshots.push({ user, roles: base.roles, created: false })\n } else {\n user = tem.create(User, {\n email: (encryptedPayload as any).email ?? base.email,\n emailHash: isTenantDataEncryptionEnabled() ? (encryptedPayload as any).emailHash ?? computeEmailHash(base.email) : undefined,\n passwordHash: resolvedPasswordHash,\n organizationId,\n tenantId,\n name: base.name ?? undefined,\n isConfirmed: confirm,\n createdAt: new Date(),\n })\n tem.persist(user)\n userSnapshots.push({ user, roles: base.roles, created: true })\n }\n await tem.flush()\n for (const roleName of base.roles) {\n const role = await findRoleByNameOrFail(tem, roleName, roleTenantId)\n const existingLink = await findOneWithDecryption(tem, UserRole, { user, role }, {}, { tenantId: tenantId ?? null, organizationId: null })\n if (!existingLink) tem.persist(tem.create(UserRole, { user, role, createdAt: new Date() }))\n }\n await tem.flush()\n }\n })\n }\n\n if (!tenantId || !organizationId) {\n throw new Error('SETUP_FAILED')\n }\n\n if (!reusedExistingUser) {\n await rebuildHierarchyForTenant(em, tenantId)\n }\n\n await ensureDefaultRoleAcls(em, tenantId, resolvedModules, { includeSuperadminRole })\n await deactivateDemoSuperAdminIfSelfOnboardingEnabled(em)\n\n // Call module onTenantCreated hooks\n for (const mod of resolvedModules) {\n if (mod.setup?.onTenantCreated) {\n await mod.setup.onTenantCreated({ em, tenantId, organizationId })\n }\n }\n\n return {\n tenantId,\n organizationId,\n users: userSnapshots,\n reusedExistingUser,\n }\n}\n\nfunction resolvePrimaryName(input: PrimaryUserInput): string | null {\n if (input.displayName && input.displayName.trim()) return input.displayName.trim()\n const parts = [input.firstName, input.lastName].map((value) => value?.trim()).filter(Boolean)\n if (parts.length) return parts.join(' ')\n return null\n}\n\nfunction readEnvValue(key: string): string | undefined {\n const value = process.env[key]\n if (typeof value !== 'string') return undefined\n const trimmed = value.trim()\n return trimmed.length > 0 ? trimmed : undefined\n}\n\nfunction addUniqueBaseUser(\n baseUsers: Array<{ email: string; roles: string[]; name?: string | null; passwordHash?: string | null }>,\n entry: { email: string; roles: string[]; name?: string | null; passwordHash?: string | null },\n) {\n if (!entry.email) return\n const normalized = entry.email.toLowerCase()\n if (baseUsers.some((user) => user.email.toLowerCase() === normalized)) return\n baseUsers.push(entry)\n}\n\nfunction isDemoModeEnabled(): boolean {\n const parsed = parseBooleanToken(process.env.DEMO_MODE ?? '')\n return parsed === false ? false : true\n}\n\nfunction shouldKeepDemoSuperadminDuringInit(): boolean {\n if (process.env.OM_INIT_FLOW !== 'true') return false\n if (!readEnvValue('OM_INIT_SUPERADMIN_EMAIL')) return false\n return isDemoModeEnabled()\n}\n\nasync function resolvePasswordHash(input: PrimaryUserInput): Promise<string | null> {\n if (typeof input.hashedPassword === 'string') return input.hashedPassword\n if (input.password) return hash(input.password, 10)\n return null\n}\n\nasync function ensureDefaultRoleAcls(\n em: EntityManager,\n tenantId: string,\n modules: Module[],\n options: { includeSuperadminRole?: boolean } = {},\n) {\n const includeSuperadminRole = options.includeSuperadminRole ?? true\n const roleTenantId = normalizeTenantId(tenantId) ?? null\n const superadminRole = includeSuperadminRole ? await findRoleByName(em, 'superadmin', roleTenantId) : null\n const adminRole = await findRoleByName(em, 'admin', roleTenantId)\n const employeeRole = await findRoleByName(em, 'employee', roleTenantId)\n\n // Merge features from all enabled modules' setup configs\n const builtInRoles = ['superadmin', 'admin', 'employee'] as const\n const superadminFeatures: string[] = []\n const adminFeatures: string[] = []\n const employeeFeatures: string[] = []\n const customRoleFeatures = new Map<string, string[]>()\n\n for (const mod of modules) {\n const roleFeatures = mod.setup?.defaultRoleFeatures\n if (!roleFeatures) continue\n if (roleFeatures.superadmin) superadminFeatures.push(...roleFeatures.superadmin)\n if (roleFeatures.admin) adminFeatures.push(...roleFeatures.admin)\n if (roleFeatures.employee) employeeFeatures.push(...roleFeatures.employee)\n\n // Collect features for custom roles (any key not in builtInRoles)\n for (const [roleName, features] of Object.entries(roleFeatures)) {\n if ((builtInRoles as readonly string[]).includes(roleName)) continue\n if (!Array.isArray(features)) continue\n const existing = customRoleFeatures.get(roleName) ?? []\n existing.push(...features)\n customRoleFeatures.set(roleName, existing)\n }\n }\n\n console.log('\u2705 Seeded default role features', {\n superadmin: superadminFeatures,\n admin: adminFeatures,\n employee: employeeFeatures,\n ...(customRoleFeatures.size > 0\n ? Object.fromEntries(customRoleFeatures)\n : {}),\n })\n\n if (includeSuperadminRole && superadminRole) {\n await ensureRoleAclFor(em, superadminRole, tenantId, superadminFeatures, { isSuperAdmin: true })\n }\n if (adminRole) {\n await ensureRoleAclFor(em, adminRole, tenantId, adminFeatures)\n }\n if (employeeRole) {\n await ensureRoleAclFor(em, employeeRole, tenantId, employeeFeatures)\n }\n\n // Seed ACLs for custom roles defined by app modules.\n // NOTE: Custom roles may not exist yet if they are created in seedDefaults\n // (which runs after this function). In that case, use ensureCustomRoleAcls()\n // after seedDefaults to pick them up.\n for (const [roleName, features] of customRoleFeatures) {\n const role = await findRoleByName(em, roleName, roleTenantId)\n if (role) {\n await ensureRoleAclFor(em, role, tenantId, features)\n }\n }\n}\n\n/**\n * Seed ACLs for custom roles defined in module defaultRoleFeatures.\n * Call this AFTER seedDefaults to pick up roles created by app modules.\n * Safe to call multiple times \u2014 ensureRoleAclFor merges features idempotently.\n */\nexport async function ensureCustomRoleAcls(\n em: EntityManager,\n tenantId: string,\n modules?: Module[],\n): Promise<void> {\n const resolvedModules = modules ?? tryGetModules()\n const roleTenantId = normalizeTenantId(tenantId) ?? null\n const builtInRoles = ['superadmin', 'admin', 'employee']\n const customRoleFeatures = new Map<string, string[]>()\n\n for (const mod of resolvedModules) {\n const roleFeatures = mod.setup?.defaultRoleFeatures\n if (!roleFeatures) continue\n for (const [roleName, features] of Object.entries(roleFeatures)) {\n if (builtInRoles.includes(roleName)) continue\n if (!Array.isArray(features)) continue\n const existing = customRoleFeatures.get(roleName) ?? []\n existing.push(...features)\n customRoleFeatures.set(roleName, existing)\n }\n }\n\n if (customRoleFeatures.size === 0) return\n\n let seeded = 0\n for (const [roleName, features] of customRoleFeatures) {\n const role = await findRoleByName(em, roleName, roleTenantId)\n if (role) {\n await ensureRoleAclFor(em, role, tenantId, features)\n seeded++\n }\n }\n if (seeded > 0) {\n console.log(`\u2705 Seeded custom role ACLs (${seeded} roles)`)\n }\n}\n\nasync function ensureRoleAclFor(\n em: EntityManager,\n role: Role,\n tenantId: string,\n features: string[],\n options: { isSuperAdmin?: boolean } = {},\n) {\n const existing = await findOneWithDecryption(em, RoleAcl, { role, tenantId }, {}, { tenantId, organizationId: null })\n if (!existing) {\n const acl = em.create(RoleAcl, {\n role,\n tenantId,\n featuresJson: features,\n isSuperAdmin: !!options.isSuperAdmin,\n createdAt: new Date(),\n })\n await em.persistAndFlush(acl)\n return\n }\n const currentFeatures = Array.isArray(existing.featuresJson) ? existing.featuresJson : []\n const merged = Array.from(new Set([...currentFeatures, ...features]))\n const changed =\n merged.length !== currentFeatures.length ||\n merged.some((value, index) => value !== currentFeatures[index])\n if (changed) existing.featuresJson = merged\n if (options.isSuperAdmin && !existing.isSuperAdmin) {\n existing.isSuperAdmin = true\n }\n if (changed || options.isSuperAdmin) {\n await em.persistAndFlush(existing)\n }\n}\n\nasync function deactivateDemoSuperAdminIfSelfOnboardingEnabled(em: EntityManager) {\n if (process.env.SELF_SERVICE_ONBOARDING_ENABLED !== 'true') return\n if (shouldKeepDemoSuperadminDuringInit()) return\n try {\n const user = await findOneWithDecryption(em, User, { email: DEMO_SUPERADMIN_EMAIL }, {}, { tenantId: null, organizationId: null })\n if (!user) return\n let dirty = false\n if (user.passwordHash) {\n user.passwordHash = null\n dirty = true\n }\n if (user.isConfirmed !== false) {\n user.isConfirmed = false\n dirty = true\n }\n if (dirty) {\n await em.persistAndFlush(user)\n }\n } catch (error) {\n console.error('[auth.setup] failed to deactivate demo superadmin user', error)\n }\n}\n\n/** Try to get modules from runtime registry; returns empty array if not yet registered. */\nfunction tryGetModules(): Module[] {\n try {\n const { getModules } = require('@open-mercato/shared/lib/modules/registry')\n return getModules()\n } catch {\n return []\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import { hash } from 'bcryptjs'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { Role, RoleAcl, User, UserRole } from '@open-mercato/core/modules/auth/data/entities'\nimport { Tenant, Organization } from '@open-mercato/core/modules/directory/data/entities'\nimport { rebuildHierarchyForTenant } from '@open-mercato/core/modules/directory/lib/hierarchy'\nimport { normalizeTenantId } from './tenantAccess'\nimport { computeEmailHash } from '@open-mercato/core/modules/auth/lib/emailHash'\nimport { getDefaultEncryptionMaps, type Module } from '@open-mercato/shared/modules/registry'\nimport { isEncryptionDebugEnabled, isTenantDataEncryptionEnabled } from '@open-mercato/shared/lib/encryption/toggles'\nimport { EncryptionMap } from '@open-mercato/core/modules/entities/data/entities'\nimport { createKmsService } from '@open-mercato/shared/lib/encryption/kms'\nimport { TenantDataEncryptionService } from '@open-mercato/shared/lib/encryption/tenantDataEncryptionService'\nimport { findOneWithDecryption, findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport { parseBooleanToken } from '@open-mercato/shared/lib/boolean'\n\nconst DEFAULT_ROLE_NAMES = ['employee', 'admin', 'superadmin'] as const\nconst DEMO_SUPERADMIN_EMAIL = 'superadmin@acme.com'\nconst DEFAULT_DERIVED_EMAIL_DOMAIN = DEMO_SUPERADMIN_EMAIL.split('@')[1] ?? 'acme.com'\n\nexport type EnsureRolesOptions = {\n roleNames?: string[]\n tenantId?: string\n}\n\nasync function ensureRolesInContext(\n em: EntityManager,\n roleNames: string[],\n tenantId: string,\n) {\n for (const name of roleNames) {\n const existing = await findOneWithDecryption(em, Role, { name, tenantId }, {}, { tenantId, organizationId: null })\n if (existing) continue\n em.persist(em.create(Role, { name, tenantId, createdAt: new Date() }))\n }\n}\n\nexport async function ensureRoles(em: EntityManager, options: EnsureRolesOptions = {}) {\n const roleNames = options.roleNames ?? [...DEFAULT_ROLE_NAMES]\n const tenantId = normalizeTenantId(options.tenantId ?? null)\n if (!tenantId) {\n throw new Error('ensureRoles requires a tenantId \u2014 global roles are not supported')\n }\n await em.transactional(async (tem) => {\n await ensureRolesInContext(tem, roleNames, tenantId)\n await tem.flush()\n })\n}\n\nasync function findRoleByName(\n em: EntityManager,\n name: string,\n tenantId: string | null,\n): Promise<Role | null> {\n const normalizedTenant = normalizeTenantId(tenantId ?? null) ?? null\n return findOneWithDecryption(em, Role, { name, tenantId: normalizedTenant }, {}, { tenantId: normalizedTenant, organizationId: null })\n}\n\nasync function findRoleByNameOrFail(\n em: EntityManager,\n name: string,\n tenantId: string | null,\n): Promise<Role> {\n const role = await findRoleByName(em, name, tenantId)\n if (!role) throw new Error(`ROLE_NOT_FOUND:${name}`)\n return role\n}\n\ntype PrimaryUserInput = {\n email: string\n password?: string\n hashedPassword?: string | null\n firstName?: string | null\n lastName?: string | null\n displayName?: string | null\n confirm?: boolean\n}\n\nconst DERIVED_EMAIL_ENV = {\n admin: 'OM_INIT_ADMIN_EMAIL',\n employee: 'OM_INIT_EMPLOYEE_EMAIL',\n} as const\n\nexport type SetupInitialTenantOptions = {\n orgName: string\n primaryUser: PrimaryUserInput\n roleNames?: string[]\n includeDerivedUsers?: boolean\n failIfUserExists?: boolean\n primaryUserRoles?: string[]\n includeSuperadminRole?: boolean\n /** Optional list of enabled modules. When provided, module setup hooks are called. */\n modules?: Module[]\n}\n\nexport type SetupInitialTenantResult = {\n tenantId: string\n organizationId: string\n users: Array<{ user: User; roles: string[]; created: boolean }>\n reusedExistingUser: boolean\n}\n\nexport async function setupInitialTenant(\n em: EntityManager,\n options: SetupInitialTenantOptions,\n): Promise<SetupInitialTenantResult> {\n const {\n primaryUser,\n includeDerivedUsers = true,\n failIfUserExists = false,\n primaryUserRoles,\n includeSuperadminRole = true,\n } = options\n const primaryRolesInput = primaryUserRoles && primaryUserRoles.length ? primaryUserRoles : ['superadmin']\n const primaryRoles = includeSuperadminRole\n ? primaryRolesInput\n : primaryRolesInput.filter((role) => role !== 'superadmin')\n if (primaryRoles.length === 0) {\n throw new Error('PRIMARY_ROLES_REQUIRED')\n }\n const defaultRoleNames = options.roleNames ?? [...DEFAULT_ROLE_NAMES]\n const resolvedRoleNames = includeSuperadminRole\n ? defaultRoleNames\n : defaultRoleNames.filter((role) => role !== 'superadmin')\n const roleNames = Array.from(new Set([...resolvedRoleNames, ...primaryRoles]))\n const resolvedModules = options.modules ?? tryGetModules()\n const defaultEncryptionMaps = getDefaultEncryptionMaps(resolvedModules)\n\n const mainEmail = primaryUser.email\n const existingUser = await findOneWithDecryption(em, User, { email: mainEmail }, {}, { tenantId: null, organizationId: null })\n if (existingUser && failIfUserExists) {\n throw new Error('USER_EXISTS')\n }\n\n let tenantId: string | undefined\n let organizationId: string | undefined\n let reusedExistingUser = false\n const userSnapshots: Array<{ user: User; roles: string[]; created: boolean }> = []\n\n await em.transactional(async (tem) => {\n if (!existingUser) return\n reusedExistingUser = true\n tenantId = existingUser.tenantId ? String(existingUser.tenantId) : undefined\n organizationId = existingUser.organizationId ? String(existingUser.organizationId) : undefined\n const roleTenantId = normalizeTenantId(existingUser.tenantId ?? null) ?? null\n if (!roleTenantId) {\n throw new Error('Cannot reuse a user without a tenantId \u2014 global roles are not supported')\n }\n\n await ensureRolesInContext(tem, roleNames, roleTenantId)\n await tem.flush()\n\n const requiredRoleSet = new Set([...roleNames, ...primaryRoles])\n const links = await findWithDecryption(\n tem,\n UserRole,\n { user: existingUser },\n { populate: ['role'] },\n { tenantId: roleTenantId, organizationId: null },\n )\n const currentRoles = new Set(links.map((link) => link.role.name))\n for (const roleName of requiredRoleSet) {\n if (!currentRoles.has(roleName)) {\n const role = await findRoleByNameOrFail(tem, roleName, roleTenantId)\n tem.persist(tem.create(UserRole, { user: existingUser, role, createdAt: new Date() }))\n }\n }\n await tem.flush()\n const roles = Array.from(new Set([...currentRoles, ...roleNames]))\n userSnapshots.push({ user: existingUser, roles, created: false })\n })\n\n if (!existingUser) {\n const baseUsers: Array<{\n email: string\n roles: string[]\n name?: string | null\n passwordHash?: string | null\n }> = [\n { email: primaryUser.email, roles: primaryRoles, name: resolvePrimaryName(primaryUser) },\n ]\n if (includeDerivedUsers) {\n const adminOverride = readEnvValue(DERIVED_EMAIL_ENV.admin)\n const employeeOverride = readEnvValue(DERIVED_EMAIL_ENV.employee)\n const adminEmail = adminOverride ?? `admin@${DEFAULT_DERIVED_EMAIL_DOMAIN}`\n const employeeEmail = employeeOverride ?? `employee@${DEFAULT_DERIVED_EMAIL_DOMAIN}`\n const adminPassword = readEnvValue('OM_INIT_ADMIN_PASSWORD') || 'secret'\n const employeePassword = readEnvValue('OM_INIT_EMPLOYEE_PASSWORD') || 'secret'\n const adminPasswordHash = adminPassword ? await resolvePasswordHash({ email: adminEmail, password: adminPassword }) : null\n const employeePasswordHash = employeePassword\n ? await resolvePasswordHash({ email: employeeEmail, password: employeePassword })\n : null\n addUniqueBaseUser(baseUsers, { email: adminEmail, roles: ['admin'], passwordHash: adminPasswordHash })\n addUniqueBaseUser(baseUsers, { email: employeeEmail, roles: ['employee'], passwordHash: employeePasswordHash })\n }\n const passwordHash = await resolvePasswordHash(primaryUser)\n\n await em.transactional(async (tem) => {\n const tenant = tem.create(Tenant, {\n name: `${options.orgName} Tenant`,\n isActive: true,\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n tem.persist(tenant)\n await tem.flush()\n\n const organization = tem.create(Organization, {\n name: options.orgName,\n tenant,\n isActive: true,\n depth: 0,\n ancestorIds: [],\n childIds: [],\n descendantIds: [],\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n tem.persist(organization)\n await tem.flush()\n\n tenantId = String(tenant.id)\n organizationId = String(organization.id)\n const roleTenantId = tenantId\n\n if (isTenantDataEncryptionEnabled()) {\n try {\n const kms = createKmsService()\n if (kms.isHealthy()) {\n if (isEncryptionDebugEnabled()) {\n console.info('\uD83D\uDD11 [encryption][setup] provisioning tenant DEK', { tenantId: String(tenant.id) })\n }\n await kms.createTenantDek(String(tenant.id))\n if (isEncryptionDebugEnabled()) {\n console.info('\uD83D\uDD11 [encryption][setup] created tenant DEK during setup', { tenantId: String(tenant.id) })\n }\n } else {\n if (isEncryptionDebugEnabled()) {\n console.warn('\u26A0\uFE0F [encryption][setup] KMS not healthy, skipping tenant DEK creation', { tenantId: String(tenant.id) })\n }\n }\n } catch (err) {\n if (isEncryptionDebugEnabled()) {\n console.warn('\u26A0\uFE0F [encryption][setup] Failed to create tenant DEK', err)\n }\n }\n }\n\n await ensureRolesInContext(tem, roleNames, roleTenantId)\n await tem.flush()\n\n if (isTenantDataEncryptionEnabled()) {\n for (const spec of defaultEncryptionMaps) {\n const existing = await findOneWithDecryption(tem, EncryptionMap, { entityId: spec.entityId, tenantId: tenant.id, organizationId: organization.id, deletedAt: null }, {}, { tenantId: String(tenant.id), organizationId: String(organization.id) })\n if (!existing) {\n tem.persist(tem.create(EncryptionMap, {\n entityId: spec.entityId,\n tenantId: tenant.id,\n organizationId: organization.id,\n fieldsJson: spec.fields,\n isActive: true,\n createdAt: new Date(),\n updatedAt: new Date(),\n }))\n } else {\n existing.fieldsJson = spec.fields\n existing.isActive = true\n }\n }\n await tem.flush()\n }\n })\n\n await em.transactional(async (tem) => {\n if (!tenantId || !organizationId) return\n const roleTenantId = tenantId\n const encryptionService = isTenantDataEncryptionEnabled()\n ? new TenantDataEncryptionService(tem as any, { kms: createKmsService() })\n : null\n if (encryptionService) {\n await encryptionService.invalidateMap('auth:user', String(tenantId), String(organizationId))\n await encryptionService.invalidateMap('auth:user', String(tenantId), null)\n }\n\n for (const base of baseUsers) {\n const resolvedPasswordHash = base.passwordHash ?? passwordHash\n let user = await findOneWithDecryption(tem, User, { email: base.email }, {}, { tenantId: tenantId ?? null, organizationId: organizationId ?? null })\n const confirm = primaryUser.confirm ?? true\n const encryptedPayload = encryptionService\n ? await encryptionService.encryptEntityPayload('auth:user', { email: base.email }, tenantId, organizationId)\n : { email: base.email, emailHash: computeEmailHash(base.email) }\n if (user) {\n user.passwordHash = resolvedPasswordHash\n user.organizationId = organizationId\n user.tenantId = tenantId\n if (isTenantDataEncryptionEnabled()) {\n user.email = encryptedPayload.email as any\n user.emailHash = (encryptedPayload as any).emailHash ?? computeEmailHash(base.email)\n }\n if (base.name) user.name = base.name\n if (confirm) user.isConfirmed = true\n tem.persist(user)\n userSnapshots.push({ user, roles: base.roles, created: false })\n } else {\n user = tem.create(User, {\n email: (encryptedPayload as any).email ?? base.email,\n emailHash: isTenantDataEncryptionEnabled() ? (encryptedPayload as any).emailHash ?? computeEmailHash(base.email) : undefined,\n passwordHash: resolvedPasswordHash,\n organizationId,\n tenantId,\n name: base.name ?? undefined,\n isConfirmed: confirm,\n createdAt: new Date(),\n })\n tem.persist(user)\n userSnapshots.push({ user, roles: base.roles, created: true })\n }\n await tem.flush()\n for (const roleName of base.roles) {\n const role = await findRoleByNameOrFail(tem, roleName, roleTenantId)\n const existingLink = await findOneWithDecryption(tem, UserRole, { user, role }, {}, { tenantId: tenantId ?? null, organizationId: null })\n if (!existingLink) tem.persist(tem.create(UserRole, { user, role, createdAt: new Date() }))\n }\n await tem.flush()\n }\n })\n }\n\n if (!tenantId || !organizationId) {\n throw new Error('SETUP_FAILED')\n }\n\n if (!reusedExistingUser) {\n await rebuildHierarchyForTenant(em, tenantId)\n }\n\n await ensureDefaultRoleAcls(em, tenantId, resolvedModules, { includeSuperadminRole })\n await deactivateDemoSuperAdminIfSelfOnboardingEnabled(em)\n\n // Call module onTenantCreated hooks\n for (const mod of resolvedModules) {\n if (mod.setup?.onTenantCreated) {\n await mod.setup.onTenantCreated({ em, tenantId, organizationId })\n }\n }\n\n return {\n tenantId,\n organizationId,\n users: userSnapshots,\n reusedExistingUser,\n }\n}\n\nfunction resolvePrimaryName(input: PrimaryUserInput): string | null {\n if (input.displayName && input.displayName.trim()) return input.displayName.trim()\n const parts = [input.firstName, input.lastName].map((value) => value?.trim()).filter(Boolean)\n if (parts.length) return parts.join(' ')\n return null\n}\n\nfunction readEnvValue(key: string): string | undefined {\n const value = process.env[key]\n if (typeof value !== 'string') return undefined\n const trimmed = value.trim()\n return trimmed.length > 0 ? trimmed : undefined\n}\n\nfunction addUniqueBaseUser(\n baseUsers: Array<{ email: string; roles: string[]; name?: string | null; passwordHash?: string | null }>,\n entry: { email: string; roles: string[]; name?: string | null; passwordHash?: string | null },\n) {\n if (!entry.email) return\n const normalized = entry.email.toLowerCase()\n if (baseUsers.some((user) => user.email.toLowerCase() === normalized)) return\n baseUsers.push(entry)\n}\n\nfunction isDemoModeEnabled(): boolean {\n const parsed = parseBooleanToken(process.env.DEMO_MODE ?? '')\n return parsed === false ? false : true\n}\n\nfunction shouldKeepDemoSuperadminDuringInit(): boolean {\n if (process.env.OM_INIT_FLOW !== 'true') return false\n if (!readEnvValue('OM_INIT_SUPERADMIN_EMAIL')) return false\n return isDemoModeEnabled()\n}\n\nasync function resolvePasswordHash(input: PrimaryUserInput): Promise<string | null> {\n if (typeof input.hashedPassword === 'string') return input.hashedPassword\n if (input.password) return hash(input.password, 10)\n return null\n}\n\nasync function ensureDefaultRoleAcls(\n em: EntityManager,\n tenantId: string,\n modules: Module[],\n options: { includeSuperadminRole?: boolean } = {},\n) {\n const includeSuperadminRole = options.includeSuperadminRole ?? true\n const roleTenantId = normalizeTenantId(tenantId) ?? null\n const superadminRole = includeSuperadminRole ? await findRoleByName(em, 'superadmin', roleTenantId) : null\n const adminRole = await findRoleByName(em, 'admin', roleTenantId)\n const employeeRole = await findRoleByName(em, 'employee', roleTenantId)\n\n // Merge features from all enabled modules' setup configs\n const builtInRoles = ['superadmin', 'admin', 'employee'] as const\n const superadminFeatures: string[] = []\n const adminFeatures: string[] = []\n const employeeFeatures: string[] = []\n const customRoleFeatures = new Map<string, string[]>()\n\n for (const mod of modules) {\n const roleFeatures = mod.setup?.defaultRoleFeatures\n if (!roleFeatures) continue\n if (roleFeatures.superadmin) superadminFeatures.push(...roleFeatures.superadmin)\n if (roleFeatures.admin) adminFeatures.push(...roleFeatures.admin)\n if (roleFeatures.employee) employeeFeatures.push(...roleFeatures.employee)\n\n // Collect features for custom roles (any key not in builtInRoles)\n for (const [roleName, features] of Object.entries(roleFeatures)) {\n if ((builtInRoles as readonly string[]).includes(roleName)) continue\n if (!Array.isArray(features)) continue\n const existing = customRoleFeatures.get(roleName) ?? []\n existing.push(...features)\n customRoleFeatures.set(roleName, existing)\n }\n }\n\n console.log('\u2705 Seeded default role features', {\n superadmin: superadminFeatures,\n admin: adminFeatures,\n employee: employeeFeatures,\n ...(customRoleFeatures.size > 0\n ? Object.fromEntries(customRoleFeatures)\n : {}),\n })\n\n if (includeSuperadminRole && superadminRole) {\n await ensureRoleAclFor(em, superadminRole, tenantId, superadminFeatures, { isSuperAdmin: true })\n }\n if (adminRole) {\n await ensureRoleAclFor(em, adminRole, tenantId, adminFeatures)\n }\n if (employeeRole) {\n await ensureRoleAclFor(em, employeeRole, tenantId, employeeFeatures)\n }\n\n // Seed ACLs for custom roles defined by app modules.\n // NOTE: Custom roles may not exist yet if they are created in seedDefaults\n // (which runs after this function). In that case, use ensureCustomRoleAcls()\n // after seedDefaults to pick them up.\n for (const [roleName, features] of customRoleFeatures) {\n const role = await findRoleByName(em, roleName, roleTenantId)\n if (role) {\n await ensureRoleAclFor(em, role, tenantId, features)\n }\n }\n}\n\n/**\n * Seed ACLs for custom roles defined in module defaultRoleFeatures.\n * Call this AFTER seedDefaults to pick up roles created by app modules.\n * Safe to call multiple times \u2014 ensureRoleAclFor merges features idempotently.\n */\nexport async function ensureCustomRoleAcls(\n em: EntityManager,\n tenantId: string,\n modules?: Module[],\n): Promise<void> {\n const resolvedModules = modules ?? tryGetModules()\n const roleTenantId = normalizeTenantId(tenantId) ?? null\n const builtInRoles = ['superadmin', 'admin', 'employee']\n const customRoleFeatures = new Map<string, string[]>()\n\n for (const mod of resolvedModules) {\n const roleFeatures = mod.setup?.defaultRoleFeatures\n if (!roleFeatures) continue\n for (const [roleName, features] of Object.entries(roleFeatures)) {\n if (builtInRoles.includes(roleName)) continue\n if (!Array.isArray(features)) continue\n const existing = customRoleFeatures.get(roleName) ?? []\n existing.push(...features)\n customRoleFeatures.set(roleName, existing)\n }\n }\n\n if (customRoleFeatures.size === 0) return\n\n let seeded = 0\n for (const [roleName, features] of customRoleFeatures) {\n const role = await findRoleByName(em, roleName, roleTenantId)\n if (role) {\n await ensureRoleAclFor(em, role, tenantId, features)\n seeded++\n }\n }\n if (seeded > 0) {\n console.log(`\u2705 Seeded custom role ACLs (${seeded} roles)`)\n }\n}\n\nasync function ensureRoleAclFor(\n em: EntityManager,\n role: Role,\n tenantId: string,\n features: string[],\n options: { isSuperAdmin?: boolean } = {},\n) {\n const existing = await findOneWithDecryption(em, RoleAcl, { role, tenantId }, {}, { tenantId, organizationId: null })\n if (!existing) {\n const acl = em.create(RoleAcl, {\n role,\n tenantId,\n featuresJson: features,\n isSuperAdmin: !!options.isSuperAdmin,\n createdAt: new Date(),\n })\n await em.persist(acl).flush()\n return\n }\n const currentFeatures = Array.isArray(existing.featuresJson) ? existing.featuresJson : []\n const merged = Array.from(new Set([...currentFeatures, ...features]))\n const changed =\n merged.length !== currentFeatures.length ||\n merged.some((value, index) => value !== currentFeatures[index])\n if (changed) existing.featuresJson = merged\n if (options.isSuperAdmin && !existing.isSuperAdmin) {\n existing.isSuperAdmin = true\n }\n if (changed || options.isSuperAdmin) {\n await em.persist(existing).flush()\n }\n}\n\nasync function deactivateDemoSuperAdminIfSelfOnboardingEnabled(em: EntityManager) {\n if (process.env.SELF_SERVICE_ONBOARDING_ENABLED !== 'true') return\n if (shouldKeepDemoSuperadminDuringInit()) return\n try {\n const user = await findOneWithDecryption(em, User, { email: DEMO_SUPERADMIN_EMAIL }, {}, { tenantId: null, organizationId: null })\n if (!user) return\n let dirty = false\n if (user.passwordHash) {\n user.passwordHash = null\n dirty = true\n }\n if (user.isConfirmed !== false) {\n user.isConfirmed = false\n dirty = true\n }\n if (dirty) {\n await em.persist(user).flush()\n }\n } catch (error) {\n console.error('[auth.setup] failed to deactivate demo superadmin user', error)\n }\n}\n\n/** Try to get modules from runtime registry; returns empty array if not yet registered. */\nfunction tryGetModules(): Module[] {\n try {\n const { getModules } = require('@open-mercato/shared/lib/modules/registry')\n return getModules()\n } catch {\n return []\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -69,7 +69,7 @@ class AuthService {
|
|
|
69
69
|
const rawToken = generateAuthToken();
|
|
70
70
|
const tokenHash = hashAuthToken(rawToken);
|
|
71
71
|
const sess = this.em.create(Session, { user, token: tokenHash, expiresAt, createdAt: /* @__PURE__ */ new Date() });
|
|
72
|
-
await this.em.
|
|
72
|
+
await this.em.persist(sess).flush();
|
|
73
73
|
return { session: sess, token: rawToken };
|
|
74
74
|
}
|
|
75
75
|
async deleteSessionByToken(token) {
|
|
@@ -111,7 +111,7 @@ class AuthService {
|
|
|
111
111
|
const tokenHash = hashAuthToken(rawToken);
|
|
112
112
|
const expiresAt = new Date(Date.now() + 60 * 60 * 1e3);
|
|
113
113
|
const row = this.em.create(PasswordReset, { user, token: tokenHash, expiresAt, createdAt: /* @__PURE__ */ new Date() });
|
|
114
|
-
await this.em.
|
|
114
|
+
await this.em.persist(row).flush();
|
|
115
115
|
return { user, token: rawToken };
|
|
116
116
|
}
|
|
117
117
|
async confirmPasswordReset(token, newPassword) {
|