@open-mercato/core 0.4.2-canary-3b5064ce72 → 0.4.2-canary-15e78de280

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (512) hide show
  1. package/dist/generated/entities/api_key/index.js +2 -0
  2. package/dist/generated/entities/api_key/index.js.map +2 -2
  3. package/dist/generated/entities.ids.generated.js +1 -5
  4. package/dist/generated/entities.ids.generated.js.map +2 -2
  5. package/dist/generated/entity-fields-registry.js +0 -2
  6. package/dist/generated/entity-fields-registry.js.map +2 -2
  7. package/dist/modules/api_docs/frontend/docs/api/page.js +2 -3
  8. package/dist/modules/api_docs/frontend/docs/api/page.js.map +2 -2
  9. package/dist/modules/api_keys/backend/api-keys/page.js +1 -1
  10. package/dist/modules/api_keys/backend/api-keys/page.js.map +2 -2
  11. package/dist/modules/api_keys/data/entities.js +3 -0
  12. package/dist/modules/api_keys/data/entities.js.map +2 -2
  13. package/dist/modules/api_keys/migrations/Migration20260125204102.js +13 -0
  14. package/dist/modules/api_keys/migrations/Migration20260125204102.js.map +7 -0
  15. package/dist/modules/api_keys/services/apiKeyService.js +41 -0
  16. package/dist/modules/api_keys/services/apiKeyService.js.map +3 -3
  17. package/dist/modules/attachments/components/AttachmentLibrary.js +0 -4
  18. package/dist/modules/attachments/components/AttachmentLibrary.js.map +2 -2
  19. package/dist/modules/attachments/components/AttachmentPartitionSettings.js +0 -2
  20. package/dist/modules/attachments/components/AttachmentPartitionSettings.js.map +2 -2
  21. package/dist/modules/auth/api/admin/nav.js +3 -4
  22. package/dist/modules/auth/api/admin/nav.js.map +2 -2
  23. package/dist/modules/auth/api/login.js +6 -25
  24. package/dist/modules/auth/api/login.js.map +2 -2
  25. package/dist/modules/auth/api/reset/confirm.js +2 -25
  26. package/dist/modules/auth/api/reset/confirm.js.map +2 -2
  27. package/dist/modules/auth/api/reset.js +0 -23
  28. package/dist/modules/auth/api/reset.js.map +2 -2
  29. package/dist/modules/auth/api/sidebar/preferences/route.js +9 -14
  30. package/dist/modules/auth/api/sidebar/preferences/route.js.map +2 -2
  31. package/dist/modules/auth/api/users/route.js +2 -4
  32. package/dist/modules/auth/api/users/route.js.map +2 -2
  33. package/dist/modules/auth/backend/roles/[id]/edit/page.js +1 -4
  34. package/dist/modules/auth/backend/roles/[id]/edit/page.js.map +2 -2
  35. package/dist/modules/auth/backend/roles/page.js +3 -3
  36. package/dist/modules/auth/backend/roles/page.js.map +2 -2
  37. package/dist/modules/auth/backend/users/[id]/edit/page.js +3 -18
  38. package/dist/modules/auth/backend/users/[id]/edit/page.js.map +2 -2
  39. package/dist/modules/auth/backend/users/create/page.js +2 -15
  40. package/dist/modules/auth/backend/users/create/page.js.map +2 -2
  41. package/dist/modules/auth/backend/users/page.js +3 -3
  42. package/dist/modules/auth/backend/users/page.js.map +2 -2
  43. package/dist/modules/auth/cli.js +11 -25
  44. package/dist/modules/auth/cli.js.map +2 -2
  45. package/dist/modules/auth/commands/users.js +2 -59
  46. package/dist/modules/auth/commands/users.js.map +2 -2
  47. package/dist/modules/auth/data/validators.js +3 -6
  48. package/dist/modules/auth/data/validators.js.map +2 -2
  49. package/dist/modules/auth/frontend/login.js +3 -112
  50. package/dist/modules/auth/frontend/login.js.map +2 -2
  51. package/dist/modules/auth/frontend/reset/[token]/page.js +10 -20
  52. package/dist/modules/auth/frontend/reset/[token]/page.js.map +2 -2
  53. package/dist/modules/auth/lib/setup-app.js +8 -42
  54. package/dist/modules/auth/lib/setup-app.js.map +2 -2
  55. package/dist/modules/auth/services/authService.js +3 -24
  56. package/dist/modules/auth/services/authService.js.map +2 -2
  57. package/dist/modules/auth/services/rbacService.js.map +2 -2
  58. package/dist/modules/business_rules/api/execute/route.js +1 -7
  59. package/dist/modules/business_rules/api/execute/route.js.map +2 -2
  60. package/dist/modules/business_rules/backend/rules/page.js +0 -4
  61. package/dist/modules/business_rules/backend/rules/page.js.map +2 -2
  62. package/dist/modules/business_rules/backend/sets/page.js +0 -3
  63. package/dist/modules/business_rules/backend/sets/page.js.map +2 -2
  64. package/dist/modules/business_rules/cli.js +1 -2
  65. package/dist/modules/business_rules/cli.js.map +2 -2
  66. package/dist/modules/business_rules/lib/rule-engine.js +3 -33
  67. package/dist/modules/business_rules/lib/rule-engine.js.map +2 -2
  68. package/dist/modules/catalog/components/PriceKindSettings.js +0 -2
  69. package/dist/modules/catalog/components/PriceKindSettings.js.map +2 -2
  70. package/dist/modules/catalog/components/categories/CategoriesDataTable.js +2 -2
  71. package/dist/modules/catalog/components/categories/CategoriesDataTable.js.map +2 -2
  72. package/dist/modules/catalog/components/products/ProductsDataTable.js +0 -2
  73. package/dist/modules/catalog/components/products/ProductsDataTable.js.map +2 -2
  74. package/dist/modules/configs/cli.js +0 -6
  75. package/dist/modules/configs/cli.js.map +2 -2
  76. package/dist/modules/configs/components/CachePanel.js +4 -4
  77. package/dist/modules/configs/components/CachePanel.js.map +2 -2
  78. package/dist/modules/configs/lib/system-status.js +1 -48
  79. package/dist/modules/configs/lib/system-status.js.map +2 -2
  80. package/dist/modules/configs/lib/upgrade-actions.js +0 -18
  81. package/dist/modules/configs/lib/upgrade-actions.js.map +2 -2
  82. package/dist/modules/currencies/backend/currencies/page.js +0 -3
  83. package/dist/modules/currencies/backend/currencies/page.js.map +2 -2
  84. package/dist/modules/currencies/backend/exchange-rates/page.js +0 -2
  85. package/dist/modules/currencies/backend/exchange-rates/page.js.map +2 -2
  86. package/dist/modules/customers/backend/customers/companies/page.js +0 -3
  87. package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
  88. package/dist/modules/customers/backend/customers/deals/page.js +0 -3
  89. package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
  90. package/dist/modules/customers/backend/customers/people/page.js +0 -3
  91. package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
  92. package/dist/modules/customers/commands/deals.js +0 -31
  93. package/dist/modules/customers/commands/deals.js.map +2 -2
  94. package/dist/modules/customers/components/CustomerTodosTable.js +0 -1
  95. package/dist/modules/customers/components/CustomerTodosTable.js.map +2 -2
  96. package/dist/modules/customers/widgets/dashboard/customer-todos/widget.js +1 -2
  97. package/dist/modules/customers/widgets/dashboard/customer-todos/widget.js.map +2 -2
  98. package/dist/modules/customers/widgets/dashboard/new-customers/widget.js +1 -2
  99. package/dist/modules/customers/widgets/dashboard/new-customers/widget.js.map +2 -2
  100. package/dist/modules/customers/widgets/dashboard/new-deals/widget.js +1 -2
  101. package/dist/modules/customers/widgets/dashboard/new-deals/widget.js.map +2 -2
  102. package/dist/modules/customers/widgets/dashboard/next-interactions/widget.js +1 -2
  103. package/dist/modules/customers/widgets/dashboard/next-interactions/widget.js.map +2 -2
  104. package/dist/modules/dashboards/cli.js +5 -44
  105. package/dist/modules/dashboards/cli.js.map +2 -2
  106. package/dist/modules/dashboards/components/WidgetVisibilityEditor.js +11 -16
  107. package/dist/modules/dashboards/components/WidgetVisibilityEditor.js.map +3 -3
  108. package/dist/modules/dashboards/services/widgetDataService.js +3 -139
  109. package/dist/modules/dashboards/services/widgetDataService.js.map +2 -2
  110. package/dist/modules/dashboards/widgets/dashboard/aov-kpi/widget.js +1 -2
  111. package/dist/modules/dashboards/widgets/dashboard/aov-kpi/widget.js.map +2 -2
  112. package/dist/modules/dashboards/widgets/dashboard/new-customers-kpi/widget.js +1 -2
  113. package/dist/modules/dashboards/widgets/dashboard/new-customers-kpi/widget.js.map +2 -2
  114. package/dist/modules/dashboards/widgets/dashboard/orders-by-status/widget.js +1 -2
  115. package/dist/modules/dashboards/widgets/dashboard/orders-by-status/widget.js.map +2 -2
  116. package/dist/modules/dashboards/widgets/dashboard/orders-kpi/widget.js +1 -2
  117. package/dist/modules/dashboards/widgets/dashboard/orders-kpi/widget.js.map +2 -2
  118. package/dist/modules/dashboards/widgets/dashboard/pipeline-summary/widget.js +1 -2
  119. package/dist/modules/dashboards/widgets/dashboard/pipeline-summary/widget.js.map +2 -2
  120. package/dist/modules/dashboards/widgets/dashboard/revenue-kpi/widget.js +1 -2
  121. package/dist/modules/dashboards/widgets/dashboard/revenue-kpi/widget.js.map +2 -2
  122. package/dist/modules/dashboards/widgets/dashboard/revenue-trend/widget.js +1 -2
  123. package/dist/modules/dashboards/widgets/dashboard/revenue-trend/widget.js.map +2 -2
  124. package/dist/modules/dashboards/widgets/dashboard/sales-by-region/widget.js +1 -2
  125. package/dist/modules/dashboards/widgets/dashboard/sales-by-region/widget.js.map +2 -2
  126. package/dist/modules/dashboards/widgets/dashboard/top-customers/widget.js +1 -2
  127. package/dist/modules/dashboards/widgets/dashboard/top-customers/widget.js.map +2 -2
  128. package/dist/modules/dashboards/widgets/dashboard/top-products/widget.js +1 -2
  129. package/dist/modules/dashboards/widgets/dashboard/top-products/widget.js.map +2 -2
  130. package/dist/modules/dictionaries/components/DictionaryTable.js +0 -2
  131. package/dist/modules/dictionaries/components/DictionaryTable.js.map +2 -2
  132. package/dist/modules/directory/backend/directory/organizations/page.js +2 -2
  133. package/dist/modules/directory/backend/directory/organizations/page.js.map +2 -2
  134. package/dist/modules/directory/backend/directory/tenants/page.js +2 -2
  135. package/dist/modules/directory/backend/directory/tenants/page.js.map +2 -2
  136. package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js +2 -2
  137. package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js.map +2 -2
  138. package/dist/modules/entities/components/SystemEntitiesTable.js +1 -1
  139. package/dist/modules/entities/components/SystemEntitiesTable.js.map +2 -2
  140. package/dist/modules/entities/components/UserEntitiesTable.js +2 -2
  141. package/dist/modules/entities/components/UserEntitiesTable.js.map +2 -2
  142. package/dist/modules/feature_toggles/components/FeatureTogglesTable.js +3 -3
  143. package/dist/modules/feature_toggles/components/FeatureTogglesTable.js.map +2 -2
  144. package/dist/modules/feature_toggles/components/OverridesTable.js +1 -1
  145. package/dist/modules/feature_toggles/components/OverridesTable.js.map +2 -2
  146. package/dist/modules/planner/backend/planner/availability-rulesets/page.js +2 -2
  147. package/dist/modules/planner/backend/planner/availability-rulesets/page.js.map +2 -2
  148. package/dist/modules/query_index/cli.js +7 -63
  149. package/dist/modules/query_index/cli.js.map +2 -2
  150. package/dist/modules/query_index/components/QueryIndexesTable.js +1 -7
  151. package/dist/modules/query_index/components/QueryIndexesTable.js.map +2 -2
  152. package/dist/modules/resources/backend/resources/resource-types/page.js +2 -2
  153. package/dist/modules/resources/backend/resources/resource-types/page.js.map +2 -2
  154. package/dist/modules/resources/backend/resources/resources/page.js +2 -2
  155. package/dist/modules/resources/backend/resources/resources/page.js.map +2 -2
  156. package/dist/modules/sales/backend/sales/channels/offers/page.js +0 -2
  157. package/dist/modules/sales/backend/sales/channels/offers/page.js.map +2 -2
  158. package/dist/modules/sales/backend/sales/channels/page.js +0 -2
  159. package/dist/modules/sales/backend/sales/channels/page.js.map +2 -2
  160. package/dist/modules/sales/commands/documents.js +0 -53
  161. package/dist/modules/sales/commands/documents.js.map +2 -2
  162. package/dist/modules/sales/commands/payments.js +0 -26
  163. package/dist/modules/sales/commands/payments.js.map +2 -2
  164. package/dist/modules/sales/components/AdjustmentKindSettings.js +2 -2
  165. package/dist/modules/sales/components/AdjustmentKindSettings.js.map +2 -2
  166. package/dist/modules/sales/components/PaymentMethodsSettings.js +2 -2
  167. package/dist/modules/sales/components/PaymentMethodsSettings.js.map +2 -2
  168. package/dist/modules/sales/components/ShippingMethodsSettings.js +2 -2
  169. package/dist/modules/sales/components/ShippingMethodsSettings.js.map +2 -2
  170. package/dist/modules/sales/components/TaxRatesSettings.js +2 -2
  171. package/dist/modules/sales/components/TaxRatesSettings.js.map +2 -2
  172. package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js +0 -2
  173. package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js.map +2 -2
  174. package/dist/modules/sales/components/documents/AdjustmentsSection.js +0 -2
  175. package/dist/modules/sales/components/documents/AdjustmentsSection.js.map +2 -2
  176. package/dist/modules/sales/components/documents/PaymentsSection.js +1 -2
  177. package/dist/modules/sales/components/documents/PaymentsSection.js.map +2 -2
  178. package/dist/modules/sales/components/documents/SalesDocumentsTable.js +0 -2
  179. package/dist/modules/sales/components/documents/SalesDocumentsTable.js.map +2 -2
  180. package/dist/modules/staff/backend/staff/team-members/page.js +1 -1
  181. package/dist/modules/staff/backend/staff/team-members/page.js.map +2 -2
  182. package/dist/modules/staff/backend/staff/team-roles/page.js +2 -2
  183. package/dist/modules/staff/backend/staff/team-roles/page.js.map +2 -2
  184. package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js +2 -2
  185. package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js.map +2 -2
  186. package/dist/modules/staff/backend/staff/teams/page.js +2 -2
  187. package/dist/modules/staff/backend/staff/teams/page.js.map +2 -2
  188. package/dist/modules/staff/commands/leave-requests.js +0 -79
  189. package/dist/modules/staff/commands/leave-requests.js.map +2 -2
  190. package/dist/modules/workflows/backend/definitions/page.js +0 -5
  191. package/dist/modules/workflows/backend/definitions/page.js.map +2 -2
  192. package/dist/modules/workflows/backend/instances/page.js +0 -3
  193. package/dist/modules/workflows/backend/instances/page.js.map +2 -2
  194. package/dist/modules/workflows/backend/tasks/page.js +0 -3
  195. package/dist/modules/workflows/backend/tasks/page.js.map +2 -2
  196. package/dist/modules/workflows/cli.js +12 -12
  197. package/dist/modules/workflows/cli.js.map +2 -2
  198. package/dist/modules/workflows/lib/transition-handler.js +6 -14
  199. package/dist/modules/workflows/lib/transition-handler.js.map +2 -2
  200. package/generated/entities/api_key/index.ts +1 -0
  201. package/generated/entities.ids.generated.ts +1 -5
  202. package/generated/entity-fields-registry.ts +0 -2
  203. package/package.json +2 -2
  204. package/src/modules/api_docs/frontend/docs/api/page.tsx +2 -3
  205. package/src/modules/api_keys/backend/api-keys/page.tsx +1 -1
  206. package/src/modules/api_keys/data/entities.ts +4 -0
  207. package/src/modules/api_keys/migrations/.snapshot-open-mercato.json +9 -0
  208. package/src/modules/api_keys/migrations/Migration20260125204102.ts +13 -0
  209. package/src/modules/api_keys/services/apiKeyService.ts +85 -0
  210. package/src/modules/attachments/components/AttachmentLibrary.tsx +0 -4
  211. package/src/modules/attachments/components/AttachmentPartitionSettings.tsx +0 -2
  212. package/src/modules/auth/README.md +1 -1
  213. package/src/modules/auth/__tests__/cli-setup-acl.test.ts +1 -1
  214. package/src/modules/auth/api/__tests__/login.test.ts +0 -2
  215. package/src/modules/auth/api/admin/nav.ts +6 -10
  216. package/src/modules/auth/api/login.ts +7 -26
  217. package/src/modules/auth/api/reset/confirm.ts +2 -25
  218. package/src/modules/auth/api/reset.ts +0 -23
  219. package/src/modules/auth/api/sidebar/preferences/route.ts +12 -21
  220. package/src/modules/auth/api/users/route.ts +2 -5
  221. package/src/modules/auth/backend/roles/[id]/edit/page.tsx +1 -4
  222. package/src/modules/auth/backend/roles/page.tsx +3 -3
  223. package/src/modules/auth/backend/users/[id]/edit/page.tsx +3 -22
  224. package/src/modules/auth/backend/users/create/page.tsx +2 -19
  225. package/src/modules/auth/backend/users/page.tsx +3 -3
  226. package/src/modules/auth/cli.ts +11 -38
  227. package/src/modules/auth/commands/users.ts +2 -73
  228. package/src/modules/auth/data/validators.ts +2 -6
  229. package/src/modules/auth/frontend/login.tsx +5 -134
  230. package/src/modules/auth/frontend/reset/[token]/page.tsx +11 -24
  231. package/src/modules/auth/i18n/de.json +1 -48
  232. package/src/modules/auth/i18n/en.json +1 -48
  233. package/src/modules/auth/i18n/es.json +1 -48
  234. package/src/modules/auth/i18n/pl.json +1 -48
  235. package/src/modules/auth/lib/setup-app.ts +9 -58
  236. package/src/modules/auth/services/authService.ts +4 -27
  237. package/src/modules/auth/services/rbacService.ts +1 -1
  238. package/src/modules/business_rules/api/execute/route.ts +1 -8
  239. package/src/modules/business_rules/backend/rules/page.tsx +0 -4
  240. package/src/modules/business_rules/backend/sets/page.tsx +0 -3
  241. package/src/modules/business_rules/cli.ts +1 -2
  242. package/src/modules/business_rules/i18n/en.json +1 -3
  243. package/src/modules/business_rules/lib/__tests__/rule-engine.test.ts +0 -51
  244. package/src/modules/business_rules/lib/rule-engine.ts +3 -57
  245. package/src/modules/catalog/components/PriceKindSettings.tsx +0 -2
  246. package/src/modules/catalog/components/categories/CategoriesDataTable.tsx +2 -2
  247. package/src/modules/catalog/components/products/ProductsDataTable.tsx +0 -2
  248. package/src/modules/catalog/i18n/en.json +1 -3
  249. package/src/modules/configs/cli.ts +0 -6
  250. package/src/modules/configs/components/CachePanel.tsx +4 -4
  251. package/src/modules/configs/i18n/en.json +2 -12
  252. package/src/modules/configs/i18n/pl.json +2 -12
  253. package/src/modules/configs/lib/system-status.ts +1 -48
  254. package/src/modules/configs/lib/system-status.types.ts +0 -1
  255. package/src/modules/configs/lib/upgrade-actions.ts +0 -18
  256. package/src/modules/currencies/backend/currencies/page.tsx +0 -3
  257. package/src/modules/currencies/backend/exchange-rates/page.tsx +0 -2
  258. package/src/modules/customers/backend/customers/companies/page.tsx +0 -3
  259. package/src/modules/customers/backend/customers/deals/page.tsx +0 -3
  260. package/src/modules/customers/backend/customers/people/page.tsx +0 -3
  261. package/src/modules/customers/commands/deals.ts +0 -39
  262. package/src/modules/customers/components/CustomerTodosTable.tsx +0 -1
  263. package/src/modules/customers/i18n/en.json +1 -5
  264. package/src/modules/customers/widgets/dashboard/customer-todos/widget.ts +2 -2
  265. package/src/modules/customers/widgets/dashboard/new-customers/widget.ts +2 -2
  266. package/src/modules/customers/widgets/dashboard/new-deals/widget.ts +2 -2
  267. package/src/modules/customers/widgets/dashboard/next-interactions/widget.ts +2 -2
  268. package/src/modules/dashboards/cli.ts +5 -55
  269. package/src/modules/dashboards/components/WidgetVisibilityEditor.tsx +11 -22
  270. package/src/modules/dashboards/services/widgetDataService.ts +4 -164
  271. package/src/modules/dashboards/widgets/dashboard/aov-kpi/widget.ts +2 -2
  272. package/src/modules/dashboards/widgets/dashboard/new-customers-kpi/widget.ts +2 -2
  273. package/src/modules/dashboards/widgets/dashboard/orders-by-status/widget.ts +2 -2
  274. package/src/modules/dashboards/widgets/dashboard/orders-kpi/widget.ts +2 -2
  275. package/src/modules/dashboards/widgets/dashboard/pipeline-summary/widget.ts +2 -2
  276. package/src/modules/dashboards/widgets/dashboard/revenue-kpi/widget.ts +2 -2
  277. package/src/modules/dashboards/widgets/dashboard/revenue-trend/widget.ts +2 -2
  278. package/src/modules/dashboards/widgets/dashboard/sales-by-region/widget.ts +2 -2
  279. package/src/modules/dashboards/widgets/dashboard/top-customers/widget.ts +2 -2
  280. package/src/modules/dashboards/widgets/dashboard/top-products/widget.ts +2 -2
  281. package/src/modules/dictionaries/components/DictionaryTable.tsx +0 -2
  282. package/src/modules/directory/backend/directory/organizations/page.tsx +2 -2
  283. package/src/modules/directory/backend/directory/tenants/page.tsx +2 -2
  284. package/src/modules/entities/backend/entities/user/[entityId]/records/page.tsx +2 -2
  285. package/src/modules/entities/components/SystemEntitiesTable.tsx +1 -1
  286. package/src/modules/entities/components/UserEntitiesTable.tsx +2 -2
  287. package/src/modules/feature_toggles/components/FeatureTogglesTable.tsx +4 -3
  288. package/src/modules/feature_toggles/components/OverridesTable.tsx +1 -1
  289. package/src/modules/planner/backend/planner/availability-rulesets/page.tsx +2 -2
  290. package/src/modules/query_index/cli.ts +13 -82
  291. package/src/modules/query_index/components/QueryIndexesTable.tsx +2 -8
  292. package/src/modules/resources/backend/resources/resource-types/page.tsx +2 -2
  293. package/src/modules/resources/backend/resources/resources/page.tsx +2 -2
  294. package/src/modules/sales/backend/sales/channels/offers/page.tsx +0 -2
  295. package/src/modules/sales/backend/sales/channels/page.tsx +0 -2
  296. package/src/modules/sales/commands/documents.ts +0 -65
  297. package/src/modules/sales/commands/payments.ts +0 -33
  298. package/src/modules/sales/components/AdjustmentKindSettings.tsx +2 -2
  299. package/src/modules/sales/components/PaymentMethodsSettings.tsx +2 -2
  300. package/src/modules/sales/components/ShippingMethodsSettings.tsx +2 -2
  301. package/src/modules/sales/components/TaxRatesSettings.tsx +2 -2
  302. package/src/modules/sales/components/channels/SalesChannelOffersPanel.tsx +0 -2
  303. package/src/modules/sales/components/documents/AdjustmentsSection.tsx +0 -2
  304. package/src/modules/sales/components/documents/PaymentsSection.tsx +1 -2
  305. package/src/modules/sales/components/documents/SalesDocumentsTable.tsx +0 -2
  306. package/src/modules/sales/i18n/de.json +0 -20
  307. package/src/modules/sales/i18n/en.json +1 -25
  308. package/src/modules/sales/i18n/es.json +0 -20
  309. package/src/modules/sales/i18n/pl.json +0 -20
  310. package/src/modules/staff/backend/staff/team-members/page.tsx +1 -1
  311. package/src/modules/staff/backend/staff/team-roles/page.tsx +2 -2
  312. package/src/modules/staff/backend/staff/teams/[id]/edit/page.tsx +2 -2
  313. package/src/modules/staff/backend/staff/teams/page.tsx +2 -2
  314. package/src/modules/staff/commands/leave-requests.ts +0 -94
  315. package/src/modules/staff/i18n/de.json +0 -4
  316. package/src/modules/staff/i18n/en.json +1 -9
  317. package/src/modules/staff/i18n/es.json +0 -4
  318. package/src/modules/staff/i18n/pl.json +0 -4
  319. package/src/modules/workflows/backend/definitions/page.tsx +0 -5
  320. package/src/modules/workflows/backend/instances/page.tsx +1 -4
  321. package/src/modules/workflows/backend/tasks/page.tsx +1 -4
  322. package/src/modules/workflows/cli.ts +12 -12
  323. package/src/modules/workflows/i18n/en.json +1 -3
  324. package/src/modules/workflows/lib/transition-handler.ts +6 -18
  325. package/dist/generated/entities/notification/index.js +0 -57
  326. package/dist/generated/entities/notification/index.js.map +0 -7
  327. package/dist/modules/auth/api/profile/route.js +0 -157
  328. package/dist/modules/auth/api/profile/route.js.map +0 -7
  329. package/dist/modules/auth/backend/auth/profile/page.js +0 -141
  330. package/dist/modules/auth/backend/auth/profile/page.js.map +0 -7
  331. package/dist/modules/auth/backend/auth/profile/page.meta.js +0 -13
  332. package/dist/modules/auth/backend/auth/profile/page.meta.js.map +0 -7
  333. package/dist/modules/auth/notifications.js +0 -112
  334. package/dist/modules/auth/notifications.js.map +0 -7
  335. package/dist/modules/business_rules/notifications.js +0 -28
  336. package/dist/modules/business_rules/notifications.js.map +0 -7
  337. package/dist/modules/business_rules/subscribers/rule-execution-failed-notification.js +0 -37
  338. package/dist/modules/business_rules/subscribers/rule-execution-failed-notification.js.map +0 -7
  339. package/dist/modules/catalog/notifications.js +0 -28
  340. package/dist/modules/catalog/notifications.js.map +0 -7
  341. package/dist/modules/catalog/subscribers/low-stock-notification.js +0 -38
  342. package/dist/modules/catalog/subscribers/low-stock-notification.js.map +0 -7
  343. package/dist/modules/customers/notifications.js +0 -48
  344. package/dist/modules/customers/notifications.js.map +0 -7
  345. package/dist/modules/dashboards/lib/role-widgets.js +0 -58
  346. package/dist/modules/dashboards/lib/role-widgets.js.map +0 -7
  347. package/dist/modules/directory/api/get/tenants/lookup.js +0 -70
  348. package/dist/modules/directory/api/get/tenants/lookup.js.map +0 -7
  349. package/dist/modules/notifications/acl.js +0 -11
  350. package/dist/modules/notifications/acl.js.map +0 -7
  351. package/dist/modules/notifications/api/[id]/action/route.js +0 -74
  352. package/dist/modules/notifications/api/[id]/action/route.js.map +0 -7
  353. package/dist/modules/notifications/api/[id]/dismiss/route.js +0 -15
  354. package/dist/modules/notifications/api/[id]/dismiss/route.js.map +0 -7
  355. package/dist/modules/notifications/api/[id]/read/route.js +0 -15
  356. package/dist/modules/notifications/api/[id]/read/route.js.map +0 -7
  357. package/dist/modules/notifications/api/[id]/restore/route.js +0 -53
  358. package/dist/modules/notifications/api/[id]/restore/route.js.map +0 -7
  359. package/dist/modules/notifications/api/batch/route.js +0 -17
  360. package/dist/modules/notifications/api/batch/route.js.map +0 -7
  361. package/dist/modules/notifications/api/feature/route.js +0 -17
  362. package/dist/modules/notifications/api/feature/route.js.map +0 -7
  363. package/dist/modules/notifications/api/mark-all-read/route.js +0 -35
  364. package/dist/modules/notifications/api/mark-all-read/route.js.map +0 -7
  365. package/dist/modules/notifications/api/openapi.js +0 -76
  366. package/dist/modules/notifications/api/openapi.js.map +0 -7
  367. package/dist/modules/notifications/api/role/route.js +0 -17
  368. package/dist/modules/notifications/api/role/route.js.map +0 -7
  369. package/dist/modules/notifications/api/route.js +0 -85
  370. package/dist/modules/notifications/api/route.js.map +0 -7
  371. package/dist/modules/notifications/api/settings/route.js +0 -155
  372. package/dist/modules/notifications/api/settings/route.js.map +0 -7
  373. package/dist/modules/notifications/api/unread-count/route.js +0 -38
  374. package/dist/modules/notifications/api/unread-count/route.js.map +0 -7
  375. package/dist/modules/notifications/backend/config/notifications/page.js +0 -10
  376. package/dist/modules/notifications/backend/config/notifications/page.js.map +0 -7
  377. package/dist/modules/notifications/backend/config/notifications/page.meta.js +0 -24
  378. package/dist/modules/notifications/backend/config/notifications/page.meta.js.map +0 -7
  379. package/dist/modules/notifications/cli.js +0 -16
  380. package/dist/modules/notifications/cli.js.map +0 -7
  381. package/dist/modules/notifications/data/entities.js +0 -112
  382. package/dist/modules/notifications/data/entities.js.map +0 -7
  383. package/dist/modules/notifications/data/validators.js +0 -98
  384. package/dist/modules/notifications/data/validators.js.map +0 -7
  385. package/dist/modules/notifications/di.js +0 -13
  386. package/dist/modules/notifications/di.js.map +0 -7
  387. package/dist/modules/notifications/emails/NotificationEmail.js +0 -58
  388. package/dist/modules/notifications/emails/NotificationEmail.js.map +0 -7
  389. package/dist/modules/notifications/frontend/NotificationInboxPageClient.js +0 -44
  390. package/dist/modules/notifications/frontend/NotificationInboxPageClient.js.map +0 -7
  391. package/dist/modules/notifications/frontend/NotificationSettingsPageClient.js +0 -220
  392. package/dist/modules/notifications/frontend/NotificationSettingsPageClient.js.map +0 -7
  393. package/dist/modules/notifications/index.js +0 -14
  394. package/dist/modules/notifications/index.js.map +0 -7
  395. package/dist/modules/notifications/lib/deliveryConfig.js +0 -107
  396. package/dist/modules/notifications/lib/deliveryConfig.js.map +0 -7
  397. package/dist/modules/notifications/lib/deliveryStrategies.js +0 -14
  398. package/dist/modules/notifications/lib/deliveryStrategies.js.map +0 -7
  399. package/dist/modules/notifications/lib/events.js +0 -12
  400. package/dist/modules/notifications/lib/events.js.map +0 -7
  401. package/dist/modules/notifications/lib/notificationBuilder.js +0 -66
  402. package/dist/modules/notifications/lib/notificationBuilder.js.map +0 -7
  403. package/dist/modules/notifications/lib/notificationFactory.js +0 -54
  404. package/dist/modules/notifications/lib/notificationFactory.js.map +0 -7
  405. package/dist/modules/notifications/lib/notificationMapper.js +0 -34
  406. package/dist/modules/notifications/lib/notificationMapper.js.map +0 -7
  407. package/dist/modules/notifications/lib/notificationRecipients.js +0 -35
  408. package/dist/modules/notifications/lib/notificationRecipients.js.map +0 -7
  409. package/dist/modules/notifications/lib/notificationService.js +0 -279
  410. package/dist/modules/notifications/lib/notificationService.js.map +0 -7
  411. package/dist/modules/notifications/lib/routeHelpers.js +0 -101
  412. package/dist/modules/notifications/lib/routeHelpers.js.map +0 -7
  413. package/dist/modules/notifications/lib/safeHref.js +0 -24
  414. package/dist/modules/notifications/lib/safeHref.js.map +0 -7
  415. package/dist/modules/notifications/migrations/Migration20260123000001.js +0 -70
  416. package/dist/modules/notifications/migrations/Migration20260123000001.js.map +0 -7
  417. package/dist/modules/notifications/migrations/Migration20260126150000.js +0 -37
  418. package/dist/modules/notifications/migrations/Migration20260126150000.js.map +0 -7
  419. package/dist/modules/notifications/migrations/Migration20260129082610.js +0 -13
  420. package/dist/modules/notifications/migrations/Migration20260129082610.js.map +0 -7
  421. package/dist/modules/notifications/subscribers/deliver-notification.js +0 -165
  422. package/dist/modules/notifications/subscribers/deliver-notification.js.map +0 -7
  423. package/dist/modules/notifications/workers/create-notification.worker.js +0 -70
  424. package/dist/modules/notifications/workers/create-notification.worker.js.map +0 -7
  425. package/dist/modules/sales/notifications.client.js +0 -51
  426. package/dist/modules/sales/notifications.client.js.map +0 -7
  427. package/dist/modules/sales/notifications.js +0 -88
  428. package/dist/modules/sales/notifications.js.map +0 -7
  429. package/dist/modules/sales/subscribers/quote-expiring-notification.js +0 -38
  430. package/dist/modules/sales/subscribers/quote-expiring-notification.js.map +0 -7
  431. package/dist/modules/sales/widgets/notifications/SalesOrderCreatedRenderer.js +0 -137
  432. package/dist/modules/sales/widgets/notifications/SalesOrderCreatedRenderer.js.map +0 -7
  433. package/dist/modules/sales/widgets/notifications/SalesQuoteCreatedRenderer.js +0 -137
  434. package/dist/modules/sales/widgets/notifications/SalesQuoteCreatedRenderer.js.map +0 -7
  435. package/dist/modules/sales/widgets/notifications/index.js +0 -7
  436. package/dist/modules/sales/widgets/notifications/index.js.map +0 -7
  437. package/dist/modules/sales/widgets/notifications/useSalesDocumentTotals.js +0 -60
  438. package/dist/modules/sales/widgets/notifications/useSalesDocumentTotals.js.map +0 -7
  439. package/dist/modules/staff/notifications.js +0 -75
  440. package/dist/modules/staff/notifications.js.map +0 -7
  441. package/dist/modules/workflows/notifications.js +0 -28
  442. package/dist/modules/workflows/notifications.js.map +0 -7
  443. package/dist/modules/workflows/subscribers/task-assigned-notification.js +0 -38
  444. package/dist/modules/workflows/subscribers/task-assigned-notification.js.map +0 -7
  445. package/generated/entities/notification/index.ts +0 -27
  446. package/src/modules/auth/api/profile/route.ts +0 -163
  447. package/src/modules/auth/backend/auth/profile/page.meta.ts +0 -9
  448. package/src/modules/auth/backend/auth/profile/page.tsx +0 -174
  449. package/src/modules/auth/notifications.ts +0 -109
  450. package/src/modules/business_rules/notifications.ts +0 -25
  451. package/src/modules/business_rules/subscribers/rule-execution-failed-notification.ts +0 -50
  452. package/src/modules/catalog/notifications.ts +0 -25
  453. package/src/modules/catalog/subscribers/low-stock-notification.ts +0 -52
  454. package/src/modules/customers/notifications.ts +0 -44
  455. package/src/modules/dashboards/lib/role-widgets.ts +0 -80
  456. package/src/modules/directory/api/get/tenants/lookup.ts +0 -75
  457. package/src/modules/notifications/__tests__/deliver-notification.test.ts +0 -195
  458. package/src/modules/notifications/__tests__/deliveryStrategies.test.ts +0 -19
  459. package/src/modules/notifications/__tests__/notificationService.test.ts +0 -208
  460. package/src/modules/notifications/acl.ts +0 -7
  461. package/src/modules/notifications/api/[id]/action/route.ts +0 -75
  462. package/src/modules/notifications/api/[id]/dismiss/route.ts +0 -12
  463. package/src/modules/notifications/api/[id]/read/route.ts +0 -12
  464. package/src/modules/notifications/api/[id]/restore/route.ts +0 -53
  465. package/src/modules/notifications/api/batch/route.ts +0 -14
  466. package/src/modules/notifications/api/feature/route.ts +0 -14
  467. package/src/modules/notifications/api/mark-all-read/route.ts +0 -34
  468. package/src/modules/notifications/api/openapi.ts +0 -76
  469. package/src/modules/notifications/api/role/route.ts +0 -14
  470. package/src/modules/notifications/api/route.ts +0 -92
  471. package/src/modules/notifications/api/settings/route.ts +0 -157
  472. package/src/modules/notifications/api/unread-count/route.ts +0 -38
  473. package/src/modules/notifications/backend/config/notifications/page.meta.ts +0 -22
  474. package/src/modules/notifications/backend/config/notifications/page.tsx +0 -12
  475. package/src/modules/notifications/cli.ts +0 -18
  476. package/src/modules/notifications/data/entities.ts +0 -99
  477. package/src/modules/notifications/data/validators.ts +0 -115
  478. package/src/modules/notifications/di.ts +0 -11
  479. package/src/modules/notifications/emails/NotificationEmail.tsx +0 -98
  480. package/src/modules/notifications/frontend/NotificationInboxPageClient.tsx +0 -42
  481. package/src/modules/notifications/frontend/NotificationSettingsPageClient.tsx +0 -233
  482. package/src/modules/notifications/i18n/de.json +0 -50
  483. package/src/modules/notifications/i18n/en.json +0 -50
  484. package/src/modules/notifications/i18n/es.json +0 -50
  485. package/src/modules/notifications/i18n/pl.json +0 -50
  486. package/src/modules/notifications/index.ts +0 -12
  487. package/src/modules/notifications/lib/deliveryConfig.ts +0 -153
  488. package/src/modules/notifications/lib/deliveryStrategies.ts +0 -50
  489. package/src/modules/notifications/lib/events.ts +0 -48
  490. package/src/modules/notifications/lib/notificationBuilder.ts +0 -121
  491. package/src/modules/notifications/lib/notificationFactory.ts +0 -76
  492. package/src/modules/notifications/lib/notificationMapper.ts +0 -33
  493. package/src/modules/notifications/lib/notificationRecipients.ts +0 -83
  494. package/src/modules/notifications/lib/notificationService.ts +0 -414
  495. package/src/modules/notifications/lib/routeHelpers.ts +0 -151
  496. package/src/modules/notifications/lib/safeHref.ts +0 -29
  497. package/src/modules/notifications/migrations/.snapshot-open-mercato.json +0 -336
  498. package/src/modules/notifications/migrations/Migration20260123000001.ts +0 -73
  499. package/src/modules/notifications/migrations/Migration20260126150000.ts +0 -39
  500. package/src/modules/notifications/migrations/Migration20260129082610.ts +0 -13
  501. package/src/modules/notifications/subscribers/deliver-notification.ts +0 -204
  502. package/src/modules/notifications/workers/create-notification.worker.ts +0 -122
  503. package/src/modules/sales/notifications.client.ts +0 -65
  504. package/src/modules/sales/notifications.ts +0 -82
  505. package/src/modules/sales/subscribers/quote-expiring-notification.ts +0 -53
  506. package/src/modules/sales/widgets/notifications/SalesOrderCreatedRenderer.tsx +0 -156
  507. package/src/modules/sales/widgets/notifications/SalesQuoteCreatedRenderer.tsx +0 -156
  508. package/src/modules/sales/widgets/notifications/index.ts +0 -2
  509. package/src/modules/sales/widgets/notifications/useSalesDocumentTotals.ts +0 -81
  510. package/src/modules/staff/notifications.ts +0 -71
  511. package/src/modules/workflows/notifications.ts +0 -25
  512. package/src/modules/workflows/subscribers/task-assigned-notification.ts +0 -53
