From 65f074828b479b73ce5b44b702bfee5dbb194e41 Mon Sep 17 00:00:00 2001 From: Christoph Wiechert Date: Thu, 12 May 2022 12:17:21 +0200 Subject: [PATCH 1/2] Add dark-theme (closes #214) --- public/assets/styles.css | 88 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/public/assets/styles.css b/public/assets/styles.css index 72dc3da..a0025bd 100644 --- a/public/assets/styles.css +++ b/public/assets/styles.css @@ -154,3 +154,91 @@ h1 .fa-icon { .preview-modal .header .btn-group { margin-left: 15px; } + + +/* Dark Mode */ +@media (prefers-color-scheme: dark) { + body { + color: #e6e6e6; + background-color: #1B1E20; + } + + .panel { + background-color: #2A2E32; + } + + .panel-primary > .panel-heading { + background-color: #1d4c74; + color: inherit; + } + + .panel-info > .panel-heading { + background-color: #2e758a; + color: inherit; + } + + .panel-default > .panel-heading { + background-color: #3e3e3e; + color: inherit; + } + + .form-control[disabled], .form-control[readonly], fieldset[disabled] .form-control { + background-color: #585858; + } + + .btn-info { + background-color: #2e758a; + } + + .btn-success { + background-color: #1f761f; + } + + .text-success { + color: #4dd050; + } + + .well { + background-color: #2A2E32; + } + + a, a:hover, a:focus { + color: #48aaff; + } + + .close { + color: #fff; + opacity: 0.7; + } + + .form-control { + color: #fff; + background-color: #222; + } + + .table-hover > tbody > tr:hover { + background-color: #2b2b2b; + } + + .expanded { + background: #2A2E32 !important; + } + + .table-striped > tbody > tr:nth-of-type(2n+1) { + background-color: #2A2E32; + } + + .modal-content { + background-color: #282828; + } + + pre { + color: #fff; + background-color: #151515; + } + + .table > tbody > tr > td { + border-top: 1px solid #5F6265; + } + +} From 886f6d6ca5ed6273bf9826725a1bb170bf5990e9 Mon Sep 17 00:00:00 2001 From: Christoph Wiechert Date: Thu, 12 May 2022 12:18:12 +0200 Subject: [PATCH 2/2] Server-side password handling #176 --- app/src/Download.vue | 90 +++++++++++++++++++------------------------- lib/endpoints.js | 22 +++++++---- 2 files changed, 52 insertions(+), 60 deletions(-) diff --git a/app/src/Download.vue b/app/src/Download.vue index 91fedc0..718a60f 100644 --- a/app/src/Download.vue +++ b/app/src/Download.vue @@ -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") @@ -53,8 +53,6 @@ diff --git a/lib/endpoints.js b/lib/endpoints.js index 6d8e2d8..52f310c 100644 --- a/lib/endpoints.js +++ b/lib/endpoints.js @@ -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 }