@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
@@ -5,8 +5,10 @@ import { InjectEntityManager } from '@nestjs/typeorm';
5
5
  import { Brackets, EntityManager, EntityMetadata, In } from 'typeorm';
6
6
 
7
7
  import { classify } from '@angular-devkit/core/src/utils/strings';
8
- import { CHATTER_MESSAGE_STATUS, CHATTER_MESSAGE_SUBTYPE, CHATTER_MESSAGE_TYPE } from 'src/constants/chatter-message.constants';
8
+ import { CHATTER_MESSAGE_STATUS, CHATTER_MESSAGE_SUBTYPE, CHATTER_MESSAGE_TYPE, CHATTER_MESSAGE_USER_FIELDS } from 'src/constants/chatter-message.constants';
9
+ import { isDangerousMediaFile } from 'src/constants/media-file-types';
9
10
  import { ERROR_MESSAGES } from 'src/constants/error-messages';
11
+ import { MediaFieldCrudManager, SolidMediaType } from 'src/helpers/field-crud-managers/MediaFieldCrudManager';
10
12
  import { PostChatterMessageDto } from 'src/dtos/post-chatter-message.dto';
11
13
  import { UpdateChatterNoteMessageDto } from 'src/dtos/update-chatter-note-message.dto';
12
14
  import { ModelMetadataHelperService } from 'src/helpers/model-metadata-helper.service';
@@ -18,9 +20,11 @@ import { FieldMetadataRepository } from 'src/repository/field-metadata.repositor
18
20
  import { MediaRepository } from 'src/repository/media.repository';
19
21
  import { ModelMetadataRepository } from 'src/repository/model-metadata.repository';
20
22
  import { CRUDService } from 'src/services/crud.service';
23
+ import { BasicFilterDto } from '../dtos/basic-filters.dto';
21
24
  import { MediaStorageProviderType } from '../dtos/create-media-storage-provider-metadata.dto';
22
25
  import { ChatterMessageDetails } from '../entities/chatter-message-details.entity';
23
26
  import { ChatterMessage } from '../entities/chatter-message.entity';
27
+ import { User } from '../entities/user.entity';
24
28
  import { getMediaStorageProvider } from './mediaStorageProviders';
25
29
  import { RequestContextService } from './request-context.service';
26
30
  import { Logger } from '@nestjs/common';
@@ -34,6 +38,16 @@ interface ChatterMention {
34
38
  id?: string | number;
35
39
  }
36
40
 
41
+ /**
42
+ * Server-side-only overrides for `postMessage`. Not part of `PostChatterMessageDto`, so
43
+ * nothing here is settable over HTTP - only in-process callers such as migration or
44
+ * back-fill services can supply it.
45
+ */
46
+ export interface PostChatterMessageOptions {
47
+ /** Backdate the message instead of stamping it with the current time. */
48
+ createdAt?: Date;
49
+ }
50
+
37
51
  @Injectable()
38
52
  export class ChatterMessageService extends CRUDService<ChatterMessage> {
39
53
  private readonly _logger = new Logger(ChatterMessageService.name);
@@ -101,6 +115,44 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
101
115
  chatterMessage.updatedBy = resolvedUserId;
102
116
  }
103
117
 
