Merge pull request #423 from JDonadio/fix/encrypted-02

Fix export/import wallet with encrypted pk
This commit is contained in:
Matias Alejo Garcia 2016-10-13 16:02:12 -03:00 committed by GitHub
commit 9667aa8e24
5 changed files with 129 additions and 68 deletions

View File

@ -15,6 +15,53 @@ angular.module('copayApp.controllers').controller('exportController',
}); });
}; };
function prepareWallet(cb) {
if ($scope.password) return cb(null, $scope.password);
walletService.prepare(wallet, function(err, password) {
if (err) return cb(err);
$scope.password = password;
walletService.getEncodedWalletInfo(wallet, $scope.password, function(err, code) {
if (err) return cb(err);
if (!code)
$scope.formData.supported = false;
else {
$scope.formData.supported = true;
$scope.formData.exportWalletInfo = code;
}
return cb(null, password);
});
});
};
$scope.generateQrCode = function() {
if ($scope.formData.exportWalletInfo) {
$scope.file.value = false;
$timeout(function() {
$scope.$apply();
});
return;
}
prepareWallet(function(err, password) {
if (err) {
popupService.showAlert(gettextCatalog.getString('Error'), err);
return;
}
if (!password) return;
$scope.file.value = false;
$scope.password = password;
$timeout(function() {
$scope.$apply();
});
});
};
var init = function() { var init = function() {
$scope.formData = {}; $scope.formData = {};
$scope.isEncrypted = wallet.isPrivKeyEncrypted(); $scope.isEncrypted = wallet.isPrivKeyEncrypted();
@ -24,24 +71,6 @@ angular.module('copayApp.controllers').controller('exportController',
$scope.showAdvanced = false; $scope.showAdvanced = false;
$scope.wallet = wallet; $scope.wallet = wallet;
$scope.canSign = wallet.canSign(); $scope.canSign = wallet.canSign();
walletService.getEncodedWalletInfo(wallet, function(err, code) {
if (err || !code) {
$log.warn(err);
return $ionicHistory.goBack();
}
if (!code)
$scope.formData.supported = false;
else {
$scope.formData.supported = true;
$scope.formData.exportWalletInfo = code;
}
$timeout(function() {
$scope.$apply();
}, 1);
});
}; };
/* /*
@ -67,23 +96,32 @@ angular.module('copayApp.controllers').controller('exportController',
}; };
$scope.downloadWalletBackup = function() { $scope.downloadWalletBackup = function() {
$scope.getAddressbook(function(err, localAddressBook) { prepareWallet(function(err, password) {
if (err) { if (err) {
popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Failed to export')); popupService.showAlert(gettextCatalog.getString('Error'), err);
return; return;
} }
var opts = { if (!password) return;
noSign: $scope.formData.noSignEnabled,
addressBook: localAddressBook
};
backupService.walletDownload($scope.formData.password, opts, function(err) { $scope.getAddressbook(function(err, localAddressBook) {
if (err) { if (err) {
popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Failed to export')); popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Failed to export'));
return; return;
} }
$ionicHistory.removeBackView(); var opts = {
$state.go('tabs.home'); noSign: $scope.formData.noSignEnabled,
addressBook: localAddressBook,
password: password
};
backupService.walletDownload($scope.formData.password, opts, function(err) {
if (err) {
popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Failed to export'));
return;
}
$ionicHistory.removeBackView();
$state.go('tabs.home');
});
}); });
}); });
}; };
@ -104,21 +142,30 @@ angular.module('copayApp.controllers').controller('exportController',
}; };
$scope.getBackup = function(cb) { $scope.getBackup = function(cb) {
$scope.getAddressbook(function(err, localAddressBook) { prepareWallet(function(err, password) {
if (err) { if (err) {
popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Failed to export')); popupService.showAlert(gettextCatalog.getString('Error'), err);
return cb(null); return;
} }
var opts = { if (!password) return;
noSign: $scope.formData.noSignEnabled,
addressBook: localAddressBook
};
var ew = backupService.walletExport($scope.formData.password, opts); $scope.getAddressbook(function(err, localAddressBook) {
if (!ew) { if (err) {
popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Failed to export')); popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Failed to export'));
} return cb(null);
return cb(ew); }
var opts = {
noSign: $scope.formData.noSignEnabled,
addressBook: localAddressBook,
password: password
};
var ew = backupService.walletExport($scope.formData.password, opts);
if (!ew) {
popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Failed to export'));
}
return cb(ew);
});
}); });
}; };
@ -171,6 +218,11 @@ angular.module('copayApp.controllers').controller('exportController',
$scope.$on("$ionicView.beforeEnter", function(event, data) { $scope.$on("$ionicView.beforeEnter", function(event, data) {
init(); init();
$scope.file = {
value: true
};
$scope.formData.exportWalletInfo = null;
$scope.password = null;
}); });
}); });

View File

@ -21,7 +21,8 @@ angular.module('copayApp.controllers').controller('preferencesDeleteWalletContro
if (err) { if (err) {
popupService.showAlert(gettextCatalog.getString('Error'), err.message || err); popupService.showAlert(gettextCatalog.getString('Error'), err.message || err);
} else { } else {
$ionicHistory.removeBackView(); $ionicHistory.clearHistory();
$ionicHistory.clearCache();
$state.go('tabs.home'); $state.go('tabs.home');
} }
}); });

View File

@ -134,8 +134,7 @@ angular.module('copayApp.services')
if (n.type == "NewBlock" && n.data.network == "testnet") { if (n.type == "NewBlock" && n.data.network == "testnet") {
throttledBwsEvent(n, wallet); throttledBwsEvent(n, wallet);
} } else newBwsEvent(n, wallet);
else newBwsEvent(n, wallet);
}); });
wallet.on('walletCompleted', function() { wallet.on('walletCompleted', function() {
@ -600,6 +599,7 @@ angular.module('copayApp.services')
var walletClient = bwcService.getClient(null, opts); var walletClient = bwcService.getClient(null, opts);
$log.debug('Importing Wallet:', opts); $log.debug('Importing Wallet:', opts);
try { try {
walletClient.import(str, { walletClient.import(str, {
compressed: opts.compressed, compressed: opts.compressed,
@ -611,6 +611,12 @@ angular.module('copayApp.services')
str = JSON.parse(str); str = JSON.parse(str);
if (str.xPrivKey && str.xPrivKeyEncrypted) {
$log.warn('Found both encrypted and decrypted key. Deleting the encrypted version');
delete str.xPrivKeyEncrypted;
delete str.mnemonicEncrypted;
}
var addressBook = str.addressBook || {}; var addressBook = str.addressBook || {};
addAndBindWalletClient(walletClient, { addAndBindWalletClient(walletClient, {

View File

@ -869,9 +869,8 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
if (!root.isEncrypted(wallet)) return cb(); if (!root.isEncrypted(wallet)) return cb();
askPassword(wallet.name, gettext('Enter Spending Password'), function(password) { askPassword(wallet.name, gettext('Enter Spending Password'), function(password) {
if (!password) return cb('no password'); if (!password) return cb('No password');
if (!wallet.checkPassword(password)) return cb('wrong password'); if (!wallet.checkPassword(password)) return cb('Wrong password');
return cb(null, password); return cb(null, password);
}); });
@ -990,8 +989,7 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
}); });
}; };
root.getEncodedWalletInfo = function(wallet, cb) { root.getEncodedWalletInfo = function(wallet, password, cb) {
var derivationPath = wallet.credentials.getBaseAddressDerivationPath(); var derivationPath = wallet.credentials.getBaseAddressDerivationPath();
var encodingType = { var encodingType = {
mnemonic: 1, mnemonic: 1,
@ -1002,25 +1000,23 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
// not supported yet // not supported yet
if (wallet.credentials.derivationStrategy != 'BIP44' || !wallet.canSign()) if (wallet.credentials.derivationStrategy != 'BIP44' || !wallet.canSign())
return null; return cb(gettextCatalog.getString('Exporting via QR not supported for this wallet'));
root.getKeys(wallet, function(err, keys) { var keys = root.getKeysWithPassword(wallet, password);
if (err || !keys) return cb(err);
if (keys.mnemonic) { if (keys.mnemonic) {
info = { info = {
type: encodingType.mnemonic, type: encodingType.mnemonic,
data: keys.mnemonic, data: keys.mnemonic,
}
} else {
info = {
type: encodingType.xpriv,
data: keys.xPrivKey
}
} }
return cb(null, info.type + '|' + info.data + '|' + wallet.credentials.network.toLowerCase() + '|' + derivationPath + '|' + (wallet.credentials.mnemonicHasPassphrase)); } else {
info = {
type: encodingType.xpriv,
data: keys.xPrivKey
}
}
}); return cb(null, info.type + '|' + info.data + '|' + wallet.credentials.network.toLowerCase() + '|' + derivationPath + '|' + (wallet.credentials.mnemonicHasPassphrase));
}; };
root.setTouchId = function(wallet, enabled, cb) { root.setTouchId = function(wallet, enabled, cb) {
@ -1055,6 +1051,12 @@ angular.module('copayApp.services').factory('walletService', function($log, $tim
}); });
}; };
root.getKeysWithPassword = function(wallet, password) {
try {
return wallet.getKeys(password);
} catch (e) {}
}
root.getViewStatus = function(wallet, txp) { root.getViewStatus = function(wallet, txp) {
var status = txp.status; var status = txp.status;
var type; var type;

View File

@ -5,17 +5,17 @@
</ion-nav-back-button> </ion-nav-back-button>
</ion-nav-bar> </ion-nav-bar>
<ion-content ng-init="file = true"> <ion-content>
<div class="row text-center top-tabs"> <div class="row text-center">
<div class="col" ng-click="file = true" ng-style="file && {'border-bottom-style': 'solid'}"> <div class="col" ng-click="file.value = true" ng-style="file.value && {'border-bottom': '2px solid'}">
<span class="" translate>File/Text</span> <span class="" translate>File/Text</span>
</div> </div>
<div class="col" ng-click="file = false" ng-style="!file && {'border-bottom-style': 'solid'}"> <div class="col" ng-click="generateQrCode();" ng-style="!file.value && {'border-bottom': '2px solid'}">
<span class="" translate>QR Code</span> <span class="" translate>QR Code</span>
</div> </div>
</div> </div>
<div ng-include="'views/tab-export-file.html'" ng-if="file"></div> <div ng-include="'views/tab-export-file.html'" ng-if="file.value"></div>
<div ng-include="'views/tab-export-qrCode.html'" ng-if="!file"></div> <div ng-include="'views/tab-export-qrCode.html'" ng-if="!file.value"></div>
</ion-content> </ion-content>
</ion-view> </ion-view>