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