118
+ /**
119
+ * Reduce a message's hydrated `user` relation to CHATTER_MESSAGE_USER_FIELDS.
120
+ *
121
+ * `getChatterMessages` restricts the columns in the query itself, which is preferable.
122
+ * The generic CRUD paths below build their query from find-options and hand `populate`
123
+ * straight to TypeORM, so they are trimmed after the fact instead. (`createdBy` /
124
+ * `updatedBy` need nothing here - CRUDService.handlePopulateUserIdFields already selects
125
+ * only USER_SUMMARY_FIELDS when a caller populates them.)
126
+ */
127
+ private trimMessageUser<M extends ChatterMessage>(message: M): M {
128
+ if (message?.user) {
129
+ message.user = this.toUserSummary(message.user) as User;
130
+ }
131
+ return message;
132
+ }
133
+
134
+ private trimMessageUsers(messages: ChatterMessage[] | undefined) {
135
+ messages?.forEach(message => this.trimMessageUser(message));
136
+ }
137
+
138
+ /**
139
+ * `GET /chatter-message?populate[]=user` would otherwise be a way around the column
140
+ * allowlist applied by getChatterMessages.
141
+ */
142
+ async find(basicFilterDto: BasicFilterDto, solidRequestContext: any = {}): Promise<any> {
143
+ const result = await super.find(basicFilterDto, solidRequestContext);
144
+ this.trimMessageUsers(result?.records);
145
+ // A grouped find (populateGroup) nests its entities one level deeper.
146
+ for (const groupRecord of result?.groupRecords ?? []) {
147
+ this.trimMessageUsers(groupRecord?.groupData?.records);
148
+ }
149
+ return result;
150
+ }
151
+
152
+ async findOne(id: number, query: any = {}, solidRequestContext: any = {}) {
153
+ return this.trimMessageUser(await super.findOne(id, query, solidRequestContext));
154
+ }
155
+
104
156
  private isEditableCustomNoteMessage(message: ChatterMessage): boolean {
105
157
  if (message.messageType !== CHATTER_MESSAGE_TYPE.CUSTOM) {
106
158
  return false;
@@ -134,6 +186,45 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
134
186
  }, messageBody || '');
135
187
  }
136
188
 
189
+ /**
190
+ * Chatter attachments bypass MediaFieldCrudManager - they go straight to
191
+ * storageProvider.store() - so the shared predicate is applied here directly. The rules
192
+ * themselves live in media-file-types so upload paths can't drift apart.
193
+ */
194
+ private validateChatterMediaFiles(files: Express.Multer.File[] = []) {
195
+ if (Array.isArray(files) && files.some(file => isDangerousMediaFile(file))) {
196
+ throw new BadRequestException('Dangerous file types are not allowed in chatter attachments.');
197
+ }
198
+ }
199
+
200
+ /**
201
+ * Validates newly-uploaded attachments against each declared media field's real config
202
+ * (mediaTypes/mediaMaxSizeKb/mediaAllowedExtensions), grouped by fieldname - the same rules
203
+ * MediaFieldCrudManager already enforces everywhere else. Shared between postMessage and
204
+ * updateCustomNoteMessage so the two entry points can't drift apart; isUpdate is the only
205
+ * thing that differs between them.
206
+ */
207
+ private validateChatterAttachmentsForFields(files: Express.Multer.File[], mediaFields: any[], isUpdate: boolean): void {
208
+ for (const mediaField of mediaFields) {
209
+ const media = files.filter(multerFile => multerFile.fieldname === mediaField.name);
210
+ if (media.length === 0) continue;
211
+
212
+ const validator = new MediaFieldCrudManager({
213
+ type: mediaField.type as SolidMediaType,
214
+ required: mediaField.required,
215
+ fieldName: mediaField.name,
216
+ mediaMaxSizeKb: mediaField.mediaMaxSizeKb,
217
+ mediaTypes: mediaField.mediaTypes,
218
+ mediaAllowedExtensions: mediaField.mediaAllowedExtensions,
219
+ isUpdate,
220
+ });
221
+ const validationErrors = validator.validate({}, media);
222
+ if (validationErrors.length > 0) {
223
+ throw new BadRequestException(validationErrors.map(error => error.error).join(', '));
224
+ }
225
+ }
226
+ }
227
+
137
228
  private async publishChatterMentionNotifications(message: ChatterMessage, model: any) {
138
229
  if (message.messageType !== CHATTER_MESSAGE_TYPE.CUSTOM || message.messageSubType !== CHATTER_MESSAGE_SUBTYPE.NOTE) {
139
230
  return;
@@ -188,6 +279,31 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
188
279
  }
189
280
  }
190
281
 
