diff --git a/www/js/home-controller.js b/www/js/home-controller.js index 187c993ac26107a49a8ec2cb32b9d7229c4fc176..b9f1ebea9f2bb48a316729001bca1c1ba192f70e 100644 --- a/www/js/home-controller.js +++ b/www/js/home-controller.js @@ -101,25 +101,27 @@ function LoginController($scope, $ionicModal, Wallet, CryptoUtils, UIUtils, $q, UIUtils.loading.show(); // Call wallet login - Wallet.login($scope.loginData.username, $scope.loginData.password) - .catch(function(err) { - $scope.loginData = {}; // Reset login data - UIUtils.loading.hide(); - console.error('>>>>>>>' , err); - UIUtils.alert.error('Your browser is not compatible with cryptographic libraries.'); - }) - .then(function(){ - UIUtils.loading.hide(); - var callback = $scope.loginData.callback; - $scope.loginData = {}; // Reset login data - if (callback != "undefined" && callback != null) { - callback(); - } - // Default: redirect to wallet view - else { - $state.go('app.view_wallet'); - } - }); + $q.all([ + Wallet.login($scope.loginData.username, $scope.loginData.password) + .catch(function(err) { + $scope.loginData = {}; // Reset login data + UIUtils.loading.hide(); + console.error('>>>>>>>' , err); + UIUtils.alert.error('Your browser is not compatible with cryptographic libraries.'); + }) + .then(function(){ + UIUtils.loading.hide(); + var callback = $scope.loginData.callback; + $scope.loginData = {}; // Reset login data + if (callback != "undefined" && callback != null) { + callback(); + } + // Default: redirect to wallet view + else { + $state.go('app.view_wallet'); + } + }) + ]); }; $scope.loginDataChanged = function() { @@ -339,7 +341,7 @@ function LookupController($scope, BMA, $state) { } -function IdentityController($scope, $state, BMA) { +function IdentityController($scope, $state, BMA, Wallet, UIUtils, $q) { $scope.$on('$ionicView.enter', function(e, $state) { $scope.showIdentity($state.stateParams.pub); @@ -356,15 +358,42 @@ function IdentityController($scope, $state, BMA) { return uids.concat({ uid: idty.uid, pub: res.pubkey, - sigDate: idty.meta.timestamp + sigDate: idty.meta.timestamp, + sig: idty.self }) }, [])); }, [])[0]; }) }; - $scope.signIdentity = function() { - alert('signIdentity'); + $scope.hasSelf = function() { + return ($scope.identity.uid + && $scope.identity.sigDate + && $scope.identity.sig); + } + + $scope.signIdentity = function(identity) { + $scope.loadWallet() + .then(function(walletData) { + UIUtils.loading.show(); + Wallet.sign($scope.identity.uid, + $scope.identity.pub, + $scope.identity.sigDate, + $scope.identity.sig) + .then(function() { + UIUtils.loading.hide(); + alert('Identity signed'); + }) + .catch(function(err) { + console.error('>>>>>>>' , err); + UIUtils.alert.error('Error while signing identity: ' + err); + UIUtils.loading.hide(); + }); + }) + .catch(function(err) { + console.error('>>>>>>>' , err); + UIUtils.alert.error('Error while signing identity: ' + err); + }); }; // Transfer click @@ -586,11 +615,12 @@ function HomeController($scope, $ionicSlideBoxDelegate, $ionicModal, $state, BMA } -function WalletController($scope, $state) { +function WalletController($scope, $state, $q, UIUtils, Wallet, $ionicPopup) { $scope.walletData = {}; $scope.convertedBalance = 0; $scope.hasCredit = false; + $scope.isMember = false; $scope.$on('$ionicView.enter', function(e, $state) { $scope.loadWallet() @@ -617,6 +647,7 @@ function WalletController($scope, $state) { $scope.updateWalletView = function(wallet) { $scope.walletData = wallet; $scope.hasCredit = $scope.walletData.balance != "undefined" && ($scope.walletData.balance > 0); + $scope.isMember = (wallet.requirements != null); }; // Has credit @@ -628,8 +659,48 @@ function WalletController($scope, $state) { $scope.transfer= function() { $state.go('app.view_transfer'); }; -} + // Self cert + $scope.self= function() { + + // ASk uid + $ionicPopup.show({ + template: '<input type="text" ng-model="walletData.uid">', + title: 'Enter Pseudo', + subTitle: 'Pseudo is used by other member member to find you', + scope: $scope, + buttons: [ + { text: 'Cancel' }, + { + text: '<b>Send</b>', + type: 'button-positive', + onTap: function(e) { + if (!$scope.walletData.uid) { + //don't allow the user to close unless he enters wifi password + e.preventDefault(); + } else { + return $scope.walletData.uid; + } + } + } + ] + }) + .then(function(uid) { + UIUtils.loading.show(); + Wallet.self(uid) + .then(function() { + UIUtils.loading.hide(); + }) + .catch(function(err) { + console.error('>>>>>>>' , err); + UIUtils.alert.error('Error while sending self certification: ' + err); + UIUtils.loading.hide(); + }); + }); + + + }; +} function TransferController($scope, $ionicModal, Wallet, UIUtils, $state, $ionicHistory) { diff --git a/www/js/services.js b/www/js/services.js index 2026df87f265c4d4ca344c8a56d3f54b69e9fb2b..9a47e67a40088129a2553f145b330c088d610bf3 100644 --- a/www/js/services.js +++ b/www/js/services.js @@ -90,7 +90,9 @@ angular.module('cesium.services', ['ngResource']) return { wot: { lookup: getResource('http://' + server + '/wot/lookup/:search'), - members: getResource('http://' + server + '/wot/members') + members: getResource('http://' + server + '/wot/members'), + requirements: getResource('http://' + server + '/wot/requirements/:pubkey'), + add: postResource('http://' + server + '/wot/add') }, network: { peering: { @@ -107,7 +109,8 @@ angular.module('cesium.services', ['ngResource']) stats: { ud: getResource('http://' + server + '/blockchain/with/ud'), tx: getResource('http://' + server + '/blockchain/with/tx') - } + }, + membership: postResource('http://' + server + '/blockchain/membership'), }, tx: { @@ -129,9 +132,9 @@ angular.module('cesium.services', ['ngResource']) } } } - //var service = BMA('metab.ucoin.fr', 'metab.ucoin.fr:9201'); + var service = BMA('metab.ucoin.fr', 'metab.ucoin.fr:9201'); //var service = BMA('192.168.0.28:9201'); - var service = BMA('metab.ucoin.io'); + //var service = BMA('metab.ucoin.io'); service.instance = BMA; return service; }) @@ -369,6 +372,7 @@ angular.module('cesium.services', ['ngResource']) createData = function() { return { + uid: null, pubkey: null, keypair: { signSk: null, @@ -380,7 +384,8 @@ angular.module('cesium.services', ['ngResource']) currency: null, currentUD: null, history: {}, - loaded: false + loaded: false, + requirements: null }; }, @@ -458,7 +463,7 @@ angular.module('cesium.services', ['ngResource']) return $q(function(resolve, reject){ data.loaded = false; - console.log('calling loadData'); + //console.log('calling loadData'); $q.all([ // Get currency parameters @@ -494,6 +499,20 @@ angular.module('cesium.services', ['ngResource']) data.balance = balance; }), + // Get requirements + BMA.wot.requirements({pubkey: data.pubkey}) + .then(function(res){ + if (res.identities != "undefined" + && res.identities != null + && res.identities.length == 1) { + data.requirements = res.identities[0]; + data.uid = res.identities[0].uid; + } + }) + .catch(function(err) { + data.requirements = null; + }), + // Get transactions BMA.tx.history.all({pubkey: data.pubkey}) .then(function(res){ @@ -518,7 +537,7 @@ angular.module('cesium.services', ['ngResource']) ]) .then(function() { data.loaded = true; - resolve(data); + resolve(data); }) .catch(function(err) { data.loaded = false; @@ -545,6 +564,23 @@ angular.module('cesium.services', ['ngResource']) } }), + // Get requirements + BMA.wot.requirements({pubkey: data.pubkey}) + .then(function(res){ + if (res.identities != "undefined" + && res.identities != null + && res.identities.length == 1) { + data.requirements = res.identities[0]; + data.uid = res.identities[0].uid; + } + else { + data.requirements = null; + } + }) + .catch(function(err) { + data.requirements = null; + }), + // Get sources BMA.tx.sources({pubkey: data.pubkey}) .then(function(res){ @@ -660,6 +696,96 @@ angular.module('cesium.services', ['ngResource']) }); } + /** + * Send self certification + */ + self = function(uid) { + return $q(function(resolve, reject) { + + BMA.blockchain.current() + .then(function(block) { + // Create the self part to sign + var self = 'UID:' + uid + '\n' + + 'META:TS:' + (block.time+1) + '\n'; + + CryptoUtils.sign(self, data.keypair) + .then(function(signature) { + var signedSelf = self + signature + '\n'; + // Send self + BMA.wot.add({pubkey: data.pubkey, self: signedSelf, other: ''}) + .then(function(result) { + // Check requirements + BMA.wot.requirements({pubkey: data.pubkey}) + .then(function(res){ + if (res.identities != "undefined" + && res.identities != null + && res.identities.length == 1) { + data.requirements = res.identities[0]; + data.uid = uid; + resolve(); + } + else{ + reject(); + } + }) + .catch(function(err) { + reject(); + }) + }) + .catch(function(err){ + reject(err); + }); + }) + .catch(function(err){ + reject(err); + }); + }) + .catch(function(err) { + reject(err); + }); + }); + }, + + /** + * Send identity certification + */ + sign = function(uid, pubkey, timestamp, signature) { + return $q(function(resolve, reject) { + + BMA.blockchain.current() + .then(function(block) { + // Create the self part to sign + var self = 'UID:' + uid + '\n' + + 'META:TS:' + timestamp + '\n' + + signature /*+"\n"*/; + + var cert = self + '\n' + + 'META:TS:' + block.number + '-' + block.hash + '\n'; + + CryptoUtils.sign(cert, data.keypair) + .then(function(signature) { + var inlineCert = data.pubkey + + ':' + pubkey + + ':' + block.number + + ':' + signature + '\n'; + BMA.wot.add({pubkey: pubkey, self: self, other: inlineCert}) + .then(function(result) { + resolve(result); + }) + .catch(function(err){ + reject(err); + }); + }) + .catch(function(err){ + reject(err); + }); + }) + .catch(function(err) { + reject(err); + }); + }); + }, + /** * Serialize to JSON string */ @@ -711,7 +837,9 @@ angular.module('cesium.services', ['ngResource']) fromJson: fromJson, loadData: loadData, refreshData: refreshData, - transfer: transfer + transfer: transfer, + self: self, + sign: sign } } var service = Wallet('default'); diff --git a/www/templates/account/view_wallet.html b/www/templates/account/view_wallet.html index 5b91218a84e7c70608bc435783793d3fc64eed04..ee491dd0183f1cc5ddb5e72cf3f24b1102e8fb8e 100644 --- a/www/templates/account/view_wallet.html +++ b/www/templates/account/view_wallet.html @@ -2,7 +2,14 @@ <ion-content> <div class="scroll"> <div class="list"> - <span class="item item-icon-left"> + + <span class="item item-icon-left" ng-if="isMember"> + <i class="icon ion-person"></i> + User + <span class="badge">{{walletData.uid}}</span> + </span> + + <span class="item item-icon-left" ng-if="!isMember"> <i class="icon ion-key"></i> Pubkey <span class="badge">{{walletData.pubkey | formatPubkey}}</span> @@ -15,7 +22,6 @@ <span class="badge badge-balanced" ng-if="walletData.useRelative">{{convertedBalance | formatDecimal}} {{unit | abbreviate}}<sub>{{udUnit | abbreviate}}</sub></span> </span> - <div class="item item-toggle dark"> Use Relative Unit (UD) <label class="toggle toggle-royal"> @@ -37,6 +43,13 @@ </a> </div> + <div class="item item-button-right positive" ng-if="!isMember" ng-click="self()"> + Send self certification + <a class="button button-clear button-positive" > + <i class="icon-right ion-chevron-right"></i> + </a> + </div> + <div class="item"> </div> diff --git a/www/templates/wot/view_identity.html b/www/templates/wot/view_identity.html index a018e468b340736f1b23d5c3b80653ac42134f90..bc61831df776c8cf68dd41c589196e216bb73e75 100644 --- a/www/templates/wot/view_identity.html +++ b/www/templates/wot/view_identity.html @@ -30,16 +30,17 @@ <i class="icon-right ion-chevron-right"></i> </a> </div> - <div class="item item-button-right positive" ng-click="signIdentity()"> + + <div class="item item-button-right positive" ng-click="signIdentity()" ng-if="hasSelf"> Certify <a class="button button-clear button-positive" > <i class="icon-right ion-chevron-right"></i> </a> </div> - <div class="item item-divider" ng-if="isLogged()"> + <!--div class="item item-divider" ng-if="isLogged()"> Last transactions - </div> + </div--> </div> <div class="scroll-bar scroll-bar-v"></div>