diff --git a/2fa b/2fa deleted file mode 100644 index fc4ff15d6..000000000 --- a/2fa +++ /dev/null @@ -1,18 +0,0 @@ - - -- 2-2 - 1 desktop - 1 mobile - - - each device creates its own key - - both devices are expected to be logged using the same profile (email / password) - - if using local storage -> all is OK. - - keys will be safe an will never leave the device - - - if using insight - both 'copayers' need to have a new and different password for accessing the wallet. - - - - - - diff --git a/css/src/main.css b/css/src/main.css index 0bcd192a0..a693ef294 100644 --- a/css/src/main.css +++ b/css/src/main.css @@ -81,7 +81,7 @@ header .alt-currency { color: #fff; } -.panel h3, .box-setup h3 { +.panel h3 { font-weight: 700; font-size: 16px; color: #2C3E50; @@ -362,13 +362,6 @@ a:hover { color: #8597A7; } -.box-setup { - margin-bottom: 1rem; - padding: 1.3rem; - border-radius: 3px; - background: #fff; -} - .box-setup-footer { overflow: hidden; margin-top: 1rem; @@ -403,6 +396,13 @@ a:hover { background-color: #C0392A; } +.box-notification a.close-notification { + position: absolute; + top: 8px; + right: 10px; + font-size: 24px; +} + .panel.last-transactions { padding: 0; margin-bottom: 2.25rem; @@ -971,8 +971,9 @@ table tbody tr:last-child td { border-bottom: none; } -table tr.deleting { - background: #FCD5D5; +table.manage-wallets tr:hover { + background-color: #eee; + cursor: pointer; } input[type=date], input[type=datetime-local], input[type=datetime], input[type=email], input[type=month], input[type=number], input[type=password], input[type=search], input[type=tel], input[type=text], input[type=time], input[type=url], input[type=week], textarea { @@ -1425,18 +1426,12 @@ a.text-warning:hover {color: #FD7262;} background-color: #1ABC9C; } -.box-setup .panel { +.panel { background-color: #2C3E50; padding: 1rem; border: 0; } -.box-setup h1 { - font-size: 16px; - text-transform: uppercase; - text-align: center; -} - .panel qrcode { background-color: white; } diff --git a/js/controllers/home.js b/js/controllers/home.js index abe9744b8..045683eab 100644 --- a/js/controllers/home.js +++ b/js/controllers/home.js @@ -148,6 +148,7 @@ angular.module('copayApp.controllers').controller('HomeController', function($sc $scope.error = 'Unknown error'; } $rootScope.starting = false; + $scope.loading = null; $timeout(function(){ $rootScope.$digest(); },1) diff --git a/js/controllers/profile.js b/js/controllers/profile.js index ee9bfc576..06fbf4e1a 100644 --- a/js/controllers/profile.js +++ b/js/controllers/profile.js @@ -1,7 +1,7 @@ 'use strict'; -angular.module('copayApp.controllers').controller('ProfileController', function($scope, $rootScope, $location, $modal, $filter, $timeout, backupService, identityService) { +angular.module('copayApp.controllers').controller('ProfileController', function($scope, $rootScope, $location, $modal, $filter, $timeout, backupService, identityService, isMobile) { $scope.username = $rootScope.iden.getName(); - $scope.isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0; + $scope.isSafari = isMobile.Safari(); $rootScope.title = 'Profile'; $scope.hideAdv = true; @@ -13,18 +13,7 @@ angular.module('copayApp.controllers').controller('ProfileController', function( $scope.viewProfileBackup = function() { $scope.backupProfilePlainText = backupService.profileEncrypted($rootScope.iden); $scope.hideViewProfileBackup = true; - }; - - $scope.deleteWallet = function(w) { - if (!w) return; - identityService.deleteWallet(w, function(err) { - $scope.loading = false; - if (err) { - copay.logger.warn(err); - } - $scope.setWallets(); - }); - }; + }; $scope.init = function() { @@ -52,30 +41,7 @@ angular.module('copayApp.controllers').controller('ProfileController', function( $timeout(function(){ $scope.$digest(); }) - }; - - $scope.downloadWalletBackup = function(w) { - if (!w) return; - backupService.walletDownload(w); - } - - $scope.viewWalletBackup = function(w) { - var ModalInstanceCtrl = function($scope, $modalInstance) { - - if (!w) return; - $scope.backupWalletPlainText = backupService.walletEncrypted(w); - $scope.hideViewWalletBackup = true; - $scope.cancel = function() { - $modalInstance.dismiss('cancel'); - }; - }; - - $modal.open({ - templateUrl: 'views/modals/backup-text.html', - windowClass: 'tiny', - controller: ModalInstanceCtrl - }); - }; + }; $scope.deleteProfile = function() { identityService.deleteProfile(function(err, res) { @@ -90,4 +56,53 @@ angular.module('copayApp.controllers').controller('ProfileController', function( }, 1); }); }; + + $scope.showWalletInfo = function(w) { + var ModalInstanceCtrl = function($scope, $modalInstance) { + if (!w) return; + $scope.isSafari = isMobile.Safari(); + $scope.item = w; + $scope.error = null; + $scope.success = null; + + $scope.deleteWallet = function() { + + $scope.loading = true; + identityService.deleteWallet($scope.item, function(err) { + if (err) { + $scope.loading = null; + $scope.error = err.message; + copay.logger.warn(err); + } + else { + $modalInstance.close($scope.item.name || $scope.item.id); + } + }); + }; + + $scope.downloadWalletBackup = function() { + backupService.walletDownload($scope.item); + }; + + $scope.viewWalletBackup = function() { + $scope.backupWalletPlainText = backupService.walletEncrypted($scope.item); + }; + + $scope.close = function() { + $modalInstance.dismiss('cancel'); + }; + }; + + var modalInstance = $modal.open({ + templateUrl: 'views/modals/wallet-info.html', + windowClass: 'tiny', + controller: ModalInstanceCtrl + }); + + modalInstance.result.then(function(walletName) { + $scope.loading = false; + $scope.success = 'The wallet "' + walletName + '" was deleted'; + $scope.setWallets(); + }); + }; }); diff --git a/js/services/identityService.js b/js/services/identityService.js index 5620e8e49..711d15301 100644 --- a/js/services/identityService.js +++ b/js/services/identityService.js @@ -120,7 +120,7 @@ angular.module('copayApp.services') }; root.deleteWallet = function(w, cb) { - $rootScope.iden.deleteWallet(w.id, cb); + $rootScope.iden.deleteWallet(w.getId(), cb); }; root.isFocused = function(wid) { diff --git a/js/services/isMobile.js b/js/services/isMobile.js index 1a859064d..ad0ffb81a 100644 --- a/js/services/isMobile.js +++ b/js/services/isMobile.js @@ -17,6 +17,9 @@ var isMobile = { Windows: function() { return !!navigator.userAgent.match(/IEMobile/i); }, + Safari: function() { + return Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0; + }, any: function() { return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows()); } diff --git a/test/unit/controllers/controllersSpec.js b/test/unit/controllers/controllersSpec.js index 80c1151a4..606d9c1f3 100644 --- a/test/unit/controllers/controllersSpec.js +++ b/test/unit/controllers/controllersSpec.js @@ -16,7 +16,7 @@ describe("Unit: Controllers", function() { config.plugins.LocalStorage = true; config.plugins.GoogleDrive = null; config.plugins.InsightStorage = null; - config.plugins.EncryptedInsightStorage= null; + config.plugins.EncryptedInsightStorage = null; var anAddr = 'mkfTyEk7tfgV611Z4ESwDDSZwhsZdbMpVy'; var anAmount = 1000; @@ -50,6 +50,10 @@ describe("Unit: Controllers", function() { $rootScope.safeUnspentCount = 1; $rootScope.pendingTxCount = 0; + // + // TODO Use the REAL wallet, and stub only networking and DB components! + // + var w = {}; w.id = 1234; w.isComplete = sinon.stub().returns(true); @@ -92,7 +96,9 @@ describe("Unit: Controllers", function() { 'e': 'errmsg', 'loading': false }); - w.sizes = sinon.stub().returns({tota:1234}); + w.sizes = sinon.stub().returns({ + tota: 1234 + }); w.getBalance = sinon.stub().returns(10000); w.publicKeyRing = sinon.stub().yields(null); w.publicKeyRing.nicknameForCopayer = sinon.stub().returns('nickcopayer'); @@ -103,11 +109,11 @@ describe("Unit: Controllers", function() { }]); var iden = {}; - iden.deleteWallet = sinon.stub().yields(null); iden.getLastFocusedWallet = sinon.stub().returns(null); iden.listWallets = sinon.stub().returns([w]); iden.getWalletById = sinon.stub().returns(w); iden.getName = sinon.stub().returns('name'); + iden.deleteWallet = sinon.stub(); $rootScope.wallet = w; $rootScope.iden = iden; @@ -561,20 +567,35 @@ describe("Unit: Controllers", function() { }); describe('Profile Controller', function() { - var ctrl, scope; + var ctrl, inScope, modalCtrl; beforeEach(inject(function($controller, $rootScope) { scope = $rootScope.$new(); ctrl = $controller('ProfileController', { $scope: scope, - $modal: {}, + $modal: { + open: function(opts) { + inScope = $rootScope.$new(); + modalCtrl = opts.controller(inScope, { + close: sinon.stub(), + }); + return { + result: { + then: sinon.stub(), + } + }; + }, + }, }); saveAsLastCall = null; + })); it('Backup Wallet controller #download', function() { var w = scope.wallet; expect(saveAsLastCall).equal(null); - scope.downloadWalletBackup(w); + scope.showWalletInfo(w); + inScope.downloadWalletBackup(); + expect(saveAsLastCall.blob.size).equal(7); expect(saveAsLastCall.blob.type).equal('text/plain;charset=utf-8'); }); @@ -582,7 +603,8 @@ describe("Unit: Controllers", function() { it('Backup Wallet controller should name backup correctly for multiple copayers', function() { var w = scope.wallet; expect(saveAsLastCall).equal(null); - scope.downloadWalletBackup(w); + scope.showWalletInfo(w); + inScope.downloadWalletBackup(); expect(saveAsLastCall.filename).equal('nickname-fakeWallet-keybackup.json.aes'); }); @@ -590,16 +612,19 @@ describe("Unit: Controllers", function() { var w = scope.wallet; expect(saveAsLastCall).equal(null); scope.wallet.totalCopayers = 1; - scope.downloadWalletBackup(w); + scope.showWalletInfo(w); + inScope.downloadWalletBackup(); expect(saveAsLastCall.filename).equal('fakeWallet-keybackup.json.aes'); }); it('Delete a wallet', function() { var w = scope.wallet; - scope.deleteWallet(w, function() { - scope.$digest(); - expect(scope.wallet).equal(null); - }); + + scope.showWalletInfo(w); + inScope.deleteWallet(); + scope.$digest(); + scope.iden.deleteWallet.calledOnce.should.equal(true); + scope.iden.deleteWallet.getCall(0).args[0].should.equal(w.getId()); }); }); diff --git a/views/home.html b/views/home.html index 268c39882..44ece6ac5 100644 --- a/views/home.html +++ b/views/home.html @@ -26,7 +26,7 @@
-
| Name | Type | -Balance | -Approx Size | -Actions | + +|
|---|---|---|---|---|---|
| {{item.name || item.id }} | + ng-init="isComplete = item.isComplete(); networkName = item.getNetworkName()" + ng-click="showWalletInfo(item)"> ++ + + {{item.name || item.id }} + + | {{item.requiredCopayers}} of {{item.totalCopayers}} - {{networkName}} | -+ | -+ | - -- - - |