@directus/api 11.1.0 → 12.0.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 +3 -4
- package/dist/auth/auth.d.ts +4 -4
- package/dist/auth/auth.js +2 -2
- package/dist/auth/drivers/ldap.js +20 -17
- package/dist/auth/drivers/local.js +5 -5
- package/dist/auth/drivers/oauth2.js +16 -16
- package/dist/auth/drivers/openid.js +18 -17
- package/dist/auth/drivers/saml.js +6 -7
- package/dist/auth.js +3 -2
- package/dist/cache.js +3 -13
- package/dist/cli/utils/create-env/env-stub.liquid +5 -7
- package/dist/controllers/activity.js +7 -6
- package/dist/controllers/assets.js +25 -12
- package/dist/controllers/auth.js +8 -7
- package/dist/controllers/collections.js +4 -3
- package/dist/controllers/dashboards.js +5 -4
- package/dist/controllers/extensions.js +3 -3
- package/dist/controllers/fields.js +9 -8
- package/dist/controllers/files.js +11 -11
- package/dist/controllers/flows.js +5 -4
- package/dist/controllers/folders.js +5 -4
- package/dist/controllers/items.js +14 -13
- package/dist/controllers/not-found.js +2 -2
- package/dist/controllers/notifications.js +5 -4
- package/dist/controllers/operations.js +5 -4
- package/dist/controllers/panels.js +5 -4
- package/dist/controllers/permissions.js +5 -4
- package/dist/controllers/presets.js +5 -4
- package/dist/controllers/relations.js +6 -5
- package/dist/controllers/roles.js +5 -4
- package/dist/controllers/schema.js +8 -8
- package/dist/controllers/server.js +2 -2
- package/dist/controllers/settings.js +3 -2
- package/dist/controllers/shares.js +7 -6
- package/dist/controllers/translations.js +6 -5
- package/dist/controllers/users.js +22 -21
- package/dist/controllers/utils.js +10 -10
- package/dist/controllers/webhooks.js +5 -4
- package/dist/{exceptions/database → database/errors}/dialects/mssql.js +8 -18
- package/dist/{exceptions/database → database/errors}/dialects/mysql.js +9 -19
- package/dist/{exceptions/database → database/errors}/dialects/oracle.js +2 -2
- package/dist/{exceptions/database → database/errors}/dialects/postgres.js +7 -18
- package/dist/{exceptions/database → database/errors}/dialects/sqlite.js +7 -10
- package/dist/{exceptions/database → database/errors}/translate.js +1 -1
- package/dist/database/migrations/run.js +10 -1
- package/dist/env.js +6 -13
- package/dist/errors/codes.d.ts +29 -0
- package/dist/errors/codes.js +30 -0
- package/dist/errors/contains-null-values.d.ts +7 -0
- package/dist/errors/contains-null-values.js +4 -0
- package/dist/errors/content-too-large.d.ts +1 -0
- package/dist/errors/content-too-large.js +3 -0
- package/dist/errors/forbidden.d.ts +1 -0
- package/dist/errors/forbidden.js +3 -0
- package/dist/errors/hit-rate-limit.d.ts +6 -0
- package/dist/errors/hit-rate-limit.js +8 -0
- package/dist/errors/illegal-asset-transformation.d.ts +4 -0
- package/dist/errors/illegal-asset-transformation.js +3 -0
- package/dist/errors/index.d.ts +28 -0
- package/dist/errors/index.js +28 -0
- package/dist/errors/invalid-credentials.d.ts +1 -0
- package/dist/errors/invalid-credentials.js +3 -0
- package/dist/errors/invalid-foreign-key.d.ts +6 -0
- package/dist/errors/invalid-foreign-key.js +14 -0
- package/dist/errors/invalid-ip.d.ts +1 -0
- package/dist/errors/invalid-ip.js +3 -0
- package/dist/errors/invalid-otp.d.ts +1 -0
- package/dist/errors/invalid-otp.js +3 -0
- package/dist/errors/invalid-payload.d.ts +5 -0
- package/dist/errors/invalid-payload.js +4 -0
- package/dist/errors/invalid-provider-config.d.ts +5 -0
- package/dist/errors/invalid-provider-config.js +3 -0
- package/dist/errors/invalid-provider.d.ts +1 -0
- package/dist/errors/invalid-provider.js +3 -0
- package/dist/errors/invalid-query.d.ts +5 -0
- package/dist/errors/invalid-query.js +4 -0
- package/dist/errors/invalid-token.d.ts +1 -0
- package/dist/errors/invalid-token.js +3 -0
- package/dist/errors/method-not-allowed.d.ts +6 -0
- package/dist/errors/method-not-allowed.js +6 -0
- package/dist/errors/not-null-violation.d.ts +6 -0
- package/dist/errors/not-null-violation.js +14 -0
- package/dist/errors/range-not-satisfiable.d.ts +7 -0
- package/dist/errors/range-not-satisfiable.js +7 -0
- package/dist/errors/record-not-unique.d.ts +6 -0
- package/dist/errors/record-not-unique.js +14 -0
- package/dist/errors/route-not-found.d.ts +5 -0
- package/dist/errors/route-not-found.js +4 -0
- package/dist/errors/service-unavailable.d.ts +7 -0
- package/dist/errors/service-unavailable.js +4 -0
- package/dist/errors/token-expired.d.ts +1 -0
- package/dist/errors/token-expired.js +3 -0
- package/dist/errors/unexpected-response.d.ts +1 -0
- package/dist/errors/unexpected-response.js +3 -0
- package/dist/errors/unprocessable-content.d.ts +5 -0
- package/dist/errors/unprocessable-content.js +4 -0
- package/dist/errors/unsupported-media-type.d.ts +6 -0
- package/dist/errors/unsupported-media-type.js +4 -0
- package/dist/errors/user-suspended.d.ts +1 -0
- package/dist/errors/user-suspended.js +3 -0
- package/dist/errors/value-out-of-range.d.ts +6 -0
- package/dist/errors/value-out-of-range.js +14 -0
- package/dist/errors/value-too-long.d.ts +6 -0
- package/dist/errors/value-too-long.js +14 -0
- package/dist/extensions.js +0 -4
- package/dist/flows.js +6 -8
- package/dist/index.d.ts +0 -2
- package/dist/index.js +0 -2
- package/dist/messenger.js +4 -4
- package/dist/middleware/authenticate.js +1 -1
- package/dist/middleware/check-ip.js +2 -2
- package/dist/middleware/collection-exists.js +2 -2
- package/dist/middleware/error-handler.js +7 -7
- package/dist/middleware/graphql.js +11 -9
- package/dist/middleware/rate-limiter-global.d.ts +2 -2
- package/dist/middleware/rate-limiter-global.js +2 -3
- package/dist/middleware/rate-limiter-ip.d.ts +2 -2
- package/dist/middleware/rate-limiter-ip.js +2 -3
- package/dist/middleware/validate-batch.js +3 -4
- package/dist/rate-limiter.js +2 -9
- package/dist/services/activity.js +3 -2
- package/dist/services/assets.js +9 -10
- package/dist/services/authentication.js +12 -11
- package/dist/services/authorization.d.ts +1 -1
- package/dist/services/authorization.js +16 -16
- package/dist/services/collections.js +17 -16
- package/dist/services/fields.js +16 -14
- package/dist/services/files.js +7 -6
- package/dist/services/graphql/errors/execution.d.ts +6 -0
- package/dist/services/graphql/errors/execution.js +2 -0
- package/dist/services/graphql/errors/index.d.ts +2 -0
- package/dist/services/graphql/errors/index.js +2 -0
- package/dist/services/graphql/errors/validation.d.ts +6 -0
- package/dist/services/graphql/errors/validation.js +2 -0
- package/dist/services/graphql/index.d.ts +2 -2
- package/dist/services/graphql/index.js +30 -12
- package/dist/services/graphql/utils/process-error.js +3 -3
- package/dist/services/import-export.js +7 -7
- package/dist/services/index.d.ts +1 -0
- package/dist/services/index.js +1 -0
- package/dist/services/items.js +14 -13
- package/dist/services/mail/index.js +3 -3
- package/dist/services/meta.js +3 -3
- package/dist/services/payload.js +11 -7
- package/dist/services/relations.js +32 -22
- package/dist/services/revisions.js +3 -3
- package/dist/services/roles.js +10 -9
- package/dist/services/schema.js +5 -5
- package/dist/services/shares.js +4 -4
- package/dist/services/tfa.js +6 -6
- package/dist/services/translations.d.ts +2 -2
- package/dist/services/translations.js +4 -4
- package/dist/services/users.js +26 -29
- package/dist/services/utils.js +4 -4
- package/dist/synchronization.js +3 -3
- package/dist/types/items.d.ts +2 -2
- package/dist/utils/apply-diff.js +2 -2
- package/dist/utils/apply-query.js +17 -7
- package/dist/utils/get-accountability-for-role.js +1 -2
- package/dist/utils/get-accountability-for-token.js +3 -3
- package/dist/utils/get-column-path.js +5 -3
- package/dist/utils/get-column.js +3 -3
- package/dist/utils/get-service.d.ts +1 -1
- package/dist/utils/get-service.js +1 -1
- package/dist/utils/jwt.js +5 -5
- package/dist/utils/validate-diff.js +23 -9
- package/dist/utils/validate-keys.js +3 -3
- package/dist/utils/validate-query.d.ts +2 -0
- package/dist/utils/validate-query.js +27 -21
- package/dist/utils/validate-snapshot.js +11 -5
- package/dist/websocket/authenticate.js +12 -15
- package/dist/websocket/controllers/base.js +18 -15
- package/dist/websocket/controllers/graphql.js +2 -2
- package/dist/websocket/controllers/index.js +3 -7
- package/dist/websocket/controllers/rest.js +3 -3
- package/dist/websocket/{exceptions.d.ts → errors.d.ts} +5 -5
- package/dist/websocket/{exceptions.js → errors.js} +10 -10
- package/dist/websocket/handlers/items.js +5 -5
- package/dist/websocket/handlers/subscribe.js +8 -8
- package/package.json +15 -15
- package/dist/exceptions/content-too-large.d.ts +0 -4
- package/dist/exceptions/content-too-large.js +0 -6
- package/dist/exceptions/database/contains-null-values.d.ts +0 -9
- package/dist/exceptions/database/contains-null-values.js +0 -6
- package/dist/exceptions/database/invalid-foreign-key.d.ts +0 -10
- package/dist/exceptions/database/invalid-foreign-key.js +0 -11
- package/dist/exceptions/database/not-null-violation.d.ts +0 -9
- package/dist/exceptions/database/not-null-violation.js +0 -6
- package/dist/exceptions/database/record-not-unique.d.ts +0 -10
- package/dist/exceptions/database/record-not-unique.js +0 -11
- package/dist/exceptions/database/value-out-of-range.d.ts +0 -10
- package/dist/exceptions/database/value-out-of-range.js +0 -11
- package/dist/exceptions/database/value-too-long.d.ts +0 -9
- package/dist/exceptions/database/value-too-long.js +0 -11
- package/dist/exceptions/forbidden.d.ts +0 -6
- package/dist/exceptions/forbidden.js +0 -13
- package/dist/exceptions/graphql-validation.d.ts +0 -4
- package/dist/exceptions/graphql-validation.js +0 -6
- package/dist/exceptions/hit-rate-limit.d.ts +0 -9
- package/dist/exceptions/hit-rate-limit.js +0 -6
- package/dist/exceptions/illegal-asset-transformation.d.ts +0 -4
- package/dist/exceptions/illegal-asset-transformation.js +0 -6
- package/dist/exceptions/index.d.ts +0 -21
- package/dist/exceptions/index.js +0 -21
- package/dist/exceptions/invalid-config.d.ts +0 -4
- package/dist/exceptions/invalid-config.js +0 -6
- package/dist/exceptions/invalid-credentials.d.ts +0 -4
- package/dist/exceptions/invalid-credentials.js +0 -6
- package/dist/exceptions/invalid-ip.d.ts +0 -4
- package/dist/exceptions/invalid-ip.js +0 -6
- package/dist/exceptions/invalid-otp.d.ts +0 -4
- package/dist/exceptions/invalid-otp.js +0 -6
- package/dist/exceptions/invalid-payload.d.ts +0 -4
- package/dist/exceptions/invalid-payload.js +0 -6
- package/dist/exceptions/invalid-provider.d.ts +0 -4
- package/dist/exceptions/invalid-provider.js +0 -6
- package/dist/exceptions/invalid-query.d.ts +0 -4
- package/dist/exceptions/invalid-query.js +0 -6
- package/dist/exceptions/invalid-token.d.ts +0 -4
- package/dist/exceptions/invalid-token.js +0 -6
- package/dist/exceptions/method-not-allowed.d.ts +0 -8
- package/dist/exceptions/method-not-allowed.js +0 -6
- package/dist/exceptions/range-not-satisfiable.d.ts +0 -5
- package/dist/exceptions/range-not-satisfiable.js +0 -9
- package/dist/exceptions/route-not-found.d.ts +0 -4
- package/dist/exceptions/route-not-found.js +0 -6
- package/dist/exceptions/service-unavailable.d.ts +0 -9
- package/dist/exceptions/service-unavailable.js +0 -6
- package/dist/exceptions/token-expired.d.ts +0 -4
- package/dist/exceptions/token-expired.js +0 -6
- package/dist/exceptions/unexpected-response.d.ts +0 -4
- package/dist/exceptions/unexpected-response.js +0 -6
- package/dist/exceptions/unprocessable-entity.d.ts +0 -4
- package/dist/exceptions/unprocessable-entity.js +0 -6
- package/dist/exceptions/unsupported-media-type.d.ts +0 -4
- package/dist/exceptions/unsupported-media-type.js +0 -6
- package/dist/exceptions/user-suspended.d.ts +0 -4
- package/dist/exceptions/user-suspended.js +0 -6
- /package/dist/{exceptions/database → database/errors}/dialects/mssql.d.ts +0 -0
- /package/dist/{exceptions/database → database/errors}/dialects/mysql.d.ts +0 -0
- /package/dist/{exceptions/database → database/errors}/dialects/oracle.d.ts +0 -0
- /package/dist/{exceptions/database → database/errors}/dialects/postgres.d.ts +0 -0
- /package/dist/{exceptions/database → database/errors}/dialects/sqlite.d.ts +0 -0
- /package/dist/{exceptions/database → database/errors}/dialects/types.d.ts +0 -0
- /package/dist/{exceptions/database → database/errors}/dialects/types.js +0 -0
- /package/dist/{exceptions/database → database/errors}/translate.d.ts +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { isDirectusError } from '@directus/errors';
|
|
1
2
|
import express from 'express';
|
|
2
|
-
import {
|
|
3
|
+
import { ErrorCode } from '../errors/index.js';
|
|
3
4
|
import { respond } from '../middleware/respond.js';
|
|
4
5
|
import useCollection from '../middleware/use-collection.js';
|
|
5
6
|
import { validateBatch } from '../middleware/validate-batch.js';
|
|
@@ -34,7 +35,7 @@ router.post('/', asyncHandler(async (req, res, next) => {
|
|
|
34
35
|
}
|
|
35
36
|
}
|
|
36
37
|
catch (error) {
|
|
37
|
-
if (error
|
|
38
|
+
if (isDirectusError(error, ErrorCode.Forbidden)) {
|
|
38
39
|
return next();
|
|
39
40
|
}
|
|
40
41
|
throw error;
|
|
@@ -96,7 +97,7 @@ router.patch('/', validateBatch('update'), asyncHandler(async (req, res, next) =
|
|
|
96
97
|
res.locals['payload'] = { data: result };
|
|
97
98
|
}
|
|
98
99
|
catch (error) {
|
|
99
|
-
if (error
|
|
100
|
+
if (isDirectusError(error, ErrorCode.Forbidden)) {
|
|
100
101
|
return next();
|
|
101
102
|
}
|
|
102
103
|
throw error;
|
|
@@ -114,7 +115,7 @@ router.patch('/:pk', asyncHandler(async (req, res, next) => {
|
|
|
114
115
|
res.locals['payload'] = { data: record };
|
|
115
116
|
}
|
|
116
117
|
catch (error) {
|
|
117
|
-
if (error
|
|
118
|
+
if (isDirectusError(error, ErrorCode.Forbidden)) {
|
|
118
119
|
return next();
|
|
119
120
|
}
|
|
120
121
|
throw error;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import express from 'express';
|
|
2
|
-
import {
|
|
2
|
+
import { isDirectusError } from '@directus/errors';
|
|
3
|
+
import { ErrorCode } from '../errors/index.js';
|
|
3
4
|
import { respond } from '../middleware/respond.js';
|
|
4
5
|
import useCollection from '../middleware/use-collection.js';
|
|
5
6
|
import { validateBatch } from '../middleware/validate-batch.js';
|
|
@@ -34,7 +35,7 @@ router.post('/', asyncHandler(async (req, res, next) => {
|
|
|
34
35
|
}
|
|
35
36
|
}
|
|
36
37
|
catch (error) {
|
|
37
|
-
if (error
|
|
38
|
+
if (isDirectusError(error, ErrorCode.Forbidden)) {
|
|
38
39
|
return next();
|
|
39
40
|
}
|
|
40
41
|
throw error;
|
|
@@ -87,7 +88,7 @@ router.patch('/', validateBatch('update'), asyncHandler(async (req, res, next) =
|
|
|
87
88
|
res.locals['payload'] = { data: result };
|
|
88
89
|
}
|
|
89
90
|
catch (error) {
|
|
90
|
-
if (error
|
|
91
|
+
if (isDirectusError(error, ErrorCode.Forbidden)) {
|
|
91
92
|
return next();
|
|
92
93
|
}
|
|
93
94
|
throw error;
|
|
@@ -105,7 +106,7 @@ router.patch('/:pk', asyncHandler(async (req, res, next) => {
|
|
|
105
106
|
res.locals['payload'] = { data: item || null };
|
|
106
107
|
}
|
|
107
108
|
catch (error) {
|
|
108
|
-
if (error
|
|
109
|
+
if (isDirectusError(error, ErrorCode.Forbidden)) {
|
|
109
110
|
return next();
|
|
110
111
|
}
|
|
111
112
|
throw error;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { isDirectusError } from '@directus/errors';
|
|
1
2
|
import express from 'express';
|
|
2
|
-
import {
|
|
3
|
+
import { ErrorCode } from '../errors/index.js';
|
|
3
4
|
import { respond } from '../middleware/respond.js';
|
|
4
5
|
import useCollection from '../middleware/use-collection.js';
|
|
5
6
|
import { validateBatch } from '../middleware/validate-batch.js';
|
|
@@ -34,7 +35,7 @@ router.post('/', asyncHandler(async (req, res, next) => {
|
|
|
34
35
|
}
|
|
35
36
|
}
|
|
36
37
|
catch (error) {
|
|
37
|
-
if (error
|
|
38
|
+
if (isDirectusError(error, ErrorCode.Forbidden)) {
|
|
38
39
|
return next();
|
|
39
40
|
}
|
|
40
41
|
throw error;
|
|
@@ -87,7 +88,7 @@ router.patch('/', validateBatch('update'), asyncHandler(async (req, res, next) =
|
|
|
87
88
|
res.locals['payload'] = { data: result };
|
|
88
89
|
}
|
|
89
90
|
catch (error) {
|
|
90
|
-
if (error
|
|
91
|
+
if (isDirectusError(error, ErrorCode.Forbidden)) {
|
|
91
92
|
return next();
|
|
92
93
|
}
|
|
93
94
|
throw error;
|
|
@@ -105,7 +106,7 @@ router.patch('/:pk', asyncHandler(async (req, res, next) => {
|
|
|
105
106
|
res.locals['payload'] = { data: item || null };
|
|
106
107
|
}
|
|
107
108
|
catch (error) {
|
|
108
|
-
if (error
|
|
109
|
+
if (isDirectusError(error, ErrorCode.Forbidden)) {
|
|
109
110
|
return next();
|
|
110
111
|
}
|
|
111
112
|
throw error;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { isDirectusError } from '@directus/errors';
|
|
1
2
|
import express from 'express';
|
|
2
|
-
import {
|
|
3
|
+
import { ErrorCode } from '../errors/index.js';
|
|
3
4
|
import { respond } from '../middleware/respond.js';
|
|
4
5
|
import useCollection from '../middleware/use-collection.js';
|
|
5
6
|
import { validateBatch } from '../middleware/validate-batch.js';
|
|
@@ -34,7 +35,7 @@ router.post('/', asyncHandler(async (req, res, next) => {
|
|
|
34
35
|
}
|
|
35
36
|
}
|
|
36
37
|
catch (error) {
|
|
37
|
-
if (error
|
|
38
|
+
if (isDirectusError(error, ErrorCode.Forbidden)) {
|
|
38
39
|
return next();
|
|
39
40
|
}
|
|
40
41
|
throw error;
|
|
@@ -101,7 +102,7 @@ router.patch('/', validateBatch('update'), asyncHandler(async (req, res, next) =
|
|
|
101
102
|
res.locals['payload'] = { data: result };
|
|
102
103
|
}
|
|
103
104
|
catch (error) {
|
|
104
|
-
if (error
|
|
105
|
+
if (isDirectusError(error, ErrorCode.Forbidden)) {
|
|
105
106
|
return next();
|
|
106
107
|
}
|
|
107
108
|
throw error;
|
|
@@ -119,7 +120,7 @@ router.patch('/:pk', asyncHandler(async (req, res, next) => {
|
|
|
119
120
|
res.locals['payload'] = { data: item || null };
|
|
120
121
|
}
|
|
121
122
|
catch (error) {
|
|
122
|
-
if (error
|
|
123
|
+
if (isDirectusError(error, ErrorCode.Forbidden)) {
|
|
123
124
|
return next();
|
|
124
125
|
}
|
|
125
126
|
throw error;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { isDirectusError } from '@directus/errors';
|
|
1
2
|
import express from 'express';
|
|
2
|
-
import {
|
|
3
|
+
import { ErrorCode } from '../errors/index.js';
|
|
3
4
|
import { respond } from '../middleware/respond.js';
|
|
4
5
|
import useCollection from '../middleware/use-collection.js';
|
|
5
6
|
import { validateBatch } from '../middleware/validate-batch.js';
|
|
@@ -34,7 +35,7 @@ router.post('/', asyncHandler(async (req, res, next) => {
|
|
|
34
35
|
}
|
|
35
36
|
}
|
|
36
37
|
catch (error) {
|
|
37
|
-
if (error
|
|
38
|
+
if (isDirectusError(error, ErrorCode.Forbidden)) {
|
|
38
39
|
return next();
|
|
39
40
|
}
|
|
40
41
|
throw error;
|
|
@@ -96,7 +97,7 @@ router.patch('/', validateBatch('update'), asyncHandler(async (req, res, next) =
|
|
|
96
97
|
res.locals['payload'] = { data: result };
|
|
97
98
|
}
|
|
98
99
|
catch (error) {
|
|
99
|
-
if (error
|
|
100
|
+
if (isDirectusError(error, ErrorCode.Forbidden)) {
|
|
100
101
|
return next();
|
|
101
102
|
}
|
|
102
103
|
throw error;
|
|
@@ -114,7 +115,7 @@ router.patch('/:pk', asyncHandler(async (req, res, next) => {
|
|
|
114
115
|
res.locals['payload'] = { data: record };
|
|
115
116
|
}
|
|
116
117
|
catch (error) {
|
|
117
|
-
if (error
|
|
118
|
+
if (isDirectusError(error, ErrorCode.Forbidden)) {
|
|
118
119
|
return next();
|
|
119
120
|
}
|
|
120
121
|
throw error;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { isDirectusError } from '@directus/errors';
|
|
1
2
|
import express from 'express';
|
|
2
3
|
import Joi from 'joi';
|
|
3
|
-
import {
|
|
4
|
+
import { ErrorCode, InvalidPayloadError } from '../errors/index.js';
|
|
4
5
|
import validateCollection from '../middleware/collection-exists.js';
|
|
5
6
|
import { respond } from '../middleware/respond.js';
|
|
6
7
|
import useCollection from '../middleware/use-collection.js';
|
|
@@ -53,7 +54,7 @@ router.post('/', asyncHandler(async (req, res, next) => {
|
|
|
53
54
|
});
|
|
54
55
|
const { error } = newRelationSchema.validate(req.body);
|
|
55
56
|
if (error) {
|
|
56
|
-
throw new
|
|
57
|
+
throw new InvalidPayloadError({ reason: error.message });
|
|
57
58
|
}
|
|
58
59
|
await service.createOne(req.body);
|
|
59
60
|
try {
|
|
@@ -61,7 +62,7 @@ router.post('/', asyncHandler(async (req, res, next) => {
|
|
|
61
62
|
res.locals['payload'] = { data: createdRelation || null };
|
|
62
63
|
}
|
|
63
64
|
catch (error) {
|
|
64
|
-
if (error
|
|
65
|
+
if (isDirectusError(error, ErrorCode.Forbidden)) {
|
|
65
66
|
return next();
|
|
66
67
|
}
|
|
67
68
|
throw error;
|
|
@@ -86,7 +87,7 @@ router.patch('/:collection/:field', validateCollection, asyncHandler(async (req,
|
|
|
86
87
|
});
|
|
87
88
|
const { error } = updateRelationSchema.validate(req.body);
|
|
88
89
|
if (error) {
|
|
89
|
-
throw new
|
|
90
|
+
throw new InvalidPayloadError({ reason: error.message });
|
|
90
91
|
}
|
|
91
92
|
await service.updateOne(req.params['collection'], req.params['field'], req.body);
|
|
92
93
|
try {
|
|
@@ -94,7 +95,7 @@ router.patch('/:collection/:field', validateCollection, asyncHandler(async (req,
|
|
|
94
95
|
res.locals['payload'] = { data: updatedField || null };
|
|
95
96
|
}
|
|
96
97
|
catch (error) {
|
|
97
|
-
if (error
|
|
98
|
+
if (isDirectusError(error, ErrorCode.Forbidden)) {
|
|
98
99
|
return next();
|
|
99
100
|
}
|
|
100
101
|
throw error;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { isDirectusError } from '@directus/errors';
|
|
1
2
|
import express from 'express';
|
|
2
|
-
import {
|
|
3
|
+
import { ErrorCode } from '../errors/index.js';
|
|
3
4
|
import { respond } from '../middleware/respond.js';
|
|
4
5
|
import useCollection from '../middleware/use-collection.js';
|
|
5
6
|
import { validateBatch } from '../middleware/validate-batch.js';
|
|
@@ -34,7 +35,7 @@ router.post('/', asyncHandler(async (req, res, next) => {
|
|
|
34
35
|
}
|
|
35
36
|
}
|
|
36
37
|
catch (error) {
|
|
37
|
-
if (error
|
|
38
|
+
if (isDirectusError(error, ErrorCode.Forbidden)) {
|
|
38
39
|
return next();
|
|
39
40
|
}
|
|
40
41
|
throw error;
|
|
@@ -87,7 +88,7 @@ router.patch('/', validateBatch('update'), asyncHandler(async (req, res, next) =
|
|
|
87
88
|
res.locals['payload'] = { data: result };
|
|
88
89
|
}
|
|
89
90
|
catch (error) {
|
|
90
|
-
if (error
|
|
91
|
+
if (isDirectusError(error, ErrorCode.Forbidden)) {
|
|
91
92
|
return next();
|
|
92
93
|
}
|
|
93
94
|
throw error;
|
|
@@ -105,7 +106,7 @@ router.patch('/:pk', asyncHandler(async (req, res, next) => {
|
|
|
105
106
|
res.locals['payload'] = { data: item || null };
|
|
106
107
|
}
|
|
107
108
|
catch (error) {
|
|
108
|
-
if (error
|
|
109
|
+
if (isDirectusError(error, ErrorCode.Forbidden)) {
|
|
109
110
|
return next();
|
|
110
111
|
}
|
|
111
112
|
throw error;
|
|
@@ -2,7 +2,7 @@ import { parseJSON } from '@directus/utils';
|
|
|
2
2
|
import Busboy from 'busboy';
|
|
3
3
|
import express from 'express';
|
|
4
4
|
import { load as loadYaml } from 'js-yaml';
|
|
5
|
-
import {
|
|
5
|
+
import { InvalidPayloadError, UnsupportedMediaTypeError } from '../errors/index.js';
|
|
6
6
|
import logger from '../logger.js';
|
|
7
7
|
import { respond } from '../middleware/respond.js';
|
|
8
8
|
import { SchemaService } from '../services/schema.js';
|
|
@@ -18,13 +18,13 @@ router.get('/snapshot', asyncHandler(async (req, res, next) => {
|
|
|
18
18
|
const schemaMultipartHandler = (req, res, next) => {
|
|
19
19
|
if (req.is('application/json')) {
|
|
20
20
|
if (Object.keys(req.body).length === 0) {
|
|
21
|
-
throw new
|
|
21
|
+
throw new InvalidPayloadError({ reason: `No data was included in the body` });
|
|
22
22
|
}
|
|
23
23
|
res.locals['upload'] = req.body;
|
|
24
24
|
return next();
|
|
25
25
|
}
|
|
26
26
|
if (!req.is('multipart/form-data')) {
|
|
27
|
-
throw new
|
|
27
|
+
throw new UnsupportedMediaTypeError({ mediaType: req.headers['content-type'], where: 'Content-Type header' });
|
|
28
28
|
}
|
|
29
29
|
const headers = req.headers['content-type']
|
|
30
30
|
? req.headers
|
|
@@ -37,7 +37,7 @@ const schemaMultipartHandler = (req, res, next) => {
|
|
|
37
37
|
let upload = null;
|
|
38
38
|
busboy.on('file', async (_, fileStream, { mimeType }) => {
|
|
39
39
|
if (isFileIncluded)
|
|
40
|
-
return next(new
|
|
40
|
+
return next(new InvalidPayloadError({ reason: `More than one file was included in the body` }));
|
|
41
41
|
isFileIncluded = true;
|
|
42
42
|
const { readableStreamToString } = await import('@directus/utils/node');
|
|
43
43
|
try {
|
|
@@ -48,7 +48,7 @@ const schemaMultipartHandler = (req, res, next) => {
|
|
|
48
48
|
}
|
|
49
49
|
catch (err) {
|
|
50
50
|
logger.warn(err);
|
|
51
|
-
throw new
|
|
51
|
+
throw new InvalidPayloadError({ reason: 'The provided JSON is invalid' });
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
else {
|
|
@@ -57,11 +57,11 @@ const schemaMultipartHandler = (req, res, next) => {
|
|
|
57
57
|
}
|
|
58
58
|
catch (err) {
|
|
59
59
|
logger.warn(err);
|
|
60
|
-
throw new
|
|
60
|
+
throw new InvalidPayloadError({ reason: 'The provided YAML is invalid' });
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
if (!upload) {
|
|
64
|
-
throw new
|
|
64
|
+
throw new InvalidPayloadError({ reason: `No file was included in the body` });
|
|
65
65
|
}
|
|
66
66
|
res.locals['upload'] = upload;
|
|
67
67
|
return next();
|
|
@@ -73,7 +73,7 @@ const schemaMultipartHandler = (req, res, next) => {
|
|
|
73
73
|
busboy.on('error', (error) => next(error));
|
|
74
74
|
busboy.on('close', () => {
|
|
75
75
|
if (!isFileIncluded)
|
|
76
|
-
return next(new
|
|
76
|
+
return next(new InvalidPayloadError({ reason: `No file was included in the body` }));
|
|
77
77
|
});
|
|
78
78
|
req.pipe(busboy);
|
|
79
79
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { format } from 'date-fns';
|
|
2
2
|
import { Router } from 'express';
|
|
3
|
-
import {
|
|
3
|
+
import { RouteNotFoundError } from '../errors/index.js';
|
|
4
4
|
import { respond } from '../middleware/respond.js';
|
|
5
5
|
import { ServerService } from '../services/server.js';
|
|
6
6
|
import { SpecificationService } from '../services/specifications.js';
|
|
@@ -25,7 +25,7 @@ router.get('/specs/graphql/:scope?', asyncHandler(async (req, res) => {
|
|
|
25
25
|
});
|
|
26
26
|
const scope = req.params['scope'] || 'items';
|
|
27
27
|
if (['items', 'system'].includes(scope) === false)
|
|
28
|
-
throw new
|
|
28
|
+
throw new RouteNotFoundError({ path: req.path });
|
|
29
29
|
const info = await serverService.serverInfo();
|
|
30
30
|
const result = await service.graphql.generate(scope);
|
|
31
31
|
const filename = info['project'].project_name + '_' + format(new Date(), 'yyyy-MM-dd') + '.graphql';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { isDirectusError } from '@directus/errors';
|
|
1
2
|
import express from 'express';
|
|
2
|
-
import {
|
|
3
|
+
import { ErrorCode } from '../errors/index.js';
|
|
3
4
|
import { respond } from '../middleware/respond.js';
|
|
4
5
|
import useCollection from '../middleware/use-collection.js';
|
|
5
6
|
import { SettingsService } from '../services/settings.js';
|
|
@@ -26,7 +27,7 @@ router.patch('/', asyncHandler(async (req, res, next) => {
|
|
|
26
27
|
res.locals['payload'] = { data: record || null };
|
|
27
28
|
}
|
|
28
29
|
catch (error) {
|
|
29
|
-
if (error
|
|
30
|
+
if (isDirectusError(error, ErrorCode.Forbidden)) {
|
|
30
31
|
return next();
|
|
31
32
|
}
|
|
32
33
|
throw error;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { isDirectusError } from '@directus/errors';
|
|
1
2
|
import express from 'express';
|
|
2
3
|
import Joi from 'joi';
|
|
3
4
|
import { COOKIE_OPTIONS, UUID_REGEX } from '../constants.js';
|
|
4
5
|
import env from '../env.js';
|
|
5
|
-
import {
|
|
6
|
+
import { ErrorCode, InvalidPayloadError } from '../errors/index.js';
|
|
6
7
|
import { respond } from '../middleware/respond.js';
|
|
7
8
|
import useCollection from '../middleware/use-collection.js';
|
|
8
9
|
import { validateBatch } from '../middleware/validate-batch.js';
|
|
@@ -22,7 +23,7 @@ router.post('/auth', asyncHandler(async (req, res, next) => {
|
|
|
22
23
|
});
|
|
23
24
|
const { error } = sharedLoginSchema.validate(req.body);
|
|
24
25
|
if (error) {
|
|
25
|
-
throw new
|
|
26
|
+
throw new InvalidPayloadError({ reason: error.message });
|
|
26
27
|
}
|
|
27
28
|
const { accessToken, refreshToken, expires } = await service.login(req.body);
|
|
28
29
|
res.cookie(env['REFRESH_TOKEN_COOKIE_NAME'], refreshToken, COOKIE_OPTIONS);
|
|
@@ -40,7 +41,7 @@ router.post('/invite', asyncHandler(async (req, _res, next) => {
|
|
|
40
41
|
});
|
|
41
42
|
const { error } = sharedInviteSchema.validate(req.body);
|
|
42
43
|
if (error) {
|
|
43
|
-
throw new
|
|
44
|
+
throw new InvalidPayloadError({ reason: error.message });
|
|
44
45
|
}
|
|
45
46
|
await service.invite(req.body);
|
|
46
47
|
return next();
|
|
@@ -70,7 +71,7 @@ router.post('/', asyncHandler(async (req, res, next) => {
|
|
|
70
71
|
}
|
|
71
72
|
}
|
|
72
73
|
catch (error) {
|
|
73
|
-
if (error
|
|
74
|
+
if (isDirectusError(error, ErrorCode.Forbidden)) {
|
|
74
75
|
return next();
|
|
75
76
|
}
|
|
76
77
|
throw error;
|
|
@@ -160,7 +161,7 @@ router.patch('/', validateBatch('update'), asyncHandler(async (req, res, next) =
|
|
|
160
161
|
res.locals['payload'] = { data: result };
|
|
161
162
|
}
|
|
162
163
|
catch (error) {
|
|
163
|
-
if (error
|
|
164
|
+
if (isDirectusError(error, ErrorCode.Forbidden)) {
|
|
164
165
|
return next();
|
|
165
166
|
}
|
|
166
167
|
throw error;
|
|
@@ -178,7 +179,7 @@ router.patch(`/:pk(${UUID_REGEX})`, asyncHandler(async (req, res, next) => {
|
|
|
178
179
|
res.locals['payload'] = { data: item || null };
|
|
179
180
|
}
|
|
180
181
|
catch (error) {
|
|
181
|
-
if (error
|
|
182
|
+
if (isDirectusError(error, ErrorCode.Forbidden)) {
|
|
182
183
|
return next();
|
|
183
184
|
}
|
|
184
185
|
throw error;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { isDirectusError } from '@directus/errors';
|
|
1
2
|
import express from 'express';
|
|
2
|
-
import {
|
|
3
|
+
import { ErrorCode } from '../errors/index.js';
|
|
3
4
|
import { respond } from '../middleware/respond.js';
|
|
4
5
|
import useCollection from '../middleware/use-collection.js';
|
|
5
6
|
import { validateBatch } from '../middleware/validate-batch.js';
|
|
6
|
-
import { TranslationsService } from '../services/translations.js';
|
|
7
7
|
import { MetaService } from '../services/meta.js';
|
|
8
|
+
import { TranslationsService } from '../services/translations.js';
|
|
8
9
|
import asyncHandler from '../utils/async-handler.js';
|
|
9
10
|
import { sanitizeQuery } from '../utils/sanitize-query.js';
|
|
10
11
|
const router = express.Router();
|
|
@@ -34,7 +35,7 @@ router.post('/', asyncHandler(async (req, res, next) => {
|
|
|
34
35
|
}
|
|
35
36
|
}
|
|
36
37
|
catch (error) {
|
|
37
|
-
if (error
|
|
38
|
+
if (isDirectusError(error, ErrorCode.Forbidden)) {
|
|
38
39
|
return next();
|
|
39
40
|
}
|
|
40
41
|
throw error;
|
|
@@ -96,7 +97,7 @@ router.patch('/', validateBatch('update'), asyncHandler(async (req, res, next) =
|
|
|
96
97
|
res.locals['payload'] = { data: result || null };
|
|
97
98
|
}
|
|
98
99
|
catch (error) {
|
|
99
|
-
if (error
|
|
100
|
+
if (isDirectusError(error, ErrorCode.Forbidden)) {
|
|
100
101
|
return next();
|
|
101
102
|
}
|
|
102
103
|
throw error;
|
|
@@ -114,7 +115,7 @@ router.patch('/:pk', asyncHandler(async (req, res, next) => {
|
|
|
114
115
|
res.locals['payload'] = { data: record || null };
|
|
115
116
|
}
|
|
116
117
|
catch (error) {
|
|
117
|
-
if (error
|
|
118
|
+
if (isDirectusError(error, ErrorCode.Forbidden)) {
|
|
118
119
|
return next();
|
|
119
120
|
}
|
|
120
121
|
throw error;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { isDirectusError } from '@directus/errors';
|
|
1
2
|
import express from 'express';
|
|
2
3
|
import Joi from 'joi';
|
|
3
|
-
import {
|
|
4
|
+
import { ErrorCode, ForbiddenError, InvalidCredentialsError, InvalidPayloadError } from '../errors/index.js';
|
|
4
5
|
import { respond } from '../middleware/respond.js';
|
|
5
6
|
import useCollection from '../middleware/use-collection.js';
|
|
6
7
|
import { validateBatch } from '../middleware/validate-batch.js';
|
|
@@ -38,7 +39,7 @@ router.post('/', asyncHandler(async (req, res, next) => {
|
|
|
38
39
|
}
|
|
39
40
|
}
|
|
40
41
|
catch (error) {
|
|
41
|
-
if (error
|
|
42
|
+
if (isDirectusError(error, ErrorCode.Forbidden)) {
|
|
42
43
|
return next();
|
|
43
44
|
}
|
|
44
45
|
throw error;
|
|
@@ -75,7 +76,7 @@ router.get('/me', asyncHandler(async (req, res, next) => {
|
|
|
75
76
|
return next();
|
|
76
77
|
}
|
|
77
78
|
if (!req.accountability?.user) {
|
|
78
|
-
throw new
|
|
79
|
+
throw new InvalidCredentialsError();
|
|
79
80
|
}
|
|
80
81
|
const service = new UsersService({
|
|
81
82
|
accountability: req.accountability,
|
|
@@ -86,7 +87,7 @@ router.get('/me', asyncHandler(async (req, res, next) => {
|
|
|
86
87
|
res.locals['payload'] = { data: item || null };
|
|
87
88
|
}
|
|
88
89
|
catch (error) {
|
|
89
|
-
if (error
|
|
90
|
+
if (isDirectusError(error, ErrorCode.Forbidden)) {
|
|
90
91
|
res.locals['payload'] = { data: { id: req.accountability.user } };
|
|
91
92
|
return next();
|
|
92
93
|
}
|
|
@@ -107,7 +108,7 @@ router.get('/:pk', asyncHandler(async (req, res, next) => {
|
|
|
107
108
|
}), respond);
|
|
108
109
|
router.patch('/me', asyncHandler(async (req, res, next) => {
|
|
109
110
|
if (!req.accountability?.user) {
|
|
110
|
-
throw new
|
|
111
|
+
throw new InvalidCredentialsError();
|
|
111
112
|
}
|
|
112
113
|
const service = new UsersService({
|
|
113
114
|
accountability: req.accountability,
|
|
@@ -120,10 +121,10 @@ router.patch('/me', asyncHandler(async (req, res, next) => {
|
|
|
120
121
|
}), respond);
|
|
121
122
|
router.patch('/me/track/page', asyncHandler(async (req, _res, next) => {
|
|
122
123
|
if (!req.accountability?.user) {
|
|
123
|
-
throw new
|
|
124
|
+
throw new InvalidCredentialsError();
|
|
124
125
|
}
|
|
125
126
|
if (!req.body.last_page) {
|
|
126
|
-
throw new
|
|
127
|
+
throw new InvalidPayloadError({ reason: `"last_page" key is required` });
|
|
127
128
|
}
|
|
128
129
|
const service = new UsersService({ schema: req.schema });
|
|
129
130
|
await service.updateOne(req.accountability.user, { last_page: req.body.last_page }, { autoPurgeCache: false });
|
|
@@ -150,7 +151,7 @@ router.patch('/', validateBatch('update'), asyncHandler(async (req, res, next) =
|
|
|
150
151
|
res.locals['payload'] = { data: result };
|
|
151
152
|
}
|
|
152
153
|
catch (error) {
|
|
153
|
-
if (error
|
|
154
|
+
if (isDirectusError(error, ErrorCode.Forbidden)) {
|
|
154
155
|
return next();
|
|
155
156
|
}
|
|
156
157
|
throw error;
|
|
@@ -168,7 +169,7 @@ router.patch('/:pk', asyncHandler(async (req, res, next) => {
|
|
|
168
169
|
res.locals['payload'] = { data: item || null };
|
|
169
170
|
}
|
|
170
171
|
catch (error) {
|
|
171
|
-
if (error
|
|
172
|
+
if (isDirectusError(error, ErrorCode.Forbidden)) {
|
|
172
173
|
return next();
|
|
173
174
|
}
|
|
174
175
|
throw error;
|
|
@@ -208,7 +209,7 @@ const inviteSchema = Joi.object({
|
|
|
208
209
|
router.post('/invite', asyncHandler(async (req, _res, next) => {
|
|
209
210
|
const { error } = inviteSchema.validate(req.body);
|
|
210
211
|
if (error)
|
|
211
|
-
throw new
|
|
212
|
+
throw new InvalidPayloadError({ reason: error.message });
|
|
212
213
|
const service = new UsersService({
|
|
213
214
|
accountability: req.accountability,
|
|
214
215
|
schema: req.schema,
|
|
@@ -223,7 +224,7 @@ const acceptInviteSchema = Joi.object({
|
|
|
223
224
|
router.post('/invite/accept', asyncHandler(async (req, _res, next) => {
|
|
224
225
|
const { error } = acceptInviteSchema.validate(req.body);
|
|
225
226
|
if (error)
|
|
226
|
-
throw new
|
|
227
|
+
throw new InvalidPayloadError({ reason: error.message });
|
|
227
228
|
const service = new UsersService({
|
|
228
229
|
accountability: req.accountability,
|
|
229
230
|
schema: req.schema,
|
|
@@ -233,10 +234,10 @@ router.post('/invite/accept', asyncHandler(async (req, _res, next) => {
|
|
|
233
234
|
}), respond);
|
|
234
235
|
router.post('/me/tfa/generate/', asyncHandler(async (req, res, next) => {
|
|
235
236
|
if (!req.accountability?.user) {
|
|
236
|
-
throw new
|
|
237
|
+
throw new InvalidCredentialsError();
|
|
237
238
|
}
|
|
238
239
|
if (!req.body.password) {
|
|
239
|
-
throw new
|
|
240
|
+
throw new InvalidPayloadError({ reason: `"password" is required` });
|
|
240
241
|
}
|
|
241
242
|
const service = new TFAService({
|
|
242
243
|
accountability: req.accountability,
|
|
@@ -253,13 +254,13 @@ router.post('/me/tfa/generate/', asyncHandler(async (req, res, next) => {
|
|
|
253
254
|
}), respond);
|
|
254
255
|
router.post('/me/tfa/enable/', asyncHandler(async (req, _res, next) => {
|
|
255
256
|
if (!req.accountability?.user) {
|
|
256
|
-
throw new
|
|
257
|
+
throw new InvalidCredentialsError();
|
|
257
258
|
}
|
|
258
259
|
if (!req.body.secret) {
|
|
259
|
-
throw new
|
|
260
|
+
throw new InvalidPayloadError({ reason: `"secret" is required` });
|
|
260
261
|
}
|
|
261
262
|
if (!req.body.otp) {
|
|
262
|
-
throw new
|
|
263
|
+
throw new InvalidPayloadError({ reason: `"otp" is required` });
|
|
263
264
|
}
|
|
264
265
|
// Override permissions only when enforce TFA is enabled in role
|
|
265
266
|
if (req.accountability.role) {
|
|
@@ -297,10 +298,10 @@ router.post('/me/tfa/enable/', asyncHandler(async (req, _res, next) => {
|
|
|
297
298
|
}), respond);
|
|
298
299
|
router.post('/me/tfa/disable', asyncHandler(async (req, _res, next) => {
|
|
299
300
|
if (!req.accountability?.user) {
|
|
300
|
-
throw new
|
|
301
|
+
throw new InvalidCredentialsError();
|
|
301
302
|
}
|
|
302
303
|
if (!req.body.otp) {
|
|
303
|
-
throw new
|
|
304
|
+
throw new InvalidPayloadError({ reason: `"otp" is required` });
|
|
304
305
|
}
|
|
305
306
|
// Override permissions only when enforce TFA is enabled in role
|
|
306
307
|
if (req.accountability.role) {
|
|
@@ -335,17 +336,17 @@ router.post('/me/tfa/disable', asyncHandler(async (req, _res, next) => {
|
|
|
335
336
|
});
|
|
336
337
|
const otpValid = await service.verifyOTP(req.accountability.user, req.body.otp);
|
|
337
338
|
if (otpValid === false) {
|
|
338
|
-
throw new
|
|
339
|
+
throw new InvalidPayloadError({ reason: `"otp" is invalid` });
|
|
339
340
|
}
|
|
340
341
|
await service.disableTFA(req.accountability.user);
|
|
341
342
|
return next();
|
|
342
343
|
}), respond);
|
|
343
344
|
router.post('/:pk/tfa/disable', asyncHandler(async (req, _res, next) => {
|
|
344
345
|
if (!req.accountability?.user) {
|
|
345
|
-
throw new
|
|
346
|
+
throw new InvalidCredentialsError();
|
|
346
347
|
}
|
|
347
348
|
if (!req.accountability.admin || !req.params['pk']) {
|
|
348
|
-
throw new
|
|
349
|
+
throw new ForbiddenError();
|
|
349
350
|
}
|
|
350
351
|
const service = new TFAService({
|
|
351
352
|
accountability: req.accountability,
|