diff --git a/controllers/uploadController.js b/controllers/uploadController.js index ec0736b..42358b4 100644 --- a/controllers/uploadController.js +++ b/controllers/uploadController.js @@ -4,6 +4,7 @@ const fs = require('fs') const path = require('path') const randomstring = require('randomstring') const searchQuery = require('search-query-parser') +const auth = require('./authController') const paths = require('./pathsController') const perms = require('./permissionController') const utils = require('./utilsController') @@ -263,12 +264,16 @@ self.parseStripTags = stripTags => { /** File uploads */ self.upload = async (req, res) => { - // Assert Request type - // Multipart for regular uploads, JSON for URL uploads - const isMultipart = req.is('multipart/form-data') - const isJson = req.is('application/json') - if (!isMultipart && !isJson) { - throw new ClientError('Request Content-Type must be either multipart/form-data or application/json.') + // Assert Request type (skip for POST /nojs requests) + let isMultipart = req.locals.nojs + let isJson + if (!req.locals.nojs) { + // Multipart for regular uploads, JSON for URL uploads + isMultipart = req.is('multipart/form-data') + isJson = req.is('application/json') + if (!isMultipart && !isJson) { + throw new ClientError('Request Content-Type must be either multipart/form-data or application/json.') + } } if (config.privateUploadGroup) { @@ -513,6 +518,18 @@ self.actuallyUpload = async (req, res, data = {}) => { return res.json({ success: true }) } + // If POST /nojs requests, additionally attempt to parse token from form input + if (req.locals.nojs) { + await new Promise((resolve, reject) => { + auth.optionalUser(req, res, error => { + if (error) return reject(error) + return resolve() + }, { + token: req.body.token + }) + }) + } + const filesData = req.files if (utils.scan.instance) { diff --git a/routes/nojs.js b/routes/nojs.js index b74593c..579717c 100644 --- a/routes/nojs.js +++ b/routes/nojs.js @@ -11,9 +11,16 @@ routes.get('/nojs', async (req, res) => { }) // HyperExpress defaults to 250kb -// https://github.com/kartikk221/hyper-express/blob/6.4.4/docs/Server.md#server-constructor-options -const maxBodyLength = parseInt(config.uploads.maxSize) * 1e6 -routes.post('/nojs', { max_body_length: maxBodyLength }, async (req, res) => { +// https://github.com/kartikk221/hyper-express/blob/6.4.8/docs/Server.md#server-constructor-options +routes.post('/nojs', { + max_body_length: parseInt(config.uploads.maxSize) * 1e6, + middlewares: [ + async (req, res) => { + // Assert Request type early + utils.assertRequestType(req, 'multipart/form-data') + } + ] +}, async (req, res) => { // Map built-in Response.json() function into Response.render() accordingly // Since NoJS uploader needs to reply with a complete HTML page res._json = res.json @@ -27,6 +34,11 @@ routes.post('/nojs', { max_body_length: maxBodyLength }, async (req, res) => { files: result.files || [{}] }) } + + // Indicate uploadController.js to additionally process this request further + // (skip request type assertion, parse token from form input, etc.) + req.locals.nojs = true + return upload.upload(req, res) }) diff --git a/views/nojs.njk b/views/nojs.njk index 967aac4..4e20734 100644 --- a/views/nojs.njk +++ b/views/nojs.njk @@ -3,14 +3,6 @@ {% extends "_layout.njk" %} -{% set private = config.private %} -{% set disabledMessage -%} - {%- if config.enableUserAccounts -%} - Anonymous upload is disabled. Log in to upload. - {%- else -%} - Running in private mode. Log in to upload. - {%- endif %} -{%- endset %} {% set maxSizeInt = config.uploads.maxSize | int %} {% set noJsMaxSizeInt = config.cloudflare.noJsMaxSize | int %} @@ -37,27 +29,26 @@
- {% if private -%} - - {{ disabledMessage }} - - {%- else -%}

+
+

+ +

+

- Files uploaded through this form will not be associated with your account, if you have any. + Files uploaded through this form will only be associated with your account if you specify your API token.

- {%- endif %} {% if files -%}
{% for file in files -%}