@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
@@ -1,17 +1,14 @@
1
- import { DEFAULT_NUMERIC_PRECISION, DEFAULT_NUMERIC_SCALE, KNEX_TYPES, REGEX_BETWEEN_PARENS, } from '@directus/constants';
1
+ import { KNEX_TYPES, REGEX_BETWEEN_PARENS, DEFAULT_NUMERIC_PRECISION, DEFAULT_NUMERIC_SCALE, } from '@directus/constants';
2
2
  import { ForbiddenError, InvalidPayloadError } from '@directus/errors';
3
3
  import { createInspector } from '@directus/schema';
4
4
  import { addFieldFlag, toArray } from '@directus/utils';
5
5
  import { isEqual, isNil, merge } from 'lodash-es';
6
- import { clearSystemCache, getCache } from '../cache.js';
6
+ import { clearSystemCache, getCache, getCacheValue, setCacheValue } from '../cache.js';
7
7
  import { ALIAS_TYPES } from '../constants.js';
8
8
  import { translateDatabaseError } from '../database/errors/translate.js';
9
9
  import { getHelpers } from '../database/helpers/index.js';
10
10
  import getDatabase, { getSchemaInspector } from '../database/index.js';
11
11
  import emitter from '../emitter.js';
12
- import { fetchPermissions } from '../permissions/lib/fetch-permissions.js';
13
- import { fetchPolicies } from '../permissions/lib/fetch-policies.js';
14
- import { validateAccess } from '../permissions/modules/validate-access/validate-access.js';
15
12
  import getDefaultValue from '../utils/get-default-value.js';
16
13
  import { getSystemFieldRowsWithAuthProviders } from '../utils/get-field-system-rows.js';
17
14
  import getLocalType from '../utils/get-local-type.js';
@@ -22,7 +19,9 @@ import { transaction } from '../utils/transaction.js';
22
19
  import { ItemsService } from './items.js';
23
20
  import { PayloadService } from './payload.js';
24
21
  import { RelationsService } from './relations.js';
22
+ import { useEnv } from '@directus/env';
25
23
  const systemFieldRows = getSystemFieldRowsWithAuthProviders();
