diff --git a/package-lock.json b/package-lock.json index e5fa9f5c26..8172c8e812 100644 --- a/package-lock.json +++ b/package-lock.json @@ -500,6 +500,12 @@ "integrity": "sha512-xSQfNcvOiE5f9dyd4Kzxbof1aTrLobL278pGLKOZI6esGfZ7ts9Ka16CzIN6Y8hFHE1C7jIBZokULhK1bOgjRw==", "dev": true }, + "@types/uuid-validate": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@types/uuid-validate/-/uuid-validate-0.0.1.tgz", + "integrity": "sha512-RbX9q0U00SLoV+l7loYX0Wrtv4QTClBC0QcdNts6x2b5G1HJN8NI9YlS1HNA6THrI9EH3OXSgya6eMQIlDjKFA==", + "dev": true + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", diff --git a/package.json b/package.json index c2ae2a25b6..6b002590fe 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "@types/pino": "^6.3.0", "@types/sharp": "^0.25.0", "@types/uuid": "^8.0.0", + "@types/uuid-validate": "0.0.1", "copyfiles": "^2.3.0", "eslint": "^7.3.1", "eslint-plugin-prettier": "^3.1.4", diff --git a/src/constants.ts b/src/constants.ts index f69e8ca984..a8546dd964 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,38 +1,35 @@ export const SYSTEM_ASSET_WHITELIST = [ { - key: 'directus-small-crop', + key: 'directus-small-cover', w: 64, h: 64, - f: 'crop', + f: 'cover', }, { key: 'directus-small-contain', w: 64, - h: 64, f: 'contain', }, { - key: 'directus-medium-crop', + key: 'directus-medium-cover', w: 300, h: 300, - f: 'crop', + f: 'cover', }, { key: 'directus-medium-contain', w: 300, - h: 300, f: 'contain', }, { - key: 'directus-large-crop', + key: 'directus-large-cover', w: 800, h: 600, - f: 'crop', + f: 'cover', }, { key: 'directus-large-contain', w: 800, - h: 600, f: 'contain', }, ]; diff --git a/src/routes/assets.ts b/src/routes/assets.ts index e70872d78a..5d3333a9c5 100644 --- a/src/routes/assets.ts +++ b/src/routes/assets.ts @@ -23,7 +23,7 @@ router.get( * validity of the uuid ahead of time. * @todo move this to a validation middleware function */ - const isValidUUID = validate(id); + const isValidUUID = validate(id, 4); if (isValidUUID === false) throw new ItemNotFoundException(id, 'directus_files'); const file = await database.select('id').from('directus_files').where({ id }); @@ -36,6 +36,7 @@ router.get( // Validate query params asyncHandler(async (req, res, next) => { const defaults = { asset_shortcuts: '[]', asset_generation: 'all' }; + const assetSettings = (await database .select('asset_shortcuts', 'asset_generation') @@ -48,7 +49,12 @@ router.get( ...assetSettings.asset_shortcuts.map((size) => size.key), ]; + // For use in the next request handler + res.locals.shortcuts = [...SYSTEM_ASSET_WHITELIST, assetSettings.asset_shortcuts]; + if (assetSettings.asset_generation === 'all') { + if (req.query.key && allKeys.includes(req.query.key as string) === false) + throw new InvalidQueryException(`Key "${req.query.key}" isn't configured.`); return next(); } else if (assetSettings.asset_generation === 'shortcut') { if (allKeys.includes(req.query.key as string)) return next(); @@ -56,7 +62,7 @@ router.get( `Only configured shortcuts can be used in asset generation.` ); } else { - if (systemKeys.includes(req.query.key as string)) return next(); + if (req.query.key && systemKeys.includes(req.query.key as string)) return next(); throw new InvalidQueryException( `Dynamic asset generation has been disabled for this project.` ); @@ -65,7 +71,10 @@ router.get( // Return file asyncHandler(async (req, res) => { - const { stream, file } = await AssetsService.getAsset(req.params.pk, req.query); + const transformation = req.query.key + ? res.locals.shortcuts.find((size) => size.key === req.query.key) + : req.query; + const { stream, file } = await AssetsService.getAsset(req.params.pk, transformation); res.setHeader('Content-Disposition', 'attachment; filename=' + file.filename_download); res.setHeader('Content-Type', file.type);