diff --git a/frontend/src/download.js b/frontend/src/download.js index 01aef44b..21819bd6 100644 --- a/frontend/src/download.js +++ b/frontend/src/download.js @@ -57,7 +57,8 @@ function download() { } throw err; }) - .then(([decrypted, fname]) => { + .then(([decrypted, file]) => { + const fname = file.name; const endTime = Date.now(); const time = endTime - startTime; const downloadTime = endTime - downloadEnd; @@ -73,7 +74,7 @@ function download() { }); const dataView = new DataView(decrypted); - const blob = new Blob([dataView]); + const blob = new Blob([dataView], { type: file.type }); const downloadUrl = URL.createObjectURL(blob); const a = document.createElement('a'); diff --git a/frontend/src/fileReceiver.js b/frontend/src/fileReceiver.js index b3215146..c93d7eba 100644 --- a/frontend/src/fileReceiver.js +++ b/frontend/src/fileReceiver.js @@ -39,13 +39,15 @@ class FileReceiver extends EventEmitter { } const blob = new Blob([this.response]); + const type = xhr.getResponseHeader('Content-Type'); + const meta = JSON.parse(xhr.getResponseHeader('X-File-Metadata')); const fileReader = new FileReader(); fileReader.onload = function() { - const meta = JSON.parse(xhr.getResponseHeader('X-File-Metadata')); resolve([ { data: this.result, filename: meta.filename, + type, iv: meta.id }, key @@ -76,7 +78,10 @@ class FileReceiver extends EventEmitter { .then(decrypted => { return Promise.resolve(decrypted); }), - decodeURIComponent(fdata.filename) + { + name: decodeURIComponent(fdata.filename), + type: fdata.type + } ]); }); } diff --git a/server/server.js b/server/server.js index e843ef05..ed430c47 100644 --- a/server/server.js +++ b/server/server.js @@ -168,7 +168,7 @@ app.get('/assets/download/:id', async (req, res) => { const contentLength = await storage.length(id); res.writeHead(200, { 'Content-Disposition': `attachment; filename=${meta.filename}`, - 'Content-Type': 'application/octet-stream', + 'Content-Type': meta.mimeType, 'Content-Length': contentLength, 'X-File-Metadata': JSON.stringify(meta) }); @@ -236,24 +236,27 @@ app.post('/upload', (req, res, next) => { meta.delete = crypto.randomBytes(10).toString('hex'); req.pipe(req.busboy); - req.busboy.on('file', async (fieldname, file, filename) => { - try { - await storage.set(newId, file, filename, meta); - - const protocol = conf.env === 'production' ? 'https' : req.protocol; - const url = `${protocol}://${req.get('host')}/download/${newId}/`; - res.json({ - url, - delete: meta.delete, - id: newId - }); - } catch (e) { - if (e.message === 'limit') { - return res.sendStatus(413); + req.busboy.on( + 'file', + async (fieldname, file, filename, encoding, mimeType) => { + try { + meta.mimeType = mimeType || 'application/octet-stream'; + await storage.set(newId, file, filename, meta); + const protocol = conf.env === 'production' ? 'https' : req.protocol; + const url = `${protocol}://${req.get('host')}/download/${newId}/`; + res.json({ + url, + delete: meta.delete, + id: newId + }); + } catch (e) { + if (e.message === 'limit') { + return res.sendStatus(413); + } + res.sendStatus(500); } - res.sendStatus(500); } - }); + ); req.on('close', async err => { try { diff --git a/test/server/server.test.js b/test/server/server.test.js index 627c3a9b..9402c7cf 100644 --- a/test/server/server.test.js +++ b/test/server/server.test.js @@ -163,7 +163,7 @@ describe('Server integration tests', function() { res.header['content-disposition'], 'attachment; filename=test_upload.txt' ); - assert.equal(res.header['content-type'], 'application/octet-stream'); + assert.equal(res.header['content-type'], 'text/plain'); }); }); diff --git a/webpack.config.js b/webpack.config.js index 904ea595..434925a5 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -14,8 +14,15 @@ module.exports = { { test: /\.js$/, loaders: 'babel-loader', - include: [path.resolve(__dirname, 'frontend'), path.resolve(__dirname, 'node_modules/testpilot-ga/src')], - query: { babelrc: false, presets: ['es2015', 'stage-2'], plugins: ['add-module-exports'] } + include: [ + path.resolve(__dirname, 'frontend'), + path.resolve(__dirname, 'node_modules/testpilot-ga/src') + ], + query: { + babelrc: false, + presets: ['es2015', 'stage-2'], + plugins: ['add-module-exports'] + } } ] }