directus 9.23.1 → 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 +14 -10
- package/dist/auth/auth.d.ts +3 -3
- package/dist/auth/auth.js +2 -0
- package/dist/auth/drivers/ldap.d.ts +1 -1
- package/dist/auth/drivers/ldap.js +39 -28
- 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 +20 -13
- package/dist/auth/drivers/openid.d.ts +1 -1
- package/dist/auth/drivers/openid.js +21 -14
- 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 +57 -14
- 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 +14 -15
- package/dist/cli/commands/schema/snapshot.js +2 -2
- package/dist/cli/utils/create-db-connection.d.ts +1 -1
- package/dist/cli/utils/create-db-connection.js +2 -1
- package/dist/cli/utils/create-env/index.d.ts +2 -2
- package/dist/cli/utils/drivers.d.ts +1 -1
- package/dist/constants.d.ts +2 -2
- package/dist/constants.js +2 -3
- package/dist/controllers/activity.js +1 -2
- package/dist/controllers/assets.js +14 -9
- package/dist/controllers/auth.js +29 -15
- package/dist/controllers/dashboards.js +5 -2
- package/dist/controllers/fields.js +4 -4
- package/dist/controllers/files.js +10 -5
- package/dist/controllers/flows.js +5 -2
- package/dist/controllers/folders.js +5 -2
- package/dist/controllers/graphql.js +2 -4
- 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/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 +1 -1
- 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 +2 -2
- package/dist/database/helpers/schema/dialects/oracle.js +4 -6
- package/dist/database/helpers/schema/types.d.ts +4 -4
- package/dist/database/helpers/types.d.ts +1 -1
- package/dist/database/helpers/types.js +1 -0
- package/dist/database/index.d.ts +1 -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 +17 -26
- 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 +10 -2
- 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 +33 -23
- package/dist/flows.js +42 -25
- 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 +5 -5
- 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 +6 -7
- 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 +19 -19
- package/dist/operations/trigger/index.js +2 -3
- package/dist/rate-limiter.d.ts +1 -1
- package/dist/rate-limiter.js +8 -8
- 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 -35
- package/dist/services/authentication.d.ts +2 -2
- package/dist/services/authentication.js +13 -10
- 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 +48 -48
- package/dist/services/files.d.ts +1 -2
- package/dist/services/files.js +27 -21
- 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 +172 -167
- 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 +11 -4
- package/dist/services/import-export.d.ts +3 -3
- package/dist/services/import-export.js +25 -22
- package/dist/services/items.d.ts +3 -3
- package/dist/services/items.js +42 -36
- 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 +45 -43
- package/dist/services/revisions.d.ts +1 -1
- package/dist/services/roles.d.ts +2 -2
- package/dist/services/roles.js +2 -2
- package/dist/services/schema.d.ts +3 -3
- package/dist/services/schema.js +9 -11
- 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 +1 -1
- package/dist/services/shares.js +5 -6
- 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 +17 -17
- 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 +1 -1
- 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/events.d.ts +2 -2
- package/dist/types/graphql.d.ts +2 -2
- package/dist/types/items.d.ts +3 -3
- package/dist/types/services.d.ts +5 -5
- package/dist/types/snapshot.d.ts +4 -4
- package/dist/utils/apply-diff.d.ts +3 -3
- package/dist/utils/apply-diff.js +25 -28
- package/dist/utils/apply-query.d.ts +3 -3
- package/dist/utils/apply-query.js +8 -11
- package/dist/utils/apply-snapshot.d.ts +3 -3
- package/dist/utils/apply-snapshot.js +5 -6
- 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 +1 -1
- package/dist/utils/get-cache-headers.js +3 -4
- 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.js +1 -2
- 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 +2 -3
- package/dist/utils/get-snapshot.d.ts +3 -3
- package/dist/utils/get-snapshot.js +6 -8
- 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/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 +2 -2
- 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/transformations.d.ts +1 -1
- package/dist/utils/transformations.js +2 -4
- package/dist/utils/url.js +7 -2
- package/dist/utils/user-name.d.ts +1 -1
- package/dist/utils/validate-diff.js +7 -8
- 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 +2 -2
- package/dist/webhooks.js +1 -1
- package/package.json +36 -37
- package/dist/utils/with-timeout.d.ts +0 -1
- package/dist/utils/with-timeout.js +0 -16
|
@@ -6,8 +6,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.SpecificationService = void 0;
|
|
7
7
|
const specs_1 = __importDefault(require("@directus/specs"));
|
|
8
8
|
const lodash_1 = require("lodash");
|
|
9
|
-
// @ts-ignore
|
|
10
9
|
const package_json_1 = require("../../package.json");
|
|
10
|
+
const constants_1 = require("../constants");
|
|
11
11
|
const database_1 = __importDefault(require("../database"));
|
|
12
12
|
const env_1 = __importDefault(require("../env"));
|
|
13
13
|
const get_relation_type_1 = require("../utils/get-relation-type");
|
|
@@ -15,10 +15,17 @@ const collections_1 = require("./collections");
|
|
|
15
15
|
const fields_1 = require("./fields");
|
|
16
16
|
const graphql_1 = require("./graphql");
|
|
17
17
|
const relations_1 = require("./relations");
|
|
18
|
-
const constants_1 = require("../constants");
|
|
19
18
|
// @ts-ignore
|
|
20
19
|
const format_title_1 = __importDefault(require("@directus/format-title"));
|
|
21
20
|
class SpecificationService {
|
|
21
|
+
accountability;
|
|
22
|
+
knex;
|
|
23
|
+
schema;
|
|
24
|
+
fieldsService;
|
|
25
|
+
collectionsService;
|
|
26
|
+
relationsService;
|
|
27
|
+
oas;
|
|
28
|
+
graphql;
|
|
22
29
|
constructor(options) {
|
|
23
30
|
this.accountability = options.accountability || null;
|
|
24
31
|
this.knex = options.knex || (0, database_1.default)();
|
|
@@ -36,93 +43,13 @@ class SpecificationService {
|
|
|
36
43
|
}
|
|
37
44
|
exports.SpecificationService = SpecificationService;
|
|
38
45
|
class OASSpecsService {
|
|
46
|
+
accountability;
|
|
47
|
+
knex;
|
|
48
|
+
schema;
|
|
49
|
+
fieldsService;
|
|
50
|
+
collectionsService;
|
|
51
|
+
relationsService;
|
|
39
52
|
constructor(options, { fieldsService, collectionsService, relationsService, }) {
|
|
40
|
-
this.fieldTypes = {
|
|
41
|
-
alias: {
|
|
42
|
-
type: 'string',
|
|
43
|
-
},
|
|
44
|
-
bigInteger: {
|
|
45
|
-
type: 'integer',
|
|
46
|
-
format: 'int64',
|
|
47
|
-
},
|
|
48
|
-
binary: {
|
|
49
|
-
type: 'string',
|
|
50
|
-
format: 'binary',
|
|
51
|
-
},
|
|
52
|
-
boolean: {
|
|
53
|
-
type: 'boolean',
|
|
54
|
-
},
|
|
55
|
-
csv: {
|
|
56
|
-
type: 'array',
|
|
57
|
-
items: {
|
|
58
|
-
type: 'string',
|
|
59
|
-
},
|
|
60
|
-
},
|
|
61
|
-
date: {
|
|
62
|
-
type: 'string',
|
|
63
|
-
format: 'date',
|
|
64
|
-
},
|
|
65
|
-
dateTime: {
|
|
66
|
-
type: 'string',
|
|
67
|
-
format: 'date-time',
|
|
68
|
-
},
|
|
69
|
-
decimal: {
|
|
70
|
-
type: 'number',
|
|
71
|
-
},
|
|
72
|
-
float: {
|
|
73
|
-
type: 'number',
|
|
74
|
-
format: 'float',
|
|
75
|
-
},
|
|
76
|
-
hash: {
|
|
77
|
-
type: 'string',
|
|
78
|
-
},
|
|
79
|
-
integer: {
|
|
80
|
-
type: 'integer',
|
|
81
|
-
},
|
|
82
|
-
json: {},
|
|
83
|
-
string: {
|
|
84
|
-
type: 'string',
|
|
85
|
-
},
|
|
86
|
-
text: {
|
|
87
|
-
type: 'string',
|
|
88
|
-
},
|
|
89
|
-
time: {
|
|
90
|
-
type: 'string',
|
|
91
|
-
format: 'time',
|
|
92
|
-
},
|
|
93
|
-
timestamp: {
|
|
94
|
-
type: 'string',
|
|
95
|
-
format: 'timestamp',
|
|
96
|
-
},
|
|
97
|
-
unknown: {
|
|
98
|
-
type: undefined,
|
|
99
|
-
},
|
|
100
|
-
uuid: {
|
|
101
|
-
type: 'string',
|
|
102
|
-
format: 'uuid',
|
|
103
|
-
},
|
|
104
|
-
geometry: {
|
|
105
|
-
type: 'object',
|
|
106
|
-
},
|
|
107
|
-
'geometry.Point': {
|
|
108
|
-
type: 'object',
|
|
109
|
-
},
|
|
110
|
-
'geometry.LineString': {
|
|
111
|
-
type: 'object',
|
|
112
|
-
},
|
|
113
|
-
'geometry.Polygon': {
|
|
114
|
-
type: 'object',
|
|
115
|
-
},
|
|
116
|
-
'geometry.MultiPoint': {
|
|
117
|
-
type: 'object',
|
|
118
|
-
},
|
|
119
|
-
'geometry.MultiLineString': {
|
|
120
|
-
type: 'object',
|
|
121
|
-
},
|
|
122
|
-
'geometry.MultiPolygon': {
|
|
123
|
-
type: 'object',
|
|
124
|
-
},
|
|
125
|
-
};
|
|
126
53
|
this.accountability = options.accountability || null;
|
|
127
54
|
this.knex = options.knex || (0, database_1.default)();
|
|
128
55
|
this.schema = options.schema;
|
|
@@ -131,11 +58,10 @@ class OASSpecsService {
|
|
|
131
58
|
this.relationsService = relationsService;
|
|
132
59
|
}
|
|
133
60
|
async generate() {
|
|
134
|
-
var _a, _b;
|
|
135
61
|
const collections = await this.collectionsService.readByQuery();
|
|
136
62
|
const fields = await this.fieldsService.readAll();
|
|
137
63
|
const relations = (await this.relationsService.readAll());
|
|
138
|
-
const permissions =
|
|
64
|
+
const permissions = this.accountability?.permissions ?? [];
|
|
139
65
|
const tags = await this.generateTags(collections);
|
|
140
66
|
const paths = await this.generatePaths(permissions, tags);
|
|
141
67
|
const components = await this.generateComponents(collections, fields, relations, tags);
|
|
@@ -152,14 +78,15 @@ class OASSpecsService {
|
|
|
152
78
|
description: 'Your current Directus instance.',
|
|
153
79
|
},
|
|
154
80
|
],
|
|
155
|
-
tags,
|
|
156
81
|
paths,
|
|
157
|
-
components,
|
|
158
82
|
};
|
|
83
|
+
if (tags)
|
|
84
|
+
spec.tags = tags;
|
|
85
|
+
if (components)
|
|
86
|
+
spec.components = components;
|
|
159
87
|
return spec;
|
|
160
88
|
}
|
|
161
89
|
async generateTags(collections) {
|
|
162
|
-
var _a;
|
|
163
90
|
const systemTags = (0, lodash_1.cloneDeep)(specs_1.default.tags);
|
|
164
91
|
const tags = [];
|
|
165
92
|
// System tags that don't have an associated collection are always readable to the user
|
|
@@ -180,18 +107,20 @@ class OASSpecsService {
|
|
|
180
107
|
}
|
|
181
108
|
}
|
|
182
109
|
else {
|
|
183
|
-
|
|
110
|
+
const tag = {
|
|
184
111
|
name: 'Items' + (0, format_title_1.default)(collection.collection).replace(/ /g, ''),
|
|
185
|
-
description: ((_a = collection.meta) === null || _a === void 0 ? void 0 : _a.note) || undefined,
|
|
186
112
|
'x-collection': collection.collection,
|
|
187
|
-
}
|
|
113
|
+
};
|
|
114
|
+
if (collection.meta?.note) {
|
|
115
|
+
tag.description = collection.meta.note;
|
|
116
|
+
}
|
|
117
|
+
tags.push(tag);
|
|
188
118
|
}
|
|
189
119
|
}
|
|
190
120
|
// Filter out the generic Items information
|
|
191
121
|
return tags.filter((tag) => tag.name !== 'Items');
|
|
192
122
|
}
|
|
193
123
|
async generatePaths(permissions, tags) {
|
|
194
|
-
var _a, _b, _c, _d, _e;
|
|
195
124
|
const paths = {};
|
|
196
125
|
if (!tags)
|
|
197
126
|
return paths;
|
|
@@ -200,11 +129,11 @@ class OASSpecsService {
|
|
|
200
129
|
if (isSystem) {
|
|
201
130
|
for (const [path, pathItem] of Object.entries(specs_1.default.paths)) {
|
|
202
131
|
for (const [method, operation] of Object.entries(pathItem)) {
|
|
203
|
-
if (
|
|
132
|
+
if (operation.tags?.includes(tag.name)) {
|
|
204
133
|
if (!paths[path]) {
|
|
205
134
|
paths[path] = {};
|
|
206
135
|
}
|
|
207
|
-
const hasPermission =
|
|
136
|
+
const hasPermission = this.accountability?.admin === true ||
|
|
208
137
|
'x-collection' in tag === false ||
|
|
209
138
|
!!permissions.find((permission) => permission.collection === tag['x-collection'] &&
|
|
210
139
|
permission.action === this.getActionForMethod(method));
|
|
@@ -212,7 +141,7 @@ class OASSpecsService {
|
|
|
212
141
|
if ('parameters' in pathItem) {
|
|
213
142
|
paths[path][method] = {
|
|
214
143
|
...operation,
|
|
215
|
-
parameters: [...(
|
|
144
|
+
parameters: [...(pathItem.parameters ?? []), ...(operation?.parameters ?? [])],
|
|
216
145
|
};
|
|
217
146
|
}
|
|
218
147
|
else {
|
|
@@ -228,7 +157,7 @@ class OASSpecsService {
|
|
|
228
157
|
const detailBase = (0, lodash_1.cloneDeep)(specs_1.default.paths['/items/{collection}/{id}']);
|
|
229
158
|
const collection = tag['x-collection'];
|
|
230
159
|
for (const method of ['post', 'get', 'patch', 'delete']) {
|
|
231
|
-
const hasPermission =
|
|
160
|
+
const hasPermission = this.accountability?.admin === true ||
|
|
232
161
|
!!permissions.find((permission) => permission.collection === collection && permission.action === this.getActionForMethod(method));
|
|
233
162
|
if (hasPermission) {
|
|
234
163
|
if (!paths[`/items/${collection}`])
|
|
@@ -332,13 +261,12 @@ class OASSpecsService {
|
|
|
332
261
|
return paths;
|
|
333
262
|
}
|
|
334
263
|
async generateComponents(collections, fields, relations, tags) {
|
|
335
|
-
var _a;
|
|
336
264
|
let components = (0, lodash_1.cloneDeep)(specs_1.default.components);
|
|
337
265
|
if (!components)
|
|
338
266
|
components = {};
|
|
339
267
|
components.schemas = {};
|
|
340
268
|
// Always includes the schemas with these names
|
|
341
|
-
if (
|
|
269
|
+
if (specs_1.default.components?.schemas !== null) {
|
|
342
270
|
for (const schemaName of constants_1.OAS_REQUIRED_SCHEMAS) {
|
|
343
271
|
if (specs_1.default.components.schemas[schemaName] !== null) {
|
|
344
272
|
components.schemas[schemaName] = (0, lodash_1.cloneDeep)(specs_1.default.components.schemas[schemaName]);
|
|
@@ -377,7 +305,7 @@ class OASSpecsService {
|
|
|
377
305
|
return components;
|
|
378
306
|
}
|
|
379
307
|
filterCollectionFromParams(parameters) {
|
|
380
|
-
return parameters.filter((param) =>
|
|
308
|
+
return parameters.filter((param) => param?.$ref !== '#/components/parameters/Collection');
|
|
381
309
|
}
|
|
382
310
|
getActionForMethod(method) {
|
|
383
311
|
switch (method) {
|
|
@@ -393,16 +321,15 @@ class OASSpecsService {
|
|
|
393
321
|
}
|
|
394
322
|
}
|
|
395
323
|
generateField(field, relations, tags, fields) {
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
nullable
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
});
|
|
324
|
+
let propertyObject = {};
|
|
325
|
+
if (field.schema && 'is_nullable' in field.schema) {
|
|
326
|
+
propertyObject.nullable = field.schema.is_nullable;
|
|
327
|
+
}
|
|
328
|
+
if (field.meta?.note) {
|
|
329
|
+
propertyObject.description = field.meta.note;
|
|
330
|
+
}
|
|
331
|
+
const relation = relations.find((relation) => (relation.collection === field.collection && relation.field === field.field) ||
|
|
332
|
+
(relation.related_collection === field.collection && relation.meta?.one_field === field.field));
|
|
406
333
|
if (!relation) {
|
|
407
334
|
propertyObject = {
|
|
408
335
|
...propertyObject,
|
|
@@ -417,7 +344,7 @@ class OASSpecsService {
|
|
|
417
344
|
});
|
|
418
345
|
if (relationType === 'm2o') {
|
|
419
346
|
const relatedTag = tags.find((tag) => tag['x-collection'] === relation.related_collection);
|
|
420
|
-
const relatedPrimaryKeyField = fields.find((field) =>
|
|
347
|
+
const relatedPrimaryKeyField = fields.find((field) => field.collection === relation.related_collection && field.schema?.is_primary_key);
|
|
421
348
|
if (!relatedTag || !relatedPrimaryKeyField)
|
|
422
349
|
return propertyObject;
|
|
423
350
|
propertyObject.oneOf = [
|
|
@@ -431,7 +358,7 @@ class OASSpecsService {
|
|
|
431
358
|
}
|
|
432
359
|
else if (relationType === 'o2m') {
|
|
433
360
|
const relatedTag = tags.find((tag) => tag['x-collection'] === relation.collection);
|
|
434
|
-
const relatedPrimaryKeyField = fields.find((field) =>
|
|
361
|
+
const relatedPrimaryKeyField = fields.find((field) => field.collection === relation.collection && field.schema?.is_primary_key);
|
|
435
362
|
if (!relatedTag || !relatedPrimaryKeyField)
|
|
436
363
|
return propertyObject;
|
|
437
364
|
propertyObject.type = 'array';
|
|
@@ -463,8 +390,97 @@ class OASSpecsService {
|
|
|
463
390
|
}
|
|
464
391
|
return propertyObject;
|
|
465
392
|
}
|
|
393
|
+
fieldTypes = {
|
|
394
|
+
alias: {
|
|
395
|
+
type: 'string',
|
|
396
|
+
},
|
|
397
|
+
bigInteger: {
|
|
398
|
+
type: 'integer',
|
|
399
|
+
format: 'int64',
|
|
400
|
+
},
|
|
401
|
+
binary: {
|
|
402
|
+
type: 'string',
|
|
403
|
+
format: 'binary',
|
|
404
|
+
},
|
|
405
|
+
boolean: {
|
|
406
|
+
type: 'boolean',
|
|
407
|
+
},
|
|
408
|
+
csv: {
|
|
409
|
+
type: 'array',
|
|
410
|
+
items: {
|
|
411
|
+
type: 'string',
|
|
412
|
+
},
|
|
413
|
+
},
|
|
414
|
+
date: {
|
|
415
|
+
type: 'string',
|
|
416
|
+
format: 'date',
|
|
417
|
+
},
|
|
418
|
+
dateTime: {
|
|
419
|
+
type: 'string',
|
|
420
|
+
format: 'date-time',
|
|
421
|
+
},
|
|
422
|
+
decimal: {
|
|
423
|
+
type: 'number',
|
|
424
|
+
},
|
|
425
|
+
float: {
|
|
426
|
+
type: 'number',
|
|
427
|
+
format: 'float',
|
|
428
|
+
},
|
|
429
|
+
hash: {
|
|
430
|
+
type: 'string',
|
|
431
|
+
},
|
|
432
|
+
integer: {
|
|
433
|
+
type: 'integer',
|
|
434
|
+
},
|
|
435
|
+
json: {},
|
|
436
|
+
string: {
|
|
437
|
+
type: 'string',
|
|
438
|
+
},
|
|
439
|
+
text: {
|
|
440
|
+
type: 'string',
|
|
441
|
+
},
|
|
442
|
+
time: {
|
|
443
|
+
type: 'string',
|
|
444
|
+
format: 'time',
|
|
445
|
+
},
|
|
446
|
+
timestamp: {
|
|
447
|
+
type: 'string',
|
|
448
|
+
format: 'timestamp',
|
|
449
|
+
},
|
|
450
|
+
unknown: {},
|
|
451
|
+
uuid: {
|
|
452
|
+
type: 'string',
|
|
453
|
+
format: 'uuid',
|
|
454
|
+
},
|
|
455
|
+
geometry: {
|
|
456
|
+
type: 'object',
|
|
457
|
+
},
|
|
458
|
+
'geometry.Point': {
|
|
459
|
+
type: 'object',
|
|
460
|
+
},
|
|
461
|
+
'geometry.LineString': {
|
|
462
|
+
type: 'object',
|
|
463
|
+
},
|
|
464
|
+
'geometry.Polygon': {
|
|
465
|
+
type: 'object',
|
|
466
|
+
},
|
|
467
|
+
'geometry.MultiPoint': {
|
|
468
|
+
type: 'object',
|
|
469
|
+
},
|
|
470
|
+
'geometry.MultiLineString': {
|
|
471
|
+
type: 'object',
|
|
472
|
+
},
|
|
473
|
+
'geometry.MultiPolygon': {
|
|
474
|
+
type: 'object',
|
|
475
|
+
},
|
|
476
|
+
};
|
|
466
477
|
}
|
|
467
478
|
class GraphQLSpecsService {
|
|
479
|
+
accountability;
|
|
480
|
+
knex;
|
|
481
|
+
schema;
|
|
482
|
+
items;
|
|
483
|
+
system;
|
|
468
484
|
constructor(options) {
|
|
469
485
|
this.accountability = options.accountability || null;
|
|
470
486
|
this.knex = options.knex || (0, database_1.default)();
|
package/dist/services/tfa.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Knex } from 'knex';
|
|
1
|
+
import type { Knex } from 'knex';
|
|
2
|
+
import type { AbstractServiceOptions, PrimaryKey } from '../types';
|
|
2
3
|
import { ItemsService } from './items';
|
|
3
|
-
import { AbstractServiceOptions, PrimaryKey } from '../types';
|
|
4
4
|
export declare class TFAService {
|
|
5
5
|
knex: Knex;
|
|
6
6
|
itemsService: ItemsService;
|
package/dist/services/tfa.js
CHANGED
|
@@ -9,6 +9,8 @@ const database_1 = __importDefault(require("../database"));
|
|
|
9
9
|
const exceptions_1 = require("../exceptions");
|
|
10
10
|
const items_1 = require("./items");
|
|
11
11
|
class TFAService {
|
|
12
|
+
knex;
|
|
13
|
+
itemsService;
|
|
12
14
|
constructor(options) {
|
|
13
15
|
this.knex = options.knex || (0, database_1.default)();
|
|
14
16
|
this.itemsService = new items_1.ItemsService('directus_users', options);
|
|
@@ -18,29 +20,29 @@ class TFAService {
|
|
|
18
20
|
return otplib_1.authenticator.check(otp, secret);
|
|
19
21
|
}
|
|
20
22
|
const user = await this.knex.select('tfa_secret').from('directus_users').where({ id: key }).first();
|
|
21
|
-
if (!
|
|
23
|
+
if (!user?.tfa_secret) {
|
|
22
24
|
throw new exceptions_1.InvalidPayloadException(`User "${key}" doesn't have TFA enabled.`);
|
|
23
25
|
}
|
|
24
26
|
return otplib_1.authenticator.check(otp, user.tfa_secret);
|
|
25
27
|
}
|
|
26
28
|
async generateTFA(key) {
|
|
27
29
|
const user = await this.knex.select('email', 'tfa_secret').from('directus_users').where({ id: key }).first();
|
|
28
|
-
if (
|
|
30
|
+
if (user?.tfa_secret !== null) {
|
|
29
31
|
throw new exceptions_1.InvalidPayloadException('TFA Secret is already set for this user');
|
|
30
32
|
}
|
|
31
|
-
if (!
|
|
33
|
+
if (!user?.email) {
|
|
32
34
|
throw new exceptions_1.InvalidPayloadException('User must have a valid email to enable TFA');
|
|
33
35
|
}
|
|
34
36
|
const secret = otplib_1.authenticator.generateSecret();
|
|
35
37
|
const project = await this.knex.select('project_name').from('directus_settings').limit(1).first();
|
|
36
38
|
return {
|
|
37
39
|
secret,
|
|
38
|
-
url: otplib_1.authenticator.keyuri(user.email,
|
|
40
|
+
url: otplib_1.authenticator.keyuri(user.email, project?.project_name || 'Directus', secret),
|
|
39
41
|
};
|
|
40
42
|
}
|
|
41
43
|
async enableTFA(key, otp, secret) {
|
|
42
44
|
const user = await this.knex.select('tfa_secret').from('directus_users').where({ id: key }).first();
|
|
43
|
-
if (
|
|
45
|
+
if (user?.tfa_secret !== null) {
|
|
44
46
|
throw new exceptions_1.InvalidPayloadException('TFA Secret is already set for this user');
|
|
45
47
|
}
|
|
46
48
|
if (!otplib_1.authenticator.check(otp, secret)) {
|
package/dist/services/users.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import type { Accountability, Query, SchemaOverview } from '@directus/shared/types';
|
|
2
|
+
import type { Knex } from 'knex';
|
|
3
|
+
import type { AbstractServiceOptions, Item, MutationOptions, PrimaryKey } from '../types';
|
|
4
4
|
import { ItemsService } from './items';
|
|
5
5
|
export declare class UsersService extends ItemsService {
|
|
6
6
|
knex: Knex;
|
package/dist/services/users.js
CHANGED
|
@@ -4,23 +4,25 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.UsersService = void 0;
|
|
7
|
+
const exceptions_1 = require("@directus/shared/exceptions");
|
|
8
|
+
const utils_1 = require("@directus/shared/utils");
|
|
7
9
|
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
|
|
8
10
|
const lodash_1 = require("lodash");
|
|
11
|
+
const perf_hooks_1 = require("perf_hooks");
|
|
9
12
|
const database_1 = __importDefault(require("../database"));
|
|
10
13
|
const env_1 = __importDefault(require("../env"));
|
|
11
|
-
const exceptions_1 = require("@directus/shared/exceptions");
|
|
12
14
|
const exceptions_2 = require("../exceptions");
|
|
13
15
|
const record_not_unique_1 = require("../exceptions/database/record-not-unique");
|
|
14
16
|
const is_url_allowed_1 = __importDefault(require("../utils/is-url-allowed"));
|
|
15
|
-
const
|
|
17
|
+
const stall_1 = require("../utils/stall");
|
|
16
18
|
const url_1 = require("../utils/url");
|
|
17
19
|
const items_1 = require("./items");
|
|
18
20
|
const mail_1 = require("./mail");
|
|
19
21
|
const settings_1 = require("./settings");
|
|
20
|
-
const stall_1 = require("../utils/stall");
|
|
21
|
-
const perf_hooks_1 = require("perf_hooks");
|
|
22
|
-
const utils_2 = require("@directus/shared/utils");
|
|
23
22
|
class UsersService extends items_1.ItemsService {
|
|
23
|
+
knex;
|
|
24
|
+
accountability;
|
|
25
|
+
schema;
|
|
24
26
|
constructor(options) {
|
|
25
27
|
super('directus_users', options);
|
|
26
28
|
this.knex = options.knex || (0, database_1.default)();
|
|
@@ -96,7 +98,7 @@ class UsersService extends items_1.ItemsService {
|
|
|
96
98
|
.andWhere({ 'directus_roles.admin_access': true })
|
|
97
99
|
.leftJoin('directus_roles', 'directus_users.role', 'directus_roles.id')
|
|
98
100
|
.first();
|
|
99
|
-
const otherAdminUsersCount = +(
|
|
101
|
+
const otherAdminUsersCount = +(otherAdminUsers?.count || 0);
|
|
100
102
|
if (otherAdminUsersCount === 0) {
|
|
101
103
|
throw new exceptions_2.UnprocessableEntityException(`You can't remove the last admin user from the role.`);
|
|
102
104
|
}
|
|
@@ -113,7 +115,7 @@ class UsersService extends items_1.ItemsService {
|
|
|
113
115
|
.andWhere({ 'directus_users.status': 'active' })
|
|
114
116
|
.leftJoin('directus_roles', 'directus_users.role', 'directus_roles.id')
|
|
115
117
|
.first();
|
|
116
|
-
const otherAdminUsersCount = +(
|
|
118
|
+
const otherAdminUsersCount = +(otherAdminUsers?.count || 0);
|
|
117
119
|
if (otherAdminUsersCount === 0) {
|
|
118
120
|
throw new exceptions_2.UnprocessableEntityException(`You can't change the active status of the last admin user.`);
|
|
119
121
|
}
|
|
@@ -179,13 +181,12 @@ class UsersService extends items_1.ItemsService {
|
|
|
179
181
|
* Update many users by primary key
|
|
180
182
|
*/
|
|
181
183
|
async updateMany(keys, data, opts) {
|
|
182
|
-
var _a, _b;
|
|
183
184
|
try {
|
|
184
185
|
if (data.role) {
|
|
185
186
|
// data.role will be an object with id with GraphQL mutations
|
|
186
|
-
const roleId =
|
|
187
|
+
const roleId = data.role?.id ?? data.role;
|
|
187
188
|
const newRole = await this.knex.select('admin_access').from('directus_roles').where('id', roleId).first();
|
|
188
|
-
if (!
|
|
189
|
+
if (!newRole?.admin_access) {
|
|
189
190
|
await this.checkRemainingAdminExistence(keys);
|
|
190
191
|
}
|
|
191
192
|
}
|
|
@@ -280,7 +281,7 @@ class UsersService extends items_1.ItemsService {
|
|
|
280
281
|
for (const email of emails) {
|
|
281
282
|
const payload = { email, scope: 'invite' };
|
|
282
283
|
const token = jsonwebtoken_1.default.sign(payload, env_1.default.SECRET, { expiresIn: '7d', issuer: 'directus' });
|
|
283
|
-
const subjectLine = subject
|
|
284
|
+
const subjectLine = subject ?? "You've been invited";
|
|
284
285
|
const inviteURL = url ? new url_1.Url(url) : new url_1.Url(env_1.default.PUBLIC_URL).addPath('admin', 'accept-invite');
|
|
285
286
|
inviteURL.setQuery('token', token);
|
|
286
287
|
// Create user first to verify uniqueness
|
|
@@ -303,7 +304,7 @@ class UsersService extends items_1.ItemsService {
|
|
|
303
304
|
if (scope !== 'invite')
|
|
304
305
|
throw new exceptions_2.ForbiddenException();
|
|
305
306
|
const user = await this.knex.select('id', 'status').from('directus_users').where({ email }).first();
|
|
306
|
-
if (
|
|
307
|
+
if (user?.status !== 'invited') {
|
|
307
308
|
throw new exceptions_2.InvalidPayloadException(`Email address ${email} hasn't been invited.`);
|
|
308
309
|
}
|
|
309
310
|
// Allow unauthenticated update
|
|
@@ -321,7 +322,7 @@ class UsersService extends items_1.ItemsService {
|
|
|
321
322
|
.from('directus_users')
|
|
322
323
|
.whereRaw('LOWER(??) = ?', ['email', email.toLowerCase()])
|
|
323
324
|
.first();
|
|
324
|
-
if (
|
|
325
|
+
if (user?.status !== 'active') {
|
|
325
326
|
await (0, stall_1.stall)(STALL_TIME, timeStart);
|
|
326
327
|
throw new exceptions_2.ForbiddenException();
|
|
327
328
|
}
|
|
@@ -333,7 +334,7 @@ class UsersService extends items_1.ItemsService {
|
|
|
333
334
|
knex: this.knex,
|
|
334
335
|
accountability: this.accountability,
|
|
335
336
|
});
|
|
336
|
-
const payload = { email, scope: 'password-reset', hash: (0,
|
|
337
|
+
const payload = { email, scope: 'password-reset', hash: (0, utils_1.getSimpleHash)('' + user.password) };
|
|
337
338
|
const token = jsonwebtoken_1.default.sign(payload, env_1.default.SECRET, { expiresIn: '1d', issuer: 'directus' });
|
|
338
339
|
const acceptURL = url
|
|
339
340
|
? new url_1.Url(url).setQuery('token', token).toString()
|
|
@@ -353,7 +354,6 @@ class UsersService extends items_1.ItemsService {
|
|
|
353
354
|
await (0, stall_1.stall)(STALL_TIME, timeStart);
|
|
354
355
|
}
|
|
355
356
|
async resetPassword(token, password) {
|
|
356
|
-
var _a;
|
|
357
357
|
const { email, scope, hash } = jsonwebtoken_1.default.verify(token, env_1.default.SECRET, { issuer: 'directus' });
|
|
358
358
|
if (scope !== 'password-reset' || !hash)
|
|
359
359
|
throw new exceptions_2.ForbiddenException();
|
|
@@ -365,7 +365,7 @@ class UsersService extends items_1.ItemsService {
|
|
|
365
365
|
opts.preMutationException = err;
|
|
366
366
|
}
|
|
367
367
|
const user = await this.knex.select('id', 'status', 'password').from('directus_users').where({ email }).first();
|
|
368
|
-
if (
|
|
368
|
+
if (user?.status !== 'active' || hash !== (0, utils_1.getSimpleHash)('' + user.password)) {
|
|
369
369
|
throw new exceptions_2.ForbiddenException();
|
|
370
370
|
}
|
|
371
371
|
// Allow unauthenticated update
|
|
@@ -373,7 +373,7 @@ class UsersService extends items_1.ItemsService {
|
|
|
373
373
|
knex: this.knex,
|
|
374
374
|
schema: this.schema,
|
|
375
375
|
accountability: {
|
|
376
|
-
...(
|
|
376
|
+
...(this.accountability ?? { role: null }),
|
|
377
377
|
admin: true, // We need to skip permissions checks for the update call below
|
|
378
378
|
},
|
|
379
379
|
});
|
package/dist/services/utils.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import type { Accountability, SchemaOverview } from '@directus/shared/types';
|
|
2
|
+
import type { Knex } from 'knex';
|
|
3
|
+
import type { AbstractServiceOptions, PrimaryKey } from '../types';
|
|
4
4
|
export declare class UtilsService {
|
|
5
5
|
knex: Knex;
|
|
6
6
|
accountability: Accountability | null;
|
package/dist/services/utils.js
CHANGED
|
@@ -6,30 +6,32 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.UtilsService = void 0;
|
|
7
7
|
const database_1 = __importDefault(require("../database"));
|
|
8
8
|
const collections_1 = require("../database/system-data/collections");
|
|
9
|
-
const exceptions_1 = require("../exceptions");
|
|
10
9
|
const emitter_1 = __importDefault(require("../emitter"));
|
|
10
|
+
const exceptions_1 = require("../exceptions");
|
|
11
11
|
class UtilsService {
|
|
12
|
+
knex;
|
|
13
|
+
accountability;
|
|
14
|
+
schema;
|
|
12
15
|
constructor(options) {
|
|
13
16
|
this.knex = options.knex || (0, database_1.default)();
|
|
14
17
|
this.accountability = options.accountability || null;
|
|
15
18
|
this.schema = options.schema;
|
|
16
19
|
}
|
|
17
20
|
async sort(collection, { item, to }) {
|
|
18
|
-
var _a, _b, _c, _d;
|
|
19
21
|
const sortFieldResponse = (await this.knex.select('sort_field').from('directus_collections').where({ collection }).first()) ||
|
|
20
22
|
collections_1.systemCollectionRows;
|
|
21
|
-
const sortField = sortFieldResponse
|
|
23
|
+
const sortField = sortFieldResponse?.sort_field;
|
|
22
24
|
if (!sortField) {
|
|
23
25
|
throw new exceptions_1.InvalidPayloadException(`Collection "${collection}" doesn't have a sort field.`);
|
|
24
26
|
}
|
|
25
|
-
if (
|
|
26
|
-
const permissions =
|
|
27
|
+
if (this.accountability?.admin !== true) {
|
|
28
|
+
const permissions = this.accountability?.permissions?.find((permission) => {
|
|
27
29
|
return permission.collection === collection && permission.action === 'update';
|
|
28
30
|
});
|
|
29
31
|
if (!permissions) {
|
|
30
32
|
throw new exceptions_1.ForbiddenException();
|
|
31
33
|
}
|
|
32
|
-
const allowedFields =
|
|
34
|
+
const allowedFields = permissions.fields ?? [];
|
|
33
35
|
if (allowedFields[0] !== '*' && allowedFields.includes(sortField) === false) {
|
|
34
36
|
throw new exceptions_1.ForbiddenException();
|
|
35
37
|
}
|
|
@@ -37,7 +39,7 @@ class UtilsService {
|
|
|
37
39
|
const primaryKeyField = this.schema.collections[collection].primary;
|
|
38
40
|
// Make sure all rows have a sort value
|
|
39
41
|
const countResponse = await this.knex.count('* as count').from(collection).whereNull(sortField).first();
|
|
40
|
-
if (
|
|
42
|
+
if (countResponse?.count && +countResponse.count !== 0) {
|
|
41
43
|
const lastSortValueResponse = await this.knex.max(sortField).from(collection).first();
|
|
42
44
|
const rowsWithoutSortValue = await this.knex
|
|
43
45
|
.select(primaryKeyField, sortField)
|
|
@@ -59,7 +61,7 @@ class UtilsService {
|
|
|
59
61
|
.groupBy(sortField)
|
|
60
62
|
.from(collection)
|
|
61
63
|
.havingRaw('count(??) > 1', [sortField]);
|
|
62
|
-
if (
|
|
64
|
+
if (duplicates?.length > 0) {
|
|
63
65
|
const ids = await this.knex.select(primaryKeyField).from(collection).orderBy(sortField);
|
|
64
66
|
// This might not scale that well, but I don't really know how to accurately set all rows
|
|
65
67
|
// to a sequential value that works cross-DB vendor otherwise
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { AbstractServiceOptions, Item, PrimaryKey, Webhook, MutationOptions } from '../types';
|
|
2
|
-
import { ItemsService } from './items';
|
|
3
1
|
import { Messenger } from '../messenger';
|
|
2
|
+
import type { AbstractServiceOptions, Item, MutationOptions, PrimaryKey, Webhook } from '../types';
|
|
3
|
+
import { ItemsService } from './items';
|
|
4
4
|
export declare class WebhooksService extends ItemsService<Webhook> {
|
|
5
5
|
messenger: Messenger;
|
|
6
6
|
constructor(options: AbstractServiceOptions);
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.WebhooksService = void 0;
|
|
4
|
-
const items_1 = require("./items");
|
|
5
4
|
const messenger_1 = require("../messenger");
|
|
5
|
+
const items_1 = require("./items");
|
|
6
6
|
class WebhooksService extends items_1.ItemsService {
|
|
7
|
+
messenger;
|
|
7
8
|
constructor(options) {
|
|
8
9
|
super('directus_webhooks', options);
|
|
9
10
|
this.messenger = (0, messenger_1.getMessenger)();
|