@solidxai/core 0.1.13-beta.2 → 0.1.13-beta.21

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 (517) hide show
  1. package/CHANGELOG.md +10107 -0
  2. package/CLAUDE.md +5 -6
  3. package/README.md +19 -0
  4. package/dist/commands/run-tests.command.d.ts +9 -1
  5. package/dist/commands/run-tests.command.d.ts.map +1 -1
  6. package/dist/commands/run-tests.command.js +69 -6
  7. package/dist/commands/run-tests.command.js.map +1 -1
  8. package/dist/commands/seed.command.d.ts +2 -0
  9. package/dist/commands/seed.command.d.ts.map +1 -1
  10. package/dist/commands/seed.command.js +21 -0
  11. package/dist/commands/seed.command.js.map +1 -1
  12. package/dist/config/cache.options.d.ts.map +1 -1
  13. package/dist/config/cache.options.js +2 -2
  14. package/dist/config/cache.options.js.map +1 -1
  15. package/dist/constants/chatter-message.constants.d.ts +1 -0
  16. package/dist/constants/chatter-message.constants.d.ts.map +1 -1
  17. package/dist/constants/chatter-message.constants.js +3 -1
  18. package/dist/constants/chatter-message.constants.js.map +1 -1
  19. package/dist/constants/draft-publish-fields.d.ts +2 -0
  20. package/dist/constants/draft-publish-fields.d.ts.map +1 -0
  21. package/dist/constants/draft-publish-fields.js +5 -0
  22. package/dist/constants/draft-publish-fields.js.map +1 -0
  23. package/dist/constants/error-messages.d.ts +7 -0
  24. package/dist/constants/error-messages.d.ts.map +1 -1
  25. package/dist/constants/error-messages.js +7 -0
  26. package/dist/constants/error-messages.js.map +1 -1
  27. package/dist/constants/media-file-types.d.ts +12 -0
  28. package/dist/constants/media-file-types.d.ts.map +1 -1
  29. package/dist/constants/media-file-types.js +66 -1
  30. package/dist/constants/media-file-types.js.map +1 -1
  31. package/dist/constants/success-messages.d.ts +3 -0
  32. package/dist/constants/success-messages.d.ts.map +1 -1
  33. package/dist/constants/success-messages.js +3 -0
  34. package/dist/constants/success-messages.js.map +1 -1
  35. package/dist/constants/user.constants.d.ts +2 -0
  36. package/dist/constants/user.constants.d.ts.map +1 -0
  37. package/dist/constants/user.constants.js +5 -0
  38. package/dist/constants/user.constants.js.map +1 -0
  39. package/dist/controllers/action-metadata.controller.d.ts +1 -1
  40. package/dist/controllers/action-metadata.controller.js +1 -1
  41. package/dist/controllers/agent-event.controller.d.ts +1 -1
  42. package/dist/controllers/agent-event.controller.js +1 -1
  43. package/dist/controllers/agent-session.controller.d.ts +1 -1
  44. package/dist/controllers/agent-session.controller.js +1 -1
  45. package/dist/controllers/authentication.controller.d.ts +1 -1
  46. package/dist/controllers/authentication.controller.d.ts.map +1 -1
  47. package/dist/controllers/authentication.controller.js +4 -3
  48. package/dist/controllers/authentication.controller.js.map +1 -1
  49. package/dist/controllers/chatter-message.controller.d.ts +5 -0
  50. package/dist/controllers/chatter-message.controller.d.ts.map +1 -1
  51. package/dist/controllers/chatter-message.controller.js +14 -0
  52. package/dist/controllers/chatter-message.controller.js.map +1 -1
  53. package/dist/controllers/dashboard-user-layout.controller.d.ts +1 -1
  54. package/dist/controllers/dashboard-user-layout.controller.js +1 -1
  55. package/dist/controllers/email-template.controller.d.ts +1 -1
  56. package/dist/controllers/email-template.controller.js +1 -1
  57. package/dist/controllers/export-template.controller.d.ts +1 -1
  58. package/dist/controllers/export-template.controller.d.ts.map +1 -1
  59. package/dist/controllers/export-template.controller.js +6 -4
  60. package/dist/controllers/export-template.controller.js.map +1 -1
  61. package/dist/controllers/export-transaction.controller.d.ts +1 -1
  62. package/dist/controllers/export-transaction.controller.js +1 -1
  63. package/dist/controllers/field-metadata.controller.d.ts +2 -2
  64. package/dist/controllers/import-transaction-error-log.controller.d.ts +1 -1
  65. package/dist/controllers/import-transaction-error-log.controller.js +1 -1
  66. package/dist/controllers/import-transaction.controller.d.ts +1 -1
  67. package/dist/controllers/import-transaction.controller.d.ts.map +1 -1
  68. package/dist/controllers/import-transaction.controller.js +7 -7
  69. package/dist/controllers/import-transaction.controller.js.map +1 -1
  70. package/dist/controllers/list-of-values.controller.d.ts +1 -1
  71. package/dist/controllers/list-of-values.controller.js +1 -1
  72. package/dist/controllers/locale.controller.d.ts +1 -1
  73. package/dist/controllers/locale.controller.js +1 -1
  74. package/dist/controllers/mcp-audit-log.controller.d.ts +1 -1
  75. package/dist/controllers/mcp-audit-log.controller.js +1 -1
  76. package/dist/controllers/media.controller.d.ts +2 -2
  77. package/dist/controllers/media.controller.d.ts.map +1 -1
  78. package/dist/controllers/media.controller.js +13 -8
  79. package/dist/controllers/media.controller.js.map +1 -1
  80. package/dist/controllers/menu-item-metadata.controller.d.ts +1 -1
  81. package/dist/controllers/menu-item-metadata.controller.js +1 -1
  82. package/dist/controllers/model-sequence.controller.d.ts +1 -1
  83. package/dist/controllers/model-sequence.controller.js +1 -1
  84. package/dist/controllers/module-package.controller.d.ts.map +1 -1
  85. package/dist/controllers/module-package.controller.js +2 -3
  86. package/dist/controllers/module-package.controller.js.map +1 -1
  87. package/dist/controllers/mpin-authentication.controller.d.ts +44 -0
  88. package/dist/controllers/mpin-authentication.controller.d.ts.map +1 -0
  89. package/dist/controllers/mpin-authentication.controller.js +102 -0
  90. package/dist/controllers/mpin-authentication.controller.js.map +1 -0
  91. package/dist/controllers/mq-message-queue.controller.d.ts +1 -1
  92. package/dist/controllers/mq-message-queue.controller.js +1 -1
  93. package/dist/controllers/mq-message.controller.d.ts +1 -1
  94. package/dist/controllers/mq-message.controller.js +1 -1
  95. package/dist/controllers/permission-metadata.controller.d.ts +1 -1
  96. package/dist/controllers/permission-metadata.controller.js +1 -1
  97. package/dist/controllers/role-metadata.controller.d.ts +1 -1
  98. package/dist/controllers/role-metadata.controller.js +1 -1
  99. package/dist/controllers/saved-filters.controller.d.ts +1 -1
  100. package/dist/controllers/saved-filters.controller.js +1 -1
  101. package/dist/controllers/scheduled-job.controller.d.ts +1 -1
  102. package/dist/controllers/scheduled-job.controller.js +1 -1
  103. package/dist/controllers/security-rule.controller.d.ts +1 -1
  104. package/dist/controllers/security-rule.controller.js +1 -1
  105. package/dist/controllers/sms-template.controller.d.ts +1 -1
  106. package/dist/controllers/sms-template.controller.js +1 -1
  107. package/dist/controllers/user-activity-history.controller.d.ts +1 -1
  108. package/dist/controllers/user-activity-history.controller.js +1 -1
  109. package/dist/controllers/user-view-metadata.controller.d.ts +1 -1
  110. package/dist/controllers/user-view-metadata.controller.js +1 -1
  111. package/dist/controllers/user.controller.d.ts +2 -2
  112. package/dist/controllers/user.controller.js +2 -2
  113. package/dist/controllers/view-metadata.controller.d.ts +2 -2
  114. package/dist/controllers/view-metadata.controller.js +1 -1
  115. package/dist/controllers/workflow-definition.controller.d.ts +1 -1
  116. package/dist/controllers/workflow-definition.controller.js +1 -1
  117. package/dist/controllers/workflow-execution-artifact.controller.d.ts +1 -1
  118. package/dist/controllers/workflow-execution-artifact.controller.js +1 -1
  119. package/dist/controllers/workflow-execution-log.controller.d.ts +1 -1
  120. package/dist/controllers/workflow-execution-log.controller.js +1 -1
  121. package/dist/controllers/workflow-execution.controller.d.ts +1 -1
  122. package/dist/controllers/workflow-execution.controller.js +1 -1
  123. package/dist/controllers/workflow-secret.controller.d.ts +1 -1
  124. package/dist/controllers/workflow-secret.controller.js +1 -1
  125. package/dist/controllers/workflow-step-execution.controller.d.ts +1 -1
  126. package/dist/controllers/workflow-step-execution.controller.js +1 -1
  127. package/dist/controllers/workflow-trigger-execution.controller.d.ts +1 -1
  128. package/dist/controllers/workflow-trigger-execution.controller.js +1 -1
  129. package/dist/dtos/basic-filters.dto.d.ts +0 -1
  130. package/dist/dtos/basic-filters.dto.d.ts.map +1 -1
  131. package/dist/dtos/basic-filters.dto.js +1 -6
  132. package/dist/dtos/basic-filters.dto.js.map +1 -1
  133. package/dist/dtos/change-mpin.dto.d.ts +6 -0
  134. package/dist/dtos/change-mpin.dto.d.ts.map +1 -0
  135. package/dist/dtos/change-mpin.dto.js +39 -0
  136. package/dist/dtos/change-mpin.dto.js.map +1 -0
  137. package/dist/dtos/create-field-metadata.dto.d.ts +3 -6
  138. package/dist/dtos/create-field-metadata.dto.d.ts.map +1 -1
  139. package/dist/dtos/create-field-metadata.dto.js +15 -10
  140. package/dist/dtos/create-field-metadata.dto.js.map +1 -1
  141. package/dist/dtos/create-model-sequence.dto.d.ts +1 -1
  142. package/dist/dtos/create-model-sequence.dto.d.ts.map +1 -1
  143. package/dist/dtos/create-model-sequence.dto.js +1 -1
  144. package/dist/dtos/create-model-sequence.dto.js.map +1 -1
  145. package/dist/dtos/mpin-login.dto.d.ts +5 -0
  146. package/dist/dtos/mpin-login.dto.d.ts.map +1 -0
  147. package/dist/dtos/mpin-login.dto.js +33 -0
  148. package/dist/dtos/mpin-login.dto.js.map +1 -0
  149. package/dist/dtos/setup-mpin.dto.d.ts +7 -0
  150. package/dist/dtos/setup-mpin.dto.d.ts.map +1 -0
  151. package/dist/dtos/setup-mpin.dto.js +47 -0
  152. package/dist/dtos/setup-mpin.dto.js.map +1 -0
  153. package/dist/entities/common.entity.d.ts +4 -0
  154. package/dist/entities/common.entity.d.ts.map +1 -1
  155. package/dist/entities/common.entity.js +25 -1
  156. package/dist/entities/common.entity.js.map +1 -1
  157. package/dist/entities/dashboard-user-layout.entity.js +2 -2
  158. package/dist/entities/dashboard-user-layout.entity.js.map +1 -1
  159. package/dist/entities/field-metadata.entity.d.ts +1 -0
  160. package/dist/entities/field-metadata.entity.d.ts.map +1 -1
  161. package/dist/entities/field-metadata.entity.js +5 -1
  162. package/dist/entities/field-metadata.entity.js.map +1 -1
  163. package/dist/entities/saved-filters.entity.js +3 -3
  164. package/dist/entities/saved-filters.entity.js.map +1 -1
  165. package/dist/entities/user-device-credential.entity.d.ts +18 -0
  166. package/dist/entities/user-device-credential.entity.d.ts.map +1 -0
  167. package/dist/entities/user-device-credential.entity.js +91 -0
  168. package/dist/entities/user-device-credential.entity.js.map +1 -0
  169. package/dist/entities/user.entity.d.ts.map +1 -1
  170. package/dist/entities/user.entity.js +36 -0
  171. package/dist/entities/user.entity.js.map +1 -1
  172. package/dist/entities/view-metadata.entity.js.map +1 -1
  173. package/dist/entities/workflow-execution-artifact.entity.d.ts.map +1 -1
  174. package/dist/entities/workflow-execution-artifact.entity.js +4 -3
  175. package/dist/entities/workflow-execution-artifact.entity.js.map +1 -1
  176. package/dist/entities/workflow-execution-log.entity.d.ts.map +1 -1
  177. package/dist/entities/workflow-execution-log.entity.js +4 -3
  178. package/dist/entities/workflow-execution-log.entity.js.map +1 -1
  179. package/dist/entities/workflow-execution.entity.d.ts.map +1 -1
  180. package/dist/entities/workflow-execution.entity.js +3 -2
  181. package/dist/entities/workflow-execution.entity.js.map +1 -1
  182. package/dist/entities/workflow-secret.entity.d.ts.map +1 -1
  183. package/dist/entities/workflow-secret.entity.js +3 -2
  184. package/dist/entities/workflow-secret.entity.js.map +1 -1
  185. package/dist/entities/workflow-step-execution.entity.d.ts.map +1 -1
  186. package/dist/entities/workflow-step-execution.entity.js +3 -2
  187. package/dist/entities/workflow-step-execution.entity.js.map +1 -1
  188. package/dist/entities/workflow-trigger-execution.entity.d.ts.map +1 -1
  189. package/dist/entities/workflow-trigger-execution.entity.js +7 -6
  190. package/dist/entities/workflow-trigger-execution.entity.js.map +1 -1
  191. package/dist/factories/mail.factory.d.ts.map +1 -1
  192. package/dist/factories/mail.factory.js +4 -0
  193. package/dist/factories/mail.factory.js.map +1 -1
  194. package/dist/filters/http-exception.filter.d.ts.map +1 -1
  195. package/dist/filters/http-exception.filter.js +5 -1
  196. package/dist/filters/http-exception.filter.js.map +1 -1
  197. package/dist/helpers/bootstrap.helper.d.ts +5 -2
  198. package/dist/helpers/bootstrap.helper.d.ts.map +1 -1
  199. package/dist/helpers/bootstrap.helper.js +7 -3
  200. package/dist/helpers/bootstrap.helper.js.map +1 -1
  201. package/dist/helpers/field-crud-managers/MediaFieldCrudManager.d.ts +7 -0
  202. package/dist/helpers/field-crud-managers/MediaFieldCrudManager.d.ts.map +1 -1
  203. package/dist/helpers/field-crud-managers/MediaFieldCrudManager.js +66 -32
  204. package/dist/helpers/field-crud-managers/MediaFieldCrudManager.js.map +1 -1
  205. package/dist/helpers/file-download.helper.d.ts +9 -0
  206. package/dist/helpers/file-download.helper.d.ts.map +1 -0
  207. package/dist/helpers/file-download.helper.js +19 -0
  208. package/dist/helpers/file-download.helper.js.map +1 -0
  209. package/dist/helpers/model-metadata-helper.service.d.ts.map +1 -1
  210. package/dist/helpers/model-metadata-helper.service.js +30 -1
  211. package/dist/helpers/model-metadata-helper.service.js.map +1 -1
  212. package/dist/helpers/security.helper.d.ts +5 -1
  213. package/dist/helpers/security.helper.d.ts.map +1 -1
  214. package/dist/helpers/security.helper.js +15 -4
  215. package/dist/helpers/security.helper.js.map +1 -1
  216. package/dist/helpers/solid-core-error-codes-provider.service.d.ts.map +1 -1
  217. package/dist/helpers/solid-core-error-codes-provider.service.js +45 -0
  218. package/dist/helpers/solid-core-error-codes-provider.service.js.map +1 -1
  219. package/dist/helpers/solid-microservice-adapter.service.d.ts.map +1 -1
  220. package/dist/helpers/solid-microservice-adapter.service.js +1 -1
  221. package/dist/helpers/solid-microservice-adapter.service.js.map +1 -1
  222. package/dist/helpers/solid-registry.js +1 -1
  223. package/dist/helpers/solid-registry.js.map +1 -1
  224. package/dist/helpers/typeorm-db-helper.d.ts.map +1 -1
  225. package/dist/helpers/typeorm-db-helper.js +9 -0
  226. package/dist/helpers/typeorm-db-helper.js.map +1 -1
  227. package/dist/index.d.ts +10 -0
  228. package/dist/index.d.ts.map +1 -1
  229. package/dist/index.js +10 -0
  230. package/dist/index.js.map +1 -1
  231. package/dist/interfaces/active-user-data.interface.d.ts +1 -0
  232. package/dist/interfaces/active-user-data.interface.d.ts.map +1 -1
  233. package/dist/interfaces/active-user-data.interface.js.map +1 -1
  234. package/dist/interfaces.d.ts +1 -0
  235. package/dist/interfaces.d.ts.map +1 -1
  236. package/dist/interfaces.js.map +1 -1
  237. package/dist/repository/user-device-credential.repository.d.ts +12 -0
  238. package/dist/repository/user-device-credential.repository.d.ts.map +1 -0
  239. package/dist/repository/user-device-credential.repository.js +34 -0
  240. package/dist/repository/user-device-credential.repository.js.map +1 -0
  241. package/dist/seeders/module-metadata-seeder.service.d.ts.map +1 -1
  242. package/dist/seeders/module-metadata-seeder.service.js +51 -30
  243. package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
  244. package/dist/seeders/module-test-data.service.d.ts +3 -1
  245. package/dist/seeders/module-test-data.service.d.ts.map +1 -1
  246. package/dist/seeders/module-test-data.service.js +8 -2
  247. package/dist/seeders/module-test-data.service.js.map +1 -1
  248. package/dist/seeders/seed-data/solid-core-metadata.json +290 -78
  249. package/dist/services/api-key.service.d.ts.map +1 -1
  250. package/dist/services/api-key.service.js +1 -1
  251. package/dist/services/api-key.service.js.map +1 -1
  252. package/dist/services/authentication.service.d.ts +9 -5
  253. package/dist/services/authentication.service.d.ts.map +1 -1
  254. package/dist/services/authentication.service.js +102 -23
  255. package/dist/services/authentication.service.js.map +1 -1
  256. package/dist/services/chatter-message.service.d.ts +16 -1
  257. package/dist/services/chatter-message.service.d.ts.map +1 -1
  258. package/dist/services/chatter-message.service.js +100 -16
  259. package/dist/services/chatter-message.service.js.map +1 -1
  260. package/dist/services/crud-helper.service.d.ts +6 -4
  261. package/dist/services/crud-helper.service.d.ts.map +1 -1
  262. package/dist/services/crud-helper.service.js +32 -48
  263. package/dist/services/crud-helper.service.js.map +1 -1
  264. package/dist/services/crud.service.d.ts +13 -1
  265. package/dist/services/crud.service.d.ts.map +1 -1
  266. package/dist/services/crud.service.js +94 -68
  267. package/dist/services/crud.service.js.map +1 -1
  268. package/dist/services/datasource-introspection.service.d.ts.map +1 -1
  269. package/dist/services/datasource-introspection.service.js.map +1 -1
  270. package/dist/services/draft-publish-helper.service.d.ts +53 -0
  271. package/dist/services/draft-publish-helper.service.d.ts.map +1 -0
  272. package/dist/services/draft-publish-helper.service.js +402 -0
  273. package/dist/services/draft-publish-helper.service.js.map +1 -0
  274. package/dist/services/field-metadata.service.d.ts +2 -2
  275. package/dist/services/field-metadata.service.d.ts.map +1 -1
  276. package/dist/services/field-metadata.service.js +4 -1
  277. package/dist/services/field-metadata.service.js.map +1 -1
  278. package/dist/services/internationalisation-helper.service.d.ts +19 -0
  279. package/dist/services/internationalisation-helper.service.d.ts.map +1 -0
  280. package/dist/services/internationalisation-helper.service.js +107 -0
  281. package/dist/services/internationalisation-helper.service.js.map +1 -0
  282. package/dist/services/locale.service.d.ts +1 -1
  283. package/dist/services/media-storage.utils.d.ts +1 -0
  284. package/dist/services/media-storage.utils.d.ts.map +1 -1
  285. package/dist/services/media-storage.utils.js +12 -1
  286. package/dist/services/media-storage.utils.js.map +1 -1
  287. package/dist/services/media.service.d.ts +3 -2
  288. package/dist/services/media.service.d.ts.map +1 -1
  289. package/dist/services/media.service.js +45 -29
  290. package/dist/services/media.service.js.map +1 -1
  291. package/dist/services/metadata-validation.service.d.ts +7 -0
  292. package/dist/services/metadata-validation.service.d.ts.map +1 -0
  293. package/dist/services/metadata-validation.service.js +42 -0
  294. package/dist/services/metadata-validation.service.js.map +1 -0
  295. package/dist/services/model-metadata.service.d.ts.map +1 -1
  296. package/dist/services/model-metadata.service.js +2 -1
  297. package/dist/services/model-metadata.service.js.map +1 -1
  298. package/dist/services/module-metadata.service.d.ts.map +1 -1
  299. package/dist/services/module-metadata.service.js +9 -1
  300. package/dist/services/module-metadata.service.js.map +1 -1
  301. package/dist/services/mpin.service.d.ts +67 -0
  302. package/dist/services/mpin.service.d.ts.map +1 -0
  303. package/dist/services/mpin.service.js +282 -0
  304. package/dist/services/mpin.service.js.map +1 -0
  305. package/dist/services/object.utils.d.ts +2 -0
  306. package/dist/services/object.utils.d.ts.map +1 -0
  307. package/dist/services/object.utils.js +11 -0
  308. package/dist/services/object.utils.js.map +1 -0
  309. package/dist/services/refresh-token-ids-storage.service.d.ts +25 -6
  310. package/dist/services/refresh-token-ids-storage.service.d.ts.map +1 -1
  311. package/dist/services/refresh-token-ids-storage.service.js +80 -42
  312. package/dist/services/refresh-token-ids-storage.service.js.map +1 -1
  313. package/dist/services/setting.service.d.ts.map +1 -1
  314. package/dist/services/setting.service.js +6 -1
  315. package/dist/services/setting.service.js.map +1 -1
  316. package/dist/services/settings/default-settings-provider.service.d.ts +248 -12
  317. package/dist/services/settings/default-settings-provider.service.d.ts.map +1 -1
  318. package/dist/services/settings/default-settings-provider.service.js +143 -6
  319. package/dist/services/settings/default-settings-provider.service.js.map +1 -1
  320. package/dist/services/user.service.d.ts +2 -2
  321. package/dist/services/user.service.d.ts.map +1 -1
  322. package/dist/services/user.service.js +9 -3
  323. package/dist/services/user.service.js.map +1 -1
  324. package/dist/services/view-metadata.service.d.ts +1 -2
  325. package/dist/services/view-metadata.service.d.ts.map +1 -1
  326. package/dist/services/view-metadata.service.js +3 -55
  327. package/dist/services/view-metadata.service.js.map +1 -1
  328. package/dist/services/workflow/nodes/execution-fail.node.d.ts +6 -0
  329. package/dist/services/workflow/nodes/execution-fail.node.d.ts.map +1 -0
  330. package/dist/services/workflow/nodes/execution-fail.node.js +81 -0
  331. package/dist/services/workflow/nodes/execution-fail.node.js.map +1 -0
  332. package/dist/services/workflow/nodes/for-each.node.d.ts +2 -0
  333. package/dist/services/workflow/nodes/for-each.node.d.ts.map +1 -1
  334. package/dist/services/workflow/nodes/for-each.node.js +114 -5
  335. package/dist/services/workflow/nodes/for-each.node.js.map +1 -1
  336. package/dist/services/workflow/nodes/if.node.d.ts.map +1 -1
  337. package/dist/services/workflow/nodes/if.node.js +7 -0
  338. package/dist/services/workflow/nodes/if.node.js.map +1 -1
  339. package/dist/services/workflow/nodes/log-write.node.d.ts.map +1 -1
  340. package/dist/services/workflow/nodes/log-write.node.js +2 -0
  341. package/dist/services/workflow/nodes/log-write.node.js.map +1 -1
  342. package/dist/services/workflow/nodes/loop-until.node.d.ts +12 -0
  343. package/dist/services/workflow/nodes/loop-until.node.d.ts.map +1 -0
  344. package/dist/services/workflow/nodes/loop-until.node.js +281 -0
  345. package/dist/services/workflow/nodes/loop-until.node.js.map +1 -0
  346. package/dist/services/workflow/nodes/parallel.node.d.ts.map +1 -1
  347. package/dist/services/workflow/nodes/parallel.node.js +7 -0
  348. package/dist/services/workflow/nodes/parallel.node.js.map +1 -1
  349. package/dist/services/workflow/nodes/sequential.node.d.ts.map +1 -1
  350. package/dist/services/workflow/nodes/sequential.node.js +7 -0
  351. package/dist/services/workflow/nodes/sequential.node.js.map +1 -1
  352. package/dist/services/workflow/nodes/switch.node.d.ts.map +1 -1
  353. package/dist/services/workflow/nodes/switch.node.js +7 -0
  354. package/dist/services/workflow/nodes/switch.node.js.map +1 -1
  355. package/dist/services/workflow/workflow-definition-validator.service.d.ts.map +1 -1
  356. package/dist/services/workflow/workflow-definition-validator.service.js +5 -2
  357. package/dist/services/workflow/workflow-definition-validator.service.js.map +1 -1
  358. package/dist/services/workflow/workflow-expression.service.d.ts.map +1 -1
  359. package/dist/services/workflow/workflow-expression.service.js +5 -0
  360. package/dist/services/workflow/workflow-expression.service.js.map +1 -1
  361. package/dist/services/workflow/workflow-node-registry.service.d.ts +2 -1
  362. package/dist/services/workflow/workflow-node-registry.service.d.ts.map +1 -1
  363. package/dist/services/workflow/workflow-node-registry.service.js +7 -0
  364. package/dist/services/workflow/workflow-node-registry.service.js.map +1 -1
  365. package/dist/services/workflow/workflow-runtime.service.d.ts +8 -0
  366. package/dist/services/workflow/workflow-runtime.service.d.ts.map +1 -1
  367. package/dist/services/workflow/workflow-runtime.service.js +197 -32
  368. package/dist/services/workflow/workflow-runtime.service.js.map +1 -1
  369. package/dist/services/workflow-definition.service.d.ts +1 -1
  370. package/dist/solid-core.module.d.ts +1 -3
  371. package/dist/solid-core.module.d.ts.map +1 -1
  372. package/dist/solid-core.module.js +28 -40
  373. package/dist/solid-core.module.js.map +1 -1
  374. package/dist/testing/adapters/ui/playwright-adapter.d.ts +5 -0
  375. package/dist/testing/adapters/ui/playwright-adapter.d.ts.map +1 -1
  376. package/dist/testing/adapters/ui/playwright-adapter.js +17 -1
  377. package/dist/testing/adapters/ui/playwright-adapter.js.map +1 -1
  378. package/dist/testing/adapters/ui/ui.types.d.ts +2 -0
  379. package/dist/testing/adapters/ui/ui.types.d.ts.map +1 -1
  380. package/dist/testing/adapters/ui/ui.types.js.map +1 -1
  381. package/dist/testing/reporter/console-reporter.d.ts +3 -0
  382. package/dist/testing/reporter/console-reporter.d.ts.map +1 -1
  383. package/dist/testing/reporter/console-reporter.js +2 -0
  384. package/dist/testing/reporter/console-reporter.js.map +1 -1
  385. package/dist/testing/reporter/progress-reporter.d.ts +64 -0
  386. package/dist/testing/reporter/progress-reporter.d.ts.map +1 -0
  387. package/dist/testing/reporter/progress-reporter.js +224 -0
  388. package/dist/testing/reporter/progress-reporter.js.map +1 -0
  389. package/dist/testing/reporter/reporter.types.d.ts +3 -0
  390. package/dist/testing/reporter/reporter.types.d.ts.map +1 -1
  391. package/dist/testing/reporter/reporter.types.js.map +1 -1
  392. package/dist/testing/runner/run-from-metadata.d.ts.map +1 -1
  393. package/dist/testing/runner/run-from-metadata.js +1 -0
  394. package/dist/testing/runner/run-from-metadata.js.map +1 -1
  395. package/dist/testing/steps/ui/actions.step.d.ts.map +1 -1
  396. package/dist/testing/steps/ui/actions.step.js +6 -2
  397. package/dist/testing/steps/ui/actions.step.js.map +1 -1
  398. package/dist/testing/steps/ui/assertions.step.d.ts.map +1 -1
  399. package/dist/testing/steps/ui/assertions.step.js +11 -3
  400. package/dist/testing/steps/ui/assertions.step.js.map +1 -1
  401. package/dist/testing/steps/ui/form.step.d.ts.map +1 -1
  402. package/dist/testing/steps/ui/form.step.js +9 -3
  403. package/dist/testing/steps/ui/form.step.js.map +1 -1
  404. package/dist/testing/steps/ui/manual.step.js +1 -1
  405. package/dist/testing/steps/ui/manual.step.js.map +1 -1
  406. package/dist/testing/steps/ui/navigation.step.d.ts.map +1 -1
  407. package/dist/testing/steps/ui/navigation.step.js +3 -1
  408. package/dist/testing/steps/ui/navigation.step.js.map +1 -1
  409. package/dist/theme/theme-registry.d.ts +14 -0
  410. package/dist/theme/theme-registry.d.ts.map +1 -0
  411. package/dist/theme/theme-registry.js +147 -0
  412. package/dist/theme/theme-registry.js.map +1 -0
  413. package/dist/types/workflow-dsl.types.d.ts +14 -0
  414. package/dist/types/workflow-dsl.types.d.ts.map +1 -1
  415. package/dist/types/workflow-dsl.types.js.map +1 -1
  416. package/package.json +2 -2
  417. package/src/commands/run-tests.command.ts +64 -4
  418. package/src/commands/seed.command.ts +19 -0
  419. package/src/config/cache.options.ts +9 -1
  420. package/src/constants/chatter-message.constants.ts +12 -0
  421. package/src/constants/draft-publish-fields.ts +5 -0
  422. package/src/constants/error-messages.ts +14 -0
  423. package/src/constants/media-file-types.ts +128 -0
  424. package/src/constants/success-messages.ts +5 -0
  425. package/src/constants/user.constants.ts +13 -0
  426. package/src/controllers/authentication.controller.ts +5 -2
  427. package/src/controllers/chatter-message.controller.ts +8 -0
  428. package/src/controllers/export-template.controller.ts +5 -3
  429. package/src/controllers/import-transaction.controller.ts +6 -6
  430. package/src/controllers/media.controller.ts +17 -6
  431. package/src/controllers/module-package.controller.ts +2 -3
  432. package/src/controllers/mpin-authentication.controller.ts +67 -0
  433. package/src/dtos/basic-filters.dto.ts +0 -4
  434. package/src/dtos/change-mpin.dto.ts +18 -0
  435. package/src/dtos/create-field-metadata.dto.ts +17 -9
  436. package/src/dtos/create-model-sequence.dto.ts +1 -1
  437. package/src/dtos/mpin-login.dto.ts +24 -0
  438. package/src/dtos/setup-mpin.dto.ts +51 -0
  439. package/src/entities/common.entity.ts +24 -0
  440. package/src/entities/dashboard-user-layout.entity.ts +2 -2
  441. package/src/entities/field-metadata.entity.ts +3 -0
  442. package/src/entities/saved-filters.entity.ts +3 -3
  443. package/src/entities/user-device-credential.entity.ts +130 -0
  444. package/src/entities/user.entity.ts +53 -36
  445. package/src/entities/view-metadata.entity.ts +2 -2
  446. package/src/entities/workflow-execution-artifact.entity.ts +4 -3
  447. package/src/entities/workflow-execution-log.entity.ts +4 -3
  448. package/src/entities/workflow-execution.entity.ts +3 -2
  449. package/src/entities/workflow-secret.entity.ts +3 -2
  450. package/src/entities/workflow-step-execution.entity.ts +3 -2
  451. package/src/entities/workflow-trigger-execution.entity.ts +7 -6
  452. package/src/factories/mail.factory.ts +7 -1
  453. package/src/filters/http-exception.filter.ts +11 -1
  454. package/src/helpers/bootstrap.helper.ts +43 -6
  455. package/src/helpers/field-crud-managers/MediaFieldCrudManager.ts +90 -37
  456. package/src/helpers/file-download.helper.ts +45 -0
  457. package/src/helpers/model-metadata-helper.service.ts +32 -1
  458. package/src/helpers/security.helper.ts +35 -8
  459. package/src/helpers/solid-core-error-codes-provider.service.ts +53 -0
  460. package/src/helpers/solid-microservice-adapter.service.ts +6 -1
  461. package/src/helpers/solid-registry.ts +1 -1
  462. package/src/helpers/typeorm-db-helper.ts +12 -1
  463. package/src/index.ts +10 -0
  464. package/src/interfaces/active-user-data.interface.ts +9 -0
  465. package/src/interfaces.ts +1 -0
  466. package/src/repository/user-device-credential.repository.ts +17 -0
  467. package/src/seeders/module-metadata-seeder.service.ts +61 -39
  468. package/src/seeders/module-test-data.service.ts +6 -0
  469. package/src/seeders/seed-data/solid-core-metadata.json +290 -78
  470. package/src/services/api-key.service.ts +13 -1
  471. package/src/services/authentication.service.ts +203 -41
  472. package/src/services/chatter-message.service.ts +180 -19
  473. package/src/services/crud-helper.service.ts +35 -50
  474. package/src/services/crud.service.ts +132 -105
  475. package/src/services/datasource-introspection.service.ts +5 -0
  476. package/src/services/draft-publish-helper.service.ts +581 -0
  477. package/src/services/field-metadata.service.ts +5 -2
  478. package/src/services/internationalisation-helper.service.ts +148 -0
  479. package/src/services/media-storage.utils.ts +26 -1
  480. package/src/services/media.service.ts +68 -36
  481. package/src/services/metadata-validation.service.ts +39 -0
  482. package/src/services/model-metadata.service.ts +4 -1
  483. package/src/services/module-metadata.service.ts +10 -1
  484. package/src/services/mpin.service.ts +447 -0
  485. package/src/services/object.utils.ts +10 -0
  486. package/src/services/refresh-token-ids-storage.service.ts +229 -90
  487. package/src/services/setting.service.ts +8 -1
  488. package/src/services/settings/default-settings-provider.service.ts +154 -6
  489. package/src/services/user.service.ts +18 -3
  490. package/src/services/view-metadata.service.ts +5 -145
  491. package/src/services/workflow/nodes/execution-fail.node.ts +82 -0
  492. package/src/services/workflow/nodes/for-each.node.ts +140 -6
  493. package/src/services/workflow/nodes/if.node.ts +7 -0
  494. package/src/services/workflow/nodes/log-write.node.ts +2 -0
  495. package/src/services/workflow/nodes/loop-until.node.ts +343 -0
  496. package/src/services/workflow/nodes/parallel.node.ts +7 -0
  497. package/src/services/workflow/nodes/sequential.node.ts +7 -0
  498. package/src/services/workflow/nodes/switch.node.ts +7 -0
  499. package/src/services/workflow/workflow-definition-validator.service.ts +5 -2
  500. package/src/services/workflow/workflow-expression.service.ts +5 -0
  501. package/src/services/workflow/workflow-node-registry.service.ts +11 -0
  502. package/src/services/workflow/workflow-runtime.service.ts +274 -39
  503. package/src/solid-core.module.ts +46 -15
  504. package/src/testing/README.md +75 -3
  505. package/src/testing/adapters/ui/playwright-adapter.ts +25 -0
  506. package/src/testing/adapters/ui/ui.types.ts +2 -0
  507. package/src/testing/reporter/console-reporter.ts +4 -0
  508. package/src/testing/reporter/progress-reporter.ts +251 -0
  509. package/src/testing/reporter/reporter.types.ts +3 -0
  510. package/src/testing/runner/run-from-metadata.ts +1 -0
  511. package/src/testing/steps/ui/actions.step.ts +8 -4
  512. package/src/testing/steps/ui/assertions.step.ts +18 -5
  513. package/src/testing/steps/ui/form.step.ts +16 -6
  514. package/src/testing/steps/ui/manual.step.ts +1 -1
  515. package/src/testing/steps/ui/navigation.step.ts +4 -2
  516. package/src/theme/theme-registry.ts +181 -0
  517. package/src/types/workflow-dsl.types.ts +43 -0
