Skip to content

Commit

Permalink
Stream encryption (#39)
Browse files Browse the repository at this point in the history
* fixed verbage - was copy/pasta from rm command

* got package updated

* now clearing log-update package when logging in case we log during a progress bar (or spinner) event

* now ask for confirmation before executing 'delete-everything' command

* added description to usage output for commands, added options to encrypt/decrypt uploads and downloads

* added support to encrypt and decrypt upload and download streams with a password

* updated changelog with encryption info
  • Loading branch information
alex-phillips authored Dec 8, 2016
1 parent c8164ea commit cc7f11f
Show file tree
Hide file tree
Showing 9 changed files with 485 additions and 331 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ All Notable changes to `clouddrive-node` will be documented in this file
- Now using custom progress bar since others were either broken in some way or no longer maintained
- `UploadCommand` now supports the `--checksum` option in addition to the default config value
- `delete-everything` command now used to delete all CLI files and folders
- `upload` and `download` now supports encryption

### Breaking Changes
- `cache` and `config` directories are now stored using the [env-paths](https://github.com/sindresorhus/env-paths) package. NOTE: you will need to either manually move your existing files or re-run `init` and `sync` with this new version.
Expand Down
54 changes: 34 additions & 20 deletions lib/Commands/DeleteEverythingCommand.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,47 @@ let Command = require('./Command'),
Node = require('../Node'),
Logger = require('../Logger'),
async = require('async'),
fs = require('fs-extra');
fs = require('fs-extra'),
inquirer = require('inquirer');

class DeleteEverythingCommand extends Command {
run(args, options) {
return new Promise((resolve, reject) => {
Command.startSpinner('Removing all files and folders');
async.waterfall([
callback => {
Logger.verbose(`Removing cache directory ${Command.getCacheDirectory()}`);
fs.remove(Command.getCacheDirectory(), callback);
},
callback => {
Logger.verbose(`Removing config directory ${Command.getConfigDirectory()}`);
fs.remove(Command.getConfigDirectory(), callback);
},
callback => {
Logger.verbose(`Removing log directory ${Command.getLogDirectory()}`);
fs.remove(Command.getLogDirectory(), callback);
},
], err => {
if (err) {
return reject(err);
inquirer.prompt([
{
type: 'confirm',
name: 'confirm',
message: 'really delete everything? ',
default: false,
}
], answers => {
if (!answers.confirm) {
return resolve();
}

Command.startSpinner('Removing all files and folders');
async.waterfall([
callback => {
Logger.verbose(`Removing cache directory ${Command.getCacheDirectory()}`);
fs.remove(Command.getCacheDirectory(), callback);
},
callback => {
Logger.verbose(`Removing config directory ${Command.getConfigDirectory()}`);
fs.remove(Command.getConfigDirectory(), callback);
},
callback => {
Logger.verbose(`Removing log directory ${Command.getLogDirectory()}`);
fs.remove(Command.getLogDirectory(), callback);
},
], err => {
if (err) {
return reject(err);
}

Command.stopSpinner('Done.');
Command.stopSpinner('Done.');

return resolve();
return resolve();
});
});
});
}
Expand Down
152 changes: 87 additions & 65 deletions lib/Commands/DownloadCommand.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ let Command = require('./Command'),
Utils = require('../Utils'),
Logger = require('../Logger'),
ProgressBar = require('../ProgressBar'),
async = require('async'),
inquirer = require('inquirer'),
logUpdate = require('log-update');

class DownloadCommand extends Command {
Expand Down Expand Up @@ -52,82 +54,102 @@ class DownloadCommand extends Command {
remote: options.remote,
queryParams: queryParams,
checkMd5: this.config.get('download.checkMd5'),
decrypt: options.decrypt || false,
};

node.on('fileDownload', node => {
if (this.config.get('cli.progressBars')) {
startTime = Date.now();
bytesDownloaded = 0;
downloadingNode = node;
lastRun = Date.now();
bar = new ProgressBar(`Downloading ${downloadingNode.getName()}\n:percent[:bar] :speed eta :etas (:downloaded / :filesize)`, {
total: node.getSize(),
incomplete: ' ',
width: 40,
clear: false,
renderThrottle: this.config.get('cli.progressInterval')
async.waterfall([
callback => {
if (!options.decrypt) {
return callback();
}

inquirer.prompt([
{
type: 'password',
name: 'password',
message: 'password: '
}
], answers => {
opts.password = answers.password;
callback();
});
}
});
},
], err => {
node.on('fileDownload', node => {
if (this.config.get('cli.progressBars')) {
startTime = Date.now();
bytesDownloaded = 0;
downloadingNode = node;
lastRun = Date.now();
bar = new ProgressBar(`Downloading ${downloadingNode.getName()}\n:percent[:bar] :speed eta :etas (:downloaded / :filesize)`, {
total: node.getSize(),
incomplete: ' ',
width: 40,
clear: false,
renderThrottle: this.config.get('cli.progressInterval')
});
}
});

node.on('downloadProgress', data => {
if (bar) {
bytesDownloaded += data.length;
bytesTransfered += data.length;

let timeDiff = Date.now() - lastRun,
elapsedTime = Date.now() - startTime,
eta = Math.round((elapsedTime * (downloadingNode.getSize() / bytesDownloaded - 1)) / 1000);

if (timeDiff >= this.config.get('cli.progressInterval') || bytesDownloaded >= downloadingNode.getSize()) {
lastRun = Date.now();
bar.tick(bytesTransfered, {
speed: `${Utils.convertFileSize(Math.round(bytesTransfered / (timeDiff / 1000)), 2)}/s`,
downloaded: Utils.convertFileSize(bytesDownloaded),
filesize: Utils.convertFileSize(downloadingNode.getSize()),
});
bytesTransfered = 0;
}
}
});

node.on('downloadComplete', (response, body, retval, data) => {
// Clear out progress bar
if (bar !== null) {
bar.clear();
bar = null;
}

node.on('downloadProgress', data => {
if (bar) {
bytesDownloaded += data.length;
bytesTransfered += data.length;
if (response) {
Logger.debug(`Response returned with status code ${response.statusCode}`);
}

let timeDiff = Date.now() - lastRun,
elapsedTime = Date.now() - startTime,
eta = Math.round((elapsedTime * (downloadingNode.getSize() / bytesDownloaded - 1)) / 1000);
if (retval.success) {
return Logger.info(`Successfully downloaded '${data.localPath}'`);
}

if (timeDiff >= this.config.get('cli.progressInterval') || bytesDownloaded >= downloadingNode.getSize()) {
lastRun = Date.now();
bar.tick(bytesTransfered, {
speed: `${Utils.convertFileSize(Math.round(bytesTransfered / (timeDiff / 1000)), 2)}/s`,
downloaded: Utils.convertFileSize(bytesDownloaded),
filesize: Utils.convertFileSize(downloadingNode.getSize()),
});
bytesTransfered = 0;
let message = `Failed to download '${data.localPath}'`;
if (retval.data.message) {
message += ': ' + retval.data.message;
}
}
});

node.on('downloadComplete', (response, body, retval, data) => {
// Clear out progress bar
if (bar !== null) {
bar.clear();
bar = null;
}

if (response) {
Logger.debug(`Response returned with status code ${response.statusCode}`);
}

if (retval.success) {
return Logger.info(`Successfully downloaded '${data.localPath}'`);
}

let message = `Failed to download '${data.localPath}'`;
if (retval.data.message) {
message += ': ' + retval.data.message;
}

if (retval.data.exists) {
Logger.warn(message);
} else {
Logger.error(message);
}
});
if (retval.data.exists) {
Logger.warn(message);
} else {
Logger.error(message);
}
});

node.download(localPath, opts, (err, data) => {
if (err) {
return reject(err);
}
node.download(localPath, opts, (err, data) => {
if (err) {
return reject(err);
}

if (data.success) {
return resolve();
}
if (data.success) {
return resolve();
}

return reject();
return reject();
});
});
});
});
Expand Down
4 changes: 2 additions & 2 deletions lib/Commands/RestoreCommand.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ class RestoreCommand extends Command {
}

if (result.success) {
Logger.info(`Successfully trashed node ${node.getPath()} (${node.getId()})`);
Logger.info(`Successfully restored node ${node.getName()} (${node.getId()})`);
} else {
Logger.error(`Failed to trash node ${node.getPath()} (${node.getId()}): ${JSON.stringify(result)}`);
Logger.error(`Failed to restore node ${node.getName()} (${node.getId()}): ${JSON.stringify(result)}`);
}

return resolve();
Expand Down
Loading

0 comments on commit cc7f11f

Please sign in to comment.