diff --git a/public/views/includes/confirmBackupPopup.html b/public/views/includes/confirmBackupPopup.html index 5dc2d2eeb..eb60681f7 100644 --- a/public/views/includes/confirmBackupPopup.html +++ b/public/views/includes/confirmBackupPopup.html @@ -1,19 +1,26 @@ -
-
Your bitcoin wallet is backed up!
-

Be sure to store your recovery phrase in a secure place. If this app is deelted, you money coont be recovered with out it.

- -
-
-
uh oh...
-

It's importante that you write your backup phrase down correctly. If something happens to your wallet, you'll need this backup to recover your money - Please review your backup and try again

- + diff --git a/src/js/controllers/backup.js b/src/js/controllers/backup.js index cf0b20c9b..cec5dd02f 100644 --- a/src/js/controllers/backup.js +++ b/src/js/controllers/backup.js @@ -1,199 +1,209 @@ 'use strict'; angular.module('copayApp.controllers').controller('backupController', - function($rootScope, $scope, $timeout, $log, $state, $stateParams, $ionicPopup, $ionicNavBarDelegate, uxLanguage, lodash, fingerprintService, platformInfo, configService, profileService, bwcService, walletService, ongoingProcess, storageService) { - var wallet = profileService.getWallet($stateParams.walletId); - $ionicNavBarDelegate.title(wallet.credentials.walletName); - $scope.n = wallet.n; - var keys; + function($rootScope, $scope, $timeout, $log, $state, $stateParams, $ionicPopup, $ionicModal, $ionicNavBarDelegate, uxLanguage, lodash, fingerprintService, platformInfo, configService, profileService, bwcService, walletService, ongoingProcess, storageService) { + var wallet = profileService.getWallet($stateParams.walletId); + $ionicNavBarDelegate.title(wallet.credentials.walletName); + $scope.n = wallet.n; + var keys; - $scope.credentialsEncrypted = wallet.isPrivKeyEncrypted(); + $scope.credentialsEncrypted = wallet.isPrivKeyEncrypted(); - var isDeletedSeed = function() { - if (!wallet.credentials.mnemonic && !wallet.credentials.mnemonicEncrypted) - return true; + var isDeletedSeed = function() { + if (!wallet.credentials.mnemonic && !wallet.credentials.mnemonicEncrypted) + return true; - return false; - }; + return false; + }; - $scope.init = function() { - $scope.deleted = isDeletedSeed(); - if ($scope.deleted) { - $log.debug('no mnemonics'); - return; - } - - walletService.getKeys(wallet, function(err, k) { - if (err || !k) { - $state.go('wallet.preferences'); - return; - } - $scope.credentialsEncrypted = false; - keys = k; - $scope.initFlow(); - }); - }; - - var shuffledWords = function(words) { - var sort = lodash.sortBy(words); - - return lodash.map(sort, function(w) { - return { - word: w, - selected: false - }; - }); - }; - - $scope.initFlow = function() { - if (!keys) return; - $scope.viewTitle = "Backup Phrase"; - var words = keys.mnemonic; - - $scope.mnemonicWords = words.split(/[\u3000\s]+/); - $scope.shuffledMnemonicWords = shuffledWords($scope.mnemonicWords); - $scope.mnemonicHasPassphrase = wallet.mnemonicHasPassphrase(); - $scope.useIdeograms = words.indexOf("\u3000") >= 0; - $scope.passphrase = ''; - $scope.customWords = []; - $scope.step = 1; - $scope.selectComplete = false; - $scope.backupError = false; - - words = lodash.repeat('x', 300); - $timeout(function() { - $scope.$apply(); - }, 10); - }; - - $scope.goBack = function() { - if ($scope.step == 1) { - if ($stateParams.fromOnboarding) $state.go('onboarding.backupRequest'); - else $state.go('wallet.preferences'); - } else { - $scope.goToStep($scope.step - 1); - } - }; - - var backupError = function(err) { - ongoingProcess.set('validatingWords', false); - $log.debug('Failed to verify backup: ', err); - $scope.backupError = true; - - $timeout(function() { - $scope.$apply(); - }, 1); - }; - - var openPopup = function() { - var confirmBackupPopup = $ionicPopup.show({ - templateUrl: "views/includes/confirmBackupPopup.html", - scope: $scope, - }); - - $scope.closePopup = function(val) { - if (val) { - confirmBackupPopup.close(); - if ($stateParams.fromOnboarding) $state.go('onboarding.disclaimer'); - else $state.go('tabs.home') - } else { - confirmBackupPopup.close(); - $scope.goToStep(1); - } - }; + $scope.init = function() { + $scope.deleted = isDeletedSeed(); + if ($scope.deleted) { + $log.debug('no mnemonics'); + return; } - var confirm = function(cb) { - $scope.backupError = false; - - var customWordList = lodash.pluck($scope.customWords, 'word'); - - if (!lodash.isEqual($scope.mnemonicWords, customWordList)) { - return cb('Mnemonic string mismatch'); + walletService.getKeys(wallet, function(err, k) { + if (err || !k) { + $state.go('wallet.preferences'); + return; } + $scope.credentialsEncrypted = false; + keys = k; + $scope.initFlow(); + }); + }; - $timeout(function() { - if ($scope.mnemonicHasPassphrase) { - var walletClient = bwcService.getClient(); - var separator = $scope.useIdeograms ? '\u3000' : ' '; - var customSentence = customWordList.join(separator); - var passphrase = $scope.passphrase || ''; + var shuffledWords = function(words) { + var sort = lodash.sortBy(words); - try { - walletClient.seedFromMnemonic(customSentence, { - network: wallet.credentials.network, - passphrase: passphrase, - account: wallet.credentials.account - }); - } catch (err) { - walletClient.credentials.xPrivKey = lodash.repeat('x', 64); - return cb(err); - } - - if (walletClient.credentials.xPrivKey.substr(walletClient.credentials.xPrivKey) != keys.xPrivKey) { - delete walletClient.credentials; - return cb('Private key mismatch'); - } - } - - profileService.setBackupFlag(wallet.credentials.walletId); - return cb(); - }, 1); - }; - - var finalStep = function() { - ongoingProcess.set('validatingWords', true); - confirm(function(err) { - ongoingProcess.set('validatingWords', false); - if (err) { - backupError(err); - } - $timeout(function() { - openPopup(); - return; - }, 1); - }); - }; - - $scope.goToStep = function(n) { - if (n == 1) - $scope.initFlow(); - if (n == 2){ - $scope.step = 2; - $scope.viewTitle = "Let's verify your backup phrase"; - } - if (n == 3) { - if (!$scope.mnemonicHasPassphrase) - finalStep(); - else - $scope.step = 3; - } - if (n == 4) - finalStep(); - }; - - $scope.addButton = function(index, item) { - var newWord = { - word: item.word, - prevIndex: index + return lodash.map(sort, function(w) { + return { + word: w, + selected: false }; - $scope.customWords.push(newWord); - $scope.shuffledMnemonicWords[index].selected = true; - $scope.shouldContinue(); - }; + }); + }; - $scope.removeButton = function(index, item) { - if ($scope.loading) return; - $scope.customWords.splice(index, 1); - $scope.shuffledMnemonicWords[item.prevIndex].selected = false; - $scope.shouldContinue(); - }; + $scope.initFlow = function() { + if (!keys) return; + $scope.viewTitle = "Backup Phrase"; + var words = keys.mnemonic; - $scope.shouldContinue = function() { - if ($scope.customWords.length == $scope.shuffledMnemonicWords.length) - $scope.selectComplete = true; - else - $scope.selectComplete = false; - }; + $scope.mnemonicWords = words.split(/[\u3000\s]+/); + $scope.shuffledMnemonicWords = shuffledWords($scope.mnemonicWords); + $scope.mnemonicHasPassphrase = wallet.mnemonicHasPassphrase(); + $scope.useIdeograms = words.indexOf("\u3000") >= 0; + $scope.passphrase = ''; + $scope.customWords = []; + $scope.step = 1; + $scope.selectComplete = false; + $scope.backupError = false; + words = lodash.repeat('x', 300); + $timeout(function() { + $scope.$apply(); + }, 10); + }; + + $scope.goBack = function() { + if ($scope.step == 1) { + if ($stateParams.fromOnboarding) $state.go('onboarding.backupRequest'); + else $state.go('wallet.preferences'); + } else { + $scope.goToStep($scope.step - 1); + } + }; + + var backupError = function(err) { + ongoingProcess.set('validatingWords', false); + $log.debug('Failed to verify backup: ', err); + $scope.backupError = true; + + $timeout(function() { + $scope.$apply(); + }, 1); + }; + + $scope.closePopup = function(val) { + if (val) { + $scope.closeModal(); + if ($stateParams.fromOnboarding) $state.go('onboarding.disclaimer'); + else $state.go('tabs.home') + } else { + confirmBackupPopup.close(); + $scope.goToStep(1); + } + }; + + $ionicModal.fromTemplateUrl('views/includes/confirmBackupPopup.html', { + scope: $scope, + animation: 'slide-in-up' + }).then(function(modal) { + $scope.modal = modal; }); + $scope.openModal = function() { + $scope.modal.show(); + }; + $scope.closeModal = function() { + $scope.modal.hide(); + }; + // Cleanup the modal when we're done with it! + $scope.$on('$destroy', function() { + $scope.modal.remove(); + }); + + var confirm = function(cb) { + $scope.backupError = false; + + var customWordList = lodash.pluck($scope.customWords, 'word'); + + if (!lodash.isEqual($scope.mnemonicWords, customWordList)) { + return cb('Mnemonic string mismatch'); + } + + $timeout(function() { + if ($scope.mnemonicHasPassphrase) { + var walletClient = bwcService.getClient(); + var separator = $scope.useIdeograms ? '\u3000' : ' '; + var customSentence = customWordList.join(separator); + var passphrase = $scope.passphrase || ''; + + try { + walletClient.seedFromMnemonic(customSentence, { + network: wallet.credentials.network, + passphrase: passphrase, + account: wallet.credentials.account + }); + } catch (err) { + walletClient.credentials.xPrivKey = lodash.repeat('x', 64); + return cb(err); + } + + if (walletClient.credentials.xPrivKey.substr(walletClient.credentials.xPrivKey) != keys.xPrivKey) { + delete walletClient.credentials; + return cb('Private key mismatch'); + } + } + + profileService.setBackupFlag(wallet.credentials.walletId); + return cb(); + }, 1); + }; + + var finalStep = function() { + ongoingProcess.set('validatingWords', true); + confirm(function(err) { + ongoingProcess.set('validatingWords', false); + if (err) { + backupError(err); + } + $timeout(function() { + $scope.openModal(); + return; + }, 1); + }); + }; + + $scope.goToStep = function(n) { + if (n == 1) + $scope.initFlow(); + if (n == 2) { + $scope.step = 2; + $scope.viewTitle = "Let's verify your backup phrase"; + } + if (n == 3) { + if (!$scope.mnemonicHasPassphrase) + finalStep(); + else + $scope.step = 3; + } + if (n == 4) + finalStep(); + }; + + $scope.addButton = function(index, item) { + var newWord = { + word: item.word, + prevIndex: index + }; + $scope.customWords.push(newWord); + $scope.shuffledMnemonicWords[index].selected = true; + $scope.shouldContinue(); + }; + + $scope.removeButton = function(index, item) { + if ($scope.loading) return; + $scope.customWords.splice(index, 1); + $scope.shuffledMnemonicWords[item.prevIndex].selected = false; + $scope.shouldContinue(); + }; + + $scope.shouldContinue = function() { + if ($scope.customWords.length == $scope.shuffledMnemonicWords.length) + $scope.selectComplete = true; + else + $scope.selectComplete = false; + }; + +}); diff --git a/src/sass/forms.scss b/src/sass/forms.scss index e69de29bb..2c725b7fd 100644 --- a/src/sass/forms.scss +++ b/src/sass/forms.scss @@ -0,0 +1,3 @@ +.button-clear{ + background: none !important; +} \ No newline at end of file diff --git a/src/sass/main.scss b/src/sass/main.scss index 50c0d36a2..4fe7e362f 100644 --- a/src/sass/main.scss +++ b/src/sass/main.scss @@ -970,3 +970,4 @@ input[type=number] { @import 'views/onboarding/onboarding'; @import "views/includes/walletActivity"; @import "views/includes/wallets"; +@import "views/includes/modals/modals"; diff --git a/src/sass/views/includes/modals/backup-confirm-modal.scss b/src/sass/views/includes/modals/backup-confirm-modal.scss new file mode 100644 index 000000000..430d8cb5c --- /dev/null +++ b/src/sass/views/includes/modals/backup-confirm-modal.scss @@ -0,0 +1,3 @@ +#backup-confirm-modal{ + +} \ No newline at end of file diff --git a/src/sass/views/includes/modals/modals.scss b/src/sass/views/includes/modals/modals.scss new file mode 100644 index 000000000..9a129bacd --- /dev/null +++ b/src/sass/views/includes/modals/modals.scss @@ -0,0 +1,47 @@ +.popup-modal { + background: #fff; + top: 20%; + position: absolute; + z-index: 10; + width: 90%; + left: 5%; + border-radius: .25rem; + &-header { + background: rgb(1, 209, 162); + padding: 1rem; + border-radius: .25rem .25rem 0 0; + min-height: 120px; + &-success { + background: url('../img/onboarding-success.svg') no-repeat center; + height: 6rem; + background-size: contain; + margin-top: .3rem; + } + } + &-content { + padding: .5rem .8rem; + h5,p{ + margin:0 0 1rem; + } + h5 { + color: rgb(74, 74, 74); + font-weight: bold; + font-size: 1.3rem; + margin-top:1rem; + } + p{ + font-weight: 200; + } + } + &-content-success{ + button{ + color:rgb(23, 174, 140) !important; + } + } +} + +.modal-backdrop.active { + background: rgba(0, 0, 0, .5); +} + +@import "backup-confirm-modal"; diff --git a/src/sass/views/wallet-backup-phrase.scss b/src/sass/views/wallet-backup-phrase.scss index 22794cd53..f075dc32f 100644 --- a/src/sass/views/wallet-backup-phrase.scss +++ b/src/sass/views/wallet-backup-phrase.scss @@ -15,7 +15,7 @@ background: rgba(246, 246, 246, 0.87); padding: .5rem .5rem 1.7rem; border: 2px dashed rgb(206, 206, 206); - width: 80%; + width: 90%; margin: 2rem auto; color: rgb(43, 43, 43); text-align: center;