From 46feadf57c2a42100918b035bd4fbf6df9ffae98 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Mon, 16 Jun 2014 15:51:19 -0300 Subject: [PATCH] delete Wallet WIP --- css/main.css | 1 - index.html | 3 + js/controllers/backup.js | 68 ++++++++++-------- js/directives.js | 21 +++++- js/models/core/WalletFactory.js | 103 ++++++++++++++-------------- js/models/storage/LocalEncrypted.js | 21 ++++++ 6 files changed, 134 insertions(+), 83 deletions(-) diff --git a/css/main.css b/css/main.css index 2ac4d575c..3e6504ec0 100644 --- a/css/main.css +++ b/css/main.css @@ -219,7 +219,6 @@ small.has-error { font-weight: bold; } - .totalAmount { line-height: 120%; margin-top:2px; diff --git a/index.html b/index.html index f96b27ae7..21c99b85a 100644 --- a/index.html +++ b/index.html @@ -727,6 +727,9 @@ +
+
Delete this wallet from this computer
+
diff --git a/js/controllers/backup.js b/js/controllers/backup.js index 92cc40f9b..8452c2f69 100644 --- a/js/controllers/backup.js +++ b/js/controllers/backup.js @@ -1,7 +1,7 @@ 'use strict'; angular.module('copayApp.controllers').controller('BackupController', - function($scope, $rootScope, $location, $window, $timeout, $modal) { + function($scope, $rootScope, $location, $window, $timeout, $modal, controllerUtils, walletFactory) { $scope.title = 'Backup'; var _getEncryptedWallet = function() { @@ -11,10 +11,12 @@ angular.module('copayApp.controllers').controller('BackupController', $scope.download = function() { var timestamp = +(new Date); - var walletName = ($rootScope.wallet.name ? $rootScope.wallet.name : '') + '-' + $rootScope.wallet.id ; + var walletName = ($rootScope.wallet.name ? $rootScope.wallet.name : '') + '-' + $rootScope.wallet.id; var filename = walletName + '-' + timestamp + '.json.aes'; var wallet = _getEncryptedWallet(); - var blob = new Blob([wallet], {type: 'text/plain;charset=utf-8'}); + var blob = new Blob([wallet], { + type: 'text/plain;charset=utf-8' + }); // show a native save dialog if we are in the shell // and pass the wallet to the shell to convert to node Buffer if (window.cshell) { @@ -27,43 +29,49 @@ angular.module('copayApp.controllers').controller('BackupController', saveAs(blob, filename); }; - $scope.openModal = function () { - var modalInstance = $modal.open({ - templateUrl: 'backupModal.html', - controller: ModalInstanceCtrl, - }); + $scope.openModal = function() { + var modalInstance = $modal.open({ + templateUrl: 'backupModal.html', + controller: ModalInstanceCtrl, + }); - modalInstance.result.then(sendEmail); - }; + modalInstance.result.then(sendEmail); + }; - var sendEmail = function(email) { - var body = _getEncryptedWallet(); - var subject = ($rootScope.wallet.name ? $rootScope.wallet.name + ' - ' : '') + $rootScope.wallet.id; - var href = 'mailto:' + email + '?' - + 'subject=[Copay Backup] ' + subject + '&' - + 'body=' + body; + $scope.deleteWallet = function() { + var w=$rootScope.wallet; + w.disconnect(); + walletFactory.remove(w.id, function() { + controllerUtils.logout(); + }); + }; - if (window.cshell) { - return window.cshell.send('backup:email', href); - } + var sendEmail = function(email) { + var body = _getEncryptedWallet(); + var subject = ($rootScope.wallet.name ? $rootScope.wallet.name + ' - ' : '') + $rootScope.wallet.id; + var href = 'mailto:' + email + '?' + 'subject=[Copay Backup] ' + subject + '&' + 'body=' + body; - var newWin = $window.open(href, '_blank', 'scrollbars=yes,resizable=yes,width=10,height=10'); + if (window.cshell) { + return window.cshell.send('backup:email', href); + } - if (newWin) { - $timeout(function() { - newWin.close(); - }, 1000); - } - }; -}); + var newWin = $window.open(href, '_blank', 'scrollbars=yes,resizable=yes,width=10,height=10'); -var ModalInstanceCtrl = function ($scope, $modalInstance) { + if (newWin) { + $timeout(function() { + newWin.close(); + }, 1000); + } + }; + }); - $scope.submit = function (form) { +var ModalInstanceCtrl = function($scope, $modalInstance) { + + $scope.submit = function(form) { $modalInstance.close($scope.email); }; - $scope.cancel = function () { + $scope.cancel = function() { $modalInstance.dismiss('cancel'); }; }; diff --git a/js/directives.js b/js/directives.js index d54858f97..c8ef3c573 100644 --- a/js/directives.js +++ b/js/directives.js @@ -202,4 +202,23 @@ angular.module('copayApp.directives') }); } }; - }); + }) +// From https://gist.github.com/asafge/7430497 +.directive('ngReallyClick', [ + + function() { + return { + restrict: 'A', + link: function(scope, element, attrs) { + element.bind('click', function() { + var message = attrs.ngReallyMessage; + if (message && confirm(message)) { + scope.$apply(attrs.ngReallyClick); + } + }); + } + } + } +]) + +; diff --git a/js/models/core/WalletFactory.js b/js/models/core/WalletFactory.js index 6c00cc96a..7ee3fa00a 100644 --- a/js/models/core/WalletFactory.js +++ b/js/models/core/WalletFactory.js @@ -1,9 +1,9 @@ 'use strict'; -var imports = require('soop').imports(); -var Storage = imports.Storage; -var Network = imports.Network; -var Blockchain = imports.Blockchain; +var imports = require('soop').imports(); +var Storage = imports.Storage; +var Network = imports.Network; +var Blockchain = imports.Blockchain; var TxProposals = require('./TxProposals'); var PublicKeyRing = require('./PublicKeyRing'); @@ -23,13 +23,13 @@ function WalletFactory(config, version) { this.network = new Network(config.network); this.blockchain = new Blockchain(config.blockchain); - this.networkName = config.networkName; - this.verbose = config.verbose; + this.networkName = config.networkName; + this.verbose = config.verbose; this.walletDefaults = config.wallet; - this.version = version; + this.version = version; } -WalletFactory.prototype.log = function(){ +WalletFactory.prototype.log = function() { if (!this.verbose) return; if (console) { console.log.apply(console, arguments); @@ -39,18 +39,18 @@ WalletFactory.prototype.log = function(){ WalletFactory.prototype._checkRead = function(walletId) { var s = this.storage; - var ret = - s.get(walletId, 'publicKeyRing') && - s.get(walletId, 'txProposals') && - s.get(walletId, 'opts') && - s.get(walletId, 'privateKey'); + var ret = + s.get(walletId, 'publicKeyRing') && + s.get(walletId, 'txProposals') && + s.get(walletId, 'opts') && + s.get(walletId, 'privateKey'); return !!ret; }; WalletFactory.prototype.fromObj = function(obj) { // not stored options - obj.opts.reconnectDelay = this.walletDefaults.reconnectDelay; + obj.opts.reconnectDelay = this.walletDefaults.reconnectDelay; var w = Wallet.fromObj(obj, this.storage, this.network, this.blockchain); if (!w) return false; @@ -69,33 +69,35 @@ WalletFactory.prototype.fromEncryptedObj = function(base64, password) { }; WalletFactory.prototype.read = function(walletId) { - if (! this._checkRead(walletId)) + if (!this._checkRead(walletId)) return false; var obj = {}; var s = this.storage; obj.id = walletId; - obj.opts = s.get(walletId, 'opts'); - obj.publicKeyRing = s.get(walletId, 'publicKeyRing'); - obj.txProposals = s.get(walletId, 'txProposals'); - obj.privateKey = s.get(walletId, 'privateKey'); + obj.opts = s.get(walletId, 'opts'); + obj.publicKeyRing = s.get(walletId, 'publicKeyRing'); + obj.txProposals = s.get(walletId, 'txProposals'); + obj.privateKey = s.get(walletId, 'privateKey'); var w = this.fromObj(obj); return w; }; WalletFactory.prototype.create = function(opts) { - opts = opts || {}; - this.log('### CREATING NEW WALLET.' + - (opts.id ? ' USING ID: ' + opts.id : ' NEW ID') + - (opts.privateKey ? ' USING PrivateKey: ' + opts.privateKey.getId() : ' NEW PrivateKey') - ); + opts = opts || {}; + this.log('### CREATING NEW WALLET.' + + (opts.id ? ' USING ID: ' + opts.id : ' NEW ID') + + (opts.privateKey ? ' USING PrivateKey: ' + opts.privateKey.getId() : ' NEW PrivateKey') + ); - opts.privateKey = opts.privateKey || new PrivateKey({ networkName: this.networkName }); + opts.privateKey = opts.privateKey || new PrivateKey({ + networkName: this.networkName + }); var requiredCopayers = opts.requiredCopayers || this.walletDefaults.requiredCopayers; - var totalCopayers = opts.totalCopayers || this.walletDefaults.totalCopayers; + var totalCopayers = opts.totalCopayers || this.walletDefaults.totalCopayers; opts.publicKeyRing = opts.publicKeyRing || new PublicKeyRing({ networkName: this.networkName, @@ -120,10 +122,10 @@ WalletFactory.prototype.create = function(opts) { opts.verbose = this.verbose; opts.spendUnconfirmed = opts.spendUnconfirmed || this.walletDefaults.spendUnconfirmed; - opts.reconnectDelay = opts.reconnectDelay || this.walletDefaults.reconnectDelay; + opts.reconnectDelay = opts.reconnectDelay || this.walletDefaults.reconnectDelay; opts.requiredCopayers = requiredCopayers; - opts.totalCopayers = totalCopayers; - opts.version = opts.version || this.version; + opts.totalCopayers = totalCopayers; + opts.version = opts.version || this.version; var w = new Wallet(opts); w.store(); return w; @@ -133,27 +135,22 @@ WalletFactory.prototype.create = function(opts) { WalletFactory.prototype._checkVersion = function(inVersion) { var thisV = this.version.split('.'); var thisV0 = parseInt(thisV[0]); - var inV = inVersion.split('.'); - var inV0 = parseInt(inV[0]); + var inV = inVersion.split('.'); + var inV0 = parseInt(inV[0]); //We only check for major version differences - if( thisV0 < inV0 ) { + if (thisV0 < inV0) { throw new Error('Major difference in software versions' + - '. Received:' + inVersion + - '. Current version:' + this.version + - '. Aborting.'); + '. Received:' + inVersion + + '. Current version:' + this.version + + '. Aborting.'); } }; WalletFactory.prototype._checkNetwork = function(inNetworkName) { - if( this.networkName !== inNetworkName ) { - throw new Error('This Wallet is configured for ' - + inNetworkName - + ' while currently Copay is configured for: ' - + this.networkName - + '. Check your settings.' - ); + if (this.networkName !== inNetworkName) { + throw new Error('This Wallet is configured for ' + inNetworkName + ' while currently Copay is configured for: ' + this.networkName + '. Check your settings.'); } }; @@ -175,14 +172,16 @@ WalletFactory.prototype.open = function(walletId, opts) { WalletFactory.prototype.getWallets = function() { var ret = this.storage.getWallets(); ret.forEach(function(i) { - i.show = i.name ? ( (i.name + ' <'+i.id+'>') ) : i.id; + i.show = i.name ? ((i.name + ' <' + i.id + '>')) : i.id; }); return ret; }; -WalletFactory.prototype.remove = function(walletId) { - // TODO remove wallet contents - this.log('TODO: remove wallet contents'); +WalletFactory.prototype.remove = function(walletId, cb) { + var s = this.storage; + this.log('## DELETING WALLET ID:'+ walletId); //TODO + s.get(walletId, 'opts'); + return cb(); }; WalletFactory.prototype.decodeSecret = function(secret) { @@ -198,9 +197,11 @@ WalletFactory.prototype.joinCreateSession = function(secret, nickname, passphras var s = self.decodeSecret(secret); if (!s) return cb('badSecret'); - + //Create our PrivateK - var privateKey = new PrivateKey({ networkName: this.networkName }); + var privateKey = new PrivateKey({ + networkName: this.networkName + }); this.log('\t### PrivateKey Initialized'); var opts = { copayerId: privateKey.getId(), @@ -219,13 +220,13 @@ WalletFactory.prototype.joinCreateSession = function(secret, nickname, passphras return cb(connectedOnce ? 'walletFull' : 'joinError'); }); self.network.on('data', function(sender, data) { - if (data.type ==='walletId') { - if (data.networkName !== self.networkName ){ + if (data.type === 'walletId') { + if (data.networkName !== self.networkName) { return cb('badNetwork'); } data.opts.privateKey = privateKey; - data.opts.nickname = nickname; + data.opts.nickname = nickname; data.opts.passphrase = passphrase; data.opts.id = data.walletId; var w = self.create(data.opts); diff --git a/js/models/storage/LocalEncrypted.js b/js/models/storage/LocalEncrypted.js index 3ab93e160..308ae59a8 100644 --- a/js/models/storage/LocalEncrypted.js +++ b/js/models/storage/LocalEncrypted.js @@ -147,6 +147,27 @@ Storage.prototype.getWallets = function() { return wallets; }; +Storage.prototype.deleteWallet = function(walletId) { + var walletIds = []; + var uniq = {}; + for (var i = 0; i < localStorage.length; i++) { + var key = localStorage.key(i); + var split = key.split('::'); + if (split.length == 2) { + var walletId = split[0]; + + if (walletId === 'nameFor') continue; + + if (typeof uniq[walletId] === 'undefined') { + walletIds.push(walletId); + uniq[walletId] = 1; + } + } + } + +}; + + //obj contains keys to be set Storage.prototype.setFromObj = function(walletId, obj) { for (var k in obj) {