Add ability to skip count query
[oweals/peertube.git] / server / helpers / express-utils.ts
1 import * as express from 'express'
2 import * as multer from 'multer'
3 import { REMOTE_SCHEME } from '../initializers/constants'
4 import { logger } from './logger'
5 import { deleteFileAsync, generateRandomString } from './utils'
6 import { extname } from 'path'
7 import { isArray } from './custom-validators/misc'
8 import { CONFIG } from '../initializers/config'
9
10 function buildNSFWFilter (res?: express.Response, paramNSFW?: string) {
11   if (paramNSFW === 'true') return true
12   if (paramNSFW === 'false') return false
13   if (paramNSFW === 'both') return undefined
14
15   if (res && res.locals.oauth) {
16     const user = res.locals.oauth.token.User
17
18     // User does not want NSFW videos
19     if (user.nsfwPolicy === 'do_not_list') return false
20
21     // Both
22     return undefined
23   }
24
25   if (CONFIG.INSTANCE.DEFAULT_NSFW_POLICY === 'do_not_list') return false
26
27   // Display all
28   return null
29 }
30
31 function cleanUpReqFiles (req: { files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[] }) {
32   const files = req.files
33
34   if (!files) return
35
36   if (isArray(files)) {
37     (files as Express.Multer.File[]).forEach(f => deleteFileAsync(f.path))
38     return
39   }
40
41   for (const key of Object.keys(files)) {
42     const file = files[ key ]
43
44     if (isArray(file)) file.forEach(f => deleteFileAsync(f.path))
45     else deleteFileAsync(file.path)
46   }
47 }
48
49 function getHostWithPort (host: string) {
50   const splitted = host.split(':')
51
52   // The port was not specified
53   if (splitted.length === 1) {
54     if (REMOTE_SCHEME.HTTP === 'https') return host + ':443'
55
56     return host + ':80'
57   }
58
59   return host
60 }
61
62 function badRequest (req: express.Request, res: express.Response) {
63   return res.type('json').status(400).end()
64 }
65
66 function createReqFiles (
67   fieldNames: string[],
68   mimeTypes: { [ id: string ]: string },
69   destinations: { [ fieldName: string ]: string }
70 ) {
71   const storage = multer.diskStorage({
72     destination: (req, file, cb) => {
73       cb(null, destinations[ file.fieldname ])
74     },
75
76     filename: async (req, file, cb) => {
77       let extension: string
78       const fileExtension = extname(file.originalname)
79       const extensionFromMimetype = mimeTypes[ file.mimetype ]
80
81       // Take the file extension if we don't understand the mime type
82       // We have the OGG/OGV exception too because firefox sends a bad mime type when sending an OGG file
83       if (fileExtension === '.ogg' || fileExtension === '.ogv' || !extensionFromMimetype) {
84         extension = fileExtension
85       } else {
86         extension = extensionFromMimetype
87       }
88
89       let randomString = ''
90
91       try {
92         randomString = await generateRandomString(16)
93       } catch (err) {
94         logger.error('Cannot generate random string for file name.', { err })
95         randomString = 'fake-random-string'
96       }
97
98       cb(null, randomString + extension)
99     }
100   })
101
102   let fields: { name: string, maxCount: number }[] = []
103   for (const fieldName of fieldNames) {
104     fields.push({
105       name: fieldName,
106       maxCount: 1
107     })
108   }
109
110   return multer({ storage }).fields(fields)
111 }
112
113 function isUserAbleToSearchRemoteURI (res: express.Response) {
114   const user = res.locals.oauth ? res.locals.oauth.token.User : undefined
115
116   return CONFIG.SEARCH.REMOTE_URI.ANONYMOUS === true ||
117     (CONFIG.SEARCH.REMOTE_URI.USERS === true && user !== undefined)
118 }
119
120 function getCountVideos (req: express.Request) {
121   return req.query.skipCount !== true
122 }
123
124 // ---------------------------------------------------------------------------
125
126 export {
127   buildNSFWFilter,
128   getHostWithPort,
129   isUserAbleToSearchRemoteURI,
130   badRequest,
131   createReqFiles,
132   cleanUpReqFiles,
133   getCountVideos
134 }