mirror of
https://github.com/directus/directus.git
synced 2026-01-31 03:08:03 -05:00
Merge branch 'main' into Kinzi/main
This commit is contained in:
@@ -9,6 +9,8 @@ import { Transformation } from '../types/assets';
|
||||
import storage from '../storage';
|
||||
import { PayloadService, AssetsService } from '../services';
|
||||
import useCollection from '../middleware/use-collection';
|
||||
import env from '../env';
|
||||
import ms from 'ms';
|
||||
|
||||
const router = Router();
|
||||
|
||||
@@ -30,11 +32,7 @@ router.get(
|
||||
const isValidUUID = validate(id, 4);
|
||||
if (isValidUUID === false) throw new ForbiddenException();
|
||||
|
||||
const file = await database
|
||||
.select('id', 'storage', 'filename_disk')
|
||||
.from('directus_files')
|
||||
.where({ id })
|
||||
.first();
|
||||
const file = await database.select('id', 'storage', 'filename_disk').from('directus_files').where({ id }).first();
|
||||
|
||||
if (!file) throw new ForbiddenException();
|
||||
|
||||
@@ -64,24 +62,17 @@ router.get(
|
||||
const transformation = pick(req.query, ASSET_TRANSFORM_QUERY_KEYS);
|
||||
|
||||
if (transformation.hasOwnProperty('key') && Object.keys(transformation).length > 1) {
|
||||
throw new InvalidQueryException(
|
||||
`You can't combine the "key" query parameter with any other transformation.`
|
||||
);
|
||||
throw new InvalidQueryException(`You can't combine the "key" query parameter with any other transformation.`);
|
||||
}
|
||||
|
||||
const systemKeys = SYSTEM_ASSET_ALLOW_LIST.map((transformation) => transformation.key);
|
||||
const allKeys: string[] = [
|
||||
...systemKeys,
|
||||
...(assetSettings.storage_asset_presets || []).map(
|
||||
(transformation: Transformation) => transformation.key
|
||||
),
|
||||
...(assetSettings.storage_asset_presets || []).map((transformation: Transformation) => transformation.key),
|
||||
];
|
||||
|
||||
// For use in the next request handler
|
||||
res.locals.shortcuts = [
|
||||
...SYSTEM_ASSET_ALLOW_LIST,
|
||||
...(assetSettings.storage_asset_presets || []),
|
||||
];
|
||||
res.locals.shortcuts = [...SYSTEM_ASSET_ALLOW_LIST, ...(assetSettings.storage_asset_presets || [])];
|
||||
res.locals.transformation = transformation;
|
||||
|
||||
if (Object.keys(transformation).length === 0) {
|
||||
@@ -93,15 +84,10 @@ router.get(
|
||||
return next();
|
||||
} else if (assetSettings.storage_asset_transform === 'shortcut') {
|
||||
if (allKeys.includes(transformation.key as string)) return next();
|
||||
throw new InvalidQueryException(
|
||||
`Only configured shortcuts can be used in asset generation.`
|
||||
);
|
||||
throw new InvalidQueryException(`Only configured shortcuts can be used in asset generation.`);
|
||||
} else {
|
||||
if (transformation.key && systemKeys.includes(transformation.key as string))
|
||||
return next();
|
||||
throw new InvalidQueryException(
|
||||
`Dynamic asset generation has been disabled for this project.`
|
||||
);
|
||||
if (transformation.key && systemKeys.includes(transformation.key as string)) return next();
|
||||
throw new InvalidQueryException(`Dynamic asset generation has been disabled for this project.`);
|
||||
}
|
||||
}),
|
||||
|
||||
@@ -114,8 +100,7 @@ router.get(
|
||||
|
||||
const transformation: Transformation = res.locals.transformation.key
|
||||
? res.locals.shortcuts.find(
|
||||
(transformation: Transformation) =>
|
||||
transformation.key === res.locals.transformation.key
|
||||
(transformation: Transformation) => transformation.key === res.locals.transformation.key
|
||||
)
|
||||
: res.locals.transformation;
|
||||
|
||||
@@ -128,6 +113,8 @@ router.get(
|
||||
res.removeHeader('Content-Disposition');
|
||||
}
|
||||
|
||||
const access = !!req.accountability?.role ? 'private' : 'public';
|
||||
res.setHeader('Cache-Control', `${access}, max-age="${ms(env.ASSETS_CACHE_TTL as string)}"`);
|
||||
stream.pipe(res);
|
||||
})
|
||||
);
|
||||
|
||||
@@ -68,8 +68,7 @@ router.post(
|
||||
httpOnly: true,
|
||||
maxAge: ms(env.REFRESH_TOKEN_TTL as string),
|
||||
secure: env.REFRESH_TOKEN_COOKIE_SECURE === 'true' ? true : false,
|
||||
sameSite:
|
||||
(env.REFRESH_TOKEN_COOKIE_SAME_SITE as 'lax' | 'strict' | 'none') || 'strict',
|
||||
sameSite: (env.REFRESH_TOKEN_COOKIE_SAME_SITE as 'lax' | 'strict' | 'none') || 'strict',
|
||||
});
|
||||
}
|
||||
|
||||
@@ -97,16 +96,12 @@ router.post(
|
||||
const currentRefreshToken = req.body.refresh_token || req.cookies.directus_refresh_token;
|
||||
|
||||
if (!currentRefreshToken) {
|
||||
throw new InvalidPayloadException(
|
||||
`"refresh_token" is required in either the JSON payload or Cookie`
|
||||
);
|
||||
throw new InvalidPayloadException(`"refresh_token" is required in either the JSON payload or Cookie`);
|
||||
}
|
||||
|
||||
const mode: 'json' | 'cookie' = req.body.mode || req.body.refresh_token ? 'json' : 'cookie';
|
||||
|
||||
const { accessToken, refreshToken, expires } = await authenticationService.refresh(
|
||||
currentRefreshToken
|
||||
);
|
||||
const { accessToken, refreshToken, expires } = await authenticationService.refresh(currentRefreshToken);
|
||||
|
||||
const payload = {
|
||||
data: { access_token: accessToken, expires },
|
||||
@@ -121,8 +116,7 @@ router.post(
|
||||
httpOnly: true,
|
||||
maxAge: ms(env.REFRESH_TOKEN_TTL as string),
|
||||
secure: env.REFRESH_TOKEN_COOKIE_SECURE === 'true' ? true : false,
|
||||
sameSite:
|
||||
(env.REFRESH_TOKEN_COOKIE_SAME_SITE as 'lax' | 'strict' | 'none') || 'strict',
|
||||
sameSite: (env.REFRESH_TOKEN_COOKIE_SAME_SITE as 'lax' | 'strict' | 'none') || 'strict',
|
||||
});
|
||||
}
|
||||
|
||||
@@ -150,9 +144,7 @@ router.post(
|
||||
const currentRefreshToken = req.body.refresh_token || req.cookies.directus_refresh_token;
|
||||
|
||||
if (!currentRefreshToken) {
|
||||
throw new InvalidPayloadException(
|
||||
`"refresh_token" is required in either the JSON payload or Cookie`
|
||||
);
|
||||
throw new InvalidPayloadException(`"refresh_token" is required in either the JSON payload or Cookie`);
|
||||
}
|
||||
|
||||
await authenticationService.logout(currentRefreshToken);
|
||||
@@ -222,10 +214,7 @@ router.get(
|
||||
respond
|
||||
);
|
||||
|
||||
router.use(
|
||||
'/oauth',
|
||||
session({ secret: env.SECRET as string, saveUninitialized: false, resave: false })
|
||||
);
|
||||
router.use('/oauth', session({ secret: env.SECRET as string, saveUninitialized: false, resave: false }));
|
||||
|
||||
router.get(
|
||||
'/oauth/:provider',
|
||||
@@ -279,8 +268,7 @@ router.get(
|
||||
httpOnly: true,
|
||||
maxAge: ms(env.REFRESH_TOKEN_TTL as string),
|
||||
secure: env.REFRESH_TOKEN_COOKIE_SECURE === 'true' ? true : false,
|
||||
sameSite:
|
||||
(env.REFRESH_TOKEN_COOKIE_SAME_SITE as 'lax' | 'strict' | 'none') || 'strict',
|
||||
sameSite: (env.REFRESH_TOKEN_COOKIE_SAME_SITE as 'lax' | 'strict' | 'none') || 'strict',
|
||||
});
|
||||
|
||||
return res.redirect(redirect);
|
||||
|
||||
@@ -52,8 +52,7 @@ router.get(
|
||||
schema: req.schema,
|
||||
});
|
||||
|
||||
if (req.params.field in req.schema[req.params.collection].columns === false)
|
||||
throw new ForbiddenException();
|
||||
if (req.params.field in req.schema[req.params.collection].columns === false) throw new ForbiddenException();
|
||||
|
||||
const field = await service.readOne(req.params.collection, req.params.field);
|
||||
|
||||
@@ -80,8 +79,7 @@ router.post(
|
||||
'/:collection',
|
||||
validateCollection,
|
||||
asyncHandler(async (req, res, next) => {
|
||||
if (!req.body.schema && !req.body.meta)
|
||||
throw new InvalidPayloadException(`"schema" or "meta" is required`);
|
||||
if (!req.body.schema && !req.body.meta) throw new InvalidPayloadException(`"schema" or "meta" is required`);
|
||||
|
||||
const service = new FieldsService({
|
||||
accountability: req.accountability,
|
||||
|
||||
@@ -68,11 +68,7 @@ const multipartHandler = asyncHandler(async (req, res, next) => {
|
||||
};
|
||||
|
||||
try {
|
||||
const primaryKey = await service.upload(
|
||||
fileStream,
|
||||
payloadWithRequiredFields,
|
||||
existingPrimaryKey
|
||||
);
|
||||
const primaryKey = await service.upload(fileStream, payloadWithRequiredFields, existingPrimaryKey);
|
||||
savedFiles.push(primaryKey);
|
||||
tryDone();
|
||||
} catch (error) {
|
||||
|
||||
@@ -2,11 +2,7 @@ import express from 'express';
|
||||
import asyncHandler from 'express-async-handler';
|
||||
import collectionExists from '../middleware/collection-exists';
|
||||
import { ItemsService, MetaService } from '../services';
|
||||
import {
|
||||
RouteNotFoundException,
|
||||
ForbiddenException,
|
||||
FailedValidationException,
|
||||
} from '../exceptions';
|
||||
import { RouteNotFoundException, ForbiddenException, FailedValidationException } from '../exceptions';
|
||||
import { respond } from '../middleware/respond';
|
||||
import { InvalidPayloadException } from '../exceptions';
|
||||
import { PrimaryKey } from '../types';
|
||||
@@ -52,6 +48,7 @@ router.get(
|
||||
accountability: req.accountability,
|
||||
schema: req.schema,
|
||||
});
|
||||
|
||||
const metaService = new MetaService({
|
||||
accountability: req.accountability,
|
||||
schema: req.schema,
|
||||
@@ -67,6 +64,7 @@ router.get(
|
||||
meta: meta,
|
||||
data: records || null,
|
||||
};
|
||||
|
||||
return next();
|
||||
}),
|
||||
respond
|
||||
|
||||
@@ -2,11 +2,7 @@ import express from 'express';
|
||||
import asyncHandler from 'express-async-handler';
|
||||
import { PermissionsService, MetaService } from '../services';
|
||||
import { clone } from 'lodash';
|
||||
import {
|
||||
InvalidCredentialsException,
|
||||
ForbiddenException,
|
||||
InvalidPayloadException,
|
||||
} from '../exceptions';
|
||||
import { InvalidCredentialsException, ForbiddenException, InvalidPayloadException } from '../exceptions';
|
||||
import useCollection from '../middleware/use-collection';
|
||||
import { respond } from '../middleware/respond';
|
||||
import { PrimaryKey } from '../types';
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
import express from 'express';
|
||||
import asyncHandler from 'express-async-handler';
|
||||
import Joi from 'joi';
|
||||
import {
|
||||
InvalidPayloadException,
|
||||
InvalidCredentialsException,
|
||||
ForbiddenException,
|
||||
} from '../exceptions';
|
||||
import { InvalidPayloadException, InvalidCredentialsException, ForbiddenException } from '../exceptions';
|
||||
import { UsersService, MetaService, AuthenticationService } from '../services';
|
||||
import useCollection from '../middleware/use-collection';
|
||||
import { respond } from '../middleware/respond';
|
||||
@@ -205,10 +201,7 @@ router.delete(
|
||||
);
|
||||
|
||||
const inviteSchema = Joi.object({
|
||||
email: Joi.alternatives(
|
||||
Joi.string().email(),
|
||||
Joi.array().items(Joi.string().email())
|
||||
).required(),
|
||||
email: Joi.alternatives(Joi.string().email(), Joi.array().items(Joi.string().email())).required(),
|
||||
role: Joi.string().uuid({ version: 'uuidv4' }).required(),
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user