@directus/api 20.0.0-rc.1 → 20.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app.js +9 -4
- package/dist/auth/drivers/ldap.js +4 -4
- package/dist/auth/drivers/local.js +4 -4
- package/dist/auth/drivers/oauth2.js +4 -4
- package/dist/auth/drivers/openid.js +4 -2
- package/dist/cache.js +0 -3
- package/dist/cli/commands/bootstrap/index.js +3 -8
- package/dist/cli/commands/init/index.js +10 -9
- package/dist/cli/utils/defaults.d.ts +11 -4
- package/dist/cli/utils/defaults.js +1 -7
- package/dist/constants.d.ts +9 -1
- package/dist/constants.js +10 -0
- package/dist/controllers/auth.js +16 -5
- package/dist/controllers/permissions.js +2 -14
- package/dist/controllers/roles.js +1 -22
- package/dist/controllers/{access.d.ts → tus.d.ts} +1 -0
- package/dist/controllers/tus.js +72 -0
- package/dist/controllers/users.js +55 -0
- package/dist/database/helpers/fn/types.d.ts +1 -2
- package/dist/database/helpers/fn/types.js +1 -1
- package/dist/database/helpers/geometry/dialects/mssql.d.ts +1 -1
- package/dist/database/helpers/geometry/dialects/mssql.js +2 -4
- package/dist/database/helpers/geometry/dialects/mysql.js +1 -1
- package/dist/database/helpers/geometry/dialects/oracle.d.ts +1 -1
- package/dist/database/helpers/geometry/dialects/oracle.js +3 -5
- package/dist/database/helpers/geometry/types.d.ts +1 -1
- package/dist/database/helpers/geometry/types.js +2 -4
- package/dist/database/index.js +1 -2
- package/dist/database/migrations/20240701A-add-tus-data.js +12 -0
- package/dist/database/{run-ast/types.d.ts → run-ast.d.ts} +9 -3
- package/dist/database/run-ast.js +458 -0
- package/dist/flows.js +4 -3
- package/dist/middleware/authenticate.js +7 -2
- package/dist/middleware/cache.js +1 -1
- package/dist/middleware/check-ip.d.ts +2 -0
- package/dist/middleware/check-ip.js +37 -0
- package/dist/middleware/get-permissions.d.ts +3 -0
- package/dist/middleware/get-permissions.js +10 -0
- package/dist/middleware/respond.js +1 -1
- package/dist/services/activity.js +10 -22
- package/dist/services/assets.d.ts +3 -2
- package/dist/services/assets.js +5 -10
- package/dist/services/authentication.js +26 -32
- package/dist/services/authorization.d.ts +17 -0
- package/dist/services/authorization.js +456 -0
- package/dist/services/collections.js +17 -18
- package/dist/services/fields.d.ts +1 -0
- package/dist/services/fields.js +24 -53
- package/dist/services/files/lib/extract-metadata.d.ts +3 -0
- package/dist/services/files/lib/extract-metadata.js +32 -0
- package/dist/services/files/utils/get-metadata.d.ts +5 -0
- package/dist/services/files/utils/get-metadata.js +107 -0
- package/dist/services/files.d.ts +4 -6
- package/dist/services/files.js +27 -140
- package/dist/services/graphql/index.d.ts +3 -3
- package/dist/services/graphql/index.js +22 -126
- package/dist/services/graphql/subscription.js +4 -2
- package/dist/services/import-export.js +4 -18
- package/dist/services/index.d.ts +2 -3
- package/dist/services/index.js +2 -3
- package/dist/services/items.d.ts +3 -3
- package/dist/services/items.js +44 -115
- package/dist/services/meta.js +23 -60
- package/dist/services/payload.d.ts +10 -9
- package/dist/services/payload.js +3 -18
- package/dist/services/{permissions.d.ts → permissions/index.d.ts} +7 -5
- package/dist/services/{permissions.js → permissions/index.js} +54 -30
- package/dist/{permissions → services/permissions}/lib/with-app-minimal-permissions.d.ts +1 -1
- package/dist/services/permissions/lib/with-app-minimal-permissions.js +13 -0
- package/dist/services/relations.d.ts +6 -0
- package/dist/services/relations.js +29 -26
- package/dist/services/roles.d.ts +12 -4
- package/dist/services/roles.js +424 -57
- package/dist/services/server.js +6 -0
- package/dist/services/shares.d.ts +2 -0
- package/dist/services/shares.js +8 -12
- package/dist/services/specifications.d.ts +2 -2
- package/dist/services/specifications.js +27 -39
- package/dist/services/tus/data-store.d.ts +36 -0
- package/dist/services/tus/data-store.js +216 -0
- package/dist/services/tus/index.d.ts +2 -0
- package/dist/services/tus/index.js +2 -0
- package/dist/services/tus/lockers.d.ts +36 -0
- package/dist/services/tus/lockers.js +83 -0
- package/dist/services/tus/server.d.ts +8 -0
- package/dist/services/tus/server.js +80 -0
- package/dist/services/tus/utils/wait-timeout.d.ts +1 -0
- package/dist/services/tus/utils/wait-timeout.js +13 -0
- package/dist/services/users.d.ts +5 -1
- package/dist/services/users.js +161 -78
- package/dist/services/utils.js +7 -11
- package/dist/services/versions.d.ts +2 -0
- package/dist/services/versions.js +10 -34
- package/dist/storage/register-locations.js +5 -1
- package/dist/telemetry/lib/get-report.js +2 -2
- package/dist/telemetry/utils/check-increased-user-limits.d.ts +7 -0
- package/dist/telemetry/utils/check-increased-user-limits.js +25 -0
- package/dist/telemetry/utils/get-role-counts-by-roles.d.ts +6 -0
- package/dist/telemetry/utils/get-role-counts-by-roles.js +27 -0
- package/dist/telemetry/utils/get-role-counts-by-users.d.ts +11 -0
- package/dist/telemetry/utils/get-role-counts-by-users.js +34 -0
- package/dist/telemetry/utils/get-user-count.d.ts +8 -0
- package/dist/telemetry/utils/get-user-count.js +33 -0
- package/dist/telemetry/utils/get-user-counts-by-roles.d.ts +7 -0
- package/dist/telemetry/utils/get-user-counts-by-roles.js +35 -0
- package/dist/types/ast.d.ts +1 -43
- package/dist/types/items.d.ts +0 -11
- package/dist/utils/apply-query.d.ts +3 -4
- package/dist/utils/apply-query.js +8 -37
- package/dist/utils/get-accountability-for-role.js +25 -16
- package/dist/utils/get-accountability-for-token.js +16 -17
- package/dist/utils/get-ast-from-query.d.ts +13 -0
- package/dist/utils/get-ast-from-query.js +297 -0
- package/dist/utils/get-cache-key.d.ts +1 -1
- package/dist/utils/get-cache-key.js +1 -12
- package/dist/utils/get-column.d.ts +1 -2
- package/dist/utils/get-column.js +0 -1
- package/dist/utils/get-permissions.d.ts +2 -0
- package/dist/utils/get-permissions.js +150 -0
- package/dist/utils/get-service.js +1 -5
- package/dist/utils/merge-permissions-for-share.d.ts +4 -0
- package/dist/utils/merge-permissions-for-share.js +109 -0
- package/dist/utils/merge-permissions.d.ts +3 -0
- package/dist/utils/merge-permissions.js +95 -0
- package/dist/utils/reduce-schema.d.ts +6 -4
- package/dist/utils/reduce-schema.js +34 -14
- package/dist/utils/verify-session-jwt.js +2 -1
- package/dist/websocket/authenticate.d.ts +2 -0
- package/dist/websocket/authenticate.js +12 -0
- package/dist/websocket/controllers/base.d.ts +1 -1
- package/dist/websocket/controllers/base.js +20 -16
- package/dist/websocket/controllers/graphql.js +4 -1
- package/dist/websocket/controllers/hooks.js +0 -4
- package/dist/websocket/controllers/rest.js +2 -0
- package/dist/websocket/handlers/subscribe.js +2 -0
- package/dist/websocket/utils/items.d.ts +1 -1
- package/package.json +39 -37
- package/dist/controllers/access.js +0 -148
- package/dist/controllers/policies.d.ts +0 -2
- package/dist/controllers/policies.js +0 -169
- package/dist/database/get-ast-from-query/get-ast-from-query.d.ts +0 -16
- package/dist/database/get-ast-from-query/get-ast-from-query.js +0 -82
- package/dist/database/get-ast-from-query/lib/convert-wildcards.d.ts +0 -13
- package/dist/database/get-ast-from-query/lib/convert-wildcards.js +0 -69
- package/dist/database/get-ast-from-query/lib/parse-fields.d.ts +0 -15
- package/dist/database/get-ast-from-query/lib/parse-fields.js +0 -190
- package/dist/database/get-ast-from-query/utils/get-deep-query.d.ts +0 -14
- package/dist/database/get-ast-from-query/utils/get-deep-query.js +0 -17
- package/dist/database/get-ast-from-query/utils/get-related-collection.d.ts +0 -2
- package/dist/database/get-ast-from-query/utils/get-related-collection.js +0 -13
- package/dist/database/get-ast-from-query/utils/get-relation.d.ts +0 -2
- package/dist/database/get-ast-from-query/utils/get-relation.js +0 -7
- package/dist/database/migrations/20240619A-permissions-policies.js +0 -164
- package/dist/database/run-ast/lib/get-db-query.d.ts +0 -4
- package/dist/database/run-ast/lib/get-db-query.js +0 -194
- package/dist/database/run-ast/lib/parse-current-level.d.ts +0 -7
- package/dist/database/run-ast/lib/parse-current-level.js +0 -41
- package/dist/database/run-ast/run-ast.d.ts +0 -7
- package/dist/database/run-ast/run-ast.js +0 -107
- package/dist/database/run-ast/types.js +0 -1
- package/dist/database/run-ast/utils/apply-case-when.d.ts +0 -16
- package/dist/database/run-ast/utils/apply-case-when.js +0 -26
- package/dist/database/run-ast/utils/apply-parent-filters.d.ts +0 -3
- package/dist/database/run-ast/utils/apply-parent-filters.js +0 -55
- package/dist/database/run-ast/utils/get-column-pre-processor.d.ts +0 -10
- package/dist/database/run-ast/utils/get-column-pre-processor.js +0 -57
- package/dist/database/run-ast/utils/get-field-alias.d.ts +0 -2
- package/dist/database/run-ast/utils/get-field-alias.js +0 -4
- package/dist/database/run-ast/utils/get-inner-query-column-pre-processor.d.ts +0 -5
- package/dist/database/run-ast/utils/get-inner-query-column-pre-processor.js +0 -23
- package/dist/database/run-ast/utils/merge-with-parent-items.d.ts +0 -3
- package/dist/database/run-ast/utils/merge-with-parent-items.js +0 -87
- package/dist/database/run-ast/utils/remove-temporary-fields.d.ts +0 -3
- package/dist/database/run-ast/utils/remove-temporary-fields.js +0 -73
- package/dist/permissions/cache.d.ts +0 -2
- package/dist/permissions/cache.js +0 -23
- package/dist/permissions/lib/fetch-permissions.d.ts +0 -10
- package/dist/permissions/lib/fetch-permissions.js +0 -55
- package/dist/permissions/lib/fetch-policies.d.ts +0 -7
- package/dist/permissions/lib/fetch-policies.js +0 -28
- package/dist/permissions/lib/fetch-roles-tree.d.ts +0 -3
- package/dist/permissions/lib/fetch-roles-tree.js +0 -28
- package/dist/permissions/lib/with-app-minimal-permissions.js +0 -10
- package/dist/permissions/modules/fetch-accountability-collection-access/fetch-accountability-collection-access.d.ts +0 -7
- package/dist/permissions/modules/fetch-accountability-collection-access/fetch-accountability-collection-access.js +0 -56
- package/dist/permissions/modules/fetch-accountability-policy-globals/fetch-accountability-policy-globals.d.ts +0 -3
- package/dist/permissions/modules/fetch-accountability-policy-globals/fetch-accountability-policy-globals.js +0 -16
- package/dist/permissions/modules/fetch-allowed-collections/fetch-allowed-collections.d.ts +0 -8
- package/dist/permissions/modules/fetch-allowed-collections/fetch-allowed-collections.js +0 -24
- package/dist/permissions/modules/fetch-allowed-field-map/fetch-allowed-field-map.d.ts +0 -9
- package/dist/permissions/modules/fetch-allowed-field-map/fetch-allowed-field-map.js +0 -31
- package/dist/permissions/modules/fetch-allowed-fields/fetch-allowed-fields.d.ts +0 -16
- package/dist/permissions/modules/fetch-allowed-fields/fetch-allowed-fields.js +0 -27
- package/dist/permissions/modules/fetch-global-access/fetch-global-access.d.ts +0 -10
- package/dist/permissions/modules/fetch-global-access/fetch-global-access.js +0 -23
- package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-roles.d.ts +0 -5
- package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-roles.js +0 -7
- package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-user.d.ts +0 -5
- package/dist/permissions/modules/fetch-global-access/lib/fetch-global-access-for-user.js +0 -10
- package/dist/permissions/modules/fetch-global-access/types.d.ts +0 -4
- package/dist/permissions/modules/fetch-global-access/types.js +0 -1
- package/dist/permissions/modules/fetch-global-access/utils/fetch-global-access-for-query.d.ts +0 -4
- package/dist/permissions/modules/fetch-global-access/utils/fetch-global-access-for-query.js +0 -27
- package/dist/permissions/modules/fetch-inconsistent-field-map/fetch-inconsistent-field-map.d.ts +0 -12
- package/dist/permissions/modules/fetch-inconsistent-field-map/fetch-inconsistent-field-map.js +0 -32
- package/dist/permissions/modules/fetch-policies-ip-access/fetch-policies-ip-access.d.ts +0 -4
- package/dist/permissions/modules/fetch-policies-ip-access/fetch-policies-ip-access.js +0 -29
- package/dist/permissions/modules/process-ast/lib/extract-fields-from-children.d.ts +0 -4
- package/dist/permissions/modules/process-ast/lib/extract-fields-from-children.js +0 -49
- package/dist/permissions/modules/process-ast/lib/extract-fields-from-query.d.ts +0 -3
- package/dist/permissions/modules/process-ast/lib/extract-fields-from-query.js +0 -56
- package/dist/permissions/modules/process-ast/lib/field-map-from-ast.d.ts +0 -4
- package/dist/permissions/modules/process-ast/lib/field-map-from-ast.js +0 -8
- package/dist/permissions/modules/process-ast/lib/inject-cases.d.ts +0 -9
- package/dist/permissions/modules/process-ast/lib/inject-cases.js +0 -93
- package/dist/permissions/modules/process-ast/process-ast.d.ts +0 -9
- package/dist/permissions/modules/process-ast/process-ast.js +0 -39
- package/dist/permissions/modules/process-ast/types.d.ts +0 -24
- package/dist/permissions/modules/process-ast/types.js +0 -1
- package/dist/permissions/modules/process-ast/utils/collections-in-field-map.d.ts +0 -2
- package/dist/permissions/modules/process-ast/utils/collections-in-field-map.js +0 -7
- package/dist/permissions/modules/process-ast/utils/dedupe-access.d.ts +0 -12
- package/dist/permissions/modules/process-ast/utils/dedupe-access.js +0 -30
- package/dist/permissions/modules/process-ast/utils/extract-paths-from-query.d.ts +0 -15
- package/dist/permissions/modules/process-ast/utils/extract-paths-from-query.js +0 -50
- package/dist/permissions/modules/process-ast/utils/find-related-collection.d.ts +0 -3
- package/dist/permissions/modules/process-ast/utils/find-related-collection.js +0 -9
- package/dist/permissions/modules/process-ast/utils/flatten-filter.d.ts +0 -3
- package/dist/permissions/modules/process-ast/utils/flatten-filter.js +0 -24
- package/dist/permissions/modules/process-ast/utils/format-a2o-key.d.ts +0 -1
- package/dist/permissions/modules/process-ast/utils/format-a2o-key.js +0 -3
- package/dist/permissions/modules/process-ast/utils/get-info-for-path.d.ts +0 -5
- package/dist/permissions/modules/process-ast/utils/get-info-for-path.js +0 -7
- package/dist/permissions/modules/process-ast/utils/has-item-permissions.d.ts +0 -2
- package/dist/permissions/modules/process-ast/utils/has-item-permissions.js +0 -3
- package/dist/permissions/modules/process-ast/utils/stringify-query-path.d.ts +0 -2
- package/dist/permissions/modules/process-ast/utils/stringify-query-path.js +0 -3
- package/dist/permissions/modules/process-ast/utils/validate-path/create-error.d.ts +0 -3
- package/dist/permissions/modules/process-ast/utils/validate-path/create-error.js +0 -16
- package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-existence.d.ts +0 -2
- package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-existence.js +0 -12
- package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-permissions.d.ts +0 -2
- package/dist/permissions/modules/process-ast/utils/validate-path/validate-path-permissions.js +0 -28
- package/dist/permissions/modules/process-payload/lib/is-field-nullable.d.ts +0 -5
- package/dist/permissions/modules/process-payload/lib/is-field-nullable.js +0 -12
- package/dist/permissions/modules/process-payload/process-payload.d.ts +0 -13
- package/dist/permissions/modules/process-payload/process-payload.js +0 -77
- package/dist/permissions/modules/validate-access/lib/validate-collection-access.d.ts +0 -12
- package/dist/permissions/modules/validate-access/lib/validate-collection-access.js +0 -11
- package/dist/permissions/modules/validate-access/lib/validate-item-access.d.ts +0 -9
- package/dist/permissions/modules/validate-access/lib/validate-item-access.js +0 -33
- package/dist/permissions/modules/validate-access/validate-access.d.ts +0 -14
- package/dist/permissions/modules/validate-access/validate-access.js +0 -28
- package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-count.d.ts +0 -1
- package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-count.js +0 -8
- package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-users.d.ts +0 -5
- package/dist/permissions/modules/validate-remaining-admin/validate-remaining-admin-users.js +0 -10
- package/dist/permissions/types.d.ts +0 -6
- package/dist/permissions/types.js +0 -1
- package/dist/permissions/utils/create-default-accountability.d.ts +0 -2
- package/dist/permissions/utils/create-default-accountability.js +0 -11
- package/dist/permissions/utils/extract-required-dynamic-variable-context.d.ts +0 -8
- package/dist/permissions/utils/extract-required-dynamic-variable-context.js +0 -27
- package/dist/permissions/utils/fetch-dynamic-variable-context.d.ts +0 -9
- package/dist/permissions/utils/fetch-dynamic-variable-context.js +0 -43
- package/dist/permissions/utils/filter-policies-by-ip.d.ts +0 -2
- package/dist/permissions/utils/filter-policies-by-ip.js +0 -15
- package/dist/permissions/utils/get-unaliased-field-key.d.ts +0 -5
- package/dist/permissions/utils/get-unaliased-field-key.js +0 -17
- package/dist/permissions/utils/process-permissions.d.ts +0 -7
- package/dist/permissions/utils/process-permissions.js +0 -9
- package/dist/permissions/utils/with-cache.d.ts +0 -10
- package/dist/permissions/utils/with-cache.js +0 -25
- package/dist/services/access.d.ts +0 -10
- package/dist/services/access.js +0 -43
- package/dist/services/policies.d.ts +0 -12
- package/dist/services/policies.js +0 -87
- package/dist/telemetry/utils/check-user-limits.d.ts +0 -5
- package/dist/telemetry/utils/check-user-limits.js +0 -19
- package/dist/utils/fetch-user-count/fetch-access-lookup.d.ts +0 -17
- package/dist/utils/fetch-user-count/fetch-access-lookup.js +0 -22
- package/dist/utils/fetch-user-count/fetch-access-roles.d.ts +0 -16
- package/dist/utils/fetch-user-count/fetch-access-roles.js +0 -37
- package/dist/utils/fetch-user-count/fetch-active-users.d.ts +0 -6
- package/dist/utils/fetch-user-count/fetch-active-users.js +0 -3
- package/dist/utils/fetch-user-count/fetch-user-count.d.ts +0 -12
- package/dist/utils/fetch-user-count/fetch-user-count.js +0 -57
- package/dist/utils/fetch-user-count/get-user-count-query.d.ts +0 -20
- package/dist/utils/fetch-user-count/get-user-count-query.js +0 -17
- package/dist/utils/validate-user-count-integrity.d.ts +0 -13
- package/dist/utils/validate-user-count-integrity.js +0 -29
- /package/dist/database/migrations/{20240619A-permissions-policies.d.ts → 20240701A-add-tus-data.d.ts} +0 -0
- /package/dist/{utils → services/files/utils}/parse-image-metadata.d.ts +0 -0
- /package/dist/{utils → services/files/utils}/parse-image-metadata.js +0 -0
package/dist/services/roles.js
CHANGED
|
@@ -1,51 +1,441 @@
|
|
|
1
|
-
import { InvalidPayloadError } from '@directus/errors';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { InvalidPayloadError, UnprocessableContentError } from '@directus/errors';
|
|
2
|
+
import { getMatch } from 'ip-matching';
|
|
3
|
+
import { omit } from 'lodash-es';
|
|
4
|
+
import { checkIncreasedUserLimits } from '../telemetry/utils/check-increased-user-limits.js';
|
|
5
|
+
import { getRoleCountsByUsers } from '../telemetry/utils/get-role-counts-by-users.js';
|
|
6
|
+
import {} from '../telemetry/utils/get-user-count.js';
|
|
7
|
+
import { getUserCountsByRoles } from '../telemetry/utils/get-user-counts-by-roles.js';
|
|
8
|
+
import { shouldCheckUserLimits } from '../telemetry/utils/should-check-user-limits.js';
|
|
9
|
+
import { shouldClearCache } from '../utils/should-clear-cache.js';
|
|
4
10
|
import { transaction } from '../utils/transaction.js';
|
|
5
|
-
import { UserIntegrityCheckFlag } from '../utils/validate-user-count-integrity.js';
|
|
6
11
|
import { ItemsService } from './items.js';
|
|
7
|
-
import {
|
|
12
|
+
import { PermissionsService } from './permissions/index.js';
|
|
8
13
|
import { PresetsService } from './presets.js';
|
|
9
14
|
import { UsersService } from './users.js';
|
|
10
15
|
export class RolesService extends ItemsService {
|
|
11
16
|
constructor(options) {
|
|
12
17
|
super('directus_roles', options);
|
|
13
18
|
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
19
|
+
async checkForOtherAdminRoles(excludeKeys) {
|
|
20
|
+
// Make sure there's at least one admin role left after this deletion is done
|
|
21
|
+
const otherAdminRoles = await this.knex
|
|
22
|
+
.count('*', { as: 'count' })
|
|
23
|
+
.from('directus_roles')
|
|
24
|
+
.whereNotIn('id', excludeKeys)
|
|
25
|
+
.andWhere({ admin_access: true })
|
|
26
|
+
.first();
|
|
27
|
+
const otherAdminRolesCount = Number(otherAdminRoles?.count ?? 0);
|
|
28
|
+
if (otherAdminRolesCount === 0) {
|
|
29
|
+
throw new UnprocessableContentError({ reason: `You can't delete the last admin role` });
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
async checkForOtherAdminUsers(key, users) {
|
|
33
|
+
const role = await this.knex.select('admin_access').from('directus_roles').where('id', '=', key).first();
|
|
34
|
+
// No-op if role doesn't exist
|
|
35
|
+
if (!role)
|
|
36
|
+
return;
|
|
37
|
+
const usersBefore = (await this.knex.select('id').from('directus_users').where('role', '=', key)).map((user) => user.id);
|
|
38
|
+
const usersAdded = [];
|
|
39
|
+
const usersUpdated = [];
|
|
40
|
+
const usersCreated = [];
|
|
41
|
+
const usersRemoved = [];
|
|
42
|
+
if (Array.isArray(users)) {
|
|
43
|
+
const usersKept = [];
|
|
44
|
+
for (const user of users) {
|
|
45
|
+
if (typeof user === 'string') {
|
|
46
|
+
if (usersBefore.includes(user)) {
|
|
47
|
+
usersKept.push(user);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
usersAdded.push({ id: user });
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else if (user.id) {
|
|
54
|
+
if (usersBefore.includes(user.id)) {
|
|
55
|
+
usersKept.push(user.id);
|
|
56
|
+
usersUpdated.push(user);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
usersAdded.push(user);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
usersCreated.push(user);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
usersRemoved.push(...usersBefore.filter((user) => !usersKept.includes(user)));
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
for (const user of users.update) {
|
|
70
|
+
if (usersBefore.includes(user['id'])) {
|
|
71
|
+
usersUpdated.push(user);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
usersAdded.push(user);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
usersCreated.push(...users.create);
|
|
78
|
+
usersRemoved.push(...users.delete);
|
|
79
|
+
}
|
|
80
|
+
if (role.admin_access === false || role.admin_access === 0) {
|
|
81
|
+
// Admin users might have moved in from other role, thus becoming non-admin
|
|
82
|
+
if (usersAdded.length > 0) {
|
|
83
|
+
const otherAdminUsers = await this.knex
|
|
84
|
+
.count('*', { as: 'count' })
|
|
85
|
+
.from('directus_users')
|
|
86
|
+
.leftJoin('directus_roles', 'directus_users.role', 'directus_roles.id')
|
|
87
|
+
.whereNotIn('directus_users.id', usersAdded.map((user) => user.id))
|
|
88
|
+
.andWhere({ 'directus_roles.admin_access': true, status: 'active' })
|
|
89
|
+
.first();
|
|
90
|
+
const otherAdminUsersCount = Number(otherAdminUsers?.count ?? 0);
|
|
91
|
+
if (otherAdminUsersCount === 0) {
|
|
92
|
+
throw new UnprocessableContentError({ reason: `You can't remove the last admin user from the admin role` });
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
// Only added or created new users
|
|
98
|
+
if (usersUpdated.length === 0 && usersRemoved.length === 0)
|
|
99
|
+
return;
|
|
100
|
+
// Active admin user(s) about to be created
|
|
101
|
+
if (usersCreated.some((user) => !('status' in user) || user.status === 'active'))
|
|
102
|
+
return;
|
|
103
|
+
const usersDeactivated = [...usersAdded, ...usersUpdated]
|
|
104
|
+
.filter((user) => 'status' in user && user.status !== 'active')
|
|
105
|
+
.map((user) => user.id);
|
|
106
|
+
const usersAddedNonDeactivated = usersAdded
|
|
107
|
+
.filter((user) => !usersDeactivated.includes(user.id))
|
|
108
|
+
.map((user) => user.id);
|
|
109
|
+
// Active user(s) about to become admin
|
|
110
|
+
if (usersAddedNonDeactivated.length > 0) {
|
|
111
|
+
const userCount = await this.knex
|
|
112
|
+
.count('*', { as: 'count' })
|
|
113
|
+
.from('directus_users')
|
|
114
|
+
.whereIn('id', usersAddedNonDeactivated)
|
|
115
|
+
.andWhere({ status: 'active' })
|
|
116
|
+
.first();
|
|
117
|
+
if (Number(userCount?.count ?? 0) > 0) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
const otherAdminUsers = await this.knex
|
|
122
|
+
.count('*', { as: 'count' })
|
|
123
|
+
.from('directus_users')
|
|
124
|
+
.leftJoin('directus_roles', 'directus_users.role', 'directus_roles.id')
|
|
125
|
+
.whereNotIn('directus_users.id', [...usersDeactivated, ...usersRemoved])
|
|
126
|
+
.andWhere({ 'directus_roles.admin_access': true, status: 'active' })
|
|
127
|
+
.first();
|
|
128
|
+
const otherAdminUsersCount = Number(otherAdminUsers?.count ?? 0);
|
|
129
|
+
if (otherAdminUsersCount === 0) {
|
|
130
|
+
throw new UnprocessableContentError({ reason: `You can't remove the last admin user from the admin role` });
|
|
131
|
+
}
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
isIpAccessValid(value) {
|
|
135
|
+
if (value === undefined)
|
|
136
|
+
return false;
|
|
137
|
+
if (value === null)
|
|
138
|
+
return true;
|
|
139
|
+
if (Array.isArray(value) && value.length === 0)
|
|
140
|
+
return true;
|
|
141
|
+
for (const ip of value) {
|
|
142
|
+
if (typeof ip !== 'string' || ip.includes('*'))
|
|
143
|
+
return false;
|
|
144
|
+
try {
|
|
145
|
+
const match = getMatch(ip);
|
|
146
|
+
if (match.type == 'IPMask')
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return true;
|
|
154
|
+
}
|
|
155
|
+
assertValidIpAccess(partialItem) {
|
|
156
|
+
if ('ip_access' in partialItem && !this.isIpAccessValid(partialItem['ip_access'])) {
|
|
157
|
+
throw new InvalidPayloadError({
|
|
158
|
+
reason: 'IP Access contains an incorrect value. Valid values are: IP addresses, IP ranges and CIDR blocks',
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
getRoleAccessType(data) {
|
|
163
|
+
if ('admin_access' in data && data['admin_access'] === true) {
|
|
164
|
+
return 'admin';
|
|
165
|
+
}
|
|
166
|
+
else if (('app_access' in data && data['app_access'] === true) || 'app_access' in data === false) {
|
|
167
|
+
return 'app';
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
return 'api';
|
|
171
|
+
}
|
|
32
172
|
}
|
|
33
|
-
async
|
|
34
|
-
|
|
35
|
-
|
|
173
|
+
async createOne(data, opts) {
|
|
174
|
+
this.assertValidIpAccess(data);
|
|
175
|
+
if (shouldCheckUserLimits()) {
|
|
176
|
+
const increasedCounts = {
|
|
177
|
+
admin: 0,
|
|
178
|
+
app: 0,
|
|
179
|
+
api: 0,
|
|
180
|
+
};
|
|
181
|
+
const existingIds = [];
|
|
182
|
+
if ('users' in data) {
|
|
183
|
+
const type = this.getRoleAccessType(data);
|
|
184
|
+
increasedCounts[type] += data['users'].length;
|
|
185
|
+
for (const user of data['users']) {
|
|
186
|
+
if (typeof user === 'string') {
|
|
187
|
+
existingIds.push(user);
|
|
188
|
+
}
|
|
189
|
+
else if (typeof user === 'object' && 'id' in user) {
|
|
190
|
+
existingIds.push(user['id']);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
await checkIncreasedUserLimits(this.knex, increasedCounts, existingIds);
|
|
195
|
+
}
|
|
196
|
+
return super.createOne(data, opts);
|
|
197
|
+
}
|
|
198
|
+
async createMany(data, opts) {
|
|
199
|
+
const needsUserLimitCheck = shouldCheckUserLimits();
|
|
200
|
+
const increasedCounts = {
|
|
201
|
+
admin: 0,
|
|
202
|
+
app: 0,
|
|
203
|
+
api: 0,
|
|
204
|
+
};
|
|
205
|
+
const existingIds = [];
|
|
206
|
+
for (const partialItem of data) {
|
|
207
|
+
this.assertValidIpAccess(partialItem);
|
|
208
|
+
if (needsUserLimitCheck && 'users' in partialItem) {
|
|
209
|
+
const type = this.getRoleAccessType(partialItem);
|
|
210
|
+
increasedCounts[type] += partialItem['users'].length;
|
|
211
|
+
for (const user of partialItem['users']) {
|
|
212
|
+
if (typeof user === 'string') {
|
|
213
|
+
existingIds.push(user);
|
|
214
|
+
}
|
|
215
|
+
else if (typeof user === 'object' && 'id' in user) {
|
|
216
|
+
existingIds.push(user['id']);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
if (needsUserLimitCheck) {
|
|
222
|
+
await checkIncreasedUserLimits(this.knex, increasedCounts, existingIds);
|
|
223
|
+
}
|
|
224
|
+
return super.createMany(data, opts);
|
|
225
|
+
}
|
|
226
|
+
async updateOne(key, data, opts) {
|
|
227
|
+
this.assertValidIpAccess(data);
|
|
228
|
+
try {
|
|
229
|
+
if ('users' in data) {
|
|
230
|
+
await this.checkForOtherAdminUsers(key, data['users']);
|
|
231
|
+
}
|
|
232
|
+
if (shouldCheckUserLimits()) {
|
|
233
|
+
const increasedCounts = {
|
|
234
|
+
admin: 0,
|
|
235
|
+
app: 0,
|
|
236
|
+
api: 0,
|
|
237
|
+
};
|
|
238
|
+
let increasedUsers = 0;
|
|
239
|
+
const existingIds = [];
|
|
240
|
+
let existingRole = await this.knex
|
|
241
|
+
.count('directus_users.id', { as: 'count' })
|
|
242
|
+
.select('directus_roles.admin_access', 'directus_roles.app_access')
|
|
243
|
+
.from('directus_users')
|
|
244
|
+
.where('directus_roles.id', '=', key)
|
|
245
|
+
.andWhere('directus_users.status', '=', 'active')
|
|
246
|
+
.leftJoin('directus_roles', 'directus_users.role', '=', 'directus_roles.id')
|
|
247
|
+
.groupBy('directus_roles.admin_access', 'directus_roles.app_access')
|
|
248
|
+
.first();
|
|
249
|
+
if (!existingRole) {
|
|
250
|
+
try {
|
|
251
|
+
const role = (await this.knex
|
|
252
|
+
.select('admin_access', 'app_access')
|
|
253
|
+
.from('directus_roles')
|
|
254
|
+
.where('id', '=', key)
|
|
255
|
+
.first()) ?? { admin_access: null, app_access: null };
|
|
256
|
+
existingRole = { count: 0, ...role };
|
|
257
|
+
}
|
|
258
|
+
catch {
|
|
259
|
+
existingRole = { count: 0, admin_access: null, app_access: null };
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
if ('users' in data) {
|
|
263
|
+
const users = data['users'];
|
|
264
|
+
if (Array.isArray(users)) {
|
|
265
|
+
increasedUsers = users.length - Number(existingRole.count);
|
|
266
|
+
for (const user of users) {
|
|
267
|
+
if (typeof user === 'string') {
|
|
268
|
+
existingIds.push(user);
|
|
269
|
+
}
|
|
270
|
+
else if (typeof user === 'object' && 'id' in user) {
|
|
271
|
+
existingIds.push(user['id']);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
increasedUsers += users.create.length;
|
|
277
|
+
increasedUsers -= users.delete.length;
|
|
278
|
+
const userIds = [];
|
|
279
|
+
for (const user of users.update) {
|
|
280
|
+
if ('status' in user) {
|
|
281
|
+
// account for users being activated and deactivated
|
|
282
|
+
if (user['status'] === 'active') {
|
|
283
|
+
increasedUsers++;
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
increasedUsers--;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
userIds.push(user.id);
|
|
290
|
+
}
|
|
291
|
+
try {
|
|
292
|
+
const existingCounts = await getRoleCountsByUsers(this.knex, userIds);
|
|
293
|
+
if (existingRole.admin_access) {
|
|
294
|
+
increasedUsers += existingCounts.app + existingCounts.api;
|
|
295
|
+
}
|
|
296
|
+
else if (existingRole.app_access) {
|
|
297
|
+
increasedUsers += existingCounts.admin + existingCounts.api;
|
|
298
|
+
}
|
|
299
|
+
else {
|
|
300
|
+
increasedUsers += existingCounts.admin + existingCounts.app;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
catch {
|
|
304
|
+
// ignore failed user call
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
let isAccessChanged = false;
|
|
309
|
+
let accessType = 'api';
|
|
310
|
+
if ('app_access' in data) {
|
|
311
|
+
if (data['app_access'] === true) {
|
|
312
|
+
accessType = 'app';
|
|
313
|
+
if (!existingRole.app_access)
|
|
314
|
+
isAccessChanged = true;
|
|
315
|
+
}
|
|
316
|
+
else if (existingRole.app_access) {
|
|
317
|
+
isAccessChanged = true;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
else if (existingRole.app_access) {
|
|
321
|
+
accessType = 'app';
|
|
322
|
+
}
|
|
323
|
+
if ('admin_access' in data) {
|
|
324
|
+
if (data['admin_access'] === true) {
|
|
325
|
+
accessType = 'admin';
|
|
326
|
+
if (!existingRole.admin_access)
|
|
327
|
+
isAccessChanged = true;
|
|
328
|
+
}
|
|
329
|
+
else if (existingRole.admin_access) {
|
|
330
|
+
isAccessChanged = true;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
else if (existingRole.admin_access) {
|
|
334
|
+
accessType = 'admin';
|
|
335
|
+
}
|
|
336
|
+
if (isAccessChanged) {
|
|
337
|
+
increasedCounts[accessType] += Number(existingRole.count);
|
|
338
|
+
}
|
|
339
|
+
increasedCounts[accessType] += increasedUsers;
|
|
340
|
+
await checkIncreasedUserLimits(this.knex, increasedCounts, existingIds);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
catch (err) {
|
|
344
|
+
(opts || (opts = {})).preMutationError = err;
|
|
345
|
+
}
|
|
346
|
+
return super.updateOne(key, data, opts);
|
|
347
|
+
}
|
|
348
|
+
async updateBatch(data, opts = {}) {
|
|
349
|
+
for (const partialItem of data) {
|
|
350
|
+
this.assertValidIpAccess(partialItem);
|
|
351
|
+
}
|
|
352
|
+
const primaryKeyField = this.schema.collections[this.collection].primary;
|
|
353
|
+
if (!opts.mutationTracker) {
|
|
354
|
+
opts.mutationTracker = this.createMutationTracker();
|
|
355
|
+
}
|
|
356
|
+
const keys = [];
|
|
357
|
+
try {
|
|
358
|
+
await transaction(this.knex, async (trx) => {
|
|
359
|
+
const service = new RolesService({
|
|
360
|
+
accountability: this.accountability,
|
|
361
|
+
knex: trx,
|
|
362
|
+
schema: this.schema,
|
|
363
|
+
});
|
|
364
|
+
for (const item of data) {
|
|
365
|
+
const combinedOpts = Object.assign({ autoPurgeCache: false }, opts);
|
|
366
|
+
keys.push(await service.updateOne(item[primaryKeyField], omit(item, primaryKeyField), combinedOpts));
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
finally {
|
|
371
|
+
if (shouldClearCache(this.cache, opts, this.collection)) {
|
|
372
|
+
await this.cache.clear();
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
return keys;
|
|
376
|
+
}
|
|
377
|
+
async updateMany(keys, data, opts) {
|
|
378
|
+
this.assertValidIpAccess(data);
|
|
379
|
+
try {
|
|
380
|
+
if ('admin_access' in data && data['admin_access'] === false) {
|
|
381
|
+
await this.checkForOtherAdminRoles(keys);
|
|
382
|
+
}
|
|
383
|
+
if (shouldCheckUserLimits() && ('admin_access' in data || 'app_access' in data)) {
|
|
384
|
+
const existingCounts = await getUserCountsByRoles(this.knex, keys);
|
|
385
|
+
const increasedCounts = {
|
|
386
|
+
admin: 0,
|
|
387
|
+
app: 0,
|
|
388
|
+
api: 0,
|
|
389
|
+
};
|
|
390
|
+
const type = this.getRoleAccessType(data);
|
|
391
|
+
for (const [existingType, existingCount] of Object.entries(existingCounts)) {
|
|
392
|
+
if (existingType === type)
|
|
393
|
+
continue;
|
|
394
|
+
increasedCounts[type] += existingCount;
|
|
395
|
+
}
|
|
396
|
+
await checkIncreasedUserLimits(this.knex, increasedCounts);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
catch (err) {
|
|
400
|
+
(opts || (opts = {})).preMutationError = err;
|
|
401
|
+
}
|
|
402
|
+
return super.updateMany(keys, data, opts);
|
|
403
|
+
}
|
|
404
|
+
async updateByQuery(query, data, opts) {
|
|
405
|
+
this.assertValidIpAccess(data);
|
|
406
|
+
return super.updateByQuery(query, data, opts);
|
|
407
|
+
}
|
|
408
|
+
async deleteMany(keys) {
|
|
409
|
+
const opts = {};
|
|
410
|
+
try {
|
|
411
|
+
await this.checkForOtherAdminRoles(keys);
|
|
412
|
+
}
|
|
413
|
+
catch (err) {
|
|
414
|
+
opts.preMutationError = err;
|
|
415
|
+
}
|
|
36
416
|
await transaction(this.knex, async (trx) => {
|
|
37
|
-
const
|
|
417
|
+
const itemsService = new ItemsService('directus_roles', {
|
|
38
418
|
knex: trx,
|
|
39
419
|
accountability: this.accountability,
|
|
40
420
|
schema: this.schema,
|
|
41
|
-
};
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
421
|
+
});
|
|
422
|
+
const permissionsService = new PermissionsService({
|
|
423
|
+
knex: trx,
|
|
424
|
+
accountability: this.accountability,
|
|
425
|
+
schema: this.schema,
|
|
426
|
+
});
|
|
427
|
+
const presetsService = new PresetsService({
|
|
428
|
+
knex: trx,
|
|
429
|
+
accountability: this.accountability,
|
|
430
|
+
schema: this.schema,
|
|
431
|
+
});
|
|
432
|
+
const usersService = new UsersService({
|
|
433
|
+
knex: trx,
|
|
434
|
+
accountability: this.accountability,
|
|
435
|
+
schema: this.schema,
|
|
436
|
+
});
|
|
47
437
|
// Delete permissions/presets for this role, suspend all remaining users in role
|
|
48
|
-
await
|
|
438
|
+
await permissionsService.deleteByQuery({
|
|
49
439
|
filter: { role: { _in: keys } },
|
|
50
440
|
}, { ...opts, bypassLimits: true });
|
|
51
441
|
await presetsService.deleteByQuery({
|
|
@@ -57,31 +447,8 @@ export class RolesService extends ItemsService {
|
|
|
57
447
|
status: 'suspended',
|
|
58
448
|
role: null,
|
|
59
449
|
}, { ...opts, bypassLimits: true });
|
|
60
|
-
// If the about to be deleted roles are the parent of other roles set those parents to null
|
|
61
|
-
// Use a newly created RolesService here that works within the current transaction
|
|
62
|
-
await rolesService.updateByQuery({
|
|
63
|
-
filter: { parent: { _in: keys } },
|
|
64
|
-
}, { parent: null });
|
|
65
450
|
await itemsService.deleteMany(keys, opts);
|
|
66
451
|
});
|
|
67
|
-
// Since nested roles could be updated, clear caches
|
|
68
|
-
await this.clearCaches();
|
|
69
452
|
return keys;
|
|
70
453
|
}
|
|
71
|
-
async validateRoleNesting(ids, parent) {
|
|
72
|
-
if (ids.includes(parent)) {
|
|
73
|
-
throw new InvalidPayloadError({ reason: 'A role cannot be a parent of itself' });
|
|
74
|
-
}
|
|
75
|
-
const roles = await fetchRolesTree(parent, this.knex);
|
|
76
|
-
if (ids.some((id) => roles.includes(id))) {
|
|
77
|
-
// The role tree up from the parent already includes this role, so it would create a circular reference
|
|
78
|
-
throw new InvalidPayloadError({ reason: 'A role cannot have a parent that is already a descendant of itself' });
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
async clearCaches(opts) {
|
|
82
|
-
await clearSystemCache({ autoPurgeCache: opts?.autoPurgeCache });
|
|
83
|
-
if (this.cache && opts?.autoPurgeCache !== false) {
|
|
84
|
-
await this.cache.clear();
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
454
|
}
|
package/dist/services/server.js
CHANGED
|
@@ -13,6 +13,7 @@ import { rateLimiter } from '../middleware/rate-limiter-ip.js';
|
|
|
13
13
|
import { SERVER_ONLINE } from '../server.js';
|
|
14
14
|
import { getStorage } from '../storage/index.js';
|
|
15
15
|
import { SettingsService } from './settings.js';
|
|
16
|
+
import { RESUMABLE_UPLOADS } from '../constants.js';
|
|
16
17
|
const env = useEnv();
|
|
17
18
|
const logger = useLogger();
|
|
18
19
|
export class ServerService {
|
|
@@ -98,6 +99,11 @@ export class ServerService {
|
|
|
98
99
|
else {
|
|
99
100
|
info['websocket'] = false;
|
|
100
101
|
}
|
|
102
|
+
if (RESUMABLE_UPLOADS.ENABLED) {
|
|
103
|
+
info['uploads'] = {
|
|
104
|
+
chunkSize: RESUMABLE_UPLOADS.CHUNK_SIZE,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
101
107
|
info['version'] = version;
|
|
102
108
|
}
|
|
103
109
|
return info;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { Item, PrimaryKey } from '@directus/types';
|
|
2
2
|
import type { AbstractServiceOptions, LoginResult, MutationOptions } from '../types/index.js';
|
|
3
|
+
import { AuthorizationService } from './authorization.js';
|
|
3
4
|
import { ItemsService } from './items.js';
|
|
4
5
|
export declare class SharesService extends ItemsService {
|
|
6
|
+
authorizationService: AuthorizationService;
|
|
5
7
|
constructor(options: AbstractServiceOptions);
|
|
6
8
|
createOne(data: Partial<Item>, opts?: MutationOptions): Promise<PrimaryKey>;
|
|
7
9
|
login(payload: Record<string, any>, options?: Partial<{
|
package/dist/services/shares.js
CHANGED
|
@@ -3,33 +3,29 @@ import { ForbiddenError, InvalidCredentialsError } from '@directus/errors';
|
|
|
3
3
|
import argon2 from 'argon2';
|
|
4
4
|
import jwt from 'jsonwebtoken';
|
|
5
5
|
import { useLogger } from '../logger.js';
|
|
6
|
-
import { validateAccess } from '../permissions/modules/validate-access/validate-access.js';
|
|
7
6
|
import { getMilliseconds } from '../utils/get-milliseconds.js';
|
|
8
7
|
import { getSecret } from '../utils/get-secret.js';
|
|
9
8
|
import { md } from '../utils/md.js';
|
|
10
9
|
import { Url } from '../utils/url.js';
|
|
11
10
|
import { userName } from '../utils/user-name.js';
|
|
11
|
+
import { AuthorizationService } from './authorization.js';
|
|
12
12
|
import { ItemsService } from './items.js';
|
|
13
13
|
import { MailService } from './mail/index.js';
|
|
14
14
|
import { UsersService } from './users.js';
|
|
15
15
|
const env = useEnv();
|
|
16
16
|
const logger = useLogger();
|
|
17
17
|
export class SharesService extends ItemsService {
|
|
18
|
+
authorizationService;
|
|
18
19
|
constructor(options) {
|
|
19
20
|
super('directus_shares', options);
|
|
21
|
+
this.authorizationService = new AuthorizationService({
|
|
22
|
+
accountability: this.accountability,
|
|
23
|
+
knex: this.knex,
|
|
24
|
+
schema: this.schema,
|
|
25
|
+
});
|
|
20
26
|
}
|
|
21
27
|
async createOne(data, opts) {
|
|
22
|
-
|
|
23
|
-
await validateAccess({
|
|
24
|
-
accountability: this.accountability,
|
|
25
|
-
action: 'share',
|
|
26
|
-
collection: data['collection'],
|
|
27
|
-
primaryKeys: [data['item']],
|
|
28
|
-
}, {
|
|
29
|
-
schema: this.schema,
|
|
30
|
-
knex: this.knex,
|
|
31
|
-
});
|
|
32
|
-
}
|
|
28
|
+
await this.authorizationService.checkAccess('share', data['collection'], data['item']);
|
|
33
29
|
return super.createOne(data, opts);
|
|
34
30
|
}
|
|
35
31
|
async login(payload, options) {
|
|
@@ -9,7 +9,7 @@ export declare class SpecificationService {
|
|
|
9
9
|
schema: SchemaOverview;
|
|
10
10
|
oas: OASSpecsService;
|
|
11
11
|
graphql: GraphQLSpecsService;
|
|
12
|
-
constructor(
|
|
12
|
+
constructor({ accountability, knex, schema }: AbstractServiceOptions);
|
|
13
13
|
}
|
|
14
14
|
interface SpecificationSubService {
|
|
15
15
|
generate: (_?: any) => Promise<any>;
|
|
@@ -18,7 +18,7 @@ declare class OASSpecsService implements SpecificationSubService {
|
|
|
18
18
|
accountability: Accountability | null;
|
|
19
19
|
knex: Knex;
|
|
20
20
|
schema: SchemaOverview;
|
|
21
|
-
constructor(
|
|
21
|
+
constructor({ knex, schema, accountability }: AbstractServiceOptions);
|
|
22
22
|
generate(host?: string): Promise<OpenAPIObject>;
|
|
23
23
|
private generateTags;
|
|
24
24
|
private generatePaths;
|