Merge branch 'main' into Kinzi/main

This commit is contained in:
rijkvanzanten
2020-12-16 16:54:54 -05:00
534 changed files with 26084 additions and 48664 deletions

View File

@@ -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);
})
);

View File

@@ -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);

View File

@@ -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,

View File

@@ -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) {

View File

@@ -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

View File

@@ -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';

View File

@@ -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(),
});