drop.chapril.org-firefoxsend/app/fileSender.js

109 lines
2.7 KiB
JavaScript
Raw Normal View History

import Nanobus from 'nanobus';
2018-01-24 19:23:13 +01:00
import OwnedFile from './ownedFile';
import Keychain from './keychain';
import { arrayToB64, bytes } from './utils';
2018-06-21 02:05:33 +02:00
import { uploadWs } from './api';
2018-07-26 07:26:11 +02:00
import { encryptedSize } from './ece';
export default class FileSender extends Nanobus {
2018-08-31 23:20:15 +02:00
constructor() {
super('FileSender');
2018-01-24 19:23:13 +01:00
this.keychain = new Keychain();
this.reset();
2017-06-02 05:59:27 +02:00
}
get progressRatio() {
return this.progress[0] / this.progress[1];
}
2018-02-21 22:59:06 +01:00
get progressIndefinite() {
2019-02-22 16:42:08 +01:00
return (
['fileSizeProgress', 'notifyUploadEncryptDone'].indexOf(this.msg) === -1
);
2018-02-21 22:59:06 +01:00
}
get sizes() {
return {
partialSize: bytes(this.progress[0]),
totalSize: bytes(this.progress[1])
};
}
reset() {
this.uploadRequest = null;
this.msg = 'importingFile';
this.progress = [0, 1];
this.cancelled = false;
}
2017-07-18 19:52:32 +02:00
cancel() {
this.cancelled = true;
2018-01-24 19:23:13 +01:00
if (this.uploadRequest) {
this.uploadRequest.cancel();
}
2017-07-18 19:52:32 +02:00
}
2019-02-12 20:50:06 +01:00
async upload(archive, bearerToken) {
2018-01-24 19:23:13 +01:00
const start = Date.now();
if (this.cancelled) {
throw new Error(0);
}
this.msg = 'encryptingFile';
2017-08-14 21:04:03 +02:00
this.emit('encrypting');
2019-02-12 20:50:06 +01:00
const totalSize = encryptedSize(archive.size);
const encStream = await this.keychain.encryptStream(archive.stream);
const metadata = await this.keychain.encryptMetadata(archive);
2018-01-24 19:23:13 +01:00
const authKeyB64 = await this.keychain.authKeyB64();
2018-06-21 02:05:33 +02:00
2018-08-08 20:07:09 +02:00
this.uploadRequest = uploadWs(
encStream,
metadata,
authKeyB64,
2019-02-12 20:50:06 +01:00
archive.timeLimit,
archive.dlimit,
2018-08-31 23:20:15 +02:00
bearerToken,
2018-08-08 20:07:09 +02:00
p => {
this.progress = [p, totalSize];
this.emit('progress');
2018-08-08 00:40:17 +02:00
}
2018-08-08 20:07:09 +02:00
);
2018-06-21 02:05:33 +02:00
if (this.cancelled) {
throw new Error(0);
}
2018-01-24 19:23:13 +01:00
this.msg = 'fileSizeProgress';
2018-03-12 20:24:09 +01:00
this.emit('progress'); // HACK to kick MS Edge
try {
2018-01-24 19:23:13 +01:00
const result = await this.uploadRequest.result;
const time = Date.now() - start;
2019-02-22 16:42:08 +01:00
this.msg = 'notifyUploadEncryptDone';
2018-01-24 19:23:13 +01:00
this.uploadRequest = null;
this.progress = [1, 1];
const secretKey = arrayToB64(this.keychain.rawSecret);
2018-01-31 20:12:36 +01:00
const ownedFile = new OwnedFile({
id: result.id,
url: `${result.url}#${secretKey}`,
2019-02-12 20:50:06 +01:00
name: archive.name,
size: archive.size,
manifest: archive.manifest,
2018-01-31 20:12:36 +01:00
time: time,
2019-02-12 20:50:06 +01:00
speed: archive.size / (time / 1000),
2018-01-31 20:12:36 +01:00
createdAt: Date.now(),
2019-02-12 20:50:06 +01:00
expiresAt: Date.now() + archive.timeLimit * 1000,
2018-01-31 20:12:36 +01:00
secretKey: secretKey,
nonce: this.keychain.nonce,
2018-08-08 20:07:09 +02:00
ownerToken: result.ownerToken,
2019-02-12 20:50:06 +01:00
dlimit: archive.dlimit,
timeLimit: archive.timeLimit
2018-01-31 20:12:36 +01:00
});
2018-07-31 20:09:18 +02:00
2018-01-24 19:23:13 +01:00
return ownedFile;
} catch (e) {
2018-01-24 19:23:13 +01:00
this.msg = 'errorPageHeader';
this.uploadRequest = null;
throw e;
}
2017-06-02 05:59:27 +02:00
}
}