@directus/api 20.0.0 → 21.0.0-rc.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 (330) hide show
  1. package/dist/app.js +5 -5
  2. package/dist/auth/drivers/ldap.js +5 -5
  3. package/dist/auth/drivers/local.js +4 -4
  4. package/dist/auth/drivers/oauth2.js +5 -5
  5. package/dist/auth/drivers/openid.js +3 -5
  6. package/dist/auth/drivers/saml.js +1 -1
  7. package/dist/auth.js +1 -1
  8. package/dist/cache.js +4 -1
  9. package/dist/cli/commands/bootstrap/index.js +10 -3
  10. package/dist/cli/commands/count/index.js +1 -1
  11. package/dist/cli/commands/database/install.js +1 -1
  12. package/dist/cli/commands/database/migrate.js +1 -1
  13. package/dist/cli/commands/init/index.js +9 -10
  14. package/dist/cli/commands/roles/create.js +1 -1
  15. package/dist/cli/commands/schema/apply.js +1 -1
  16. package/dist/cli/commands/schema/snapshot.js +1 -1
  17. package/dist/cli/commands/users/create.js +1 -1
  18. package/dist/cli/commands/users/passwd.js +1 -1
  19. package/dist/cli/load-extensions.js +1 -1
  20. package/dist/cli/utils/defaults.d.ts +4 -11
  21. package/dist/cli/utils/defaults.js +7 -1
  22. package/dist/constants.d.ts +1 -1
  23. package/dist/constants.js +2 -2
  24. package/dist/controllers/access.d.ts +2 -0
  25. package/dist/controllers/access.js +148 -0
  26. package/dist/controllers/assets.js +1 -1
  27. package/dist/controllers/auth.js +6 -17
  28. package/dist/controllers/files.js +1 -1
  29. package/dist/controllers/permissions.js +14 -2
  30. package/dist/controllers/policies.d.ts +2 -0
  31. package/dist/controllers/policies.js +169 -0
  32. package/dist/controllers/roles.js +22 -1
  33. package/dist/controllers/schema.js +1 -1
  34. package/dist/controllers/tus.js +11 -23
  35. package/dist/controllers/users.js +0 -55
  36. package/dist/database/get-ast-from-query/get-ast-from-query.d.ts +16 -0
  37. package/dist/database/get-ast-from-query/get-ast-from-query.js +82 -0
  38. package/dist/database/get-ast-from-query/lib/convert-wildcards.d.ts +13 -0
  39. package/dist/database/get-ast-from-query/lib/convert-wildcards.js +69 -0
  40. package/dist/database/get-ast-from-query/lib/parse-fields.d.ts +15 -0
  41. package/dist/database/get-ast-from-query/lib/parse-fields.js +190 -0
  42. package/dist/database/get-ast-from-query/utils/get-deep-query.d.ts +14 -0
  43. package/dist/database/get-ast-from-query/utils/get-deep-query.js +17 -0
  44. package/dist/database/get-ast-from-query/utils/get-related-collection.d.ts +2 -0
  45. package/dist/database/get-ast-from-query/utils/get-related-collection.js +13 -0
  46. package/dist/database/get-ast-from-query/utils/get-relation.d.ts +2 -0
  47. package/dist/database/get-ast-from-query/utils/get-relation.js +7 -0
  48. package/dist/database/helpers/fn/types.d.ts +2 -1
  49. package/dist/database/helpers/fn/types.js +1 -1
  50. package/dist/database/helpers/geometry/dialects/mssql.d.ts +1 -1
  51. package/dist/database/helpers/geometry/dialects/mssql.js +4 -2
  52. package/dist/database/helpers/geometry/dialects/mysql.js +1 -1
  53. package/dist/database/helpers/geometry/dialects/oracle.d.ts +1 -1
  54. package/dist/database/helpers/geometry/dialects/oracle.js +5 -3
  55. package/dist/database/helpers/geometry/types.d.ts +1 -1
  56. package/dist/database/helpers/geometry/types.js +4 -2
  57. package/dist/database/index.js +3 -2
  58. package/dist/database/migrations/20210518A-add-foreign-key-constraints.js +1 -1
  59. package/dist/database/migrations/20210519A-add-system-fk-triggers.js +1 -1
  60. package/dist/database/migrations/20210802A-replace-groups.js +1 -1
  61. package/dist/database/migrations/20230721A-require-shares-fields.js +1 -1
  62. package/dist/database/migrations/20240710A-permissions-policies.d.ts +3 -0
  63. package/dist/database/migrations/20240710A-permissions-policies.js +169 -0
  64. package/dist/database/migrations/run.js +1 -1
  65. package/dist/database/run-ast/lib/get-db-query.d.ts +4 -0
  66. package/dist/database/run-ast/lib/get-db-query.js +208 -0
  67. package/dist/database/run-ast/lib/parse-current-level.d.ts +7 -0
  68. package/dist/database/run-ast/lib/parse-current-level.js +41 -0
  69. package/dist/database/run-ast/run-ast.d.ts +7 -0
  70. package/dist/database/run-ast/run-ast.js +107 -0
  71. package/dist/database/{run-ast.d.ts → run-ast/types.d.ts} +3 -9
  72. package/dist/database/run-ast/types.js +1 -0
  73. package/dist/database/run-ast/utils/apply-case-when.d.ts +16 -0
  74. package/dist/database/run-ast/utils/apply-case-when.js +26 -0
  75. package/dist/database/run-ast/utils/apply-parent-filters.d.ts +3 -0
  76. package/dist/database/run-ast/utils/apply-parent-filters.js +55 -0
  77. package/dist/database/run-ast/utils/get-column-pre-processor.d.ts +10 -0
  78. package/dist/database/run-ast/utils/get-column-pre-processor.js +57 -0
  79. package/dist/database/run-ast/utils/get-field-alias.d.ts +2 -0
  80. package/dist/database/run-ast/utils/get-field-alias.js +4 -0
  81. package/dist/database/run-ast/utils/get-inner-query-column-pre-processor.d.ts +5 -0
  82. package/dist/database/run-ast/utils/get-inner-query-column-pre-processor.js +23 -0
  83. package/dist/database/run-ast/utils/merge-with-parent-items.d.ts +3 -0
  84. package/dist/database/run-ast/utils/merge-with-parent-items.js +87 -0
  85. package/dist/database/run-ast/utils/remove-temporary-fields.d.ts +3 -0
  86. package/dist/database/run-ast/utils/remove-temporary-fields.js +73 -0
  87. package/dist/emitter.js +1 -1
  88. package/dist/extensions/lib/get-shared-deps-mapping.js +1 -1
  89. package/dist/extensions/lib/installation/manager.js +1 -1
  90. package/dist/extensions/lib/sandbox/register/call-reference.js +1 -1
  91. package/dist/extensions/lib/sandbox/sdk/generators/log.js +1 -1
  92. package/dist/extensions/lib/sync-extensions.js +1 -1
  93. package/dist/extensions/manager.js +1 -1
  94. package/dist/flows.js +4 -5
  95. package/dist/{logger.js → logger/index.js} +2 -8
  96. package/dist/logger/redact-query.d.ts +1 -0
  97. package/dist/logger/redact-query.js +13 -0
  98. package/dist/mailer.js +1 -1
  99. package/dist/middleware/authenticate.js +2 -7
  100. package/dist/middleware/cache.js +2 -2
  101. package/dist/middleware/error-handler.js +1 -1
  102. package/dist/middleware/rate-limiter-global.js +1 -1
  103. package/dist/middleware/respond.js +2 -2
  104. package/dist/operations/log/index.js +1 -1
  105. package/dist/operations/mail/index.js +1 -1
  106. package/dist/permissions/cache.d.ts +2 -0
  107. package/dist/permissions/cache.js +23 -0
  108. package/dist/permissions/lib/fetch-permissions.d.ts +10 -0
  109. package/dist/permissions/lib/fetch-permissions.js +55 -0
  110. package/dist/permissions/lib/fetch-policies.d.ts +7 -0
  111. package/dist/permissions/lib/fetch-policies.js +28 -0
  112. package/dist/permissions/lib/fetch-roles-tree.d.ts +3 -0
  113. package/dist/permissions/lib/fetch-roles-tree.js +28 -0
  114. package/dist/{services/permissions → permissions}/lib/with-app-minimal-permissions.d.ts +1 -1
  115. package/dist/permissions/lib/with-app-minimal-permissions.js +10 -0
  116. package/dist/permissions/modules/fetch-accountability-collection-access/fetch-accountability-collection-access.d.ts +7 -0
  117. package/dist/permissions/modules/fetch-accountability-collection-access/fetch-accountability-collection-access.js +56 -0
  118. package/dist/permissions/modules/fetch-accountability-policy-globals/fetch-accountability-policy-globals.d.ts +3 -0
  119. package/dist/permissions/modules/fetch-accountability-policy-globals/fetch-accountability-policy-globals.js +16 -0
  120. package/dist/permissions/modules/fetch-allowed-collections/fetch-allowed-collections.d.ts +8 -0
  121. package/dist/permissions/modules/fetch-allowed-collections/fetch-allowed-collections.js +24 -0
  122. package/dist/permissions/modules/fetch-allowed-field-map/fetch-allowed-field-map.d.ts +9 -0
  123. package/dist/permissions/modules/fetch-allowed-field-map/fetch-allowed-field-map.js +31 -0
  124. package/dist/permissions/modules/fetch-allowed-fields/fetch-allowed-fields.d.ts +16 -0
  125. package/dist/permissions/modules/fetch-allowed-fields/fetch-allowed-fields.js +27 -0
  126. package/dist/permissions/modules/fetch-global-access/fetch-global-access.d.ts +10 -0
  127. package/dist/permissions/modules/fetch-global-access/fetch-global-access.js +23 -0
  128. package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-roles.d.ts +5 -0
  129. package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-roles.js +7 -0
  130. package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-user.d.ts +5 -0
  131. package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-user.js +10 -0
  132. package/dist/permissions/modules/fetch-global-access/types.d.ts +4 -0
  133. package/dist/permissions/modules/fetch-global-access/types.js +1 -0
  134. package/dist/permissions/modules/fetch-global-access/utils/fetch-global-access-for-query.d.ts +4 -0
  135. package/dist/permissions/modules/fetch-global-access/utils/fetch-global-access-for-query.js +27 -0
  136. package/dist/permissions/modules/fetch-inconsistent-field-map/fetch-inconsistent-field-map.d.ts +12 -0
  137. package/dist/permissions/modules/fetch-inconsistent-field-map/fetch-inconsistent-field-map.js +32 -0
  138. package/dist/permissions/modules/fetch-policies-ip-access/fetch-policies-ip-access.d.ts +4 -0
  139. package/dist/permissions/modules/fetch-policies-ip-access/fetch-policies-ip-access.js +29 -0
  140. package/dist/permissions/modules/process-ast/lib/extract-fields-from-children.d.ts +4 -0
  141. package/dist/permissions/modules/process-ast/lib/extract-fields-from-children.js +49 -0
  142. package/dist/permissions/modules/process-ast/lib/extract-fields-from-query.d.ts +3 -0
  143. package/dist/permissions/modules/process-ast/lib/extract-fields-from-query.js +56 -0
  144. package/dist/permissions/modules/process-ast/lib/field-map-from-ast.d.ts +4 -0
  145. package/dist/permissions/modules/process-ast/lib/field-map-from-ast.js +8 -0
  146. package/dist/permissions/modules/process-ast/lib/inject-cases.d.ts +9 -0
  147. package/dist/permissions/modules/process-ast/lib/inject-cases.js +93 -0
  148. package/dist/permissions/modules/process-ast/process-ast.d.ts +9 -0
  149. package/dist/permissions/modules/process-ast/process-ast.js +39 -0
  150. package/dist/permissions/modules/process-ast/types.d.ts +24 -0
  151. package/dist/permissions/modules/process-ast/types.js +1 -0
  152. package/dist/permissions/modules/process-ast/utils/collections-in-field-map.d.ts +2 -0
  153. package/dist/permissions/modules/process-ast/utils/collections-in-field-map.js +7 -0
  154. package/dist/permissions/modules/process-ast/utils/dedupe-access.d.ts +12 -0
  155. package/dist/permissions/modules/process-ast/utils/dedupe-access.js +30 -0
  156. package/dist/permissions/modules/process-ast/utils/extract-paths-from-query.d.ts +15 -0
  157. package/dist/permissions/modules/process-ast/utils/extract-paths-from-query.js +50 -0
  158. package/dist/permissions/modules/process-ast/utils/find-related-collection.d.ts +3 -0
  159. package/dist/permissions/modules/process-ast/utils/find-related-collection.js +9 -0
  160. package/dist/permissions/modules/process-ast/utils/flatten-filter.d.ts +3 -0
  161. package/dist/permissions/modules/process-ast/utils/flatten-filter.js +34 -0
  162. package/dist/permissions/modules/process-ast/utils/format-a2o-key.d.ts +1 -0
  163. package/dist/permissions/modules/process-ast/utils/format-a2o-key.js +3 -0
  164. package/dist/permissions/modules/process-ast/utils/get-info-for-path.d.ts +5 -0
  165. package/dist/permissions/modules/process-ast/utils/get-info-for-path.js +7 -0
  166. package/dist/permissions/modules/process-ast/utils/has-item-permissions.d.ts +2 -0
  167. package/dist/permissions/modules/process-ast/utils/has-item-permissions.js +3 -0
  168. package/dist/permissions/modules/process-ast/utils/stringify-query-path.d.ts +2 -0
  169. package/dist/permissions/modules/process-ast/utils/stringify-query-path.js +3 -0
  170. package/dist/permissions/modules/process-ast/utils/validate-path/create-error.d.ts +3 -0
  171. package/dist/permissions/modules/process-ast/utils/validate-path/create-error.js +16 -0
  172. package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-existence.d.ts +2 -0
  173. package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-existence.js +12 -0
  174. package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-permissions.d.ts +2 -0
  175. package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-permissions.js +28 -0
  176. package/dist/permissions/modules/process-payload/lib/is-field-nullable.d.ts +5 -0
  177. package/dist/permissions/modules/process-payload/lib/is-field-nullable.js +12 -0
  178. package/dist/permissions/modules/process-payload/process-payload.d.ts +13 -0
  179. package/dist/permissions/modules/process-payload/process-payload.js +77 -0
  180. package/dist/permissions/modules/validate-access/lib/validate-collection-access.d.ts +12 -0
  181. package/dist/permissions/modules/validate-access/lib/validate-collection-access.js +11 -0
  182. package/dist/permissions/modules/validate-access/lib/validate-item-access.d.ts +9 -0
  183. package/dist/permissions/modules/validate-access/lib/validate-item-access.js +33 -0
  184. package/dist/permissions/modules/validate-access/validate-access.d.ts +14 -0
  185. package/dist/permissions/modules/validate-access/validate-access.js +28 -0
  186. package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-count.d.ts +1 -0
  187. package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-count.js +8 -0
  188. package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-users.d.ts +5 -0
  189. package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-users.js +10 -0
  190. package/dist/permissions/types.d.ts +6 -0
  191. package/dist/permissions/types.js +1 -0
  192. package/dist/permissions/utils/create-default-accountability.d.ts +2 -0
  193. package/dist/permissions/utils/create-default-accountability.js +11 -0
  194. package/dist/permissions/utils/extract-required-dynamic-variable-context.d.ts +8 -0
  195. package/dist/permissions/utils/extract-required-dynamic-variable-context.js +27 -0
  196. package/dist/permissions/utils/fetch-dynamic-variable-context.d.ts +9 -0
  197. package/dist/permissions/utils/fetch-dynamic-variable-context.js +43 -0
  198. package/dist/permissions/utils/filter-policies-by-ip.d.ts +2 -0
  199. package/dist/permissions/utils/filter-policies-by-ip.js +15 -0
  200. package/dist/permissions/utils/get-unaliased-field-key.d.ts +5 -0
  201. package/dist/permissions/utils/get-unaliased-field-key.js +17 -0
  202. package/dist/permissions/utils/process-permissions.d.ts +7 -0
  203. package/dist/permissions/utils/process-permissions.js +9 -0
  204. package/dist/permissions/utils/with-cache.d.ts +10 -0
  205. package/dist/permissions/utils/with-cache.js +25 -0
  206. package/dist/request/is-denied-ip.js +1 -1
  207. package/dist/server.js +1 -1
  208. package/dist/services/access.d.ts +10 -0
  209. package/dist/services/access.js +43 -0
  210. package/dist/services/activity.js +23 -11
  211. package/dist/services/assets.d.ts +2 -3
  212. package/dist/services/assets.js +11 -6
  213. package/dist/services/authentication.js +18 -18
  214. package/dist/services/collections.js +18 -17
  215. package/dist/services/fields.d.ts +0 -1
  216. package/dist/services/fields.js +53 -24
  217. package/dist/services/files/utils/get-metadata.js +1 -1
  218. package/dist/services/files.js +25 -15
  219. package/dist/services/graphql/index.d.ts +3 -3
  220. package/dist/services/graphql/index.js +126 -22
  221. package/dist/services/graphql/subscription.js +2 -4
  222. package/dist/services/graphql/utils/process-error.js +1 -1
  223. package/dist/services/graphql/utils/sanitize-gql-schema.js +1 -1
  224. package/dist/services/import-export.js +19 -5
  225. package/dist/services/index.d.ts +3 -2
  226. package/dist/services/index.js +3 -2
  227. package/dist/services/items.d.ts +3 -3
  228. package/dist/services/items.js +115 -44
  229. package/dist/services/mail/index.js +1 -1
  230. package/dist/services/meta.js +60 -23
  231. package/dist/services/notifications.js +15 -7
  232. package/dist/services/payload.d.ts +9 -10
  233. package/dist/services/payload.js +18 -3
  234. package/dist/services/{permissions/index.d.ts → permissions.d.ts} +5 -7
  235. package/dist/services/{permissions/index.js → permissions.js} +30 -54
  236. package/dist/services/policies.d.ts +12 -0
  237. package/dist/services/policies.js +87 -0
  238. package/dist/services/relations.d.ts +0 -6
  239. package/dist/services/relations.js +26 -29
  240. package/dist/services/roles.d.ts +4 -12
  241. package/dist/services/roles.js +57 -424
  242. package/dist/services/server.js +1 -1
  243. package/dist/services/shares.d.ts +0 -2
  244. package/dist/services/shares.js +13 -9
  245. package/dist/services/specifications.d.ts +2 -2
  246. package/dist/services/specifications.js +39 -27
  247. package/dist/services/tus/data-store.js +3 -1
  248. package/dist/services/users.d.ts +1 -5
  249. package/dist/services/users.js +79 -162
  250. package/dist/services/utils.js +11 -7
  251. package/dist/services/versions.d.ts +0 -2
  252. package/dist/services/versions.js +34 -10
  253. package/dist/services/webhooks.js +1 -1
  254. package/dist/telemetry/lib/get-report.js +2 -2
  255. package/dist/telemetry/lib/track.js +1 -1
  256. package/dist/telemetry/utils/check-user-limits.d.ts +5 -0
  257. package/dist/telemetry/utils/check-user-limits.js +19 -0
  258. package/dist/types/ast.d.ts +43 -1
  259. package/dist/types/items.d.ts +11 -0
  260. package/dist/utils/apply-diff.js +1 -1
  261. package/dist/utils/apply-query.d.ts +4 -3
  262. package/dist/utils/apply-query.js +37 -8
  263. package/dist/utils/delete-from-require-cache.js +1 -1
  264. package/dist/utils/fetch-user-count/fetch-access-lookup.d.ts +17 -0
  265. package/dist/utils/fetch-user-count/fetch-access-lookup.js +22 -0
  266. package/dist/utils/fetch-user-count/fetch-access-roles.d.ts +16 -0
  267. package/dist/utils/fetch-user-count/fetch-access-roles.js +37 -0
  268. package/dist/utils/fetch-user-count/fetch-active-users.d.ts +6 -0
  269. package/dist/utils/fetch-user-count/fetch-active-users.js +3 -0
  270. package/dist/utils/fetch-user-count/fetch-user-count.d.ts +12 -0
  271. package/dist/utils/fetch-user-count/fetch-user-count.js +57 -0
  272. package/dist/utils/fetch-user-count/get-user-count-query.d.ts +20 -0
  273. package/dist/utils/fetch-user-count/get-user-count-query.js +17 -0
  274. package/dist/utils/get-accountability-for-role.js +16 -25
  275. package/dist/utils/get-accountability-for-token.js +17 -16
  276. package/dist/utils/get-cache-key.d.ts +1 -1
  277. package/dist/utils/get-cache-key.js +12 -1
  278. package/dist/utils/get-column.d.ts +2 -1
  279. package/dist/utils/get-column.js +1 -0
  280. package/dist/utils/get-default-value.js +1 -1
  281. package/dist/utils/get-ip-from-req.js +1 -1
  282. package/dist/utils/get-schema.js +1 -1
  283. package/dist/utils/get-service.js +5 -1
  284. package/dist/utils/is-url-allowed.js +1 -1
  285. package/dist/utils/reduce-schema.d.ts +4 -6
  286. package/dist/utils/reduce-schema.js +16 -32
  287. package/dist/utils/sanitize-query.js +1 -1
  288. package/dist/utils/transaction.js +1 -1
  289. package/dist/utils/validate-env.js +1 -1
  290. package/dist/utils/validate-storage.js +1 -1
  291. package/dist/utils/validate-user-count-integrity.d.ts +13 -0
  292. package/dist/utils/validate-user-count-integrity.js +29 -0
  293. package/dist/websocket/authenticate.d.ts +0 -2
  294. package/dist/websocket/authenticate.js +0 -12
  295. package/dist/websocket/controllers/base.d.ts +1 -1
  296. package/dist/websocket/controllers/base.js +21 -17
  297. package/dist/websocket/controllers/graphql.js +2 -5
  298. package/dist/websocket/controllers/hooks.js +4 -0
  299. package/dist/websocket/controllers/rest.js +1 -3
  300. package/dist/websocket/errors.js +1 -1
  301. package/dist/websocket/handlers/subscribe.js +0 -2
  302. package/dist/websocket/utils/items.d.ts +1 -1
  303. package/package.json +28 -27
  304. package/dist/database/run-ast.js +0 -450
  305. package/dist/middleware/check-ip.d.ts +0 -2
  306. package/dist/middleware/check-ip.js +0 -37
  307. package/dist/middleware/get-permissions.d.ts +0 -3
  308. package/dist/middleware/get-permissions.js +0 -10
  309. package/dist/services/authorization.d.ts +0 -17
  310. package/dist/services/authorization.js +0 -456
  311. package/dist/services/permissions/lib/with-app-minimal-permissions.js +0 -13
  312. package/dist/telemetry/utils/check-increased-user-limits.d.ts +0 -7
  313. package/dist/telemetry/utils/check-increased-user-limits.js +0 -25
  314. package/dist/telemetry/utils/get-role-counts-by-roles.d.ts +0 -6
  315. package/dist/telemetry/utils/get-role-counts-by-roles.js +0 -27
  316. package/dist/telemetry/utils/get-role-counts-by-users.d.ts +0 -11
  317. package/dist/telemetry/utils/get-role-counts-by-users.js +0 -34
  318. package/dist/telemetry/utils/get-user-count.d.ts +0 -8
  319. package/dist/telemetry/utils/get-user-count.js +0 -33
  320. package/dist/telemetry/utils/get-user-counts-by-roles.d.ts +0 -7
  321. package/dist/telemetry/utils/get-user-counts-by-roles.js +0 -35
  322. package/dist/utils/get-ast-from-query.d.ts +0 -13
  323. package/dist/utils/get-ast-from-query.js +0 -297
  324. package/dist/utils/get-permissions.d.ts +0 -2
  325. package/dist/utils/get-permissions.js +0 -150
  326. package/dist/utils/merge-permissions-for-share.d.ts +0 -4
  327. package/dist/utils/merge-permissions-for-share.js +0 -109
  328. package/dist/utils/merge-permissions.d.ts +0 -3
  329. package/dist/utils/merge-permissions.js +0 -95
  330. /package/dist/{logger.d.ts → logger/index.d.ts} +0 -0
