diff options
Diffstat (limited to 'server')
-rw-r--r-- | server/helpers/custom-validators/search.ts | 19 | ||||
-rw-r--r-- | server/middlewares/validators/search.ts | 4 | ||||
-rw-r--r-- | server/tests/api/check-params/search.ts | 79 |
3 files changed, 98 insertions, 4 deletions
diff --git a/server/helpers/custom-validators/search.ts b/server/helpers/custom-validators/search.ts index bb17134c3..429fcafcf 100644 --- a/server/helpers/custom-validators/search.ts +++ b/server/helpers/custom-validators/search.ts | |||
@@ -1,5 +1,7 @@ | |||
1 | import validator from 'validator' | 1 | import validator from 'validator' |
2 | import { isArray } from './misc' | 2 | import { SearchTargetType } from '@shared/models/search/search-target-query.model' |
3 | import { isArray, exists } from './misc' | ||
4 | import { CONFIG } from '@server/initializers/config' | ||
3 | 5 | ||
4 | function isNumberArray (value: any) { | 6 | function isNumberArray (value: any) { |
5 | return isArray(value) && value.every(v => validator.isInt('' + v)) | 7 | return isArray(value) && value.every(v => validator.isInt('' + v)) |
@@ -13,10 +15,23 @@ function isNSFWQueryValid (value: any) { | |||
13 | return value === 'true' || value === 'false' || value === 'both' | 15 | return value === 'true' || value === 'false' || value === 'both' |
14 | } | 16 | } |
15 | 17 | ||
18 | function isSearchTargetValid (value: SearchTargetType) { | ||
19 | if (!exists(value)) return true | ||
20 | |||
21 | const searchIndexConfig = CONFIG.SEARCH.SEARCH_INDEX | ||
22 | |||
23 | if (value === 'local' && (!searchIndexConfig.ENABLED || !searchIndexConfig.DISABLE_LOCAL_SEARCH)) return true | ||
24 | |||
25 | if (value === 'search-index' && searchIndexConfig.ENABLED) return true | ||
26 | |||
27 | return false | ||
28 | } | ||
29 | |||
16 | // --------------------------------------------------------------------------- | 30 | // --------------------------------------------------------------------------- |
17 | 31 | ||
18 | export { | 32 | export { |
19 | isNumberArray, | 33 | isNumberArray, |
20 | isStringArray, | 34 | isStringArray, |
21 | isNSFWQueryValid | 35 | isNSFWQueryValid, |
36 | isSearchTargetValid | ||
22 | } | 37 | } |
diff --git a/server/middlewares/validators/search.ts b/server/middlewares/validators/search.ts index 5a3c83f2c..b4faa8894 100644 --- a/server/middlewares/validators/search.ts +++ b/server/middlewares/validators/search.ts | |||
@@ -3,6 +3,7 @@ import { areValidationErrors } from './utils' | |||
3 | import { logger } from '../../helpers/logger' | 3 | import { logger } from '../../helpers/logger' |
4 | import { query } from 'express-validator' | 4 | import { query } from 'express-validator' |
5 | import { isDateValid } from '../../helpers/custom-validators/misc' | 5 | import { isDateValid } from '../../helpers/custom-validators/misc' |
6 | import { isSearchTargetValid } from '@server/helpers/custom-validators/search' | ||
6 | 7 | ||
7 | const videosSearchValidator = [ | 8 | const videosSearchValidator = [ |
8 | query('search').optional().not().isEmpty().withMessage('Should have a valid search'), | 9 | query('search').optional().not().isEmpty().withMessage('Should have a valid search'), |
@@ -16,6 +17,8 @@ const videosSearchValidator = [ | |||
16 | query('durationMin').optional().isInt().withMessage('Should have a valid min duration'), | 17 | query('durationMin').optional().isInt().withMessage('Should have a valid min duration'), |
17 | query('durationMax').optional().isInt().withMessage('Should have a valid max duration'), | 18 | query('durationMax').optional().isInt().withMessage('Should have a valid max duration'), |
18 | 19 | ||
20 | query('searchTarget').optional().custom(isSearchTargetValid).withMessage('Should have a valid search target'), | ||
21 | |||
19 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 22 | (req: express.Request, res: express.Response, next: express.NextFunction) => { |
20 | logger.debug('Checking videos search query', { parameters: req.query }) | 23 | logger.debug('Checking videos search query', { parameters: req.query }) |
21 | 24 | ||
@@ -27,6 +30,7 @@ const videosSearchValidator = [ | |||
27 | 30 | ||
28 | const videoChannelsSearchValidator = [ | 31 | const videoChannelsSearchValidator = [ |
29 | query('search').not().isEmpty().withMessage('Should have a valid search'), | 32 | query('search').not().isEmpty().withMessage('Should have a valid search'), |
33 | query('searchTarget').optional().custom(isSearchTargetValid).withMessage('Should have a valid search target'), | ||
30 | 34 | ||
31 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | 35 | (req: express.Request, res: express.Response, next: express.NextFunction) => { |
32 | logger.debug('Checking video channels search query', { parameters: req.query }) | 36 | logger.debug('Checking video channels search query', { parameters: req.query }) |
diff --git a/server/tests/api/check-params/search.ts b/server/tests/api/check-params/search.ts index f8d0cd4ec..1a8a7235e 100644 --- a/server/tests/api/check-params/search.ts +++ b/server/tests/api/check-params/search.ts | |||
@@ -1,14 +1,32 @@ | |||
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ | 1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ |
2 | 2 | ||
3 | import 'mocha' | 3 | import 'mocha' |
4 | 4 | import { | |
5 | import { cleanupTests, flushAndRunServer, immutableAssign, makeGetRequest, ServerInfo } from '../../../../shared/extra-utils' | 5 | cleanupTests, |
6 | flushAndRunServer, | ||
7 | immutableAssign, | ||
8 | makeGetRequest, | ||
9 | ServerInfo, | ||
10 | updateCustomSubConfig, | ||
11 | setAccessTokensToServers | ||
12 | } from '../../../../shared/extra-utils' | ||
6 | import { | 13 | import { |
7 | checkBadCountPagination, | 14 | checkBadCountPagination, |
8 | checkBadSortPagination, | 15 | checkBadSortPagination, |
9 | checkBadStartPagination | 16 | checkBadStartPagination |
10 | } from '../../../../shared/extra-utils/requests/check-api-params' | 17 | } from '../../../../shared/extra-utils/requests/check-api-params' |
11 | 18 | ||
19 | function updateSearchIndex (server: ServerInfo, enabled: boolean, disableLocalSearch = false) { | ||
20 | return updateCustomSubConfig(server.url, server.accessToken, { | ||
21 | search: { | ||
22 | searchIndex: { | ||
23 | enabled, | ||
24 | disableLocalSearch | ||
25 | } | ||
26 | } | ||
27 | }) | ||
28 | } | ||
29 | |||
12 | describe('Test videos API validator', function () { | 30 | describe('Test videos API validator', function () { |
13 | let server: ServerInfo | 31 | let server: ServerInfo |
14 | 32 | ||
@@ -18,6 +36,7 @@ describe('Test videos API validator', function () { | |||
18 | this.timeout(30000) | 36 | this.timeout(30000) |
19 | 37 | ||
20 | server = await flushAndRunServer(1) | 38 | server = await flushAndRunServer(1) |
39 | await setAccessTokensToServers([ server ]) | ||
21 | }) | 40 | }) |
22 | 41 | ||
23 | describe('When searching videos', function () { | 42 | describe('When searching videos', function () { |
@@ -144,6 +163,62 @@ describe('Test videos API validator', function () { | |||
144 | }) | 163 | }) |
145 | }) | 164 | }) |
146 | 165 | ||
166 | describe('Search target', function () { | ||
167 | |||
168 | it('Should fail/succeed depending on the search target', async function () { | ||
169 | this.timeout(10000) | ||
170 | |||
171 | const query = { search: 'coucou' } | ||
172 | const paths = [ | ||
173 | '/api/v1/search/video-channels/', | ||
174 | '/api/v1/search/videos/' | ||
175 | ] | ||
176 | |||
177 | for (const path of paths) { | ||
178 | { | ||
179 | const customQuery = immutableAssign(query, { searchTarget: 'hello' }) | ||
180 | await makeGetRequest({ url: server.url, path, query: customQuery, statusCodeExpected: 400 }) | ||
181 | } | ||
182 | |||
183 | { | ||
184 | const customQuery = immutableAssign(query, { searchTarget: undefined }) | ||
185 | await makeGetRequest({ url: server.url, path, query: customQuery, statusCodeExpected: 200 }) | ||
186 | } | ||
187 | |||
188 | { | ||
189 | const customQuery = immutableAssign(query, { searchTarget: 'local' }) | ||
190 | await makeGetRequest({ url: server.url, path, query: customQuery, statusCodeExpected: 200 }) | ||
191 | } | ||
192 | |||
193 | { | ||
194 | const customQuery = immutableAssign(query, { searchTarget: 'search-index' }) | ||
195 | await makeGetRequest({ url: server.url, path, query: customQuery, statusCodeExpected: 400 }) | ||
196 | } | ||
197 | |||
198 | await updateSearchIndex(server, true, true) | ||
199 | |||
200 | { | ||
201 | const customQuery = immutableAssign(query, { searchTarget: 'local' }) | ||
202 | await makeGetRequest({ url: server.url, path, query: customQuery, statusCodeExpected: 400 }) | ||
203 | } | ||
204 | |||
205 | { | ||
206 | const customQuery = immutableAssign(query, { searchTarget: 'search-index' }) | ||
207 | await makeGetRequest({ url: server.url, path, query: customQuery, statusCodeExpected: 200 }) | ||
208 | } | ||
209 | |||
210 | await updateSearchIndex(server, true, false) | ||
211 | |||
212 | { | ||
213 | const customQuery = immutableAssign(query, { searchTarget: 'local' }) | ||
214 | await makeGetRequest({ url: server.url, path, query: customQuery, statusCodeExpected: 200 }) | ||
215 | } | ||
216 | |||
217 | await updateSearchIndex(server, false, false) | ||
218 | } | ||
219 | }) | ||
220 | }) | ||
221 | |||
147 | after(async function () { | 222 | after(async function () { |
148 | await cleanupTests([ server ]) | 223 | await cleanupTests([ server ]) |
149 | }) | 224 | }) |