@directus/api 21.0.0-rc.0 → 21.0.0

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 (285) hide show
  1. package/dist/app.js +5 -5
  2. package/dist/auth/drivers/ldap.js +4 -4
  3. package/dist/auth/drivers/local.js +4 -4
  4. package/dist/auth/drivers/oauth2.js +4 -4
  5. package/dist/auth/drivers/openid.js +4 -2
  6. package/dist/cache.d.ts +0 -1
  7. package/dist/cache.js +7 -25
  8. package/dist/cli/commands/bootstrap/index.js +2 -8
  9. package/dist/cli/commands/init/index.js +10 -9
  10. package/dist/cli/utils/defaults.d.ts +11 -4
  11. package/dist/cli/utils/defaults.js +1 -7
  12. package/dist/constants.d.ts +1 -1
  13. package/dist/controllers/auth.js +16 -5
  14. package/dist/controllers/permissions.js +2 -14
  15. package/dist/controllers/roles.js +1 -22
  16. package/dist/controllers/tus.js +27 -13
  17. package/dist/controllers/users.js +55 -0
  18. package/dist/database/helpers/fn/types.d.ts +1 -2
  19. package/dist/database/helpers/fn/types.js +1 -1
  20. package/dist/database/helpers/geometry/dialects/mssql.d.ts +1 -1
  21. package/dist/database/helpers/geometry/dialects/mssql.js +2 -4
  22. package/dist/database/helpers/geometry/dialects/mysql.js +1 -1
  23. package/dist/database/helpers/geometry/dialects/oracle.d.ts +1 -1
  24. package/dist/database/helpers/geometry/dialects/oracle.js +3 -5
  25. package/dist/database/helpers/geometry/types.d.ts +1 -1
  26. package/dist/database/helpers/geometry/types.js +2 -4
  27. package/dist/database/index.js +11 -8
  28. package/dist/database/migrations/20240305A-change-useragent-type.js +1 -1
  29. package/dist/database/migrations/20240716A-update-files-date-fields.js +33 -0
  30. package/dist/database/{run-ast/types.d.ts → run-ast.d.ts} +9 -3
  31. package/dist/database/run-ast.js +458 -0
  32. package/dist/flows.js +4 -3
  33. package/dist/logger/index.js +1 -1
  34. package/dist/middleware/authenticate.js +7 -2
  35. package/dist/middleware/cache.js +1 -1
  36. package/dist/middleware/check-ip.d.ts +2 -0
  37. package/dist/middleware/check-ip.js +37 -0
  38. package/dist/middleware/error-handler.d.ts +2 -2
  39. package/dist/middleware/error-handler.js +54 -51
  40. package/dist/middleware/get-permissions.d.ts +3 -0
  41. package/dist/middleware/get-permissions.js +10 -0
  42. package/dist/middleware/respond.js +1 -1
  43. package/dist/services/activity.js +10 -22
  44. package/dist/services/assets.d.ts +3 -2
  45. package/dist/services/assets.js +7 -15
  46. package/dist/services/authentication.js +18 -18
  47. package/dist/services/authorization.d.ts +17 -0
  48. package/dist/services/authorization.js +456 -0
  49. package/dist/services/collections.js +17 -18
  50. package/dist/services/fields.d.ts +4 -0
  51. package/dist/services/fields.js +53 -58
  52. package/dist/services/files/lib/get-sharp-instance.d.ts +2 -0
  53. package/dist/services/files/lib/get-sharp-instance.js +10 -0
  54. package/dist/services/files/utils/get-metadata.js +7 -6
  55. package/dist/services/files.js +8 -10
  56. package/dist/services/graphql/index.d.ts +3 -3
  57. package/dist/services/graphql/index.js +22 -126
  58. package/dist/services/graphql/subscription.js +4 -2
  59. package/dist/services/import-export.js +4 -18
  60. package/dist/services/index.d.ts +2 -3
  61. package/dist/services/index.js +2 -3
  62. package/dist/services/items.js +44 -115
  63. package/dist/services/mail/index.d.ts +1 -1
  64. package/dist/services/mail/index.js +9 -1
  65. package/dist/services/meta.js +23 -60
  66. package/dist/services/notifications.js +6 -14
  67. package/dist/services/payload.d.ts +10 -9
  68. package/dist/services/payload.js +3 -18
  69. package/dist/services/{permissions.d.ts → permissions/index.d.ts} +7 -5
  70. package/dist/services/{permissions.js → permissions/index.js} +54 -30
  71. package/dist/{permissions → services/permissions}/lib/with-app-minimal-permissions.d.ts +1 -1
  72. package/dist/services/permissions/lib/with-app-minimal-permissions.js +13 -0
  73. package/dist/services/relations.d.ts +9 -1
  74. package/dist/services/relations.js +56 -31
  75. package/dist/services/roles.d.ts +12 -4
  76. package/dist/services/roles.js +424 -57
  77. package/dist/services/shares.d.ts +2 -0
  78. package/dist/services/shares.js +8 -12
  79. package/dist/services/specifications.d.ts +2 -2
  80. package/dist/services/specifications.js +27 -39
  81. package/dist/services/tus/data-store.js +4 -5
  82. package/dist/services/tus/server.d.ts +1 -1
  83. package/dist/services/tus/server.js +9 -2
  84. package/dist/services/users.d.ts +5 -1
  85. package/dist/services/users.js +161 -78
  86. package/dist/services/utils.js +7 -11
  87. package/dist/services/versions.d.ts +2 -0
  88. package/dist/services/versions.js +10 -34
  89. package/dist/telemetry/lib/get-report.js +2 -2
  90. package/dist/telemetry/utils/check-increased-user-limits.d.ts +7 -0
  91. package/dist/telemetry/utils/check-increased-user-limits.js +25 -0
  92. package/dist/telemetry/utils/get-role-counts-by-roles.d.ts +6 -0
  93. package/dist/telemetry/utils/get-role-counts-by-roles.js +27 -0
  94. package/dist/telemetry/utils/get-role-counts-by-users.d.ts +11 -0
  95. package/dist/telemetry/utils/get-role-counts-by-users.js +34 -0
  96. package/dist/telemetry/utils/get-user-count.d.ts +8 -0
  97. package/dist/telemetry/utils/get-user-count.js +33 -0
  98. package/dist/telemetry/utils/get-user-counts-by-roles.d.ts +7 -0
  99. package/dist/telemetry/utils/get-user-counts-by-roles.js +35 -0
  100. package/dist/types/ast.d.ts +1 -43
  101. package/dist/types/items.d.ts +0 -11
  102. package/dist/utils/apply-query.d.ts +3 -4
  103. package/dist/utils/apply-query.js +16 -39
  104. package/dist/utils/get-accountability-for-role.js +25 -16
  105. package/dist/utils/get-accountability-for-token.js +16 -17
  106. package/dist/utils/get-ast-from-query.d.ts +13 -0
  107. package/dist/utils/get-ast-from-query.js +297 -0
  108. package/dist/utils/get-cache-key.d.ts +1 -1
  109. package/dist/utils/get-cache-key.js +1 -12
  110. package/dist/utils/get-column.d.ts +1 -2
  111. package/dist/utils/get-column.js +0 -1
  112. package/dist/utils/get-permissions.d.ts +2 -0
  113. package/dist/utils/get-permissions.js +150 -0
  114. package/dist/utils/get-schema.js +3 -3
  115. package/dist/utils/get-service.js +1 -5
  116. package/dist/utils/merge-permissions-for-share.d.ts +4 -0
  117. package/dist/utils/merge-permissions-for-share.js +109 -0
  118. package/dist/utils/merge-permissions.d.ts +3 -0
  119. package/dist/utils/merge-permissions.js +95 -0
  120. package/dist/utils/reduce-schema.d.ts +6 -4
  121. package/dist/utils/reduce-schema.js +32 -16
  122. package/dist/websocket/authenticate.d.ts +2 -0
  123. package/dist/websocket/authenticate.js +12 -0
  124. package/dist/websocket/controllers/graphql.js +4 -1
  125. package/dist/websocket/controllers/hooks.js +0 -4
  126. package/dist/websocket/controllers/rest.js +2 -0
  127. package/dist/websocket/handlers/subscribe.js +2 -0
  128. package/dist/websocket/utils/items.d.ts +1 -1
  129. package/package.json +36 -37
  130. package/dist/controllers/access.d.ts +0 -2
  131. package/dist/controllers/access.js +0 -148
  132. package/dist/controllers/policies.d.ts +0 -2
  133. package/dist/controllers/policies.js +0 -169
  134. package/dist/database/get-ast-from-query/get-ast-from-query.d.ts +0 -16
  135. package/dist/database/get-ast-from-query/get-ast-from-query.js +0 -82
  136. package/dist/database/get-ast-from-query/lib/convert-wildcards.d.ts +0 -13
  137. package/dist/database/get-ast-from-query/lib/convert-wildcards.js +0 -69
  138. package/dist/database/get-ast-from-query/lib/parse-fields.d.ts +0 -15
  139. package/dist/database/get-ast-from-query/lib/parse-fields.js +0 -190
  140. package/dist/database/get-ast-from-query/utils/get-deep-query.d.ts +0 -14
  141. package/dist/database/get-ast-from-query/utils/get-deep-query.js +0 -17
  142. package/dist/database/get-ast-from-query/utils/get-related-collection.d.ts +0 -2
  143. package/dist/database/get-ast-from-query/utils/get-related-collection.js +0 -13
  144. package/dist/database/get-ast-from-query/utils/get-relation.d.ts +0 -2
  145. package/dist/database/get-ast-from-query/utils/get-relation.js +0 -7
  146. package/dist/database/migrations/20240710A-permissions-policies.js +0 -169
  147. package/dist/database/run-ast/lib/get-db-query.d.ts +0 -4
  148. package/dist/database/run-ast/lib/get-db-query.js +0 -208
  149. package/dist/database/run-ast/lib/parse-current-level.d.ts +0 -7
  150. package/dist/database/run-ast/lib/parse-current-level.js +0 -41
  151. package/dist/database/run-ast/run-ast.d.ts +0 -7
  152. package/dist/database/run-ast/run-ast.js +0 -107
  153. package/dist/database/run-ast/types.js +0 -1
  154. package/dist/database/run-ast/utils/apply-case-when.d.ts +0 -16
  155. package/dist/database/run-ast/utils/apply-case-when.js +0 -26
  156. package/dist/database/run-ast/utils/apply-parent-filters.d.ts +0 -3
  157. package/dist/database/run-ast/utils/apply-parent-filters.js +0 -55
  158. package/dist/database/run-ast/utils/get-column-pre-processor.d.ts +0 -10
  159. package/dist/database/run-ast/utils/get-column-pre-processor.js +0 -57
  160. package/dist/database/run-ast/utils/get-field-alias.d.ts +0 -2
  161. package/dist/database/run-ast/utils/get-field-alias.js +0 -4
  162. package/dist/database/run-ast/utils/get-inner-query-column-pre-processor.d.ts +0 -5
  163. package/dist/database/run-ast/utils/get-inner-query-column-pre-processor.js +0 -23
  164. package/dist/database/run-ast/utils/merge-with-parent-items.d.ts +0 -3
  165. package/dist/database/run-ast/utils/merge-with-parent-items.js +0 -87
  166. package/dist/database/run-ast/utils/remove-temporary-fields.d.ts +0 -3
  167. package/dist/database/run-ast/utils/remove-temporary-fields.js +0 -73
  168. package/dist/permissions/cache.d.ts +0 -2
  169. package/dist/permissions/cache.js +0 -23
  170. package/dist/permissions/lib/fetch-permissions.d.ts +0 -10
  171. package/dist/permissions/lib/fetch-permissions.js +0 -55
  172. package/dist/permissions/lib/fetch-policies.d.ts +0 -7
  173. package/dist/permissions/lib/fetch-policies.js +0 -28
  174. package/dist/permissions/lib/fetch-roles-tree.d.ts +0 -3
  175. package/dist/permissions/lib/fetch-roles-tree.js +0 -28
  176. package/dist/permissions/lib/with-app-minimal-permissions.js +0 -10
  177. package/dist/permissions/modules/fetch-accountability-collection-access/fetch-accountability-collection-access.d.ts +0 -7
  178. package/dist/permissions/modules/fetch-accountability-collection-access/fetch-accountability-collection-access.js +0 -56
  179. package/dist/permissions/modules/fetch-accountability-policy-globals/fetch-accountability-policy-globals.d.ts +0 -3
  180. package/dist/permissions/modules/fetch-accountability-policy-globals/fetch-accountability-policy-globals.js +0 -16
  181. package/dist/permissions/modules/fetch-allowed-collections/fetch-allowed-collections.d.ts +0 -8
  182. package/dist/permissions/modules/fetch-allowed-collections/fetch-allowed-collections.js +0 -24
  183. package/dist/permissions/modules/fetch-allowed-field-map/fetch-allowed-field-map.d.ts +0 -9
  184. package/dist/permissions/modules/fetch-allowed-field-map/fetch-allowed-field-map.js +0 -31
  185. package/dist/permissions/modules/fetch-allowed-fields/fetch-allowed-fields.d.ts +0 -16
  186. package/dist/permissions/modules/fetch-allowed-fields/fetch-allowed-fields.js +0 -27
  187. package/dist/permissions/modules/fetch-global-access/fetch-global-access.d.ts +0 -10
  188. package/dist/permissions/modules/fetch-global-access/fetch-global-access.js +0 -23
  189. package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-roles.d.ts +0 -5
  190. package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-roles.js +0 -7
  191. package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-user.d.ts +0 -5
  192. package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-user.js +0 -10
  193. package/dist/permissions/modules/fetch-global-access/types.d.ts +0 -4
  194. package/dist/permissions/modules/fetch-global-access/types.js +0 -1
  195. package/dist/permissions/modules/fetch-global-access/utils/fetch-global-access-for-query.d.ts +0 -4
  196. package/dist/permissions/modules/fetch-global-access/utils/fetch-global-access-for-query.js +0 -27
  197. package/dist/permissions/modules/fetch-inconsistent-field-map/fetch-inconsistent-field-map.d.ts +0 -12
  198. package/dist/permissions/modules/fetch-inconsistent-field-map/fetch-inconsistent-field-map.js +0 -32
  199. package/dist/permissions/modules/fetch-policies-ip-access/fetch-policies-ip-access.d.ts +0 -4
  200. package/dist/permissions/modules/fetch-policies-ip-access/fetch-policies-ip-access.js +0 -29
  201. package/dist/permissions/modules/process-ast/lib/extract-fields-from-children.d.ts +0 -4
  202. package/dist/permissions/modules/process-ast/lib/extract-fields-from-children.js +0 -49
  203. package/dist/permissions/modules/process-ast/lib/extract-fields-from-query.d.ts +0 -3
  204. package/dist/permissions/modules/process-ast/lib/extract-fields-from-query.js +0 -56
  205. package/dist/permissions/modules/process-ast/lib/field-map-from-ast.d.ts +0 -4
  206. package/dist/permissions/modules/process-ast/lib/field-map-from-ast.js +0 -8
  207. package/dist/permissions/modules/process-ast/lib/inject-cases.d.ts +0 -9
  208. package/dist/permissions/modules/process-ast/lib/inject-cases.js +0 -93
  209. package/dist/permissions/modules/process-ast/process-ast.d.ts +0 -9
  210. package/dist/permissions/modules/process-ast/process-ast.js +0 -39
  211. package/dist/permissions/modules/process-ast/types.d.ts +0 -24
  212. package/dist/permissions/modules/process-ast/types.js +0 -1
  213. package/dist/permissions/modules/process-ast/utils/collections-in-field-map.d.ts +0 -2
  214. package/dist/permissions/modules/process-ast/utils/collections-in-field-map.js +0 -7
  215. package/dist/permissions/modules/process-ast/utils/dedupe-access.d.ts +0 -12
  216. package/dist/permissions/modules/process-ast/utils/dedupe-access.js +0 -30
  217. package/dist/permissions/modules/process-ast/utils/extract-paths-from-query.d.ts +0 -15
  218. package/dist/permissions/modules/process-ast/utils/extract-paths-from-query.js +0 -50
  219. package/dist/permissions/modules/process-ast/utils/find-related-collection.d.ts +0 -3
  220. package/dist/permissions/modules/process-ast/utils/find-related-collection.js +0 -9
  221. package/dist/permissions/modules/process-ast/utils/flatten-filter.d.ts +0 -3
  222. package/dist/permissions/modules/process-ast/utils/flatten-filter.js +0 -34
  223. package/dist/permissions/modules/process-ast/utils/format-a2o-key.d.ts +0 -1
  224. package/dist/permissions/modules/process-ast/utils/format-a2o-key.js +0 -3
  225. package/dist/permissions/modules/process-ast/utils/get-info-for-path.d.ts +0 -5
  226. package/dist/permissions/modules/process-ast/utils/get-info-for-path.js +0 -7
  227. package/dist/permissions/modules/process-ast/utils/has-item-permissions.d.ts +0 -2
  228. package/dist/permissions/modules/process-ast/utils/has-item-permissions.js +0 -3
  229. package/dist/permissions/modules/process-ast/utils/stringify-query-path.d.ts +0 -2
  230. package/dist/permissions/modules/process-ast/utils/stringify-query-path.js +0 -3
  231. package/dist/permissions/modules/process-ast/utils/validate-path/create-error.d.ts +0 -3
  232. package/dist/permissions/modules/process-ast/utils/validate-path/create-error.js +0 -16
  233. package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-existence.d.ts +0 -2
  234. package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-existence.js +0 -12
  235. package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-permissions.d.ts +0 -2
  236. package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-permissions.js +0 -28
  237. package/dist/permissions/modules/process-payload/lib/is-field-nullable.d.ts +0 -5
  238. package/dist/permissions/modules/process-payload/lib/is-field-nullable.js +0 -12
  239. package/dist/permissions/modules/process-payload/process-payload.d.ts +0 -13
  240. package/dist/permissions/modules/process-payload/process-payload.js +0 -77
  241. package/dist/permissions/modules/validate-access/lib/validate-collection-access.d.ts +0 -12
  242. package/dist/permissions/modules/validate-access/lib/validate-collection-access.js +0 -11
  243. package/dist/permissions/modules/validate-access/lib/validate-item-access.d.ts +0 -9
  244. package/dist/permissions/modules/validate-access/lib/validate-item-access.js +0 -33
  245. package/dist/permissions/modules/validate-access/validate-access.d.ts +0 -14
  246. package/dist/permissions/modules/validate-access/validate-access.js +0 -28
  247. package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-count.d.ts +0 -1
  248. package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-count.js +0 -8
  249. package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-users.d.ts +0 -5
  250. package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-users.js +0 -10
  251. package/dist/permissions/types.d.ts +0 -6
  252. package/dist/permissions/types.js +0 -1
  253. package/dist/permissions/utils/create-default-accountability.d.ts +0 -2
  254. package/dist/permissions/utils/create-default-accountability.js +0 -11
  255. package/dist/permissions/utils/extract-required-dynamic-variable-context.d.ts +0 -8
  256. package/dist/permissions/utils/extract-required-dynamic-variable-context.js +0 -27
  257. package/dist/permissions/utils/fetch-dynamic-variable-context.d.ts +0 -9
  258. package/dist/permissions/utils/fetch-dynamic-variable-context.js +0 -43
  259. package/dist/permissions/utils/filter-policies-by-ip.d.ts +0 -2
  260. package/dist/permissions/utils/filter-policies-by-ip.js +0 -15
  261. package/dist/permissions/utils/get-unaliased-field-key.d.ts +0 -5
  262. package/dist/permissions/utils/get-unaliased-field-key.js +0 -17
  263. package/dist/permissions/utils/process-permissions.d.ts +0 -7
  264. package/dist/permissions/utils/process-permissions.js +0 -9
  265. package/dist/permissions/utils/with-cache.d.ts +0 -10
  266. package/dist/permissions/utils/with-cache.js +0 -25
  267. package/dist/services/access.d.ts +0 -10
  268. package/dist/services/access.js +0 -43
  269. package/dist/services/policies.d.ts +0 -12
  270. package/dist/services/policies.js +0 -87
  271. package/dist/telemetry/utils/check-user-limits.d.ts +0 -5
  272. package/dist/telemetry/utils/check-user-limits.js +0 -19
  273. package/dist/utils/fetch-user-count/fetch-access-lookup.d.ts +0 -17
  274. package/dist/utils/fetch-user-count/fetch-access-lookup.js +0 -22
  275. package/dist/utils/fetch-user-count/fetch-access-roles.d.ts +0 -16
  276. package/dist/utils/fetch-user-count/fetch-access-roles.js +0 -37
  277. package/dist/utils/fetch-user-count/fetch-active-users.d.ts +0 -6
  278. package/dist/utils/fetch-user-count/fetch-active-users.js +0 -3
  279. package/dist/utils/fetch-user-count/fetch-user-count.d.ts +0 -12
  280. package/dist/utils/fetch-user-count/fetch-user-count.js +0 -57
  281. package/dist/utils/fetch-user-count/get-user-count-query.d.ts +0 -20
  282. package/dist/utils/fetch-user-count/get-user-count-query.js +0 -17
  283. package/dist/utils/validate-user-count-integrity.d.ts +0 -13
  284. package/dist/utils/validate-user-count-integrity.js +0 -29
  285. /package/dist/database/migrations/{20240710A-permissions-policies.d.ts → 20240716A-update-files-date-fields.d.ts} +0 -0
