Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge remote-tracking branch 'remotes/origin/feat/serverside-decrypt'
  • Loading branch information
psi-4ward committed May 25, 2022
2 parents f71dc94 + 886f6d6 commit 1aeb6f1
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 60 deletions.
90 changes: 38 additions & 52 deletions app/src/Download.vue
Expand Up @@ -14,10 +14,10 @@
p.text-danger(v-show='passwordWrong')
strong {{ $root.lang.accessDenied }}
|
button.decrypt.btn.btn-primary(:disabled='password.length<1', @click='decrypt()')
button.decrypt.btn.btn-primary(:disabled='password.length<1', @click='fetchBucket()')
icon.fa-fw(name="key")
| {{ $root.lang.decrypt }}
.panel.panel-primary(v-if='!needsPassword')
.panel.panel-primary(v-if='!needsPassword && !loading')
.panel-heading
strong {{ $root.lang.files }}
div.pull-right.btn-group.btn-download-archive(v-if="downloadsAvailable")
Expand Down Expand Up @@ -53,8 +53,6 @@

<script>
"use strict";
import AES from 'crypto-js/aes';
import encUtf8 from 'crypto-js/enc-utf8';
import MD5 from 'crypto-js/md5';
import FileIcon from './common/FileIcon.vue';
Expand Down Expand Up @@ -93,6 +91,7 @@
baseURI: this.$root.baseURI,
passwordWrong: false,
needsPassword: false,
loading: true,
password: '',
content: '',
error: '',
Expand Down Expand Up @@ -145,28 +144,6 @@
file.downloaded = $event === 'copied';
},
decrypt() {
this.passwordWrong = false;
this.files = this.files.map(item => {
if(typeof item === 'object') return item;
let f = AES.decrypt(item, this.password);
try {
f = JSON.parse(f.toString(encUtf8));
return Object.assign(f, {
downloaded: false,
previewType: getPreviewType(f, this.config.maxPreviewSize)
});
} catch(e) {
this.passwordWrong = true;
return item;
}
});
if(!this.passwordWrong) {
this.needsPassword = false;
this.password = '';
}
},
humanFileSize(fileSizeInBytes) {
let i = -1;
const byteUnits = [' kB', ' MB', ' GB', ' TB', 'PB', 'EB', 'ZB', 'YB'];
Expand All @@ -185,35 +162,44 @@
isFinite(value) {
if(typeof value !== 'number') return false;
return !(value !== value || value === Infinity || value === -Infinity);
}
},
},
beforeMount() {
const xhr = new XMLHttpRequest();
xhr.open('GET', this.sid + '.json');
xhr.onload = () => {
if(xhr.status === 200) {
try {
let data = JSON.parse(xhr.responseText);
this.config = data.config;
this.files = data.items.map(f => {
if(typeof f !== 'object') {
this.needsPassword = true;
return f;
}
return Object.assign(f, {
downloaded: false,
previewType: getPreviewType(f, this.config.maxPreviewSize)
fetchBucket() {
const xhr = new XMLHttpRequest();
xhr.open('GET', this.sid + '.json');
if(this.password) {
xhr.setRequestHeader('x-download-pass', this.password);
}
xhr.onload = () => {
if (xhr.status === 200) {
try {
let data = JSON.parse(xhr.responseText);
this.config = data.config;
this.files = data.items.map(f => {
return Object.assign(f, {
downloaded: false,
previewType: getPreviewType(f, this.config.maxPreviewSize)
});
});
});
} catch(e) {
this.error = e.toString();
this.loading = false;
this.needsPassword = false;
}
catch (e) {
this.error = e.toString();
}
} else if (xhr.status === 401) {
this.needsPassword = true;
this.loading = false;
} else {
this.error = `${ xhr.status } ${ xhr.statusText }: ${ xhr.responseText }`;
}
} else {
this.error = `${xhr.status} ${xhr.statusText}: ${xhr.responseText}`;
}
};
xhr.send();
};
xhr.send();
},
},
beforeMount() {
this.fetchBucket();
}
}
</script>
22 changes: 14 additions & 8 deletions lib/endpoints.js
Expand Up @@ -158,16 +158,22 @@ app.get(`${ config.baseUrl }:sid`, (req, res, next) => {
const sid = req.params.sid.substr(0, req.params.sid.length - 5);
if (!db.get(sid)) return res.status(404).end();

const downloadPassword = req.get('x-download-pass');
const items = db.get(sid).map(item => ({
...item,
url: `${ config.baseUrl }files/${ sid }++${ item.key }`
}));

res.header('Cache-control', 'private, max-age=0, no-cache, no-store, must-revalidate');

// Currently, every item in a bucket must have the same password
if(items.some(item => item.metadata.password && item.metadata.password !== downloadPassword)) {
setTimeout(() => res.status(401).send('Unauthorized'), 500);
return;
}

res.json({
items: db.get(sid).map(data => {
const item = Object.assign(data, { url: `${ config.baseUrl }files/${ sid }++${ data.key }` });
if (item.metadata.password) {
return AES.encrypt(JSON.stringify(data), item.metadata.password).toString();
} else {
return item;
}
}),
items,
config: {
maxPreviewSize: config.maxPreviewSize
}
Expand Down

0 comments on commit 1aeb6f1

Please sign in to comment.