123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- import assert from 'assert';
- import Archive from '../../../app/archive';
- import FileSender from '../../../app/fileSender';
- import FileReceiver from '../../../app/fileReceiver';
- import storage from '../../../app/storage';
- const headless = /Headless/.test(navigator.userAgent);
- // TODO: save on headless doesn't work as it used to since it now
- // follows a link instead of fetch. Maybe there's a way to make it
- // work? For now always set noSave.
- const options = { noSave: true || !headless, stream: true, storage }; // only run the saveFile code if headless
- // FileSender uses a File in real life but a Blob works for testing
- const blob = new Blob([new ArrayBuffer(1024 * 128)], { type: 'text/plain' });
- blob.name = 'test.txt';
- const archive = new Archive([blob]);
- navigator.serviceWorker.register('/serviceWorker.js');
- describe('Upload / Download flow', function() {
- this.timeout(0);
- it('can only download once by default', async function() {
- const fs = new FileSender();
- const file = await fs.upload(archive);
- const fr = new FileReceiver({
- secretKey: file.toJSON().secretKey,
- id: file.id,
- nonce: file.keychain.nonce,
- requiresPassword: false
- });
- await fr.getMetadata();
- await fr.download(options);
- try {
- await fr.download(options);
- assert.fail('downloaded again');
- } catch (e) {
- assert.equal(e.message, '404');
- }
- });
- it('downloads with the correct password', async function() {
- const fs = new FileSender();
- const file = await fs.upload(archive);
- await file.setPassword('magic');
- const fr = new FileReceiver({
- secretKey: file.toJSON().secretKey,
- id: file.id,
- url: file.url,
- nonce: file.keychain.nonce,
- requiresPassword: true,
- password: 'magic'
- });
- await fr.getMetadata();
- await fr.download(options);
- assert.equal(fr.state, 'complete');
- });
- it('blocks invalid passwords from downloading', async function() {
- const fs = new FileSender();
- const file = await fs.upload(archive);
- await file.setPassword('magic');
- const fr = new FileReceiver({
- secretKey: file.toJSON().secretKey,
- id: file.id,
- url: file.url,
- nonce: file.keychain.nonce,
- requiresPassword: true,
- password: 'password'
- });
- try {
- await fr.getMetadata();
- assert.fail('got metadata with bad password');
- } catch (e) {
- assert.equal(e.message, '401');
- }
- try {
- // We can't decrypt without IV from metadata
- // but let's try to download anyway
- await fr.download(options);
- assert.fail('downloaded file with bad password');
- } catch (e) {
- assert.equal(e.message, '401');
- }
- });
- it('retries a bad nonce', async function() {
- const fs = new FileSender();
- const file = await fs.upload(archive);
- const fr = new FileReceiver({
- secretKey: file.toJSON().secretKey,
- id: file.id,
- nonce: null, // oops
- requiresPassword: false
- });
- await fr.getMetadata();
- assert.equal(fr.fileInfo.name, archive.name);
- });
- it('can cancel the upload', async function() {
- const fs = new FileSender();
- const up = fs.upload(archive);
- fs.cancel(); // before encrypting
- try {
- await up;
- assert.fail('not cancelled 1');
- } catch (e) {
- assert.equal(e.message, '0');
- }
- fs.reset();
- fs.once('encrypting', () => fs.cancel());
- try {
- await fs.upload(archive);
- assert.fail('not cancelled 2');
- } catch (e) {
- assert.equal(e.message, '0');
- }
- fs.reset();
- fs.once('progress', () => fs.cancel());
- try {
- await fs.upload(archive);
- assert.fail('not cancelled 3');
- } catch (e) {
- assert.equal(e.message, '0');
- }
- });
- it('can cancel the download', async function() {
- const fs = new FileSender();
- const file = await fs.upload(archive);
- const fr = new FileReceiver({
- secretKey: file.toJSON().secretKey,
- id: file.id,
- nonce: file.keychain.nonce,
- requiresPassword: false
- });
- await fr.getMetadata();
- fr.once('progress', () => fr.cancel());
- try {
- await fr.download(options);
- assert.fail('not cancelled');
- } catch (e) {
- assert.equal(e.message, '0');
- }
- });
- it('can increase download count on download', async function() {
- this.timeout(0);
- const fs = new FileSender();
- const file = await fs.upload(archive);
- const fr = new FileReceiver({
- secretKey: file.toJSON().secretKey,
- id: file.id,
- nonce: file.keychain.nonce,
- requiresPassword: false
- });
- await fr.getMetadata();
- await fr.download(options);
- await file.updateDownloadCount();
- assert.equal(file.dtotal, 1);
- });
- it('does not increase download count when download cancelled', async function() {
- const fs = new FileSender();
- const file = await fs.upload(archive);
- const fr = new FileReceiver({
- secretKey: file.toJSON().secretKey,
- id: file.id,
- nonce: file.keychain.nonce,
- requiresPassword: false
- });
- await fr.getMetadata();
- fr.once('progress', () => fr.cancel());
- try {
- await fr.download(options);
- assert.fail('not cancelled');
- } catch (e) {
- await file.updateDownloadCount();
- assert.equal(file.dtotal, 0);
- }
- });
- it('can allow multiple downloads', async function() {
- const fs = new FileSender();
- const a = new Archive([blob]);
- a.dlimit = 2;
- const file = await fs.upload(a);
- const fr = new FileReceiver({
- secretKey: file.toJSON().secretKey,
- id: file.id,
- nonce: file.keychain.nonce,
- requiresPassword: false
- });
- await fr.getMetadata();
- await fr.download(options);
- await file.updateDownloadCount();
- assert.equal(file.dtotal, 1);
- await fr.download(options);
- await file.updateDownloadCount();
- assert.equal(file.dtotal, 2);
- try {
- await fr.download(options);
- assert.fail('downloaded too many times');
- } catch (e) {
- assert.equal(e.message, '404');
- }
- });
- it('can delete the file before download', async function() {
- const fs = new FileSender();
- const file = await fs.upload(archive);
- const fr = new FileReceiver({
- secretKey: file.toJSON().secretKey,
- id: file.id,
- nonce: file.keychain.nonce,
- requiresPassword: false
- });
- await file.del();
- try {
- await fr.getMetadata();
- assert.fail('file still exists');
- } catch (e) {
- assert.equal(e.message, '404');
- }
- });
- });
|