refactor lock warning and add tests

This commit is contained in:
Matias Alejo Garcia 2014-08-12 15:26:15 -04:00
parent fb3a7191e5
commit 35ab711846
13 changed files with 660 additions and 585 deletions

View File

@ -112,6 +112,7 @@
<script src="js/controllers/settings.js"></script>
<script src="js/controllers/uriPayment.js"></script>
<script src="js/controllers/version.js"></script>
<script src="js/controllers/warning.js"></script>
<!-- PLACEHOLDER: CORDOVA SRIPT -->
<script src="js/mobile.js"></script>

View File

@ -1,7 +1,6 @@
'use strict';
angular.module('copayApp.controllers').controller('SidebarController',
function($scope, $rootScope, $sce, $location, $http, notification, controllerUtils) {
angular.module('copayApp.controllers').controller('SidebarController', function($scope, $rootScope, $sce, $location, $http, notification, controllerUtils) {
$scope.menu = [{
'title': 'Receive',
@ -26,7 +25,9 @@ angular.module('copayApp.controllers').controller('SidebarController',
};
// Ensures a graceful disconnect
window.onbeforeunload = logout;
window.onbeforeunload = function() {
controllerUtils.logout();
};
$scope.$on('$destroy', function() {
window.onbeforeunload = undefined;
@ -73,18 +74,4 @@ angular.module('copayApp.controllers').controller('SidebarController',
notification.warning('Session closed', 'Session closed because a long time of inactivity');
});
}
$scope.checkIfWarning = function() {
if ($rootScope.wallet && !$rootScope.wallet.isLocked) {
controllerUtils.redirIfLogged();
}
};
$scope.ignoreLocked = function() {
if ($rootScope.wallet) {
$rootScope.wallet.isLocked = false;
controllerUtils.redirIfLogged();
}
};
});

28
js/controllers/warning.js Normal file
View File

@ -0,0 +1,28 @@
'use strict';
angular.module('copayApp.controllers').controller('WarningController', function($scope, $rootScope, $location, controllerUtils) {
$scope.checkLock = function() {
if (!$rootScope.tmp || !$rootScope.tmp.getLock()) {
controllerUtils.redirIfLogged();
}
};
$scope.signout = function() {
controllerUtils.logout();
};
$scope.ignoreLock = function() {
var w = $rootScope.tmp;
delete $rootScope['tmp'];
if (!w) {
$location.path('/');
} else {
w.ignoreLock = 1;
$scope.loading = true;
controllerUtils.startNetwork(w, $scope);
}
};
});

View File

@ -43,8 +43,8 @@ function Wallet(opts) {
this.id = opts.id || Wallet.getRandomId();
this.name = opts.name;
this.isLocked = false;
this.ignoreLock = opts.ignoreLock;
this.verbose = opts.verbose;
this.publicKeyRing.walletId = this.id;
this.txProposals.walletId = this.id;
@ -93,25 +93,25 @@ Wallet.prototype.connectToAll = function() {
}
};
Wallet.prototype.getIsOpen = function() {
return this.storage.getIsOpen(this.id);
Wallet.prototype.getLock = function() {
return this.storage.getLock(this.id);
};
Wallet.prototype.setIsOpen = function() {
return this.storage.setIsOpen(this.id);
Wallet.prototype.setLock = function() {
return this.storage.setLock(this.id);
};
Wallet.prototype.closeIfOpen = function() {
this.storage.removeIsOpen(this.id);
Wallet.prototype.unlock = function() {
this.storage.removeLock(this.id);
};
Wallet.prototype._checkLocked = function() {
if (this.getIsOpen()) {
this.isLocked = true;
}
else {
this.setIsOpen();
Wallet.prototype.checkAndLock = function() {
if (this.getLock()) {
return true;
}
this.setLock();
return false;
};
Wallet.prototype._handleIndexes = function(senderId, data, isInbound) {
@ -432,6 +432,12 @@ Wallet.prototype.netStart = function(callback) {
var self = this;
var net = this.network;
if (this.checkAndLock() && !this.ignoreLock) {
console.log('[Wallet.js.436] LOCKED' ); //TODO
this.emit('locked');
return;
}
net.removeAllListeners();
net.on('connect', self._handleConnect.bind(self));
@ -464,7 +470,6 @@ Wallet.prototype.netStart = function(callback) {
self.scheduleConnect();
self.emit('txProposalsUpdated');
}, 10);
self._checkLocked();
});
};
@ -1018,9 +1023,7 @@ Wallet.prototype.indexDiscovery = function(start, change, cosigner, gap, cb) {
Wallet.prototype.disconnect = function() {
this.log('## DISCONNECTING');
if (!this.isLocked) {
this.closeIfOpen();
}
this.unlock();
this.network.disconnect();
};

View File

@ -180,16 +180,16 @@ Storage.prototype.getLastOpened = function() {
return this.getGlobal('lastOpened');
}
Storage.prototype.setIsOpen = function(walletId) {
this.setGlobal(this._key(walletId, 'isOpen'), true);
Storage.prototype.setLock = function(walletId) {
this.setGlobal(this._key(walletId, 'Lock'), true);
}
Storage.prototype.getIsOpen = function(walletId) {
return this.getGlobal(this._key(walletId, 'isOpen'));
Storage.prototype.getLock = function(walletId) {
return this.getGlobal(this._key(walletId, 'Lock'));
}
Storage.prototype.removeIsOpen = function(walletId) {
this.localStorage.removeItem(this._key(walletId, 'isOpen'));
Storage.prototype.removeLock = function(walletId) {
this.removeGlobal(this._key(walletId, 'Lock'));
}
//obj contains keys to be set

View File

@ -83,16 +83,29 @@ angular
if (!util.supports.data) {
$location.path('unsupported');
} else {
// Locked?
if ($rootScope.showLockWarning) {
if ($rootScope.tmp) {
if ($location.path() !== '/warning') {
$location.path('/warning');
}
else {
delete $rootScope['showLockWarning'];
}
}
return;
}
if ((!$rootScope.wallet || !$rootScope.wallet.id) && next.validate) {
$idle.unwatch();
$location.path('/');
}
// In creation?
if ($rootScope.wallet && !$rootScope.wallet.isReady()) {
$location.path('/copayers');
}
if ($rootScope.wallet && $rootScope.wallet.isLocked) {
$location.path('/warning');
}
}
});
})

View File

@ -15,17 +15,20 @@ angular.module('copayApp.services')
};
root.redirIfLogged = function() {
var w = $rootScope.wallet;
if (w) {
$location.path('receive');
if ($rootScope.wallet) {
$rootScope.wallet.path('receive');
}
};
root.logout = function() {
if ($rootScope.wallet)
$rootScope.wallet.disconnect();
Socket.removeAllListeners();
$rootScope.wallet = null;
$rootScope.wallet = $rootScope.tmp = null;
delete $rootScope['wallet'];
video.close();
// Clear rootScope
for (var i in $rootScope) {
@ -69,6 +72,7 @@ angular.module('copayApp.services')
root.setupRootVariables = function() {
uriHandler.register();
$rootScope.unitName = config.unitName;
$rootScope.showLockWarning = false;
$rootScope.txAlertCount = 0;
$rootScope.insightError = 0;
$rootScope.isCollapsed = true;
@ -121,6 +125,12 @@ angular.module('copayApp.services')
};
notification.enableHtml5Mode(); // for chrome: if support, enable it
w.on('locked', function() {
$rootScope.tmp = w;
$rootScope.showLockWarning=true;
$location.path('/warning');
$rootScope.$digest();
});
w.on('badMessage', function(peerId) {
notification.error('Error', 'Received wrong message from peer ' + peerId);

View File

@ -27,16 +27,16 @@ FakeStorage.prototype.getLastOpened = function() {
return this.storage['lastOpened'];
};
FakeStorage.prototype.setIsOpen = function(id) {
this.storage[id + '::isOpen'] = true;
FakeStorage.prototype.setLock = function(id) {
this.storage[id + '::lock'] = true;
}
FakeStorage.prototype.getIsOpen = function(id) {
return this.storage[id + '::isOpen'];
FakeStorage.prototype.getLock = function(id) {
return this.storage[id + '::lock'];
}
FakeStorage.prototype.removeIsOpen = function(id) {
delete this[id + '::isOpen'];
FakeStorage.prototype.removeLock = function(id) {
delete this.storage[id + '::lock'];
}
FakeStorage.prototype.removeGlobal = function(id) {

View File

@ -181,6 +181,7 @@ describe('Wallet model', function() {
cachedW2obj.opts.reconnectDelay = 100;
}
var w = Wallet.fromObj(cachedW2obj, cachedW2.storage, cachedW2.network, cachedW2.blockchain);
w.unlock();
return w;
};
@ -1024,11 +1025,34 @@ describe('Wallet model', function() {
});
it('should check if wallet is already opened', function() {
var w = createW();
w._checkLocked();
w.isLocked.should.equal(false);
w._checkLocked();
w.isLocked.should.equal(true);
var w = cachedCreateW2();
should.not.exist(w.getLock());
w.checkAndLock().should.equal(false);
w.getLock().should.equal(true);
});
it('should check if wallet is already opened', function() {
var w = cachedCreateW2();
should.not.exist(w.getLock());
w.checkAndLock().should.equal(false);
w.getLock().should.equal(true);
});
it('should not start if locked', function() {
var w = cachedCreateW2();
w.netStart();
w.emit = sinon.spy();
w.netStart();
w.emit.getCall(0).args[0].should.equal('locked');
});
it('should accept ignoreLocked', function() {
var w = cachedCreateW2();
w.netStart();
w.network.start = sinon.spy();
w.ignoreLock=1;
w.netStart();
w.network.start.getCall(0).args[0].privkey.length.should.equal(64);
});
});

View File

@ -160,16 +160,16 @@ describe('Storage/LocalEncrypted model', function() {
});
});
describe('#WalletIsOpened', function() {
describe('#WalletLock', function() {
it('should get/set/remove opened', function() {
var s = new LocalEncrypted({
localStorage: localMock,
password: 'password'
});
s.setIsOpen('walletId');
s.getIsOpen('walletId').should.equal(true);
s.removeIsOpen('walletId');
should.not.exist(s.getIsOpen('walletId'));
s.setLock('walletId');
s.getLock('walletId').should.equal(true);
s.removeLock('walletId');
should.not.exist(s.getLock('walletId'));
});
});

View File

@ -303,11 +303,6 @@ describe("Unit: Controllers", function() {
expect(array.length).equal(n);
});
it('should ignore if wallet is locked', function() {
scope.ignoreLocked();
expect(rootScope.wallet.isLocked).equal(false);
});
});
describe('Send Controller', function() {
@ -428,4 +423,18 @@ describe("Unit: Controllers", function() {
});
});
describe('Warning Controller', function() {
var what;
beforeEach(inject(function($controller, $rootScope) {
scope = $rootScope.$new();
what = $controller('WarningController', {
$scope: scope,
});
}));
it('should exist', function() {
should.exist(what);
});
});
});

View File

@ -97,14 +97,14 @@ var createBundle = function(opts) {
expose: '../js/models/core/HDPath'
});
if (opts.dontminify) {
if (opts.debug) {
//include dev dependencies
b.require('sinon');
b.require('blanket');
b.require('soop');
}
if (!opts.dontminify) {
if (!opts.debug) {
b.transform({
global: true
}, 'uglifyify');
@ -120,7 +120,7 @@ if (require.main === module) {
var program = require('commander');
program
.version('0.0.1')
.option('-d, --dontminify', 'Development. Don\'t minify the code.')
.option('-d, --debug', 'Development. Don\'t minify the codem and include debug packages.')
.option('-o, --stdout', 'Specify output as stdout')
.parse(process.argv);

View File

@ -1,26 +1,26 @@
<div class="wide-page" ng-controller="SidebarController"
ng-init="checkIfWarning()">
<div class="wide-page" ng-controller="WarningController"
ng-init="checkLock()">
<div class="text-center">
<img src="img/logo-negative-beta.svg" alt="Copay">
<div class="text-white" ng-include="'views/includes/version.html'"></div>
</div>
<h1 class="text-center text-warning">Warning!</h1>
<h3 class="text-center text-white">
This wallet appear to be open on an other tab at your browser. Are you sure
you want to proceed? (*)
This wallet appears to be currently open.
<br>
Opening the wallet in multiple browser tabs could lead to unexpected results
</h3>
<div class="text-center m30v large-12 columns">
<div class="row">
<div class="large-6 medium-6 small-6 columns text-center">
<a href class="button gray" ng-click="signout()">No, I am not sure.</a>
</div>
<div class="large-6 columns medium-6 small-6 text-center">
<a href class="button warning" ng-click="ignoreLocked()">I am. Go!</a>
<div class="large-12 columns medium-12 small-12 text-center">
<a href class="button sucess" ng-click="signout()">Go back</a>
<br>
<br>
<a href ng-click="ignoreLock()">Continue anyways</a>
</div>
</div>
</div>
<div class="text-center text-gray small cb">
(*) Opening the wallet in multiple tabs could lead to unexpected results
</div>
</div>