[WO-464] jump to the next keychain code and allow paste

This commit is contained in:
Felix Hammerl 2014-07-22 21:05:34 +02:00
parent 26f62668c6
commit 10d19b5816
7 changed files with 115 additions and 11 deletions

View File

@ -64,6 +64,7 @@ requirejs([
'read',
'contacts',
'login-new-device',
'privatekey-upload',
'popover',
'infinite-scroll'
]);

View File

@ -10,6 +10,26 @@ define(function(require) {
$scope.step = 1;
$scope.handlePaste = function(event) {
var evt = event;
if (evt.originalEvent) {
evt = evt.originalEvent;
}
var value = evt.clipboardData.getData('text/plain');
if (!value) {
return;
}
value = value.replace(/-/g, '');
$scope.code0 = value.slice(0, 4);
$scope.code1 = value.slice(4, 8);
$scope.code2 = value.slice(8, 12);
$scope.code3 = value.slice(12, 16);
$scope.code4 = value.slice(16, 20);
$scope.code5 = value.slice(20, 24);
};
$scope.verifyRecoveryToken = function(callback) {
if (!$scope.recoveryToken) {
$scope.onError(new Error('Please set the recovery token!'));

View File

@ -1,7 +1,8 @@
define(function(require) {
'use strict';
var appController = require('js/app-controller'),
var angular = require('angular'),
appController = require('js/app-controller'),
keychain, pgp;
var PrivateKeyUploadCtrl = function($scope) {
@ -37,6 +38,26 @@ define(function(require) {
}
};
$scope.handlePaste = function(event) {
var evt = event;
if (evt.originalEvent) {
evt = evt.originalEvent;
}
var value = evt.clipboardData.getData('text/plain');
if (!value) {
return;
}
value = value.replace(/-/g, '');
$scope.code0 = value.slice(0, 4);
$scope.code1 = value.slice(4, 8);
$scope.code2 = value.slice(8, 12);
$scope.code3 = value.slice(12, 16);
$scope.code4 = value.slice(16, 20);
$scope.code5 = value.slice(20, 24);
};
$scope.checkServerForKey = function(callback) {
var keyParams = pgp.getKeyParams();
keychain.requestPrivateKeyDownload({
@ -166,5 +187,27 @@ define(function(require) {
};
//
// Directives
//
var ngModule = angular.module('privatekey-upload', []);
ngModule.directive('focusNext', function() {
return {
link: function(scope, element, attr) {
var maxLen = element[0].maxLength;
scope.$watch(attr.ngModel, function(val) {
if (val.length === maxLen) {
var nextinput = element.next('input');
if (nextinput.length) {
nextinput[0].focus();
}
}
});
}
};
});
return PrivateKeyUploadCtrl;
});

View File

@ -13,11 +13,11 @@
<div class="step" ng-show="step === 2">
<p><b>Key sync.</b> Please enter the keychain code you wrote down during sync setup.</p>
<input type="text" class="input-text code" size="4" maxlength="4" ng-model="code0" focus-me="step === 2"> -
<input type="text" class="input-text code" size="4" maxlength="4" ng-model="code1"> -
<input type="text" class="input-text code" size="4" maxlength="4" ng-model="code2"> -
<input type="text" class="input-text code" size="4" maxlength="4" ng-model="code3"> -
<input type="text" class="input-text code" size="4" maxlength="4" ng-model="code4"> -
<input type="text" class="input-text code" size="4" maxlength="4" ng-model="code0" focus-me="step === 2" focus-next ng-paste="handlePaste($event)"> -
<input type="text" class="input-text code" size="4" maxlength="4" ng-model="code1" focus-next> -
<input type="text" class="input-text code" size="4" maxlength="4" ng-model="code2" focus-next> -
<input type="text" class="input-text code" size="4" maxlength="4" ng-model="code3" focus-next> -
<input type="text" class="input-text code" size="4" maxlength="4" ng-model="code4" focus-next> -
<input type="text" class="input-text code" size="4" maxlength="4" ng-model="code5">
<!--<a href="https://whiteout.io/revocation.html" title="Click here to reset your account." target="_blank">Lost your keychain code?</a>-->
</div>

View File

@ -17,11 +17,11 @@
<div class="step" ng-show="step === 2">
<p>Please confirm the keychain code you have written down.</p>
<input type="text" class="input-text" size="4" maxlength="4" ng-model="code0" focus-me="step === 2"> -
<input type="text" class="input-text" size="4" maxlength="4" ng-model="code1"> -
<input type="text" class="input-text" size="4" maxlength="4" ng-model="code2"> -
<input type="text" class="input-text" size="4" maxlength="4" ng-model="code3"> -
<input type="text" class="input-text" size="4" maxlength="4" ng-model="code4"> -
<input type="text" class="input-text" size="4" maxlength="4" ng-model="code0" focus-me="step === 2" focus-next ng-paste="handlePaste($event)"> -
<input type="text" class="input-text" size="4" maxlength="4" ng-model="code1" focus-next> -
<input type="text" class="input-text" size="4" maxlength="4" ng-model="code2" focus-next> -
<input type="text" class="input-text" size="4" maxlength="4" ng-model="code3" focus-next> -
<input type="text" class="input-text" size="4" maxlength="4" ng-model="code4" focus-next> -
<input type="text" class="input-text" size="4" maxlength="4" ng-model="code5">
</div>

View File

@ -108,6 +108,26 @@ define(function(require) {
});
});
describe('handlePaste', function() {
it('should work', function() {
scope.handlePaste({
clipboardData: {
getData: function(val) {
expect(val).to.equal('text/plain');
return '1qaz-2wsx-3edc-4rfv-5tgb-6yhn';
}
}
});
expect(scope.code0).to.equal('1qaz');
expect(scope.code1).to.equal('2wsx');
expect(scope.code2).to.equal('3edc');
expect(scope.code3).to.equal('4rfv');
expect(scope.code4).to.equal('5tgb');
expect(scope.code5).to.equal('6yhn');
});
});
describe('decryptAndStorePrivateKeyLocally', function() {
beforeEach(function() {
scope.code0 = '0';

View File

@ -87,6 +87,26 @@ define(function(require) {
});
});
describe('handlePaste', function() {
it('should work', function() {
scope.handlePaste({
clipboardData: {
getData: function(val) {
expect(val).to.equal('text/plain');
return '1qaz-2wsx-3edc-4rfv-5tgb-6yhn';
}
}
});
expect(scope.code0).to.equal('1qaz');
expect(scope.code1).to.equal('2wsx');
expect(scope.code2).to.equal('3edc');
expect(scope.code3).to.equal('4rfv');
expect(scope.code4).to.equal('5tgb');
expect(scope.code5).to.equal('6yhn');
});
});
describe('displayUploadUi', function() {
it('should work', function() {
var generateCodeStub = sinon.stub(scope, 'generateCode');