@@ -22,21 +22,16 @@ import {
22
22
  import { normalizeTenantId } from "@open-mercato/core/modules/auth/lib/tenantAccess";
23
23
  import { computeEmailHash } from "@open-mercato/core/modules/auth/lib/emailHash";
24
24
  import { findOneWithDecryption, findWithDecryption } from "@open-mercato/shared/lib/encryption/find";
25
- import { buildNotificationFromType } from "@open-mercato/core/modules/notifications/lib/notificationBuilder";
26
- import { resolveNotificationService } from "@open-mercato/core/modules/notifications/lib/notificationService";
27
- import notificationTypes from "@open-mercato/core/modules/auth/notifications";
28
- import { buildPasswordSchema } from "@open-mercato/shared/lib/auth/passwordPolicy";
29
- const passwordSchema = buildPasswordSchema();
30
25
  const createSchema = z.object({
31
26
  email: z.string().email(),
32
- password: passwordSchema,
27
+ password: z.string().min(6),
33
28
  organizationId: z.string().uuid(),
34
29
  roles: z.array(z.string()).optional()
35
30
  });
36
31
  const updateSchema = z.object({
37
32
  id: z.string().uuid(),
38
33
  email: z.string().email().optional(),
39
- password: passwordSchema.optional(),
34
+ password: z.string().min(6).optional(),
40
35
  organizationId: z.string().uuid().optional(),
41
36
  roles: z.array(z.string()).optional()
42
37
  });
@@ -65,38 +60,6 @@ const userCrudIndexer = {
65
60
  tenantId: ctx.identifiers.tenantId
66
61
  })
