diff --git a/www/i18n/locale-en.json b/www/i18n/locale-en.json index 120e04d1d467d808c987371452098ae187e7d28c..a78629d02978168d6774f6ff5397c92e164dabad 100644 --- a/www/i18n/locale-en.json +++ b/www/i18n/locale-en.json @@ -386,6 +386,7 @@ "RECOVER_ID": "Recover your password", "REVOCATION": "Revocation ...", "REVOKE" : "Revoke this identity", + "REVOKE_WITH_FILE" : "Rekoke this identity with a file", "SAVE_ID": "Save your login", "STRONG_LEVEL": "Strong <span class=\"hidden-xs \">(6 questions minimum)</span>", "TITLE": "Sign-in and security" @@ -543,20 +544,15 @@ "MENU_BTN_ACCOUNT": "<b>{{'ACCOUNT.TITLE'|translate}}</b> allows access to your account balance and transaction history.", "MENU_BTN_ACCOUNT_MEMBER": "Here you can consult your account status, transaction history and your certifications.", "WALLET_CERTIFICATIONS": "Click here to reveiw the details of your certifications (given and received).", - "WALLET_RECEIVED_CERTIFICATIONS": "Click here to reveiw the details of your <b>received certifications</b>.", - "WALLET_GIVEN_CERTIFICATIONS": "Click here to reveiw the details of your <b>given certifications</b>.", "WALLET_BALANCE": "Your account <b>balance</b> is shown here.", "WALLET_BALANCE_RELATIVE": "{{'HELP.TIP.WALLET_BALANCE'|translate}}<br/><br/>The used unit (“<b>{{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub></b>”) signifies that the amount in {{currency|capitalize}} has been divided by the <b>Universal Dividend</b> (UD) co-created by each member.<br/>At this moment, 1 UD equals {{currentUD}} {{currency|capitalize}}.", "WALLET_BALANCE_CHANGE_UNIT": "You can <b>change the unit</b> in which amounts are shown in <b><i class=\"icon ion-android-settings\"></i> {{'MENU.SETTINGS'|translate}}</b>.<br/><br/>For example, to display amounts <b>directly in {{currency|capitalize}}</b> instead of relative amounts.", - "WALLET_PUBKEY": "This is your account public key. You can communicate it to a third party so that it more easily identifies your account.", "WALLET_SEND": "Issue a payment in just a few clicks.", "WALLET_SEND_NO_MONEY": "Issue a payment in just a few clicks.<br/>(Your balance does not allow this yet)", "WALLET_OPTIONS": "Please note that this button allows access to <b>other, less used actions</b>.<br/><br/>Don't forget to take a quick look, when you have a moment!", "WALLET_RECEIVED_CERTS": "This shows the list of persons that certified you.", "WALLET_CERTIFY": "The button <b>{{'WOT.BTN_SELECT_AND_CERTIFY'|translate}}</b> allows selecting an identity and certifying it.<br/><br/>Only users that are <b>already member</b> may certify others.", "WALLET_CERT_STOCK": "Your supply of certifications (to send) is limited to <b>{{sigStock}} certifications</b>.<br/><br/>This supply will replete itself over time, as and when earlier certifications expire.", - "MENU_BTN_TX_MEMBER": "<b>{{'MENU.TRANSACTIONS'|translate}}</b> allow access to transactions history, and send new payments.", - "MENU_BTN_TX": "Consultez ici l'historique vos transactions et envoyez de nouveaux paiements.", "MENU_BTN_WOT": "The menu <b>{{'MENU.WOT'|translate}}</b> allows searching <b>users</b> of the currency (member or not).", "WOT_SEARCH_TEXT_XS": "To search in the registry, type the <b>first letters of a users pseudonym or public key</b>.<br/><br/>The search will start automatically.", "WOT_SEARCH_TEXT": "To search in the registry, type the <b>first letters of a users pseudonym or public key</b>.<br/><br/>Then hit <b>Enter</b> to start the search.", diff --git a/www/i18n/locale-fr-FR.json b/www/i18n/locale-fr-FR.json index 1db5f23f4a6237b1ae42b05c7ac825d8faa2aecb..2dd7f82c1a78cf722c49cad2519267a3892346c6 100644 --- a/www/i18n/locale-fr-FR.json +++ b/www/i18n/locale-fr-FR.json @@ -357,7 +357,7 @@ "ADD_QUESTION" : "Ajouter une question personnalisée ", "BTN_CLEAN" : "Vider", "BTN_RESET" : "Réinitialiser", - "CHOOSE_FILE" : "Déposez votre fichier de sauvegarde <br/>ou cliquez pour le sélectionner", + "CHOOSE_FILE" : "Déposez votre fichier <br/>ou cliquez pour le sélectionner", "DEFINITELY_REVOKE" : "Revoquer définitivement cette identité", "DOWNLOAD_REVOKE": "Sauvegarder un fichier de revocation", "HELP_LEVEL": "Pour générer un fichier de sauvegarde de vos identifiants, choisissez <strong> au moins {{nb}} questions :</strong>", @@ -385,7 +385,8 @@ "QUESTION_19": "Quel était le métier de votre grand-père ?", "RECOVER_ID": "Recupérer vos identifiants", "REVOCATION": "Révocation ...", - "REVOKE" : "Revoquer cette identité", + "REVOKE" : "Révoquer cette identité", + "REVOKE_WITH_FILE" : "Révoquer une identité à partir d'un fichier", "SAVE_ID": "Sauvegarder vos identifiants", "STRONG_LEVEL": "Fort <span class=\"hidden-xs \">(6 questions minimum)</span>", "TITLE": "Compte et sécurité" diff --git a/www/js/controllers/wallet-controllers.js b/www/js/controllers/wallet-controllers.js index 2163b97fc493d1b97b2e7c5183cb4722d29975d7..e3ae2da26b111adf76af6e70a4bdd08c43d575c0 100644 --- a/www/js/controllers/wallet-controllers.js +++ b/www/js/controllers/wallet-controllers.js @@ -772,6 +772,12 @@ function WalletSecurityModalController($scope, $rootScope, UIUtils, csWallet, $t element.answer = undefined; }) } + + else if ($scope.slides.slider.activeIndex === 2 && $scope.option === 'revocation'){ + $scope.isValidFile = false; + $scope.hasContent = false; + $scope.revocation = undefined; + } }; /** @@ -781,10 +787,9 @@ function WalletSecurityModalController($scope, $rootScope, UIUtils, csWallet, $t $scope.recoverContent = function(file) { $scope.hasContent = angular.isDefined(file) && file !== ''; $scope.fileData = file.fileData ? file.fileData : ''; - $scope.fileData.type = /^image/.test($scope.fileData.type) ? 'image' : $scope.fileData.type; $scope.isValidFile = $scope.fileData !== '' && $scope.fileData.type == 'text/plain'; - if ($scope.isValidFile) { + if ($scope.isValidFile && $scope.option === 'recoverID') { $scope.content = file.fileContent.split('\n'); var indexOfQuestions = _.indexOf($scope.content, 'Questions: '); var LastIndexQuestions = -1; @@ -810,6 +815,9 @@ function WalletSecurityModalController($scope, $rootScope, UIUtils, csWallet, $t $scope.recover.questions.push({value: $scope.content[i]}); } } + else if ($scope.isValidFile && $scope.option === "revocation"){ + $scope.revocation = file.fileContent; + } }; $scope.recoverId = function(){ @@ -894,6 +902,13 @@ function WalletSecurityModalController($scope, $rootScope, UIUtils, csWallet, $t return questionChecked.length < $scope.formData.level; }; + $scope.revokeWithFile = function(){ + if ($scope.slides.slider.activeIndex === 2 && $scope.option === "revocation" && $scope.isValidFile){ + console.debug($scope.revocation); + $scope.revokeIdentity(); + } + } + /** * Download revocation file */ @@ -905,7 +920,7 @@ function WalletSecurityModalController($scope, $rootScope, UIUtils, csWallet, $t * Revoke identity */ $scope.revokeIdentity = function (confirm, confirmAgain) { - if ($rootScope.formData.requirements.needSelf) { + if ($rootScope.walletData.requirements.needSelf) { return UIUtils.alert.error("ERROR.ONLY_SELF_CAN_EXECUTE_THIS_ACTION"); } if (!confirm) { @@ -931,10 +946,16 @@ function WalletSecurityModalController($scope, $rootScope, UIUtils, csWallet, $t return UIUtils.loading.show() .then(function () { - return csWallet.revoke(); + if (!$scope.revocation){ + return csWallet.revoke(); + } + else { + return csWallet.revokeWithFile($scope.revocation) + } }) .then(function () { UIUtils.toast.show("INFO.REVOCATION_SENT"); + $scope.revocation = undefined; $scope.updateView(); return UIUtils.loading.hide(); }) @@ -942,4 +963,14 @@ function WalletSecurityModalController($scope, $rootScope, UIUtils, csWallet, $t UIUtils.onError('ERROR.REVOCATION_FAILED')(err); }); }; + + // Update view + $scope.updateView = function() { + // Set Motion + $timeout(function() { + UIUtils.motion.fadeSlideInRight({selector: '#wallet .animate-fade-slide-in-right .item'}); + // Set Ink + UIUtils.ink({selector: '#wallet .animate-fade-slide-in-right .item'}); + }, 10); + }; } diff --git a/www/js/services/wallet-services.js b/www/js/services/wallet-services.js index ad5ddd3d6c554e491593d7677643f8036ce37b2c..d9411f51d8033a9a5a63cbd79b2b28f320a3d516 100644 --- a/www/js/services/wallet-services.js +++ b/www/js/services/wallet-services.js @@ -1438,74 +1438,74 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser }); }, - getCryptedId = function(record){ - return getkeypairSaveId(record) - .then(function() { - return CryptoUtils.util.random_nonce() - }) - .then(function(nonce) { - record.nonce = nonce; - return CryptoUtils.box.pack(record.salt, record.nonce, record.keypair.boxPk, record.keypair.boxSk) - }) - .then(function (cypherSalt) { - record.salt = cypherSalt; - return CryptoUtils.box.pack(record.pwd, record.nonce, record.keypair.boxPk, record.keypair.boxSk) - }) - .then(function (cypherPwd) { - record.pwd = cypherPwd; - record.nonce = CryptoUtils.util.encode_base58(record.nonce); - return record; - }); - }, + getCryptedId = function(record){ + return getkeypairSaveId(record) + .then(function() { + return CryptoUtils.util.random_nonce() + }) + .then(function(nonce) { + record.nonce = nonce; + return CryptoUtils.box.pack(record.salt, record.nonce, record.keypair.boxPk, record.keypair.boxSk) + }) + .then(function (cypherSalt) { + record.salt = cypherSalt; + return CryptoUtils.box.pack(record.pwd, record.nonce, record.keypair.boxPk, record.keypair.boxSk) + }) + .then(function (cypherPwd) { + record.pwd = cypherPwd; + record.nonce = CryptoUtils.util.encode_base58(record.nonce); + return record; + }); + }, - recoverId = function(recover) { - var nonce = CryptoUtils.util.decode_base58(recover.cypherNonce); - return getkeypairSaveId(recover) - .then(function (recover) { - return CryptoUtils.box.open(recover.cypherSalt, nonce, recover.keypair.boxPk, recover.keypair.boxSk) - }) - .then(function (salt) { - recover.salt = salt; - return CryptoUtils.box.open(recover.cypherPwd, nonce, recover.keypair.boxPk, recover.keypair.boxSk) - }) - .then(function (pwd) { - recover.pwd = pwd; - return recover; - }) - .catch(function(err){ - console.warn('Incorrect answers - Unable to recover passwords'); - }); - }, + recoverId = function(recover) { + var nonce = CryptoUtils.util.decode_base58(recover.cypherNonce); + return getkeypairSaveId(recover) + .then(function (recover) { + return CryptoUtils.box.open(recover.cypherSalt, nonce, recover.keypair.boxPk, recover.keypair.boxSk) + }) + .then(function (salt) { + recover.salt = salt; + return CryptoUtils.box.open(recover.cypherPwd, nonce, recover.keypair.boxPk, recover.keypair.boxSk) + }) + .then(function (pwd) { + recover.pwd = pwd; + return recover; + }) + .catch(function(err){ + console.warn('Incorrect answers - Unable to recover passwords'); + }); + }, - getSaveIDDocument = function(record) { - var saveId = 'Version: 10 \n' + - 'Type: SaveID\n' + - 'Questions: ' + '\n' + record.questions + - 'Issuer: ' + data.pubkey + '\n' + - 'Crypted-Nonce: '+ record.nonce + '\n'+ - 'Crypted-Pubkey: '+ record.pubkey +'\n' + - 'Crypted-Salt: '+ record.salt + '\n' + - 'Crypted-Pwd: '+ record.pwd + '\n'; + getSaveIDDocument = function(record) { + var saveId = 'Version: 10 \n' + + 'Type: SaveID\n' + + 'Questions: ' + '\n' + record.questions + + 'Issuer: ' + data.pubkey + '\n' + + 'Crypted-Nonce: '+ record.nonce + '\n'+ + 'Crypted-Pubkey: '+ record.pubkey +'\n' + + 'Crypted-Salt: '+ record.salt + '\n' + + 'Crypted-Pwd: '+ record.pwd + '\n'; - // Sign SaveId document - return CryptoUtils.sign(saveId, data.keypair) + // Sign SaveId document + return CryptoUtils.sign(saveId, data.keypair) - .then(function(signature) { - saveId += signature + '\n'; - console.debug('Has generate an SaveID document:\n----\n' + saveId + '----'); - return saveId; - }); + .then(function(signature) { + saveId += signature + '\n'; + console.debug('Has generate an SaveID document:\n----\n' + saveId + '----'); + return saveId; + }); - }, + }, - downloadSaveId = function(record){ - return getSaveIDDocument(record) - .then(function(saveId) { - var saveIdFile = new Blob([saveId], {type: 'text/plain; charset=utf-8'}); - FileSaver.saveAs(saveIdFile, 'saveID.txt'); - }); + downloadSaveId = function(record){ + return getSaveIDDocument(record) + .then(function(saveId) { + var saveIdFile = new Blob([saveId], {type: 'text/plain; charset=utf-8'}); + FileSaver.saveAs(saveIdFile, 'saveID.txt'); + }); - }, + }, getRevocationDocument = function() { @@ -1548,8 +1548,11 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser // Get revocation document return getRevocationDocument() + .then(function(revocation){ + console.debug(revocation); + }) - // Send revocation document +/* // Send revocation document .then(function(revocation) { return BMA.wot.revoke({revocation: revocation}); }) @@ -1577,7 +1580,35 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser throw err; } }) - ; + ;*/ + }, + + revokeWithFile = function(revocation){ + console.debug(revocation); + /*return BMA.wot.revoke({revocation: revocation}) + // Reload requirements + .then(function() { + return $timeout(function() { + return loadRequirements(); + }, 1000); // waiting for node to process membership doc + }) + + .then(function() { + finishLoadRequirements(); + + // Add user event + addEvent({type:'pending', message: 'INFO.REVOCATION_SENT_WAITING_PROCESS', context: 'revocation'}, true); + }) + .catch(function(err) { + if (err && err.ucode == BMA.errorCodes.REVOCATION_ALREADY_REGISTERED) { + // Already registered by node: just add an event + addEvent({type:'pending', message: 'INFO.REVOCATION_SENT_WAITING_PROCESS', context: 'revocation'}, true); + } + else { + throw err; + } + })*/ + }, downloadRevocation = function(){ @@ -1684,6 +1715,7 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser transfer: transfer, self: self, revoke: revoke, + revokeWithFile: revokeWithFile, downloadSaveId: downloadSaveId, getCryptedId: getCryptedId, recoverId: recoverId, diff --git a/www/templates/wallet/modal_security.html b/www/templates/wallet/modal_security.html index 01e0c94302ff3896c51f337ca6f758394facfd4f..3f1e6e73bdba3127b9b6ea2dcdc42472eeb371b4 100644 --- a/www/templates/wallet/modal_security.html +++ b/www/templates/wallet/modal_security.html @@ -43,7 +43,7 @@ <i class="icon ion-ios-arrow-right"></i> </div> <div class="item card item-icon-right stable-bg padding ink dark" - ng-click="selectOption('revocation')" ng-if="isLogin"> + ng-click="selectOption('revocation')"> <span ng-bind-html="'ACCOUNT.SECURITY.REVOCATION' | translate"></span> <i class="icon ion-ios-arrow-right"></i> </div> @@ -57,8 +57,11 @@ </ion-content> </ion-slide-page> - <ion-slide-page ng-if="isLogin && option == 'revocation'"> - <ng-include src="'templates/wallet/slides/slides_revocation.html'"></ng-include> + <ion-slide-page ng-if="option == 'revocation'"> + <ng-include src="'templates/wallet/slides/slides_revocation_1.html'"></ng-include> + </ion-slide-page> + <ion-slide-page ng-if="option == 'revocation'"> + <ng-include src="'templates/wallet/slides/slides_revocation_2.html'"></ng-include> </ion-slide-page> <ion-slide-page ng-if="isLogin && option == 'saveID'"> diff --git a/www/templates/wallet/slides/slides_revocation.html b/www/templates/wallet/slides/slides_revocation_1.html similarity index 69% rename from www/templates/wallet/slides/slides_revocation.html rename to www/templates/wallet/slides/slides_revocation_1.html index 348b6a86b8a96d54892a492650c51ff90f869ea0..e6d72fe152c2bf2f0bf3225d5021f5a577440387 100644 --- a/www/templates/wallet/slides/slides_revocation.html +++ b/www/templates/wallet/slides/slides_revocation_1.html @@ -3,12 +3,17 @@ <h3 translate>ACCOUNT.SECURITY.REVOCATION</h3> <div class="list"> <div class="item card item-icon-right stable-bg padding ink dark" - ng-click="downloadRevokeFile()"> + ng-click="downloadRevokeFile()" ng-if="isLogin"> <i class="icon ion-android-archive"></i> <span ng-bind-html="'ACCOUNT.SECURITY.DOWNLOAD_REVOKE' | translate"></span> </div> <div class="item card item-icon-right stable-bg padding ink dark" - ng-click="revokeIdentity()"> + ng-click="slideNext()"> + <i class="icon ion-ios-arrow-right"></i> + <span ng-bind-html="'ACCOUNT.SECURITY.REVOKE_WITH_FILE' | translate"></span> + </div> + <div class="item card item-icon-right stable-bg padding ink dark" + ng-click="revokeIdentity()" ng-if="isLogin"> <i class="icon ion-minus-circled assertive"></i> <span ng-bind-html="'ACCOUNT.SECURITY.DEFINITELY_REVOKE' | translate"></span> </div> diff --git a/www/templates/wallet/slides/slides_revocation_2.html b/www/templates/wallet/slides/slides_revocation_2.html new file mode 100644 index 0000000000000000000000000000000000000000..dd6320fea9644f10c5ba06cbea42e675dd8088d0 --- /dev/null +++ b/www/templates/wallet/slides/slides_revocation_2.html @@ -0,0 +1,39 @@ +<ion-content class="has-header padding" > + <h3 translate>ACCOUNT.SECURITY.REVOKE_WITH_FILE</h3> + + <div dropzone="recoverContent(file)"> + <div ng-if="!hasContent" onclick="angular.element(document.querySelector('#revocationFile'))[0].click();"> + <span translate>ACCOUNT.SECURITY.CHOOSE_FILE</span> + <input type="file" id="revocationFile" accept=".txt" + style="visibility:hidden; position:absolute;" on-read-file="recoverContent(file)"/> + </div> + + <div ng-if="hasContent" class="item row item-icon-left no-padding"> + <i class="icon ion-document-text gray"></i> + <div class="col"> + <span>{{fileData.name}}</span> + <br /> + <small>{{fileData.size}} Ko</small> + </div> + <div class="col-10"> + <b ng-class="{'ion-android-done balanced': isValidFile,'ion-android-close assertive': !isValidFile}" + style="font-size: 28px; position: relative; top: 6px;"></b> + <button class="button-icon ion-close-round gray pull-right" style="font-size:10px;" + ng-click="restore()"></button> + </div> + </div> + </div> + + <div class="padding hidden-xs text-right"> + <button class="button button-clear button-dark ink" ng-click="closeModal()" + type="button" translate>COMMON.BTN_CANCEL + </button> + <button class="button button-calm icon-right ion-chevron-right ink" + ng-click="revokeWithFile()" translate> + COMMON.BTN_NEXT + <i class="icon ion-arrow-right-a"></i> + </button> + </div> +</ion-content> + +