24
+ const env = useEnv();
26
25
  export class FieldsService {
27
26
  knex;
28
27
  helpers;
@@ -33,6 +32,7 @@ export class FieldsService {
33
32
  schema;
34
33
  cache;
35
34
  systemCache;
35
+ schemaCache;
36
36
  constructor(options) {
37
37
  this.knex = options.knex || getDatabase();
38
38
  this.helpers = getHelpers(this.knex);
@@ -41,21 +41,40 @@ export class FieldsService {
41
41
  this.itemsService = new ItemsService('directus_fields', options);
42
42
  this.payloadService = new PayloadService('directus_fields', options);
43
43
  this.schema = options.schema;
44
- const { cache, systemCache } = getCache();
44
+ const { cache, systemCache, localSchemaCache } = getCache();
45
45
  this.cache = cache;
46
46
  this.systemCache = systemCache;
47
+ this.schemaCache = localSchemaCache;
48
+ }
49
+ get hasReadAccess() {
50
+ return !!this.accountability?.permissions?.find((permission) => {
51
+ return permission.collection === 'directus_fields' && permission.action === 'read';
52
+ });
53
+ }
54
+ async columnInfo(collection, field) {
55
+ const schemaCacheIsEnabled = Boolean(env['CACHE_SCHEMA']);
56
+ let columnInfo = null;
57
+ if (schemaCacheIsEnabled) {
58
+ columnInfo = await getCacheValue(this.schemaCache, 'columnInfo');
59
+ }
60
+ if (!columnInfo) {
61
+ columnInfo = await this.schemaInspector.columnInfo();
62
+ if (schemaCacheIsEnabled) {
63
+ setCacheValue(this.schemaCache, 'columnInfo', columnInfo);
64
+ }
65
+ }
66
+ if (collection) {
67
+ columnInfo = columnInfo.filter((column) => column.table === collection);
68
+ }
69
+ if (field) {
70
+ return columnInfo.find((column) => column.name === field);
71
+ }
72
+ return columnInfo;
47
73
  }
48
74
  async readAll(collection) {
49
75
  let fields;
50
- if (this.accountability) {
51
- await validateAccess({
52
- accountability: this.accountability,
53
- action: 'read',
54
- collection: 'directus_fields',
55
- }, {
56
- schema: this.schema,
57
- knex: this.knex,
58
- });
76
+ if (this.accountability && this.accountability.admin !== true && this.hasReadAccess === false) {
77
+ throw new ForbiddenError();
59
78
  }
60
79
  const nonAuthorizedItemsService = new ItemsService('directus_fields', {
61
80
  knex: this.knex,
@@ -72,7 +91,7 @@ export class FieldsService {
72
91
  fields = (await nonAuthorizedItemsService.readByQuery({ limit: -1 }));
73
92
  fields.push(...systemFieldRows);
74
93
  }
75
- const columns = (await this.schemaInspector.columnInfo(collection)).map((column) => ({
94
+ const columns = (await this.columnInfo(collection)).map((column) => ({
76
95
  ...column,
77
96
  default_value: getDefaultValue(column, fields.find((field) => field.collection === column.table && field.field === column.name)),
78
97
  }));
@@ -124,27 +143,12 @@ export class FieldsService {
124
143
  const result = [...columnsWithSystem, ...aliasFieldsAsField].filter((field) => knownCollections.includes(field.collection));
125
144
  // Filter the result so we only return the fields you have read access to
126
145
  if (this.accountability && this.accountability.admin !== true) {
127
- const policies = await fetchPolicies(this.accountability, { knex: this.knex, schema: this.schema });
128
- const permissions = await fetchPermissions(collection
129
- ? {
130
- action: 'read',
131
- policies,
132
- collections: [collection],
133
- accountability: this.accountability,
134
- }
135
- : {
136
- action: 'read',
137
- policies,
138
- accountability: this.accountability,
139
- }, { knex: this.knex, schema: this.schema });
146
+ const permissions = this.accountability.permissions.filter((permission) => {
147
+ return permission.action === 'read';
148
+ });
140
149
  const allowedFieldsInCollection = {};
141
150
  permissions.forEach((permission) => {
142
- if (!allowedFieldsInCollection[permission.collection]) {
143
- allowedFieldsInCollection[permission.collection] = new Set();
144
- }
145
- for (const field of permission.fields ?? []) {
146
- allowedFieldsInCollection[permission.collection].add(field);
147
- }
151
+ allowedFieldsInCollection[permission.collection] = permission.fields ?? [];
148
152
  });
149
153
  if (collection && collection in allowedFieldsInCollection === false) {
150
154
  throw new ForbiddenError();
@@ -153,9 +157,9 @@ export class FieldsService {
153
157
  if (field.collection in allowedFieldsInCollection === false)
154
158
  return false;
155
159
  const allowedFields = allowedFieldsInCollection[field.collection];
156
- if (allowedFields.has('*'))
160
+ if (allowedFields[0] === '*')
157
161
  return true;
158
- return allowedFields.has(field.field);
162
+ return allowedFields.includes(field.field);
159
163
  });
160
164
  }
161
165
  // Update specific database type overrides
@@ -172,27 +176,18 @@ export class FieldsService {
172
176
  }
173
177
  async readOne(collection, field) {
174
178
  if (this.accountability && this.accountability.admin !== true) {
175
- await validateAccess({
176
- accountability: this.accountability,
177
- action: 'read',
178
- collection,
179
- }, {
180
- schema: this.schema,
181
- knex: this.knex,
182
- });
183
- const policies = await fetchPolicies(this.accountability, { knex: this.knex, schema: this.schema });
184
- const permissions = await fetchPermissions({ action: 'read', policies, collections: [collection], accountability: this.accountability }, { knex: this.knex, schema: this.schema });
185
- let hasAccess = false;
186
- for (const permission of permissions) {
187
- if (permission.fields) {
188
- if (permission.fields.includes('*') || permission.fields.includes(field)) {
189
- hasAccess = true;
190
- break;
191
- }
192
- }
179
+ if (this.hasReadAccess === false) {
180
+ throw new ForbiddenError();
193
181
  }
194
- if (!hasAccess) {
182
+ const permissions = this.accountability.permissions.find((permission) => {
183
+ return permission.action === 'read' && permission.collection === collection;
184
+ });
185
+ if (!permissions || !permissions.fields)
195
186
  throw new ForbiddenError();
187
+ if (permissions.fields.includes('*') === false) {
188
+ const allowedFields = permissions.fields;
189
+ if (allowedFields.includes(field) === false)
190
+ throw new ForbiddenError();
196
191
  }
197
192
  }
198
193
  let column = undefined;
@@ -204,7 +199,7 @@ export class FieldsService {
204
199
  fieldInfo ||
205
200
  systemFieldRows.find((fieldMeta) => fieldMeta.collection === collection && fieldMeta.field === field);
206
201
  try {
207
- column = await this.schemaInspector.columnInfo(collection, field);
202
+ column = await this.columnInfo(collection, field);
208
203
  }
209
204
  catch {
210
205
  // Do nothing
@@ -359,7 +354,7 @@ export class FieldsService {
359
354
  throw new InvalidPayloadError({ reason: 'Alias type cannot be changed' });
360
355
  }
361
356
  if (hookAdjustedField.schema) {
362
- const existingColumn = await this.schemaInspector.columnInfo(collection, hookAdjustedField.field);
357
+ const existingColumn = await this.columnInfo(collection, hookAdjustedField.field);
363
358
  if (hookAdjustedField.schema?.is_nullable === true && existingColumn.is_primary_key) {
364
359
  throw new InvalidPayloadError({ reason: 'Primary key cannot be null' });
365
360
  }
@@ -0,0 +1,2 @@
1
+ import { type Sharp } from 'sharp';
2
+ export declare function getSharpInstance(): Sharp;
@@ -0,0 +1,10 @@
1
+ import { useEnv } from '@directus/env';
2
+ import sharp, {} from 'sharp';
3
+ export function getSharpInstance() {
4
+ const env = useEnv();
5
+ return sharp({
6
+ limitInputPixels: Math.trunc(Math.pow(env['ASSETS_TRANSFORM_IMAGE_MAX_DIMENSION'], 2)),
7
+ sequentialRead: true,
8
+ failOn: env['ASSETS_INVALID_IMAGE_SENSITIVITY_LEVEL'],
9
+ });
10
+ }
@@ -1,19 +1,20 @@
1
+ import { useEnv } from '@directus/env';
1
2
  import exif, {} from 'exif-reader';
2
3
  import { parse as parseIcc } from 'icc';
3
4
  import { pick } from 'lodash-es';
4
5
  import { pipeline } from 'node:stream/promises';
5
- import sharp from 'sharp';
6
- import { useEnv } from '@directus/env';
7
6
  import { useLogger } from '../../../logger/index.js';
7
+ import { getSharpInstance } from '../lib/get-sharp-instance.js';
8
8
  import { parseIptc, parseXmp } from './parse-image-metadata.js';
9
9
  const env = useEnv();
10
10
  const logger = useLogger();
11
11
  export async function getMetadata(stream, allowList = env['FILE_METADATA_ALLOW_LIST']) {
12
- return new Promise((resolve, reject) => {
13
- pipeline(stream, sharp().metadata(async (err, sharpMetadata) => {
12
+ const transformer = getSharpInstance();
13
+ return new Promise((resolve) => {
14
+ pipeline(stream, transformer.metadata(async (err, sharpMetadata) => {
14
15
  if (err) {
15
- reject(err);
16
- return;
16
+ logger.error(err);
17
+ return resolve({});
17
18
  }
18
19
  const metadata = {};
19
20
  if (sharpMetadata.orientation && sharpMetadata.orientation >= 5) {
@@ -12,7 +12,6 @@ import url from 'url';
12
12
  import { RESUMABLE_UPLOADS } from '../constants.js';
13
13
  import emitter from '../emitter.js';
14
14
  import { useLogger } from '../logger/index.js';
15
- import { validateAccess } from '../permissions/modules/validate-access/validate-access.js';
16
15
  import { getAxios } from '../request/index.js';
17
16
  import { getStorage } from '../storage/index.js';
18
17
  import { extractMetadata } from './files/lib/extract-metadata.js';
@@ -58,6 +57,10 @@ export class FilesService extends ItemsService {
58
57
  const fileExtension = path.extname(payload.filename_download) || (payload.type && '.' + extension(payload.type)) || '';
59
58
  // The filename_disk is the FINAL filename on disk
60
59
  payload.filename_disk ||= primaryKey + (fileExtension || '');
60
+ // If the filename_disk extension doesn't match the new mimetype, update it
61
+ if (isReplacement === true && path.extname(payload.filename_disk) !== fileExtension) {
62
+ payload.filename_disk = primaryKey + (fileExtension || '');
63
+ }
61
64
  // Temp filename is used for replacements
62
65
  const tempFilenameDisk = 'temp_' + payload.filename_disk;
63
66
  if (!payload.type) {
@@ -126,6 +129,7 @@ export class FilesService extends ItemsService {
126
129
  const { size } = await storage.location(data.storage).stat(payload.filename_disk);
127
130
  payload.filesize = size;
128
131
  const metadata = await extractMetadata(data.storage, payload);
132
+ payload.uploaded_on = new Date().toISOString();
129
133
  // We do this in a service without accountability. Even if you don't have update permissions to the file,
130
134
  // we still want to be able to set the extracted values from the file on create
131
135
  const sudoService = new ItemsService('directus_files', {
@@ -153,15 +157,9 @@ export class FilesService extends ItemsService {
153
157
  * Import a single file from an external URL
154
158
  */
155
159
  async importOne(importURL, body) {
156
- if (this.accountability) {
157
- await validateAccess({
158
- accountability: this.accountability,
159
- action: 'create',
160
- collection: 'directus_files',
161
- }, {
162
- knex: this.knex,
163
- schema: this.schema,
164
- });
160
+ const fileCreatePermissions = this.accountability?.permissions?.find((permission) => permission.collection === 'directus_files' && permission.action === 'create');
161
+ if (this.accountability && this.accountability?.admin !== true && !fileCreatePermissions) {
162
+ throw new ForbiddenError();
165
163
  }
166
164
  let fileResponse;
167
165
  try {
@@ -20,9 +20,9 @@ export declare class GraphQLService {
20
20
  /**
21
21
  * Generate the GraphQL schema. Pulls from the schema information generated by the get-schema util.
22
22
  */
23
- getSchema(): Promise<GraphQLSchema>;
24
- getSchema(type: 'schema'): Promise<GraphQLSchema>;
25
- getSchema(type: 'sdl'): Promise<GraphQLSchema | string>;
23
+ getSchema(): GraphQLSchema;
24
+ getSchema(type: 'schema'): GraphQLSchema;
25
+ getSchema(type: 'sdl'): GraphQLSchema | string;
26
26
  /**
27
27
  * Generic resolver that's used for every "regular" items/system query. Converts the incoming GraphQL AST / fragments into
28
28
  * Directus' query structure which is then executed by the services.
@@ -11,9 +11,6 @@ import { clearSystemCache, getCache } from '../../cache.js';
11
11
  import { DEFAULT_AUTH_PROVIDER, GENERATE_SPECIAL, REFRESH_COOKIE_OPTIONS, SESSION_COOKIE_OPTIONS, } from '../../constants.js';
12
12
  import getDatabase from '../../database/index.js';
13
13
  import { rateLimiter } from '../../middleware/rate-limiter-registration.js';
14
- import { fetchAllowedFieldMap } from '../../permissions/modules/fetch-allowed-field-map/fetch-allowed-field-map.js';
15
- import { fetchInconsistentFieldMap } from '../../permissions/modules/fetch-inconsistent-field-map/fetch-inconsistent-field-map.js';
16
- import { createDefaultAccountability } from '../../permissions/utils/create-default-accountability.js';
17
14
  import { generateHash } from '../../utils/generate-hash.js';
18
15
  import { getGraphQLType } from '../../utils/get-graphql-type.js';
19
16
  import { getIPFromReq } from '../../utils/get-ip-from-req.js';
@@ -51,9 +48,6 @@ import { GraphQLVoid } from './types/void.js';
51
48
  import { addPathToValidationError } from './utils/add-path-to-validation-error.js';
52
49
  import processError from './utils/process-error.js';
53
50
  import { sanitizeGraphqlSchema } from './utils/sanitize-gql-schema.js';
54
- import { fetchAccountabilityCollectionAccess } from '../../permissions/modules/fetch-accountability-collection-access/fetch-accountability-collection-access.js';
55
- import { fetchAccountabilityPolicyGlobals } from '../../permissions/modules/fetch-accountability-policy-globals/fetch-accountability-policy-globals.js';
56
- import { RolesService } from '../roles.js';
57
51
  const env = useEnv();
58
52
  const validationRules = Array.from(specifiedRules);
59
53
  if (env['GRAPHQL_INTROSPECTION'] === false) {
@@ -86,7 +80,7 @@ export class GraphQLService {
86
80
  * Execute a GraphQL structure
87
81
  */
88
82
  async execute({ document, variables, operationName, contextValue, }) {
89
- const schema = await this.getSchema();
83
+ const schema = this.getSchema();
90
84
  const validationErrors = validate(schema, document, validationRules).map((validationError) => addPathToValidationError(validationError));
91
85
  if (validationErrors.length > 0) {
92
86
  throw new GraphQLValidationError({ errors: validationErrors });
@@ -114,7 +108,7 @@ export class GraphQLService {
114
108
  formattedResult.extensions = result['extensions'];
115
109
  return formattedResult;
116
110
  }
117
- async getSchema(type = 'schema') {
111
+ getSchema(type = 'schema') {
118
112
  const key = `${this.scope}_${type}_${this.accountability?.role}_${this.accountability?.user}`;
119
113
  const cachedSchema = cache.get(key);
120
114
  if (cachedSchema)
@@ -122,53 +116,20 @@ export class GraphQLService {
122
116
  // eslint-disable-next-line @typescript-eslint/no-this-alias
123
117
  const self = this;
124
118
  const schemaComposer = new SchemaComposer();
125
- let schema;
126
119
  const sanitizedSchema = sanitizeGraphqlSchema(this.schema);
127
- if (!this.accountability || this.accountability.admin) {
128
- schema = {
129
- read: sanitizedSchema,
130
- create: sanitizedSchema,
131
- update: sanitizedSchema,
132
- delete: sanitizedSchema,
133
- };
134
- }
135
- else {
136
- schema = {
137
- read: reduceSchema(sanitizedSchema, await fetchAllowedFieldMap({
138
- accountability: this.accountability,
139
- action: 'read',
140
- }, { schema: this.schema, knex: this.knex })),
141
- create: reduceSchema(sanitizedSchema, await fetchAllowedFieldMap({
142
- accountability: this.accountability,
143
- action: 'create',
144
- }, { schema: this.schema, knex: this.knex })),
145
- update: reduceSchema(sanitizedSchema, await fetchAllowedFieldMap({
146
- accountability: this.accountability,
147
- action: 'update',
148
- }, { schema: this.schema, knex: this.knex })),
149
- delete: reduceSchema(sanitizedSchema, await fetchAllowedFieldMap({
150
- accountability: this.accountability,
151
- action: 'delete',
152
- }, { schema: this.schema, knex: this.knex })),
153
- };
154
- }
155
- const inconsistentFields = {
156
- read: await fetchInconsistentFieldMap({
157
- accountability: this.accountability,
158
- action: 'read',
159
- }, { schema: this.schema, knex: this.knex }),
160
- create: await fetchInconsistentFieldMap({
161
- accountability: this.accountability,
162
- action: 'create',
163
- }, { schema: this.schema, knex: this.knex }),
164
- update: await fetchInconsistentFieldMap({
165
- accountability: this.accountability,
166
- action: 'update',
167
- }, { schema: this.schema, knex: this.knex }),
168
- delete: await fetchInconsistentFieldMap({
169
- accountability: this.accountability,
170
- action: 'delete',
171
- }, { schema: this.schema, knex: this.knex }),
120
+ const schema = {
121
+ read: this.accountability?.admin === true
122
+ ? sanitizedSchema
123
+ : reduceSchema(sanitizedSchema, this.accountability?.permissions || null, ['read']),
124
+ create: this.accountability?.admin === true
125
+ ? sanitizedSchema
126
+ : reduceSchema(sanitizedSchema, this.accountability?.permissions || null, ['create']),
127
+ update: this.accountability?.admin === true
128
+ ? sanitizedSchema
129
+ : reduceSchema(sanitizedSchema, this.accountability?.permissions || null, ['update']),
130
+ delete: this.accountability?.admin === true
131
+ ? sanitizedSchema
132
+ : reduceSchema(sanitizedSchema, this.accountability?.permissions || null, ['delete']),
172
133
  };
173
134
  const subscriptionEventType = schemaComposer.createEnumTC({
174
135
  name: 'EventEnum',
@@ -339,18 +300,16 @@ export class GraphQLService {
339
300
  name: action === 'read' ? collection.collection : `${action}_${collection.collection}`,
340
301
  fields: Object.values(collection.fields).reduce((acc, field) => {
341
302
  let type = getGraphQLType(field.type, field.special);
342
- const fieldIsInconsistent = inconsistentFields[action][collection.collection]?.includes(field.field);
343
303
  // GraphQL doesn't differentiate between not-null and has-to-be-submitted. We
344
304
  // can't non-null in update, as that would require every not-nullable field to be
345
305
  // submitted on updates
346
306
  if (field.nullable === false &&
347
307
  !field.defaultValue &&
348
308
  !GENERATE_SPECIAL.some((flag) => field.special.includes(flag)) &&
349
- fieldIsInconsistent === false &&
350
309
  action !== 'update') {
351
310
  type = new GraphQLNonNull(type);
352
311
  }
353
- if (collection.primary === field.field && fieldIsInconsistent === false) {
312
+ if (collection.primary === field.field) {
354
313
  // permissions IDs need to be nullable https://github.com/directus/directus/issues/20509
355
314
  if (collection.collection === 'directus_permissions') {
356
315
  type = GraphQLID;
@@ -1803,7 +1762,7 @@ export class GraphQLService {
1803
1762
  accountability: this.accountability,
1804
1763
  scope: args['scope'] ?? 'items',
1805
1764
  });
1806
- return await service.getSchema('sdl');
1765
+ return service.getSchema('sdl');
1807
1766
  },
1808
1767
  },
1809
1768
  server_ping: {
@@ -1856,7 +1815,7 @@ export class GraphQLService {
1856
1815
  otp: GraphQLString,
1857
1816
  },
1858
1817
  resolve: async (_, args, { req, res }) => {
1859
- const accountability = createDefaultAccountability();
1818
+ const accountability = { role: null };
1860
1819
  if (req?.ip)
1861
1820
  accountability.ip = req.ip;
1862
1821
  const userAgent = req?.get('user-agent');
@@ -1896,7 +1855,7 @@ export class GraphQLService {
1896
1855
  mode: AuthMode,
1897
1856
  },
1898
1857
  resolve: async (_, args, { req, res }) => {
1899
- const accountability = createDefaultAccountability();
1858
+ const accountability = { role: null };
1900
1859
  if (req?.ip)
1901
1860
  accountability.ip = req.ip;
1902
1861
  const userAgent = req?.get('user-agent');
@@ -1954,7 +1913,7 @@ export class GraphQLService {
1954
1913
  mode: AuthMode,
1955
1914
  },
1956
1915
  resolve: async (_, args, { req, res }) => {
1957
- const accountability = createDefaultAccountability();
1916
+ const accountability = { role: null };
1958
1917
  if (req?.ip)
1959
1918
  accountability.ip = req.ip;
1960
1919
  const userAgent = req?.get('user-agent');
@@ -2004,7 +1963,7 @@ export class GraphQLService {
2004
1963
  reset_url: GraphQLString,
2005
1964
  },
2006
1965
  resolve: async (_, args, { req }) => {
2007
- const accountability = createDefaultAccountability();
1966
+ const accountability = { role: null };
2008
1967
  if (req?.ip)
2009
1968
  accountability.ip = req.ip;
2010
1969
  const userAgent = req?.get('user-agent');
@@ -2032,7 +1991,7 @@ export class GraphQLService {
2032
1991
  password: new GraphQLNonNull(GraphQLString),
2033
1992
  },
2034
1993
  resolve: async (_, args, { req }) => {
2035
- const accountability = createDefaultAccountability();
1994
+ const accountability = { role: null };
2036
1995
  if (req?.ip)
2037
1996
  accountability.ip = req.ip;
2038
1997
  const userAgent = req?.get('user-agent');
@@ -2673,69 +2632,6 @@ export class GraphQLService {
2673
2632
  },
2674
2633
  });
2675
2634
  }
2676
- if ('directus_permissions' in schema.read.collections) {
2677
- schemaComposer.Query.addFields({
2678
- permissions_me: {
2679
- type: schemaComposer.createScalarTC({
2680
- name: 'permissions_me_type',
2681
- parseValue: (value) => value,
2682
- serialize: (value) => value,
2683
- }),
2684
- resolve: async (_, _args, __, _info) => {
2685
- if (!this.accountability?.user && !this.accountability?.role)
2686
- return null;
2687
- const result = await fetchAccountabilityCollectionAccess(this.accountability, {
2688
- schema: this.schema,
2689
- knex: getDatabase(),
2690
- });
2691
- return result;
2692
- },
2693
- },
2694
- });
2695
- }
2696
- if ('directus_roles' in schema.read.collections) {
2697
- schemaComposer.Query.addFields({
2698
- roles_me: {
2699
- type: ReadCollectionTypes['directus_roles'].List,
2700
- resolve: async (_, args, __, info) => {
2701
- if (!this.accountability?.user && !this.accountability?.role)
2702
- return null;
2703
- const service = new RolesService({
2704
- accountability: this.accountability,
2705
- schema: this.schema,
2706
- });
2707
- const selections = this.replaceFragmentsInSelections(info.fieldNodes[0]?.selectionSet?.selections, info.fragments);
2708
- const query = this.getQuery(args, selections || [], info.variableValues);
2709
- query.limit = -1;
2710
- const roles = await service.readMany(this.accountability.roles, query);
2711
- return roles;
2712
- },
2713
- },
2714
- });
2715
- }
2716
- if ('directus_policies' in schema.read.collections) {
2717
- schemaComposer.Query.addFields({
2718
- policies_me_globals: {
2719
- type: schemaComposer.createObjectTC({
2720
- name: 'policy_me_globals_type',
2721
- fields: {
2722
- enforce_tfa: 'Boolean',
2723
- app_access: 'Boolean',
2724
- admin_access: 'Boolean',
2725
- },
2726
- }),
2727
- resolve: async (_, _args, __, _info) => {
2728
- if (!this.accountability?.user && !this.accountability?.role)
2729
- return null;
2730
- const result = await fetchAccountabilityPolicyGlobals(this.accountability, {
2731
- schema: this.schema,
2732
- knex: getDatabase(),
2733
- });
2734
- return result;
2735
- },
2736
- },
2737
- });
2738
- }
2739
2635
  if ('directus_users' in schema.update.collections && this.accountability?.user) {
2740
2636
  schemaComposer.Mutation.addFields({
2741
2637
  update_users_me: {
@@ -1,6 +1,7 @@
1
1
  import { EventEmitter, on } from 'events';
2
2
  import { useBus } from '../../bus/index.js';
3
3
  import { getSchema } from '../../utils/get-schema.js';
4
+ import { refreshAccountability } from '../../websocket/authenticate.js';
4
5
  import { getPayload } from '../../websocket/utils/items.js';
5
6
  const messages = createPubSub(new EventEmitter());
6
7
  export function bindPubSub() {
@@ -18,6 +19,7 @@ export function createSubscriptionGenerator(self, event) {
18
19
  if ('event' in args && eventData['action'] !== args['event']) {
19
20
  continue; // skip filtered events
20
21
  }
22
+ const accountability = await refreshAccountability(self.accountability);
21
23
  const schema = await getSchema();
22
24
  const subscription = {
23
25
  collection: eventData['collection'],
@@ -33,7 +35,7 @@ export function createSubscriptionGenerator(self, event) {
33
35
  if (eventData['action'] === 'create') {
34
36
  try {
35
37
  subscription.item = eventData['key'];
36
- const result = await getPayload(subscription, self.accountability, schema, eventData);
38
+ const result = await getPayload(subscription, accountability, schema, eventData);
37
39
  yield {
38
40
  [event]: {
39
41
  key: eventData['key'],
@@ -50,7 +52,7 @@ export function createSubscriptionGenerator(self, event) {
50
52
  for (const key of eventData['keys']) {
51
53
  try {
52
54
  subscription.item = key;
53
- const result = await getPayload(subscription, self.accountability, schema, eventData);
55
+ const result = await getPayload(subscription, accountability, schema, eventData);
54
56
  yield {
55
57
  [event]: {
56
58
  key,
@@ -15,7 +15,6 @@ import StreamArray from 'stream-json/streamers/StreamArray.js';
15
15
  import getDatabase from '../database/index.js';
16
16
  import emitter from '../emitter.js';
17
17
  import { useLogger } from '../logger/index.js';
18
- import { validateAccess } from '../permissions/modules/validate-access/validate-access.js';
19
18
  import { getDateFormatted } from '../utils/get-date-formatted.js';
20
19
  import { getService } from '../utils/get-service.js';
21
20
  import { transaction } from '../utils/transaction.js';
@@ -38,23 +37,10 @@ export class ImportService {
38
37
  async import(collection, mimetype, stream) {
39
38
  if (this.accountability?.admin !== true && isSystemCollection(collection))
40
39
  throw new ForbiddenError();
41
- if (this.accountability) {
42
- await validateAccess({
43
- accountability: this.accountability,
44
- action: 'create',
45
- collection,
46
- }, {
47
- schema: this.schema,
48
- knex: this.knex,
49
- });
50
- await validateAccess({
51
- accountability: this.accountability,
52
- action: 'update',
53
- collection,
54
- }, {
55
- schema: this.schema,
56
- knex: this.knex,
57
- });
40
+ const createPermissions = this.accountability?.permissions?.find((permission) => permission.collection === collection && permission.action === 'create');
41
+ const updatePermissions = this.accountability?.permissions?.find((permission) => permission.collection === collection && permission.action === 'update');
42
+ if (this.accountability?.admin !== true && (!createPermissions || !updatePermissions)) {
43
+ throw new ForbiddenError();
58
44
  }
59
45
  switch (mimetype) {
60
46
  case 'application/json':
@@ -1,7 +1,7 @@
1
- export * from './access.js';
2
1
  export * from './activity.js';
3
2
  export * from './assets.js';
4
3
  export * from './authentication.js';
4
+ export * from './authorization.js';
5
5
  export * from './collections.js';
6
6
  export * from './dashboards.js';
7
7
  export * from './extensions.js';
@@ -18,8 +18,7 @@ export * from './notifications.js';
18
18
  export * from './operations.js';
19
19
  export * from './panels.js';
20
20
  export * from './payload.js';
21
- export * from './permissions.js';
22
- export * from './policies.js';
21
+ export * from './permissions/index.js';
23
22
  export * from './presets.js';
24
23
  export * from './relations.js';
25
24
  export * from './revisions.js';
@@ -1,7 +1,7 @@
1
- export * from './access.js';
2
1
  export * from './activity.js';
3
2
  export * from './assets.js';
4
3
  export * from './authentication.js';
4
+ export * from './authorization.js';
5
5
  export * from './collections.js';
6
6
  export * from './dashboards.js';
7
7
  export * from './extensions.js';
@@ -18,8 +18,7 @@ export * from './notifications.js';
18
18
  export * from './operations.js';
19
19
  export * from './panels.js';
20
20
  export * from './payload.js';
21
- export * from './permissions.js';
22
- export * from './policies.js';
21
+ export * from './permissions/index.js';
23
22
  export * from './presets.js';
24
23
  export * from './relations.js';
25
24
  export * from './revisions.js';