diff --git a/app/routes/upload.js b/app/routes/upload.js index 2ba637a..e96666f 100644 --- a/app/routes/upload.js +++ b/app/routes/upload.js @@ -2,22 +2,24 @@ const express = require('express'); const router = express.Router(); const config = require('config'); +const fsPromises = require('fs').promises; + const ModelPath = '../models/'; const User = require(ModelPath + 'User.js'); const Upload = require(ModelPath + 'Upload.js'); const Key = require(ModelPath + 'Key.js'); +const verifyScope = require('../util/verifyScope.js'); + const multer = require('multer'); const fileUpload = multer({dest: config.get('Upload.path')}).single('file'); -const fsPromises = require('fs').promises; -const requireAuth = require('../util/requireAuth'); const wrap = require('../util/wrap.js'); const generatedIdExists = async id => await Upload.countDocuments({id: id}) === 1; -const generateId = async () => { +const generateId = async() => { const charset = config.get('Upload.charset'); const len = config.get('Upload.idLength'); @@ -39,7 +41,37 @@ const updateStats = async req => ]); -router.post('/', requireAuth('file.upload'), fileUpload, wrap(async (req, res) => { +router.post('/', fileUpload, wrap(async(req, res) => { + // We need to authenticate in place because the form data needs to be processed by multer first + const deleteAndError = async (code, message) => { + if (req.file) + await fsPromises.unlink(req.file.path); + res.status(code).json({message: message}); + }; + + if (req.isAuthenticated()) { + if (verifyScope(req.session.passport.scope, 'file.upload')) { + req.username = req.session.passport.user; + req.displayname = req.session.passport.displayname; + req.scope = req.session.passport.scope; + req.key = null; + } else { + return await deleteAndError(403, 'Forbidden.'); + } + } else if (req.body.key) { + const key = await Key.findOne({key: req.body.key}); + if (verifyScope(key.scope, 'file.upload')) { + req.username = key.issuer; + req.displayname = key.issuer; + req.scope = key.scope; + req.key = key.key; + } else { + return await deleteAndError(403, 'Forbidden.'); + } + } else { + return await deleteAndError(401, 'Unauthorized.'); + } + if (!req.file) return res.status(400).json({message: 'No file specified.'}); diff --git a/app/util/requireAuth.js b/app/util/requireAuth.js index 6cdb0d8..27881e0 100644 --- a/app/util/requireAuth.js +++ b/app/util/requireAuth.js @@ -1,7 +1,7 @@ const Key = require('../models/Key.js'); const wrap = require('./wrap.js'); -const verifyScope = (scope, requiredScope) => scope.indexOf(requiredScope) !== -1; +const verifyScope = require('./verifyScope.js'); // Checks for authentication by either API Key or Session // Sets body.authUser and body.authKey if check passed @@ -20,11 +20,11 @@ const requireAuth = scope => } else { res.status(403).json({message: 'Forbidden.'}); } - } else if (req.body.apikey) { - const key = await Key.findOne({key: apikey}); + } else if (req.body.key) { + const key = await Key.findOne({key: key}); if (scope ? verifyScope(key.scope, scope) : true) { - req.username = key.username; - req.displayname = key.username; + req.username = key.issuer; + req.displayname = key.issuer; req.scope = key.scope; req.key = key.key; next(); diff --git a/app/util/verifyScope.js b/app/util/verifyScope.js new file mode 100644 index 0000000..67f988f --- /dev/null +++ b/app/util/verifyScope.js @@ -0,0 +1,3 @@ +const verifyScope = (scope, requiredScope) => scope.indexOf(requiredScope) !== -1; + +module.exports = verifyScope;