fox-send/app/fileSender.js

106 lines
2.7 KiB
JavaScript
Raw Normal View History

2018-01-24 18:23:13 +00:00
/* global EXPIRE_SECONDS */
import Nanobus from 'nanobus';
2018-01-24 18:23:13 +00:00
import OwnedFile from './ownedFile';
import Keychain from './keychain';
import { arrayToB64, bytes } from './utils';
import { uploadFile } from './api';
export default class FileSender extends Nanobus {
2017-06-02 03:59:27 +00:00
constructor(file) {
super('FileSender');
2017-06-02 03:59:27 +00:00
this.file = file;
2018-01-24 18:23:13 +00:00
this.uploadRequest = null;
this.msg = 'importingFile';
this.progress = [0, 1];
this.cancelled = false;
2018-01-24 18:23:13 +00:00
this.keychain = new Keychain();
2017-06-02 03:59:27 +00:00
}
get progressRatio() {
return this.progress[0] / this.progress[1];
}
get sizes() {
return {
partialSize: bytes(this.progress[0]),
totalSize: bytes(this.progress[1])
};
}
2017-07-18 17:52:32 +00:00
cancel() {
this.cancelled = true;
2018-01-24 18:23:13 +00:00
if (this.uploadRequest) {
this.uploadRequest.cancel();
}
2017-07-18 17:52:32 +00:00
}
2017-08-14 19:04:03 +00:00
readFile() {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsArrayBuffer(this.file);
2018-01-24 18:23:13 +00:00
// TODO: progress?
2017-08-14 19:04:03 +00:00
reader.onload = function(event) {
const plaintext = new Uint8Array(this.result);
resolve(plaintext);
};
reader.onerror = function(err) {
reject(err);
};
});
}
2017-06-02 03:59:27 +00:00
2018-01-31 19:12:36 +00:00
async upload() {
2018-01-24 18:23:13 +00:00
const start = Date.now();
2017-08-14 19:04:03 +00:00
const plaintext = await this.readFile();
if (this.cancelled) {
throw new Error(0);
}
this.msg = 'encryptingFile';
2017-08-14 19:04:03 +00:00
this.emit('encrypting');
2018-01-24 18:23:13 +00:00
const encrypted = await this.keychain.encryptFile(plaintext);
const metadata = await this.keychain.encryptMetadata(this.file);
const authKeyB64 = await this.keychain.authKeyB64();
if (this.cancelled) {
throw new Error(0);
}
2018-01-24 18:23:13 +00:00
this.uploadRequest = uploadFile(
encrypted,
metadata,
authKeyB64,
this.keychain
2018-01-14 14:49:10 +00:00
);
2018-01-24 18:23:13 +00:00
this.msg = 'fileSizeProgress';
this.uploadRequest.onprogress = p => {
this.progress = p;
this.emit('progress', p);
};
try {
2018-01-24 18:23:13 +00:00
const result = await this.uploadRequest.result;
const time = Date.now() - start;
this.msg = 'notifyUploadDone';
this.uploadRequest = null;
this.progress = [1, 1];
const secretKey = arrayToB64(this.keychain.rawSecret);
2018-01-31 19:12:36 +00:00
const ownedFile = new OwnedFile({
id: result.id,
url: `${result.url}#${secretKey}`,
name: this.file.name,
size: this.file.size,
type: this.file.type, //TODO 'click' ?
time: time,
speed: this.file.size / (time / 1000),
createdAt: Date.now(),
expiresAt: Date.now() + EXPIRE_SECONDS * 1000,
secretKey: secretKey,
nonce: this.keychain.nonce,
ownerToken: result.ownerToken
});
2018-01-24 18:23:13 +00:00
return ownedFile;
} catch (e) {
2018-01-24 18:23:13 +00:00
this.msg = 'errorPageHeader';
this.uploadRequest = null;
throw e;
}
2017-06-02 03:59:27 +00:00
}
}