diff options
Diffstat (limited to 'server/middlewares')
-rw-r--r-- | server/middlewares/validators/index.ts | 1 | ||||
-rw-r--r-- | server/middlewares/validators/oembed.ts | 63 |
2 files changed, 64 insertions, 0 deletions
diff --git a/server/middlewares/validators/index.ts b/server/middlewares/validators/index.ts index 418fa5f1d..068c41b24 100644 --- a/server/middlewares/validators/index.ts +++ b/server/middlewares/validators/index.ts | |||
@@ -1,3 +1,4 @@ | |||
1 | export * from './oembed' | ||
1 | export * from './remote' | 2 | export * from './remote' |
2 | export * from './pagination' | 3 | export * from './pagination' |
3 | export * from './pods' | 4 | export * from './pods' |
diff --git a/server/middlewares/validators/oembed.ts b/server/middlewares/validators/oembed.ts new file mode 100644 index 000000000..4b8c03faf --- /dev/null +++ b/server/middlewares/validators/oembed.ts | |||
@@ -0,0 +1,63 @@ | |||
1 | import { query } from 'express-validator/check' | ||
2 | import * as express from 'express' | ||
3 | import { join } from 'path' | ||
4 | |||
5 | import { checkErrors } from './utils' | ||
6 | import { CONFIG } from '../../initializers' | ||
7 | import { logger } from '../../helpers' | ||
8 | import { checkVideoExists, isVideoIdOrUUIDValid } from '../../helpers/custom-validators/videos' | ||
9 | import { isTestInstance } from '../../helpers/core-utils' | ||
10 | |||
11 | const urlShouldStartWith = CONFIG.WEBSERVER.SCHEME + '://' + join(CONFIG.WEBSERVER.HOST, 'videos', 'watch') + '/' | ||
12 | const videoWatchRegex = new RegExp('([^/]+)$') | ||
13 | const isURLOptions = { | ||
14 | require_host: true, | ||
15 | require_tld: true | ||
16 | } | ||
17 | |||
18 | // We validate 'localhost', so we don't have the top level domain | ||
19 | if (isTestInstance()) { | ||
20 | isURLOptions.require_tld = false | ||
21 | } | ||
22 | |||
23 | const oembedValidator = [ | ||
24 | query('url').isURL(isURLOptions).withMessage('Should have a valid url'), | ||
25 | query('maxwidth').optional().isInt().withMessage('Should have a valid max width'), | ||
26 | query('maxheight').optional().isInt().withMessage('Should have a valid max height'), | ||
27 | query('format').optional().isIn([ 'xml', 'json' ]).withMessage('Should have a valid format'), | ||
28 | |||
29 | (req: express.Request, res: express.Response, next: express.NextFunction) => { | ||
30 | logger.debug('Checking oembed parameters', { parameters: req.query }) | ||
31 | |||
32 | checkErrors(req, res, () => { | ||
33 | if (req.query.format !== undefined && req.query.format !== 'json') { | ||
34 | return res.status(501) | ||
35 | .json({ error: 'Requested format is not implemented on server.' }) | ||
36 | .end() | ||
37 | } | ||
38 | |||
39 | const startIsOk = req.query.url.startsWith(urlShouldStartWith) | ||
40 | const matches = videoWatchRegex.exec(req.query.url) | ||
41 | if (startIsOk === false || matches === null) { | ||
42 | return res.status(400) | ||
43 | .json({ error: 'Invalid url.' }) | ||
44 | .end() | ||
45 | } | ||
46 | |||
47 | const videoId = matches[1] | ||
48 | if (isVideoIdOrUUIDValid(videoId) === false) { | ||
49 | return res.status(400) | ||
50 | .json({ error: 'Invalid video id.' }) | ||
51 | .end() | ||
52 | } | ||
53 | |||
54 | checkVideoExists(videoId, res, next) | ||
55 | }) | ||
56 | } | ||
57 | ] | ||
58 | |||
59 | // --------------------------------------------------------------------------- | ||
60 | |||
61 | export { | ||
62 | oembedValidator | ||
63 | } | ||