@@ -0,0 +1,109 @@
1
+ import { assign, set, uniq } from 'lodash-es';
2
+ import { schemaPermissions } from '@directus/system-data';
3
+ import { mergePermissions } from './merge-permissions.js';
4
+ import { reduceSchema } from './reduce-schema.js';
5
+ export function mergePermissionsForShare(currentPermissions, accountability, schema) {
6
+ const defaults = {
7
+ action: 'read',
8
+ role: accountability.role,
9
+ collection: '',
10
+ permissions: {},
11
+ validation: null,
12
+ presets: null,
13
+ fields: null,
14
+ };
15
+ const { collection, item } = accountability.share_scope;
16
+ const parentPrimaryKeyField = schema.collections[collection].primary;
17
+ const reducedSchema = reduceSchema(schema, currentPermissions, ['read']);
18
+ const relationalPermissions = traverse(reducedSchema, parentPrimaryKeyField, item, collection);
19
+ const parentCollectionPermission = assign({}, defaults, {
20
+ collection,
21
+ permissions: {
22
+ [parentPrimaryKeyField]: {
23
+ _eq: item,
24
+ },
25
+ },
26
+ });
27
+ // All permissions that will be merged into the original permissions set
28
+ const allGeneratedPermissions = [
29
+ parentCollectionPermission,
30
+ ...relationalPermissions.map((generated) => assign({}, defaults, generated)),
31
+ ...schemaPermissions,
32
+ ];
33
+ // All the collections that are touched through the relational tree from the current root collection, and the schema collections
34
+ const allowedCollections = uniq(allGeneratedPermissions.map(({ collection }) => collection));
35
+ const generatedPermissions = [];
36
+ // Merge all the permissions that relate to the same collection with an _or (this allows you to properly retrieve)
37
+ // the items of a collection if you entered that collection from multiple angles
38
+ for (const collection of allowedCollections) {
39
+ const permissionsForCollection = allGeneratedPermissions.filter((permission) => permission.collection === collection);
40
+ if (permissionsForCollection.length > 0) {
41
+ generatedPermissions.push(...mergePermissions('or', permissionsForCollection));
42
+ }
43
+ else {
44
+ generatedPermissions.push(...permissionsForCollection);
45
+ }
46
+ }
47
+ // Explicitly filter out permissions to collections unrelated to the root parent item.
48
+ const limitedPermissions = currentPermissions.filter(({ action, collection }) => allowedCollections.includes(collection) && action === 'read');
49
+ return mergePermissions('and', limitedPermissions, generatedPermissions);
50
+ }
51
+ export function traverse(schema, rootItemPrimaryKeyField, rootItemPrimaryKey, currentCollection, parentCollections = [], path = []) {
52
+ const permissions = [];
53
+ // If there's already a permissions rule for the collection we're currently checking, we'll shortcircuit.
54
+ // This prevents infinite loop in recursive relationships, like articles->related_articles->articles, or
55
+ // articles.author->users.avatar->files.created_by->users.avatar->files.created_by->🔁
56
+ if (parentCollections.includes(currentCollection)) {
57
+ return permissions;
58
+ }
59
+ const relationsInCollection = schema.relations.filter((relation) => {
60
+ return relation.collection === currentCollection || relation.related_collection === currentCollection;
61
+ });
62
+ for (const relation of relationsInCollection) {
63
+ let type;
64
+ if (relation.related_collection === currentCollection) {
65
+ type = 'o2m';
66
+ }
67
+ else if (!relation.related_collection) {
68
+ type = 'a2o';
69
+ }
70
+ else {
71
+ type = 'm2o';
72
+ }
73
+ if (type === 'o2m') {
74
+ permissions.push({
75
+ collection: relation.collection,
76
+ permissions: getFilterForPath(type, [...path, relation.field], rootItemPrimaryKeyField, rootItemPrimaryKey),
77
+ });
78
+ permissions.push(...traverse(schema, rootItemPrimaryKeyField, rootItemPrimaryKey, relation.collection, [...parentCollections, currentCollection], [...path, relation.field]));
79
+ }
80
+ if (type === 'a2o' && relation.meta?.one_allowed_collections) {
81
+ for (const collection of relation.meta.one_allowed_collections) {
82
+ permissions.push({
83
+ collection,
84
+ permissions: getFilterForPath(type, [...path, `$FOLLOW(${relation.collection},${relation.field},${relation.meta.one_collection_field})`], rootItemPrimaryKeyField, rootItemPrimaryKey),
85
+ });
86
+ }
87
+ }
88
+ if (type === 'm2o') {
89
+ permissions.push({
90
+ collection: relation.related_collection,
91
+ permissions: getFilterForPath(type, [...path, `$FOLLOW(${relation.collection},${relation.field})`], rootItemPrimaryKeyField, rootItemPrimaryKey),
92
+ });
93
+ if (relation.meta?.one_field) {
94
+ permissions.push(...traverse(schema, rootItemPrimaryKeyField, rootItemPrimaryKey, relation.related_collection, [...parentCollections, currentCollection], [...path, relation.meta?.one_field]));
95
+ }
96
+ }
97
+ }
98
+ return permissions;
99
+ }
100
+ export function getFilterForPath(type, path, rootPrimaryKeyField, rootPrimaryKey) {
101
+ const filter = {};
102
+ if (type === 'm2o' || type === 'a2o') {
103
+ set(filter, path.reverse(), { [rootPrimaryKeyField]: { _eq: rootPrimaryKey } });
104
+ }
105
+ else {
106
+ set(filter, path.reverse(), { _eq: rootPrimaryKey });
107
+ }
108
+ return filter;
109
+ }
@@ -0,0 +1,3 @@
1
+ import type { Permission } from '@directus/types';
2
+ export declare function mergePermissions(strategy: 'and' | 'or', ...permissions: Permission[][]): Permission[];
3
+ export declare function mergePermission(strategy: 'and' | 'or', currentPerm: Permission, newPerm: Permission): Omit<Permission, 'id' | 'system'>;
@@ -0,0 +1,95 @@
1
+ import { flatten, intersection, isEqual, merge, omit } from 'lodash-es';
2
+ export function mergePermissions(strategy, ...permissions) {
3
+ const allPermissions = flatten(permissions);
4
+ const mergedPermissions = allPermissions
5
+ .reduce((acc, val) => {
6
+ const key = `${val.collection}__${val.action}__${val.role || '$PUBLIC'}`;
7
+ const current = acc.get(key);
8
+ acc.set(key, current ? mergePermission(strategy, current, val) : val);
9
+ return acc;
10
+ }, new Map())
11
+ .values();
12
+ return Array.from(mergedPermissions);
13
+ }
14
+ export function mergePermission(strategy, currentPerm, newPerm) {
15
+ const logicalKey = `_${strategy}`;
16
+ let permissions = currentPerm.permissions;
17
+ let validation = currentPerm.validation;
18
+ let fields = currentPerm.fields;
19
+ let presets = currentPerm.presets;
20
+ if (newPerm.permissions) {
21
+ if (currentPerm.permissions && Object.keys(currentPerm.permissions)[0] === logicalKey) {
22
+ permissions = {
23
+ [logicalKey]: [
24
+ ...currentPerm.permissions[logicalKey],
25
+ newPerm.permissions,
26
+ ],
27
+ };
28
+ }
29
+ else if (currentPerm.permissions) {
30
+ // Empty {} supersedes other permissions in _OR merge
31
+ if (strategy === 'or' && (isEqual(currentPerm.permissions, {}) || isEqual(newPerm.permissions, {}))) {
32
+ permissions = {};
33
+ }
34
+ else {
35
+ permissions = {
36
+ [logicalKey]: [currentPerm.permissions, newPerm.permissions],
37
+ };
38
+ }
39
+ }
40
+ else {
41
+ permissions = {
42
+ [logicalKey]: [newPerm.permissions],
43
+ };
44
+ }
45
+ }
46
+ if (newPerm.validation) {
47
+ if (currentPerm.validation && Object.keys(currentPerm.validation)[0] === logicalKey) {
48
+ validation = {
49
+ [logicalKey]: [
50
+ ...currentPerm.validation[logicalKey],
51
+ newPerm.validation,
52
+ ],
53
+ };
54
+ }
55
+ else if (currentPerm.validation) {
56
+ // Empty {} supersedes other validations in _OR merge
57
+ if (strategy === 'or' && (isEqual(currentPerm.validation, {}) || isEqual(newPerm.validation, {}))) {
58
+ validation = {};
59
+ }
60
+ else {
61
+ validation = {
62
+ [logicalKey]: [currentPerm.validation, newPerm.validation],
63
+ };
64
+ }
65
+ }
66
+ else {
67
+ validation = {
68
+ [logicalKey]: [newPerm.validation],
69
+ };
70
+ }
71
+ }
72
+ if (newPerm.fields) {
73
+ if (Array.isArray(currentPerm.fields) && strategy === 'or') {
74
+ fields = [...new Set([...currentPerm.fields, ...newPerm.fields])];
75
+ }
76
+ else if (Array.isArray(currentPerm.fields) && strategy === 'and') {
77
+ fields = intersection(currentPerm.fields, newPerm.fields);
78
+ }
79
+ else {
80
+ fields = newPerm.fields;
81
+ }
82
+ if (fields.includes('*'))
83
+ fields = ['*'];
84
+ }
85
+ if (newPerm.presets) {
86
+ presets = merge({}, presets, newPerm.presets);
87
+ }
88
+ return omit({
89
+ ...currentPerm,
90
+ permissions,
91
+ validation,
92
+ fields,
93
+ presets,
94
+ }, ['id', 'system']);
95
+ }
@@ -1,7 +1,9 @@
1
- import type { SchemaOverview } from '@directus/types';
2
- import type { FieldMap } from '../permissions/modules/fetch-allowed-field-map/fetch-allowed-field-map.js';
1
+ import type { Permission, PermissionsAction, SchemaOverview } from '@directus/types';
3
2
  /**
4
3
  * Reduces the schema based on the included permissions. The resulting object is the schema structure, but with only
5
- * the allowed collections/fields/relations included based on the passed field map.
4
+ * the allowed collections/fields/relations included based on the permissions.
5
+ * @param schema The full project schema
6
+ * @param actions Array of permissions actions (crud)
7
+ * @returns Reduced schema
6
8
  */
