2015-03-06 12:00:10 -03:00
'use strict' ;
2015-11-18 18:37:42 -03:00
angular . module ( 'copayApp.controllers' ) . controller ( 'backupController' ,
2016-09-13 17:51:05 -03:00
function ( $scope , $timeout , $log , $state , $stateParams , $ionicHistory , lodash , profileService , bwcService , walletService , ongoingProcess , popupService , gettextCatalog , $ionicModal ) {
2016-08-19 13:09:27 -03:00
var wallet = profileService . getWallet ( $stateParams . walletId ) ;
2016-09-13 17:44:06 -03:00
$scope . viewTitle = wallet . name || wallet . credentials . walletName ;
2016-08-19 14:38:28 -03:00
$scope . n = wallet . n ;
2016-08-29 16:22:54 -03:00
var keys ;
2016-08-19 14:38:28 -03:00
2016-08-29 16:13:18 -03:00
$scope . credentialsEncrypted = wallet . isPrivKeyEncrypted ( ) ;
2015-11-23 17:53:42 -03:00
2016-08-25 16:31:47 -03:00
var isDeletedSeed = function ( ) {
2016-08-29 16:22:54 -03:00
if ( ! wallet . credentials . mnemonic && ! wallet . credentials . mnemonicEncrypted )
2016-08-25 16:31:47 -03:00
return true ;
2016-08-29 16:22:54 -03:00
2016-08-25 16:31:47 -03:00
return false ;
} ;
2016-08-19 13:07:18 -03:00
$scope . init = function ( ) {
2016-06-16 14:43:10 -03:00
$scope . deleted = isDeletedSeed ( ) ;
2016-08-29 16:22:54 -03:00
if ( $scope . deleted ) {
$log . debug ( 'no mnemonics' ) ;
return ;
}
2016-09-13 14:05:49 -04:00
2016-08-29 16:22:54 -03:00
walletService . getKeys ( wallet , function ( err , k ) {
if ( err || ! k ) {
2016-09-08 16:19:45 -03:00
$log . error ( 'Could not get keys: ' , err ) ;
2016-08-29 16:22:54 -03:00
$state . go ( 'wallet.preferences' ) ;
2016-06-16 14:43:10 -03:00
return ;
}
2016-08-29 11:58:23 -03:00
$scope . credentialsEncrypted = false ;
2016-08-29 16:22:54 -03:00
keys = k ;
$scope . initFlow ( ) ;
2016-05-09 15:56:44 -03:00
} ) ;
} ;
2016-09-13 14:05:49 -04:00
2016-08-25 16:31:47 -03:00
var shuffledWords = function ( words ) {
2016-06-16 14:43:10 -03:00
var sort = lodash . sortBy ( words ) ;
2015-11-30 17:30:26 -03:00
2016-06-16 14:43:10 -03:00
return lodash . map ( sort , function ( w ) {
return {
word : w ,
selected : false
} ;
} ) ;
} ;
2016-08-25 16:31:47 -03:00
2016-08-29 16:22:54 -03:00
$scope . initFlow = function ( ) {
if ( ! keys ) return ;
2016-06-16 14:43:10 -03:00
2016-08-29 16:13:18 -03:00
var words = keys . mnemonic ;
2016-09-13 17:00:27 -03:00
$scope . data = { } ;
2016-06-16 14:43:10 -03:00
$scope . mnemonicWords = words . split ( /[\u3000\s]+/ ) ;
2016-06-13 16:13:35 -03:00
$scope . shuffledMnemonicWords = shuffledWords ( $scope . mnemonicWords ) ;
2016-08-19 13:09:27 -03:00
$scope . mnemonicHasPassphrase = wallet . mnemonicHasPassphrase ( ) ;
2016-06-16 14:43:10 -03:00
$scope . useIdeograms = words . indexOf ( "\u3000" ) >= 0 ;
2016-09-13 17:00:27 -03:00
$scope . data . passphrase = null ;
2016-06-13 16:13:35 -03:00
$scope . customWords = [ ] ;
$scope . step = 1 ;
$scope . selectComplete = false ;
$scope . backupError = false ;
2016-06-16 13:53:44 -03:00
2016-08-29 11:58:23 -03:00
words = lodash . repeat ( 'x' , 300 ) ;
2016-06-16 14:43:10 -03:00
$timeout ( function ( ) {
$scope . $apply ( ) ;
} , 10 ) ;
2016-05-30 13:37:15 -03:00
} ;
2016-08-25 16:31:47 -03:00
$scope . goBack = function ( ) {
if ( $scope . step == 1 ) {
if ( $stateParams . fromOnboarding ) $state . go ( 'onboarding.backupRequest' ) ;
else $state . go ( 'wallet.preferences' ) ;
2016-08-29 16:48:15 -03:00
} else {
2016-08-25 16:31:47 -03:00
$scope . goToStep ( $scope . step - 1 ) ;
2016-09-13 14:05:49 -04:00
}
2016-05-24 13:19:13 -03:00
} ;
2015-11-23 17:53:42 -03:00
2016-08-25 16:31:47 -03:00
var backupError = function ( err ) {
ongoingProcess . set ( 'validatingWords' , false ) ;
$log . debug ( 'Failed to verify backup: ' , err ) ;
$scope . backupError = true ;
2015-11-20 14:38:29 -03:00
2016-09-13 14:05:49 -04:00
$timeout ( function ( ) {
2016-08-25 16:31:47 -03:00
$scope . $apply ( ) ;
} , 1 ) ;
2016-05-24 13:19:13 -03:00
} ;
2015-11-20 14:38:29 -03:00
2016-09-13 17:00:27 -03:00
function openConfirmBackupModal ( ) {
$ionicModal . fromTemplateUrl ( 'views/includes/confirmBackupPopup.html' , {
scope : $scope ,
backdropClickToClose : false ,
hardwareBackButtonClose : false
} ) . then ( function ( modal ) {
$scope . confirmBackupModal = modal ;
$scope . confirmBackupModal . show ( ) ;
} ) ;
2016-09-13 14:26:25 -04:00
} ;
2016-08-25 16:31:47 -03:00
2016-09-13 17:00:27 -03:00
var showBackupResult = function ( ) {
2016-09-09 11:14:04 -03:00
if ( $scope . backupError ) {
var title = gettextCatalog . getString ( 'uh oh...' ) ;
var message = gettextCatalog . getString ( "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" ) ;
popupService . showAlert ( title , message , function ( ) {
$scope . goToStep ( 1 ) ;
} )
2016-09-13 17:00:27 -03:00
} else {
openConfirmBackupModal ( ) ;
2016-09-09 11:14:04 -03:00
}
2016-09-13 17:00:27 -03:00
} ;
$scope . closeBackupResultModal = function ( ) {
$scope . confirmBackupModal . hide ( ) ;
if ( $stateParams . fromOnboarding ) {
$state . go ( 'onboarding.disclaimer' ) ;
} else {
$ionicHistory . clearHistory ( ) ;
$state . go ( 'tabs.home' ) ;
2016-09-09 11:14:04 -03:00
}
2016-09-13 17:00:27 -03:00
} ;
2015-11-20 14:38:29 -03:00
2016-08-25 16:31:47 -03:00
var confirm = function ( cb ) {
2016-06-13 16:13:35 -03:00
$scope . backupError = false ;
2015-11-20 14:38:29 -03:00
2016-06-13 16:13:35 -03:00
var customWordList = lodash . pluck ( $scope . customWords , 'word' ) ;
2015-11-20 14:38:29 -03:00
2016-06-13 16:13:35 -03:00
if ( ! lodash . isEqual ( $scope . mnemonicWords , customWordList ) ) {
2016-06-09 14:50:58 -03:00
return cb ( 'Mnemonic string mismatch' ) ;
2015-11-20 14:38:29 -03:00
}
2016-06-09 14:50:58 -03:00
$timeout ( function ( ) {
2016-06-13 16:13:35 -03:00
if ( $scope . mnemonicHasPassphrase ) {
2016-06-09 14:50:58 -03:00
var walletClient = bwcService . getClient ( ) ;
2016-06-13 16:13:35 -03:00
var separator = $scope . useIdeograms ? '\u3000' : ' ' ;
2016-06-09 14:50:58 -03:00
var customSentence = customWordList . join ( separator ) ;
2016-09-13 17:00:27 -03:00
var passphrase = $scope . data . passphrase || '' ;
2016-06-09 14:50:58 -03:00
try {
walletClient . seedFromMnemonic ( customSentence , {
2016-08-19 13:09:27 -03:00
network : wallet . credentials . network ,
2016-06-09 14:50:58 -03:00
passphrase : passphrase ,
2016-08-19 13:09:27 -03:00
account : wallet . credentials . account
2016-06-09 14:50:58 -03:00
} ) ;
} catch ( err ) {
2016-08-29 11:58:23 -03:00
walletClient . credentials . xPrivKey = lodash . repeat ( 'x' , 64 ) ;
2016-06-09 14:50:58 -03:00
return cb ( err ) ;
}
2016-08-29 16:22:54 -03:00
if ( walletClient . credentials . xPrivKey . substr ( walletClient . credentials . xPrivKey ) != keys . xPrivKey ) {
2016-08-29 16:13:18 -03:00
delete walletClient . credentials ;
2016-06-09 14:50:58 -03:00
return cb ( 'Private key mismatch' ) ;
}
2016-06-09 14:45:28 -03:00
}
2015-11-30 17:30:26 -03:00
2016-09-02 11:09:51 -03:00
profileService . setBackupFlag ( wallet . credentials . walletId ) ;
2016-08-30 17:07:49 -03:00
return cb ( ) ;
2016-06-09 14:50:58 -03:00
} , 1 ) ;
2016-05-24 13:19:13 -03:00
} ;
2015-11-30 17:30:26 -03:00
2016-08-25 16:31:47 -03:00
var finalStep = function ( ) {
ongoingProcess . set ( 'validatingWords' , true ) ;
confirm ( function ( err ) {
ongoingProcess . set ( 'validatingWords' , false ) ;
if ( err ) {
backupError ( err ) ;
}
$timeout ( function ( ) {
2016-09-13 17:00:27 -03:00
showBackupResult ( ) ;
2016-08-25 16:31:47 -03:00
return ;
} , 1 ) ;
} ) ;
} ;
$scope . goToStep = function ( n ) {
if ( n == 1 )
$scope . initFlow ( ) ;
if ( n == 2 )
$scope . step = 2 ;
if ( n == 3 ) {
if ( ! $scope . mnemonicHasPassphrase )
finalStep ( ) ;
else
$scope . step = 3 ;
2016-06-16 14:43:10 -03:00
}
2016-08-25 16:31:47 -03:00
if ( n == 4 )
2016-09-13 14:05:49 -04:00
finalStep ( ) ;
2016-08-25 16:31:47 -03:00
} ;
2016-06-16 14:43:10 -03:00
2016-08-25 16:31:47 -03:00
$scope . addButton = function ( index , item ) {
var newWord = {
word : item . word ,
prevIndex : index
} ;
$scope . customWords . push ( newWord ) ;
$scope . shuffledMnemonicWords [ index ] . selected = true ;
$scope . shouldContinue ( ) ;
2016-06-16 14:43:10 -03:00
} ;
2016-08-25 16:31:47 -03:00
$scope . removeButton = function ( index , item ) {
if ( $scope . loading ) return ;
$scope . customWords . splice ( index , 1 ) ;
$scope . shuffledMnemonicWords [ item . prevIndex ] . selected = false ;
$scope . shouldContinue ( ) ;
} ;
2015-11-30 17:30:26 -03:00
2016-08-25 16:31:47 -03:00
$scope . shouldContinue = function ( ) {
if ( $scope . customWords . length == $scope . shuffledMnemonicWords . length )
$scope . selectComplete = true ;
else
$scope . selectComplete = false ;
2015-11-30 17:30:26 -03:00
} ;
2016-08-25 16:31:47 -03:00
2016-09-13 17:00:27 -03:00
} ) ;