@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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-mercato/core",
3
- "version": "0.4.2-canary-3b5064ce72",
3
+ "version": "0.4.2-canary-15e78de280",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "scripts": {
@@ -207,7 +207,7 @@
207
207
  }
208
208
  },
209
209
  "dependencies": {
210
- "@open-mercato/shared": "0.4.2-canary-3b5064ce72",
210
+ "@open-mercato/shared": "0.4.2-canary-15e78de280",
211
211
  "@xyflow/react": "^12.6.0",
212
212
  "date-fns": "^4.1.0",
213
213
  "date-fns-tz": "^3.2.0"
@@ -2,7 +2,6 @@ import ApiDocsExplorer from './Explorer'
2
2
  import { getModules } from '@open-mercato/shared/lib/i18n/server'
3
3
  import { buildOpenApiDocument } from '@open-mercato/shared/lib/openapi'
4
4
  import { resolveApiDocsBaseUrl } from '@open-mercato/core/modules/api_docs/lib/resources'
5
- import { APP_VERSION } from '@open-mercato/shared/lib/version'
6
5
 
7
6
  type ExplorerOperation = {
8
7
  id: string
@@ -55,7 +54,7 @@ export default async function ApiDocsViewerPage() {
55
54
  const modules = getModules()
56
55
  const doc = buildOpenApiDocument(modules, {
57
56
  title: 'Open Mercato API',
58
- version: APP_VERSION,
57
+ version: '1.0.0',
59
58
  description: 'Auto-generated OpenAPI definition for all enabled modules.',
60
59
  servers: [{ url: baseUrl, description: 'Default environment' }],
61
60
  baseUrlForExamples: baseUrl,
@@ -68,7 +67,7 @@ export default async function ApiDocsViewerPage() {
68
67
  return (
69
68
  <ApiDocsExplorer
70
69
  title={doc.info?.title ?? 'Open Mercato API'}
71
- version={doc.info?.version ?? APP_VERSION}
70
+ version={doc.info?.version ?? '1.0.0'}
72
71
  description={doc.info?.description}
73
72
  operations={operations}
74
73
  tagOrder={tagOrder}
@@ -175,7 +175,7 @@ export default function ApiKeysListPage() {
175
175
  perspective={{ tableId: 'api_keys.list' }}
176
176
  rowActions={(row) => (
177
177
  <RowActions items={[
178
- { id: 'delete', label: t('common.delete'), destructive: true, onSelect: () => { void handleDelete(row) } },
178
+ { label: t('common.delete'), destructive: true, onSelect: () => { void handleDelete(row) } },
179
179
  ]} />
180
180
  )}
181
181
  pagination={{ page, pageSize: 20, total, totalPages, onPageChange: setPage }}
@@ -38,6 +38,10 @@ export class ApiKey {
38
38
  @Property({ name: 'session_user_id', type: 'uuid', nullable: true })
39
39
  sessionUserId?: string | null
40
40
 
41
+ /** Encrypted API key secret for session keys (recoverable for API calls) */
42
+ @Property({ name: 'session_secret_encrypted', type: 'text', nullable: true })
43
+ sessionSecretEncrypted?: string | null
44
+
41
45
  @Property({ name: 'last_used_at', type: Date, nullable: true })
42
46
  lastUsedAt?: Date | null
43
47
 
@@ -106,6 +106,15 @@
106
106
  "nullable": true,
107
107
  "mappedType": "uuid"
108
108
  },
109
+ "session_secret_encrypted": {
110
+ "name": "session_secret_encrypted",
111
+ "type": "text",
112
+ "unsigned": false,
113
+ "autoincrement": false,
114
+ "primary": false,
115
+ "nullable": true,
116
+ "mappedType": "text"
117
+ },
109
118
  "last_used_at": {
110
119
  "name": "last_used_at",
111
120
  "type": "timestamptz",
@@ -0,0 +1,13 @@
1
+ import { Migration } from '@mikro-orm/migrations';
2
+
3
+ export class Migration20260125204102 extends Migration {
4
+
5
+ override async up(): Promise<void> {
6
+ this.addSql(`alter table "api_keys" add column "session_secret_encrypted" text null;`);
7
+ }
8
+
9
+ override async down(): Promise<void> {
10
+ this.addSql(`alter table "api_keys" drop column "session_secret_encrypted";`);
11
+ }
12
+
13
+ }
@@ -4,9 +4,60 @@ import { hash, compare } from 'bcryptjs'
4
4
  import type { RbacService } from '@open-mercato/core/modules/auth/services/rbacService'
5
5
  import { Role } from '@open-mercato/core/modules/auth/data/entities'
6
6
  import { ApiKey } from '../data/entities'
7
+ import { createKmsService } from '@open-mercato/shared/lib/encryption/kms'
8
+ import { encryptWithAesGcm, decryptWithAesGcm } from '@open-mercato/shared/lib/encryption/aes'
7
9
 
8
10
  const BCRYPT_COST = 10
9
11
 
12
+ // =============================================================================
13
+ // Session Secret Encryption Helpers
14
+ // =============================================================================
15
+
16
+ /**
17
+ * Encrypt an API key secret for storage.
18
+ * Uses tenant-specific DEK if available, otherwise returns null.
19
+ */
20
+ async function encryptSessionSecret(
21
+ secret: string,
22
+ tenantId: string | null
23
+ ): Promise<string | null> {
24
+ if (!tenantId) return null
25
+
26
+ const kms = createKmsService()
27
+ if (!kms.isHealthy()) return null
28
+
29
+ const dek = await kms.getTenantDek(tenantId)
30
+ if (!dek) {
31
+ // Try to create a DEK if one doesn't exist
32
+ const created = await kms.createTenantDek(tenantId)
33
+ if (!created) return null
34
+ const encrypted = encryptWithAesGcm(secret, created.key)
35
+ return encrypted.value
36
+ }
37
+
38
+ const encrypted = encryptWithAesGcm(secret, dek.key)
39
+ return encrypted.value
40
+ }
41
+
42
+ /**
43
+ * Decrypt an API key secret from storage.
44
+ * Returns null if decryption fails or no DEK available.
45
+ */
46
+ async function decryptSessionSecret(
47
+ encrypted: string,
48
+ tenantId: string | null
49
+ ): Promise<string | null> {
50
+ if (!tenantId || !encrypted) return null
51
+
52
+ const kms = createKmsService()
53
+ if (!kms.isHealthy()) return null
54
+
55
+ const dek = await kms.getTenantDek(tenantId)
56
+ if (!dek) return null
57
+
58
+ return decryptWithAesGcm(encrypted, dek.key)
59
+ }
60
+
10
61
  export type CreateApiKeyInput = {
11
62
  name: string
12
63
  description?: string | null
@@ -117,6 +168,7 @@ export function generateSessionToken(): string {
117
168
  /**
118
169
  * Create an ephemeral API key scoped to a chat session.
119
170
  * The key inherits the user's roles and expires after ttlMinutes (default 30).
171
+ * The API key secret is encrypted and stored so it can be recovered for API calls.
120
172
  */
121
173
  export async function createSessionApiKey(
122
174
  em: EntityManager,
@@ -127,6 +179,9 @@ export async function createSessionApiKey(
127
179
  const expiresAt = new Date(Date.now() + ttl * 60 * 1000)
128
180
  const keyHash = await hashApiKey(secret)
129
181
 
182
+ // Encrypt the secret for later retrieval (used by MCP server for API calls)
183
+ const encryptedSecret = await encryptSessionSecret(secret, input.tenantId ?? null)
184
+
130
185
  const record = em.create(ApiKey, {
131
186
  name: `__session_${input.sessionToken}__`,
132
187
  description: 'Ephemeral session API key for AI chat',
@@ -138,6 +193,7 @@ export async function createSessionApiKey(
138
193
  createdBy: input.userId,
139
194
  sessionToken: input.sessionToken,
140
195
  sessionUserId: input.userId,
196
+ sessionSecretEncrypted: encryptedSecret,
141
197
  expiresAt,
142
198
  createdAt: new Date(),
143
199
  })
@@ -172,6 +228,35 @@ export async function findApiKeyBySessionToken(
172
228
  return record
173
229
  }
174
230
 
231
+ /**
232
+ * Find a session API key with its decrypted secret.
233
+ * Returns null if not found, expired, deleted, or decryption fails.
234
+ * This is used by the MCP server to recover the API key secret for making
235
+ * authenticated API calls on behalf of the user.
236
+ */
237
+ export async function findSessionApiKeyWithSecret(
238
+ em: EntityManager,
239
+ sessionToken: string
240
+ ): Promise<{ key: ApiKey; secret: string } | null> {
241
+ const record = await findApiKeyBySessionToken(em, sessionToken)
242
+ if (!record) return null
243
+
244
+ // If no encrypted secret stored, cannot recover
245
+ if (!record.sessionSecretEncrypted) {
246
+ console.warn('[ApiKeyService] Session key has no encrypted secret:', sessionToken.slice(0, 12))
247
+ return null
248
+ }
249
+
250
+ // Decrypt the secret
251
+ const secret = await decryptSessionSecret(record.sessionSecretEncrypted, record.tenantId ?? null)
252
+ if (!secret) {
253
+ console.warn('[ApiKeyService] Failed to decrypt session secret:', sessionToken.slice(0, 12))
254
+ return null
255
+ }
256
+
257
+ return { key: record, secret }
258
+ }
259
+
175
260
  /**
176
261
  * Delete an ephemeral API key by its session token.
177
262
  */
@@ -1056,7 +1056,6 @@ export function AttachmentLibrary() {
1056
1056
  <RowActions
1057
1057
  items={[
1058
1058
  {
1059
- id: 'open',
1060
1059
  label: t('attachments.library.actions.open', 'Open'),
1061
1060
  onSelect: () => {
1062
1061
  if (!row.url) return
@@ -1064,12 +1063,10 @@ export function AttachmentLibrary() {
1064
1063
  },
1065
1064
  },
1066
1065
  {
1067
- id: 'edit',
1068
1066
  label: t('attachments.library.actions.edit', 'Edit metadata'),
1069
1067
  onSelect: () => openMetadataDialog(row),
1070
1068
  },
1071
1069
  {
1072
- id: 'copy-url',
1073
1070
  label: t('attachments.library.actions.copyUrl', 'Copy URL'),
1074
1071
  onSelect: () => {
1075
1072
  if (!row.url) {
@@ -1094,7 +1091,6 @@ export function AttachmentLibrary() {
1094
1091
  },
1095
1092
  },
1096
1093
  {
1097
- id: 'delete',
1098
1094
  label: t('attachments.library.actions.delete', 'Delete'),
1099
1095
  destructive: true,
1100
1096
  onSelect: () => openDeleteDialog(row),
@@ -305,12 +305,10 @@ export function AttachmentPartitionSettings() {
305
305
  <RowActions
306
306
  items={[
307
307
  {
308
- id: 'edit',
309
308
  label: t('attachments.partitions.actions.edit', 'Edit'),
310
309
  onSelect: () => openDialog({ mode: 'edit', entry }),
311
310
  },
312
311
  {
313
- id: 'delete',
314
312
  label: t('attachments.partitions.actions.delete', 'Delete'),
315
313
  destructive: true,
316
314
  onSelect: () => { void handleDelete(entry) },
@@ -8,7 +8,7 @@ Features:
8
8
  - `mercato auth add-user --email <e> --password <p> --organizationId <id> [--roles r1,r2]`
9
9
  - `mercato auth seed-roles`
10
10
  - `mercato auth add-org --name <org>`
11
- - `mercato auth setup --orgName <org> --email <e> --password <p> [--roles superadmin,admin] [--skip-password-policy]`
11
+ - `mercato auth setup --orgName <org> --email <e> --password <p> [--roles superadmin,admin]`
12
12
 
13
13
  DB entities used (defined in root schema):
14
14
  - `users` with: `email`, `password_hash`, `is_confirmed`, `last_login_at`, `organization_id`, timestamps.
@@ -46,7 +46,7 @@ describe('auth CLI setup seeds ACLs', () => {
46
46
  findOneOrFail.mockImplementation(async (_: any, where: any) => ({ id: 'role-' + where.name, name: where.name }))
47
47
 
48
48
  // Act
49
- await setup.run(['--orgName', 'Acme', '--email', 'root@acme.com', '--password', 'secret', '--skip-password-policy'])
49
+ await setup.run(['--orgName', 'Acme', '--email', 'root@acme.com', '--password', 'secret'])
50
50
 
51
51
  // Assert: persistAndFlush was called to create three RoleAcl rows with expected flags/features
52
52
  const calls = persistAndFlush.mock.calls.map((c) => c[0])
@@ -15,8 +15,6 @@ jest.mock('@open-mercato/shared/lib/di/container', () => ({
15
15
  createRequestContainer: async () => ({
16
16
  resolve: (_: string) => ({
17
17
  findUserByEmail: async (email: string) => ({ id: 1, email, passwordHash: 'hash', tenantId: tenantId, organizationId: orgId }),
18
- findUsersByEmail: async (email: string) => ([{ id: 1, email, passwordHash: 'hash', tenantId: tenantId, organizationId: orgId }]),
19
- findUserByEmailAndTenant: async (email: string) => ({ id: 1, email, passwordHash: 'hash', tenantId: tenantId, organizationId: orgId }),
20
18
  verifyPassword: async () => true,
21
19
  getUserRoles: async (_user: any, _tenant: string | null | undefined) => ['admin'],
22
20
  updateLastLoginAt: async () => undefined,
@@ -297,16 +297,12 @@ export async function GET(req: Request) {
297
297
  const groupsWithRole = rolePreference ? applySidebarPreference(groups, rolePreference) : groups
298
298
  const baseForUser = adoptSidebarDefaults(groupsWithRole)
299
299
 
300
- // For API key auth, use userId (the actual user) if available; otherwise skip user preferences
301
- const effectiveUserId = auth.isApiKey ? auth.userId : auth.sub
302
- const preference = effectiveUserId
303
- ? await loadSidebarPreference(em, {
304
- userId: effectiveUserId,
305
- tenantId: auth.tenantId ?? null,
306
- organizationId: auth.orgId ?? null,
307
- locale,
308
- })
309
- : null
300
+ const preference = await loadSidebarPreference(em, {
301
+ userId: auth.sub,
302
+ tenantId: auth.tenantId ?? null,
303
+ organizationId: auth.orgId ?? null,
304
+ locale,
305
+ })
310
306
 
311
307
  const withPreference = applySidebarPreference(baseForUser, preference)
312
308
 
@@ -17,33 +17,15 @@ export async function POST(req: Request) {
17
17
  const email = String(form.get('email') ?? '')
18
18
  const password = String(form.get('password') ?? '')
19
19
  const remember = parseBooleanToken(form.get('remember')?.toString()) === true
20
- const tenantIdRaw = String(form.get('tenantId') ?? form.get('tenant') ?? '').trim()
21
20
  const requireRoleRaw = (String(form.get('requireRole') ?? form.get('role') ?? '')).trim()
22
21
  const requiredRoles = requireRoleRaw ? requireRoleRaw.split(',').map((s) => s.trim()).filter(Boolean) : []
23
- const parsed = userLoginSchema.pick({ email: true, password: true, tenantId: true }).safeParse({
24
- email,
25
- password,
26
- tenantId: tenantIdRaw || undefined,
27
- })
22
+ const parsed = userLoginSchema.pick({ email: true, password: true }).safeParse({ email, password })
28
23
  if (!parsed.success) {
29
24
  return NextResponse.json({ ok: false, error: translate('auth.login.errors.invalidCredentials', 'Invalid credentials') }, { status: 400 })
30
25
  }
31
26
  const container = await createRequestContainer()
32
27
  const auth = (container.resolve('authService') as AuthService)
33
- const tenantId = parsed.data.tenantId ?? null
34
- let user = null
35
- if (tenantId) {
36
- user = await auth.findUserByEmailAndTenant(parsed.data.email, tenantId)
37
- } else {
38
- const users = await auth.findUsersByEmail(parsed.data.email)
39
- if (users.length > 1) {
40
- return NextResponse.json({
41
- ok: false,
42
- error: translate('auth.login.errors.tenantRequired', 'Use the login link provided with your tenant activation to continue.'),
43
- }, { status: 400 })
44
- }
45
- user = users[0] ?? null
46
- }
28
+ const user = await auth.findUserByEmail(parsed.data.email)
47
29
  if (!user || !user.passwordHash) {
48
30
  return NextResponse.json({ ok: false, error: translate('auth.login.errors.invalidCredentials', 'Invalid email or password') }, { status: 401 })
49
31
  }
@@ -53,27 +35,26 @@ export async function POST(req: Request) {
53
35
  }
54
36
  // Optional role requirement
55
37
  if (requiredRoles.length) {
56
- const userRoleNames = await auth.getUserRoles(user, tenantId ?? (user.tenantId ? String(user.tenantId) : null))
38
+ const userRoleNames = await auth.getUserRoles(user, user.tenantId ? String(user.tenantId) : null)
57
39
  const authorized = requiredRoles.some(r => userRoleNames.includes(r))
58
40
  if (!authorized) {
59
41
  return NextResponse.json({ ok: false, error: translate('auth.login.errors.permissionDenied', 'Not authorized for this area') }, { status: 403 })
60
42
  }
61
43
  }
62
44
  await auth.updateLastLoginAt(user)
63
- const resolvedTenantId = tenantId ?? (user.tenantId ? String(user.tenantId) : null)
64
- const userRoleNames = await auth.getUserRoles(user, resolvedTenantId)
45
+ const userRoleNames = await auth.getUserRoles(user, user.tenantId ? String(user.tenantId) : null)
65
46
  try {
66
47
  const eventBus = (container.resolve('eventBus') as EventBus)
67
48
  void eventBus.emitEvent('query_index.coverage.warmup', {
68
- tenantId: resolvedTenantId,
49
+ tenantId: user.tenantId ? String(user.tenantId) : null,
69
50
  }).catch(() => undefined)
70
51
  } catch {
71
52
  // optional warmup
72
53
  }
73
54
  const token = signJwt({
74
55
  sub: String(user.id),
75
- tenantId: resolvedTenantId,
76
- orgId: user.organizationId ? String(user.organizationId) : null,
56
+ tenantId: user.tenantId ? String(user.tenantId) : null,
57
+ orgId: user.organizationId ? String(user.organizationId) : null,
77
58
  email: user.email,
78
59
  roles: userRoleNames
79
60
  })
@@ -3,9 +3,6 @@ import { NextResponse } from 'next/server'
3
3
  import type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'
4
4
  import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
5
5
  import { AuthService } from '@open-mercato/core/modules/auth/services/authService'
6
- import { buildNotificationFromType } from '@open-mercato/core/modules/notifications/lib/notificationBuilder'
7
- import { resolveNotificationService } from '@open-mercato/core/modules/notifications/lib/notificationService'
8
- import notificationTypes from '@open-mercato/core/modules/auth/notifications'
9
6
  import { z } from 'zod'
10
7
 
11
8
  // validation via confirmPasswordResetSchema
@@ -18,28 +15,8 @@ export async function POST(req: Request) {
18
15
  if (!parsed.success) return NextResponse.json({ ok: false, error: 'Invalid request' }, { status: 400 })
19
16
  const c = await createRequestContainer()
20
17
  const auth = c.resolve<AuthService>('authService')
21
- const user = await auth.confirmPasswordReset(parsed.data.token, parsed.data.password)
22
- if (!user) return NextResponse.json({ ok: false, error: 'Invalid or expired token' }, { status: 400 })
23
- try {
24
- const tenantId = user.tenantId ? String(user.tenantId) : null
25
- if (tenantId) {
26
- const notificationService = resolveNotificationService(c)
27
- const typeDef = notificationTypes.find((type) => type.type === 'auth.password_reset.completed')
28
- if (typeDef) {
29
- const notificationInput = buildNotificationFromType(typeDef, {
30
- recipientUserId: String(user.id),
31
- sourceEntityType: 'auth:user',
32
- sourceEntityId: String(user.id),
33
- })
34
- await notificationService.create(notificationInput, {
35
- tenantId,
36
- organizationId: user.organizationId ? String(user.organizationId) : null,
37
- })
38
- }
39
- }
40
- } catch (err) {
41
- console.error('[auth.reset.confirm] Failed to create notification:', err)
42
- }
18
+ const ok = await auth.confirmPasswordReset(parsed.data.token, parsed.data.password)
19
+ if (!ok) return NextResponse.json({ ok: false, error: 'Invalid or expired token' }, { status: 400 })
43
20
  return NextResponse.json({ ok: true, redirect: '/login' })
44
21
  }
45
22
 
@@ -6,9 +6,6 @@ import { AuthService } from '@open-mercato/core/modules/auth/services/authServic
6
6
  import { sendEmail } from '@open-mercato/shared/lib/email/send'
7
7
  import ResetPasswordEmail from '@open-mercato/core/modules/auth/emails/ResetPasswordEmail'
8
8
  import { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'
9
- import { buildNotificationFromType } from '@open-mercato/core/modules/notifications/lib/notificationBuilder'
10
- import { resolveNotificationService } from '@open-mercato/core/modules/notifications/lib/notificationService'
11
- import notificationTypes from '@open-mercato/core/modules/auth/notifications'
12
9
  import { z } from 'zod'
13
10
 
14
11
  // validation via requestPasswordResetSchema
@@ -38,26 +35,6 @@ export async function POST(req: Request) {
38
35
  }
39
36
 
40
37
  await sendEmail({ to: user.email, subject, react: ResetPasswordEmail({ resetUrl, copy }) })
41
- try {
42
- const tenantId = user.tenantId ? String(user.tenantId) : null
43
- if (tenantId) {
44
- const notificationService = resolveNotificationService(c)
45
- const typeDef = notificationTypes.find((type) => type.type === 'auth.password_reset.requested')
46
- if (typeDef) {
47
- const notificationInput = buildNotificationFromType(typeDef, {
48
- recipientUserId: String(user.id),
49
- sourceEntityType: 'auth:user',
50
- sourceEntityId: String(user.id),
51
- })
52
- await notificationService.create(notificationInput, {
53
- tenantId,
54
- organizationId: user.organizationId ? String(user.organizationId) : null,
55
- })
56
- }
57
- }
58
- } catch (err) {
59
- console.error('[auth.reset] Failed to create notification:', err)
60
- }
61
38
  return NextResponse.json({ ok: true })
62
39
  }
63
40
 
@@ -64,16 +64,12 @@ export async function GET(req: Request) {
64
64
  { tenantId: auth.tenantId ?? null, organizationId: auth.orgId ?? null },
65
65
  ) ?? false
66
66
 
67
- // For API key auth, use userId (the actual user) if available
68
- const effectiveUserId = auth.isApiKey ? auth.userId : auth.sub
69
- const settings = effectiveUserId
70
- ? await loadSidebarPreference(em, {
71
- userId: effectiveUserId,
72
- tenantId: auth.tenantId ?? null,
73
- organizationId: auth.orgId ?? null,
74
- locale,
75
- })
76
- : null
67
+ const settings = await loadSidebarPreference(em, {
68
+ userId: auth.sub,
69
+ tenantId: auth.tenantId ?? null,
70
+ organizationId: auth.orgId ?? null,
71
+ locale,
72
+ })
77
73
 
78
74
  let rolesPayload: Array<{ id: string; name: string; hasPreference: boolean }> = []
79
75
  if (canApplyToRoles) {
@@ -96,11 +92,11 @@ export async function GET(req: Request) {
96
92
  return NextResponse.json({
97
93
  locale,
98
94
  settings: {
99
- version: settings?.version ?? SIDEBAR_PREFERENCES_VERSION,
100
- groupOrder: settings?.groupOrder ?? [],
101
- groupLabels: settings?.groupLabels ?? {},
102
- itemLabels: settings?.itemLabels ?? {},
103
- hiddenItems: settings?.hiddenItems ?? [],
95
+ version: settings.version ?? SIDEBAR_PREFERENCES_VERSION,
96
+ groupOrder: settings.groupOrder ?? [],
97
+ groupLabels: settings.groupLabels ?? {},
98
+ itemLabels: settings.itemLabels ?? {},
99
+ hiddenItems: settings.hiddenItems ?? [],
104
100
  },
105
101
  canApplyToRoles,
106
102
  roles: rolesPayload,
@@ -110,11 +106,6 @@ export async function GET(req: Request) {
110
106
  export async function PUT(req: Request) {
111
107
  const auth = await getAuthFromRequest(req)
112
108
  if (!auth) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
113
- // For API key auth, use userId (the actual user) if available
114
- const effectiveUserId = auth.isApiKey ? auth.userId : auth.sub
115
- if (!effectiveUserId) {
116
- return NextResponse.json({ error: 'Cannot save preferences: no user associated with this API key' }, { status: 403 })
117
- }
118
109
 
119
110
  let parsedBody: unknown
120
111
  try {
@@ -191,7 +182,7 @@ export async function PUT(req: Request) {
191
182
  }
192
183
 
193
184
  const settings = await saveSidebarPreference(em, {
194
- userId: effectiveUserId,
185
+ userId: auth.sub,
195
186
  tenantId: auth.tenantId ?? null,
196
187
  organizationId: auth.orgId ?? null,
197
188
  locale,
@@ -15,7 +15,6 @@ import type { EntityManager } from '@mikro-orm/postgresql'
15
15
  import { userCrudEvents, userCrudIndexer } from '@open-mercato/core/modules/auth/commands/users'
16
16
  import { findWithDecryption } from '@open-mercato/shared/lib/encryption/find'
17
17
  import { escapeLikePattern } from '@open-mercato/shared/lib/db/escapeLikePattern'
18
- import { buildPasswordSchema } from '@open-mercato/shared/lib/auth/passwordPolicy'
19
18
 
20
19
  const querySchema = z.object({
21
20
  id: z.string().uuid().optional(),
@@ -28,11 +27,9 @@ const querySchema = z.object({
28
27
 
29
28
  const rawBodySchema = z.object({}).passthrough()
30
29
 
31
- const passwordSchema = buildPasswordSchema()
32
-
33
30
  const userCreateSchema = z.object({
34
31
  email: z.string().email(),
35
- password: passwordSchema,
32
+ password: z.string().min(6),
36
33
  organizationId: z.string().uuid(),
37
34
  roles: z.array(z.string()).optional(),
38
35
  })
@@ -40,7 +37,7 @@ const userCreateSchema = z.object({
40
37
  const userUpdateSchema = z.object({
41
38
  id: z.string().uuid(),
42
39
  email: z.string().email().optional(),
43
- password: passwordSchema.optional(),
40
+ password: z.string().min(6).optional(),
44
41
  organizationId: z.string().uuid().optional(),
45
42
  roles: z.array(z.string()).optional(),
46
43
  })
@@ -6,7 +6,7 @@ import { apiCall } from '@open-mercato/ui/backend/utils/apiCall'
6
6
  import { deleteCrud, updateCrud } from '@open-mercato/ui/backend/utils/crud'
7
7
  import { collectCustomFieldValues } from '@open-mercato/ui/backend/utils/customFieldValues'
8
8
  import { AclEditor, type AclData } from '@open-mercato/core/modules/auth/components/AclEditor'
9
- import { WidgetVisibilityEditor, type WidgetVisibilityEditorHandle } from '@open-mercato/core/modules/dashboards/components/WidgetVisibilityEditor'
9
+ import { WidgetVisibilityEditor } from '@open-mercato/core/modules/dashboards/components/WidgetVisibilityEditor'
10
10
  import { E } from '#generated/entities.ids.generated'
11
11
  import { TenantSelect } from '@open-mercato/core/modules/directory/components/TenantSelect'
12
12
  import { useT } from '@open-mercato/shared/lib/i18n/context'
@@ -37,7 +37,6 @@ export default function EditRolePage({ params }: { params?: { id?: string } }) {
37
37
  const [aclData, setAclData] = React.useState<AclData>({ isSuperAdmin: false, features: [], organizations: null })
38
38
  const [actorIsSuperAdmin, setActorIsSuperAdmin] = React.useState(false)
39
39
  const [selectedTenantId, setSelectedTenantId] = React.useState<string | null>(null)
40
- const widgetEditorRef = React.useRef<WidgetVisibilityEditorHandle | null>(null)
41
40
 
42
41
  React.useEffect(() => {
43
42
  if (!id) return
@@ -154,7 +153,6 @@ export default function EditRolePage({ params }: { params?: { id?: string } }) {
154
153
  kind="role"
155
154
  targetId={String(id)}
156
155
  tenantId={selectedTenantId ?? (initial?.tenantId ?? null)}
157
- ref={widgetEditorRef}
158
156
  />
159
157
  )
160
158
  : null),
@@ -193,7 +191,6 @@ export default function EditRolePage({ params }: { params?: { id?: string } }) {
193
191
  await updateCrud('auth/roles/acl', { roleId: id, tenantId: effectiveTenantId, ...aclData }, {
194
192
  errorMessage: t('auth.roles.form.errors.aclUpdate', 'Failed to update role access control'),
195
193
  })
196
- await widgetEditorRef.current?.save()
197
194
  try { window.dispatchEvent(new Event('om:refresh-sidebar')) } catch {}
198
195
  }}
199
196
  onDelete={async () => {
@@ -117,9 +117,9 @@ export default function RolesListPage() {
117
117
  onSearchChange={(v) => { setSearch(v); setPage(1) }}
118
118
  rowActions={(row) => (
119
119
  <RowActions items={[
120
- { id: 'edit', label: t('common.edit', 'Edit'), href: `/backend/roles/${row.id}/edit` },
121
- { id: 'show-users', label: t('auth.roles.list.actions.showUsers', 'Show users'), href: `/backend/users?roleId=${encodeURIComponent(row.id)}` },
122
- { id: 'delete', label: t('common.delete', 'Delete'), destructive: true, onSelect: () => { void handleDelete(row) } },
120
+ { label: t('common.edit', 'Edit'), href: `/backend/roles/${row.id}/edit` },
121
+ { label: t('auth.roles.list.actions.showUsers', 'Show users'), href: `/backend/users?roleId=${encodeURIComponent(row.id)}` },
122
+ { label: t('common.delete', 'Delete'), destructive: true, onSelect: () => { void handleDelete(row) } },
123
123
  ]} />
124
124
  )}
125
125
  sortable