@@ -20,7 +20,7 @@ import { SUCCESS_MESSAGES } from "src/constants/success-messages";
20
20
  import { CreateUserDto } from "src/dtos/create-user.dto";
21
21
  import { MailFactory } from "src/factories/mail.factory";
22
22
  import { UserRepository } from "src/repository/user.repository";
23
- import { DataSource, DeepPartial, Repository } from "typeorm";
23
+ import { DataSource, DeepPartial, FindOptionsWhere, Repository } from "typeorm";
24
24
  import { v4 as uuidv4 } from "uuid";
25
25
  import {
26
26
  ForgotPasswordSendVerificationTokenOn,
@@ -49,6 +49,7 @@ import { SsoCodeStorageService } from "./sso-code-storage.service";
49
49
  import { RoleMetadataService } from "./role-metadata.service";
50
50
  import { SettingService } from "./setting.service";
51
51
  import { UserActivityHistoryService } from "./user-activity-history.service";
52
+ import { MetadataValidationService } from "./metadata-validation.service";
52
53
  import { UserService } from "./user.service";
53
54
  import { SmsFactory } from "src/factories/sms.factory";
54
55
  import { WhatsAppFactory } from "src/factories/whatsapp.factory";
@@ -88,6 +89,7 @@ export class AuthenticationService {
88
89
  private readonly roleMetadataService: RoleMetadataService,
89
90
  private readonly userActivityHistoryService: UserActivityHistoryService,
90
91
  private readonly ssoCodeStorage: SsoCodeStorageService,
92
+ private readonly metadataValidationService: MetadataValidationService,
91
93
 
92
94
  @InjectDataSource()
93
95
  private readonly dataSource: DataSource,
@@ -225,6 +227,9 @@ export class AuthenticationService {
225
227
  preferEntityApiKeyFlag: boolean = false,
226
228
  ): Promise<T> {
227
229
  try {
230
+ await this.assertUniqueSignupIdentifiers(signUpDto, repo);
231
+ await this.metadataValidationService.validateCreateDto("user", signUpDto);
232
+
228
233
  const onForcePasswordChange =
229
234
  this.settingService.getConfigValue<SolidCoreSetting>(
230
235
  "forceChangePasswordOnFirstLogin",
@@ -276,6 +281,59 @@ export class AuthenticationService {
276
281
  }
277
282
  }
278
283
 
284
+ private async assertUniqueSignupIdentifiers<T extends User>(
285
+ signUpDto: SignUpDto,
286
+ repo: Repository<T>,
287
+ ): Promise<void> {
288
+ const username = signUpDto.username?.trim();
289
+ const email = signUpDto.email?.trim();
290
+ const mobile = signUpDto.mobile?.trim();
291
+
292
+ const where: FindOptionsWhere<T>[] = [];
293
+
294
+ if (username) {
295
+ where.push({ username } as FindOptionsWhere<T>);
296
+ }
297
+
298
+ if (email) {
299
+ where.push({ email } as FindOptionsWhere<T>);
300
+ }
301
+
302
+ if (mobile) {
303
+ where.push({ mobile } as FindOptionsWhere<T>);
304
+ }
305
+
306
+ if (where.length === 0) {
307
+ return;
308
+ }
309
+
310
+ const existingUser = await repo.findOne({ where });
311
+
312
+ if (!existingUser) {
313
+ return;
314
+ }
315
+
316
+ if (email && existingUser.email === email) {
317
+ throw new ConflictException(
318
+ `A user with email address "${email}" already exists.`,
319
+ );
320
+ }
321
+
322
+ if (mobile && existingUser.mobile === mobile) {
323
+ throw new ConflictException(
324
+ `A user with mobile number "${mobile}" already exists.`,
325
+ );
326
+ }
327
+
328
+ if (username && existingUser.username === username) {
329
+ throw new ConflictException(
330
+ `A user with username "${username}" already exists.`,
331
+ );
332
+ }
333
+
334
+ throw new ConflictException(ERROR_MESSAGES.USER_ALREADY_EXISTS);
335
+ }
336
+
279
337
  private async handlePasswordlessSignupOtp<T extends User>(
280
338
  user: T,
281
339
  signUpDto: SignUpDto,
@@ -400,11 +458,23 @@ export class AuthenticationService {
400
458
  // if forcePasswordChange is true, then we trigger an email to the user to change the password, this needs to be done using a queue.
401
459
  // Create a new method like notifyUserOnForcePasswordChange, create a new email template we can call it on-force-password-change this template to include the random password
402
460
  if (user.forcePasswordChange && autoGeneratedPwd) {
403
- await this.notifyUserOnForcePasswordChange(user, autoGeneratedPwd);
461
+ try {
462
+ await this.notifyUserOnForcePasswordChange(user, autoGeneratedPwd);
463
+ } catch (error: any) {
464
+ this.logger.error(
465
+ `Failed to send force-password-change email for user ${user.id}: ${error?.message ?? error}`,
466
+ );
467
+ }
404
468
  }
405
469
 
406
470
  // Send welcome notifications (email/SMS) if enabled.
407
- await this.notifyUserOnSignup(user);
471
+ try {
472
+ await this.notifyUserOnSignup(user);
473
+ } catch (error: any) {
474
+ this.logger.error(
475
+ `Failed to send signup notifications for user ${user.id}: ${error?.message ?? error}`,
476
+ );
477
+ }
408
478
  }
409
479
 
410
480
  generatePassword(length: number = 8): string {
@@ -1578,7 +1648,7 @@ export class AuthenticationService {
1578
1648
  // Assuming all users do not have mobile as mandatory.
1579
1649
  if (
1580
1650
  forgotPasswordSendVerificationTokenOn ==
1581
- ForgotPasswordSendVerificationTokenOn.MOBILE &&
1651
+ ForgotPasswordSendVerificationTokenOn.MOBILE &&
1582
1652
  user.mobile
1583
1653
  ) {
1584
1654
  const smsService = this.smsFactory.getSmsService();
@@ -1702,7 +1772,7 @@ export class AuthenticationService {
1702
1772
  // Assuming all users do not have mobile as mandatory.
1703
1773
  if (
1704
1774
  forgotPasswordSendVerificationTokenOn ==
1705
- ForgotPasswordSendVerificationTokenOn.MOBILE &&
1775
+ ForgotPasswordSendVerificationTokenOn.MOBILE &&
1706
1776
  user.mobile
1707
1777
  ) {
1708
1778
  const smsService = this.smsFactory.getSmsService();
@@ -1723,7 +1793,13 @@ export class AuthenticationService {
1723
1793
  }
1724
1794
  }
1725
1795
 
1726
- async generateTokens(user: User) {
1796
+ /**
1797
+ * @param deviceId optional stable per-device identifier. Supplied by callers
1798
+ * that own a device credential; otherwise a key is minted per login so that
1799
+ * clients with no device concept (the web UI) still get their own bucket
1800
+ * instead of sharing - and evicting - one.
1801
+ */
1802
+ async generateTokens(user: User, deviceId?: string) {
1727
1803
  const sessionId = this.shouldPreventConcurrentLogins()
1728
1804
  ? randomUUID()
1729
1805
  : undefined;
@@ -1732,9 +1808,17 @@ export class AuthenticationService {
1732
1808
  } else {
1733
1809
  await this.activeSessionStorage.clearActiveSession(user.id);
1734
1810
  }
1811
+
1812
+ // Mutually exclusive with sessionId by construction: per-device buckets
1813
+ // exist only when preventConcurrentLogins is off, sessionId only when it
1814
+ // is on.
1815
+ const deviceKey = this.refreshTokenIdsStorage.areConcurrentLoginsAllowed()
1816
+ ? deviceId ?? randomUUID()
1817
+ : undefined;
1818
+
1735
1819
  const [accessToken, refreshToken] = await Promise.all([
1736
- await this.generateAccessToken(user, sessionId),
1737
- await this.generateRefreshToken(user),
1820
+ await this.generateAccessToken(user, sessionId, deviceKey),
1821
+ await this.generateRefreshToken(user, undefined, deviceKey),
1738
1822
  ]);
1739
1823
 
1740
1824
  return {
@@ -1743,7 +1827,7 @@ export class AuthenticationService {
1743
1827
  };
1744
1828
  }
1745
1829
 
1746
- async generateAccessToken(user: User, sessionId?: string) {
1830
+ async generateAccessToken(user: User, sessionId?: string, deviceKey?: string) {
1747
1831
  // const userRoleNames = user.roles.map((role) => role.name).join(';')
1748
1832
  const userRoleNames = user.roles.map((role) => role.name);
1749
1833
  const resolvedSessionId = this.shouldPreventConcurrentLogins()
@@ -1760,18 +1844,36 @@ export class AuthenticationService {
1760
1844
  email: user.email,
1761
1845
  roles: userRoleNames,
1762
1846
  ...(resolvedSessionId ? { sessionId: resolvedSessionId } : {}),
1847
+ // Carried so that bearer-authenticated endpoints which need this
1848
+ // session's refresh token - generateSsoCode, me - can locate its
1849
+ // bucket. The refresh token is not available to them.
1850
+ ...(deviceKey ? { deviceKey } : {}),
1763
1851
  },
1764
1852
  );
1765
1853
 
1766
1854
  return accessToken;
1767
1855
  }
1768
1856
 
1769
- async generateRefreshToken(user: User, previousRefreshToken?: string) {
1857
+ async generateRefreshToken(
1858
+ user: User,
1859
+ previousRefreshToken?: string,
1860
+ deviceKey?: string,
1861
+ ) {
1770
1862
  const refreshTokenId = randomUUID();
1771
1863
  const refreshTokenTtl =
1772
1864
  this.settingService.getConfigValue<SolidCoreSetting>("refreshTokenTtl");
1865
+
1866
+ // Only per-device tokens carry an epoch - it is what makes bulk
1867
+ // invalidation possible without enumerating buckets. Single-slot tokens
1868
+ // are invalidated by deleting their one key.
1869
+ const epoch = deviceKey
1870
+ ? await this.refreshTokenIdsStorage.getEpoch(user.id)
1871
+ : undefined;
1872
+
1773
1873
  const refreshToken = await this.signToken(user.id, refreshTokenTtl, {
1774
1874
  refreshTokenId,
1875
+ ...(deviceKey ? { deviceKey } : {}),
1876
+ ...(epoch !== undefined ? { epoch } : {}),
1775
1877
  });
1776
1878
 
1777
1879
  // store the refresh token id in the redis storage.
@@ -1779,6 +1881,7 @@ export class AuthenticationService {
1779
1881
  user.id,
1780
1882
  refreshToken,
1781
1883
  previousRefreshToken,
1884
+ deviceKey,
1782
1885
  );
1783
1886
 
1784
1887
  return refreshToken;
@@ -1793,8 +1896,16 @@ export class AuthenticationService {
1793
1896
  const issuer =
1794
1897
  this.settingService.getConfigValue<SolidCoreSetting>("issuer");
1795
1898
 
1796
- const { sub } = await this.jwtService.verifyAsync<
1797
- Pick<ActiveUserData, "sub"> & { refreshTokenId: string }
1899
+ // deviceKey/epoch are absent on tokens issued before per-device sessions,
1900
+ // and on tokens issued while preventConcurrentLogins is on. That absence
1901
+ // is the signal the storage layer branches on - no request-body change
1902
+ // and no client change is needed to carry it.
1903
+ const { sub, deviceKey, epoch } = await this.jwtService.verifyAsync<
1904
+ Pick<ActiveUserData, "sub"> & {
1905
+ refreshTokenId: string;
1906
+ deviceKey?: string;
1907
+ epoch?: number;
1908
+ }
1798
1909
  >(refreshTokenDto.refreshToken, {
1799
1910
  secret,
1800
1911
  audience,
@@ -1822,17 +1933,24 @@ export class AuthenticationService {
1822
1933
  // throw new Error('Refresh token is invalid');
1823
1934
  // }
1824
1935
 
1825
- const currentRefreshToken =
1826
- await this.refreshTokenIdsStorage.validateAndRotate(
1827
- user,
1828
- refreshTokenDto.refreshToken,
1829
- );
1936
+ const rotated = await this.refreshTokenIdsStorage.validateAndRotate(
1937
+ user,
1938
+ refreshTokenDto.refreshToken,
1939
+ { deviceKey, epoch },
1940
+ );
1830
1941
 
1831
1942
  await this.userActivityHistoryService.logEvent("tokenRefreshed", user);
1832
1943
 
1833
1944
  return {
1834
- accessToken: await this.generateAccessToken(user),
1835
- refreshToken: currentRefreshToken,
1945
+ // The rotated key, not the incoming one: a session migrating out of the
1946
+ // pre-deploy single slot is assigned a bucket here, and the new access
1947
+ // token has to name the same one.
1948
+ accessToken: await this.generateAccessToken(
1949
+ user,
1950
+ undefined,
1951
+ rotated.deviceKey,
1952
+ ),
1953
+ refreshToken: rotated.refreshToken,
1836
1954
  };
1837
1955
  } catch (err: any) {
1838
1956
  if (err instanceof InvalidatedRefreshTokenError) {
@@ -2221,28 +2339,31 @@ export class AuthenticationService {
2221
2339
  // // Invalidate the refresh token
2222
2340
  // // await this.refreshTokenIdsStorage.invalidate(user.id);
2223
2341
  // }
2224
- async logout(refreshToken: string) {
2342
+ async logout(refreshToken: string, allDevices = false) {
2225
2343
  try {
2226
- // const activeUser = this.requestContextService.getActiveUser();
2227
- // const userId = activeUser?.sub;
2228
- // const user = await this.userRepository.findOne({
2229
- // where: {
2230
- // id: userId,
2231
- // }
2232
- // })
2233
- // // Invalidate refresh token if you store them
2234
- // await this.refreshTokenIdsStorage.invalidate(userId); // Your existing logic
2235
- // if (!refreshToken) {
2236
- // throw new UnauthorizedException('Refresh token is required');
2237
- // }
2238
- const payload = this.jwtService.decode(refreshToken) as any;
2239
-
2240
- if (!payload || !payload.sub) {
2241
- throw new UnauthorizedException(ERROR_MESSAGES.INVALID_REFRESH_TOKEN);
2344
+ const payload = await this.verifyRefreshTokenForLogout(refreshToken);
2345
+
2346
+ // Nothing verifiable to act on: forged, malformed, or signed with another
2347
+ // secret. Acting on an unauthenticated `sub` is exactly the hole this
2348
+ // closes - the route is @Public(), so a decoded-but-unverified token let
2349
+ // anyone log out an arbitrary user. Report success either way: logout
2350
+ // must be safe to call blindly from a client error path, and a 401/200
2351
+ // split here would leak whether a token string is genuine (RFC 7009 §2.2
2352
+ // takes the same position for revocation endpoints).
2353
+ if (!payload?.sub) {
2354
+ this.logger.warn("logout called with an unverifiable refresh token");
2355
+ return { message: SUCCESS_MESSAGES.LOGOUT_SUCCESS };
2242
2356
  }
2243
2357
 
2244
2358
  const userId = payload.sub;
2245
- await this.refreshTokenIdsStorage.invalidate(userId);
2359
+ if (allDevices) {
2360
+ await this.refreshTokenIdsStorage.invalidateAll(userId);
2361
+ } else {
2362
+ // Scoped to the bucket this token belongs to, so signing out on one
2363
+ // device leaves the others alive. A token with no deviceKey names the
2364
+ // single slot, which is the same key as before.
2365
+ await this.refreshTokenIdsStorage.invalidate(userId, payload.deviceKey);
2366
+ }
2246
2367
  await this.activeSessionStorage.clearActiveSession(userId);
2247
2368
  const user = await this.userRepository.findOne({
2248
2369
  where: {
@@ -2250,10 +2371,15 @@ export class AuthenticationService {
2250
2371
  },
2251
2372
  });
2252
2373
  // Log logout event
2253
- await this.userActivityHistoryService.logEvent("logout", user);
2374
+ if (user) {
2375
+ await this.userActivityHistoryService.logEvent("logout", user);
2376
+ }
2254
2377
 
2255
2378
  return { message: SUCCESS_MESSAGES.LOGOUT_SUCCESS };
2256
2379
  } catch (err: any) {
2380
+ // JWT problems no longer reach here - verifyRefreshTokenForLogout
2381
+ // swallows them - so this is left for genuine infrastructure failures
2382
+ // (cache or database unavailable), where a 500 is the correct answer.
2257
2383
  throw err instanceof UnauthorizedException ||
2258
2384
  err instanceof InternalServerErrorException
2259
2385
  ? err
@@ -2261,6 +2387,31 @@ export class AuthenticationService {
2261
2387
  }
2262
2388
  }
2263
2389
 
2390
+ private async verifyRefreshTokenForLogout(
2391
+ refreshToken: string,
2392
+ ): Promise<{ sub: number; deviceKey?: string } | null> {
2393
+ try {
2394
+ const payload = await this.jwtService.verifyAsync(refreshToken, {
2395
+ secret: this.settingService.getConfigValue<SolidCoreSetting>("secret"),
2396
+ audience:
2397
+ this.settingService.getConfigValue<SolidCoreSetting>("audience"),
2398
+ issuer: this.settingService.getConfigValue<SolidCoreSetting>("issuer"),
2399
+ // Signature, audience and issuer are still enforced; only `exp` is
2400
+ // tolerated. An expired session must still be able to log out - the
2401
+ // previous jwtService.decode() allowed that, and a plain verifyAsync
2402
+ // would throw TokenExpiredError, which the catch above would turn into
2403
+ // a 500 on an ordinary sign-out.
2404
+ ignoreExpiration: true,
2405
+ });
2406
+
2407
+ // Access and refresh tokens share secret, audience and issuer, so only
2408
+ // this claim distinguishes them. Reject an access token presented here.
2409
+ return payload?.refreshTokenId ? payload : null;
2410
+ } catch {
2411
+ return null; // bad signature or malformed
2412
+ }
2413
+ }
2414
+
2264
2415
  async activateUser(userId: number) {
2265
2416
  const user = await this.userService.findOne(userId, {});
2266
2417
  if (!user) {
@@ -2282,9 +2433,14 @@ export class AuthenticationService {
2282
2433
 
2283
2434
  // const tokens = await this.generateTokens(user);
2284
2435
 
2285
- // Get the refresh token for a user from refresh token storage.
2436
+ // Get the refresh token for a user from refresh token storage. The bucket
2437
+ // is named by the access token's own deviceKey claim; absent for
2438
+ // single-slot sessions, which resolves to the same key as before.
2286
2439
  const refreshTokenState =
2287
- await this.refreshTokenIdsStorage.getCurrentRefreshTokenState(user.id);
2440
+ await this.refreshTokenIdsStorage.getCurrentRefreshTokenState(
2441
+ user.id,
2442
+ activeUser.deviceKey,
2443
+ );
2288
2444
 
2289
2445
  const response = {
2290
2446
  user: {
@@ -2295,7 +2451,11 @@ export class AuthenticationService {
2295
2451
  id: user.id,
2296
2452
  roles: user.roles.map((role) => role.name),
2297
2453
  },
2298
- refreshToken: refreshTokenState.currentRefreshToken,
2454
+ // Null-guarded because the cache entry now carries a TTL: once it
2455
+ // expires - or after a logout followed by a call with a still-valid
2456
+ // access token - there is no state to read. Matches the existing
2457
+ // handling in generateSsoCode.
2458
+ refreshToken: refreshTokenState?.currentRefreshToken ?? null,
2299
2459
  // ...tokens
2300
2460
  };
2301
2461
  return response;
@@ -2308,6 +2468,7 @@ export class AuthenticationService {
2308
2468
  const refreshTokenState =
2309
2469
  await this.refreshTokenIdsStorage.getCurrentRefreshTokenState(
2310
2470
  activeUser.sub,
2471
+ activeUser.deviceKey,
2311
2472
  );
2312
2473
  if (!refreshTokenState?.currentRefreshToken) {
2313
2474
  throw new UnauthorizedException("No active session found");
@@ -2342,6 +2503,7 @@ function parseUniqueConstraintError(detail: string): string {
2342
2503
  const fieldMap: Record<string, string> = {
2343
2504
  username: "username",
2344
2505
  email: "email address",
2506
+ mobile: "mobile number",
2345
2507
  full_name_user_key: "full name",
2346
2508
  };
2347
2509
  const friendlyField = fieldMap[field] || field;