282
+ // Deliberately bypasses UserRepository's security-rule filtering: the mention picker
283
+ // needs id/username/fullName for any active user regardless of the caller's row-level
284
+ // access to the User model, same as the getChatterMessages one-to-many lookup below.
285
+ async getMentionableUsers(search?: string, limit: number = 8): Promise<Array<{ id: number; username: string; fullName: string }>> {
286
+ const normalizedLimit = Number.isInteger(limit) && limit > 0 && limit <= 50 ? limit : 8;
287
+ const userRepository = this.entityManager.getRepository(User);
288
+
289
+ const qb = userRepository
290
+ .createQueryBuilder('user')
291
+ .select(['user.id', 'user.username', 'user.fullName'])
292
+ .where('user.active = :active', { active: true });
293
+
294
+ const trimmedSearch = (search ?? '').trim();
295
+ if (trimmedSearch) {
296
+ qb.andWhere('(LOWER(user.username) LIKE :search OR LOWER(user.fullName) LIKE :search)', {
297
+ search: `%${trimmedSearch.toLowerCase()}%`,
298
+ });
299
+ }
300
+
301
+ qb.orderBy('user.username', 'ASC').take(normalizedLimit);
302
+
303
+ const users = await qb.getMany();
304
+ return users.map(user => ({ id: user.id, username: user.username, fullName: user.fullName }));
305
+ }
306
+
191
307
  async markCompleted(id: number) {
192
308
  const activeUser = this.requestContextService.getActiveUser();
193
309
  if (!activeUser) {
@@ -240,6 +356,26 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
240
356
  throw new BadRequestException('Message body cannot be empty.');
241
357
  }
242
358
 
359
+ this.validateChatterMediaFiles(files);
360
+
361
+ let chatterModel: any = null;
362
+ let mediaFields: any[] = [];
363
+ if (removeAttachmentIds.length > 0 || hasNewFiles) {
364
+ chatterModel = await this.modelMetadataService.findOneBySingularName('chatterMessage', {
365
+ fields: {
366
+ model: true,
367
+ mediaStorageProvider: true,
368
+ },
369
+ module: true,
370
+ });
371
+
372
+ mediaFields = chatterModel.fields.filter(field => field.type === 'mediaSingle' || field.type === 'mediaMultiple');
373
+
374
+ if (hasNewFiles) {
375
+ this.validateChatterAttachmentsForFields(files, mediaFields, true);
376
+ }
377
+ }
378
+
243
379
  if (hasMessageBody) {
244
380
  message.messageBody = trimmedMessageBody;
245
381
  }
@@ -256,15 +392,6 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
256
392
  const savedMessage = await this.repo.save(message);
257
393
 
258
394
  if (removeAttachmentIds.length > 0 || hasNewFiles) {
259
- const model = await this.modelMetadataService.findOneBySingularName('chatterMessage', {
260
- fields: {
261
- model: true,
262
- mediaStorageProvider: true,
263
- },
264
- module: true,
265
- });
266
-
267
- const mediaFields = model.fields.filter(field => field.type === 'mediaSingle' || field.type === 'mediaMultiple');
268
395
  const attachmentFieldIds = mediaFields.map(field => field.id);
269
396
 
270
397
  if (removeAttachmentIds.length > 0 && attachmentFieldIds.length > 0) {
@@ -272,7 +399,7 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
272
399
  where: {
273
400
  id: In(removeAttachmentIds),
274
401
  entityId: savedMessage.id,
275
- modelMetadata: { id: model.id },
402
+ modelMetadata: { id: chatterModel.id },
276
403
  fieldMetadata: { id: In(attachmentFieldIds) },
277
404
  },
278
405
  relations: {
@@ -306,13 +433,23 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
306
433
 
307
434
  await this.publishChatterMentionNotifications(savedMessage, model);
308
435
 
309
- return savedMessage;
436
+ // The `user` relation was loaded for the ownership check above; don't return all of it.
437
+ return this.trimMessageUser(savedMessage);
310
438
  }
311
439
 
312
- async postMessage(postDto: PostChatterMessageDto, files: Express.Multer.File[] = []) {
440
+ /**
441
+ * Post a chatter message.
442
+ *
443
+ * `options` is deliberately kept out of `PostChatterMessageDto` so it can only be supplied
444
+ * by server-side callers (migrations, back-fills). The controller binds the DTO alone, so
445
+ * an API client has no way to backdate a message.
446
+ */
447
+ async postMessage(postDto: PostChatterMessageDto, files: Express.Multer.File[] = [], options: PostChatterMessageOptions = {}) {
313
448
  const coModelName = lowerFirst(postDto.coModelName);
314
449
  await this.assertRecordAccess(coModelName, postDto.coModelEntityId);
315
450
 
451
+ this.validateChatterMediaFiles(files);
452
+
316
453
  const chatterMessage = new ChatterMessage();
317
454
  chatterMessage.messageType = CHATTER_MESSAGE_TYPE.CUSTOM;
318
455
  chatterMessage.messageSubType = postDto.messageSubType || CHATTER_MESSAGE_SUBTYPE.CUSTOM;
@@ -322,6 +459,10 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
322
459
  chatterMessage.coModelEntityId = postDto.coModelEntityId;
323
460
  chatterMessage.coModelName = coModelName;
324
461
  chatterMessage.modelUserKey = postDto.modelUserKey ?? null;
462
+ // Left unset otherwise, so the @CreateDateColumn default still applies.
463
+ if (options.createdAt) {
464
+ chatterMessage.createdAt = options.createdAt;
465
+ }
325
466
 
326
467
  const model = await this.modelMetadataRepo.findOne({
327
468
  where: { singularName: coModelName },
@@ -331,10 +472,9 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
331
472
 
332
473
  this.stampMessageAuditFields(chatterMessage);
333
474
 
334
- const savedMessage = await this.repo.save(chatterMessage);
335
-
475
+ let mediaFields: any[] = [];
336
476
  if (files && files.length > 0) {
337
- const model = await this.modelMetadataService.findOneBySingularName('chatterMessage', {
477
+ const chatterModel = await this.modelMetadataService.findOneBySingularName('chatterMessage', {
338
478
  fields: {
339
479
  model: true,
340
480
  mediaStorageProvider: true,
@@ -342,8 +482,13 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
342
482
  module: true,
343
483
  });
344
484
 
345
- const mediaFields = model.fields.filter(field => field.type === 'mediaSingle' || field.type === 'mediaMultiple');
485
+ mediaFields = chatterModel.fields.filter(field => field.type === 'mediaSingle' || field.type === 'mediaMultiple');
486
+ this.validateChatterAttachmentsForFields(files, mediaFields, false);
487
+ }
488
+
489
+ const savedMessage = await this.repo.save(chatterMessage);
346
490
 
491
+ if (files && files.length > 0) {
347
492
  for (const mediaField of mediaFields) {
348
493
  const media = files.filter(multerFile => multerFile.fieldname === mediaField.name);
349
494
  if (media.length > 0) {
@@ -891,16 +1036,25 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
891
1036
  qb.where(orConditions.join(' OR '), parameters);
892
1037
  }));
893
1038
 
894
- const relations = ['chatterMessageDetails', 'user'];
1039
+ const relations = ['chatterMessageDetails'];
895
1040
  if (populate && populate.length > 0) {
896
1041
  const normalizedPopulate = this.crudHelperService.normalize(populate);
897
- relations.push(...normalizedPopulate.filter(rel => !relations.includes(rel)));
1042
+ // SECURITY: 'user' is joined below with an explicit column allowlist. A client-supplied
1043
+ // populate[]=user must not be able to turn it back into a full-entity join (the chatter
1044
+ // panel does send exactly that).
1045
+ relations.push(...normalizedPopulate.filter(rel => rel !== 'user' && !relations.includes(rel)));
898
1046
  }
899
1047
 
900
1048
  relations.forEach(relation => {
901
1049
  qb.leftJoinAndSelect(`entity.${relation}`, relation);
902
1050
  });
903
1051
 
1052
+ // Only the author's id and display name leave this endpoint - see CHATTER_MESSAGE_USER_FIELDS.
1053
+ // This join must stay before applyFilters below: it lets filters[user][fullName] reuse this
1054
+ // alias instead of adding a second join of its own.
1055
+ qb.leftJoin('entity.user', 'user');
1056
+ qb.addSelect(CHATTER_MESSAGE_USER_FIELDS.map(field => `user.${field}`));
1057
+
904
1058
  if (filters) {
905
1059
  qb.andWhere(new Brackets(whereQb => {
906
1060
  this.crudHelperService.applyFilters(whereQb, filters, 'entity', qb);
@@ -914,6 +1068,13 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
914
1068
  const [entities, count] = await qb.getManyAndCount();
915
1069
  this.logHeapUsed('getChatterMessages-entitiesLoaded');
916
1070
 
1071
+ // The join above only selects the allowlisted columns, but TypeORM still hydrates the
1072
+ // author with `new User()`, which leaves every initialiser-backed property (active,
1073
+ // forcePasswordChange, ...) sitting on the instance holding its default rather than a
1074
+ // value read from the database. Replace it with a plain object of exactly the
1075
+ // allowlisted keys so the response cannot report fabricated defaults as data.
1076
+ this.trimMessageUsers(entities);
1077
+
917
1078
  // Convert date strings in message details to ISO format for consistent handling on the frontend
918
1079
  const DATE_FIELD_TYPES = ['date', 'datetime', 'time'];
919
1080
  for (const entity of entities) {
@@ -3,9 +3,12 @@ import { BasicFilterDto } from "../dtos/basic-filters.dto";
3
3
  import { classify } from '../helpers/string.helper';
4
4
  import { ActiveUserData } from "src/interfaces/active-user-data.interface";
5
5
  import { SolidRegistry } from "src/helpers/solid-registry";
6
- import { BadRequestException, Logger } from "@nestjs/common";
6
+ import { BadRequestException, Injectable, Logger } from "@nestjs/common";
7
7
  import { ERROR_MESSAGES } from "src/constants/error-messages";
8
8
  import { buildCastToText } from "src/helpers/typeorm-db-helper";
9
+ import { DraftPublishHelperService } from "./draft-publish-helper.service";
10
+ import { InternationalisationHelperService } from "./internationalisation-helper.service";
11
+ import { normalizeObjectKeys } from "./object.utils";
9
12
 
10
13
  export enum FilterCombinator {
11
14
  AND = '$and',
@@ -36,10 +39,14 @@ export interface ResolvedFieldPath {
36
39
  leafIsRelation: boolean;
37
40
  }
38
41
 
42
+ @Injectable()
39
43
  export class CrudHelperService {
44
+ private readonly logger = new Logger(CrudHelperService.name);
45
+
40
46
  constructor(
47
+ private readonly draftPublishHelperService: DraftPublishHelperService,
48
+ private readonly internationalisationHelperService: InternationalisationHelperService,
41
49
  ) { }
42
- private readonly logger = new Logger(CrudHelperService.name);
43
50
 
44
51
  /**
45
52
  * Resolve a user-supplied dotted path (e.g. "customer.name") against real TypeORM metadata.
@@ -163,7 +170,7 @@ export class CrudHelperService {
163
170
  }
164
171
 
165
172
  applyFilters(qb: WhereExpressionBuilder, filters: any, alias: string = 'entity', selectQb: SelectQueryBuilder<any>) {
166
- const normalizedFilters = this.normalizeObjectKeys(filters);
173
+ const normalizedFilters = normalizeObjectKeys(filters);
167
174
  if (normalizedFilters.$and) {
168
175
  normalizedFilters.$and.forEach((andFilter: any) => {
169
176
  qb.andWhere(
@@ -182,7 +189,7 @@ export class CrudHelperService {
182
189
  // For individual conditions
183
190
  Object.keys(normalizedFilters).forEach(key => {
184
191
  const primaryFilterObj = normalizedFilters[key];
185
- const normalizedPrimaryFilterObj = this.normalizeObjectKeys(primaryFilterObj);
192
+ const normalizedPrimaryFilterObj = normalizeObjectKeys(primaryFilterObj);
186
193
 
187
194
  const [rawField, funcAlias] = key.split(':');
188
195
 
@@ -312,17 +319,6 @@ export class CrudHelperService {
312
319
  }
313
320
  }
314
321
 
315
- // Normalize the primary operator object by removing the surrounding brackets in the keys e.g [$eq] => $eq
316
- private normalizeObjectKeys(obj: any): any {
317
- return Object.keys(obj).reduce((acc, key) => {
318
- // Transform the key by removing surrounding brackets
319
- const newKey = key.replace(/^\[(.*)\]$/, '$1');
320
- // Assign the value to the transformed key in the accumulator object
321
- acc[newKey] = obj[key];
322
- return acc;
323
- }, {});
324
- }
325
-
326
322
  normalize(value: string | string[]): string[] {
327
323
  if (!value) return []; // if the value is nullish, then return an empty array
328
324
  return Array.isArray(value) ? value : [value]; // if the value is an array, return it as is, otherwise return it as an array
@@ -359,7 +355,7 @@ export class CrudHelperService {
359
355
  applySorting: boolean = true
360
356
  ): SelectQueryBuilder<any> { // TODO : Check how to pass a type to SelectQueryBuilder instead of any
361
357
  let { limit, offset, showSoftDeleted, filters } = basicFilterDto;
362
- const { fields, sort, populate = [], populateMedia = [], locale, status } = basicFilterDto;
358
+ const { fields, sort, populate = [], populateMedia = [], locale } = basicFilterDto;
363
359
 
364
360
  // Normalize the fields, sort, groupBy and populate options i.e (since they can be either a string or an array of strings, when coming from the request)
365
361
  const normalizedFields = this.normalize(fields);
@@ -390,28 +386,14 @@ export class CrudHelperService {
390
386
  }
391
387
  }
392
388
 
393
- let finalLocale = locale
394
389
  if (internationalisation) {
395
- // If locale is not provided in the filter dto, then assume it is the default locale to be used.
396
- if (!finalLocale) {
397
- //Get default locale from registry
398
- const solidRegistry = moduleRef.get(SolidRegistry, { strict: false });
399
- const defaultLocale = solidRegistry.getDefaultLocale();
400
- if(defaultLocale){
401
- finalLocale = defaultLocale.locale;
402
- }else{
403
- finalLocale = 'en';
404
- }
405
- }
390
+ // If locale is not provided in the filter dto, then assume it is the default locale to be used.
391
+ const finalLocale = locale || this.internationalisationHelperService.resolveDefaultLocaleName(moduleRef.get(SolidRegistry, { strict: false }));
406
392
  qb.andWhere(`${entityAlias}.localeName = :locale`, { locale: finalLocale });
407
393
  }
408
394
 
409
- if (draftPublishWorkflow && status) {
410
- if (basicFilterDto.status === 'published') {
411
- qb.andWhere(`${entityAlias}.publishedAt IS NOT NULL`);
412
- } else if (basicFilterDto.status === 'draft') {
413
- qb.andWhere(`${entityAlias}.publishedAt IS NULL`);
414
- }
395
+ if (draftPublishWorkflow) {
396
+ this.draftPublishHelperService.applyDraftPublishFilterDefaults(qb, filters, entityAlias);
415
397
  }
416
398
  // Depending upon the select option, apply the select clause
417
399
  if (normalizedFields && normalizedFields.length) {
@@ -907,25 +889,25 @@ export class CrudHelperService {
907
889
  };
908
890
  }
909
891
 
910
- async countGroupedRecords(qb: SelectQueryBuilder<any>, basicFilterDto: BasicFilterDto, entityAlias: string) { //TODO : Check how to pass a type to SelectQueryBuilder instead of any
911
- const { limit, offset, ...rest } = basicFilterDto;
912
- const filteredDto = { ...rest, limit: undefined, offset: undefined };
892
+ // async countGroupedRecords(qb: SelectQueryBuilder<any>, basicFilterDto: BasicFilterDto, entityAlias: string, internationalisation?: boolean, draftPublishWorkflow?: boolean, moduleRef?: any) { //TODO : Check how to pass a type to SelectQueryBuilder instead of any
893
+ // const { limit, offset, ...rest } = basicFilterDto;
894
+ // const filteredDto = { ...rest, limit: undefined, offset: undefined };
913
895
 
914
- const filteredQB = this.buildFilterQuery(qb, filteredDto as BasicFilterDto, entityAlias, undefined, undefined, undefined, FilterCombinator.AND, false, false);
896
+ // const filteredQB = this.buildFilterQuery(qb, filteredDto as BasicFilterDto, entityAlias, internationalisation, draftPublishWorkflow, moduleRef, FilterCombinator.AND, false, false);
915
897
 
916
- const groupByFields = this.normalize(filteredDto.groupBy);
898
+ // const groupByFields = this.normalize(filteredDto.groupBy);
917
899
 
918
- if (!groupByFields || groupByFields.length === 0) {
919
- throw new Error(ERROR_MESSAGES.INVALID_GROUP_BY_COUNT);
920
- }
900
+ // if (!groupByFields || groupByFields.length === 0) {
901
+ // throw new Error(ERROR_MESSAGES.INVALID_GROUP_BY_COUNT);
902
+ // }
921
903
 
922
- this.applyGroupBySelections(filteredQB, groupByFields, entityAlias);
923
- this.applyAggregates(filteredQB, ['count'], entityAlias);
924
- filteredQB.limit(undefined).offset(undefined).take(undefined).skip(undefined);
904
+ // this.applyGroupBySelections(filteredQB, groupByFields, entityAlias);
905
+ // this.applyAggregates(filteredQB, ['count'], entityAlias);
906
+ // filteredQB.limit(undefined).offset(undefined).take(undefined).skip(undefined);
925
907
 
926
- const rawResults = await filteredQB.getRawMany();
927
- return rawResults.length;
928
- }
908
+ // const rawResults = await filteredQB.getRawMany();
909
+ // return rawResults.length;
910
+ // }
929
911
 
930
912
  hasReadPermissionOnModel = (activeUser: ActiveUserData, modelName: string) => {
931
913
  const permissionNames = [`${classify(modelName)}Controller.findOne`, `${classify(modelName)}Controller.findMany`];
@@ -998,7 +980,10 @@ export class CrudHelperService {
998
980
  basicFilterDto: BasicFilterDto,
999
981
  alias: string,
1000
982
  createQbFn: () => Promise<SelectQueryBuilder<T>>,
1001
- postProcessEntities?: (entities: T[]) => Promise<void>
983
+ postProcessEntities?: (entities: T[]) => Promise<void>,
984
+ internationalisation?: boolean,
985
+ draftPublishWorkflow?: boolean,
986
+ moduleRef?: any
1002
987
  ): Promise<{ meta: { totalRecords: number }; groupMeta: any[]; groupRecords: any[] }> {
1003
988
  const groupByFields = this.normalize(basicFilterDto.groupBy);
1004
989
  if (!groupByFields.length) throw new BadRequestException(ERROR_MESSAGES.INVALID_GROUP_BY_COUNT);
@@ -1033,7 +1018,7 @@ export class CrudHelperService {
1033
1018
  aggregates: undefined,
1034
1019
  sort: basicFilterDto.groupFilter?.sort,
1035
1020
  };
1036
- groupQb = this.buildFilterQuery(groupQb, groupFilterDto, alias);
1021
+ groupQb = this.buildFilterQuery(groupQb, groupFilterDto, alias, internationalisation, draftPublishWorkflow, moduleRef);
1037
1022
  groupQb = this.buildGroupByRecordsQuery(groupQb, group, alias, groupAliasMap, aggregateAliasMap, groupExpressionMap);
1038
1023
  const [entities, count] = await groupQb.getManyAndCount();
1039
1024
  if (postProcessEntities) await postProcessEntities(entities);