diff --git a/app/api.js b/app/api.js index 79a7785e..a816e63c 100644 --- a/app/api.js +++ b/app/api.js @@ -136,7 +136,14 @@ function listenForResponse(ws, canceller) { }); } -async function upload(stream, metadata, verifierB64, onprogress, canceller) { +async function upload( + stream, + metadata, + verifierB64, + timeLimit, + onprogress, + canceller +) { const host = window.location.hostname; const port = window.location.port; const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; @@ -151,7 +158,8 @@ async function upload(stream, metadata, verifierB64, onprogress, canceller) { const metadataHeader = arrayToB64(new Uint8Array(metadata)); const fileMeta = { fileMetadata: metadataHeader, - authorization: `send-v1 ${verifierB64}` + authorization: `send-v1 ${verifierB64}`, + timeLimit }; const responsePromise = listenForResponse(ws, canceller); @@ -188,7 +196,13 @@ async function upload(stream, metadata, verifierB64, onprogress, canceller) { } } -export function uploadWs(encrypted, metadata, verifierB64, onprogress) { +export function uploadWs( + encrypted, + metadata, + verifierB64, + onprogress, + timeLimit +) { const canceller = { cancelled: false }; return { @@ -196,7 +210,15 @@ export function uploadWs(encrypted, metadata, verifierB64, onprogress) { canceller.error = new Error(0); canceller.cancelled = true; }, - result: upload(encrypted, metadata, verifierB64, onprogress, canceller) + + result: upload( + encrypted, + metadata, + verifierB64, + timeLimit, + onprogress, + canceller + ) }; } diff --git a/app/base.css b/app/base.css index f30d5c63..c922a34e 100644 --- a/app/base.css +++ b/app/base.css @@ -276,7 +276,6 @@ a { } .stripedBox { - margin-top: 72; min-height: 400px; flex: 1; } @@ -289,3 +288,9 @@ a { margin: 15px; } } + +@media (max-device-width: 700px), (max-width: 700px) { + .stripedBox { + margin-top: 72px; + } +} diff --git a/app/fileManager.js b/app/fileManager.js index f294f199..204034ad 100644 --- a/app/fileManager.js +++ b/app/fileManager.js @@ -1,4 +1,5 @@ /* global MAXFILESIZE */ +/* global DEFAULT_EXPIRE_SECONDS */ import FileSender from './fileSender'; import FileReceiver from './fileReceiver'; import { copyToClipboard, delay, openLinksInNewTab, percent } from './utils'; @@ -110,7 +111,9 @@ export default function(state, emitter) { emitter.on('upload', async ({ type, dlCount, password }) => { if (!state.archive) return; const size = state.archive.size; - const sender = new FileSender(state.archive); + if (!state.timeLimit) state.timeLimit = DEFAULT_EXPIRE_SECONDS; + const sender = new FileSender(state.archive, state.timeLimit); + sender.on('progress', updateProgress); sender.on('encrypting', render); sender.on('complete', render); @@ -157,7 +160,7 @@ export default function(state, emitter) { } } finally { openLinksInNewTab(links, false); - state.files = []; + state.archive = null; state.password = ''; state.uploading = false; state.transfer = null; diff --git a/app/fileSender.js b/app/fileSender.js index d8ef3f8b..42d67e40 100644 --- a/app/fileSender.js +++ b/app/fileSender.js @@ -1,4 +1,4 @@ -/* global EXPIRE_SECONDS */ +/* global DEFAULT_EXPIRE_SECONDS */ import Nanobus from 'nanobus'; import OwnedFile from './ownedFile'; import Keychain from './keychain'; @@ -7,8 +7,9 @@ import { uploadWs } from './api'; import { encryptedSize } from './ece'; export default class FileSender extends Nanobus { - constructor(file) { + constructor(file, timeLimit) { super('FileSender'); + this.timeLimit = timeLimit || DEFAULT_EXPIRE_SECONDS; this.file = file; this.keychain = new Keychain(); this.reset(); @@ -70,10 +71,16 @@ export default class FileSender extends Nanobus { const metadata = await this.keychain.encryptMetadata(this.file); const authKeyB64 = await this.keychain.authKeyB64(); - this.uploadRequest = uploadWs(encStream, metadata, authKeyB64, p => { - this.progress = [p, totalSize]; - this.emit('progress'); - }); + this.uploadRequest = uploadWs( + encStream, + metadata, + authKeyB64, + p => { + this.progress = [p, totalSize]; + this.emit('progress'); + }, + this.timeLimit + ); if (this.cancelled) { throw new Error(0); @@ -97,10 +104,11 @@ export default class FileSender extends Nanobus { time: time, speed: this.file.size / (time / 1000), createdAt: Date.now(), - expiresAt: Date.now() + EXPIRE_SECONDS * 1000, + expiresAt: Date.now() + this.timeLimit * 1000, secretKey: secretKey, nonce: this.keychain.nonce, - ownerToken: result.ownerToken + ownerToken: result.ownerToken, + timeLimit: this.timeLimit }); return ownedFile; diff --git a/app/ownedFile.js b/app/ownedFile.js index 3cee3594..3b4dfbae 100644 --- a/app/ownedFile.js +++ b/app/ownedFile.js @@ -19,6 +19,7 @@ export default class OwnedFile { this.dtotal = obj.dtotal || 0; this.keychain = new Keychain(obj.secretKey, obj.nonce); this._hasPassword = !!obj.hasPassword; + this.timeLimit = obj.timeLimit; } async setPassword(password) { @@ -80,7 +81,8 @@ export default class OwnedFile { ownerToken: this.ownerToken, dlimit: this.dlimit, dtotal: this.dtotal, - hasPassword: this.hasPassword + hasPassword: this.hasPassword, + timeLimit: this.timeLimit }; } } diff --git a/app/pages/share/index.js b/app/pages/share/index.js index 8d72729b..153c3a98 100644 --- a/app/pages/share/index.js +++ b/app/pages/share/index.js @@ -1,10 +1,10 @@ -/* global EXPIRE_SECONDS */ const html = require('choo/html'); const raw = require('choo/html/raw'); const assets = require('../../../common/assets'); const notFound = require('../notFound'); const deletePopup = require('../../templates/popup'); const uploadedFileList = require('../../templates/uploadedFileList'); +const timeLimitText = require('../../templates/timeLimitText'); const { allowedCopy, delay, fadeOut } = require('../../utils'); module.exports = function(state, emit) { @@ -18,7 +18,6 @@ module.exports = function(state, emit) { : 'passwordReminder--hidden'; return html` -
@@ -98,13 +97,14 @@ module.exports = function(state, emit) { }; function expireInfo(file, translate) { - const hours = Math.floor(EXPIRE_SECONDS / 60 / 60); - const el = html`
${raw( - translate('expireInfo', { - downloadCount: translate('downloadCount', { num: file.dlimit }), - timespan: translate('timespanHours', { num: hours }) - }) - )}
`; + const el = html`
+ ${raw( + translate('expireInfo', { + downloadCount: translate('downloadCount', { num: file.dlimit }), + timespan: timeLimitText(translate, file.timeLimit) + }) + )} +
`; return el; } diff --git a/app/pages/welcome/index.js b/app/pages/welcome/index.js index c20a9965..ad818aa5 100644 --- a/app/pages/welcome/index.js +++ b/app/pages/welcome/index.js @@ -34,6 +34,7 @@ module.exports = function(state, emit) { ${title(state)}