@open-mercato/core 0.4.2-canary-f075c3eb92 → 0.4.2-canary-e2aeb1a7bf
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/generated/entities/notification/index.js +57 -0
- package/dist/generated/entities/notification/index.js.map +7 -0
- package/dist/generated/entities.ids.generated.js +5 -1
- package/dist/generated/entities.ids.generated.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +2 -0
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/modules/api_docs/frontend/docs/api/page.js +3 -2
- package/dist/modules/api_docs/frontend/docs/api/page.js.map +2 -2
- package/dist/modules/api_keys/backend/api-keys/page.js +1 -1
- package/dist/modules/api_keys/backend/api-keys/page.js.map +2 -2
- package/dist/modules/attachments/components/AttachmentLibrary.js +4 -0
- package/dist/modules/attachments/components/AttachmentLibrary.js.map +2 -2
- package/dist/modules/attachments/components/AttachmentPartitionSettings.js +2 -0
- package/dist/modules/attachments/components/AttachmentPartitionSettings.js.map +2 -2
- package/dist/modules/auth/api/admin/nav.js +4 -3
- package/dist/modules/auth/api/admin/nav.js.map +2 -2
- package/dist/modules/auth/api/login.js +25 -6
- package/dist/modules/auth/api/login.js.map +2 -2
- package/dist/modules/auth/api/profile/route.js +157 -0
- package/dist/modules/auth/api/profile/route.js.map +7 -0
- package/dist/modules/auth/api/reset/confirm.js +25 -2
- package/dist/modules/auth/api/reset/confirm.js.map +2 -2
- package/dist/modules/auth/api/reset.js +23 -0
- package/dist/modules/auth/api/reset.js.map +2 -2
- package/dist/modules/auth/api/sidebar/preferences/route.js +14 -9
- package/dist/modules/auth/api/sidebar/preferences/route.js.map +2 -2
- package/dist/modules/auth/api/users/route.js +4 -2
- package/dist/modules/auth/api/users/route.js.map +2 -2
- package/dist/modules/auth/backend/auth/profile/page.js +141 -0
- package/dist/modules/auth/backend/auth/profile/page.js.map +7 -0
- package/dist/modules/auth/backend/auth/profile/page.meta.js +13 -0
- package/dist/modules/auth/backend/auth/profile/page.meta.js.map +7 -0
- package/dist/modules/auth/backend/roles/[id]/edit/page.js +4 -1
- package/dist/modules/auth/backend/roles/[id]/edit/page.js.map +2 -2
- package/dist/modules/auth/backend/roles/page.js +3 -3
- package/dist/modules/auth/backend/roles/page.js.map +2 -2
- package/dist/modules/auth/backend/users/[id]/edit/page.js +18 -3
- package/dist/modules/auth/backend/users/[id]/edit/page.js.map +2 -2
- package/dist/modules/auth/backend/users/create/page.js +15 -2
- package/dist/modules/auth/backend/users/create/page.js.map +2 -2
- package/dist/modules/auth/backend/users/page.js +3 -3
- package/dist/modules/auth/backend/users/page.js.map +2 -2
- package/dist/modules/auth/cli.js +25 -11
- package/dist/modules/auth/cli.js.map +2 -2
- package/dist/modules/auth/commands/users.js +59 -2
- package/dist/modules/auth/commands/users.js.map +2 -2
- package/dist/modules/auth/data/validators.js +6 -3
- package/dist/modules/auth/data/validators.js.map +2 -2
- package/dist/modules/auth/frontend/login.js +112 -3
- package/dist/modules/auth/frontend/login.js.map +2 -2
- package/dist/modules/auth/frontend/reset/[token]/page.js +20 -10
- package/dist/modules/auth/frontend/reset/[token]/page.js.map +2 -2
- package/dist/modules/auth/lib/setup-app.js +41 -8
- package/dist/modules/auth/lib/setup-app.js.map +2 -2
- package/dist/modules/auth/notifications.js +112 -0
- package/dist/modules/auth/notifications.js.map +7 -0
- package/dist/modules/auth/services/authService.js +24 -3
- package/dist/modules/auth/services/authService.js.map +2 -2
- package/dist/modules/business_rules/api/execute/route.js +7 -1
- package/dist/modules/business_rules/api/execute/route.js.map +2 -2
- package/dist/modules/business_rules/backend/rules/page.js +4 -0
- package/dist/modules/business_rules/backend/rules/page.js.map +2 -2
- package/dist/modules/business_rules/backend/sets/page.js +3 -0
- package/dist/modules/business_rules/backend/sets/page.js.map +2 -2
- package/dist/modules/business_rules/cli.js +2 -1
- package/dist/modules/business_rules/cli.js.map +2 -2
- package/dist/modules/business_rules/lib/rule-engine.js +33 -3
- package/dist/modules/business_rules/lib/rule-engine.js.map +2 -2
- package/dist/modules/business_rules/notifications.js +28 -0
- package/dist/modules/business_rules/notifications.js.map +7 -0
- package/dist/modules/business_rules/subscribers/rule-execution-failed-notification.js +37 -0
- package/dist/modules/business_rules/subscribers/rule-execution-failed-notification.js.map +7 -0
- package/dist/modules/catalog/components/PriceKindSettings.js +2 -0
- package/dist/modules/catalog/components/PriceKindSettings.js.map +2 -2
- package/dist/modules/catalog/components/categories/CategoriesDataTable.js +2 -2
- package/dist/modules/catalog/components/categories/CategoriesDataTable.js.map +2 -2
- package/dist/modules/catalog/components/products/ProductsDataTable.js +2 -0
- package/dist/modules/catalog/components/products/ProductsDataTable.js.map +2 -2
- package/dist/modules/catalog/notifications.js +28 -0
- package/dist/modules/catalog/notifications.js.map +7 -0
- package/dist/modules/catalog/subscribers/low-stock-notification.js +38 -0
- package/dist/modules/catalog/subscribers/low-stock-notification.js.map +7 -0
- package/dist/modules/configs/cli.js +6 -0
- package/dist/modules/configs/cli.js.map +2 -2
- package/dist/modules/configs/components/CachePanel.js +4 -4
- package/dist/modules/configs/components/CachePanel.js.map +2 -2
- package/dist/modules/configs/lib/system-status.js +48 -1
- package/dist/modules/configs/lib/system-status.js.map +2 -2
- package/dist/modules/configs/lib/upgrade-actions.js +1 -352
- package/dist/modules/configs/lib/upgrade-actions.js.map +2 -2
- package/dist/modules/currencies/backend/currencies/page.js +3 -0
- package/dist/modules/currencies/backend/currencies/page.js.map +2 -2
- package/dist/modules/currencies/backend/exchange-rates/page.js +2 -0
- package/dist/modules/currencies/backend/exchange-rates/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies/page.js +3 -0
- package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/page.js +3 -0
- package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/people/page.js +3 -0
- package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
- package/dist/modules/customers/commands/deals.js +31 -0
- package/dist/modules/customers/commands/deals.js.map +2 -2
- package/dist/modules/customers/components/CustomerTodosTable.js +1 -0
- package/dist/modules/customers/components/CustomerTodosTable.js.map +2 -2
- package/dist/modules/customers/notifications.js +48 -0
- package/dist/modules/customers/notifications.js.map +7 -0
- package/dist/modules/customers/widgets/dashboard/customer-todos/widget.js +2 -1
- package/dist/modules/customers/widgets/dashboard/customer-todos/widget.js.map +2 -2
- package/dist/modules/customers/widgets/dashboard/new-customers/widget.js +2 -1
- package/dist/modules/customers/widgets/dashboard/new-customers/widget.js.map +2 -2
- package/dist/modules/customers/widgets/dashboard/new-deals/widget.js +2 -1
- package/dist/modules/customers/widgets/dashboard/new-deals/widget.js.map +2 -2
- package/dist/modules/customers/widgets/dashboard/next-interactions/widget.js +2 -1
- package/dist/modules/customers/widgets/dashboard/next-interactions/widget.js.map +2 -2
- package/dist/modules/dashboards/cli.js +44 -5
- package/dist/modules/dashboards/cli.js.map +2 -2
- package/dist/modules/dashboards/components/WidgetVisibilityEditor.js +16 -11
- package/dist/modules/dashboards/components/WidgetVisibilityEditor.js.map +3 -3
- package/dist/modules/dashboards/lib/role-widgets.js +58 -0
- package/dist/modules/dashboards/lib/role-widgets.js.map +7 -0
- package/dist/modules/dashboards/services/widgetDataService.js +139 -3
- package/dist/modules/dashboards/services/widgetDataService.js.map +2 -2
- package/dist/modules/dashboards/setup.js +15 -0
- package/dist/modules/dashboards/setup.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/aov-kpi/widget.js +2 -1
- package/dist/modules/dashboards/widgets/dashboard/aov-kpi/widget.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/new-customers-kpi/widget.js +2 -1
- package/dist/modules/dashboards/widgets/dashboard/new-customers-kpi/widget.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/orders-by-status/widget.js +2 -1
- package/dist/modules/dashboards/widgets/dashboard/orders-by-status/widget.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/orders-kpi/widget.js +2 -1
- package/dist/modules/dashboards/widgets/dashboard/orders-kpi/widget.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/pipeline-summary/widget.js +2 -1
- package/dist/modules/dashboards/widgets/dashboard/pipeline-summary/widget.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/revenue-kpi/widget.js +2 -1
- package/dist/modules/dashboards/widgets/dashboard/revenue-kpi/widget.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/revenue-trend/widget.js +2 -1
- package/dist/modules/dashboards/widgets/dashboard/revenue-trend/widget.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/sales-by-region/widget.js +2 -1
- package/dist/modules/dashboards/widgets/dashboard/sales-by-region/widget.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/top-customers/widget.js +2 -1
- package/dist/modules/dashboards/widgets/dashboard/top-customers/widget.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/top-products/widget.js +2 -1
- package/dist/modules/dashboards/widgets/dashboard/top-products/widget.js.map +2 -2
- package/dist/modules/dictionaries/components/DictionaryTable.js +2 -0
- package/dist/modules/dictionaries/components/DictionaryTable.js.map +2 -2
- package/dist/modules/directory/api/get/tenants/lookup.js +70 -0
- package/dist/modules/directory/api/get/tenants/lookup.js.map +7 -0
- package/dist/modules/directory/backend/directory/organizations/page.js +2 -2
- package/dist/modules/directory/backend/directory/organizations/page.js.map +2 -2
- package/dist/modules/directory/backend/directory/tenants/page.js +2 -2
- package/dist/modules/directory/backend/directory/tenants/page.js.map +2 -2
- package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js +2 -2
- package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js.map +2 -2
- package/dist/modules/entities/components/SystemEntitiesTable.js +1 -1
- package/dist/modules/entities/components/SystemEntitiesTable.js.map +2 -2
- package/dist/modules/entities/components/UserEntitiesTable.js +2 -2
- package/dist/modules/entities/components/UserEntitiesTable.js.map +2 -2
- package/dist/modules/feature_toggles/components/FeatureTogglesTable.js +3 -3
- package/dist/modules/feature_toggles/components/FeatureTogglesTable.js.map +2 -2
- package/dist/modules/feature_toggles/components/OverridesTable.js +1 -1
- package/dist/modules/feature_toggles/components/OverridesTable.js.map +2 -2
- package/dist/modules/notifications/acl.js +11 -0
- package/dist/modules/notifications/acl.js.map +7 -0
- package/dist/modules/notifications/api/[id]/action/route.js +74 -0
- package/dist/modules/notifications/api/[id]/action/route.js.map +7 -0
- package/dist/modules/notifications/api/[id]/dismiss/route.js +15 -0
- package/dist/modules/notifications/api/[id]/dismiss/route.js.map +7 -0
- package/dist/modules/notifications/api/[id]/read/route.js +15 -0
- package/dist/modules/notifications/api/[id]/read/route.js.map +7 -0
- package/dist/modules/notifications/api/[id]/restore/route.js +53 -0
- package/dist/modules/notifications/api/[id]/restore/route.js.map +7 -0
- package/dist/modules/notifications/api/batch/route.js +17 -0
- package/dist/modules/notifications/api/batch/route.js.map +7 -0
- package/dist/modules/notifications/api/feature/route.js +17 -0
- package/dist/modules/notifications/api/feature/route.js.map +7 -0
- package/dist/modules/notifications/api/mark-all-read/route.js +35 -0
- package/dist/modules/notifications/api/mark-all-read/route.js.map +7 -0
- package/dist/modules/notifications/api/openapi.js +76 -0
- package/dist/modules/notifications/api/openapi.js.map +7 -0
- package/dist/modules/notifications/api/role/route.js +17 -0
- package/dist/modules/notifications/api/role/route.js.map +7 -0
- package/dist/modules/notifications/api/route.js +85 -0
- package/dist/modules/notifications/api/route.js.map +7 -0
- package/dist/modules/notifications/api/settings/route.js +155 -0
- package/dist/modules/notifications/api/settings/route.js.map +7 -0
- package/dist/modules/notifications/api/unread-count/route.js +38 -0
- package/dist/modules/notifications/api/unread-count/route.js.map +7 -0
- package/dist/modules/notifications/backend/config/notifications/page.js +10 -0
- package/dist/modules/notifications/backend/config/notifications/page.js.map +7 -0
- package/dist/modules/notifications/backend/config/notifications/page.meta.js +24 -0
- package/dist/modules/notifications/backend/config/notifications/page.meta.js.map +7 -0
- package/dist/modules/notifications/cli.js +16 -0
- package/dist/modules/notifications/cli.js.map +7 -0
- package/dist/modules/notifications/data/entities.js +112 -0
- package/dist/modules/notifications/data/entities.js.map +7 -0
- package/dist/modules/notifications/data/validators.js +98 -0
- package/dist/modules/notifications/data/validators.js.map +7 -0
- package/dist/modules/notifications/di.js +13 -0
- package/dist/modules/notifications/di.js.map +7 -0
- package/dist/modules/notifications/emails/NotificationEmail.js +58 -0
- package/dist/modules/notifications/emails/NotificationEmail.js.map +7 -0
- package/dist/modules/notifications/frontend/NotificationInboxPageClient.js +44 -0
- package/dist/modules/notifications/frontend/NotificationInboxPageClient.js.map +7 -0
- package/dist/modules/notifications/frontend/NotificationSettingsPageClient.js +220 -0
- package/dist/modules/notifications/frontend/NotificationSettingsPageClient.js.map +7 -0
- package/dist/modules/notifications/index.js +14 -0
- package/dist/modules/notifications/index.js.map +7 -0
- package/dist/modules/notifications/lib/deliveryConfig.js +107 -0
- package/dist/modules/notifications/lib/deliveryConfig.js.map +7 -0
- package/dist/modules/notifications/lib/deliveryStrategies.js +14 -0
- package/dist/modules/notifications/lib/deliveryStrategies.js.map +7 -0
- package/dist/modules/notifications/lib/events.js +12 -0
- package/dist/modules/notifications/lib/events.js.map +7 -0
- package/dist/modules/notifications/lib/notificationBuilder.js +66 -0
- package/dist/modules/notifications/lib/notificationBuilder.js.map +7 -0
- package/dist/modules/notifications/lib/notificationFactory.js +54 -0
- package/dist/modules/notifications/lib/notificationFactory.js.map +7 -0
- package/dist/modules/notifications/lib/notificationMapper.js +34 -0
- package/dist/modules/notifications/lib/notificationMapper.js.map +7 -0
- package/dist/modules/notifications/lib/notificationRecipients.js +35 -0
- package/dist/modules/notifications/lib/notificationRecipients.js.map +7 -0
- package/dist/modules/notifications/lib/notificationService.js +279 -0
- package/dist/modules/notifications/lib/notificationService.js.map +7 -0
- package/dist/modules/notifications/lib/routeHelpers.js +101 -0
- package/dist/modules/notifications/lib/routeHelpers.js.map +7 -0
- package/dist/modules/notifications/lib/safeHref.js +24 -0
- package/dist/modules/notifications/lib/safeHref.js.map +7 -0
- package/dist/modules/notifications/migrations/Migration20260123000001.js +70 -0
- package/dist/modules/notifications/migrations/Migration20260123000001.js.map +7 -0
- package/dist/modules/notifications/migrations/Migration20260126150000.js +37 -0
- package/dist/modules/notifications/migrations/Migration20260126150000.js.map +7 -0
- package/dist/modules/notifications/migrations/Migration20260129082610.js +13 -0
- package/dist/modules/notifications/migrations/Migration20260129082610.js.map +7 -0
- package/dist/modules/notifications/subscribers/deliver-notification.js +165 -0
- package/dist/modules/notifications/subscribers/deliver-notification.js.map +7 -0
- package/dist/modules/notifications/workers/create-notification.worker.js +70 -0
- package/dist/modules/notifications/workers/create-notification.worker.js.map +7 -0
- package/dist/modules/planner/backend/planner/availability-rulesets/page.js +2 -2
- package/dist/modules/planner/backend/planner/availability-rulesets/page.js.map +2 -2
- package/dist/modules/query_index/cli.js +63 -7
- package/dist/modules/query_index/cli.js.map +2 -2
- package/dist/modules/query_index/components/QueryIndexesTable.js +7 -1
- package/dist/modules/query_index/components/QueryIndexesTable.js.map +2 -2
- package/dist/modules/resources/backend/resources/resource-types/page.js +2 -2
- package/dist/modules/resources/backend/resources/resource-types/page.js.map +2 -2
- package/dist/modules/resources/backend/resources/resources/page.js +2 -2
- package/dist/modules/resources/backend/resources/resources/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/channels/offers/page.js +2 -0
- package/dist/modules/sales/backend/sales/channels/offers/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/channels/page.js +2 -0
- package/dist/modules/sales/backend/sales/channels/page.js.map +2 -2
- package/dist/modules/sales/cli.js +2 -42
- package/dist/modules/sales/cli.js.map +2 -2
- package/dist/modules/sales/commands/documents.js +53 -0
- package/dist/modules/sales/commands/documents.js.map +2 -2
- package/dist/modules/sales/commands/payments.js +26 -0
- package/dist/modules/sales/commands/payments.js.map +2 -2
- package/dist/modules/sales/components/AdjustmentKindSettings.js +2 -2
- package/dist/modules/sales/components/AdjustmentKindSettings.js.map +2 -2
- package/dist/modules/sales/components/PaymentMethodsSettings.js +2 -2
- package/dist/modules/sales/components/PaymentMethodsSettings.js.map +2 -2
- package/dist/modules/sales/components/ShippingMethodsSettings.js +2 -2
- package/dist/modules/sales/components/ShippingMethodsSettings.js.map +2 -2
- package/dist/modules/sales/components/TaxRatesSettings.js +2 -2
- package/dist/modules/sales/components/TaxRatesSettings.js.map +2 -2
- package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js +2 -0
- package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js.map +2 -2
- package/dist/modules/sales/components/documents/AdjustmentsSection.js +2 -0
- package/dist/modules/sales/components/documents/AdjustmentsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/PaymentsSection.js +2 -1
- package/dist/modules/sales/components/documents/PaymentsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/SalesDocumentsTable.js +2 -0
- package/dist/modules/sales/components/documents/SalesDocumentsTable.js.map +2 -2
- package/dist/modules/sales/lib/seeds.js +48 -0
- package/dist/modules/sales/lib/seeds.js.map +7 -0
- package/dist/modules/sales/notifications.client.js +51 -0
- package/dist/modules/sales/notifications.client.js.map +7 -0
- package/dist/modules/sales/notifications.js +88 -0
- package/dist/modules/sales/notifications.js.map +7 -0
- package/dist/modules/sales/subscribers/quote-expiring-notification.js +38 -0
- package/dist/modules/sales/subscribers/quote-expiring-notification.js.map +7 -0
- package/dist/modules/sales/widgets/notifications/SalesOrderCreatedRenderer.js +137 -0
- package/dist/modules/sales/widgets/notifications/SalesOrderCreatedRenderer.js.map +7 -0
- package/dist/modules/sales/widgets/notifications/SalesQuoteCreatedRenderer.js +137 -0
- package/dist/modules/sales/widgets/notifications/SalesQuoteCreatedRenderer.js.map +7 -0
- package/dist/modules/sales/widgets/notifications/index.js +7 -0
- package/dist/modules/sales/widgets/notifications/index.js.map +7 -0
- package/dist/modules/sales/widgets/notifications/useSalesDocumentTotals.js +60 -0
- package/dist/modules/sales/widgets/notifications/useSalesDocumentTotals.js.map +7 -0
- package/dist/modules/staff/backend/staff/team-members/page.js +1 -1
- package/dist/modules/staff/backend/staff/team-members/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-roles/page.js +2 -2
- package/dist/modules/staff/backend/staff/team-roles/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js +2 -2
- package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/teams/page.js +2 -2
- package/dist/modules/staff/backend/staff/teams/page.js.map +2 -2
- package/dist/modules/staff/commands/leave-requests.js +79 -0
- package/dist/modules/staff/commands/leave-requests.js.map +2 -2
- package/dist/modules/staff/notifications.js +75 -0
- package/dist/modules/staff/notifications.js.map +7 -0
- package/dist/modules/workflows/backend/definitions/page.js +5 -0
- package/dist/modules/workflows/backend/definitions/page.js.map +2 -2
- package/dist/modules/workflows/backend/instances/page.js +3 -0
- package/dist/modules/workflows/backend/instances/page.js.map +2 -2
- package/dist/modules/workflows/backend/tasks/page.js +3 -0
- package/dist/modules/workflows/backend/tasks/page.js.map +2 -2
- package/dist/modules/workflows/cli.js +12 -12
- package/dist/modules/workflows/cli.js.map +2 -2
- package/dist/modules/workflows/lib/transition-handler.js +14 -6
- package/dist/modules/workflows/lib/transition-handler.js.map +2 -2
- package/dist/modules/workflows/notifications.js +28 -0
- package/dist/modules/workflows/notifications.js.map +7 -0
- package/dist/modules/workflows/subscribers/task-assigned-notification.js +38 -0
- package/dist/modules/workflows/subscribers/task-assigned-notification.js.map +7 -0
- package/generated/entities/notification/index.ts +27 -0
- package/generated/entities.ids.generated.ts +5 -1
- package/generated/entity-fields-registry.ts +2 -0
- package/package.json +2 -2
- package/src/modules/api_docs/frontend/docs/api/page.tsx +3 -2
- package/src/modules/api_keys/backend/api-keys/page.tsx +1 -1
- package/src/modules/attachments/components/AttachmentLibrary.tsx +4 -0
- package/src/modules/attachments/components/AttachmentPartitionSettings.tsx +2 -0
- package/src/modules/auth/README.md +1 -1
- package/src/modules/auth/__tests__/cli-setup-acl.test.ts +1 -1
- package/src/modules/auth/api/__tests__/login.test.ts +2 -0
- package/src/modules/auth/api/admin/nav.ts +10 -6
- package/src/modules/auth/api/login.ts +26 -7
- package/src/modules/auth/api/profile/route.ts +163 -0
- package/src/modules/auth/api/reset/confirm.ts +25 -2
- package/src/modules/auth/api/reset.ts +23 -0
- package/src/modules/auth/api/sidebar/preferences/route.ts +21 -12
- package/src/modules/auth/api/users/route.ts +5 -2
- package/src/modules/auth/backend/auth/profile/page.meta.ts +9 -0
- package/src/modules/auth/backend/auth/profile/page.tsx +174 -0
- package/src/modules/auth/backend/roles/[id]/edit/page.tsx +4 -1
- package/src/modules/auth/backend/roles/page.tsx +3 -3
- package/src/modules/auth/backend/users/[id]/edit/page.tsx +22 -3
- package/src/modules/auth/backend/users/create/page.tsx +19 -2
- package/src/modules/auth/backend/users/page.tsx +3 -3
- package/src/modules/auth/cli.ts +38 -11
- package/src/modules/auth/commands/users.ts +73 -2
- package/src/modules/auth/data/validators.ts +6 -2
- package/src/modules/auth/frontend/login.tsx +134 -5
- package/src/modules/auth/frontend/reset/[token]/page.tsx +24 -11
- package/src/modules/auth/i18n/de.json +48 -1
- package/src/modules/auth/i18n/en.json +48 -1
- package/src/modules/auth/i18n/es.json +48 -1
- package/src/modules/auth/i18n/pl.json +48 -1
- package/src/modules/auth/lib/setup-app.ts +57 -9
- package/src/modules/auth/notifications.ts +109 -0
- package/src/modules/auth/services/authService.ts +27 -4
- package/src/modules/business_rules/api/execute/route.ts +8 -1
- package/src/modules/business_rules/backend/rules/page.tsx +4 -0
- package/src/modules/business_rules/backend/sets/page.tsx +3 -0
- package/src/modules/business_rules/cli.ts +2 -1
- package/src/modules/business_rules/i18n/en.json +3 -1
- package/src/modules/business_rules/lib/__tests__/rule-engine.test.ts +51 -0
- package/src/modules/business_rules/lib/rule-engine.ts +57 -3
- package/src/modules/business_rules/notifications.ts +25 -0
- package/src/modules/business_rules/subscribers/rule-execution-failed-notification.ts +50 -0
- package/src/modules/catalog/components/PriceKindSettings.tsx +2 -0
- package/src/modules/catalog/components/categories/CategoriesDataTable.tsx +2 -2
- package/src/modules/catalog/components/products/ProductsDataTable.tsx +2 -0
- package/src/modules/catalog/i18n/en.json +3 -1
- package/src/modules/catalog/notifications.ts +25 -0
- package/src/modules/catalog/subscribers/low-stock-notification.ts +52 -0
- package/src/modules/configs/cli.ts +6 -0
- package/src/modules/configs/components/CachePanel.tsx +4 -4
- package/src/modules/configs/i18n/en.json +12 -2
- package/src/modules/configs/i18n/pl.json +12 -2
- package/src/modules/configs/lib/system-status.ts +48 -1
- package/src/modules/configs/lib/system-status.types.ts +1 -0
- package/src/modules/configs/lib/upgrade-actions.ts +2 -396
- package/src/modules/currencies/backend/currencies/page.tsx +3 -0
- package/src/modules/currencies/backend/exchange-rates/page.tsx +2 -0
- package/src/modules/customers/backend/customers/companies/page.tsx +3 -0
- package/src/modules/customers/backend/customers/deals/page.tsx +3 -0
- package/src/modules/customers/backend/customers/people/page.tsx +3 -0
- package/src/modules/customers/commands/deals.ts +39 -0
- package/src/modules/customers/components/CustomerTodosTable.tsx +1 -0
- package/src/modules/customers/i18n/en.json +5 -1
- package/src/modules/customers/notifications.ts +44 -0
- package/src/modules/customers/widgets/dashboard/customer-todos/widget.ts +2 -2
- package/src/modules/customers/widgets/dashboard/new-customers/widget.ts +2 -2
- package/src/modules/customers/widgets/dashboard/new-deals/widget.ts +2 -2
- package/src/modules/customers/widgets/dashboard/next-interactions/widget.ts +2 -2
- package/src/modules/dashboards/cli.ts +55 -5
- package/src/modules/dashboards/components/WidgetVisibilityEditor.tsx +22 -11
- package/src/modules/dashboards/lib/role-widgets.ts +80 -0
- package/src/modules/dashboards/services/widgetDataService.ts +164 -4
- package/src/modules/dashboards/setup.ts +16 -0
- package/src/modules/dashboards/widgets/dashboard/aov-kpi/widget.ts +2 -2
- package/src/modules/dashboards/widgets/dashboard/new-customers-kpi/widget.ts +2 -2
- package/src/modules/dashboards/widgets/dashboard/orders-by-status/widget.ts +2 -2
- package/src/modules/dashboards/widgets/dashboard/orders-kpi/widget.ts +2 -2
- package/src/modules/dashboards/widgets/dashboard/pipeline-summary/widget.ts +2 -2
- package/src/modules/dashboards/widgets/dashboard/revenue-kpi/widget.ts +2 -2
- package/src/modules/dashboards/widgets/dashboard/revenue-trend/widget.ts +2 -2
- package/src/modules/dashboards/widgets/dashboard/sales-by-region/widget.ts +2 -2
- package/src/modules/dashboards/widgets/dashboard/top-customers/widget.ts +2 -2
- package/src/modules/dashboards/widgets/dashboard/top-products/widget.ts +2 -2
- package/src/modules/dictionaries/components/DictionaryTable.tsx +2 -0
- package/src/modules/directory/api/get/tenants/lookup.ts +75 -0
- package/src/modules/directory/backend/directory/organizations/page.tsx +2 -2
- package/src/modules/directory/backend/directory/tenants/page.tsx +2 -2
- package/src/modules/entities/backend/entities/user/[entityId]/records/page.tsx +2 -2
- package/src/modules/entities/components/SystemEntitiesTable.tsx +1 -1
- package/src/modules/entities/components/UserEntitiesTable.tsx +2 -2
- package/src/modules/feature_toggles/components/FeatureTogglesTable.tsx +3 -4
- package/src/modules/feature_toggles/components/OverridesTable.tsx +1 -1
- package/src/modules/notifications/__tests__/deliver-notification.test.ts +195 -0
- package/src/modules/notifications/__tests__/deliveryStrategies.test.ts +19 -0
- package/src/modules/notifications/__tests__/notificationService.test.ts +208 -0
- package/src/modules/notifications/acl.ts +7 -0
- package/src/modules/notifications/api/[id]/action/route.ts +75 -0
- package/src/modules/notifications/api/[id]/dismiss/route.ts +12 -0
- package/src/modules/notifications/api/[id]/read/route.ts +12 -0
- package/src/modules/notifications/api/[id]/restore/route.ts +53 -0
- package/src/modules/notifications/api/batch/route.ts +14 -0
- package/src/modules/notifications/api/feature/route.ts +14 -0
- package/src/modules/notifications/api/mark-all-read/route.ts +34 -0
- package/src/modules/notifications/api/openapi.ts +76 -0
- package/src/modules/notifications/api/role/route.ts +14 -0
- package/src/modules/notifications/api/route.ts +92 -0
- package/src/modules/notifications/api/settings/route.ts +157 -0
- package/src/modules/notifications/api/unread-count/route.ts +38 -0
- package/src/modules/notifications/backend/config/notifications/page.meta.ts +22 -0
- package/src/modules/notifications/backend/config/notifications/page.tsx +12 -0
- package/src/modules/notifications/cli.ts +18 -0
- package/src/modules/notifications/data/entities.ts +99 -0
- package/src/modules/notifications/data/validators.ts +115 -0
- package/src/modules/notifications/di.ts +11 -0
- package/src/modules/notifications/emails/NotificationEmail.tsx +98 -0
- package/src/modules/notifications/frontend/NotificationInboxPageClient.tsx +42 -0
- package/src/modules/notifications/frontend/NotificationSettingsPageClient.tsx +233 -0
- package/src/modules/notifications/i18n/de.json +50 -0
- package/src/modules/notifications/i18n/en.json +50 -0
- package/src/modules/notifications/i18n/es.json +50 -0
- package/src/modules/notifications/i18n/pl.json +50 -0
- package/src/modules/notifications/index.ts +12 -0
- package/src/modules/notifications/lib/deliveryConfig.ts +153 -0
- package/src/modules/notifications/lib/deliveryStrategies.ts +50 -0
- package/src/modules/notifications/lib/events.ts +48 -0
- package/src/modules/notifications/lib/notificationBuilder.ts +121 -0
- package/src/modules/notifications/lib/notificationFactory.ts +76 -0
- package/src/modules/notifications/lib/notificationMapper.ts +33 -0
- package/src/modules/notifications/lib/notificationRecipients.ts +83 -0
- package/src/modules/notifications/lib/notificationService.ts +414 -0
- package/src/modules/notifications/lib/routeHelpers.ts +151 -0
- package/src/modules/notifications/lib/safeHref.ts +29 -0
- package/src/modules/notifications/migrations/.snapshot-open-mercato.json +336 -0
- package/src/modules/notifications/migrations/Migration20260123000001.ts +73 -0
- package/src/modules/notifications/migrations/Migration20260126150000.ts +39 -0
- package/src/modules/notifications/migrations/Migration20260129082610.ts +13 -0
- package/src/modules/notifications/subscribers/deliver-notification.ts +204 -0
- package/src/modules/notifications/workers/create-notification.worker.ts +122 -0
- package/src/modules/planner/backend/planner/availability-rulesets/page.tsx +2 -2
- package/src/modules/query_index/cli.ts +82 -13
- package/src/modules/query_index/components/QueryIndexesTable.tsx +8 -2
- package/src/modules/resources/backend/resources/resource-types/page.tsx +2 -2
- package/src/modules/resources/backend/resources/resources/page.tsx +2 -2
- package/src/modules/sales/backend/sales/channels/offers/page.tsx +2 -0
- package/src/modules/sales/backend/sales/channels/page.tsx +2 -0
- package/src/modules/sales/cli.ts +2 -43
- package/src/modules/sales/commands/documents.ts +65 -0
- package/src/modules/sales/commands/payments.ts +33 -0
- package/src/modules/sales/components/AdjustmentKindSettings.tsx +2 -2
- package/src/modules/sales/components/PaymentMethodsSettings.tsx +2 -2
- package/src/modules/sales/components/ShippingMethodsSettings.tsx +2 -2
- package/src/modules/sales/components/TaxRatesSettings.tsx +2 -2
- package/src/modules/sales/components/channels/SalesChannelOffersPanel.tsx +2 -0
- package/src/modules/sales/components/documents/AdjustmentsSection.tsx +2 -0
- package/src/modules/sales/components/documents/PaymentsSection.tsx +2 -1
- package/src/modules/sales/components/documents/SalesDocumentsTable.tsx +2 -0
- package/src/modules/sales/i18n/de.json +20 -0
- package/src/modules/sales/i18n/en.json +25 -1
- package/src/modules/sales/i18n/es.json +20 -0
- package/src/modules/sales/i18n/pl.json +20 -0
- package/src/modules/sales/lib/seeds.ts +53 -0
- package/src/modules/sales/notifications.client.ts +65 -0
- package/src/modules/sales/notifications.ts +82 -0
- package/src/modules/sales/subscribers/quote-expiring-notification.ts +53 -0
- package/src/modules/sales/widgets/notifications/SalesOrderCreatedRenderer.tsx +156 -0
- package/src/modules/sales/widgets/notifications/SalesQuoteCreatedRenderer.tsx +156 -0
- package/src/modules/sales/widgets/notifications/index.ts +2 -0
- package/src/modules/sales/widgets/notifications/useSalesDocumentTotals.ts +81 -0
- package/src/modules/staff/backend/staff/team-members/page.tsx +1 -1
- package/src/modules/staff/backend/staff/team-roles/page.tsx +2 -2
- package/src/modules/staff/backend/staff/teams/[id]/edit/page.tsx +2 -2
- package/src/modules/staff/backend/staff/teams/page.tsx +2 -2
- package/src/modules/staff/commands/leave-requests.ts +94 -0
- package/src/modules/staff/i18n/de.json +4 -0
- package/src/modules/staff/i18n/en.json +9 -1
- package/src/modules/staff/i18n/es.json +4 -0
- package/src/modules/staff/i18n/pl.json +4 -0
- package/src/modules/staff/notifications.ts +71 -0
- package/src/modules/workflows/backend/definitions/page.tsx +5 -0
- package/src/modules/workflows/backend/instances/page.tsx +4 -1
- package/src/modules/workflows/backend/tasks/page.tsx +4 -1
- package/src/modules/workflows/cli.ts +12 -12
- package/src/modules/workflows/i18n/en.json +3 -1
- package/src/modules/workflows/lib/transition-handler.ts +18 -6
- package/src/modules/workflows/notifications.ts +25 -0
- package/src/modules/workflows/subscribers/task-assigned-notification.ts +53 -0
|
@@ -2,12 +2,26 @@
|
|
|
2
2
|
"auth.signIn": "Sign in",
|
|
3
3
|
"auth.email": "Email",
|
|
4
4
|
"auth.password": "Password",
|
|
5
|
+
"auth.password.requirements.help": "Password requirements: {requirements}",
|
|
6
|
+
"auth.password.requirements.minLength": "At least {min} characters",
|
|
7
|
+
"auth.password.requirements.digit": "One number",
|
|
8
|
+
"auth.password.requirements.uppercase": "One uppercase letter",
|
|
9
|
+
"auth.password.requirements.special": "One special character",
|
|
10
|
+
"auth.password.requirements.separator": ", ",
|
|
5
11
|
"auth.sendResetLink": "Send reset link",
|
|
6
12
|
"auth.resetPassword": "Reset password",
|
|
13
|
+
"auth.reset.title": "Set a new password",
|
|
14
|
+
"auth.reset.subtitle": "Choose a strong password for your account.",
|
|
15
|
+
"auth.reset.form.password": "New password",
|
|
16
|
+
"auth.reset.form.loading": "...",
|
|
17
|
+
"auth.reset.form.submit": "Update password",
|
|
18
|
+
"auth.reset.errors.failed": "Unable to reset password",
|
|
7
19
|
"auth.usersRoles": "Users & Roles",
|
|
8
20
|
"auth.manageAuthSettings": "Manage authentication settings.",
|
|
9
21
|
"auth.login.errors.permissionDenied": "You do not have permission to access this area. Please contact your administrator.",
|
|
10
22
|
"auth.login.errors.invalidCredentials": "Invalid email or password",
|
|
23
|
+
"auth.login.errors.tenantRequired": "Use the login link provided with your tenant activation to continue.",
|
|
24
|
+
"auth.login.errors.tenantInvalid": "Tenant not found. Clear the tenant selection and try again.",
|
|
11
25
|
"auth.login.errors.generic": "An error occurred. Please try again.",
|
|
12
26
|
"auth.login.logoAlt": "Open Mercato logo",
|
|
13
27
|
"auth.login.brandName": "Open Mercato",
|
|
@@ -15,6 +29,9 @@
|
|
|
15
29
|
"auth.login.requireRoleMessage": "Access requires role: {roles}",
|
|
16
30
|
"auth.login.requireRolesMessage": "Access requires one of the following roles: {roles}",
|
|
17
31
|
"auth.login.featureDenied": "You don't have access to this feature ({feature}). Please contact your administrator.",
|
|
32
|
+
"auth.login.tenantBanner": "You're logging in to {tenant} tenant.",
|
|
33
|
+
"auth.login.tenantLoading": "Loading tenant details...",
|
|
34
|
+
"auth.login.tenantClear": "Clear",
|
|
18
35
|
"auth.login.rememberMe": "Remember me",
|
|
19
36
|
"auth.login.loading": "Loading...",
|
|
20
37
|
"auth.login.forgotPassword": "Forgot password?",
|
|
@@ -80,6 +97,21 @@
|
|
|
80
97
|
"auth.users.form.errors.load": "Failed to load user data",
|
|
81
98
|
"auth.users.form.errors.aclUpdate": "Failed to update user access control",
|
|
82
99
|
"auth.users.form.errors.delete": "Failed to delete user",
|
|
100
|
+
"auth.profile.title": "Profile",
|
|
101
|
+
"auth.profile.subtitle": "Change password",
|
|
102
|
+
"auth.profile.form.email": "Email",
|
|
103
|
+
"auth.profile.form.password": "New password",
|
|
104
|
+
"auth.profile.form.confirmPassword": "Confirm new password",
|
|
105
|
+
"auth.profile.form.save": "Save changes",
|
|
106
|
+
"auth.profile.form.loading": "Loading profile...",
|
|
107
|
+
"auth.profile.form.errors.load": "Failed to load profile.",
|
|
108
|
+
"auth.profile.form.errors.save": "Failed to update profile.",
|
|
109
|
+
"auth.profile.form.errors.invalid": "Invalid profile update.",
|
|
110
|
+
"auth.profile.form.errors.passwordMismatch": "Passwords do not match.",
|
|
111
|
+
"auth.profile.form.errors.passwordRequirements": "Password must meet the requirements.",
|
|
112
|
+
"auth.profile.form.errors.noChanges": "No changes to save.",
|
|
113
|
+
"auth.profile.form.errors.emailRequired": "Email is required.",
|
|
114
|
+
"auth.profile.form.success": "Profile updated.",
|
|
83
115
|
"auth.users.list.error.load": "Failed to load users",
|
|
84
116
|
"auth.users.list.error.delete": "Failed to delete user",
|
|
85
117
|
"auth.users.flash.created": "User created",
|
|
@@ -95,5 +127,20 @@
|
|
|
95
127
|
"auth.email.resetPassword.title": "Reset your password",
|
|
96
128
|
"auth.email.resetPassword.body": "Click the link below to set a new password. This link will expire in 60 minutes.",
|
|
97
129
|
"auth.email.resetPassword.cta": "Set a new password",
|
|
98
|
-
"auth.email.resetPassword.hint": "If you didn't request this, you can safely ignore this email."
|
|
130
|
+
"auth.email.resetPassword.hint": "If you didn't request this, you can safely ignore this email.",
|
|
131
|
+
"auth.notifications.passwordReset.requested.title": "Password reset requested",
|
|
132
|
+
"auth.notifications.passwordReset.requested.body": "A password reset link has been sent to your email",
|
|
133
|
+
"auth.notifications.passwordReset.completed.title": "Password successfully changed",
|
|
134
|
+
"auth.notifications.passwordReset.completed.body": "Your password has been updated successfully",
|
|
135
|
+
"auth.notifications.account.locked.title": "Account locked",
|
|
136
|
+
"auth.notifications.account.locked.body": "Your account has been locked due to security reasons. Please contact support.",
|
|
137
|
+
"auth.notifications.login.newDevice.title": "New device login detected",
|
|
138
|
+
"auth.notifications.login.newDevice.body": "A new login from an unrecognized device was detected on your account",
|
|
139
|
+
"auth.notifications.role.assigned.title": "New role assigned",
|
|
140
|
+
"auth.notifications.role.assigned.body": "You have been assigned a new role with additional permissions",
|
|
141
|
+
"auth.notifications.role.revoked.title": "Role removed",
|
|
142
|
+
"auth.notifications.role.revoked.body": "A role has been removed from your account",
|
|
143
|
+
"auth.actions.contactSupport": "Contact Support",
|
|
144
|
+
"auth.actions.viewSessions": "View Sessions",
|
|
145
|
+
"auth.actions.viewPermissions": "View Permissions"
|
|
99
146
|
}
|
|
@@ -2,12 +2,26 @@
|
|
|
2
2
|
"auth.signIn": "Iniciar sesión",
|
|
3
3
|
"auth.email": "Correo electrónico",
|
|
4
4
|
"auth.password": "Contraseña",
|
|
5
|
+
"auth.password.requirements.help": "Requisitos de la contraseña: {requirements}",
|
|
6
|
+
"auth.password.requirements.minLength": "Al menos {min} caracteres",
|
|
7
|
+
"auth.password.requirements.digit": "Un número",
|
|
8
|
+
"auth.password.requirements.uppercase": "Una letra mayúscula",
|
|
9
|
+
"auth.password.requirements.special": "Un carácter especial",
|
|
10
|
+
"auth.password.requirements.separator": ", ",
|
|
5
11
|
"auth.sendResetLink": "Enviar enlace de restablecimiento",
|
|
6
12
|
"auth.resetPassword": "Restablecer contraseña",
|
|
13
|
+
"auth.reset.title": "Establecer una nueva contraseña",
|
|
14
|
+
"auth.reset.subtitle": "Elige una contraseña segura para tu cuenta.",
|
|
15
|
+
"auth.reset.form.password": "Nueva contraseña",
|
|
16
|
+
"auth.reset.form.loading": "...",
|
|
17
|
+
"auth.reset.form.submit": "Actualizar contraseña",
|
|
18
|
+
"auth.reset.errors.failed": "No se pudo restablecer la contraseña",
|
|
7
19
|
"auth.usersRoles": "Usuarios y roles",
|
|
8
20
|
"auth.manageAuthSettings": "Administra la configuración de autenticación.",
|
|
9
21
|
"auth.login.errors.permissionDenied": "No tienes permiso para acceder a esta área. Ponte en contacto con tu administrador.",
|
|
10
22
|
"auth.login.errors.invalidCredentials": "Correo electrónico o contraseña no válidos",
|
|
23
|
+
"auth.login.errors.tenantRequired": "Usa el enlace de inicio de sesión proporcionado con la activación de tu inquilino para continuar.",
|
|
24
|
+
"auth.login.errors.tenantInvalid": "No se encontró el inquilino. Borra la selección e inténtalo de nuevo.",
|
|
11
25
|
"auth.login.errors.generic": "Se produjo un error. Inténtalo de nuevo.",
|
|
12
26
|
"auth.login.logoAlt": "Logotipo de Open Mercato",
|
|
13
27
|
"auth.login.brandName": "Open Mercato",
|
|
@@ -15,6 +29,9 @@
|
|
|
15
29
|
"auth.login.requireRoleMessage": "El acceso requiere el rol: {roles}",
|
|
16
30
|
"auth.login.requireRolesMessage": "El acceso requiere uno de los siguientes roles: {roles}",
|
|
17
31
|
"auth.login.featureDenied": "No tienes acceso a esta funcionalidad ({feature}). Ponte en contacto con tu administrador.",
|
|
32
|
+
"auth.login.tenantBanner": "Estás iniciando sesión en el inquilino {tenant}.",
|
|
33
|
+
"auth.login.tenantLoading": "Cargando detalles del inquilino...",
|
|
34
|
+
"auth.login.tenantClear": "Borrar",
|
|
18
35
|
"auth.login.rememberMe": "Recordarme",
|
|
19
36
|
"auth.login.loading": "Cargando...",
|
|
20
37
|
"auth.login.forgotPassword": "¿Olvidaste tu contraseña?",
|
|
@@ -80,6 +97,21 @@
|
|
|
80
97
|
"auth.users.form.errors.load": "No se pudieron cargar los datos del usuario",
|
|
81
98
|
"auth.users.form.errors.aclUpdate": "No se pudo actualizar el control de acceso del usuario",
|
|
82
99
|
"auth.users.form.errors.delete": "No se pudo eliminar el usuario",
|
|
100
|
+
"auth.profile.title": "Perfil",
|
|
101
|
+
"auth.profile.subtitle": "Cambiar contraseña",
|
|
102
|
+
"auth.profile.form.email": "Correo electrónico",
|
|
103
|
+
"auth.profile.form.password": "Nueva contraseña",
|
|
104
|
+
"auth.profile.form.confirmPassword": "Confirmar nueva contraseña",
|
|
105
|
+
"auth.profile.form.save": "Guardar cambios",
|
|
106
|
+
"auth.profile.form.loading": "Cargando perfil...",
|
|
107
|
+
"auth.profile.form.errors.load": "No se pudo cargar el perfil.",
|
|
108
|
+
"auth.profile.form.errors.save": "No se pudo actualizar el perfil.",
|
|
109
|
+
"auth.profile.form.errors.invalid": "Actualización de perfil inválida.",
|
|
110
|
+
"auth.profile.form.errors.passwordMismatch": "Las contraseñas no coinciden.",
|
|
111
|
+
"auth.profile.form.errors.passwordRequirements": "La contraseña debe cumplir los requisitos.",
|
|
112
|
+
"auth.profile.form.errors.noChanges": "No hay cambios para guardar.",
|
|
113
|
+
"auth.profile.form.errors.emailRequired": "El correo electrónico es obligatorio.",
|
|
114
|
+
"auth.profile.form.success": "Perfil actualizado.",
|
|
83
115
|
"auth.users.list.error.load": "No se pudieron cargar los usuarios",
|
|
84
116
|
"auth.users.list.error.delete": "No se pudo eliminar el usuario",
|
|
85
117
|
"auth.users.flash.created": "Usuario creado",
|
|
@@ -95,5 +127,20 @@
|
|
|
95
127
|
"auth.email.resetPassword.title": "Restablecer tu contraseña",
|
|
96
128
|
"auth.email.resetPassword.body": "Haz clic en el siguiente enlace para establecer una nueva contraseña. Este enlace caducará en 60 minutos.",
|
|
97
129
|
"auth.email.resetPassword.cta": "Establecer nueva contraseña",
|
|
98
|
-
"auth.email.resetPassword.hint": "Si no solicitaste esto, puedes ignorar este correo de forma segura."
|
|
130
|
+
"auth.email.resetPassword.hint": "Si no solicitaste esto, puedes ignorar este correo de forma segura.",
|
|
131
|
+
"auth.notifications.passwordReset.requested.title": "Solicitud de restablecimiento de contraseña",
|
|
132
|
+
"auth.notifications.passwordReset.requested.body": "Se ha enviado un enlace de restablecimiento de contraseña a tu correo electrónico",
|
|
133
|
+
"auth.notifications.passwordReset.completed.title": "Contraseña cambiada correctamente",
|
|
134
|
+
"auth.notifications.passwordReset.completed.body": "Tu contraseña se actualizó correctamente",
|
|
135
|
+
"auth.notifications.account.locked.title": "Cuenta bloqueada",
|
|
136
|
+
"auth.notifications.account.locked.body": "Tu cuenta ha sido bloqueada por razones de seguridad. Ponte en contacto con soporte.",
|
|
137
|
+
"auth.notifications.login.newDevice.title": "Nuevo inicio de sesión detectado",
|
|
138
|
+
"auth.notifications.login.newDevice.body": "Se detectó un inicio de sesión desde un dispositivo no reconocido en tu cuenta",
|
|
139
|
+
"auth.notifications.role.assigned.title": "Nuevo rol asignado",
|
|
140
|
+
"auth.notifications.role.assigned.body": "Se te ha asignado un nuevo rol con permisos adicionales",
|
|
141
|
+
"auth.notifications.role.revoked.title": "Rol eliminado",
|
|
142
|
+
"auth.notifications.role.revoked.body": "Se ha eliminado un rol de tu cuenta",
|
|
143
|
+
"auth.actions.contactSupport": "Contactar soporte",
|
|
144
|
+
"auth.actions.viewSessions": "Ver sesiones",
|
|
145
|
+
"auth.actions.viewPermissions": "Ver permisos"
|
|
99
146
|
}
|
|
@@ -2,12 +2,26 @@
|
|
|
2
2
|
"auth.signIn": "Zaloguj się",
|
|
3
3
|
"auth.email": "Email",
|
|
4
4
|
"auth.password": "Hasło",
|
|
5
|
+
"auth.password.requirements.help": "Wymagania hasła: {requirements}",
|
|
6
|
+
"auth.password.requirements.minLength": "Co najmniej {min} znaków",
|
|
7
|
+
"auth.password.requirements.digit": "Jedna cyfra",
|
|
8
|
+
"auth.password.requirements.uppercase": "Jedna wielka litera",
|
|
9
|
+
"auth.password.requirements.special": "Jeden znak specjalny",
|
|
10
|
+
"auth.password.requirements.separator": ", ",
|
|
5
11
|
"auth.sendResetLink": "Wyślij link resetujący",
|
|
6
12
|
"auth.resetPassword": "Resetuj hasło",
|
|
13
|
+
"auth.reset.title": "Ustaw nowe hasło",
|
|
14
|
+
"auth.reset.subtitle": "Wybierz silne hasło dla swojego konta.",
|
|
15
|
+
"auth.reset.form.password": "Nowe hasło",
|
|
16
|
+
"auth.reset.form.loading": "...",
|
|
17
|
+
"auth.reset.form.submit": "Zaktualizuj hasło",
|
|
18
|
+
"auth.reset.errors.failed": "Nie udało się zresetować hasła",
|
|
7
19
|
"auth.usersRoles": "Użytkownicy i role",
|
|
8
20
|
"auth.manageAuthSettings": "Zarządzaj ustawieniami uwierzytelniania.",
|
|
9
21
|
"auth.login.errors.permissionDenied": "Nie masz uprawnień do tego obszaru. Skontaktuj się z administratorem.",
|
|
10
22
|
"auth.login.errors.invalidCredentials": "Nieprawidłowy email lub hasło",
|
|
23
|
+
"auth.login.errors.tenantRequired": "Użyj linku logowania z aktywacji najemcy, aby kontynuować.",
|
|
24
|
+
"auth.login.errors.tenantInvalid": "Nie znaleziono najemcy. Wyczyść wybór i spróbuj ponownie.",
|
|
11
25
|
"auth.login.errors.generic": "Wystąpił błąd. Spróbuj ponownie.",
|
|
12
26
|
"auth.login.logoAlt": "Logo Open Mercato",
|
|
13
27
|
"auth.login.brandName": "Open Mercato",
|
|
@@ -15,6 +29,9 @@
|
|
|
15
29
|
"auth.login.requireRoleMessage": "Dostęp wymaga roli: {roles}",
|
|
16
30
|
"auth.login.requireRolesMessage": "Dostęp wymaga jednej z następujących ról: {roles}",
|
|
17
31
|
"auth.login.featureDenied": "Nie masz dostępu do tej funkcji ({feature}). Skontaktuj się z administratorem.",
|
|
32
|
+
"auth.login.tenantBanner": "Logujesz się do najemcy {tenant}.",
|
|
33
|
+
"auth.login.tenantLoading": "Ładowanie szczegółów najemcy...",
|
|
34
|
+
"auth.login.tenantClear": "Wyczyść",
|
|
18
35
|
"auth.login.rememberMe": "Zapamiętaj mnie",
|
|
19
36
|
"auth.login.loading": "Ładowanie...",
|
|
20
37
|
"auth.login.forgotPassword": "Nie pamiętasz hasła?",
|
|
@@ -80,6 +97,21 @@
|
|
|
80
97
|
"auth.users.form.errors.load": "Nie udało się wczytać danych użytkownika",
|
|
81
98
|
"auth.users.form.errors.aclUpdate": "Nie udało się zaktualizować uprawnień użytkownika",
|
|
82
99
|
"auth.users.form.errors.delete": "Nie udało się usunąć użytkownika",
|
|
100
|
+
"auth.profile.title": "Profil",
|
|
101
|
+
"auth.profile.subtitle": "Zmiana hasła",
|
|
102
|
+
"auth.profile.form.email": "Email",
|
|
103
|
+
"auth.profile.form.password": "Nowe hasło",
|
|
104
|
+
"auth.profile.form.confirmPassword": "Potwierdź nowe hasło",
|
|
105
|
+
"auth.profile.form.save": "Zapisz zmiany",
|
|
106
|
+
"auth.profile.form.loading": "Ładowanie profilu...",
|
|
107
|
+
"auth.profile.form.errors.load": "Nie udało się wczytać profilu.",
|
|
108
|
+
"auth.profile.form.errors.save": "Nie udało się zaktualizować profilu.",
|
|
109
|
+
"auth.profile.form.errors.invalid": "Nieprawidłowa aktualizacja profilu.",
|
|
110
|
+
"auth.profile.form.errors.passwordMismatch": "Hasła nie są zgodne.",
|
|
111
|
+
"auth.profile.form.errors.passwordRequirements": "Hasło musi spełniać wymagania.",
|
|
112
|
+
"auth.profile.form.errors.noChanges": "Brak zmian do zapisania.",
|
|
113
|
+
"auth.profile.form.errors.emailRequired": "Email jest wymagany.",
|
|
114
|
+
"auth.profile.form.success": "Profil zaktualizowany.",
|
|
83
115
|
"auth.users.list.error.load": "Nie udało się wczytać użytkowników",
|
|
84
116
|
"auth.users.list.error.delete": "Nie udało się usunąć użytkownika",
|
|
85
117
|
"auth.users.flash.created": "Użytkownik utworzony",
|
|
@@ -95,5 +127,20 @@
|
|
|
95
127
|
"auth.email.resetPassword.title": "Zresetuj swoje hasło",
|
|
96
128
|
"auth.email.resetPassword.body": "Kliknij poniższy link, aby ustawić nowe hasło. Link wygaśnie za 60 minut.",
|
|
97
129
|
"auth.email.resetPassword.cta": "Ustaw nowe hasło",
|
|
98
|
-
"auth.email.resetPassword.hint": "Jeśli nie prosiłeś o tę wiadomość, możesz ją bezpiecznie zignorować."
|
|
130
|
+
"auth.email.resetPassword.hint": "Jeśli nie prosiłeś o tę wiadomość, możesz ją bezpiecznie zignorować.",
|
|
131
|
+
"auth.notifications.passwordReset.requested.title": "Żądanie resetu hasła",
|
|
132
|
+
"auth.notifications.passwordReset.requested.body": "Link do resetu hasła został wysłany na Twój adres e-mail",
|
|
133
|
+
"auth.notifications.passwordReset.completed.title": "Hasło zmienione pomyślnie",
|
|
134
|
+
"auth.notifications.passwordReset.completed.body": "Twoje hasło zostało pomyślnie zaktualizowane",
|
|
135
|
+
"auth.notifications.account.locked.title": "Konto zablokowane",
|
|
136
|
+
"auth.notifications.account.locked.body": "Twoje konto zostało zablokowane z powodów bezpieczeństwa. Skontaktuj się z pomocą techniczną.",
|
|
137
|
+
"auth.notifications.login.newDevice.title": "Wykryto logowanie z nowego urządzenia",
|
|
138
|
+
"auth.notifications.login.newDevice.body": "Wykryto logowanie z nieznanego urządzenia na Twoim koncie",
|
|
139
|
+
"auth.notifications.role.assigned.title": "Przypisano nową rolę",
|
|
140
|
+
"auth.notifications.role.assigned.body": "Przypisano Ci nową rolę z dodatkowymi uprawnieniami",
|
|
141
|
+
"auth.notifications.role.revoked.title": "Rola usunięta",
|
|
142
|
+
"auth.notifications.role.revoked.body": "Z Twojego konta usunięto rolę",
|
|
143
|
+
"auth.actions.contactSupport": "Skontaktuj się z pomocą",
|
|
144
|
+
"auth.actions.viewSessions": "Zobacz sesje",
|
|
145
|
+
"auth.actions.viewPermissions": "Zobacz uprawnienia"
|
|
99
146
|
}
|
|
@@ -12,6 +12,7 @@ import { DEFAULT_ENCRYPTION_MAPS } from '@open-mercato/core/modules/entities/lib
|
|
|
12
12
|
import { createKmsService } from '@open-mercato/shared/lib/encryption/kms'
|
|
13
13
|
import { TenantDataEncryptionService } from '@open-mercato/shared/lib/encryption/tenantDataEncryptionService'
|
|
14
14
|
import { findWithDecryption } from '@open-mercato/shared/lib/encryption/find'
|
|
15
|
+
import { parseBooleanToken } from '@open-mercato/shared/lib/boolean'
|
|
15
16
|
|
|
16
17
|
const DEFAULT_ROLE_NAMES = ['employee', 'admin', 'superadmin'] as const
|
|
17
18
|
const DEMO_SUPERADMIN_EMAIL = 'superadmin@acme.com'
|
|
@@ -83,6 +84,11 @@ type PrimaryUserInput = {
|
|
|
83
84
|
confirm?: boolean
|
|
84
85
|
}
|
|
85
86
|
|
|
87
|
+
const DERIVED_EMAIL_ENV = {
|
|
88
|
+
admin: 'OM_INIT_ADMIN_EMAIL',
|
|
89
|
+
employee: 'OM_INIT_EMPLOYEE_EMAIL',
|
|
90
|
+
} as const
|
|
91
|
+
|
|
86
92
|
export type SetupInitialTenantOptions = {
|
|
87
93
|
orgName: string
|
|
88
94
|
primaryUser: PrimaryUserInput
|
|
@@ -168,16 +174,28 @@ export async function setupInitialTenant(
|
|
|
168
174
|
})
|
|
169
175
|
|
|
170
176
|
if (!existingUser) {
|
|
171
|
-
const baseUsers: Array<{
|
|
177
|
+
const baseUsers: Array<{
|
|
178
|
+
email: string
|
|
179
|
+
roles: string[]
|
|
180
|
+
name?: string | null
|
|
181
|
+
passwordHash?: string | null
|
|
182
|
+
}> = [
|
|
172
183
|
{ email: primaryUser.email, roles: primaryRoles, name: resolvePrimaryName(primaryUser) },
|
|
173
184
|
]
|
|
174
185
|
if (includeDerivedUsers) {
|
|
175
|
-
const [
|
|
176
|
-
const
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
186
|
+
const [, domain] = String(primaryUser.email).split('@')
|
|
187
|
+
const adminOverride = readEnvValue(DERIVED_EMAIL_ENV.admin)
|
|
188
|
+
const employeeOverride = readEnvValue(DERIVED_EMAIL_ENV.employee)
|
|
189
|
+
const adminEmail = adminOverride ?? (domain ? `admin@${domain}` : '')
|
|
190
|
+
const employeeEmail = employeeOverride ?? (domain ? `employee@${domain}` : '')
|
|
191
|
+
const adminPassword = readEnvValue('OM_INIT_ADMIN_PASSWORD') || 'secret'
|
|
192
|
+
const employeePassword = readEnvValue('OM_INIT_EMPLOYEE_PASSWORD') || 'secret'
|
|
193
|
+
const adminPasswordHash = adminPassword ? await resolvePasswordHash({ email: adminEmail, password: adminPassword }) : null
|
|
194
|
+
const employeePasswordHash = employeePassword
|
|
195
|
+
? await resolvePasswordHash({ email: employeeEmail, password: employeePassword })
|
|
196
|
+
: null
|
|
197
|
+
addUniqueBaseUser(baseUsers, { email: adminEmail, roles: ['admin'], passwordHash: adminPasswordHash })
|
|
198
|
+
addUniqueBaseUser(baseUsers, { email: employeeEmail, roles: ['employee'], passwordHash: employeePasswordHash })
|
|
181
199
|
}
|
|
182
200
|
const passwordHash = await resolvePasswordHash(primaryUser)
|
|
183
201
|
|
|
@@ -269,13 +287,14 @@ export async function setupInitialTenant(
|
|
|
269
287
|
}
|
|
270
288
|
|
|
271
289
|
for (const base of baseUsers) {
|
|
290
|
+
const resolvedPasswordHash = base.passwordHash ?? passwordHash
|
|
272
291
|
let user = await tem.findOne(User, { email: base.email })
|
|
273
292
|
const confirm = primaryUser.confirm ?? true
|
|
274
293
|
const encryptedPayload = encryptionService
|
|
275
294
|
? await encryptionService.encryptEntityPayload('auth:user', { email: base.email }, tenantId, organizationId)
|
|
276
295
|
: { email: base.email, emailHash: computeEmailHash(base.email) }
|
|
277
296
|
if (user) {
|
|
278
|
-
user.passwordHash =
|
|
297
|
+
user.passwordHash = resolvedPasswordHash
|
|
279
298
|
user.organizationId = organizationId
|
|
280
299
|
user.tenantId = tenantId
|
|
281
300
|
if (isTenantDataEncryptionEnabled()) {
|
|
@@ -290,7 +309,7 @@ export async function setupInitialTenant(
|
|
|
290
309
|
user = tem.create(User, {
|
|
291
310
|
email: (encryptedPayload as any).email ?? base.email,
|
|
292
311
|
emailHash: isTenantDataEncryptionEnabled() ? (encryptedPayload as any).emailHash ?? computeEmailHash(base.email) : undefined,
|
|
293
|
-
passwordHash,
|
|
312
|
+
passwordHash: resolvedPasswordHash,
|
|
294
313
|
organizationId,
|
|
295
314
|
tenantId,
|
|
296
315
|
name: base.name ?? undefined,
|
|
@@ -345,6 +364,34 @@ function resolvePrimaryName(input: PrimaryUserInput): string | null {
|
|
|
345
364
|
return null
|
|
346
365
|
}
|
|
347
366
|
|
|
367
|
+
function readEnvValue(key: string): string | undefined {
|
|
368
|
+
const value = process.env[key]
|
|
369
|
+
if (typeof value !== 'string') return undefined
|
|
370
|
+
const trimmed = value.trim()
|
|
371
|
+
return trimmed.length > 0 ? trimmed : undefined
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
function addUniqueBaseUser(
|
|
375
|
+
baseUsers: Array<{ email: string; roles: string[]; name?: string | null; passwordHash?: string | null }>,
|
|
376
|
+
entry: { email: string; roles: string[]; name?: string | null; passwordHash?: string | null },
|
|
377
|
+
) {
|
|
378
|
+
if (!entry.email) return
|
|
379
|
+
const normalized = entry.email.toLowerCase()
|
|
380
|
+
if (baseUsers.some((user) => user.email.toLowerCase() === normalized)) return
|
|
381
|
+
baseUsers.push(entry)
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
function isDemoModeEnabled(): boolean {
|
|
385
|
+
const parsed = parseBooleanToken(process.env.DEMO_MODE ?? '')
|
|
386
|
+
return parsed === false ? false : true
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
function shouldKeepDemoSuperadminDuringInit(): boolean {
|
|
390
|
+
if (process.env.OM_INIT_FLOW !== 'true') return false
|
|
391
|
+
if (!readEnvValue('OM_INIT_SUPERADMIN_EMAIL')) return false
|
|
392
|
+
return isDemoModeEnabled()
|
|
393
|
+
}
|
|
394
|
+
|
|
348
395
|
async function resolvePasswordHash(input: PrimaryUserInput): Promise<string | null> {
|
|
349
396
|
if (typeof input.hashedPassword === 'string') return input.hashedPassword
|
|
350
397
|
if (input.password) return hash(input.password, 10)
|
|
@@ -422,6 +469,7 @@ async function ensureRoleAclFor(
|
|
|
422
469
|
|
|
423
470
|
async function deactivateDemoSuperAdminIfSelfOnboardingEnabled(em: EntityManager) {
|
|
424
471
|
if (process.env.SELF_SERVICE_ONBOARDING_ENABLED !== 'true') return
|
|
472
|
+
if (shouldKeepDemoSuperadminDuringInit()) return
|
|
425
473
|
try {
|
|
426
474
|
const user = await em.findOne(User, { email: DEMO_SUPERADMIN_EMAIL })
|
|
427
475
|
if (!user) return
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import type { NotificationTypeDefinition } from '@open-mercato/shared/modules/notifications/types'
|
|
2
|
+
|
|
3
|
+
export const notificationTypes: NotificationTypeDefinition[] = [
|
|
4
|
+
{
|
|
5
|
+
type: 'auth.password_reset.requested',
|
|
6
|
+
module: 'auth',
|
|
7
|
+
titleKey: 'auth.notifications.passwordReset.requested.title',
|
|
8
|
+
bodyKey: 'auth.notifications.passwordReset.requested.body',
|
|
9
|
+
icon: 'key',
|
|
10
|
+
severity: 'info',
|
|
11
|
+
actions: [
|
|
12
|
+
{
|
|
13
|
+
id: 'view',
|
|
14
|
+
labelKey: 'common.view',
|
|
15
|
+
variant: 'outline',
|
|
16
|
+
href: '/backend/auth/profile',
|
|
17
|
+
icon: 'external-link',
|
|
18
|
+
},
|
|
19
|
+
],
|
|
20
|
+
linkHref: '/backend/auth/profile',
|
|
21
|
+
expiresAfterHours: 24,
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
type: 'auth.password_reset.completed',
|
|
25
|
+
module: 'auth',
|
|
26
|
+
titleKey: 'auth.notifications.passwordReset.completed.title',
|
|
27
|
+
bodyKey: 'auth.notifications.passwordReset.completed.body',
|
|
28
|
+
icon: 'check-circle',
|
|
29
|
+
severity: 'success',
|
|
30
|
+
actions: [],
|
|
31
|
+
expiresAfterHours: 72,
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
type: 'auth.account.locked',
|
|
35
|
+
module: 'auth',
|
|
36
|
+
titleKey: 'auth.notifications.account.locked.title',
|
|
37
|
+
bodyKey: 'auth.notifications.account.locked.body',
|
|
38
|
+
icon: 'lock',
|
|
39
|
+
severity: 'warning',
|
|
40
|
+
actions: [
|
|
41
|
+
{
|
|
42
|
+
id: 'contact_support',
|
|
43
|
+
labelKey: 'auth.actions.contactSupport',
|
|
44
|
+
variant: 'default',
|
|
45
|
+
href: '/backend/support',
|
|
46
|
+
icon: 'mail',
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
linkHref: '/backend/support',
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
type: 'auth.login.new_device',
|
|
53
|
+
module: 'auth',
|
|
54
|
+
titleKey: 'auth.notifications.login.newDevice.title',
|
|
55
|
+
bodyKey: 'auth.notifications.login.newDevice.body',
|
|
56
|
+
icon: 'smartphone',
|
|
57
|
+
severity: 'info',
|
|
58
|
+
actions: [
|
|
59
|
+
{
|
|
60
|
+
id: 'view_sessions',
|
|
61
|
+
labelKey: 'auth.actions.viewSessions',
|
|
62
|
+
variant: 'outline',
|
|
63
|
+
href: '/backend/auth/sessions',
|
|
64
|
+
icon: 'list',
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
linkHref: '/backend/auth/sessions',
|
|
68
|
+
expiresAfterHours: 168, // 7 days
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
type: 'auth.role.assigned',
|
|
72
|
+
module: 'auth',
|
|
73
|
+
titleKey: 'auth.notifications.role.assigned.title',
|
|
74
|
+
bodyKey: 'auth.notifications.role.assigned.body',
|
|
75
|
+
icon: 'user-plus',
|
|
76
|
+
severity: 'success',
|
|
77
|
+
actions: [
|
|
78
|
+
{
|
|
79
|
+
id: 'view_permissions',
|
|
80
|
+
labelKey: 'auth.actions.viewPermissions',
|
|
81
|
+
variant: 'outline',
|
|
82
|
+
href: '/backend/auth/profile',
|
|
83
|
+
icon: 'shield',
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
linkHref: '/backend/auth/profile',
|
|
87
|
+
expiresAfterHours: 168,
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
type: 'auth.role.revoked',
|
|
91
|
+
module: 'auth',
|
|
92
|
+
titleKey: 'auth.notifications.role.revoked.title',
|
|
93
|
+
bodyKey: 'auth.notifications.role.revoked.body',
|
|
94
|
+
icon: 'user-minus',
|
|
95
|
+
severity: 'warning',
|
|
96
|
+
actions: [
|
|
97
|
+
{
|
|
98
|
+
id: 'view_profile',
|
|
99
|
+
labelKey: 'common.view',
|
|
100
|
+
variant: 'outline',
|
|
101
|
+
href: '/backend/auth/profile',
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
linkHref: '/backend/auth/profile',
|
|
105
|
+
expiresAfterHours: 168,
|
|
106
|
+
},
|
|
107
|
+
]
|
|
108
|
+
|
|
109
|
+
export default notificationTypes
|
|
@@ -18,6 +18,29 @@ export class AuthService {
|
|
|
18
18
|
} as any)
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
async findUsersByEmail(email: string) {
|
|
22
|
+
const emailHash = computeEmailHash(email)
|
|
23
|
+
return this.em.find(User, {
|
|
24
|
+
deletedAt: null,
|
|
25
|
+
$or: [
|
|
26
|
+
{ email },
|
|
27
|
+
{ emailHash },
|
|
28
|
+
],
|
|
29
|
+
} as any)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async findUserByEmailAndTenant(email: string, tenantId: string) {
|
|
33
|
+
const emailHash = computeEmailHash(email)
|
|
34
|
+
return this.em.findOne(User, {
|
|
35
|
+
tenantId,
|
|
36
|
+
deletedAt: null,
|
|
37
|
+
$or: [
|
|
38
|
+
{ email },
|
|
39
|
+
{ emailHash },
|
|
40
|
+
],
|
|
41
|
+
} as any)
|
|
42
|
+
}
|
|
43
|
+
|
|
21
44
|
async verifyPassword(user: User, password: string) {
|
|
22
45
|
if (!user.passwordHash) return false
|
|
23
46
|
return compare(password, user.passwordHash)
|
|
@@ -75,15 +98,15 @@ export class AuthService {
|
|
|
75
98
|
return { user, token }
|
|
76
99
|
}
|
|
77
100
|
|
|
78
|
-
async confirmPasswordReset(token: string, newPassword: string) {
|
|
101
|
+
async confirmPasswordReset(token: string, newPassword: string): Promise<User | null> {
|
|
79
102
|
const now = new Date()
|
|
80
103
|
const row = await this.em.findOne(PasswordReset, { token })
|
|
81
|
-
if (!row || (row.usedAt && row.usedAt <= now) || row.expiresAt <= now) return
|
|
104
|
+
if (!row || (row.usedAt && row.usedAt <= now) || row.expiresAt <= now) return null
|
|
82
105
|
const user = await this.em.findOne(User, { id: row.user.id })
|
|
83
|
-
if (!user) return
|
|
106
|
+
if (!user) return null
|
|
84
107
|
user.passwordHash = await hash(newPassword, 10)
|
|
85
108
|
row.usedAt = new Date()
|
|
86
109
|
await this.em.flush()
|
|
87
|
-
return
|
|
110
|
+
return user
|
|
88
111
|
}
|
|
89
112
|
}
|
|
@@ -4,6 +4,7 @@ import type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'
|
|
|
4
4
|
import { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'
|
|
5
5
|
import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
|
|
6
6
|
import type { EntityManager } from '@mikro-orm/postgresql'
|
|
7
|
+
import type { EventBus } from '@open-mercato/events'
|
|
7
8
|
import { ruleEngineContextSchema } from '../../data/validators'
|
|
8
9
|
import * as ruleEngine from '../../lib/rule-engine'
|
|
9
10
|
|
|
@@ -46,6 +47,12 @@ export async function POST(req: Request) {
|
|
|
46
47
|
|
|
47
48
|
const container = await createRequestContainer()
|
|
48
49
|
const em = container.resolve('em') as EntityManager
|
|
50
|
+
let eventBus: EventBus | null = null
|
|
51
|
+
try {
|
|
52
|
+
eventBus = container.resolve('eventBus') as EventBus
|
|
53
|
+
} catch {
|
|
54
|
+
eventBus = null
|
|
55
|
+
}
|
|
49
56
|
|
|
50
57
|
let body: any
|
|
51
58
|
try {
|
|
@@ -85,7 +92,7 @@ export async function POST(req: Request) {
|
|
|
85
92
|
}
|
|
86
93
|
|
|
87
94
|
try {
|
|
88
|
-
const result = await ruleEngine.executeRules(em, context)
|
|
95
|
+
const result = await ruleEngine.executeRules(em, context, { eventBus })
|
|
89
96
|
|
|
90
97
|
const response = {
|
|
91
98
|
allowed: result.allowed,
|
|
@@ -264,14 +264,17 @@ export default function RulesListPage() {
|
|
|
264
264
|
<RowActions
|
|
265
265
|
items={[
|
|
266
266
|
{
|
|
267
|
+
id: 'edit',
|
|
267
268
|
label: t('common.edit'),
|
|
268
269
|
href: `/backend/rules/${row.original.id}`,
|
|
269
270
|
},
|
|
270
271
|
{
|
|
272
|
+
id: row.original.enabled ? 'disable' : 'enable',
|
|
271
273
|
label: row.original.enabled ? t('common.disable') : t('common.enable'),
|
|
272
274
|
onSelect: () => handleToggleEnabled(row.original.id, row.original.enabled),
|
|
273
275
|
},
|
|
274
276
|
{
|
|
277
|
+
id: 'duplicate',
|
|
275
278
|
label: t('common.duplicate'),
|
|
276
279
|
onSelect: () => {
|
|
277
280
|
// TODO: Implement duplicate functionality in Step 5.2
|
|
@@ -279,6 +282,7 @@ export default function RulesListPage() {
|
|
|
279
282
|
},
|
|
280
283
|
},
|
|
281
284
|
{
|
|
285
|
+
id: 'delete',
|
|
282
286
|
label: t('common.delete'),
|
|
283
287
|
onSelect: () => handleDelete(row.original.id, row.original.ruleName),
|
|
284
288
|
destructive: true,
|
|
@@ -196,14 +196,17 @@ export default function RuleSetsListPage() {
|
|
|
196
196
|
<RowActions
|
|
197
197
|
items={[
|
|
198
198
|
{
|
|
199
|
+
id: 'edit',
|
|
199
200
|
label: t('common.edit'),
|
|
200
201
|
href: `/backend/sets/${row.original.id}`,
|
|
201
202
|
},
|
|
202
203
|
{
|
|
204
|
+
id: row.original.enabled ? 'disable' : 'enable',
|
|
203
205
|
label: row.original.enabled ? t('common.disable') : t('common.enable'),
|
|
204
206
|
onSelect: () => handleToggleEnabled(row.original.id, row.original.enabled),
|
|
205
207
|
},
|
|
206
208
|
{
|
|
209
|
+
id: 'delete',
|
|
207
210
|
label: t('common.delete'),
|
|
208
211
|
onSelect: () => handleDelete(row.original.id, row.original.setName),
|
|
209
212
|
destructive: true,
|
|
@@ -44,6 +44,7 @@ const seedGuardRules: ModuleCli = {
|
|
|
44
44
|
const rulesPath = path.join(__dirname, '../workflows/examples', 'guard-rules-example.json')
|
|
45
45
|
const rulesData = JSON.parse(fs.readFileSync(rulesPath, 'utf8'))
|
|
46
46
|
|
|
47
|
+
console.log('🧠 Seeding guard rules...')
|
|
47
48
|
let seededCount = 0
|
|
48
49
|
let skippedCount = 0
|
|
49
50
|
|
|
@@ -73,7 +74,7 @@ const seedGuardRules: ModuleCli = {
|
|
|
73
74
|
seededCount++
|
|
74
75
|
}
|
|
75
76
|
|
|
76
|
-
console.log(`\n
|
|
77
|
+
console.log(`\n✅ Guard rules seeding complete:`)
|
|
77
78
|
console.log(` - Seeded: ${seededCount}`)
|
|
78
79
|
console.log(` - Skipped (existing): ${skippedCount}`)
|
|
79
80
|
console.log(` - Total: ${rulesData.length}`)
|
|
@@ -367,5 +367,7 @@
|
|
|
367
367
|
"business_rules.components.conditionRow.field.comparisonPlaceholder": "e.g., user.role",
|
|
368
368
|
"business_rules.components.conditionRow.value.help": "Use JSON for arrays: [\"a\",\"b\"]",
|
|
369
369
|
"business_rules.components.conditionRow.field.comparisonHelp": "Field path to compare with",
|
|
370
|
-
"business_rules.components.conditionRow.deleteCondition": "Delete condition"
|
|
370
|
+
"business_rules.components.conditionRow.deleteCondition": "Delete condition",
|
|
371
|
+
"businessRules.notifications.rule.executionFailed.title": "Business Rule Failed",
|
|
372
|
+
"businessRules.notifications.rule.executionFailed.body": "Rule \"{ruleName}\" failed to execute{entityType, select, other { on {entityType}}}: {errorMessage}"
|
|
371
373
|
}
|