@@ -1,12 +1,10 @@
1
- import type { Item, ItemPermissions, PermissionsAction, PrimaryKey, Query } from '@directus/types';
2
- import type Keyv from 'keyv';
3
- import type { AbstractServiceOptions, MutationOptions } from '../../types/index.js';
4
- import type { QueryOptions } from '../items.js';
5
- import { ItemsService } from '../items.js';
1
+ import type { Item, ItemPermissions, PrimaryKey, Query } from '@directus/types';
2
+ import type { AbstractServiceOptions, MutationOptions } from '../types/index.js';
3
+ import type { QueryOptions } from './items.js';
4
+ import { ItemsService } from './items.js';
6
5
  export declare class PermissionsService extends ItemsService {
7
- systemCache: Keyv<any>;
8
6
  constructor(options: AbstractServiceOptions);
9
- getAllowedFields(action: PermissionsAction, collection?: string): Record<string, string[]>;
7
+ private clearCaches;
10
8
  readByQuery(query: Query, opts?: QueryOptions): Promise<Partial<Item>[]>;
11
9
  createOne(data: Partial<Item>, opts?: MutationOptions): Promise<PrimaryKey>;
12
10
  createMany(data: Partial<Item>[], opts?: MutationOptions): Promise<PrimaryKey[]>;
@@ -1,32 +1,17 @@
1
1
  import { ForbiddenError } from '@directus/errors';
2
- import { clearSystemCache, getCache } from '../../cache.js';
3
- import { AuthorizationService } from '../authorization.js';
4
- import { ItemsService } from '../items.js';
5
- import { withAppMinimalPermissions } from './lib/with-app-minimal-permissions.js';
2
+ import { clearSystemCache } from '../cache.js';
3
+ import { withAppMinimalPermissions } from '../permissions/lib/with-app-minimal-permissions.js';
4
+ import { validateAccess } from '../permissions/modules/validate-access/validate-access.js';
5
+ import { ItemsService } from './items.js';
6
6
  export class PermissionsService extends ItemsService {
7
- systemCache;
8
7
  constructor(options) {
9
8
  super('directus_permissions', options);
10
- const { systemCache } = getCache();
11
- this.systemCache = systemCache;
12
9
  }
13
- getAllowedFields(action, collection) {
14
- const results = this.accountability?.permissions?.filter((permission) => {
15
- let matchesCollection = true;
16
- if (collection) {
17
- matchesCollection = permission.collection === collection;
18
- }
19
- const matchesAction = permission.action === action;
20
- return collection ? matchesCollection && matchesAction : matchesAction;
21
- }) ?? [];
22
- const fieldsPerCollection = {};
23
- for (const result of results) {
24
- const { collection, fields } = result;
25
- if (!fieldsPerCollection[collection])
26
- fieldsPerCollection[collection] = [];
27
- fieldsPerCollection[collection].push(...(fields ?? []));
10
+ async clearCaches(opts) {
11
+ await clearSystemCache({ autoPurgeCache: opts?.autoPurgeCache });
12
+ if (this.cache && opts?.autoPurgeCache !== false) {
13
+ await this.cache.clear();
28
14
  }
29
- return fieldsPerCollection;
30
15
  }
31
16
  async readByQuery(query, opts) {
32
17
  const result = (await super.readByQuery(query, opts));
@@ -34,50 +19,32 @@ export class PermissionsService extends ItemsService {
34
19
  }
35
20
  async createOne(data, opts) {
36
21
  const res = await super.createOne(data, opts);
37
- await clearSystemCache({ autoPurgeCache: opts?.autoPurgeCache });
38
- if (this.cache && opts?.autoPurgeCache !== false) {
39
- await this.cache.clear();
40
- }
22
+ await this.clearCaches(opts);
41
23
  return res;
42
24
  }
43
25
  async createMany(data, opts) {
44
26
  const res = await super.createMany(data, opts);
45
- await clearSystemCache({ autoPurgeCache: opts?.autoPurgeCache });
46
- if (this.cache && opts?.autoPurgeCache !== false) {
47
- await this.cache.clear();
48
- }
27
+ await this.clearCaches(opts);
49
28
  return res;
50
29
  }
51
30
  async updateBatch(data, opts) {
52
31
  const res = await super.updateBatch(data, opts);
53
- await clearSystemCache({ autoPurgeCache: opts?.autoPurgeCache });
54
- if (this.cache && opts?.autoPurgeCache !== false) {
55
- await this.cache.clear();
56
- }
32
+ await this.clearCaches(opts);
57
33
  return res;
58
34
  }
59
35
  async updateMany(keys, data, opts) {
60
36
  const res = await super.updateMany(keys, data, opts);
61
- await clearSystemCache({ autoPurgeCache: opts?.autoPurgeCache });
62
- if (this.cache && opts?.autoPurgeCache !== false) {
63
- await this.cache.clear();
64
- }
37
+ await this.clearCaches(opts);
65
38
  return res;
66
39
  }
67
40
  async upsertMany(payloads, opts) {
68
41
  const res = await super.upsertMany(payloads, opts);
69
- await clearSystemCache({ autoPurgeCache: opts?.autoPurgeCache });
70
- if (this.cache && opts?.autoPurgeCache !== false) {
71
- await this.cache.clear();
72
- }
42
+ await this.clearCaches(opts);
73
43
  return res;
74
44
  }
75
45
  async deleteMany(keys, opts) {
76
46
  const res = await super.deleteMany(keys, opts);
77
- await clearSystemCache({ autoPurgeCache: opts?.autoPurgeCache });
78
- if (this.cache && opts?.autoPurgeCache !== false) {
79
- await this.cache.clear();
80
- }
47
+ await this.clearCaches(opts);
81
48
  return res;
82
49
  }
83
50
  async getItemPermissions(collection, primaryKey) {
@@ -115,16 +82,25 @@ export class PermissionsService extends ItemsService {
115
82
  updateAction = 'create';
116
83
  }
117
84
  }
118
- const authorizationService = new AuthorizationService({
119
- knex: this.knex,
120
- accountability: this.accountability,
121
- schema: this.schema,
122
- });
123
85
  await Promise.all(Object.keys(itemPermissions).map((key) => {
124
86
  const action = key;
125
87
  const checkAction = action === 'update' ? updateAction : action;
126
- return authorizationService
127
- .checkAccess(checkAction, collection, primaryKey)
88
+ if (!this.accountability) {
89
+ itemPermissions[action].access = true;
90
+ return Promise.resolve();
91
+ }
92
+ const opts = {
93
+ accountability: this.accountability,
94
+ action: checkAction,
95
+ collection,
96
+ };
97
+ if (primaryKey) {
98
+ opts.primaryKeys = [primaryKey];
99
+ }
100
+ return validateAccess(opts, {
101
+ schema: this.schema,
102
+ knex: this.knex,
103
+ })
128
104
  .then(() => (itemPermissions[action].access = true))
129
105
  .catch(() => { });
130
106
  }));
@@ -0,0 +1,12 @@
1
+ import type { Policy, PrimaryKey } from '@directus/types';
2
+ import type { AbstractServiceOptions, MutationOptions } from '../types/index.js';
3
+ import { ItemsService } from './items.js';
4
+ export declare class PoliciesService extends ItemsService<Policy> {
5
+ constructor(options: AbstractServiceOptions);
6
+ private clearCaches;
7
+ private isIpAccessValid;
8
+ private assertValidIpAccess;
9
+ createOne(data: Partial<Policy>, opts?: MutationOptions): Promise<PrimaryKey>;
10
+ updateMany(keys: PrimaryKey[], data: Partial<Policy>, opts?: MutationOptions): Promise<PrimaryKey[]>;
11
+ deleteMany(keys: PrimaryKey[], opts?: MutationOptions): Promise<PrimaryKey[]>;
12
+ }
@@ -0,0 +1,87 @@
1
+ import { InvalidPayloadError } from '@directus/errors';
2
+ import { getMatch } from 'ip-matching';
3
+ import { clearSystemCache } from '../cache.js';
4
+ import { clearCache as clearPermissionsCache } from '../permissions/cache.js';
5
+ import { UserIntegrityCheckFlag } from '../utils/validate-user-count-integrity.js';
6
+ import { ItemsService } from './items.js';
7
+ export class PoliciesService extends ItemsService {
8
+ constructor(options) {
9
+ super('directus_policies', options);
10
+ }
11
+ async clearCaches(opts) {
12
+ await clearSystemCache({ autoPurgeCache: opts?.autoPurgeCache });
13
+ if (this.cache && opts?.autoPurgeCache !== false) {
14
+ await this.cache.clear();
15
+ }
16
+ }
17
+ isIpAccessValid(value) {
18
+ if (value === undefined)
19
+ return false;
20
+ if (value === null)
21
+ return true;
22
+ if (Array.isArray(value) && value.length === 0)
23
+ return true;
24
+ for (const ip of value) {
25
+ if (typeof ip !== 'string' || ip.includes('*'))
26
+ return false;
27
+ try {
28
+ const match = getMatch(ip);
29
+ if (match.type == 'IPMask')
30
+ return false;
31
+ }
32
+ catch {
33
+ return false;
34
+ }
35
+ }
36
+ return true;
37
+ }
38
+ assertValidIpAccess(partialItem) {
39
+ if ('ip_access' in partialItem && !this.isIpAccessValid(partialItem['ip_access'])) {
40
+ throw new InvalidPayloadError({
41
+ reason: 'IP Access contains an incorrect value. Valid values are: IP addresses, IP ranges and CIDR blocks',
42
+ });
43
+ }
44
+ }
45
+ async createOne(data, opts = {}) {
46
+ this.assertValidIpAccess(data);
47
+ // A policy has been created, but the attachment to a user/role happens in the AccessService,
48
+ // so no need to check user integrity
49
+ const result = await super.createOne(data, opts);
50
+ // TODO is this necessary? Since the attachment should be handled in the AccessService
51
+ // A new policy has created, clear the permissions cache
52
+ await clearPermissionsCache();
53
+ return result;
54
+ }
55
+ async updateMany(keys, data, opts = {}) {
56
+ this.assertValidIpAccess(data);
57
+ if ('admin_access' in data) {
58
+ let flags = UserIntegrityCheckFlag.RemainingAdmins;
59
+ if (data['admin_access'] === true) {
60
+ // Only need to perform a full user count if the policy allows admin access
61
+ flags |= UserIntegrityCheckFlag.All;
62
+ }
63
+ opts.userIntegrityCheckFlags = (opts.userIntegrityCheckFlags ?? UserIntegrityCheckFlag.None) | flags;
64
+ }
65
+ if ('app_access' in data) {
66
+ opts.userIntegrityCheckFlags =
67
+ (opts.userIntegrityCheckFlags ?? UserIntegrityCheckFlag.None) | UserIntegrityCheckFlag.UserLimits;
68
+ }
69
+ if (opts.userIntegrityCheckFlags)
70
+ opts.onRequireUserIntegrityCheck?.(opts.userIntegrityCheckFlags);
71
+ const result = await super.updateMany(keys, data, opts);
72
+ if ('admin_access' in data || 'app_access' in data || 'ip_access' in data || 'enforce_tfa' in data) {
73
+ // Some relevant properties on policies have been updated, clear the caches
74
+ await this.clearCaches(opts);
75
+ }
76
+ return result;
77
+ }
78
+ async deleteMany(keys, opts = {}) {
79
+ opts.userIntegrityCheckFlags = UserIntegrityCheckFlag.All;
80
+ opts.onRequireUserIntegrityCheck?.(opts.userIntegrityCheckFlags);
81
+ const result = await super.deleteMany(keys, opts);
82
+ // TODO is this necessary? Since the detachment should be handled in the AccessService
83
+ // Some policies have been deleted, clear the permissions cache
84
+ await this.clearCaches(opts);
85
+ return result;
86
+ }
87
+ }
@@ -5,10 +5,8 @@ import type { Knex } from 'knex';
5
5
  import type { Helpers } from '../database/helpers/index.js';
6
6
  import type { AbstractServiceOptions, MutationOptions } from '../types/index.js';
7
7
  import { ItemsService, type QueryOptions } from './items.js';
8
- import { PermissionsService } from './permissions/index.js';
9
8
  export declare class RelationsService {
10
9
  knex: Knex;
11
- permissionsService: PermissionsService;
12
10
  schemaInspector: SchemaInspector;
13
11
  accountability: Accountability | null;
14
12
  schema: SchemaOverview;
@@ -32,10 +30,6 @@ export declare class RelationsService {
32
30
  * Delete an existing relationship
33
31
  */
34
32
  deleteOne(collection: string, field: string, opts?: MutationOptions): Promise<void>;
35
- /**
36
- * Whether or not the current user has read access to relations
37
- */
38
- private get hasReadAccess();
39
33
  /**
40
34
  * Combine raw schema foreign key information with Directus relations meta rows to form final
41
35
  * Relation objects
@@ -6,14 +6,15 @@ import { clearSystemCache, getCache } from '../cache.js';
6
6
  import { getHelpers } from '../database/helpers/index.js';
7
7
  import getDatabase, { getSchemaInspector } from '../database/index.js';
8
8
  import emitter from '../emitter.js';
9
+ import { fetchAllowedFieldMap } from '../permissions/modules/fetch-allowed-field-map/fetch-allowed-field-map.js';
10
+ import { fetchAllowedFields } from '../permissions/modules/fetch-allowed-fields/fetch-allowed-fields.js';
11
+ import { validateAccess } from '../permissions/modules/validate-access/validate-access.js';
9
12
  import { getDefaultIndexName } from '../utils/get-default-index-name.js';
10
13
  import { getSchema } from '../utils/get-schema.js';
11
14
  import { transaction } from '../utils/transaction.js';
12
15
  import { ItemsService } from './items.js';
13
- import { PermissionsService } from './permissions/index.js';
14
16
  export class RelationsService {
15
17
  knex;
16
- permissionsService;
17
18
  schemaInspector;
18
19
  accountability;
19
20
  schema;
@@ -22,7 +23,6 @@ export class RelationsService {
22
23
  helpers;
23
24
  constructor(options) {
24
25
  this.knex = options.knex || getDatabase();
25
- this.permissionsService = new PermissionsService(options);
26
26
  this.schemaInspector = options.knex ? createInspector(options.knex) : getSchemaInspector();
27
27
  this.schema = options.schema;
28
28
  this.accountability = options.accountability || null;
@@ -37,8 +37,15 @@ export class RelationsService {
37
37
  this.helpers = getHelpers(this.knex);
38
38
  }
39
39
  async readAll(collection, opts) {
40
- if (this.accountability && this.accountability.admin !== true && this.hasReadAccess === false) {
41
- throw new ForbiddenError();
40
+ if (this.accountability) {
41
+ await validateAccess({
42
+ accountability: this.accountability,
43
+ action: 'read',
44
+ collection: 'directus_relations',
45
+ }, {
46
+ knex: this.knex,
47
+ schema: this.schema,
48
+ });
42
49
  }
43
50
  const metaReadQuery = {
44
51
  limit: -1,
@@ -64,18 +71,17 @@ export class RelationsService {
64
71
  }
65
72
  async readOne(collection, field) {
66
73
  if (this.accountability && this.accountability.admin !== true) {
67
- if (this.hasReadAccess === false) {
68
- throw new ForbiddenError();
69
- }
70
- const permissions = this.accountability.permissions?.find((permission) => {
71
- return permission.action === 'read' && permission.collection === collection;
74
+ await validateAccess({
75
+ accountability: this.accountability,
76
+ action: 'read',
77
+ collection: 'directus_relations',
78
+ }, {
79
+ schema: this.schema,
80
+ knex: this.knex,
72
81
  });
73
- if (!permissions || !permissions.fields)
82
+ const allowedFields = await fetchAllowedFields({ collection, action: 'read', accountability: this.accountability }, { schema: this.schema, knex: this.knex });
83
+ if (allowedFields.includes('*') === false && allowedFields.includes(field) === false) {
74
84
  throw new ForbiddenError();
75
- if (permissions.fields.includes('*') === false) {
76
- const allowedFields = permissions.fields;
77
- if (allowedFields.includes(field) === false)
78
- throw new ForbiddenError();
79
85
  }
80
86
  }
81
87
  const metaRow = await this.relationsItemService.readByQuery({
@@ -357,14 +363,6 @@ export class RelationsService {
357
363
  }
358
364
  }
359
365
  }
360
- /**
361
- * Whether or not the current user has read access to relations
362
- */
363
- get hasReadAccess() {
364
- return !!this.accountability?.permissions?.find((permission) => {
365
- return permission.collection === 'directus_relations' && permission.action === 'read';
366
- });
367
- }
368
366
  /**
369
367
  * Combine raw schema foreign key information with Directus relations meta rows to form final
370
368
  * Relation objects
@@ -413,12 +411,11 @@ export class RelationsService {
413
411
  async filterForbidden(relations) {
414
412
  if (this.accountability === null || this.accountability?.admin === true)
415
413
  return relations;
416
- const allowedCollections = this.accountability.permissions
417
- ?.filter((permission) => {
418
- return permission.action === 'read';
419
- })
420
- .map(({ collection }) => collection) ?? [];
421
- const allowedFields = this.permissionsService.getAllowedFields('read');
414
+ const allowedFields = await fetchAllowedFieldMap({
415
+ accountability: this.accountability,
416
+ action: 'read',
417
+ }, { schema: this.schema, knex: this.knex });
418
+ const allowedCollections = Object.keys(allowedFields);
422
419
  relations = toArray(relations);
423
420
  return relations.filter((relation) => {
424
421
  let collectionsAllowed = true;
@@ -1,18 +1,10 @@
1
- import type { Item, PrimaryKey, Query } from '@directus/types';
1
+ import type { Item, PrimaryKey } from '@directus/types';
2
2
  import type { AbstractServiceOptions, MutationOptions } from '../types/index.js';
3
3
  import { ItemsService } from './items.js';
4
4
  export declare class RolesService extends ItemsService {
5
5
  constructor(options: AbstractServiceOptions);
6
- private checkForOtherAdminRoles;
7
- private checkForOtherAdminUsers;
8
- private isIpAccessValid;
9
- private assertValidIpAccess;
10
- private getRoleAccessType;
11
- createOne(data: Partial<Item>, opts?: MutationOptions): Promise<PrimaryKey>;
12
- createMany(data: Partial<Item>[], opts?: MutationOptions): Promise<PrimaryKey[]>;
13
- updateOne(key: PrimaryKey, data: Partial<Item>, opts?: MutationOptions): Promise<PrimaryKey>;
14
- updateBatch(data: Partial<Item>[], opts?: MutationOptions): Promise<PrimaryKey[]>;
15
6
  updateMany(keys: PrimaryKey[], data: Partial<Item>, opts?: MutationOptions): Promise<PrimaryKey[]>;
16
- updateByQuery(query: Query, data: Partial<Item>, opts?: MutationOptions | undefined): Promise<PrimaryKey[]>;
17
- deleteMany(keys: PrimaryKey[]): Promise<PrimaryKey[]>;
7
+ deleteMany(keys: PrimaryKey[], opts?: MutationOptions): Promise<PrimaryKey[]>;
8
+ private validateRoleNesting;
9
+ private clearCaches;
18
10
  }