From ff580541585a3b31b4bca0779ede6b99ac65dccf Mon Sep 17 00:00:00 2001 From: Bobby Date: Thu, 6 Oct 2022 03:26:19 +0700 Subject: [PATCH] fix: type-is uploads filtering also improved its parsing logic --- controllers/uploadController.js | 70 +++++++++++++++++++++------------ controllers/utilsController.js | 2 +- 2 files changed, 45 insertions(+), 27 deletions(-) diff --git a/controllers/uploadController.js b/controllers/uploadController.js index caf8976..15a617c 100644 --- a/controllers/uploadController.js +++ b/controllers/uploadController.js @@ -1208,13 +1208,14 @@ self.list = async (req, res) => { queries: { exclude: {} }, - typeIs: [ - 'image', - 'video', - 'audio' - ], + typeIs: { + image: Constants.IMAGE_EXTS, + video: Constants.VIDEO_EXTS, + audio: Constants.AUDIO_EXTS + }, flags: {} } + const typeIsKeys = Object.keys(filterObj.typeIs) const sortObj = { // Cast columns to specific type if they are stored differently @@ -1536,34 +1537,51 @@ self.list = async (req, res) => { delete filterObj.queries.sort } - // Parse is keys - let isKeys = 0 - let isLast + // Parse type-is keys if (filterObj.queries.is || filterObj.queries.exclude.is) { - for (const type of filterObj.typeIs) { - const inQuery = filterObj.queries.is && filterObj.queries.is.includes(type) - const inExclude = filterObj.queries.exclude.is && filterObj.queries.exclude.is.includes(type) + const types = [] - // Prioritize exclude keys when both types found - if (inQuery || inExclude) { - filterObj.flags[`is${type}`] = inExclude ? false : inQuery - if (isLast !== undefined && isLast !== filterObj.flags[`is${type}`]) { - throw new ClientError('Cannot mix inclusion and exclusion type-is keys.') - } - isKeys++ - isLast = filterObj.flags[`is${type}`] + if (filterObj.queries.is) { + filterObj.queries.is = filterObj.queries.is.map(type => type.toLowerCase()) + types.push(...filterObj.queries.is) + } + if (filterObj.queries.exclude.is) { + filterObj.queries.exclude.is = filterObj.queries.exclude.is.map(type => type.toLowerCase()) + types.push(...filterObj.queries.exclude.is) + } + + let isKeys = 0 + let isLast + + for (const type of types) { + if (!typeIsKeys.includes(type)) { + throw new ClientError(`Found invalid type-is key: ${type}.`) } + + if (filterObj.queries.is && filterObj.queries.is.includes(type)) { + filterObj.flags[`is${type}`] = true + } else { + filterObj.flags[`is${type}`] = false + } + + isKeys++ + + if (isLast === undefined) { + isLast = filterObj.flags[`is${type}`] + } else if (filterObj.flags[`is${type}`] !== isLast) { + throw new ClientError('Cannot mix inclusion and exclusion type-is keys.') + } + } + + // Regular user threshold check + if (!ismoderator && isKeys > MAX_IS_KEYS) { + throw new ClientError(`Users are only allowed to use ${MAX_IS_KEYS} type-is key${MAX_IS_KEYS === 1 ? '' : 's'} at a time.`) } // Delete keys to avoid unexpected behavior delete filterObj.queries.is delete filterObj.queries.exclude.is } - - // Regular user threshold check - if (!ismoderator && isKeys > MAX_IS_KEYS) { - throw new ClientError(`Users are only allowed to use ${MAX_IS_KEYS} type-is key${MAX_IS_KEYS === 1 ? '' : 's'} at a time.`) - } } function filter () { @@ -1670,7 +1688,7 @@ self.list = async (req, res) => { // Then, refine using type-is flags this.andWhere(function () { - for (const type of filterObj.typeIs) { + for (const type of typeIsKeys) { let func let operator if (filterObj.flags[`is${type}`] === true) { @@ -1682,7 +1700,7 @@ self.list = async (req, res) => { } if (func) { - for (const pattern of utils[`${type}Exts`].map(ext => `%${ext}`)) { + for (const pattern of filterObj.typeIs[type].map(ext => `%${ext}`)) { this[func]('name', operator, pattern) } } diff --git a/controllers/utilsController.js b/controllers/utilsController.js index 5b7af03..a98d7de 100644 --- a/controllers/utilsController.js +++ b/controllers/utilsController.js @@ -10,8 +10,8 @@ const path = require('path') const sharp = require('sharp') const paths = require('./pathsController') const perms = require('./permissionController') -const Constants = require('./utils/Constants') const ClientError = require('./utils/ClientError') +const Constants = require('./utils/Constants') const ServerError = require('./utils/ServerError') const SimpleDataStore = require('./utils/SimpleDataStore') const StatsManager = require('./utils/StatsManager')