@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
@@ -1,5 +1,5 @@
1
1
  import { FieldCrudManager, ValidationError } from "src/interfaces";
2
- import { DANGEROUS_EXTENSIONS, EXT_TO_MEDIA_TYPE, MediaCategory } from "src/constants/media-file-types";
2
+ import { EXT_TO_MEDIA_TYPE, getLowercaseFileExtension, getUploadedFileName, isDangerousMediaFile, MediaCategory } from "src/constants/media-file-types";
3
3
 
4
4
  export enum SolidMediaType {
5
5
  mediaSingle = 'mediaSingle',
@@ -12,6 +12,7 @@ export interface MediaFieldOptions {
12
12
  fieldName: string | undefined | null;
13
13
  mediaMaxSizeKb: number | undefined | null;
14
14
  mediaTypes: string[];
15
+ mediaAllowedExtensions?: string[] | null;
15
16
  isUpdate: boolean | undefined | null;
16
17
  }
17
18
 
@@ -79,32 +80,35 @@ export class MediaFieldCrudManager implements FieldCrudManager {
79
80
  constructor(private readonly options: MediaFieldOptions) {
80
81
  }
81
82
 
82
- private resolveMediaType(mimetype?: string, filename?: string): MediaType | null {
83
- const ext = (filename || '').split('.').pop()?.toLowerCase();
84
- if (ext && DANGEROUS_EXTENSIONS.has(ext)) {
83
+ private resolveMediaType(file: Express.Multer.File): MediaType | null {
84
+ // Belt-and-braces: dangerous files are already rejected outright by
85
+ // validateDangerousFiles, but never let one resolve to a usable category.
86
+ if (isDangerousMediaFile(file)) {
85
87
  return null;
86
88
  }
87
89
 
88
- const mt = (mimetype || '').toLowerCase().trim();
89
- if (mt === 'image/svg+xml' || mt === 'text/html' || mt === 'application/xhtml+xml') {
90
+ // Extension is authoritative: a declared mimetype is fully attacker-controlled and
91
+ // proved insufficient on its own (a .msi uploaded as image/png previously resolved to
92
+ // 'image', since the mimetype match short-circuited before the extension was ever
93
+ // checked). The extension must independently resolve to a known-safe category before
94
+ // anything is accepted - not merely "not on the denylist".
95
+ const ext = getLowercaseFileExtension(getUploadedFileName(file));
96
+ const extType = ext ? EXT_TO_MEDIA_TYPE[ext] : undefined;
97
+ if (!extType) {
90
98
  return null;
91
99
  }
92
- if (mt && MIME_TO_MEDIA_TYPE[mt]) {
93
- return MIME_TO_MEDIA_TYPE[mt];
94
- }
95
-
96
- // Some libs may send "image/*" etc. Treat broad families safely.
97
- if (mt.startsWith('image/')) return 'image';
98
- if (mt.startsWith('audio/')) return 'audio';
99
- if (mt.startsWith('video/')) return 'video';
100
100
 
101
- // Fallback to extension if provided (also covers generic/unrecognized
102
- // mimetypes such as application/octet-stream).
103
- if (ext && EXT_TO_MEDIA_TYPE[ext]) {
104
- return EXT_TO_MEDIA_TYPE[ext];
101
+ // The mimetype may only confirm or veto what the extension already established, never
102
+ // grant a category on its own. A mimetype that doesn't resolve to anything (e.g.
103
+ // application/octet-stream) has no opinion and is treated as agreeing.
104
+ const mt = (file.mimetype || '').toLowerCase().trim();
105
+ const mimeType = MIME_TO_MEDIA_TYPE[mt]
106
+ ?? (mt.startsWith('image/') ? 'image' : mt.startsWith('audio/') ? 'audio' : mt.startsWith('video/') ? 'video' : undefined);
107
+ if (mimeType && mimeType !== extType) {
108
+ return null;
105
109
  }
106
110
 
107
- return null;
111
+ return extType;
108
112
  }
109
113
 
110
114
  validate(dto: any, files: Array<Express.Multer.File>): ValidationError[] {
@@ -113,17 +117,42 @@ export class MediaFieldCrudManager implements FieldCrudManager {
113
117
  }
114
118
 
115
119
  private applyValidations(fieldFiles: Array<Express.Multer.File>): ValidationError[] {
120
+ // A dangerous upload is never acceptable, regardless of admin config, so this is the
121
+ // only check that sits outside validateCommon() and can't be skipped either way below.
122
+ const dangerousFileErrors = this.validateDangerousFiles(fieldFiles);
123
+
116
124
  switch (this.options.type) {
117
125
  case SolidMediaType.mediaSingle:
118
- return this.validateMediaSingle(fieldFiles);
126
+ return [...dangerousFileErrors, ...this.validateMediaSingle(fieldFiles)];
119
127
  case SolidMediaType.mediaMultiple:
120
- return this.validateMediaMultiple(fieldFiles);
128
+ return [...dangerousFileErrors, ...this.validateMediaMultiple(fieldFiles)];
121
129
  default:
122
- return [];
130
+ return dangerousFileErrors;
123
131
  }
124
132
  }
125
133
 
126
- private validateMediaSingle(fieldFiles: Array<Express.Multer.File>): ValidationError[] {
134
+ private validateDangerousFiles(fieldFiles: Array<Express.Multer.File>): ValidationError[] {
135
+ return fieldFiles
136
+ .filter(fieldFile => isDangerousMediaFile(fieldFile))
137
+ .map(fieldFile => ({
138
+ field: this.options.fieldName,
139
+ error: `${this.options.fieldName} file type not allowed. ` +
140
+ `${getUploadedFileName(fieldFile) || 'File'} is a potentially dangerous file type.`
141
+ }));
142
+ }
143
+
144
+ // Every optional, admin-configured, per-field check - no-ops when its setting is unset -
145
+ // shared between mediaSingle and mediaMultiple so neither can drift out of sync with it.
146
+ private validateCommon(fieldFiles: Array<Express.Multer.File>): ValidationError[] {
147
+ return [
148
+ ...this.validateRequired(fieldFiles),
149
+ ...this.validateSize(fieldFiles),
150
+ ...this.validateTypes(fieldFiles),
151
+ ...this.validateAllowedExtensions(fieldFiles),
152
+ ];
153
+ }
154
+
155
+ private validateRequired(fieldFiles: Array<Express.Multer.File>): ValidationError[] {
127
156
  const errors: ValidationError[] = [];
128
157
  if (!this.options.isUpdate && this.options.required && fieldFiles.length === 0) {
129
158
  errors.push({
@@ -131,13 +160,11 @@ export class MediaFieldCrudManager implements FieldCrudManager {
131
160
  error: `${this.options.fieldName} is required`
132
161
  });
133
162
  }
134
- if (fieldFiles.length > 1) {
135
- errors.push({
136
- field: this.options.fieldName,
137
- error: `${this.options.fieldName} must be a single file`
138
- });
139
- }
140
- // validate size
163
+ return errors;
164
+ }
165
+
166
+ private validateSize(fieldFiles: Array<Express.Multer.File>): ValidationError[] {
167
+ const errors: ValidationError[] = [];
141
168
  if (this.options.mediaMaxSizeKb) {
142
169
  for (let i = 0; i < fieldFiles.length; i++) {
143
170
  const fieldFile = fieldFiles[i];
@@ -150,14 +177,18 @@ export class MediaFieldCrudManager implements FieldCrudManager {
150
177
  }
151
178
  }
152
179
  }
153
- // validate type
180
+ return errors;
181
+ }
182
+
183
+ private validateTypes(fieldFiles: Array<Express.Multer.File>): ValidationError[] {
184
+ const errors: ValidationError[] = [];
154
185
  if (this.options.mediaTypes && this.options.mediaTypes.length > 0) {
155
186
  const allowedFileTypes = this.options.mediaTypes as MediaType[];
156
187
 
157
188
  for (let i = 0; i < fieldFiles.length; i++) {
158
189
  const fieldFile = fieldFiles[i];
159
190
 
160
- const resolvedType = this.resolveMediaType(fieldFile.mimetype, fieldFile.originalname ?? fieldFile.filename ?? '');
191
+ const resolvedType = this.resolveMediaType(fieldFile);
161
192
  if (!resolvedType || !allowedFileTypes.includes(resolvedType)) {
162
193
  errors.push({
163
194
  field: this.options.fieldName,
@@ -168,21 +199,43 @@ export class MediaFieldCrudManager implements FieldCrudManager {
168
199
  }
169
200
  }
170
201
  }
171
-
172
202
  return errors;
173
203
  }
174
204
 
175
- private validateMediaMultiple(fieldFiles: Array<Express.Multer.File>): ValidationError[] {
176
- const errors: ValidationError[] = [];
177
- if (!this.options.isUpdate && this.options.required && fieldFiles.length === 0) {
205
+ private validateAllowedExtensions(fieldFiles: Array<Express.Multer.File>): ValidationError[] {
206
+ const allowed = this.options.mediaAllowedExtensions;
207
+ if (!allowed || allowed.length === 0) {
208
+ return [];
209
+ }
210
+
211
+ const normalizedAllowed = new Set(allowed.map(ext => ext.toLowerCase().replace(/^\./, '')));
212
+ return fieldFiles
213
+ .filter(fieldFile => {
214
+ const ext = getLowercaseFileExtension(getUploadedFileName(fieldFile));
215
+ return !ext || !normalizedAllowed.has(ext);
216
+ })
217
+ .map(fieldFile => ({
218
+ field: this.options.fieldName,
219
+ error: `${this.options.fieldName} file type not allowed. ` +
220
+ `Allowed extensions: ${[...normalizedAllowed].join(', ')}.`
221
+ }));
222
+ }
223
+
224
+ private validateMediaSingle(fieldFiles: Array<Express.Multer.File>): ValidationError[] {
225
+ const errors = this.validateCommon(fieldFiles);
226
+ if (fieldFiles.length > 1) {
178
227
  errors.push({
179
228
  field: this.options.fieldName,
180
- error: `${this.options.fieldName} is required`
229
+ error: `${this.options.fieldName} must be a single file`
181
230
  });
182
231
  }
183
232
  return errors;
184
233
  }
185
234
 
235
+ private validateMediaMultiple(fieldFiles: Array<Express.Multer.File>): ValidationError[] {
236
+ return this.validateCommon(fieldFiles);
237
+ }
238
+
186
239
  transformForCreate(dto: any): any {
187
240
  return dto;
188
241
  }
@@ -0,0 +1,45 @@
1
+ import type { Response } from "express";
2
+
3
+ export interface FileDownloadHeaderOptions {
4
+ fileName: string;
5
+ mimeType: string;
6
+ /** Defaults to 'attachment'; only pass 'inline' for types known safe to render. */
7
+ disposition?: "inline" | "attachment";
8
+ /** Opt in for assets loaded cross-origin by the UI (e.g. media served to :3000). */
9
+ crossOriginResourcePolicy?: boolean;
10
+ }
11
+
12
+ /**
13
+ * Builds an RFC 6266 Content-Disposition value. The file name is attacker-controlled (it comes
14
+ * from the uploaded originalFileName), so it can't be interpolated raw: a quote would close the
15
+ * quoted-string early and let the rest of the name forge further header parameters. The ASCII
16
+ * fallback is stripped to a safe subset and the real name is carried in the RFC 5987
17
+ * `filename*` parameter, which is also what preserves non-ASCII names correctly.
18
+ */
19
+ function buildContentDisposition(disposition: "inline" | "attachment", fileName: string): string {
20
+ const name = (fileName || "file").replace(/[\r\n]/g, "");
21
+ const asciiFallback = name.replace(/[^\x20-\x7E]/g, "_").replace(/["\\]/g, "_") || "file";
22
+
23
+ return `${disposition}; filename="${asciiFallback}"; filename*=UTF-8''${encodeURIComponent(name)}`;
24
+ }
25
+
26
+ /**
27
+ * Single place that stamps the response headers for every streamed file download, so the
28
+ * security headers can't be applied to one endpoint and forgotten on the next.
29
+ */
30
+ export function setFileDownloadHeaders(res: Response, options: FileDownloadHeaderOptions): void {
31
+ const disposition = options.disposition ?? "attachment";
32
+
33
+ res.setHeader("Content-Disposition", buildContentDisposition(disposition, options.fileName));
34
+ res.setHeader("Content-Type", options.mimeType);
35
+ res.setHeader("Access-Control-Expose-Headers", "Content-Disposition, Content-Type");
36
+
37
+ // Prevent the browser from ever content-sniffing a served file into something more
38
+ // dangerous than its declared Content-Type (e.g. rendering a mislabeled upload as HTML
39
+ // and executing embedded script).
40
+ res.setHeader("X-Content-Type-Options", "nosniff");
41
+
42
+ if (options.crossOriginResourcePolicy) {
43
+ res.setHeader("Cross-Origin-Resource-Policy", "cross-origin");
44
+ }
45
+ }
@@ -2,6 +2,7 @@
2
2
 
3
3
  import { forwardRef, Inject, Injectable, Logger } from "@nestjs/common";
4
4
  import { _ } from "lodash";
5
+ import { DRAFT_PUBLISH_VERSIONING_FIELD_NAMES } from "src/constants/draft-publish-fields";
5
6
  import { LEGACY_TABLE_FIELDS_PREFIX } from "src/entities/legacy-common.entity-with-existing-id.entity";
6
7
  import { LegacyTableType } from "src/enums/legacy-table-type.enum";
7
8
  import { ModelMetadataRepository } from "src/repository/model-metadata.repository";
@@ -87,6 +88,32 @@ export class ModelMetadataHelperService {
87
88
  isSystem: true,
88
89
  enableAuditTracking:true
89
90
  },
91
+ {
92
+ name: "isPublished",
93
+ displayName: "Is Published",
94
+ type: "boolean",
95
+ isSystem: true,
96
+ enableAuditTracking: true
97
+ },
98
+ {
99
+ name: "isLatest",
100
+ displayName: "Is Latest",
101
+ type: "boolean",
102
+ isSystem: true,
103
+ enableAuditTracking: true
104
+ },
105
+ {
106
+ name: "initialEntityVersionId",
107
+ displayName: "Initial Entity Version Id",
108
+ type: "int",
109
+ isSystem: true,
110
+ },
111
+ {
112
+ name: "publishedTracker",
113
+ displayName: "Published Tracker",
114
+ type: "shortText",
115
+ isSystem: true,
116
+ },
90
117
  {
91
118
  name: "localeName",
92
119
  displayName: "Locale",
@@ -117,7 +144,11 @@ export class ModelMetadataHelperService {
117
144
  }
118
145
 
119
146
  private getSystemFieldsMetadataMappingForLegacyTable(withId: boolean=true) {
120
- const systemFieldsMetadata = this.getSystemFieldsMetadataMapping();
147
+ // Legacy tables don't have the draft/publish versioning columns, so exclude
148
+ // them from the legacy system fields metadata mapping.
149
+ const legacyExcludedFieldNames: readonly string[] = DRAFT_PUBLISH_VERSIONING_FIELD_NAMES;
150
+ const systemFieldsMetadata = this.getSystemFieldsMetadataMapping()
151
+ .filter(field => !legacyExcludedFieldNames.includes(field.name));
121
152
  if (!withId) {
122
153
  // Remove the id field metadata
123
154
  const index = systemFieldsMetadata.findIndex(field => field.name === 'id');
@@ -1,15 +1,39 @@
1
1
  import { HelmetOptions } from "helmet";
2
2
  import { Environment } from "src/decorators/disallow-in-production.decorator";
3
3
 
4
+ export interface SolidSecurityOptions {
5
+ /**
6
+ * Origins that may embed this application in an iframe.
7
+ * Defaults to the local HTTP/HTTPS loopback origins on any port.
8
+ */
9
+ frameAncestors?: string[];
10
+ }
11
+
12
+ export const DEFAULT_FRAME_ANCESTORS = [
13
+ "'self'",
14
+ "http://localhost:*",
15
+ "https://localhost:*",
16
+ "http://127.0.0.1:*",
17
+ "https://127.0.0.1:*",
18
+ "http://[::1]:*",
19
+ "https://[::1]:*",
20
+ ];
21
+
4
22
  /**
5
23
  * Default security headers for SolidX apps.
6
24
  * - HSTS only in prod over HTTPS
7
- * - CSP with frame-ancestors 'none' (prevents clickjacking)
8
- * - X-Frame-Options: DENY (legacy fallback)
25
+ * - CSP with configurable frame-ancestors
26
+ * - X-Frame-Options disabled when cross-origin frame ancestors are allowed
9
27
  * - No X-XSS-Protection (deprecated)
10
28
  */
11
- export function buildDefaultSecurityHeaderOptions(): Readonly<HelmetOptions> {
29
+ export function buildDefaultSecurityHeaderOptions(
30
+ options: SolidSecurityOptions = {},
31
+ ): Readonly<HelmetOptions> {
12
32
  const isProd = process.env.ENV === Environment.Production;
33
+ const frameAncestors = options.frameAncestors ?? DEFAULT_FRAME_ANCESTORS;
34
+ const allowsCrossOriginFrames = frameAncestors.some(
35
+ (source) => source !== "'self'" && source !== "'none'",
36
+ );
13
37
 
14
38
  return {
15
39
  // Modern CSP. Add more directives as your app needs (script-src, connect-src, etc.)
@@ -23,7 +47,7 @@ export function buildDefaultSecurityHeaderOptions(): Readonly<HelmetOptions> {
23
47
  // "form-action": ["'self'"],
24
48
 
25
49
  // clickjacking defense (modern)
26
- "frame-ancestors": ["'none'"],
50
+ "frame-ancestors": frameAncestors,
27
51
  "style-src": ["'self'"],
28
52
  // add/adjust as needed for your app:
29
53
  // "script-src": ["'self'"], // add hashes/nonces/CSPRO if needed
@@ -34,9 +58,12 @@ export function buildDefaultSecurityHeaderOptions(): Readonly<HelmetOptions> {
34
58
  },
35
59
  },
36
60
 
37
-
38
- // Legacy clickjacking defense (kept for older UAs)
39
- frameguard: { action: "deny" },
61
+ // Legacy clickjacking defense for configurations that do not allow
62
+ // cross-origin parents (kept for older UAs).
63
+ // X-Frame-Options cannot express an allowlist. It must be omitted when
64
+ // CSP allows a parent on another origin, otherwise older browsers may
65
+ // still block the iframe despite the CSP configuration.
66
+ frameguard: allowsCrossOriginFrames ? false : { action: "deny" },
40
67
 
41
68
  // Referrer/cross-origin policies
42
69
  referrerPolicy: { policy: "strict-origin-when-cross-origin" },
@@ -115,4 +142,4 @@ export function setDefaultCacheControl() {
115
142
  // res.setHeader("Permissions-Policy", buildPermissionsPolicyHeader());
116
143
  // next();
117
144
  // });
118
- // app.use(setDefaultCacheControl());
145
+ // app.use(setDefaultCacheControl());
@@ -32,6 +32,59 @@ export class SolidCoreErrorCodesProvider implements IErrorCodeProvider {
32
32
  httpStatus: 401,
33
33
  },
34
34
  },
35
+ // MPIN rules sit above the generic session rules so that an MPIN
36
+ // failure is never reported as a session problem. The three codes
37
+ // drive three different client behaviours: retry, wait, and
38
+ // discard-the-handle.
39
+ {
40
+ code: 'solidx-mpin-locked',
41
+ priority: 120,
42
+ match: (txt) => txt.includes(ERROR_MESSAGES.MPIN_LOCKED.toLowerCase()),
43
+ meta: {
44
+ message: ERROR_MESSAGES.MPIN_LOCKED,
45
+ httpStatus: 401,
46
+ },
47
+ },
48
+ {
49
+ code: 'solidx-mpin-revoked',
50
+ priority: 120,
51
+ match: (txt) => txt.includes(ERROR_MESSAGES.MPIN_REVOKED.toLowerCase()),
52
+ meta: {
53
+ message: ERROR_MESSAGES.MPIN_REVOKED,
54
+ httpStatus: 401,
55
+ },
56
+ },
57
+ {
58
+ code: 'solidx-mpin-invalid',
59
+ priority: 120,
60
+ match: (txt) => txt.includes(ERROR_MESSAGES.MPIN_INVALID.toLowerCase()),
61
+ meta: {
62
+ message: ERROR_MESSAGES.MPIN_INVALID,
63
+ httpStatus: 401,
64
+ },
65
+ },
66
+ // Setup-time rejections. Distinct codes so the client can say
67
+ // "choose a less predictable PIN" rather than parsing a message.
68
+ // Safe to distinguish: both occur only on bearer-authenticated
69
+ // routes, so neither discloses anything.
70
+ {
71
+ code: 'solidx-mpin-too-predictable',
72
+ priority: 120,
73
+ match: (txt) => txt.includes(ERROR_MESSAGES.MPIN_TOO_PREDICTABLE.toLowerCase()),
74
+ meta: {
75
+ message: ERROR_MESSAGES.MPIN_TOO_PREDICTABLE,
76
+ httpStatus: 400,
77
+ },
78
+ },
79
+ {
80
+ code: 'solidx-mpin-format-invalid',
81
+ priority: 120,
82
+ match: (txt) => txt.includes(ERROR_MESSAGES.MPIN_FORMAT_INVALID.toLowerCase()),
83
+ meta: {
84
+ message: ERROR_MESSAGES.MPIN_FORMAT_INVALID,
85
+ httpStatus: 400,
86
+ },
87
+ },
35
88
  {
36
89
  code: 'solidx-mcp-server-unavailable',
37
90
  priority: 100,
@@ -79,7 +79,12 @@ export class SolidMicroserviceAdapter {
79
79
  const responseData = response.data as SolidxIamAuthResponse;
80
80
  const ttlSeconds = this.getJwtTtlSeconds(responseData?.data?.accessToken);
81
81
  if (ttlSeconds && ttlSeconds > 0) {
82
- await this.cacheManager.set(cacheKey, responseData, ttlSeconds);
82
+ // cache-manager v5 expects milliseconds. This previously passed seconds,
83
+ // which the old Redis store discarded outright - so the entry simply
84
+ // never expired. Now that TTLs are honoured, passing seconds unconverted
85
+ // would expire the cached token ~1000x too early and re-authenticate
86
+ // against IAM on nearly every call.
87
+ await this.cacheManager.set(cacheKey, responseData, ttlSeconds * 1000);
83
88
  }
84
89
 
85
90
  return responseData;
@@ -366,7 +366,7 @@ export class SolidRegistry {
366
366
  }
367
367
 
368
368
  getCommonEntityKeys(): (keyof CommonEntity | 'createdBy' | 'updatedBy')[] {
369
- return ['id', 'createdAt', 'updatedAt', 'deletedAt', 'createdBy', 'updatedBy', 'deletedTracker', 'localeName', 'defaultEntityLocaleId', 'publishedAt'];
369
+ return ['id', 'createdAt', 'updatedAt', 'deletedAt', 'createdBy', 'updatedBy', 'deletedTracker', 'localeName', 'defaultEntityLocaleId', 'publishedAt', 'isPublished', 'isLatest', 'initialEntityVersionId', 'publishedTracker'];
370
370
  // return Reflect.getMetadataKeys(CommonEntity.prototype) as (keyof CommonEntity)[];
371
371
  }
372
372
 
@@ -40,6 +40,14 @@ const DECIMAL_MAP: Record<DatasourceType, ColumnOptions> = {
40
40
  [DatasourceType.oracle]: { type: "float" },
41
41
  };
42
42
 
43
+ const DATE_TIME_MAP: Record<DatasourceType, ColumnOptions> = {
44
+ [DatasourceType.postgres]: { type: "timestamp" },
45
+ [DatasourceType.mssql]: { type: "datetime2" },
46
+ [DatasourceType.mysql]: { type: "datetime" },
47
+ [DatasourceType.mariadb]: { type: "datetime" },
48
+ [DatasourceType.oracle]: { type: "timestamp" },
49
+ };
50
+
43
51
  const solidCoreDbType: DatasourceType =
44
52
  Object.values(DatasourceType).includes(process.env.SOLID_CORE_DB_TYPE as DatasourceType)
45
53
  ? (process.env.SOLID_CORE_DB_TYPE as DatasourceType)
@@ -72,7 +80,10 @@ export function getColumnType(solidType: string): ColumnOptions {
72
80
  case "decimal":
73
81
  return DECIMAL_MAP[solidCoreDbType];
74
82
 
83
+ case "datetime":
84
+ return DATE_TIME_MAP[solidCoreDbType];
85
+
75
86
  default:
76
87
  return {};
77
88
  }
78
- }
89
+ }
package/src/index.ts CHANGED
@@ -160,6 +160,12 @@ export * from './entities/role-metadata.entity'
160
160
  export * from './entities/sms-template.entity'
161
161
  export * from './entities/user.entity'
162
162
  export * from './entities/user-api-key.entity'
163
+ export * from './entities/user-device-credential.entity'
164
+ export * from './repository/user-device-credential.repository'
165
+ export * from './services/mpin.service'
166
+ export * from './dtos/setup-mpin.dto'
167
+ export * from './dtos/change-mpin.dto'
168
+ export * from './dtos/mpin-login.dto'
163
169
  export * from './entities/view-metadata.entity'
164
170
  export * from './entities/setting.entity'
165
171
  export * from './entities/saved-filters.entity'
@@ -225,6 +231,7 @@ export * from './helpers/environment.helper'
225
231
  export * from './helpers/cache.helper'
226
232
  export * from './helpers/cors.helper'
227
233
  export * from './helpers/security.helper'
234
+ export * from './helpers/file-download.helper'
228
235
  export * from './helpers/model-metadata-helper.service'
229
236
  export * from './helpers/image-encoding.helper'
230
237
  export * from './helpers/solid-microservice-adapter.service'
@@ -248,10 +255,12 @@ export * from './services/workflow/workflow-expression.service'
248
255
  export * from './services/workflow/workflow-invocation.service'
249
256
  export * from './services/workflow/workflow-node-registry.service'
250
257
  export * from './services/workflow/workflow-runtime.service'
258
+ export * from './services/workflow/nodes/execution-fail.node'
251
259
  export * from './services/workflow/nodes/for-each.node'
252
260
  export * from './services/workflow/nodes/http-request.node'
253
261
  export * from './services/workflow/nodes/if.node'
254
262
  export * from './services/workflow/nodes/log-write.node'
263
+ export * from './services/workflow/nodes/loop-until.node'
255
264
  export * from './services/workflow/nodes/parallel.node'
256
265
  export * from './services/workflow/nodes/sequential.node'
257
266
  export * from './services/workflow/nodes/solidx-crud.nodes'
@@ -335,6 +344,7 @@ export * from './services/action-metadata.service'
335
344
  export * from './services/authentication.service'
336
345
  export * from './services/bcrypt.service'
337
346
  export * from './services/computed-fields/uuid-external-id-computed-field-provider.service'
347
+ export * from './services/draft-publish-helper.service'
338
348
  export * from './services/crud-helper.service'
339
349
  export * from './services/crud.service'
340
350
  export * from './services/email-template.service'
@@ -22,6 +22,15 @@ export interface ActiveUserData {
22
22
  */
23
23
  sessionId?: string;
24
24
 
25
+ /**
26
+ * Identifies which per-device refresh-token bucket this session belongs to.
27
+ * Present only while concurrent logins are permitted; mutually exclusive with
28
+ * sessionId, which exists only when they are not. Carried on the access token
29
+ * so bearer-authenticated endpoints that need this session's refresh token
30
+ * can find it.
31
+ */
32
+ deviceKey?: string;
33
+
25
34
  /**
26
35
  * The subject's (user) roles.
27
36
  * These are part of the JWT token, we simply decode them.
package/src/interfaces.ts CHANGED
@@ -272,6 +272,7 @@ export interface ModuleMetadataSeederOptions {
272
272
  modulesToSeed: string[] | null;
273
273
  pruneMetadata: boolean;
274
274
  seedGlobalMetadata: boolean;
275
+ skipHooks: boolean;
275
276
  }
276
277
 
277
278
  export interface ModuleMetadataSeederEventPayload {
@@ -0,0 +1,17 @@
1
+ import { Injectable } from '@nestjs/common';
2
+ import { UserDeviceCredential } from 'src/entities/user-device-credential.entity';
3
+ import { RequestContextService } from 'src/services/request-context.service';
4
+ import { DataSource } from 'typeorm';
5
+ import { SecurityRuleRepository } from './security-rule.repository';
6
+ import { SolidBaseRepository } from './solid-base.repository';
7
+
8
+ @Injectable()
9
+ export class UserDeviceCredentialRepository extends SolidBaseRepository<UserDeviceCredential> {
10
+ constructor(
11
+ readonly dataSource: DataSource,
12
+ readonly requestContextService: RequestContextService,
13
+ readonly securityRuleRepository: SecurityRuleRepository,
14
+ ) {
15
+ super(UserDeviceCredential, dataSource, requestContextService, securityRuleRepository);
16
+ }
17
+ }