7
- export declare function reduceSchema(schema: SchemaOverview, fieldMap: FieldMap): SchemaOverview;
9
+ export declare function reduceSchema(schema: SchemaOverview, permissions: Permission[] | null, actions?: PermissionsAction[]): SchemaOverview;
@@ -1,24 +1,40 @@
1
+ import { uniq } from 'lodash-es';
1
2
  /**
2
3
  * Reduces the schema based on the included permissions. The resulting object is the schema structure, but with only
3
- * the allowed collections/fields/relations included based on the passed field map.
4
+ * the allowed collections/fields/relations included based on the permissions.
5
+ * @param schema The full project schema
6
+ * @param actions Array of permissions actions (crud)
7
+ * @returns Reduced schema
4
8
  */
5
- export function reduceSchema(schema, fieldMap) {
9
+ export function reduceSchema(schema, permissions, actions = ['create', 'read', 'update', 'delete']) {
6
10
  const reduced = {
7
11
  collections: {},
8
12
  relations: [],
9
13
  };
14
+ const allowedFieldsInCollection = permissions
15
+ ?.filter((permission) => actions.includes(permission.action))
16
+ .reduce((acc, permission) => {
17
+ if (!acc[permission.collection]) {
18
+ acc[permission.collection] = [];
19
+ }
20
+ if (permission.fields) {
21
+ acc[permission.collection] = uniq([...acc[permission.collection], ...permission.fields]);
22
+ }
23
+ return acc;
24
+ }, {}) ?? {};
10
25
  for (const [collectionName, collection] of Object.entries(schema.collections)) {
11
- if (!fieldMap[collectionName]) {
12
- // Collection is not allowed at all
26
+ if (!permissions?.some((permission) => permission.collection === collectionName && actions.includes(permission.action))) {
13
27
  continue;
14
28
  }
15
29
  const fields = {};
16
30
  for (const [fieldName, field] of Object.entries(schema.collections[collectionName].fields)) {
17
- if (!fieldMap[collectionName]?.includes('*') && !fieldMap[collectionName]?.includes(fieldName)) {
31
+ if (!allowedFieldsInCollection[collectionName]?.includes('*') &&
32
+ !allowedFieldsInCollection[collectionName]?.includes(fieldName)) {
18
33
  continue;
19
34
  }
20
35
  const o2mRelation = schema.relations.find((relation) => relation.related_collection === collectionName && relation.meta?.one_field === fieldName);
21
- if (o2mRelation && !fieldMap[collectionName]) {
36
+ if (o2mRelation &&
37
+ !permissions?.some((permission) => permission.collection === o2mRelation.collection && actions.includes(permission.action))) {
22
38
  continue;
23
39
  }
24
40
  fields[fieldName] = field;
@@ -31,29 +47,29 @@ export function reduceSchema(schema, fieldMap) {
31
47
  reduced.relations = schema.relations.filter((relation) => {
32
48
  let collectionsAllowed = true;
33
49
  let fieldsAllowed = true;
34
- if (Object.keys(fieldMap).includes(relation.collection) === false) {
50
+ if (Object.keys(allowedFieldsInCollection).includes(relation.collection) === false) {
35
51
  collectionsAllowed = false;
36
52
  }
37
53
  if (relation.related_collection &&
38
- (Object.keys(fieldMap).includes(relation.related_collection) === false ||
54
+ (Object.keys(allowedFieldsInCollection).includes(relation.related_collection) === false ||
39
55
  // Ignore legacy permissions with an empty fields array
40
- fieldMap[relation.related_collection]?.length === 0)) {
56
+ allowedFieldsInCollection[relation.related_collection]?.length === 0)) {
41
57
  collectionsAllowed = false;
42
58
  }
43
59
  if (relation.meta?.one_allowed_collections &&
44
- relation.meta.one_allowed_collections.every((collection) => Object.keys(fieldMap).includes(collection)) === false) {
60
+ relation.meta.one_allowed_collections.every((collection) => Object.keys(allowedFieldsInCollection).includes(collection)) === false) {
45
61
  collectionsAllowed = false;
46
62
  }
47
- if (!fieldMap[relation.collection] ||
48
- (fieldMap[relation.collection]?.includes('*') === false &&
49
- fieldMap[relation.collection]?.includes(relation.field) === false)) {
63
+ if (!allowedFieldsInCollection[relation.collection] ||
64
+ (allowedFieldsInCollection[relation.collection]?.includes('*') === false &&
65
+ allowedFieldsInCollection[relation.collection]?.includes(relation.field) === false)) {
50
66
  fieldsAllowed = false;
51
67
  }
52
68
  if (relation.related_collection &&
53
69
  relation.meta?.one_field &&
54
- (!fieldMap[relation.related_collection] ||
55
- (fieldMap[relation.related_collection]?.includes('*') === false &&
56
- fieldMap[relation.related_collection]?.includes(relation.meta?.one_field) === false))) {
70
+ (!allowedFieldsInCollection[relation.related_collection] ||
71
+ (allowedFieldsInCollection[relation.related_collection]?.includes('*') === false &&
72
+ allowedFieldsInCollection[relation.related_collection]?.includes(relation.meta?.one_field) === false))) {
57
73
  fieldsAllowed = false;
58
74
  }
59
75
  return collectionsAllowed && fieldsAllowed;
@@ -1,4 +1,6 @@
1
+ import type { Accountability } from '@directus/types';
1
2
  import type { BasicAuthMessage } from './messages.js';
2
3
  import type { AuthenticationState } from './types.js';
3
4
  export declare function authenticateConnection(message: BasicAuthMessage & Record<string, any>): Promise<AuthenticationState>;
5
+ export declare function refreshAccountability(accountability: Accountability | null | undefined): Promise<Accountability>;
4
6
  export declare function authenticationSuccess(uid?: string | number, refresh_token?: string): string;
@@ -1,6 +1,7 @@
1
1
  import { DEFAULT_AUTH_PROVIDER } from '../constants.js';
2
2
  import { AuthenticationService } from '../services/index.js';
3
3
  import { getAccountabilityForToken } from '../utils/get-accountability-for-token.js';
4
+ import { getPermissions } from '../utils/get-permissions.js';
4
5
  import { getSchema } from '../utils/get-schema.js';
5
6
  import { WebSocketError } from './errors.js';
6
7
  import { getExpiresAtForToken } from './utils/get-expires-at-for-token.js';
@@ -32,6 +33,17 @@ export async function authenticateConnection(message) {
32
33
  throw new WebSocketError('auth', 'AUTH_FAILED', 'Authentication failed.', message['uid']);
33
34
  }
34
35
  }
36
+ export async function refreshAccountability(accountability) {
37
+ accountability = accountability ?? {
38
+ role: null,
39
+ user: null,
40
+ admin: false,
41
+ app: false,
42
+ };
43
+ const schema = await getSchema();
44
+ const permissions = await getPermissions(accountability, schema);
45
+ return { ...accountability, permissions };
46
+ }
35
47
  export function authenticationSuccess(uid, refresh_token) {
36
48
  const message = {
37
49
  type: 'auth',
@@ -4,7 +4,7 @@ import { useLogger } from '../../logger/index.js';
4
4
  import { bindPubSub } from '../../services/graphql/subscription.js';
5
5
  import { GraphQLService } from '../../services/index.js';
6
6
  import { getSchema } from '../../utils/get-schema.js';
7
- import { authenticateConnection } from '../authenticate.js';
7
+ import { authenticateConnection, refreshAccountability } from '../authenticate.js';
8
8
  import { handleWebSocketError } from '../errors.js';
9
9
  import { ConnectionParams, WebSocketMessage } from '../messages.js';
10
10
  import { getMessageType } from '../utils/message.js';
@@ -64,6 +64,9 @@ export class GraphQLSubscriptionController extends SocketController {
64
64
  client.close(CloseCode.Forbidden, 'Forbidden');
65
65
  return;
66
66
  }
67
+ else {
68
+ client.accountability = await refreshAccountability(client.accountability);
69
+ }
67
70
  await cb(JSON.stringify(message));
68
71
  }
69
72
  catch (error) {
@@ -7,23 +7,19 @@ export function registerWebSocketEvents() {
7
7
  actionsRegistered = true;
8
8
  registerActionHooks([
9
9
  'items',
10
- 'access',
11
10
  'activity',
12
11
  'collections',
13
12
  'dashboards',
14
- 'flows',
15
13
  'folders',
16
14
  'notifications',
17
15
  'operations',
18
16
  'panels',
19
17
  'permissions',
20
- 'policies',
21
18
  'presets',
22
19
  'revisions',
23
20
  'roles',
24
21
  'settings',
25
22
  'shares',
26
- 'translations',
27
23
  'users',
28
24
  'versions',
29
25
  'webhooks',
@@ -2,6 +2,7 @@ import { useEnv } from '@directus/env';
2
2
  import { parseJSON } from '@directus/utils';
3
3
  import emitter from '../../emitter.js';
4
4
  import { useLogger } from '../../logger/index.js';
5
+ import { refreshAccountability } from '../authenticate.js';
5
6
  import { WebSocketError, handleWebSocketError } from '../errors.js';
6
7
  import { WebSocketMessage } from '../messages.js';
7
8
  import SocketController from './base.js';
@@ -19,6 +20,7 @@ export class WebSocketController extends SocketController {
19
20
  client.on('parsed-message', async (message) => {
20
21
  try {
21
22
  message = WebSocketMessage.parse(await emitter.emitFilter('websocket.message', message, { client }));
23
+ client.accountability = await refreshAccountability(client.accountability);
22
24
  emitter.emitAction('websocket.message', { message, client });
23
25
  }
24
26
  catch (error) {
@@ -4,6 +4,7 @@ import { useBus } from '../../bus/index.js';
4
4
  import emitter from '../../emitter.js';
5
5
  import { getSchema } from '../../utils/get-schema.js';
6
6
  import { sanitizeQuery } from '../../utils/sanitize-query.js';
7
+ import { refreshAccountability } from '../authenticate.js';
7
8
  import { WebSocketError, handleWebSocketError } from '../errors.js';
8
9
  import { WebSocketSubscribeMessage } from '../messages.js';
9
10
  import { getPayload } from '../utils/items.js';
@@ -111,6 +112,7 @@ export class SubscribeHandler {
111
112
  continue;
112
113
  }
113
114
  try {
115
+ client.accountability = await refreshAccountability(client.accountability);
114
116
  const result = await getPayload(subscription, client.accountability, schema, event);
115
117
  if (Array.isArray(result?.['data']) && result?.['data']?.length === 0)
116
118
  continue;
@@ -39,5 +39,5 @@ export declare function getFieldsPayload(subscription: PSubscription, accountabi
39
39
  * @param event Event data
40
40
  * @returns the fetched data
41
41
  */
42
- export declare function getItemsPayload(subscription: PSubscription, accountability: Accountability | null, schema: SchemaOverview, event?: WebSocketEvent): Promise<string | number | (string | number)[] | import("@directus/types").Item | import("@directus/types").Item[]>;
42
+ export declare function getItemsPayload(subscription: PSubscription, accountability: Accountability | null, schema: SchemaOverview, event?: WebSocketEvent): Promise<string | number | import("@directus/types").Item | (string | number)[] | import("@directus/types").Item[]>;
43
43
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@directus/api",
3
- "version": "21.0.0-rc.0",
3
+ "version": "21.0.0",
4
4
  "description": "Directus is a real-time API and App dashboard for managing SQL database content",
5
5
  "keywords": [
6
6
  "directus",
@@ -59,7 +59,7 @@
59
59
  ],
60
60
  "dependencies": {
61
61
  "@authenio/samlify-node-xmllint": "2.0.0",
62
- "@aws-sdk/client-ses": "3.600.0",
62
+ "@aws-sdk/client-ses": "3.614.0",
63
63
  "@godaddy/terminus": "4.12.1",
64
64
  "@rollup/plugin-alias": "5.1.0",
65
65
  "@rollup/plugin-node-resolve": "15.2.3",
@@ -70,7 +70,7 @@
70
70
  "@types/cookie": "0.6.0",
71
71
  "argon2": "0.40.3",
72
72
  "async": "3.2.5",
73
- "axios": "1.7.2",
73
+ "axios": "1.7.3",
74
74
  "busboy": "1.6.0",
75
75
  "bytes": "3.1.2",
76
76
  "camelcase": "8.0.0",
@@ -99,7 +99,7 @@
99
99
  "graphql-ws": "5.16.0",
100
100
  "helmet": "7.1.0",
101
101
  "icc": "3.0.0",
102
- "inquirer": "9.3.2",
102
+ "inquirer": "9.3.5",
103
103
  "ioredis": "5.4.1",
104
104
  "ip-matching": "2.1.2",
105
105
  "isolated-vm": "4.7.2",
@@ -111,12 +111,12 @@
111
111
  "keyv": "4.5.4",
112
112
  "knex": "3.1.0",
113
113
  "ldapjs": "2.3.3",
114
- "liquidjs": "10.14.0",
114
+ "liquidjs": "10.15.0",
115
115
  "lodash-es": "4.17.21",
116
116
  "marked": "12.0.2",
117
117
  "micromustache": "8.0.3",
118
118
  "mime-types": "2.1.35",
119
- "minimatch": "9.0.4",
119
+ "minimatch": "9.0.5",
120
120
  "mnemonist": "0.39.8",
121
121
  "ms": "2.1.3",
122
122
  "nanoid": "5.0.7",
@@ -124,7 +124,7 @@
124
124
  "node-schedule": "2.1.1",
125
125
  "nodemailer": "6.9.14",
126
126
  "object-hash": "3.0.0",
127
- "openapi3-ts": "4.3.2",
127
+ "openapi3-ts": "4.3.3",
128
128
  "openid-client": "5.6.5",
129
129
  "ora": "8.0.1",
130
130
  "otplib": "12.0.1",
@@ -135,7 +135,7 @@
135
135
  "pino-http": "9.0.0",
136
136
  "pino-http-print": "3.1.0",
137
137
  "pino-pretty": "11.2.1",
138
- "qs": "6.12.2",
138
+ "qs": "6.12.3",
139
139
  "rate-limiter-flexible": "5.0.3",
140
140
  "rollup": "4.17.2",
141
141
  "samlify": "2.8.10",
@@ -143,35 +143,35 @@
143
143
  "sharp": "0.33.4",
144
144
  "snappy": "7.2.2",
145
145
  "stream-json": "1.8.0",
146
- "tar": "7.4.0",
147
- "tsx": "4.12.0",
146
+ "tar": "7.4.2",
147
+ "tsx": "4.16.5",
148
148
  "wellknown": "0.5.0",
149
149
  "ws": "8.18.0",
150
150
  "zod": "3.23.8",
151
151
  "zod-validation-error": "3.3.0",
152
- "@directus/constants": "11.1.0-rc.1",
153
- "@directus/env": "1.3.1-rc.0",
154
- "@directus/errors": "0.4.0-rc.1",
155
- "@directus/app": "13.0.0-rc.2",
156
- "@directus/extensions": "2.0.0-rc.1",
157
- "@directus/extensions-registry": "1.0.10-rc.0",
158
- "@directus/extensions-sdk": "11.0.10-rc.0",
159
- "@directus/memory": "1.1.0-rc.1",
152
+ "@directus/app": "12.2.2",
153
+ "@directus/errors": "0.4.0",
154
+ "@directus/constants": "11.0.4",
155
+ "@directus/env": "1.3.1",
156
+ "@directus/extensions": "1.0.10",
157
+ "@directus/extensions-registry": "1.0.10",
158
+ "@directus/extensions-sdk": "11.0.10",
160
159
  "@directus/format-title": "10.1.2",
161
- "@directus/pressure": "1.0.22-rc.0",
162
- "@directus/schema": "11.0.3",
163
- "@directus/specs": "10.2.10",
160
+ "@directus/memory": "1.0.11",
161
+ "@directus/pressure": "1.0.22",
162
+ "@directus/schema": "11.0.4",
163
+ "@directus/specs": "10.2.11",
164
164
  "@directus/storage": "10.1.0",
165
- "@directus/storage-driver-azure": "10.0.24-rc.0",
166
- "@directus/storage-driver-cloudinary": "10.0.24-rc.0",
167
- "@directus/storage-driver-gcs": "10.0.25-rc.0",
165
+ "@directus/storage-driver-cloudinary": "10.0.24",
166
+ "@directus/storage-driver-azure": "10.0.24",
167
+ "@directus/storage-driver-gcs": "10.0.25",
168
168
  "@directus/storage-driver-local": "10.1.0",
169
- "@directus/storage-driver-s3": "10.1.1-rc.0",
170
- "@directus/storage-driver-supabase": "1.0.16-rc.0",
171
- "@directus/validation": "0.0.19-rc.0",
172
- "directus": "11.0.0-rc.3",
173
- "@directus/system-data": "2.0.0-rc.1",
174
- "@directus/utils": "12.0.0-rc.1"
169
+ "@directus/storage-driver-supabase": "1.0.16",
170
+ "@directus/storage-driver-s3": "10.1.1",
171
+ "@directus/utils": "11.0.11",
172
+ "@directus/validation": "0.0.19",
173
+ "@directus/system-data": "1.1.1",
174
+ "directus": "10.13.2"
175
175
  },
176
176
  "devDependencies": {
177
177
  "@ngneat/falso": "7.2.0",
@@ -196,7 +196,7 @@
196
196
  "@types/lodash-es": "4.17.12",
197
197
  "@types/mime-types": "2.1.4",
198
198
  "@types/ms": "0.7.34",
199
- "@types/node": "18.19.33",
199
+ "@types/node": "18.19.43",
200
200
  "@types/node-schedule": "2.1.7",
201
201
  "@types/nodemailer": "6.4.15",
202
202
  "@types/object-hash": "3.0.6",
@@ -205,20 +205,20 @@
205
205
  "@types/sanitize-html": "2.11.0",
206
206
  "@types/stream-json": "1.7.7",
207
207
  "@types/wellknown": "0.5.8",
208
- "@types/ws": "8.5.10",
208
+ "@types/ws": "8.5.11",
209
209
  "@vitest/coverage-v8": "1.5.3",
210
210
  "copyfiles": "2.4.1",
211
211
  "form-data": "4.0.0",
212
212
  "knex-mock-client": "2.0.1",
213
213
  "typescript": "5.4.5",
214
214
  "vitest": "1.5.3",
215
- "@directus/random": "0.2.8",
216
215
  "@directus/tsconfig": "1.0.1",
217
- "@directus/types": "12.0.0-rc.1"
216
+ "@directus/random": "0.2.8",
217
+ "@directus/types": "11.2.1"
218
218
  },
219
219
  "optionalDependencies": {
220
220
  "@keyv/redis": "2.8.5",
221
- "mysql2": "3.10.0",
221
+ "mysql": "2.18.1",
222
222
  "nodemailer-mailgun-transport": "2.1.5",
223
223
  "nodemailer-sendgrid": "1.0.3",
224
224
  "oracledb": "6.5.1",
@@ -233,7 +233,6 @@
233
233
  "build": "tsc --project tsconfig.prod.json && copyfiles \"src/**/*.{yaml,liquid}\" -u 1 dist",
234
234
  "cli": "NODE_ENV=development SERVE_APP=false tsx src/cli/run.ts",
235
235
  "dev": "NODE_ENV=development SERVE_APP=true tsx watch --ignore extensions --clear-screen=false src/start.ts",
236
- "test": "vitest run",
237
- "test:watch": "vitest"
236
+ "test": "vitest --watch=false"
238
237
  }
239
238
  }
@@ -1,2 +0,0 @@
1
- declare const router: import("express-serve-static-core").Router;
2
- export default router;