directus 9.22.4 → 9.23.3
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.
- package/dist/app.js +19 -14
- package/dist/auth/auth.d.ts +3 -3
- package/dist/auth/auth.js +2 -0
- package/dist/auth/drivers/ldap.d.ts +2 -2
- package/dist/auth/drivers/ldap.js +47 -36
- package/dist/auth/drivers/local.d.ts +1 -1
- package/dist/auth/drivers/local.js +13 -10
- package/dist/auth/drivers/oauth2.d.ts +1 -1
- package/dist/auth/drivers/oauth2.js +22 -15
- package/dist/auth/drivers/openid.d.ts +1 -1
- package/dist/auth/drivers/openid.js +23 -16
- package/dist/auth/drivers/saml.d.ts +1 -1
- package/dist/auth/drivers/saml.js +10 -7
- package/dist/auth.d.ts +1 -1
- package/dist/auth.js +4 -4
- package/dist/cache.d.ts +9 -1
- package/dist/cache.js +59 -16
- package/dist/cli/commands/bootstrap/index.js +2 -2
- package/dist/cli/commands/init/index.js +3 -3
- package/dist/cli/commands/schema/apply.js +21 -20
- package/dist/cli/commands/schema/snapshot.js +2 -2
- package/dist/cli/utils/create-db-connection.d.ts +2 -1
- package/dist/cli/utils/create-db-connection.js +2 -1
- package/dist/cli/utils/create-env/env-stub.liquid +1 -1
- package/dist/cli/utils/create-env/index.d.ts +2 -2
- package/dist/cli/utils/drivers.d.ts +3 -9
- package/dist/constants.d.ts +3 -9
- package/dist/constants.js +5 -10
- package/dist/controllers/activity.js +1 -2
- package/dist/controllers/assets.js +17 -12
- package/dist/controllers/auth.js +29 -15
- package/dist/controllers/dashboards.js +5 -2
- package/dist/controllers/extensions.js +7 -7
- package/dist/controllers/fields.js +4 -4
- package/dist/controllers/files.js +11 -6
- package/dist/controllers/flows.js +5 -2
- package/dist/controllers/folders.js +5 -2
- package/dist/controllers/graphql.js +6 -0
- package/dist/controllers/items.js +5 -2
- package/dist/controllers/not-found.d.ts +1 -1
- package/dist/controllers/not-found.js +1 -2
- package/dist/controllers/notifications.js +5 -2
- package/dist/controllers/operations.js +5 -2
- package/dist/controllers/panels.js +5 -2
- package/dist/controllers/permissions.js +5 -2
- package/dist/controllers/presets.js +5 -2
- package/dist/controllers/roles.js +5 -2
- package/dist/controllers/schema.d.ts +2 -0
- package/dist/controllers/schema.js +98 -0
- package/dist/controllers/shares.js +8 -5
- package/dist/controllers/users.js +16 -20
- package/dist/controllers/utils.js +6 -11
- package/dist/controllers/webhooks.js +5 -2
- package/dist/database/helpers/fn/dialects/mssql.d.ts +1 -1
- package/dist/database/helpers/fn/dialects/mssql.js +10 -11
- package/dist/database/helpers/fn/dialects/mysql.d.ts +1 -1
- package/dist/database/helpers/fn/dialects/mysql.js +2 -3
- package/dist/database/helpers/fn/dialects/oracle.d.ts +1 -1
- package/dist/database/helpers/fn/dialects/oracle.js +10 -11
- package/dist/database/helpers/fn/dialects/postgres.d.ts +1 -1
- package/dist/database/helpers/fn/dialects/postgres.js +10 -11
- package/dist/database/helpers/fn/dialects/sqlite.d.ts +1 -1
- package/dist/database/helpers/fn/dialects/sqlite.js +10 -11
- package/dist/database/helpers/fn/types.d.ts +5 -5
- package/dist/database/helpers/fn/types.js +5 -4
- package/dist/database/helpers/geometry/dialects/mssql.d.ts +3 -3
- package/dist/database/helpers/geometry/dialects/mysql.d.ts +1 -1
- package/dist/database/helpers/geometry/dialects/oracle.d.ts +3 -3
- package/dist/database/helpers/geometry/dialects/postgres.d.ts +3 -3
- package/dist/database/helpers/geometry/dialects/postgres.js +1 -2
- package/dist/database/helpers/geometry/dialects/redshift.d.ts +2 -2
- package/dist/database/helpers/geometry/dialects/sqlite.d.ts +1 -1
- package/dist/database/helpers/geometry/types.d.ts +2 -2
- package/dist/database/helpers/geometry/types.js +1 -2
- package/dist/database/helpers/index.d.ts +5 -5
- package/dist/database/helpers/schema/dialects/cockroachdb.d.ts +2 -2
- package/dist/database/helpers/schema/dialects/mssql.d.ts +1 -1
- package/dist/database/helpers/schema/dialects/mysql.d.ts +1 -1
- package/dist/database/helpers/schema/dialects/mysql.js +1 -2
- package/dist/database/helpers/schema/dialects/oracle.d.ts +5 -2
- package/dist/database/helpers/schema/dialects/oracle.js +23 -0
- package/dist/database/helpers/schema/types.d.ts +9 -7
- package/dist/database/helpers/schema/types.js +7 -1
- package/dist/database/helpers/types.d.ts +1 -1
- package/dist/database/helpers/types.js +1 -0
- package/dist/database/index.d.ts +2 -1
- package/dist/database/index.js +8 -8
- package/dist/database/migrations/20201028A-remove-collection-foreign-keys.d.ts +1 -1
- package/dist/database/migrations/20201029A-remove-system-relations.d.ts +1 -1
- package/dist/database/migrations/20201029B-remove-system-collections.d.ts +1 -1
- package/dist/database/migrations/20201029C-remove-system-fields.d.ts +1 -1
- package/dist/database/migrations/20201105A-add-cascade-system-relations.d.ts +1 -1
- package/dist/database/migrations/20201105B-change-webhook-url-type.d.ts +1 -1
- package/dist/database/migrations/20210225A-add-relations-sort-field.d.ts +1 -1
- package/dist/database/migrations/20210225A-add-relations-sort-field.js +1 -2
- package/dist/database/migrations/20210304A-remove-locked-fields.d.ts +1 -1
- package/dist/database/migrations/20210312A-webhooks-collections-text.d.ts +1 -1
- package/dist/database/migrations/20210331A-add-refresh-interval.d.ts +1 -1
- package/dist/database/migrations/20210415A-make-filesize-nullable.d.ts +1 -1
- package/dist/database/migrations/20210416A-add-collections-accountability.d.ts +1 -1
- package/dist/database/migrations/20210422A-remove-files-interface.d.ts +1 -1
- package/dist/database/migrations/20210506A-rename-interfaces.d.ts +1 -1
- package/dist/database/migrations/20210510A-restructure-relations.d.ts +1 -1
- package/dist/database/migrations/20210518A-add-foreign-key-constraints.d.ts +1 -1
- package/dist/database/migrations/20210518A-add-foreign-key-constraints.js +1 -1
- package/dist/database/migrations/20210519A-add-system-fk-triggers.d.ts +1 -1
- package/dist/database/migrations/20210519A-add-system-fk-triggers.js +2 -2
- package/dist/database/migrations/20210521A-add-collections-icon-color.d.ts +1 -1
- package/dist/database/migrations/20210525A-add-insights.d.ts +1 -1
- package/dist/database/migrations/20210608A-add-deep-clone-config.d.ts +1 -1
- package/dist/database/migrations/20210626A-change-filesize-bigint.d.ts +1 -1
- package/dist/database/migrations/20210716A-add-conditions-to-fields.d.ts +1 -1
- package/dist/database/migrations/20210721A-add-default-folder.d.ts +1 -1
- package/dist/database/migrations/20210802A-replace-groups.d.ts +1 -1
- package/dist/database/migrations/20210803A-add-required-to-fields.d.ts +1 -1
- package/dist/database/migrations/20210805A-update-groups.d.ts +1 -1
- package/dist/database/migrations/20210805B-change-image-metadata-structure.d.ts +1 -1
- package/dist/database/migrations/20210811A-add-geometry-config.d.ts +1 -1
- package/dist/database/migrations/20210831A-remove-limit-column.d.ts +1 -1
- package/dist/database/migrations/20210903A-add-auth-provider.d.ts +1 -1
- package/dist/database/migrations/20210907A-webhooks-collections-not-null.d.ts +1 -1
- package/dist/database/migrations/20210910A-move-module-setup.d.ts +1 -1
- package/dist/database/migrations/20210920A-webhooks-url-not-null.d.ts +1 -1
- package/dist/database/migrations/20210924A-add-collection-organization.d.ts +1 -1
- package/dist/database/migrations/20210927A-replace-fields-group.d.ts +1 -1
- package/dist/database/migrations/20210927B-replace-m2m-interface.d.ts +1 -1
- package/dist/database/migrations/20210929A-rename-login-action.d.ts +1 -1
- package/dist/database/migrations/20211007A-update-presets.d.ts +1 -1
- package/dist/database/migrations/20211007A-update-presets.js +7 -9
- package/dist/database/migrations/20211009A-add-auth-data.d.ts +1 -1
- package/dist/database/migrations/20211016A-add-webhook-headers.d.ts +1 -1
- package/dist/database/migrations/20211103A-set-unique-to-user-token.d.ts +1 -1
- package/dist/database/migrations/20211103B-update-special-geometry.d.ts +1 -1
- package/dist/database/migrations/20211104A-remove-collections-listing.d.ts +1 -1
- package/dist/database/migrations/20211118A-add-notifications.d.ts +1 -1
- package/dist/database/migrations/20211211A-add-shares.d.ts +1 -1
- package/dist/database/migrations/20211230A-add-project-descriptor.d.ts +1 -1
- package/dist/database/migrations/20220303A-remove-default-project-color.d.ts +1 -1
- package/dist/database/migrations/20220308A-add-bookmark-icon-and-color.d.ts +1 -1
- package/dist/database/migrations/20220314A-add-translation-strings.d.ts +1 -1
- package/dist/database/migrations/20220322A-rename-field-typecast-flags.d.ts +1 -1
- package/dist/database/migrations/20220323A-add-field-validation.d.ts +1 -1
- package/dist/database/migrations/20220325A-fix-typecast-flags.d.ts +1 -1
- package/dist/database/migrations/20220325B-add-default-language.d.ts +1 -1
- package/dist/database/migrations/20220402A-remove-default-value-panel-icon.d.ts +1 -1
- package/dist/database/migrations/20220429A-add-flows.d.ts +1 -1
- package/dist/database/migrations/20220429B-add-color-to-insights-icon.d.ts +1 -1
- package/dist/database/migrations/20220429C-drop-non-null-from-ip-of-activity.d.ts +1 -1
- package/dist/database/migrations/20220429D-drop-non-null-from-sender-of-notifications.d.ts +1 -1
- package/dist/database/migrations/20220614A-rename-hook-trigger-to-event.d.ts +1 -1
- package/dist/database/migrations/20220801A-update-notifications-timestamp-column.d.ts +1 -1
- package/dist/database/migrations/20220802A-add-custom-aspect-ratios.d.ts +1 -1
- package/dist/database/migrations/20220826A-add-origin-to-accountability.d.ts +1 -1
- package/dist/database/migrations/run.d.ts +1 -1
- package/dist/database/run-ast.d.ts +3 -3
- package/dist/database/run-ast.js +19 -28
- package/dist/database/seeds/run.d.ts +1 -1
- package/dist/database/seeds/run.js +1 -2
- package/dist/database/system-data/app-access-permissions/index.d.ts +1 -1
- package/dist/database/system-data/collections/index.d.ts +1 -1
- package/dist/database/system-data/fields/collections.yaml +2 -0
- package/dist/database/system-data/fields/index.d.ts +1 -1
- package/dist/database/system-data/fields/index.js +1 -2
- package/dist/database/system-data/fields/settings.yaml +4 -0
- package/dist/database/system-data/relations/index.d.ts +1 -1
- package/dist/emitter.d.ts +1 -1
- package/dist/emitter.js +3 -0
- package/dist/env.js +19 -4
- package/dist/exceptions/database/dialects/mssql.d.ts +1 -1
- package/dist/exceptions/database/dialects/mssql.js +5 -6
- package/dist/exceptions/database/dialects/mysql.d.ts +1 -1
- package/dist/exceptions/database/dialects/mysql.js +19 -25
- package/dist/exceptions/database/dialects/oracle.d.ts +1 -1
- package/dist/exceptions/database/dialects/postgres.d.ts +1 -1
- package/dist/exceptions/database/dialects/sqlite.d.ts +1 -1
- package/dist/exceptions/database/translate.d.ts +1 -1
- package/dist/exceptions/database/value-out-of-range.js +1 -1
- package/dist/exceptions/range-not-satisfiable.js +2 -3
- package/dist/extensions.d.ts +1 -1
- package/dist/extensions.js +34 -24
- package/dist/flows.js +56 -30
- package/dist/logger.d.ts +1 -1
- package/dist/logger.js +19 -3
- package/dist/messenger.js +8 -6
- package/dist/middleware/authenticate.d.ts +1 -1
- package/dist/middleware/authenticate.js +12 -5
- package/dist/middleware/cache.d.ts +1 -1
- package/dist/middleware/cache.js +7 -7
- package/dist/middleware/check-ip.d.ts +1 -1
- package/dist/middleware/check-ip.js +1 -1
- package/dist/middleware/collection-exists.d.ts +1 -1
- package/dist/middleware/collection-exists.js +2 -2
- package/dist/middleware/cors.d.ts +1 -1
- package/dist/middleware/error-handler.d.ts +1 -1
- package/dist/middleware/error-handler.js +9 -10
- package/dist/middleware/extract-token.d.ts +1 -1
- package/dist/middleware/get-permissions.d.ts +1 -1
- package/dist/middleware/graphql.d.ts +1 -1
- package/dist/middleware/graphql.js +3 -3
- package/dist/middleware/rate-limiter-global.d.ts +5 -0
- package/dist/middleware/rate-limiter-global.js +48 -0
- package/dist/middleware/{rate-limiter.d.ts → rate-limiter-ip.d.ts} +2 -2
- package/dist/middleware/{rate-limiter.js → rate-limiter-ip.js} +3 -3
- package/dist/middleware/respond.d.ts +1 -1
- package/dist/middleware/respond.js +18 -14
- package/dist/middleware/sanitize-query.d.ts +1 -1
- package/dist/middleware/schema.d.ts +1 -1
- package/dist/middleware/use-collection.d.ts +1 -1
- package/dist/operations/condition/index.d.ts +1 -1
- package/dist/operations/exec/index.js +14 -3
- package/dist/operations/item-create/index.js +1 -2
- package/dist/operations/item-delete/index.d.ts +1 -1
- package/dist/operations/item-read/index.d.ts +1 -1
- package/dist/operations/item-update/index.d.ts +1 -1
- package/dist/operations/item-update/index.js +1 -2
- package/dist/operations/notification/index.js +1 -2
- package/dist/operations/request/index.js +21 -20
- package/dist/operations/trigger/index.d.ts +2 -0
- package/dist/operations/trigger/index.js +27 -11
- package/dist/rate-limiter.d.ts +1 -1
- package/dist/rate-limiter.js +8 -8
- package/dist/request/index.d.ts +5 -0
- package/dist/request/index.js +18 -0
- package/dist/request/index.test.d.ts +1 -0
- package/dist/request/request-interceptor.d.ts +2 -0
- package/dist/request/request-interceptor.js +33 -0
- package/dist/request/request-interceptor.test.d.ts +1 -0
- package/dist/request/response-interceptor.d.ts +2 -0
- package/dist/request/response-interceptor.js +9 -0
- package/dist/request/response-interceptor.test.d.ts +1 -0
- package/dist/request/validate-ip.d.ts +1 -0
- package/dist/request/validate-ip.js +27 -0
- package/dist/request/validate-ip.test.d.ts +1 -0
- package/dist/server.js +8 -9
- package/dist/services/activity.d.ts +1 -1
- package/dist/services/activity.js +7 -6
- package/dist/services/assets.d.ts +3 -3
- package/dist/services/assets.js +33 -26
- package/dist/services/authentication.d.ts +2 -2
- package/dist/services/authentication.js +18 -15
- package/dist/services/authorization.d.ts +3 -3
- package/dist/services/authorization.js +27 -31
- package/dist/services/collections.d.ts +5 -5
- package/dist/services/collections.js +52 -48
- package/dist/services/dashboards.d.ts +1 -1
- package/dist/services/fields.d.ts +5 -5
- package/dist/services/fields.js +49 -48
- package/dist/services/files.d.ts +1 -2
- package/dist/services/files.js +70 -108
- package/dist/services/flows.d.ts +2 -2
- package/dist/services/folders.d.ts +1 -1
- package/dist/services/graphql/index.d.ts +4 -4
- package/dist/services/graphql/index.js +181 -170
- package/dist/services/graphql/utils/add-path-to-validation-error.js +1 -2
- package/dist/services/graphql/utils/process-error.d.ts +2 -2
- package/dist/services/graphql/utils/process-error.js +29 -9
- package/dist/services/import-export.d.ts +7 -5
- package/dist/services/import-export.js +41 -24
- package/dist/services/import-export.test.d.ts +1 -0
- package/dist/services/index.d.ts +1 -0
- package/dist/services/index.js +1 -0
- package/dist/services/items.d.ts +3 -3
- package/dist/services/items.js +67 -42
- package/dist/services/mail/index.d.ts +4 -4
- package/dist/services/mail/index.js +9 -5
- package/dist/services/meta.d.ts +3 -3
- package/dist/services/meta.js +10 -9
- package/dist/services/notifications.d.ts +3 -3
- package/dist/services/notifications.js +7 -6
- package/dist/services/operations.d.ts +2 -2
- package/dist/services/panels.d.ts +1 -1
- package/dist/services/payload.d.ts +3 -3
- package/dist/services/payload.js +124 -122
- package/dist/services/permissions.d.ts +3 -3
- package/dist/services/permissions.js +11 -11
- package/dist/services/presets.d.ts +1 -1
- package/dist/services/relations.d.ts +6 -6
- package/dist/services/relations.js +47 -43
- package/dist/services/revisions.d.ts +1 -1
- package/dist/services/roles.d.ts +2 -2
- package/dist/services/roles.js +34 -13
- package/dist/services/schema.d.ts +15 -0
- package/dist/services/schema.js +56 -0
- package/dist/services/schema.test.d.ts +1 -0
- package/dist/services/server.d.ts +3 -3
- package/dist/services/server.js +69 -13
- package/dist/services/settings.d.ts +1 -1
- package/dist/services/shares.d.ts +2 -2
- package/dist/services/shares.js +14 -15
- package/dist/services/specifications.d.ts +4 -4
- package/dist/services/specifications.js +132 -116
- package/dist/services/tfa.d.ts +2 -2
- package/dist/services/tfa.js +7 -5
- package/dist/services/users.d.ts +3 -3
- package/dist/services/users.js +89 -62
- package/dist/services/utils.d.ts +3 -3
- package/dist/services/utils.js +10 -8
- package/dist/services/webhooks.d.ts +2 -2
- package/dist/services/webhooks.js +2 -1
- package/dist/types/assets.d.ts +2 -2
- package/dist/types/ast.d.ts +1 -1
- package/dist/types/auth.d.ts +2 -2
- package/dist/types/collection.d.ts +2 -2
- package/dist/types/database.d.ts +3 -0
- package/dist/types/database.js +4 -0
- package/dist/types/events.d.ts +2 -2
- package/dist/types/graphql.d.ts +2 -2
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +1 -0
- package/dist/types/items.d.ts +7 -2
- package/dist/types/services.d.ts +5 -5
- package/dist/types/snapshot.d.ts +25 -3
- package/dist/types/snapshot.js +14 -0
- package/dist/utils/apply-diff.d.ts +9 -0
- package/dist/utils/apply-diff.js +256 -0
- package/dist/utils/apply-diff.test.d.ts +1 -0
- package/dist/utils/apply-query.d.ts +3 -3
- package/dist/utils/apply-query.js +15 -16
- package/dist/utils/apply-snapshot.d.ts +3 -5
- package/dist/utils/apply-snapshot.js +9 -240
- package/dist/utils/construct-flow-tree.d.ts +1 -1
- package/dist/utils/construct-flow-tree.js +2 -2
- package/dist/utils/filter-items.d.ts +1 -1
- package/dist/utils/get-accountability-for-role.d.ts +2 -2
- package/dist/utils/get-accountability-for-role.js +1 -1
- package/dist/utils/get-ast-from-query.d.ts +3 -3
- package/dist/utils/get-ast-from-query.js +22 -28
- package/dist/utils/get-cache-headers.d.ts +4 -2
- package/dist/utils/get-cache-headers.js +21 -21
- package/dist/utils/get-cache-headers.test.d.ts +1 -0
- package/dist/utils/get-cache-key.d.ts +1 -1
- package/dist/utils/get-cache-key.js +2 -3
- package/dist/utils/get-collection-from-alias.d.ts +1 -1
- package/dist/utils/get-column-path.d.ts +2 -2
- package/dist/utils/get-column-path.js +3 -4
- package/dist/utils/get-column.d.ts +4 -4
- package/dist/utils/get-column.js +4 -5
- package/dist/utils/get-default-value.d.ts +2 -2
- package/dist/utils/get-default-value.js +1 -2
- package/dist/utils/get-graphql-query-and-variables.d.ts +1 -1
- package/dist/utils/get-graphql-query-and-variables.js +1 -2
- package/dist/utils/get-graphql-type.d.ts +2 -2
- package/dist/utils/get-graphql-type.js +1 -1
- package/dist/utils/get-ip-from-req.d.ts +1 -1
- package/dist/utils/get-local-type.d.ts +1 -1
- package/dist/utils/get-local-type.js +3 -3
- package/dist/utils/get-milliseconds.d.ts +4 -0
- package/dist/utils/get-milliseconds.js +14 -0
- package/dist/utils/get-milliseconds.test.d.ts +1 -0
- package/dist/utils/get-permissions.d.ts +1 -1
- package/dist/utils/get-permissions.js +1 -1
- package/dist/utils/get-relation-info.d.ts +1 -1
- package/dist/utils/get-relation-info.js +3 -5
- package/dist/utils/get-relation-type.d.ts +1 -1
- package/dist/utils/get-relation-type.js +3 -4
- package/dist/utils/get-schema.d.ts +2 -2
- package/dist/utils/get-schema.js +19 -21
- package/dist/utils/get-snapshot-diff.js +10 -7
- package/dist/utils/get-snapshot.d.ts +3 -3
- package/dist/utils/get-snapshot.js +35 -14
- package/dist/utils/get-versioned-hash.d.ts +1 -0
- package/dist/utils/get-versioned-hash.js +12 -0
- package/dist/utils/get-versioned-hash.test.d.ts +1 -0
- package/dist/utils/is-directus-jwt.js +1 -1
- package/dist/utils/job-queue.js +2 -0
- package/dist/utils/jwt.d.ts +1 -1
- package/dist/utils/map-values-deep.d.ts +1 -0
- package/dist/utils/map-values-deep.js +29 -0
- package/dist/utils/map-values-deep.test.d.ts +1 -0
- package/dist/utils/merge-permissions-for-share.d.ts +1 -1
- package/dist/utils/merge-permissions-for-share.js +3 -4
- package/dist/utils/merge-permissions.d.ts +3 -3
- package/dist/utils/redact-header-cookies.d.ts +1 -0
- package/dist/utils/redact-header-cookies.js +11 -0
- package/dist/utils/redact-header-cookies.test.d.ts +1 -0
- package/dist/utils/reduce-schema.d.ts +1 -1
- package/dist/utils/reduce-schema.js +12 -12
- package/dist/utils/sanitize-query.d.ts +1 -1
- package/dist/utils/sanitize-query.js +1 -1
- package/dist/utils/sanitize-schema.d.ts +30 -0
- package/dist/utils/sanitize-schema.js +80 -0
- package/dist/utils/sanitize-schema.test.d.ts +1 -0
- package/dist/utils/should-skip-cache.d.ts +7 -0
- package/dist/utils/should-skip-cache.js +21 -0
- package/dist/utils/should-skip-cache.test.d.ts +1 -0
- package/dist/utils/track.js +3 -3
- package/dist/utils/transformations.d.ts +1 -1
- package/dist/utils/transformations.js +2 -4
- package/dist/utils/url.js +9 -8
- package/dist/utils/url.test.d.ts +1 -0
- package/dist/utils/user-name.d.ts +1 -1
- package/dist/utils/validate-diff.d.ts +7 -0
- package/dist/utils/validate-diff.js +113 -0
- package/dist/utils/validate-diff.test.d.ts +1 -0
- package/dist/utils/validate-keys.d.ts +2 -2
- package/dist/utils/validate-keys.js +1 -1
- package/dist/utils/validate-query.d.ts +1 -1
- package/dist/utils/validate-query.js +3 -3
- package/dist/utils/validate-query.test.d.ts +1 -0
- package/dist/utils/validate-snapshot.d.ts +5 -0
- package/dist/utils/validate-snapshot.js +71 -0
- package/dist/utils/validate-snapshot.test.d.ts +1 -0
- package/dist/webhooks.js +4 -3
- package/package.json +62 -62
package/dist/logger.js
CHANGED
|
@@ -27,13 +27,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
29
|
exports.expressLogger = void 0;
|
|
30
|
+
const utils_1 = require("@directus/shared/utils");
|
|
31
|
+
const lodash_1 = require("lodash");
|
|
30
32
|
const pino_1 = __importDefault(require("pino"));
|
|
31
33
|
const pino_http_1 = __importStar(require("pino-http"));
|
|
32
|
-
const get_config_from_env_1 = require("./utils/get-config-from-env");
|
|
33
34
|
const url_1 = require("url");
|
|
34
35
|
const env_1 = __importDefault(require("./env"));
|
|
35
|
-
const
|
|
36
|
-
const
|
|
36
|
+
const get_config_from_env_1 = require("./utils/get-config-from-env");
|
|
37
|
+
const redact_header_cookies_1 = require("./utils/redact-header-cookies");
|
|
37
38
|
const pinoOptions = {
|
|
38
39
|
level: env_1.default.LOG_LEVEL || 'info',
|
|
39
40
|
redact: {
|
|
@@ -104,8 +105,23 @@ exports.expressLogger = (0, pino_http_1.default)({
|
|
|
104
105
|
req(request) {
|
|
105
106
|
const output = pino_http_1.stdSerializers.req(request);
|
|
106
107
|
output.url = redactQuery(output.url);
|
|
108
|
+
if (output.headers?.cookie) {
|
|
109
|
+
output.headers.cookie = (0, redact_header_cookies_1.redactHeaderCookie)(output.headers.cookie, [
|
|
110
|
+
'access_token',
|
|
111
|
+
`${env_1.default.REFRESH_TOKEN_COOKIE_NAME}`,
|
|
112
|
+
]);
|
|
113
|
+
}
|
|
107
114
|
return output;
|
|
108
115
|
},
|
|
116
|
+
res(response) {
|
|
117
|
+
if (response.headers?.['set-cookie']) {
|
|
118
|
+
response.headers['set-cookie'] = (0, redact_header_cookies_1.redactHeaderCookie)(response.headers['set-cookie'], [
|
|
119
|
+
'access_token',
|
|
120
|
+
`${env_1.default.REFRESH_TOKEN_COOKIE_NAME}`,
|
|
121
|
+
]);
|
|
122
|
+
}
|
|
123
|
+
return response;
|
|
124
|
+
},
|
|
109
125
|
},
|
|
110
126
|
});
|
|
111
127
|
exports.default = logger;
|
package/dist/messenger.js
CHANGED
|
@@ -9,12 +9,12 @@ const ioredis_1 = __importDefault(require("ioredis"));
|
|
|
9
9
|
const env_1 = __importDefault(require("./env"));
|
|
10
10
|
const get_config_from_env_1 = require("./utils/get-config-from-env");
|
|
11
11
|
class MessengerMemory {
|
|
12
|
+
handlers;
|
|
12
13
|
constructor() {
|
|
13
14
|
this.handlers = {};
|
|
14
15
|
}
|
|
15
16
|
publish(channel, payload) {
|
|
16
|
-
|
|
17
|
-
(_b = (_a = this.handlers)[channel]) === null || _b === void 0 ? void 0 : _b.call(_a, payload);
|
|
17
|
+
this.handlers[channel]?.(payload);
|
|
18
18
|
}
|
|
19
19
|
subscribe(channel, callback) {
|
|
20
20
|
this.handlers[channel] = callback;
|
|
@@ -25,12 +25,14 @@ class MessengerMemory {
|
|
|
25
25
|
}
|
|
26
26
|
exports.MessengerMemory = MessengerMemory;
|
|
27
27
|
class MessengerRedis {
|
|
28
|
+
namespace;
|
|
29
|
+
pub;
|
|
30
|
+
sub;
|
|
28
31
|
constructor() {
|
|
29
|
-
var _a, _b, _c;
|
|
30
32
|
const config = (0, get_config_from_env_1.getConfigFromEnv)('MESSENGER_REDIS');
|
|
31
|
-
this.pub = new ioredis_1.default(
|
|
32
|
-
this.sub = new ioredis_1.default(
|
|
33
|
-
this.namespace =
|
|
33
|
+
this.pub = new ioredis_1.default(env_1.default.MESSENGER_REDIS ?? config);
|
|
34
|
+
this.sub = new ioredis_1.default(env_1.default.MESSENGER_REDIS ?? config);
|
|
35
|
+
this.namespace = env_1.default.MESSENGER_NAMESPACE ?? 'directus';
|
|
34
36
|
}
|
|
35
37
|
publish(channel, payload) {
|
|
36
38
|
this.pub.publish(`${this.namespace}:${channel}`, JSON.stringify(payload));
|
|
@@ -23,9 +23,13 @@ const handler = async (req, res, next) => {
|
|
|
23
23
|
admin: false,
|
|
24
24
|
app: false,
|
|
25
25
|
ip: (0, get_ip_from_req_1.getIPFromReq)(req),
|
|
26
|
-
userAgent: req.get('user-agent'),
|
|
27
|
-
origin: req.get('origin'),
|
|
28
26
|
};
|
|
27
|
+
const userAgent = req.get('user-agent');
|
|
28
|
+
if (userAgent)
|
|
29
|
+
defaultAccountability.userAgent = userAgent;
|
|
30
|
+
const origin = req.get('origin');
|
|
31
|
+
if (origin)
|
|
32
|
+
defaultAccountability.origin = origin;
|
|
29
33
|
const database = (0, database_1.default)();
|
|
30
34
|
const customAccountability = await emitter_1.default.emitFilter('authenticate', defaultAccountability, {
|
|
31
35
|
req,
|
|
@@ -42,12 +46,15 @@ const handler = async (req, res, next) => {
|
|
|
42
46
|
if (req.token) {
|
|
43
47
|
if ((0, is_directus_jwt_1.default)(req.token)) {
|
|
44
48
|
const payload = (0, jwt_1.verifyAccessJWT)(req.token, env_1.default.SECRET);
|
|
45
|
-
req.accountability.share = payload.share;
|
|
46
|
-
req.accountability.share_scope = payload.share_scope;
|
|
47
|
-
req.accountability.user = payload.id;
|
|
48
49
|
req.accountability.role = payload.role;
|
|
49
50
|
req.accountability.admin = payload.admin_access === true || payload.admin_access == 1;
|
|
50
51
|
req.accountability.app = payload.app_access === true || payload.app_access == 1;
|
|
52
|
+
if (payload.share)
|
|
53
|
+
req.accountability.share = payload.share;
|
|
54
|
+
if (payload.share_scope)
|
|
55
|
+
req.accountability.share_scope = payload.share_scope;
|
|
56
|
+
if (payload.id)
|
|
57
|
+
req.accountability.user = payload.id;
|
|
51
58
|
}
|
|
52
59
|
else {
|
|
53
60
|
// Try finding the user with the provided token
|
package/dist/middleware/cache.js
CHANGED
|
@@ -5,20 +5,20 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const cache_1 = require("../cache");
|
|
7
7
|
const env_1 = __importDefault(require("../env"));
|
|
8
|
+
const logger_1 = __importDefault(require("../logger"));
|
|
8
9
|
const async_handler_1 = __importDefault(require("../utils/async-handler"));
|
|
9
10
|
const get_cache_headers_1 = require("../utils/get-cache-headers");
|
|
10
11
|
const get_cache_key_1 = require("../utils/get-cache-key");
|
|
11
|
-
const
|
|
12
|
+
const should_skip_cache_1 = require("../utils/should-skip-cache");
|
|
12
13
|
const checkCacheMiddleware = (0, async_handler_1.default)(async (req, res, next) => {
|
|
13
|
-
var _a, _b, _c, _d;
|
|
14
14
|
const { cache } = (0, cache_1.getCache)();
|
|
15
|
-
if (req.method.toLowerCase() !== 'get' &&
|
|
15
|
+
if (req.method.toLowerCase() !== 'get' && req.originalUrl?.startsWith('/graphql') === false)
|
|
16
16
|
return next();
|
|
17
17
|
if (env_1.default.CACHE_ENABLED !== true)
|
|
18
18
|
return next();
|
|
19
19
|
if (!cache)
|
|
20
20
|
return next();
|
|
21
|
-
if ((
|
|
21
|
+
if ((0, should_skip_cache_1.shouldSkipCache)(req)) {
|
|
22
22
|
if (env_1.default.CACHE_STATUS_HEADER)
|
|
23
23
|
res.setHeader(`${env_1.default.CACHE_STATUS_HEADER}`, 'MISS');
|
|
24
24
|
return next();
|
|
@@ -37,7 +37,7 @@ const checkCacheMiddleware = (0, async_handler_1.default)(async (req, res, next)
|
|
|
37
37
|
if (cachedData) {
|
|
38
38
|
let cacheExpiryDate;
|
|
39
39
|
try {
|
|
40
|
-
cacheExpiryDate = (
|
|
40
|
+
cacheExpiryDate = (await (0, cache_1.getCacheValue)(cache, `${key}__expires_at`))?.exp;
|
|
41
41
|
}
|
|
42
42
|
catch (err) {
|
|
43
43
|
logger_1.default.warn(err, `[cache] Couldn't read key ${`${key}__expires_at`}. ${err.message}`);
|
|
@@ -45,8 +45,8 @@ const checkCacheMiddleware = (0, async_handler_1.default)(async (req, res, next)
|
|
|
45
45
|
res.setHeader(`${env_1.default.CACHE_STATUS_HEADER}`, 'MISS');
|
|
46
46
|
return next();
|
|
47
47
|
}
|
|
48
|
-
const cacheTTL = cacheExpiryDate ? cacheExpiryDate - Date.now() :
|
|
49
|
-
res.setHeader('Cache-Control', (0, get_cache_headers_1.getCacheControlHeader)(req, cacheTTL));
|
|
48
|
+
const cacheTTL = cacheExpiryDate ? cacheExpiryDate - Date.now() : undefined;
|
|
49
|
+
res.setHeader('Cache-Control', (0, get_cache_headers_1.getCacheControlHeader)(req, cacheTTL, true, true));
|
|
50
50
|
res.setHeader('Vary', 'Origin, Cache-Control');
|
|
51
51
|
if (env_1.default.CACHE_STATUS_HEADER)
|
|
52
52
|
res.setHeader(`${env_1.default.CACHE_STATUS_HEADER}`, 'HIT');
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { RequestHandler } from 'express';
|
|
1
|
+
import type { RequestHandler } from 'express';
|
|
2
2
|
export declare const checkIP: RequestHandler;
|
|
@@ -17,7 +17,7 @@ exports.checkIP = (0, async_handler_1.default)(async (req, _res, next) => {
|
|
|
17
17
|
query.whereNull('id');
|
|
18
18
|
}
|
|
19
19
|
const role = await query.first();
|
|
20
|
-
const ipAllowlist = (
|
|
20
|
+
const ipAllowlist = (role?.ip_access || '').split(',').filter((ip) => ip);
|
|
21
21
|
if (ipAllowlist.length > 0 && ipAllowlist.includes(req.accountability.ip) === false)
|
|
22
22
|
throw new exceptions_1.InvalidIPException();
|
|
23
23
|
return next();
|
|
@@ -18,9 +18,9 @@ const collectionExists = (0, async_handler_1.default)(async (req, res, next) =>
|
|
|
18
18
|
req.collection = req.params.collection;
|
|
19
19
|
if (req.collection.startsWith('directus_')) {
|
|
20
20
|
const systemRow = collections_1.systemCollectionRows.find((collection) => {
|
|
21
|
-
return
|
|
21
|
+
return collection?.collection === req.collection;
|
|
22
22
|
});
|
|
23
|
-
req.singleton = !!
|
|
23
|
+
req.singleton = !!systemRow?.singleton;
|
|
24
24
|
}
|
|
25
25
|
else {
|
|
26
26
|
req.singleton = req.schema.collections[req.collection].singleton;
|
|
@@ -3,22 +3,21 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const exceptions_1 = require("@directus/shared/exceptions");
|
|
7
|
+
const utils_1 = require("@directus/shared/utils");
|
|
8
|
+
const database_1 = __importDefault(require("../database"));
|
|
6
9
|
const emitter_1 = __importDefault(require("../emitter"));
|
|
7
10
|
const env_1 = __importDefault(require("../env"));
|
|
8
|
-
const
|
|
9
|
-
const exceptions_2 = require("@directus/shared/exceptions");
|
|
11
|
+
const exceptions_2 = require("../exceptions");
|
|
10
12
|
const logger_1 = __importDefault(require("../logger"));
|
|
11
|
-
const utils_1 = require("@directus/shared/utils");
|
|
12
|
-
const database_1 = __importDefault(require("../database"));
|
|
13
13
|
// Note: keep all 4 parameters here. That's how Express recognizes it's the error handler, even if
|
|
14
14
|
// we don't use next
|
|
15
15
|
const errorHandler = (err, req, res, _next) => {
|
|
16
|
-
var _a, _b;
|
|
17
16
|
let payload = {
|
|
18
17
|
errors: [],
|
|
19
18
|
};
|
|
20
19
|
const errors = (0, utils_1.toArray)(err);
|
|
21
|
-
if (errors.some((err) => err instanceof
|
|
20
|
+
if (errors.some((err) => err instanceof exceptions_1.BaseException === false)) {
|
|
22
21
|
res.status(500);
|
|
23
22
|
}
|
|
24
23
|
else {
|
|
@@ -39,7 +38,7 @@ const errorHandler = (err, req, res, _next) => {
|
|
|
39
38
|
stack: err.stack,
|
|
40
39
|
};
|
|
41
40
|
}
|
|
42
|
-
if (err instanceof
|
|
41
|
+
if (err instanceof exceptions_1.BaseException) {
|
|
43
42
|
logger_1.default.debug(err);
|
|
44
43
|
res.status(err.status);
|
|
45
44
|
payload.errors.push({
|
|
@@ -49,14 +48,14 @@ const errorHandler = (err, req, res, _next) => {
|
|
|
49
48
|
...err.extensions,
|
|
50
49
|
},
|
|
51
50
|
});
|
|
52
|
-
if (err instanceof
|
|
51
|
+
if (err instanceof exceptions_2.MethodNotAllowedException) {
|
|
53
52
|
res.header('Allow', err.extensions.allow.join(', '));
|
|
54
53
|
}
|
|
55
54
|
}
|
|
56
55
|
else {
|
|
57
56
|
logger_1.default.error(err);
|
|
58
57
|
res.status(500);
|
|
59
|
-
if (
|
|
58
|
+
if (req.accountability?.admin === true) {
|
|
60
59
|
payload = {
|
|
61
60
|
errors: [
|
|
62
61
|
{
|
|
@@ -87,7 +86,7 @@ const errorHandler = (err, req, res, _next) => {
|
|
|
87
86
|
.emitFilter('request.error', payload.errors, {}, {
|
|
88
87
|
database: (0, database_1.default)(),
|
|
89
88
|
schema: req.schema,
|
|
90
|
-
accountability:
|
|
89
|
+
accountability: req.accountability ?? null,
|
|
91
90
|
})
|
|
92
91
|
.then(() => {
|
|
93
92
|
return res.json(payload);
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { RequestHandler } from 'express';
|
|
1
|
+
import type { RequestHandler } from 'express';
|
|
2
2
|
export declare const parseGraphQL: RequestHandler;
|
|
@@ -49,13 +49,13 @@ exports.parseGraphQL = (0, async_handler_1.default)(async (req, res, next) => {
|
|
|
49
49
|
}
|
|
50
50
|
const operationAST = (0, graphql_1.getOperationAST)(document, operationName);
|
|
51
51
|
// You can only do `query` through GET
|
|
52
|
-
if (req.method === 'GET' &&
|
|
53
|
-
throw new exceptions_1.MethodNotAllowedException(`Can only perform a ${operationAST
|
|
52
|
+
if (req.method === 'GET' && operationAST?.operation !== 'query') {
|
|
53
|
+
throw new exceptions_1.MethodNotAllowedException(`Can only perform a ${operationAST?.operation} from a POST request.`, {
|
|
54
54
|
allow: ['POST'],
|
|
55
55
|
});
|
|
56
56
|
}
|
|
57
57
|
// Prevent caching responses when mutations are made
|
|
58
|
-
if (
|
|
58
|
+
if (operationAST?.operation === 'mutation') {
|
|
59
59
|
res.locals.cache = false;
|
|
60
60
|
}
|
|
61
61
|
res.locals.graphqlParams = { document, query, variables, operationName, contextValue: { req, res } };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { RequestHandler } from 'express';
|
|
2
|
+
import type { RateLimiterMemcache, RateLimiterMemory, RateLimiterRedis } from 'rate-limiter-flexible';
|
|
3
|
+
declare let checkRateLimit: RequestHandler;
|
|
4
|
+
export declare let rateLimiterGlobal: RateLimiterRedis | RateLimiterMemcache | RateLimiterMemory;
|
|
5
|
+
export default checkRateLimit;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.rateLimiterGlobal = void 0;
|
|
7
|
+
const ms_1 = __importDefault(require("ms"));
|
|
8
|
+
const env_1 = __importDefault(require("../env"));
|
|
9
|
+
const index_1 = require("../exceptions/index");
|
|
10
|
+
const logger_1 = __importDefault(require("../logger"));
|
|
11
|
+
const rate_limiter_1 = require("../rate-limiter");
|
|
12
|
+
const async_handler_1 = __importDefault(require("../utils/async-handler"));
|
|
13
|
+
const validate_env_1 = require("../utils/validate-env");
|
|
14
|
+
const RATE_LIMITER_GLOBAL_KEY = 'global-rate-limit';
|
|
15
|
+
let checkRateLimit = (_req, _res, next) => next();
|
|
16
|
+
if (env_1.default.RATE_LIMITER_GLOBAL_ENABLED === true) {
|
|
17
|
+
(0, validate_env_1.validateEnv)(['RATE_LIMITER_GLOBAL_STORE', 'RATE_LIMITER_GLOBAL_DURATION', 'RATE_LIMITER_GLOBAL_POINTS']);
|
|
18
|
+
validateConfiguration();
|
|
19
|
+
exports.rateLimiterGlobal = (0, rate_limiter_1.createRateLimiter)('RATE_LIMITER_GLOBAL');
|
|
20
|
+
checkRateLimit = (0, async_handler_1.default)(async (_req, res, next) => {
|
|
21
|
+
try {
|
|
22
|
+
await exports.rateLimiterGlobal.consume(RATE_LIMITER_GLOBAL_KEY, 1);
|
|
23
|
+
}
|
|
24
|
+
catch (rateLimiterRes) {
|
|
25
|
+
if (rateLimiterRes instanceof Error)
|
|
26
|
+
throw rateLimiterRes;
|
|
27
|
+
res.set('Retry-After', String(Math.round(rateLimiterRes.msBeforeNext / 1000)));
|
|
28
|
+
throw new index_1.HitRateLimitException(`Too many requests, retry after ${(0, ms_1.default)(rateLimiterRes.msBeforeNext)}.`, {
|
|
29
|
+
limit: +env_1.default.RATE_LIMITER_GLOBAL_POINTS,
|
|
30
|
+
reset: new Date(Date.now() + rateLimiterRes.msBeforeNext),
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
next();
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
exports.default = checkRateLimit;
|
|
37
|
+
function validateConfiguration() {
|
|
38
|
+
if (env_1.default.RATE_LIMITER_ENABLED !== true) {
|
|
39
|
+
logger_1.default.error(`The IP based rate limiter needs to be enabled when using the global rate limiter.`);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
const globalPointsPerSec = Number(env_1.default.RATE_LIMITER_GLOBAL_POINTS) / Math.max(Number(env_1.default.RATE_LIMITER_GLOBAL_DURATION), 1);
|
|
43
|
+
const regularPointsPerSec = Number(env_1.default.RATE_LIMITER_POINTS) / Math.max(Number(env_1.default.RATE_LIMITER_DURATION), 1);
|
|
44
|
+
if (globalPointsPerSec <= regularPointsPerSec) {
|
|
45
|
+
logger_1.default.error(`The global rate limiter needs to allow more requests per second than the IP based rate limiter.`);
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { RequestHandler } from 'express';
|
|
2
|
-
import { RateLimiterMemcache, RateLimiterMemory, RateLimiterRedis } from 'rate-limiter-flexible';
|
|
1
|
+
import type { RequestHandler } from 'express';
|
|
2
|
+
import type { RateLimiterMemcache, RateLimiterMemory, RateLimiterRedis } from 'rate-limiter-flexible';
|
|
3
3
|
declare let checkRateLimit: RequestHandler;
|
|
4
4
|
export declare let rateLimiter: RateLimiterRedis | RateLimiterMemcache | RateLimiterMemory;
|
|
5
5
|
export default checkRateLimit;
|
|
@@ -11,10 +11,10 @@ const rate_limiter_1 = require("../rate-limiter");
|
|
|
11
11
|
const async_handler_1 = __importDefault(require("../utils/async-handler"));
|
|
12
12
|
const get_ip_from_req_1 = require("../utils/get-ip-from-req");
|
|
13
13
|
const validate_env_1 = require("../utils/validate-env");
|
|
14
|
-
let checkRateLimit = (
|
|
14
|
+
let checkRateLimit = (_req, _res, next) => next();
|
|
15
15
|
if (env_1.default.RATE_LIMITER_ENABLED === true) {
|
|
16
16
|
(0, validate_env_1.validateEnv)(['RATE_LIMITER_STORE', 'RATE_LIMITER_DURATION', 'RATE_LIMITER_POINTS']);
|
|
17
|
-
exports.rateLimiter = (0, rate_limiter_1.createRateLimiter)();
|
|
17
|
+
exports.rateLimiter = (0, rate_limiter_1.createRateLimiter)('RATE_LIMITER');
|
|
18
18
|
checkRateLimit = (0, async_handler_1.default)(async (req, res, next) => {
|
|
19
19
|
try {
|
|
20
20
|
await exports.rateLimiter.consume((0, get_ip_from_req_1.getIPFromReq)(req), 1);
|
|
@@ -22,7 +22,7 @@ if (env_1.default.RATE_LIMITER_ENABLED === true) {
|
|
|
22
22
|
catch (rateLimiterRes) {
|
|
23
23
|
if (rateLimiterRes instanceof Error)
|
|
24
24
|
throw rateLimiterRes;
|
|
25
|
-
res.set('Retry-After', String(rateLimiterRes.msBeforeNext / 1000));
|
|
25
|
+
res.set('Retry-After', String(Math.round(rateLimiterRes.msBeforeNext / 1000)));
|
|
26
26
|
throw new exceptions_1.HitRateLimitException(`Too many requests, retry after ${(0, ms_1.default)(rateLimiterRes.msBeforeNext)}.`, {
|
|
27
27
|
limit: +env_1.default.RATE_LIMITER_POINTS,
|
|
28
28
|
reset: new Date(Date.now() + rateLimiterRes.msBeforeNext),
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { RequestHandler } from 'express';
|
|
1
|
+
import type { RequestHandler } from 'express';
|
|
2
2
|
export declare const respond: RequestHandler;
|
|
@@ -4,19 +4,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.respond = void 0;
|
|
7
|
-
const
|
|
7
|
+
const bytes_1 = require("bytes");
|
|
8
8
|
const cache_1 = require("../cache");
|
|
9
9
|
const env_1 = __importDefault(require("../env"));
|
|
10
|
-
const async_handler_1 = __importDefault(require("../utils/async-handler"));
|
|
11
|
-
const get_cache_key_1 = require("../utils/get-cache-key");
|
|
12
|
-
const get_cache_headers_1 = require("../utils/get-cache-headers");
|
|
13
10
|
const logger_1 = __importDefault(require("../logger"));
|
|
14
11
|
const services_1 = require("../services");
|
|
12
|
+
const async_handler_1 = __importDefault(require("../utils/async-handler"));
|
|
13
|
+
const get_cache_headers_1 = require("../utils/get-cache-headers");
|
|
14
|
+
const get_cache_key_1 = require("../utils/get-cache-key");
|
|
15
15
|
const get_date_formatted_1 = require("../utils/get-date-formatted");
|
|
16
|
+
const get_milliseconds_1 = require("../utils/get-milliseconds");
|
|
16
17
|
const get_string_byte_size_1 = require("../utils/get-string-byte-size");
|
|
17
|
-
const bytes_1 = require("bytes");
|
|
18
18
|
exports.respond = (0, async_handler_1.default)(async (req, res) => {
|
|
19
|
-
var _a, _b, _c, _d;
|
|
20
19
|
const { cache } = (0, cache_1.getCache)();
|
|
21
20
|
let exceedsMaxSize = false;
|
|
22
21
|
if (env_1.default.CACHE_VALUE_MAX_SIZE !== false) {
|
|
@@ -24,7 +23,7 @@ exports.respond = (0, async_handler_1.default)(async (req, res) => {
|
|
|
24
23
|
const maxSize = (0, bytes_1.parse)(env_1.default.CACHE_VALUE_MAX_SIZE);
|
|
25
24
|
exceedsMaxSize = valueSize > maxSize;
|
|
26
25
|
}
|
|
27
|
-
if ((req.method.toLowerCase() === 'get' ||
|
|
26
|
+
if ((req.method.toLowerCase() === 'get' || req.originalUrl?.startsWith('/graphql')) &&
|
|
28
27
|
env_1.default.CACHE_ENABLED === true &&
|
|
29
28
|
cache &&
|
|
30
29
|
!req.sanitizedQuery.export &&
|
|
@@ -32,13 +31,13 @@ exports.respond = (0, async_handler_1.default)(async (req, res) => {
|
|
|
32
31
|
exceedsMaxSize === false) {
|
|
33
32
|
const key = (0, get_cache_key_1.getCacheKey)(req);
|
|
34
33
|
try {
|
|
35
|
-
await (0, cache_1.setCacheValue)(cache, key, res.locals.payload, (0,
|
|
36
|
-
await (0, cache_1.setCacheValue)(cache, `${key}__expires_at`, { exp: Date.now() + (0,
|
|
34
|
+
await (0, cache_1.setCacheValue)(cache, key, res.locals.payload, (0, get_milliseconds_1.getMilliseconds)(env_1.default.CACHE_TTL));
|
|
35
|
+
await (0, cache_1.setCacheValue)(cache, `${key}__expires_at`, { exp: Date.now() + (0, get_milliseconds_1.getMilliseconds)(env_1.default.CACHE_TTL, 0) });
|
|
37
36
|
}
|
|
38
37
|
catch (err) {
|
|
39
38
|
logger_1.default.warn(err, `[cache] Couldn't set key ${key}. ${err}`);
|
|
40
39
|
}
|
|
41
|
-
res.setHeader('Cache-Control', (0, get_cache_headers_1.getCacheControlHeader)(req, (0,
|
|
40
|
+
res.setHeader('Cache-Control', (0, get_cache_headers_1.getCacheControlHeader)(req, (0, get_milliseconds_1.getMilliseconds)(env_1.default.CACHE_TTL), true, true));
|
|
42
41
|
res.setHeader('Vary', 'Origin, Cache-Control');
|
|
43
42
|
}
|
|
44
43
|
else {
|
|
@@ -47,7 +46,7 @@ exports.respond = (0, async_handler_1.default)(async (req, res) => {
|
|
|
47
46
|
res.setHeader('Vary', 'Origin, Cache-Control');
|
|
48
47
|
}
|
|
49
48
|
if (req.sanitizedQuery.export) {
|
|
50
|
-
const exportService = new services_1.ExportService({ accountability: req.accountability, schema: req.schema });
|
|
49
|
+
const exportService = new services_1.ExportService({ accountability: req.accountability ?? null, schema: req.schema });
|
|
51
50
|
let filename = '';
|
|
52
51
|
if (req.collection) {
|
|
53
52
|
filename += req.collection;
|
|
@@ -59,17 +58,22 @@ exports.respond = (0, async_handler_1.default)(async (req, res) => {
|
|
|
59
58
|
if (req.sanitizedQuery.export === 'json') {
|
|
60
59
|
res.attachment(`${filename}.json`);
|
|
61
60
|
res.set('Content-Type', 'application/json');
|
|
62
|
-
return res.status(200).send(exportService.transform(
|
|
61
|
+
return res.status(200).send(exportService.transform(res.locals.payload?.data, 'json'));
|
|
63
62
|
}
|
|
64
63
|
if (req.sanitizedQuery.export === 'xml') {
|
|
65
64
|
res.attachment(`${filename}.xml`);
|
|
66
65
|
res.set('Content-Type', 'text/xml');
|
|
67
|
-
return res.status(200).send(exportService.transform(
|
|
66
|
+
return res.status(200).send(exportService.transform(res.locals.payload?.data, 'xml'));
|
|
68
67
|
}
|
|
69
68
|
if (req.sanitizedQuery.export === 'csv') {
|
|
70
69
|
res.attachment(`${filename}.csv`);
|
|
71
70
|
res.set('Content-Type', 'text/csv');
|
|
72
|
-
return res.status(200).send(exportService.transform(
|
|
71
|
+
return res.status(200).send(exportService.transform(res.locals.payload?.data, 'csv'));
|
|
72
|
+
}
|
|
73
|
+
if (req.sanitizedQuery.export === 'yaml') {
|
|
74
|
+
res.attachment(`${filename}.yaml`);
|
|
75
|
+
res.set('Content-Type', 'text/yaml');
|
|
76
|
+
return res.status(200).send(exportService.transform(res.locals.payload?.data, 'yaml'));
|
|
73
77
|
}
|
|
74
78
|
}
|
|
75
79
|
if (Buffer.isBuffer(res.locals.payload)) {
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
* Sanitize query parameters.
|
|
3
3
|
* This ensures that query params are formatted and ready to go for the services.
|
|
4
4
|
*/
|
|
5
|
-
import { RequestHandler } from 'express';
|
|
5
|
+
import type { RequestHandler } from 'express';
|
|
6
6
|
declare const sanitizeQueryMiddleware: RequestHandler;
|
|
7
7
|
export default sanitizeQueryMiddleware;
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
* Set req.collection for use in other middleware. Used as an alternative on validate-collection for
|
|
3
3
|
* system collections
|
|
4
4
|
*/
|
|
5
|
-
import { RequestHandler } from 'express';
|
|
5
|
+
import type { RequestHandler } from 'express';
|
|
6
6
|
declare const useCollection: (collection: string) => RequestHandler;
|
|
7
7
|
export default useCollection;
|
|
@@ -2,21 +2,32 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const utils_1 = require("@directus/shared/utils");
|
|
4
4
|
const vm2_1 = require("vm2");
|
|
5
|
+
const node_module_1 = require("node:module");
|
|
5
6
|
exports.default = (0, utils_1.defineOperationApi)({
|
|
6
7
|
id: 'exec',
|
|
7
8
|
handler: async ({ code }, { data, env }) => {
|
|
8
|
-
var _a;
|
|
9
9
|
const allowedModules = env.FLOWS_EXEC_ALLOWED_MODULES ? (0, utils_1.toArray)(env.FLOWS_EXEC_ALLOWED_MODULES) : [];
|
|
10
|
-
const
|
|
10
|
+
const allowedModulesBuiltIn = [];
|
|
11
|
+
const allowedModulesExternal = [];
|
|
12
|
+
const allowedEnv = data.$env ?? {};
|
|
11
13
|
const opts = {
|
|
12
14
|
eval: false,
|
|
13
15
|
wasm: false,
|
|
14
16
|
env: allowedEnv,
|
|
15
17
|
};
|
|
18
|
+
for (const module of allowedModules) {
|
|
19
|
+
if ((0, node_module_1.isBuiltin)(module)) {
|
|
20
|
+
allowedModulesBuiltIn.push(module);
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
allowedModulesExternal.push(module);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
16
26
|
if (allowedModules.length > 0) {
|
|
17
27
|
opts.require = {
|
|
28
|
+
builtin: allowedModulesBuiltIn,
|
|
18
29
|
external: {
|
|
19
|
-
modules:
|
|
30
|
+
modules: allowedModulesExternal,
|
|
20
31
|
transitive: false,
|
|
21
32
|
},
|
|
22
33
|
};
|
|
@@ -6,7 +6,6 @@ const get_accountability_for_role_1 = require("../../utils/get-accountability-fo
|
|
|
6
6
|
exports.default = (0, utils_1.defineOperationApi)({
|
|
7
7
|
id: 'item-create',
|
|
8
8
|
handler: async ({ collection, payload, emitEvents, permissions }, { accountability, database, getSchema }) => {
|
|
9
|
-
var _a;
|
|
10
9
|
const schema = await getSchema({ database });
|
|
11
10
|
let customAccountability;
|
|
12
11
|
if (!permissions || permissions === '$trigger') {
|
|
@@ -26,7 +25,7 @@ exports.default = (0, utils_1.defineOperationApi)({
|
|
|
26
25
|
accountability: customAccountability,
|
|
27
26
|
knex: database,
|
|
28
27
|
});
|
|
29
|
-
const payloadObject = (
|
|
28
|
+
const payloadObject = (0, utils_1.optionToObject)(payload) ?? null;
|
|
30
29
|
let result;
|
|
31
30
|
if (!payloadObject) {
|
|
32
31
|
result = null;
|
|
@@ -7,7 +7,6 @@ const sanitize_query_1 = require("../../utils/sanitize-query");
|
|
|
7
7
|
exports.default = (0, utils_1.defineOperationApi)({
|
|
8
8
|
id: 'item-update',
|
|
9
9
|
handler: async ({ collection, key, payload, query, emitEvents, permissions }, { accountability, database, getSchema }) => {
|
|
10
|
-
var _a;
|
|
11
10
|
const schema = await getSchema({ database });
|
|
12
11
|
let customAccountability;
|
|
13
12
|
if (!permissions || permissions === '$trigger') {
|
|
@@ -27,7 +26,7 @@ exports.default = (0, utils_1.defineOperationApi)({
|
|
|
27
26
|
accountability: customAccountability,
|
|
28
27
|
knex: database,
|
|
29
28
|
});
|
|
30
|
-
const payloadObject = (
|
|
29
|
+
const payloadObject = (0, utils_1.optionToObject)(payload) ?? null;
|
|
31
30
|
const queryObject = query ? (0, utils_1.optionToObject)(query) : {};
|
|
32
31
|
const sanitizedQueryObject = (0, sanitize_query_1.sanitizeQuery)(queryObject, customAccountability);
|
|
33
32
|
if (!payloadObject) {
|