]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - server/helpers/express-utils.ts
Merge branch 'release/4.3.0' into develop
[github/Chocobozzz/PeerTube.git] / server / helpers / express-utils.ts
index 10a860787cf44bf8ded1b7c8d49d63fa61d66caa..82dd4c17807006dce47cdfa884974d62082a58f5 100644 (file)
@@ -1,14 +1,13 @@
-import * as express from 'express'
-import * as multer from 'multer'
-import { extname } from 'path'
-import { HttpStatusCode } from '../../shared/core-utils/miscs/http-error-codes'
+import express, { RequestHandler } from 'express'
+import multer, { diskStorage } from 'multer'
+import { getLowercaseExtension } from '@shared/core-utils'
+import { HttpStatusCode } from '../../shared/models/http/http-error-codes'
 import { CONFIG } from '../initializers/config'
 import { REMOTE_SCHEME } from '../initializers/constants'
 import { isArray } from './custom-validators/misc'
 import { logger } from './logger'
 import { deleteFileAndCatch, generateRandomString } from './utils'
 import { getExtFromMimetype } from './video'
-import { ProblemDocument, ProblemDocumentExtension } from 'http-problem-details'
 
 function buildNSFWFilter (res?: express.Response, paramNSFW?: string) {
   if (paramNSFW === 'true') return true
@@ -31,9 +30,7 @@ function buildNSFWFilter (res?: express.Response, paramNSFW?: string) {
   return null
 }
 
-function cleanUpReqFiles (
-  req: { files: { [fieldname: string]: Express.Multer.File[] } | Express.Multer.File[] }
-) {
+function cleanUpReqFiles (req: express.Request) {
   const filesObject = req.files
   if (!filesObject) return
 
@@ -62,7 +59,7 @@ function getHostWithPort (host: string) {
   return host
 }
 
-function badRequest (req: express.Request, res: express.Response) {
+function badRequest (_req: express.Request, res: express.Response) {
   return res.type('json')
             .status(HttpStatusCode.BAD_REQUEST_400)
             .end()
@@ -71,36 +68,15 @@ function badRequest (req: express.Request, res: express.Response) {
 function createReqFiles (
   fieldNames: string[],
   mimeTypes: { [id: string]: string | string[] },
-  destinations: { [fieldName: string]: string }
-) {
-  const storage = multer.diskStorage({
+  destination = CONFIG.STORAGE.TMP_DIR
+): RequestHandler {
+  const storage = diskStorage({
     destination: (req, file, cb) => {
-      cb(null, destinations[file.fieldname])
+      cb(null, destination)
     },
 
-    filename: async (req, file, cb) => {
-      let extension: string
-      const fileExtension = extname(file.originalname)
-      const extensionFromMimetype = getExtFromMimetype(mimeTypes, file.mimetype)
-
-      // Take the file extension if we don't understand the mime type
-      if (!extensionFromMimetype) {
-        extension = fileExtension
-      } else {
-        // Take the first available extension for this mimetype
-        extension = extensionFromMimetype
-      }
-
-      let randomString = ''
-
-      try {
-        randomString = await generateRandomString(16)
-      } catch (err) {
-        logger.error('Cannot generate random string for file name.', { err })
-        randomString = 'fake-random-string'
-      }
-
-      cb(null, randomString + extension)
+    filename: (req, file, cb) => {
+      return generateReqFilename(file, mimeTypes, cb)
     }
   })
 
@@ -115,6 +91,23 @@ function createReqFiles (
   return multer({ storage }).fields(fields)
 }
 
+function createAnyReqFiles (
+  mimeTypes: { [id: string]: string | string[] },
+  fileFilter: (req: express.Request, file: Express.Multer.File, cb: (err: Error, result: boolean) => void) => void
+): RequestHandler {
+  const storage = diskStorage({
+    destination: (req, file, cb) => {
+      cb(null, CONFIG.STORAGE.TMP_DIR)
+    },
+
+    filename: (req, file, cb) => {
+      return generateReqFilename(file, mimeTypes, cb)
+    }
+  })
+
+  return multer({ storage, fileFilter }).any()
+}
+
 function isUserAbleToSearchRemoteURI (res: express.Response) {
   const user = res.locals.oauth ? res.locals.oauth.token.User : undefined
 
@@ -126,43 +119,46 @@ function getCountVideos (req: express.Request) {
   return req.query.skipCount !== true
 }
 
-// helpers added in server.ts and used in subsequent controllers used
-const apiResponseHelpers = (req, res: express.Response, next = null) => {
-  res.fail = (options) => {
-    const { data, status = HttpStatusCode.BAD_REQUEST_400, message, title, type, docs = res.docs, instance } = options
-
-    const extension = new ProblemDocumentExtension({
-      ...data,
-      docs,
-      // fields for <= 3.2 compatibility, deprecated
-      error: message,
-      code: type
-    })
-
-    res.status(status)
-    res.setHeader('Content-Type', 'application/problem+json')
-    res.json(new ProblemDocument({
-      status,
-      title,
-      instance,
-      // fields intended to replace 'error' and 'code' respectively
-      detail: message,
-      type: type && 'https://docs.joinpeertube.org/api-rest-reference.html#section/Errors/' + type
-    }, extension))
-  }
-
-  if (next) next()
-}
-
 // ---------------------------------------------------------------------------
 
 export {
   buildNSFWFilter,
   getHostWithPort,
+  createAnyReqFiles,
   isUserAbleToSearchRemoteURI,
   badRequest,
   createReqFiles,
   cleanUpReqFiles,
-  getCountVideos,
-  apiResponseHelpers
+  getCountVideos
+}
+
+// ---------------------------------------------------------------------------
+
+async function generateReqFilename (
+  file: Express.Multer.File,
+  mimeTypes: { [id: string]: string | string[] },
+  cb: (err: Error, name: string) => void
+) {
+  let extension: string
+  const fileExtension = getLowercaseExtension(file.originalname)
+  const extensionFromMimetype = getExtFromMimetype(mimeTypes, file.mimetype)
+
+  // Take the file extension if we don't understand the mime type
+  if (!extensionFromMimetype) {
+    extension = fileExtension
+  } else {
+    // Take the first available extension for this mimetype
+    extension = extensionFromMimetype
+  }
+
+  let randomString = ''
+
+  try {
+    randomString = await generateRandomString(16)
+  } catch (err) {
+    logger.error('Cannot generate random string for file name.', { err })
+    randomString = 'fake-random-string'
+  }
+
+  cb(null, randomString + extension)
 }