67
62
  };
68
- async function notifyRoleChanges(ctx, user, assignedRoles, revokedRoles) {
69
- const tenantId = user.tenantId ? String(user.tenantId) : null;
70
- if (!tenantId) return;
71
- const organizationId = user.organizationId ? String(user.organizationId) : null;
72
- try {
73
- const notificationService = resolveNotificationService(ctx.container);
74
- if (assignedRoles.length) {
75
- const assignedType = notificationTypes.find((type) => type.type === "auth.role.assigned");
76
- if (assignedType) {
77
- const notificationInput = buildNotificationFromType(assignedType, {
78
- recipientUserId: String(user.id),
79
- sourceEntityType: "auth:user",
80
- sourceEntityId: String(user.id)
81
- });
82
- await notificationService.create(notificationInput, { tenantId, organizationId });
83
- }
84
- }
85
- if (revokedRoles.length) {
86
- const revokedType = notificationTypes.find((type) => type.type === "auth.role.revoked");
87
- if (revokedType) {
88
- const notificationInput = buildNotificationFromType(revokedType, {
89
- recipientUserId: String(user.id),
90
- sourceEntityType: "auth:user",
91
- sourceEntityId: String(user.id)
92
- });
93
- await notificationService.create(notificationInput, { tenantId, organizationId });
94
- }
95
- }
96
- } catch (err) {
97
- console.error("[auth.users.roles] Failed to create notification:", err);
98
- }
99
- }
100
63
  const createUserCommand = {
101
64
  id: "auth.users.create",
102
65
  async execute(rawInput, ctx) {
@@ -134,10 +97,8 @@ const createUserCommand = {
134
97
  if (isUniqueViolation(error)) await throwDuplicateEmailError();
135
98
  throw error;
136
99
  }
137
- let assignedRoles = [];
138
100
  if (Array.isArray(parsed.roles) && parsed.roles.length) {
139
101
  await syncUserRoles(em, user, parsed.roles, tenantId);
140
- assignedRoles = await loadUserRoleNames(em, String(user.id));
141
102
  }
142
103
  await setCustomFieldsIfAny({
143
104
  dataEngine: de,
@@ -159,9 +120,6 @@ const createUserCommand = {
159
120
  events: userCrudEvents,
160
121
  indexer: userCrudIndexer
161
122
  });
162
- if (assignedRoles.length) {
163
- await notifyRoleChanges(ctx, user, assignedRoles, []);
164
- }
165
123
  return user;
166
124
  },
167
125
  captureAfter: async (_input, result, ctx) => {
@@ -272,7 +230,6 @@ const updateUserCommand = {
272
230
  async execute(rawInput, ctx) {
273
231
  const { parsed, custom } = parseWithCustomFields(updateSchema, rawInput);
274
232
  const em = ctx.container.resolve("em");
275
- const rolesBefore = Array.isArray(parsed.roles) ? await loadUserRoleNames(em, parsed.id) : null;
276
233
  if (parsed.email !== void 0) {
277
234
  const emailHash2 = computeEmailHash(parsed.email);
278
235
  const duplicate = await em.findOne(
@@ -353,13 +310,6 @@ const updateUserCommand = {
353
310
  events: userCrudEvents,
354
311
  indexer: userCrudIndexer
355
312
  });
356
- if (Array.isArray(parsed.roles) && rolesBefore) {
357
- const rolesAfter = await loadUserRoleNames(em, String(user.id));
358
- const { assigned, revoked } = diffRoleChanges(rolesBefore, rolesAfter);
359
- if (assigned.length || revoked.length) {
360
- await notifyRoleChanges(ctx, user, assigned, revoked);
361
- }
362
- }
363
313
  await invalidateUserCache(ctx, parsed.id);
364
314
  return user;
365
315
  },
@@ -706,13 +656,6 @@ async function invalidateUserCache(ctx, userId) {
706
656
  } catch {
707
657
  }
708
658
  }
709
- function diffRoleChanges(before, after) {
710
- const beforeSet = new Set(before);
711
- const afterSet = new Set(after);
712
- const assigned = after.filter((role) => !beforeSet.has(role));
713
- const revoked = before.filter((role) => !afterSet.has(role));
714
- return { assigned, revoked };
715
- }
716
659
  function arrayEquals(left, right) {
717
660
  if (!left) return false;
718
661
  if (left.length !== right.length) return false;
@@ -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 { 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'\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,\n organizationId: z.string().uuid(),\n roles: z.array(z.string()).optional(),\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\nconst createUserCommand: CommandHandler<Record<string, unknown>, User> = {\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 em.findOne(User, { $or: [{ email: parsed.email }, { emailHash }], deletedAt: null } as any)\n if (duplicate) await throwDuplicateEmailError()\n\n const { hash } = await import('bcryptjs')\n const passwordHash = await hash(parsed.password, 10)\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 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) {\n await notifyRoleChanges(ctx, user, assignedRoles, [])\n }\n\n return user\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager)\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, ctx }) => {\n const { translate } = await resolveTranslations()\n const em = (ctx.container.resolve('em') as EntityManager)\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 const snapshot = captureUserSnapshots(result, roles, undefined, custom)\n return {\n actionLabel: translate('auth.audit.users.create', 'Create user'),\n resourceKind: 'auth.user',\n resourceId: String(result.id),\n tenantId: result.tenantId ? String(result.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\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 em.findOne(User, { id: parsed.id, deletedAt: 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 em.findOne(\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 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 (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)\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)\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(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 em.findOne(User, { id, deletedAt: 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(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager)\n let user = await em.findOne(User, { id: before.id })\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\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 currentLinks = await em.find(UserRole, { user })\n const currentNames = new Map(\n currentLinks.map((link) => {\n const roleEntity = link.role\n const name = roleEntity?.name ?? ''\n return [name, link] as const\n }),\n )\n\n for (const [name, link] of currentNames.entries()) {\n if (!unique.includes(name) && link) {\n em.remove(link)\n }\n }\n\n const normalizedTenantId = normalizeTenantId(tenantId ?? null) ?? null\n\n for (const name of unique) {\n if (!currentNames.has(name)) {\n let role = await em.findOne(Role, { name, tenantId: normalizedTenantId })\n if (!role && normalizedTenantId !== null) {\n role = await em.findOne(Role, { name, tenantId: null })\n }\n if (!role) {\n role = em.create(Role, { name, tenantId: normalizedTenantId, createdAt: new Date() })\n await em.persistAndFlush(role)\n } else if (normalizedTenantId !== null && role.tenantId !== normalizedTenantId) {\n role.tenantId = normalizedTenantId\n await em.persistAndFlush(role)\n }\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()\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 em.find(UserAcl, { user: userId as unknown as User })\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\ntype UndoPayload = { undo?: { before?: UserUndoSnapshot | null; after?: UserUndoSnapshot | null } }\n\nfunction extractUndoPayload(logEntry: { commandPayload?: unknown }): { before?: UserUndoSnapshot | null; after?: UserUndoSnapshot | null } | null {\n const payload = logEntry?.commandPayload as UndoPayload | undefined\n if (!payload || typeof payload !== 'object') return null\n return payload.undo ?? null\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 { 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'\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 createSchema = z.object({\n email: z.string().email(),\n password: z.string().min(6),\n organizationId: z.string().uuid(),\n roles: z.array(z.string()).optional(),\n})\n\nconst updateSchema = z.object({\n id: z.string().uuid(),\n email: z.string().email().optional(),\n password: z.string().min(6).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\nconst createUserCommand: CommandHandler<Record<string, unknown>, User> = {\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 em.findOne(User, { $or: [{ email: parsed.email }, { emailHash }], deletedAt: null } as any)\n if (duplicate) await throwDuplicateEmailError()\n\n const { hash } = await import('bcryptjs')\n const passwordHash = await hash(parsed.password, 10)\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 if (Array.isArray(parsed.roles) && parsed.roles.length) {\n await syncUserRoles(em, user, parsed.roles, tenantId)\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 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 return user\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager)\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, ctx }) => {\n const { translate } = await resolveTranslations()\n const em = (ctx.container.resolve('em') as EntityManager)\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 const snapshot = captureUserSnapshots(result, roles, undefined, custom)\n return {\n actionLabel: translate('auth.audit.users.create', 'Create user'),\n resourceKind: 'auth.user',\n resourceId: String(result.id),\n tenantId: result.tenantId ? String(result.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\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 em.findOne(User, { id: parsed.id, deletedAt: 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\n if (parsed.email !== undefined) {\n const emailHash = computeEmailHash(parsed.email)\n const duplicate = await em.findOne(\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 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 (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 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)\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)\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(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 em.findOne(User, { id, deletedAt: 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(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager)\n let user = await em.findOne(User, { id: before.id })\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\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 currentLinks = await em.find(UserRole, { user })\n const currentNames = new Map(\n currentLinks.map((link) => {\n const roleEntity = link.role\n const name = roleEntity?.name ?? ''\n return [name, link] as const\n }),\n )\n\n for (const [name, link] of currentNames.entries()) {\n if (!unique.includes(name) && link) {\n em.remove(link)\n }\n }\n\n const normalizedTenantId = normalizeTenantId(tenantId ?? null) ?? null\n\n for (const name of unique) {\n if (!currentNames.has(name)) {\n let role = await em.findOne(Role, { name, tenantId: normalizedTenantId })\n if (!role && normalizedTenantId !== null) {\n role = await em.findOne(Role, { name, tenantId: null })\n }\n if (!role) {\n role = em.create(Role, { name, tenantId: normalizedTenantId, createdAt: new Date() })\n await em.persistAndFlush(role)\n } else if (normalizedTenantId !== null && role.tenantId !== normalizedTenantId) {\n role.tenantId = normalizedTenantId\n await em.persistAndFlush(role)\n }\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()\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 em.find(UserAcl, { user: userId as unknown as User })\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\ntype UndoPayload = { undo?: { before?: UserUndoSnapshot | null; after?: UserUndoSnapshot | null } }\n\nfunction extractUndoPayload(logEntry: { commandPayload?: unknown }): { before?: UserUndoSnapshot | null; after?: UserUndoSnapshot | null } | null {\n const payload = logEntry?.commandPayload as UndoPayload | undefined\n if (!payload || typeof payload !== 'object') return null\n return payload.undo ?? null\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 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
  }
@@ -1,18 +1,15 @@
1
1
  import { z } from "zod";
2
- import { buildPasswordSchema } from "@open-mercato/shared/lib/auth/passwordPolicy";
3
- const passwordSchema = buildPasswordSchema();
4
2
  const userLoginSchema = z.object({
5
3
  email: z.string().email(),
6
4
  password: z.string().min(6),
7
- requireRole: z.string().optional(),
8
- tenantId: z.string().uuid().optional()
5
+ requireRole: z.string().optional()
9
6
  });
10
7
  const requestPasswordResetSchema = z.object({
11
8
  email: z.string().email()
12
9
  });
13
10
  const confirmPasswordResetSchema = z.object({
14
11
  token: z.string().min(10),
15
- password: passwordSchema
12
+ password: z.string().min(6)
16
13
  });
17
14
  const sidebarPreferencesInputSchema = z.object({
18
15
  version: z.number().int().positive().optional(),
@@ -25,7 +22,7 @@ const sidebarPreferencesInputSchema = z.object({
25
22
  });
26
23
  const userCreateSchema = z.object({
27
24
  email: z.string().email(),
28
- password: passwordSchema,
25
+ password: z.string().min(6),
29
26
  tenantId: z.string().uuid().optional(),
30
27
  organizationId: z.string().uuid(),
31
28
  rolesCsv: z.string().optional()
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/auth/data/validators.ts"],
4
- "sourcesContent": ["import { z } from 'zod'\nimport { buildPasswordSchema } from '@open-mercato/shared/lib/auth/passwordPolicy'\n\nconst passwordSchema = buildPasswordSchema()\n\n// Core auth validators\nexport const userLoginSchema = z.object({\n email: z.string().email(),\n password: z.string().min(6),\n requireRole: z.string().optional(),\n tenantId: z.string().uuid().optional(),\n})\n\nexport const requestPasswordResetSchema = z.object({\n email: z.string().email(),\n})\n\nexport const confirmPasswordResetSchema = z.object({\n token: z.string().min(10),\n password: passwordSchema,\n})\n\nexport const sidebarPreferencesInputSchema = z.object({\n version: z.number().int().positive().optional(),\n groupOrder: z.array(z.string().min(1)).max(200).optional(),\n groupLabels: z.record(z.string().min(1), z.string().min(1).max(120)).optional(),\n itemLabels: z.record(z.string().min(1), z.string().min(1).max(120)).optional(),\n hiddenItems: z.array(z.string().min(1)).max(500).optional(),\n applyToRoles: z.array(z.string().uuid()).optional(),\n clearRoleIds: z.array(z.string().uuid()).optional(),\n})\n\n// Optional helpers for CLI or admin forms\nexport const userCreateSchema = z.object({\n email: z.string().email(),\n password: passwordSchema,\n tenantId: z.string().uuid().optional(),\n organizationId: z.string().uuid(),\n rolesCsv: z.string().optional(),\n})\n\nexport type UserLoginInput = z.infer<typeof userLoginSchema>\nexport type RequestPasswordResetInput = z.infer<typeof requestPasswordResetSchema>\nexport type ConfirmPasswordResetInput = z.infer<typeof confirmPasswordResetSchema>\nexport type SidebarPreferencesInput = z.infer<typeof sidebarPreferencesInputSchema>\nexport type UserCreateInput = z.infer<typeof userCreateSchema>\n"],
5
- "mappings": "AAAA,SAAS,SAAS;AAClB,SAAS,2BAA2B;AAEpC,MAAM,iBAAiB,oBAAoB;AAGpC,MAAM,kBAAkB,EAAE,OAAO;AAAA,EACtC,OAAO,EAAE,OAAO,EAAE,MAAM;AAAA,EACxB,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC1B,aAAa,EAAE,OAAO,EAAE,SAAS;AAAA,EACjC,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS;AACvC,CAAC;AAEM,MAAM,6BAA6B,EAAE,OAAO;AAAA,EACjD,OAAO,EAAE,OAAO,EAAE,MAAM;AAC1B,CAAC;AAEM,MAAM,6BAA6B,EAAE,OAAO;AAAA,EACjD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE;AAAA,EACxB,UAAU;AACZ,CAAC;AAEM,MAAM,gCAAgC,EAAE,OAAO;AAAA,EACpD,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS;AAAA,EAC9C,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EACzD,aAAa,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,CAAC,EAAE,SAAS;AAAA,EAC9E,YAAY,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,CAAC,EAAE,SAAS;AAAA,EAC7E,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EAC1D,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,SAAS;AAAA,EAClD,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,SAAS;AACpD,CAAC;AAGM,MAAM,mBAAmB,EAAE,OAAO;AAAA,EACvC,OAAO,EAAE,OAAO,EAAE,MAAM;AAAA,EACxB,UAAU;AAAA,EACV,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS;AAAA,EACrC,gBAAgB,EAAE,OAAO,EAAE,KAAK;AAAA,EAChC,UAAU,EAAE,OAAO,EAAE,SAAS;AAChC,CAAC;",
4
+ "sourcesContent": ["import { z } from 'zod'\n\n// Core auth validators\nexport const userLoginSchema = z.object({\n email: z.string().email(),\n password: z.string().min(6),\n requireRole: z.string().optional(),\n})\n\nexport const requestPasswordResetSchema = z.object({\n email: z.string().email(),\n})\n\nexport const confirmPasswordResetSchema = z.object({\n token: z.string().min(10),\n password: z.string().min(6),\n})\n\nexport const sidebarPreferencesInputSchema = z.object({\n version: z.number().int().positive().optional(),\n groupOrder: z.array(z.string().min(1)).max(200).optional(),\n groupLabels: z.record(z.string().min(1), z.string().min(1).max(120)).optional(),\n itemLabels: z.record(z.string().min(1), z.string().min(1).max(120)).optional(),\n hiddenItems: z.array(z.string().min(1)).max(500).optional(),\n applyToRoles: z.array(z.string().uuid()).optional(),\n clearRoleIds: z.array(z.string().uuid()).optional(),\n})\n\n// Optional helpers for CLI or admin forms\nexport const userCreateSchema = z.object({\n email: z.string().email(),\n password: z.string().min(6),\n tenantId: z.string().uuid().optional(),\n organizationId: z.string().uuid(),\n rolesCsv: z.string().optional(),\n})\n\nexport type UserLoginInput = z.infer<typeof userLoginSchema>\nexport type RequestPasswordResetInput = z.infer<typeof requestPasswordResetSchema>\nexport type ConfirmPasswordResetInput = z.infer<typeof confirmPasswordResetSchema>\nexport type SidebarPreferencesInput = z.infer<typeof sidebarPreferencesInputSchema>\nexport type UserCreateInput = z.infer<typeof userCreateSchema>\n"],
5
+ "mappings": "AAAA,SAAS,SAAS;AAGX,MAAM,kBAAkB,EAAE,OAAO;AAAA,EACtC,OAAO,EAAE,OAAO,EAAE,MAAM;AAAA,EACxB,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC1B,aAAa,EAAE,OAAO,EAAE,SAAS;AACnC,CAAC;AAEM,MAAM,6BAA6B,EAAE,OAAO;AAAA,EACjD,OAAO,EAAE,OAAO,EAAE,MAAM;AAC1B,CAAC;AAEM,MAAM,6BAA6B,EAAE,OAAO;AAAA,EACjD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE;AAAA,EACxB,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC;AAC5B,CAAC;AAEM,MAAM,gCAAgC,EAAE,OAAO;AAAA,EACpD,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS;AAAA,EAC9C,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EACzD,aAAa,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,CAAC,EAAE,SAAS;AAAA,EAC9E,YAAY,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,CAAC,EAAE,SAAS;AAAA,EAC7E,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EAC1D,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,SAAS;AAAA,EAClD,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,SAAS;AACpD,CAAC;AAGM,MAAM,mBAAmB,EAAE,OAAO;AAAA,EACvC,OAAO,EAAE,OAAO,EAAE,MAAM;AAAA,EACxB,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC1B,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS;AAAA,EACrC,gBAAgB,EAAE,OAAO,EAAE,KAAK;AAAA,EAChC,UAAU,EAAE,OAAO,EAAE,SAAS;AAChC,CAAC;",
6
6
  "names": []
7
7
  }
@@ -1,37 +1,15 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
- import { useCallback, useEffect, useState } from "react";
3
+ import { useState } from "react";
4
4
  import Image from "next/image";
5
5
  import Link from "next/link";
6
6
  import { useRouter, useSearchParams } from "next/navigation";
7
7
  import { Card, CardContent, CardHeader, CardDescription } from "@open-mercato/ui/primitives/card";
8
8
  import { Input } from "@open-mercato/ui/primitives/input";
9
9
  import { Label } from "@open-mercato/ui/primitives/label";
10
- import { Button } from "@open-mercato/ui/primitives/button";
11
10
  import { useT } from "@open-mercato/shared/lib/i18n/context";
12
11
  import { translateWithFallback } from "@open-mercato/shared/lib/i18n/translate";
13
12
  import { clearAllOperations } from "@open-mercato/ui/backend/operations/store";
14
- import { apiCall } from "@open-mercato/ui/backend/utils/apiCall";
15
- import { X } from "lucide-react";
16
- const loginTenantKey = "om_login_tenant";
17
- const loginTenantCookieMaxAge = 60 * 60 * 24 * 14;
18
- function readTenantCookie() {
19
- if (typeof document === "undefined") return null;
20
- const entries = document.cookie.split(";");
21
- for (const entry of entries) {
22
- const [name, ...rest] = entry.trim().split("=");
23
- if (name === loginTenantKey) return decodeURIComponent(rest.join("="));
24
- }
25
- return null;
26
- }
27
- function setTenantCookie(value) {
28
- if (typeof document === "undefined") return;
29
- document.cookie = `${loginTenantKey}=${encodeURIComponent(value)}; path=/; max-age=${loginTenantCookieMaxAge}; samesite=lax`;
30
- }
31
- function clearTenantCookie() {
32
- if (typeof document === "undefined") return;
33
- document.cookie = `${loginTenantKey}=; path=/; max-age=0; samesite=lax`;
34
- }
35
13
  function extractErrorMessage(payload) {
36
14
  if (!payload) return null;
37
15
  if (typeof payload === "string") return payload;
@@ -64,10 +42,7 @@ function looksLikeJsonString(value) {
64
42
  }
65
43
  function LoginPage() {
66
44
  const t = useT();
67
- const translate = useCallback(
68
- (key, fallback, params) => translateWithFallback(t, key, fallback, params),
69
- [t]
70
- );
45
+ const translate = (key, fallback, params) => translateWithFallback(t, key, fallback, params);
71
46
  const router = useRouter();
72
47
  const searchParams = useSearchParams();
73
48
  const requireRole = (searchParams.get("requireRole") || searchParams.get("role") || "").trim();
@@ -78,74 +53,6 @@ function LoginPage() {
78
53
  const translatedFeatures = requiredFeatures.map((feature) => translate(`features.${feature}`, feature));
79
54
  const [error, setError] = useState(null);
80
55
  const [submitting, setSubmitting] = useState(false);
81
- const [tenantId, setTenantId] = useState(null);
82
- const [tenantName, setTenantName] = useState(null);
83
- const [tenantLoading, setTenantLoading] = useState(false);
84
- const [tenantInvalid, setTenantInvalid] = useState(null);
85
- const showTenantInvalid = tenantId != null && tenantInvalid === tenantId;
86
- useEffect(() => {
87
- const tenantParam = (searchParams.get("tenant") || "").trim();
88
- if (tenantParam) {
89
- setTenantId(tenantParam);
90
- window.localStorage.setItem(loginTenantKey, tenantParam);
91
- setTenantCookie(tenantParam);
92
- return;
93
- }
94
- const storedTenant = window.localStorage.getItem(loginTenantKey) || readTenantCookie();
95
- if (storedTenant) {
96
- setTenantId(storedTenant);
97
- }
98
- }, [searchParams]);
99
- useEffect(() => {
100
- if (!tenantId) {
101
- setTenantName(null);
102
- setTenantInvalid(null);
103
- return;
104
- }
105
- if (tenantInvalid === tenantId) {
106
- setTenantName(null);
107
- setTenantLoading(false);
108
- return;
109
- }
110
- let active = true;
111
- setTenantLoading(true);
112
- setTenantInvalid(null);
113
- apiCall(
114
- `/api/directory/tenants/lookup?tenantId=${encodeURIComponent(tenantId)}`
115
- ).then(({ result }) => {
116
- if (!active) return;
117
- if (result?.ok && result.tenant) {
118
- setTenantName(result.tenant.name);
119
- return;
120
- }
121
- const message = translate("auth.login.errors.tenantInvalid", "Tenant not found. Clear the tenant selection and try again.");
122
- setTenantName(null);
123
- setTenantInvalid(tenantId);
124
- setError(null);
125
- }).catch(() => {
126
- if (!active) return;
127
- setTenantName(null);
128
- setTenantInvalid(tenantId);
129
- setError(null);
130
- }).finally(() => {
131
- if (active) setTenantLoading(false);
132
- });
133
- return () => {
134
- active = false;
135
- };
136
- }, [tenantId, translate]);
137
- function handleClearTenant() {
138
- window.localStorage.removeItem(loginTenantKey);
139
- clearTenantCookie();
140
- setTenantId(null);
141
- setTenantName(null);
142
- setTenantInvalid(null);
143
- const params = new URLSearchParams(searchParams);
144
- params.delete("tenant");
145
- setError(null);
146
- const query = params.toString();
147
- router.replace(query ? `/login?${query}` : "/login");
148
- }
149
56
  async function onSubmit(e) {
150
57
  e.preventDefault();
151
58
  setError(null);
@@ -223,7 +130,6 @@ function LoginPage() {
223
130
  /* @__PURE__ */ jsx(CardDescription, { children: translate("auth.login.subtitle", "Access your workspace") })
224
131
  ] }),
225
132
  /* @__PURE__ */ jsx(CardContent, { children: /* @__PURE__ */ jsxs("form", { className: "grid gap-3", onSubmit, noValidate: true, children: [
226
- tenantId ? /* @__PURE__ */ jsx("input", { type: "hidden", name: "tenantId", value: tenantId }) : null,
227
133
  !!translatedRoles.length && /* @__PURE__ */ jsx("div", { className: "rounded-md border border-blue-200 bg-blue-50 px-3 py-2 text-center text-xs text-blue-900", children: translate(
228
134
  translatedRoles.length > 1 ? "auth.login.requireRolesMessage" : "auth.login.requireRoleMessage",
229
135
  translatedRoles.length > 1 ? "Access requires one of the following roles: {roles}" : "Access requires role: {roles}",
@@ -232,22 +138,7 @@ function LoginPage() {
232
138
  !!translatedFeatures.length && /* @__PURE__ */ jsx("div", { className: "rounded-md border border-blue-200 bg-blue-50 px-3 py-2 text-center text-xs text-blue-900", children: translate("auth.login.featureDenied", "You don't have access to this feature ({feature}). Please contact your administrator.", {
233
139
  feature: translatedFeatures.join(", ")
234
140
  }) }),
235
- showTenantInvalid ? /* @__PURE__ */ jsxs("div", { className: "rounded-md border border-red-200 bg-red-50 px-3 py-2 text-center text-xs text-red-700", children: [
236
- /* @__PURE__ */ jsx("div", { className: "font-medium", children: translate("auth.login.errors.tenantInvalid", "Tenant not found. Clear the tenant selection and try again.") }),
237
- /* @__PURE__ */ jsxs(Button, { type: "button", variant: "outline", size: "sm", className: "mt-2 border-red-300 text-red-700", onClick: handleClearTenant, children: [
238
- /* @__PURE__ */ jsx(X, { className: "mr-2 size-4", "aria-hidden": "true" }),
239
- translate("auth.login.tenantClear", "Clear")
240
- ] })
241
- ] }) : tenantId ? /* @__PURE__ */ jsxs("div", { className: "rounded-md border border-emerald-200 bg-emerald-50 px-3 py-2 text-center text-xs text-emerald-900", children: [
242
- /* @__PURE__ */ jsx("div", { className: "font-medium", children: tenantLoading ? translate("auth.login.tenantLoading", "Loading tenant details...") : translate("auth.login.tenantBanner", "You're logging in to {tenant} tenant.", {
243
- tenant: tenantName || tenantId
244
- }) }),
245
- /* @__PURE__ */ jsxs(Button, { type: "button", variant: "outline", size: "sm", className: "mt-2 border-emerald-300 text-emerald-900", onClick: handleClearTenant, children: [
246
- /* @__PURE__ */ jsx(X, { className: "mr-2 size-4", "aria-hidden": "true" }),
247
- translate("auth.login.tenantClear", "Clear")
248
- ] })
249
- ] }) : null,
250
- error && !showTenantInvalid && /* @__PURE__ */ jsx("div", { className: "rounded-md border border-red-200 bg-red-50 px-3 py-2 text-center text-sm text-red-700", role: "alert", "aria-live": "polite", children: error }),
141
+ error && /* @__PURE__ */ jsx("div", { className: "rounded-md border border-red-200 bg-red-50 px-3 py-2 text-center text-sm text-red-700", role: "alert", "aria-live": "polite", children: error }),
251
142
  /* @__PURE__ */ jsxs("div", { className: "grid gap-1", children: [
252
143
  /* @__PURE__ */ jsx(Label, { htmlFor: "email", children: t("auth.email") }),
253
144
  /* @__PURE__ */ jsx(Input, { id: "email", name: "email", type: "email", required: true, "aria-invalid": !!error })