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
|
@@ -27,10 +27,9 @@ exports.default = (0, utils_1.defineOperationApi)({
|
|
|
27
27
|
});
|
|
28
28
|
const messageString = message ? (0, utils_1.optionToString)(message) : null;
|
|
29
29
|
const payload = (0, utils_1.toArray)(recipient).map((userId) => {
|
|
30
|
-
var _a;
|
|
31
30
|
return {
|
|
32
31
|
recipient: userId,
|
|
33
|
-
sender:
|
|
32
|
+
sender: customAccountability?.user ?? null,
|
|
34
33
|
subject,
|
|
35
34
|
message: messageString,
|
|
36
35
|
};
|
|
@@ -5,33 +5,34 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const utils_1 = require("@directus/shared/utils");
|
|
7
7
|
const encodeurl_1 = __importDefault(require("encodeurl"));
|
|
8
|
+
const index_1 = require("../../request/index");
|
|
8
9
|
exports.default = (0, utils_1.defineOperationApi)({
|
|
9
10
|
id: 'request',
|
|
10
11
|
handler: async ({ url, method, body, headers }) => {
|
|
11
|
-
|
|
12
|
-
const axios = (await import('axios')).default;
|
|
13
|
-
const customHeaders = (_a = headers === null || headers === void 0 ? void 0 : headers.reduce((acc, { header, value }) => {
|
|
12
|
+
const customHeaders = headers?.reduce((acc, { header, value }) => {
|
|
14
13
|
acc[header] = value;
|
|
15
14
|
return acc;
|
|
16
|
-
}, {})
|
|
17
|
-
if (!customHeaders['Content-Type'] && isValidJSON(body)) {
|
|
15
|
+
}, {}) ?? {};
|
|
16
|
+
if (!customHeaders['Content-Type'] && (typeof body === 'object' || (0, utils_1.isValidJSON)(body))) {
|
|
18
17
|
customHeaders['Content-Type'] = 'application/json';
|
|
19
18
|
}
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
19
|
+
const axios = await (0, index_1.getAxios)();
|
|
20
|
+
try {
|
|
21
|
+
const result = await axios({
|
|
22
|
+
url: (0, encodeurl_1.default)(url),
|
|
23
|
+
method,
|
|
24
|
+
data: body,
|
|
25
|
+
headers: customHeaders,
|
|
26
|
+
});
|
|
27
|
+
return { status: result.status, statusText: result.statusText, headers: result.headers, data: result.data };
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
throw JSON.stringify({
|
|
31
|
+
status: error.response.status,
|
|
32
|
+
statusText: error.response.statusText,
|
|
33
|
+
headers: error.response.headers,
|
|
34
|
+
data: error.response.data,
|
|
35
|
+
});
|
|
35
36
|
}
|
|
36
37
|
},
|
|
37
38
|
});
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
type Options = {
|
|
2
2
|
flow: string;
|
|
3
3
|
payload?: Record<string, any> | Record<string, any>[] | string | null;
|
|
4
|
+
iterationMode?: 'serial' | 'batch' | 'parallel';
|
|
5
|
+
batchSize?: number;
|
|
4
6
|
};
|
|
5
7
|
declare const _default: import("@directus/shared/types").OperationApiConfig<Options>;
|
|
6
8
|
export default _default;
|
|
@@ -5,19 +5,35 @@ const lodash_1 = require("lodash");
|
|
|
5
5
|
const flows_1 = require("../../flows");
|
|
6
6
|
exports.default = (0, utils_1.defineOperationApi)({
|
|
7
7
|
id: 'trigger',
|
|
8
|
-
handler: async ({ flow, payload }, context) => {
|
|
9
|
-
var _a;
|
|
8
|
+
handler: async ({ flow, payload, iterationMode, batchSize }, context) => {
|
|
10
9
|
const flowManager = (0, flows_1.getFlowManager)();
|
|
11
|
-
const payloadObject = (
|
|
12
|
-
let result;
|
|
10
|
+
const payloadObject = (0, utils_1.optionToObject)(payload) ?? null;
|
|
13
11
|
if (Array.isArray(payloadObject)) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
if (iterationMode === 'serial') {
|
|
13
|
+
const result = [];
|
|
14
|
+
for (const payload of payloadObject) {
|
|
15
|
+
result.push(await flowManager.runOperationFlow(flow, payload, (0, lodash_1.omit)(context, 'data')));
|
|
16
|
+
}
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
if (iterationMode === 'batch') {
|
|
20
|
+
const size = batchSize ?? 10;
|
|
21
|
+
const result = [];
|
|
22
|
+
for (let i = 0; i < payloadObject.length; i += size) {
|
|
23
|
+
const batch = payloadObject.slice(i, i + size);
|
|
24
|
+
const batchResults = await Promise.all(batch.map((payload) => {
|
|
25
|
+
return flowManager.runOperationFlow(flow, payload, (0, lodash_1.omit)(context, 'data'));
|
|
26
|
+
}));
|
|
27
|
+
result.push(...batchResults);
|
|
28
|
+
}
|
|
29
|
+
return result;
|
|
30
|
+
}
|
|
31
|
+
if (iterationMode === 'parallel' || !iterationMode) {
|
|
32
|
+
return await Promise.all(payloadObject.map((payload) => {
|
|
33
|
+
return flowManager.runOperationFlow(flow, payload, (0, lodash_1.omit)(context, 'data'));
|
|
34
|
+
}));
|
|
35
|
+
}
|
|
17
36
|
}
|
|
18
|
-
|
|
19
|
-
result = await flowManager.runOperationFlow(flow, payloadObject, (0, lodash_1.omit)(context, 'data'));
|
|
20
|
-
}
|
|
21
|
-
return result;
|
|
37
|
+
return await flowManager.runOperationFlow(flow, payloadObject, (0, lodash_1.omit)(context, 'data'));
|
|
22
38
|
},
|
|
23
39
|
});
|
package/dist/rate-limiter.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { IRateLimiterOptions, IRateLimiterStoreOptions, RateLimiterAbstract } from 'rate-limiter-flexible';
|
|
2
2
|
type IRateLimiterOptionsOverrides = Partial<IRateLimiterOptions> | Partial<IRateLimiterStoreOptions>;
|
|
3
|
-
export declare function createRateLimiter(configOverrides?: IRateLimiterOptionsOverrides): RateLimiterAbstract;
|
|
3
|
+
export declare function createRateLimiter(configPrefix?: string, configOverrides?: IRateLimiterOptionsOverrides): RateLimiterAbstract;
|
|
4
4
|
export {};
|
package/dist/rate-limiter.js
CHANGED
|
@@ -8,28 +8,28 @@ const lodash_1 = require("lodash");
|
|
|
8
8
|
const rate_limiter_flexible_1 = require("rate-limiter-flexible");
|
|
9
9
|
const env_1 = __importDefault(require("./env"));
|
|
10
10
|
const get_config_from_env_1 = require("./utils/get-config-from-env");
|
|
11
|
-
function createRateLimiter(configOverrides) {
|
|
11
|
+
function createRateLimiter(configPrefix = 'RATE_LIMITER', configOverrides) {
|
|
12
12
|
switch (env_1.default.RATE_LIMITER_STORE) {
|
|
13
13
|
case 'redis':
|
|
14
|
-
return new rate_limiter_flexible_1.RateLimiterRedis(getConfig('redis', configOverrides));
|
|
14
|
+
return new rate_limiter_flexible_1.RateLimiterRedis(getConfig('redis', configPrefix, configOverrides));
|
|
15
15
|
case 'memcache':
|
|
16
|
-
return new rate_limiter_flexible_1.RateLimiterMemcache(getConfig('memcache', configOverrides));
|
|
16
|
+
return new rate_limiter_flexible_1.RateLimiterMemcache(getConfig('memcache', configPrefix, configOverrides));
|
|
17
17
|
case 'memory':
|
|
18
18
|
default:
|
|
19
|
-
return new rate_limiter_flexible_1.RateLimiterMemory(getConfig('memory', configOverrides));
|
|
19
|
+
return new rate_limiter_flexible_1.RateLimiterMemory(getConfig('memory', configPrefix, configOverrides));
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
exports.createRateLimiter = createRateLimiter;
|
|
23
|
-
function getConfig(store = 'memory', overrides) {
|
|
24
|
-
const config = (0, get_config_from_env_1.getConfigFromEnv)(
|
|
23
|
+
function getConfig(store = 'memory', configPrefix = 'RATE_LIMITER', overrides) {
|
|
24
|
+
const config = (0, get_config_from_env_1.getConfigFromEnv)(`${configPrefix}_`, `${configPrefix}_${store}_`);
|
|
25
25
|
if (store === 'redis') {
|
|
26
26
|
const Redis = require('ioredis');
|
|
27
27
|
delete config.redis;
|
|
28
|
-
config.storeClient = new Redis(env_1.default
|
|
28
|
+
config.storeClient = new Redis(env_1.default[`${configPrefix}_REDIS`] || (0, get_config_from_env_1.getConfigFromEnv)(`${configPrefix}_REDIS_`));
|
|
29
29
|
}
|
|
30
30
|
if (store === 'memcache') {
|
|
31
31
|
const Memcached = require('memcached');
|
|
32
|
-
config.storeClient = new Memcached(env_1.default
|
|
32
|
+
config.storeClient = new Memcached(env_1.default[`${configPrefix}_MEMCACHE`], (0, get_config_from_env_1.getConfigFromEnv)(`${configPrefix}_MEMCACHE_`));
|
|
33
33
|
}
|
|
34
34
|
delete config.enabled;
|
|
35
35
|
delete config.store;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getAxios = exports._cache = void 0;
|
|
4
|
+
const request_interceptor_1 = require("./request-interceptor");
|
|
5
|
+
const response_interceptor_1 = require("./response-interceptor");
|
|
6
|
+
exports._cache = {
|
|
7
|
+
axiosInstance: null,
|
|
8
|
+
};
|
|
9
|
+
async function getAxios() {
|
|
10
|
+
if (!exports._cache.axiosInstance) {
|
|
11
|
+
const axios = (await import('axios')).default;
|
|
12
|
+
exports._cache.axiosInstance = axios.create();
|
|
13
|
+
exports._cache.axiosInstance.interceptors.request.use(request_interceptor_1.requestInterceptor);
|
|
14
|
+
exports._cache.axiosInstance.interceptors.response.use(response_interceptor_1.responseInterceptor);
|
|
15
|
+
}
|
|
16
|
+
return exports._cache.axiosInstance;
|
|
17
|
+
}
|
|
18
|
+
exports.getAxios = getAxios;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
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.requestInterceptor = void 0;
|
|
7
|
+
const axios_1 = __importDefault(require("axios"));
|
|
8
|
+
const promises_1 = require("node:dns/promises");
|
|
9
|
+
const node_net_1 = require("node:net");
|
|
10
|
+
const node_url_1 = require("node:url");
|
|
11
|
+
const logger_1 = __importDefault(require("../logger"));
|
|
12
|
+
const validate_ip_1 = require("./validate-ip");
|
|
13
|
+
const requestInterceptor = async (config) => {
|
|
14
|
+
const uri = axios_1.default.getUri(config);
|
|
15
|
+
const { hostname } = new node_url_1.URL(uri);
|
|
16
|
+
let ip;
|
|
17
|
+
if ((0, node_net_1.isIP)(hostname) === 0) {
|
|
18
|
+
try {
|
|
19
|
+
const dns = await (0, promises_1.lookup)(hostname);
|
|
20
|
+
ip = dns.address;
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
logger_1.default.warn(err, `Couldn't lookup the DNS for url "${uri}"`);
|
|
24
|
+
throw new Error(`Requested URL "${uri}" resolves to a denied IP address`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
ip = hostname;
|
|
29
|
+
}
|
|
30
|
+
await (0, validate_ip_1.validateIP)(ip, uri);
|
|
31
|
+
return config;
|
|
32
|
+
};
|
|
33
|
+
exports.requestInterceptor = requestInterceptor;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.responseInterceptor = void 0;
|
|
4
|
+
const validate_ip_1 = require("./validate-ip");
|
|
5
|
+
const responseInterceptor = async (config) => {
|
|
6
|
+
await (0, validate_ip_1.validateIP)(config.request.socket.remoteAddress, config.request.url);
|
|
7
|
+
return config;
|
|
8
|
+
};
|
|
9
|
+
exports.responseInterceptor = responseInterceptor;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const validateIP: (ip: string, url: string) => Promise<void>;
|
|
@@ -0,0 +1,27 @@
|
|
|
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.validateIP = void 0;
|
|
7
|
+
const node_os_1 = __importDefault(require("node:os"));
|
|
8
|
+
const env_1 = require("../env");
|
|
9
|
+
const validateIP = async (ip, url) => {
|
|
10
|
+
const env = (0, env_1.getEnv)();
|
|
11
|
+
if (env.IMPORT_IP_DENY_LIST.includes(ip)) {
|
|
12
|
+
throw new Error(`Requested URL "${url}" resolves to a denied IP address`);
|
|
13
|
+
}
|
|
14
|
+
if (env.IMPORT_IP_DENY_LIST.includes('0.0.0.0')) {
|
|
15
|
+
const networkInterfaces = node_os_1.default.networkInterfaces();
|
|
16
|
+
for (const networkInfo of Object.values(networkInterfaces)) {
|
|
17
|
+
if (!networkInfo)
|
|
18
|
+
continue;
|
|
19
|
+
for (const info of networkInfo) {
|
|
20
|
+
if (info.address === ip) {
|
|
21
|
+
throw new Error(`Requested URL "${url}" resolves to a denied IP address`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
exports.validateIP = validateIP;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/server.js
CHANGED
|
@@ -32,14 +32,14 @@ const http = __importStar(require("http"));
|
|
|
32
32
|
const https = __importStar(require("https"));
|
|
33
33
|
const lodash_1 = require("lodash");
|
|
34
34
|
const qs_1 = __importDefault(require("qs"));
|
|
35
|
+
const update_check_1 = __importDefault(require("update-check"));
|
|
35
36
|
const url_1 = __importDefault(require("url"));
|
|
37
|
+
const package_json_1 = __importDefault(require("../package.json"));
|
|
36
38
|
const app_1 = __importDefault(require("./app"));
|
|
37
39
|
const database_1 = __importDefault(require("./database"));
|
|
40
|
+
const emitter_1 = __importDefault(require("./emitter"));
|
|
38
41
|
const env_1 = __importDefault(require("./env"));
|
|
39
42
|
const logger_1 = __importDefault(require("./logger"));
|
|
40
|
-
const emitter_1 = __importDefault(require("./emitter"));
|
|
41
|
-
const update_check_1 = __importDefault(require("update-check"));
|
|
42
|
-
const package_json_1 = __importDefault(require("../package.json"));
|
|
43
43
|
const get_config_from_env_1 = require("./utils/get-config-from-env");
|
|
44
44
|
async function createServer() {
|
|
45
45
|
const server = http.createServer(await (0, app_1.default)());
|
|
@@ -47,12 +47,11 @@ async function createServer() {
|
|
|
47
47
|
server.on('request', function (req, res) {
|
|
48
48
|
const startTime = process.hrtime();
|
|
49
49
|
const complete = (0, lodash_1.once)(function (finished) {
|
|
50
|
-
var _a, _b, _c, _d;
|
|
51
50
|
const elapsedTime = process.hrtime(startTime);
|
|
52
51
|
const elapsedNanoseconds = elapsedTime[0] * 1e9 + elapsedTime[1];
|
|
53
52
|
const elapsedMilliseconds = elapsedNanoseconds / 1e6;
|
|
54
|
-
const previousIn =
|
|
55
|
-
const previousOut =
|
|
53
|
+
const previousIn = req.socket._metrics?.in || 0;
|
|
54
|
+
const previousOut = req.socket._metrics?.out || 0;
|
|
56
55
|
const metrics = {
|
|
57
56
|
in: req.socket.bytesRead - previousIn,
|
|
58
57
|
out: req.socket.bytesWritten - previousOut,
|
|
@@ -85,13 +84,13 @@ async function createServer() {
|
|
|
85
84
|
size: metrics.out,
|
|
86
85
|
headers: res.getHeaders(),
|
|
87
86
|
},
|
|
88
|
-
ip: req.headers['x-forwarded-for'] ||
|
|
87
|
+
ip: req.headers['x-forwarded-for'] || req.socket?.remoteAddress,
|
|
89
88
|
duration: elapsedMilliseconds.toFixed(),
|
|
90
89
|
};
|
|
91
90
|
emitter_1.default.emitAction('response', info, {
|
|
92
91
|
database: (0, database_1.default)(),
|
|
93
92
|
schema: req.schema,
|
|
94
|
-
accountability:
|
|
93
|
+
accountability: req.accountability ?? null,
|
|
95
94
|
});
|
|
96
95
|
});
|
|
97
96
|
res.once('finish', complete.bind(null, true));
|
|
@@ -151,7 +150,7 @@ async function startServer() {
|
|
|
151
150
|
});
|
|
152
151
|
})
|
|
153
152
|
.once('error', (err) => {
|
|
154
|
-
if (
|
|
153
|
+
if (err?.code === 'EADDRINUSE') {
|
|
155
154
|
logger_1.default.error(`Port ${port} is already in use`);
|
|
156
155
|
process.exit(1);
|
|
157
156
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AbstractServiceOptions, Item, MutationOptions, PrimaryKey } from '../types';
|
|
1
|
+
import type { AbstractServiceOptions, Item, MutationOptions, PrimaryKey } from '../types';
|
|
2
2
|
import { ItemsService } from './items';
|
|
3
3
|
import { NotificationsService } from './notifications';
|
|
4
4
|
import { UsersService } from './users';
|
|
@@ -18,16 +18,17 @@ const items_1 = require("./items");
|
|
|
18
18
|
const notifications_1 = require("./notifications");
|
|
19
19
|
const users_1 = require("./users");
|
|
20
20
|
class ActivityService extends items_1.ItemsService {
|
|
21
|
+
notificationsService;
|
|
22
|
+
usersService;
|
|
21
23
|
constructor(options) {
|
|
22
24
|
super('directus_activity', options);
|
|
23
25
|
this.notificationsService = new notifications_1.NotificationsService({ schema: this.schema });
|
|
24
26
|
this.usersService = new users_1.UsersService({ schema: this.schema });
|
|
25
27
|
}
|
|
26
28
|
async createOne(data, opts) {
|
|
27
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
28
29
|
if (data.action === types_1.Action.COMMENT && typeof data.comment === 'string') {
|
|
29
30
|
const usersRegExp = new RegExp(/@[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}/gi);
|
|
30
|
-
const mentions = (0, lodash_1.uniq)(
|
|
31
|
+
const mentions = (0, lodash_1.uniq)(data.comment.match(usersRegExp) ?? []);
|
|
31
32
|
const sender = await this.usersService.readOne(this.accountability.user, {
|
|
32
33
|
fields: ['id', 'first_name', 'last_name', 'email'],
|
|
33
34
|
});
|
|
@@ -38,9 +39,9 @@ class ActivityService extends items_1.ItemsService {
|
|
|
38
39
|
});
|
|
39
40
|
const accountability = {
|
|
40
41
|
user: userID,
|
|
41
|
-
role:
|
|
42
|
-
admin:
|
|
43
|
-
app:
|
|
42
|
+
role: user.role?.id ?? null,
|
|
43
|
+
admin: user.role?.admin_access ?? null,
|
|
44
|
+
app: user.role?.app_access ?? null,
|
|
44
45
|
};
|
|
45
46
|
accountability.permissions = await (0, get_permissions_1.getPermissions)(accountability, this.schema);
|
|
46
47
|
const authorizationService = new authorization_1.AuthorizationService({ schema: this.schema, accountability });
|
|
@@ -61,7 +62,7 @@ class ActivityService extends items_1.ItemsService {
|
|
|
61
62
|
// We only match on UUIDs in the first place. This is just an extra sanity check
|
|
62
63
|
if ((0, uuid_validate_1.default)(uuid) === false)
|
|
63
64
|
continue;
|
|
64
|
-
comment = comment.replace(new RegExp(mention, 'gm'),
|
|
65
|
+
comment = comment.replace(new RegExp(mention, 'gm'), userPreviews[uuid] ?? '@Unknown User');
|
|
65
66
|
}
|
|
66
67
|
comment = `> ${comment.replace(/\n+/gm, '\n> ')}`;
|
|
67
68
|
const message = `
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import type { Range, Stat } from '@directus/storage';
|
|
3
|
-
import { Accountability } from '@directus/shared/types';
|
|
3
|
+
import type { Accountability } from '@directus/shared/types';
|
|
4
|
+
import type { Knex } from 'knex';
|
|
4
5
|
import type { Readable } from 'node:stream';
|
|
5
|
-
import {
|
|
6
|
-
import { AbstractServiceOptions, TransformationParams, TransformationPreset } from '../types';
|
|
6
|
+
import type { AbstractServiceOptions, TransformationParams, TransformationPreset } from '../types';
|
|
7
7
|
import { AuthorizationService } from './authorization';
|
|
8
8
|
export declare class AssetsService {
|
|
9
9
|
knex: Knex;
|
package/dist/services/assets.js
CHANGED
|
@@ -27,7 +27,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
29
|
exports.AssetsService = void 0;
|
|
30
|
-
const
|
|
30
|
+
const lodash_1 = require("lodash");
|
|
31
31
|
const mime_types_1 = require("mime-types");
|
|
32
32
|
const object_hash_1 = __importDefault(require("object-hash"));
|
|
33
33
|
const path_1 = __importDefault(require("path"));
|
|
@@ -36,22 +36,22 @@ const uuid_validate_1 = __importDefault(require("uuid-validate"));
|
|
|
36
36
|
const database_1 = __importDefault(require("../database"));
|
|
37
37
|
const env_1 = __importDefault(require("../env"));
|
|
38
38
|
const exceptions_1 = require("../exceptions");
|
|
39
|
+
const service_unavailable_1 = require("../exceptions/service-unavailable");
|
|
39
40
|
const logger_1 = __importDefault(require("../logger"));
|
|
40
41
|
const storage_1 = require("../storage");
|
|
42
|
+
const get_milliseconds_1 = require("../utils/get-milliseconds");
|
|
41
43
|
const TransformationUtils = __importStar(require("../utils/transformations"));
|
|
42
44
|
const authorization_1 = require("./authorization");
|
|
43
|
-
sharp_1.default.concurrency(1);
|
|
44
|
-
// Note: don't put this in the service. The service can be initialized in multiple places, but they
|
|
45
|
-
// should all share the same semaphore instance.
|
|
46
|
-
const semaphore = new async_mutex_1.Semaphore(env_1.default.ASSETS_TRANSFORM_MAX_CONCURRENT);
|
|
47
45
|
class AssetsService {
|
|
46
|
+
knex;
|
|
47
|
+
accountability;
|
|
48
|
+
authorizationService;
|
|
48
49
|
constructor(options) {
|
|
49
50
|
this.knex = options.knex || (0, database_1.default)();
|
|
50
51
|
this.accountability = options.accountability || null;
|
|
51
52
|
this.authorizationService = new authorization_1.AuthorizationService(options);
|
|
52
53
|
}
|
|
53
54
|
async getAsset(id, transformation, range) {
|
|
54
|
-
var _a;
|
|
55
55
|
const storage = await (0, storage_1.getStorage)();
|
|
56
56
|
const publicSettings = await this.knex
|
|
57
57
|
.select('project_logo', 'public_background', 'public_foreground')
|
|
@@ -66,7 +66,7 @@ class AssetsService {
|
|
|
66
66
|
const isValidUUID = (0, uuid_validate_1.default)(id, 4);
|
|
67
67
|
if (isValidUUID === false)
|
|
68
68
|
throw new exceptions_1.ForbiddenException();
|
|
69
|
-
if (systemPublicKeys.includes(id) === false &&
|
|
69
|
+
if (systemPublicKeys.includes(id) === false && this.accountability?.admin !== true) {
|
|
70
70
|
await this.authorizationService.checkAccess('read', 'directus_files', id);
|
|
71
71
|
}
|
|
72
72
|
const file = (await this.knex.select('*').from('directus_files').where({ id }).first());
|
|
@@ -135,27 +135,34 @@ class AssetsService {
|
|
|
135
135
|
height > env_1.default.ASSETS_TRANSFORM_IMAGE_MAX_DIMENSION) {
|
|
136
136
|
throw new exceptions_1.IllegalAssetTransformation(`Image is too large to be transformed, or image size couldn't be determined.`);
|
|
137
137
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
sequentialRead: true,
|
|
143
|
-
failOn: env_1.default.ASSETS_INVALID_IMAGE_SENSITIVITY_LEVEL,
|
|
138
|
+
const { queue, process } = sharp_1.default.counters();
|
|
139
|
+
if (queue + process > env_1.default.ASSETS_TRANSFORM_MAX_CONCURRENT) {
|
|
140
|
+
throw new service_unavailable_1.ServiceUnavailableException('Server too busy', {
|
|
141
|
+
service: 'files',
|
|
144
142
|
});
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
143
|
+
}
|
|
144
|
+
const readStream = await storage.location(file.storage).read(file.filename_disk, range);
|
|
145
|
+
const transformer = (0, sharp_1.default)({
|
|
146
|
+
limitInputPixels: Math.pow(env_1.default.ASSETS_TRANSFORM_IMAGE_MAX_DIMENSION, 2),
|
|
147
|
+
sequentialRead: true,
|
|
148
|
+
failOn: env_1.default.ASSETS_INVALID_IMAGE_SENSITIVITY_LEVEL,
|
|
149
|
+
});
|
|
150
|
+
transformer.timeout({
|
|
151
|
+
seconds: (0, lodash_1.clamp)(Math.round((0, get_milliseconds_1.getMilliseconds)(env_1.default.ASSETS_TRANSFORM_TIMEOUT, 0) / 1000), 1, 3600),
|
|
152
|
+
});
|
|
153
|
+
if (transforms.find((transform) => transform[0] === 'rotate') === undefined)
|
|
154
|
+
transformer.rotate();
|
|
155
|
+
transforms.forEach(([method, ...args]) => transformer[method].apply(transformer, args));
|
|
156
|
+
readStream.on('error', (e) => {
|
|
157
|
+
logger_1.default.error(e, `Couldn't transform file ${file.id}`);
|
|
158
|
+
readStream.unpipe(transformer);
|
|
158
159
|
});
|
|
160
|
+
await storage.location(file.storage).write(assetFilename, readStream.pipe(transformer), type);
|
|
161
|
+
return {
|
|
162
|
+
stream: await storage.location(file.storage).read(assetFilename, range),
|
|
163
|
+
stat: await storage.location(file.storage).stat(assetFilename),
|
|
164
|
+
file,
|
|
165
|
+
};
|
|
159
166
|
}
|
|
160
167
|
else {
|
|
161
168
|
const readStream = await storage.location(file.storage).read(file.filename_disk, range);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Accountability, SchemaOverview } from '@directus/shared/types';
|
|
2
|
-
import { Knex } from 'knex';
|
|
3
|
-
import { AbstractServiceOptions, LoginResult } from '../types';
|
|
2
|
+
import type { Knex } from 'knex';
|
|
3
|
+
import type { AbstractServiceOptions, LoginResult } from '../types';
|
|
4
4
|
import { ActivityService } from './activity';
|
|
5
5
|
export declare class AuthenticationService {
|
|
6
6
|
knex: Knex;
|