Implemented file downloads

This commit is contained in:
Mark van Renswoude 2018-04-26 16:34:07 +02:00
parent 9defe0746f
commit 5d454ea7c7
4 changed files with 77 additions and 12 deletions

View File

@ -11,6 +11,7 @@ const tus = require('tus-node-server');
const jwt = require('jsonwebtoken');
const path = require('path');
const resolvePath = require('resolve-path');
const cookieParser = require('cookie-parser');
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');
@ -38,6 +39,7 @@ const webpackConfig = require('./webpack.config.js');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(cookieParser());

View File

@ -2,18 +2,36 @@ const config = require('../../config');
const express = require('Express');
const asyncHandler = require('express-async-handler');
const jwt = require('jsonwebtoken');
const path = require('path');
const resolvePath = require('resolve-path');
const AuthTokens = require('../authtokens');
async function checkAuthorization(req, res, repository, onVerified)
{
if (!req.headers.authorization || req.headers.authorization.split(' ')[0] !== 'Bearer')
var token;
if (req.headers.authorization)
{
res.sendStatus(400);
if (req.headers.authorization.split(' ')[0] !== 'Bearer')
{
res.sendStatus(400);
return;
}
token = req.headers.authorization.split(' ')[1];
}
else if (req.cookies && req.cookies.token)
{
token = req.cookies.token;
}
else
{
res.sendStatus(403);
return;
}
var token = req.headers.authorization.split(' ')[1];
jwt.verify(token, config.jwtSecret, async (err, decoded) =>
{
try
@ -100,5 +118,18 @@ module.exports = (repository) =>
}));
router.get('/download/:fileid/:displayname', asyncHandler(async (req, res) =>
{
await checkAuthorization(req, res, repository, async (user) =>
{
// TODO should we check if the user has access to the file?
// for now not that important, if you know the file's UID and are logged in
var fullpath = resolvePath(config.fileUpload.path, req.params.fileid);
res.download(fullpath, req.params.displayname);
});
}));
return router;
}

View File

@ -18,6 +18,7 @@
"async-retry": "^1.2.1",
"bcrypt": "^1.0.3",
"body-parser": "^1.18.2",
"cookie-parser": "^1.4.3",
"debug": "^3.1.0",
"express": "^4.16.3",
"express-async-handler": "^1.1.2",

View File

@ -13,10 +13,12 @@
<div class="pure-g row">
<div class="pure-u-3-4">{{ upload.created }}</div>
<div class="pure-u-1-4">{{ upload.username }}</div>
<div class="pure-u-1-1" v-for="file in upload.files">
<div class="file">
<img :src="getFileIconUrl(file.name)">
{{ file.name }}
<div class="pure-u-1-1">
<div class="file" v-for="file in upload.files" :title="file.name">
<a :href="getDownloadUrl(file)">
<img :src="getFileIconUrl(file.name)" class="icon">
<span class="filename">{{ file.name }}</span>
</a>
</div>
</div>
</div>
@ -86,13 +88,24 @@ export default {
methods: {
getFileIconUrl(filename)
{
var ext = '_blank';
var parts = filename.split('.');
if (parts.length > 0)
ext = parts.pop();
var ext = this.getExtension(filename);
if (ext == '')
ext = '_blank';
return '/images/fileicons/32px/' + ext + '.png';
},
getExtension(filename)
{
var parts = filename.split('.');
return parts.length > 0 ? parts.pop() : '';
},
getDownloadUrl(file)
{
return '/admin/download/' + encodeURIComponent(file.id) + '/' + encodeURIComponent(file.name);
}
}
}
@ -101,6 +114,24 @@ export default {
<style lang="scss">
.file
{
display: inline-block;
width: 10rem;
padding: .5rem;
font-size: 75%;
text-align: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
.icon
{
display: block;
margin-bottom: .5rem;
margin-left: auto;
margin-right: auto;
}
}
</style>