diff --git a/Makefile b/Makefile index 2cc12a548..e6b385010 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,22 @@ sign: verify: gpg --verify browser-extensions/chrome/copay-chrome-extension.zip.sig browser-extensions/chrome/copay-chrome-extension.zip +sign-desktop: + gpg -u 1112CFA1 --output webkitbuilds/copay-linux32.zip.sig --detach-sig webkitbuilds/copay-linux32.zip + gpg -u 1112CFA1 --output webkitbuilds/copay-linux64.zip.sig --detach-sig webkitbuilds/copay-linux64.zip + gpg -u 1112CFA1 --output webkitbuilds/copay-osx32.dmg.sig --detach-sig webkitbuilds/copay-osx32.dmg + gpg -u 1112CFA1 --output webkitbuilds/copay-osx64.dmg.sig --detach-sig webkitbuilds/copay-osx64.dmg + gpg -u 1112CFA1 --output webkitbuilds/copay-win32.exe.sig --detach-sig webkitbuilds/copay-win32.exe + gpg -u 1112CFA1 --output webkitbuilds/copay-win64.exe.sig --detach-sig webkitbuilds/copay-win64.exe + +verify-desktop: + gpg --verify webkitbuilds/copay-linux32.zip.sig webkitbuilds/copay-linux32.zip + gpg --verify webkitbuilds/copay-linux64.zip.sig webkitbuilds/copay-linux64.zip + gpg --verify webkitbuilds/copay-osx32.dmg.sig webkitbuilds/copay-osx32.dmg + gpg --verify webkitbuilds/copay-osx64.dmg.sig webkitbuilds/copay-osx64.dmg + gpg --verify webkitbuilds/copay-win32.exe.sig webkitbuilds/copay-win32.exe + gpg --verify webkitbuilds/copay-win64.exe.sig webkitbuilds/copay-win64.exe + chrome: browser-extensions/chrome/build.sh diff --git a/cordova/build.sh b/cordova/build.sh index ba85d6ed0..a23a39f03 100755 --- a/cordova/build.sh +++ b/cordova/build.sh @@ -212,15 +212,20 @@ if [ $CURRENT_OS == "WP8" ]; then echo "Wp8 project!!!" cp -R $PROJECT/www/* $PROJECT/platforms/wp8/www checkOK - cp -vf wp/Properties/* $PROJECT/platforms/wp8/Properties/ - cp -vf wp/Package.appxmanifest $PROJECT/platforms/wp8/ - cp -vf wp/MainPage.xaml $PROJECT/platforms/wp8/ - checkOK - cp -vf wp/Assets/* $PROJECT/platforms/wp8/Assets/ - cp -vf wp/SplashScreenImage.jpg $PROJECT/platforms/wp8/ - cp -vf wp/ApplicationIcon.png $PROJECT/platforms/wp8/ - cp -vf wp/Background.png $PROJECT/platforms/wp8/ - checkOK + if ! $CLEAR + then + cp -vf wp/Properties/* $PROJECT/platforms/wp8/Properties/ + checkOK + cp -vf wp/MainPage.xaml $PROJECT/platforms/wp8/ + checkOK + cp -vf wp/Package.appxmanifest $PROJECT/platforms/wp8/ + checkOK + cp -vf wp/Assets/* $PROJECT/platforms/wp8/Assets/ + cp -vf wp/SplashScreenImage.jpg $PROJECT/platforms/wp8/ + cp -vf wp/ApplicationIcon.png $PROJECT/platforms/wp8/ + cp -vf wp/Background.png $PROJECT/platforms/wp8/ + checkOK + fi fi diff --git a/cordova/config.xml b/cordova/config.xml index 9a55e492c..9c7b7dbc2 100644 --- a/cordova/config.xml +++ b/cordova/config.xml @@ -1,8 +1,8 @@ + version="1.4.3" + android-versionCode="53" + ios-CFBundleVersion="1.4.3"> Copay A secure bitcoin wallet for friends and companies. diff --git a/cordova/ios/Copay-Info.plist b/cordova/ios/Copay-Info.plist index 0eb24c975..6c9ecd5c9 100644 --- a/cordova/ios/Copay-Info.plist +++ b/cordova/ios/Copay-Info.plist @@ -57,11 +57,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.4.1 + 1.4.3 CFBundleSignature ???? CFBundleVersion - 1.4.1 + 1.4.3 LSRequiresIPhoneOS NSMainNibFile diff --git a/cordova/wp/Package.appxmanifest b/cordova/wp/Package.appxmanifest index 5ba5f6c11..09659ce53 100644 --- a/cordova/wp/Package.appxmanifest +++ b/cordova/wp/Package.appxmanifest @@ -1,9 +1,9 @@  - + - Copay Wallet + Copay Bitcoin Wallet BitPay Inc. Assets\StoreLogo.png @@ -16,7 +16,7 @@ - + diff --git a/cordova/wp/Properties/WMAppManifest.xml b/cordova/wp/Properties/WMAppManifest.xml index 5940682ca..fa8cb0f38 100644 --- a/cordova/wp/Properties/WMAppManifest.xml +++ b/cordova/wp/Properties/WMAppManifest.xml @@ -3,9 +3,13 @@ + + + + - - Assets/icon@2.png + + Assets\icon@2.png @@ -18,10 +22,10 @@ - Assets/200x200@1.png + Assets\200x200@1.png 0 - Assets/200x200@2.png - Copay Wallet + Assets\200x200@2.png + Copay Bitcoin Wallet diff --git a/package.json b/package.json index ec8a52fd2..5588a7cfb 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "copay", "description": "A multisignature wallet", "author": "BitPay", - "version": "1.4.1", + "version": "1.4.3", "keywords": [ "wallet", "copay", diff --git a/public/views/backup.html b/public/views/backup.html index f3d85f9a8..25a2c3ce5 100644 --- a/public/views/backup.html +++ b/public/views/backup.html @@ -8,7 +8,6 @@

-
{{wordsC.error|translate}} @@ -17,7 +16,7 @@ -
+
@@ -33,11 +32,11 @@ To restore this {{index.m}}-{{index.n}} shared wallet you will need : -
    -
  1. Your wallet seed and access to the server that coordinated the initial wallet creation. You still need {{index.m}} keys to spend.
  2. -
  3. OR the wallet seed of all copayers in the wallet
  4. -
  5. OR 1 wallet export file and the remaining quorum of wallet seeds (e.g. in a 3-5 wallet: 1 wallet export file + 2 wallet seeds of any of the other copayers).
  6. -
+
    +
  1. Your wallet seed and access to the server that coordinated the initial wallet creation. You still need {{index.m}} keys to spend.
  2. +
  3. OR the wallet seed of all copayers in the wallet
  4. +
  5. OR 1 wallet export file and the remaining quorum of wallet seeds (e.g. in a 3-5 wallet: 1 wallet export file + 2 wallet seeds of any of the other copayers).
  6. +
@@ -46,22 +45,22 @@ To restore this {{index.m}}-{{index.n}} shared wallet you will need : -
    -
  1. Your wallet seed and access to the server that coordinated the initial wallet creation. You still need {{index.m}} keys to spend.
  2. -
  3. OR the wallet seeds of all copayers in the wallet
  4. -
+
    +
  1. Your wallet seed and access to the server that coordinated the initial wallet creation. You still need {{index.m}} keys to spend.
  2. +
  3. OR the wallet seeds of all copayers in the wallet
  4. +
- -
+ +
Wallet seed not available. You can still export it from Advanced > Export.
-
+
diff --git a/src/js/controllers/backup.js b/src/js/controllers/backup.js index f99f1a946..25a92733c 100644 --- a/src/js/controllers/backup.js +++ b/src/js/controllers/backup.js @@ -5,27 +5,38 @@ angular.module('copayApp.controllers').controller('wordsController', var msg = gettext('Are you sure you want to delete the backup words?'); var successMsg = gettext('Backup words deleted'); - this.show = false; - var self = this; + self.show = false; + var fc = profileService.focusedClient; - this.toggle = function() { - this.show = !this.show; + if (fc.isPrivKeyEncrypted()) self.credentialsEncrypted = true; + else { + setWords(fc.getMnemonic()); + $rootScope.$emit('Local/BackupDone'); + } + if (fc.credentials && !fc.credentials.mnemonicEncrypted && !fc.credentials.mnemonic) { + self.deleted = true; + } - if (this.show) - $rootScope.$emit('Local/BackupDone'); + self.toggle = function() { + self.error = ""; + if (!self.credentialsEncrypted) + self.show = !self.show; - $timeout(function(){ + if (self.credentialsEncrypted) + self.passwordRequest(); + + $timeout(function() { $scope.$apply(); }, 1); }; - this.delete = function() { - var fc = profileService.focusedClient; + self.delete = function() { confirmDialog.show(msg, function(ok) { if (ok) { fc.clearMnemonic(); profileService.updateCredentialsFC(function() { + self.deleted = true; notification.success(successMsg); go.walletHome(); }); @@ -33,12 +44,10 @@ angular.module('copayApp.controllers').controller('wordsController', }); }; - $scope.$on('$destroy', function() { profileService.lockFC(); }); - function setWords(words) { if (words) { self.mnemonicWords = words.split(/[\u3000\s]+/); @@ -47,26 +56,30 @@ angular.module('copayApp.controllers').controller('wordsController', } }; - var fc = profileService.focusedClient; - try { - setWords(fc.getMnemonic()); - } catch (e) { - if (e.message && e.message.match(/encrypted/) && fc.isPrivKeyEncrypted()) { - self.credentialsEncrypted = true; + self.passwordRequest = function() { + try { + setWords(fc.getMnemonic()); + } catch (e) { + if (e.message && e.message.match(/encrypted/) && fc.isPrivKeyEncrypted()) { + self.credentialsEncrypted = true; - $timeout(function(){ - $scope.$apply(); - }, 1); + $timeout(function() { + $scope.$apply(); + }, 1); - profileService.unlockFC(function(err) { - if (err) { - self.error = bwsError.msg(err, gettext('Could not decrypt')); - $log.warn('Error decrypting credentials:',self.error); //TODO - return; - } - self.credentialsEncrypted = false; - setWords(fc.getMnemonic()); - }); - } + profileService.unlockFC(function(err) { + if (err) { + self.error = bwsError.msg(err, gettext('Could not decrypt')); + $log.warn('Error decrypting credentials:', self.error); //TODO + return; + } + if (!self.show && self.credentialsEncrypted) + self.show = !self.show; + self.credentialsEncrypted = false; + setWords(fc.getMnemonic()); + $rootScope.$emit('Local/BackupDone'); + }); + } + } } - }); + }); \ No newline at end of file diff --git a/src/js/controllers/index.js b/src/js/controllers/index.js index 947fd2952..bf3f9b316 100644 --- a/src/js/controllers/index.js +++ b/src/js/controllers/index.js @@ -1116,13 +1116,16 @@ angular.module('copayApp.controllers').controller('indexController', function($r self.needsBackup = false; $log.debug('Backup done'); storageService.setBackupFlag(self.walletId, function(err) { - if (err) root.showErrorPopup(err); $log.debug('Backup done stored'); }); }); $rootScope.$on('Local/DeviceError', function(event, err) { - root.showErrorPopup(err); + self.showErrorPopup(err, function() { + if (self.isCordova && navigator && navigator.app) { + navigator.app.exitApp(); + } + }); }); $rootScope.$on('Local/WalletImported', function(event, walletId) { diff --git a/src/js/directives/qrScanner.js b/src/js/directives/qrScanner.js index c64c8ed12..0ba7ae2a9 100644 --- a/src/js/directives/qrScanner.js +++ b/src/js/directives/qrScanner.js @@ -67,7 +67,11 @@ angular.module('copayApp.directives') localMediaStreamTrack[i].stop(); } } else { - localMediaStream.stop(); + try { + localMediaStream.stop(); + } catch(e) { + // Older Chromium not support the STOP function + }; } localMediaStream = null; video.src = ''; diff --git a/src/js/routes.js b/src/js/routes.js index f6d58c84e..1533ba74a 100644 --- a/src/js/routes.js +++ b/src/js/routes.js @@ -515,10 +515,10 @@ angular // Try to open local profile profileService.loadAndBindProfile(function(err) { if (err) { - if (err.message.match('NOPROFILE')) { + if (err.message && err.message.match('NOPROFILE')) { $log.debug('No profile... redirecting'); $state.transitionTo('splash'); - } else if (err.message.match('NONAGREEDDISCLAIMER')) { + } else if (err.message && err.message.match('NONAGREEDDISCLAIMER')) { $log.debug('Display disclaimer... redirecting'); $state.transitionTo('disclaimer'); } else { @@ -545,4 +545,4 @@ angular }, 50); } }); - }); \ No newline at end of file + }); diff --git a/src/js/services/applicationService.js b/src/js/services/applicationService.js index a694a86be..c06cabfe5 100644 --- a/src/js/services/applicationService.js +++ b/src/js/services/applicationService.js @@ -14,17 +14,15 @@ angular.module('copayApp.services') } else { // Go home reloading the application if (isChromeApp) { - if (nodeWebkit.isDefined()) { - go.walletHome(); - $timeout(function() { - var win = require('nw.gui').Window.get(); - win.reload(3); - //or - win.reloadDev(); - }, 100); - } else { - chrome.runtime.reload(); - } + chrome.runtime.reload(); + } else if (nodeWebkit.isDefined()) { + go.walletHome(); + $timeout(function() { + var win = require('nw.gui').Window.get(); + win.reload(3); + //or + win.reloadDev(); + }, 100); } else { window.location = window.location.href.substr(0, hashIndex); } diff --git a/src/js/services/storageService.js b/src/js/services/storageService.js index 9673863ff..851ea860e 100644 --- a/src/js/services/storageService.js +++ b/src/js/services/storageService.js @@ -41,15 +41,23 @@ angular.module('copayApp.services') json = JSON.parse(text); } catch (e) {}; + if (!json) return cb('Could not access storage') + if (!json.iter || !json.ct) return cb(null, text); $log.debug('Profile is encrypted'); getUUID(function(uuid) { + $log.debug('Device UUID:' + uuid); if (!uuid) - return cb(new Error('Could not decrypt localstorage profile')); + return cb('Could not decrypt storage: could not get device ID'); - text = sjcl.decrypt(uuid, text); + try { + text = sjcl.decrypt(uuid, text); + } catch(e) { + $log.warn('Decrypt error: ', e); + return cb('Could not decrypt storage: device ID mismatch'); + }; return cb(null, text); }); }; diff --git a/webkitbuilds/.desktop b/webkitbuilds/.desktop index 473b8eeec..9e19c2860 100644 --- a/webkitbuilds/.desktop +++ b/webkitbuilds/.desktop @@ -1,6 +1,6 @@ [Desktop Entry] Type=Application -Version=1.4.1 +Version=1.4.3 Name=Copay Comment=A multisignature wallet Exec=copay diff --git a/webkitbuilds/setup-win32.iss b/webkitbuilds/setup-win32.iss index 2f12f30e9..4c9db7437 100755 --- a/webkitbuilds/setup-win32.iss +++ b/webkitbuilds/setup-win32.iss @@ -2,7 +2,7 @@ ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! #define MyAppName "Copay" -#define MyAppVersion "1.4.1" +#define MyAppVersion "1.4.3" #define MyAppPublisher "BitPay" #define MyAppURL "https://copay.io" #define MyAppExeName "copay.exe" diff --git a/webkitbuilds/setup-win64.iss b/webkitbuilds/setup-win64.iss index 1c84dab16..dbb916584 100755 --- a/webkitbuilds/setup-win64.iss +++ b/webkitbuilds/setup-win64.iss @@ -2,7 +2,7 @@ ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! #define MyAppName "Copay" -#define MyAppVersion "1.4.1" +#define MyAppVersion "1.4.3" #define MyAppPublisher "BitPay" #define MyAppURL "https://copay.io" #define MyAppExeName "copay.exe"