mirror of
https://github.com/moparisthebest/mail
synced 2025-02-07 02:20:14 -05:00
implement passphrase quality indicator on initial login
This commit is contained in:
parent
7d0fc373ab
commit
7824ed396c
@ -25,6 +25,49 @@ define(function(require) {
|
||||
// scope functions
|
||||
//
|
||||
|
||||
$scope.checkPassphraseQuality = function() {
|
||||
var passphrase = $scope.state.passphrase;
|
||||
$scope.passphraseRating = 0;
|
||||
|
||||
var LOWER = /[a-z]/,
|
||||
UPPER = /[A-Z]/,
|
||||
DIGIT = /[0-9]/,
|
||||
DIGITS = /[0-9].*[0-9]/,
|
||||
SPECIAL = /[^a-zA-Z0-9]/,
|
||||
SAME = /^(.)\1+$/;
|
||||
|
||||
function uncapitalize(str) {
|
||||
return str.substring(0, 1).toLowerCase() + str.substring(1);
|
||||
}
|
||||
|
||||
if (!passphrase || passphrase.length < 10) {
|
||||
$scope.passphraseMsg = 'Too short';
|
||||
return;
|
||||
}
|
||||
|
||||
if (SAME.test(passphrase)) {
|
||||
$scope.passphraseMsg = 'Very weak';
|
||||
return;
|
||||
}
|
||||
|
||||
var lower = LOWER.test(passphrase),
|
||||
upper = UPPER.test(uncapitalize(passphrase)),
|
||||
digit = DIGIT.test(passphrase),
|
||||
digits = DIGITS.test(passphrase),
|
||||
special = SPECIAL.test(passphrase);
|
||||
|
||||
if (lower && upper && digit || lower && digits || upper && digits || special) {
|
||||
$scope.passphraseMsg = 'Strong';
|
||||
$scope.passphraseRating = 3;
|
||||
} else if (lower && upper || lower && digit || upper && digit) {
|
||||
$scope.passphraseMsg = 'Good';
|
||||
$scope.passphraseRating = 2;
|
||||
} else {
|
||||
$scope.passphraseMsg = 'Weak';
|
||||
$scope.passphraseRating = 1;
|
||||
}
|
||||
};
|
||||
|
||||
$scope.confirmPassphrase = function() {
|
||||
var passphrase = $scope.state.passphrase,
|
||||
confirmation = $scope.state.confirmation;
|
||||
|
@ -9,6 +9,17 @@
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.input-text-error {
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
.input-error-message {
|
||||
margin: 5px 0;
|
||||
padding: 0;
|
||||
color: red;
|
||||
font-size: em(13);
|
||||
}
|
||||
|
||||
.input-search {
|
||||
width: 93%;
|
||||
-webkit-appearance: searchfield;
|
||||
|
@ -66,8 +66,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
.error {
|
||||
border: 1px solid red;
|
||||
.passphrase-label-ok {
|
||||
color: green;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
<form>
|
||||
<div>
|
||||
<input class="input-text" type="password" ng-model="passphrase" ng-change="change()" ng-class="{error:incorrect}" placeholder="Passphrase" tabindex="1" focus-me="true">
|
||||
<input class="input-text" type="password" ng-model="passphrase" ng-change="change()" ng-class="{'input-text-error':incorrect}" placeholder="Passphrase" tabindex="1" focus-me="true">
|
||||
<span class="popover-info" data-icon-append="" popover="#passphrase-info"></span>
|
||||
</div>
|
||||
<div>
|
||||
|
@ -9,12 +9,13 @@
|
||||
<p><b>Set passphrase.</b> The passphrase protects your keypair. If you forget your passphrase you will not be able to recover your messages.</p>
|
||||
<form>
|
||||
<div>
|
||||
<input class="input-text" type="password" ng-model="state.passphrase" placeholder="Enter passphrase" tabindex="1" focus-me="true">
|
||||
<input class="input-text" type="password" ng-model="state.confirmation" ng-class="{error: state.confirmation !== state.passphrase}" placeholder="Confirm passphrase" tabindex="2">
|
||||
<label class="input-error-message" ng-class="{'passphrase-label-ok': passphraseRating >= 2}">{{passphraseMsg}}</label><br>
|
||||
<input class="input-text" ng-class="{'input-text-error': passphraseRating < 2}" type="password" ng-model="state.passphrase" ng-change="checkPassphraseQuality()" placeholder="Enter passphrase" tabindex="1" focus-me="true">
|
||||
<input class="input-text" type="password" ng-model="state.confirmation" ng-class="{'input-text-error': state.confirmation && state.confirmation !== state.passphrase}" placeholder="Confirm passphrase" tabindex="2">
|
||||
<span class="popover-info" data-icon-append="" popover="#passphrase-info"></span>
|
||||
</div>
|
||||
<div>
|
||||
<button type="submit" ng-click="confirmPassphrase()" class="btn" ng-disabled="!state.passphrase || state.passphrase !== state.confirmation" tabindex="3">Generate keypair</button>
|
||||
<button type="submit" ng-click="confirmPassphrase()" class="btn" ng-disabled="passphraseRating < 2 || state.passphrase !== state.confirmation" tabindex="3">Generate keypair</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
@ -12,7 +12,7 @@
|
||||
<span class="popover-info" data-icon-append="" popover="#keyfile-info"></span>
|
||||
</div>
|
||||
<div>
|
||||
<input class="input-text" type="password" ng-model="passphrase" ng-class="{error:incorrect}" placeholder="Passphrase" tabindex="2" focus-me="true">
|
||||
<input class="input-text" type="password" ng-model="passphrase" ng-class="{'input-text-error':incorrect}" placeholder="Passphrase" tabindex="2" focus-me="true">
|
||||
<span class="popover-info" data-icon-append="" popover="#passphrase-info"></span>
|
||||
</div>
|
||||
<div><button type="submit" ng-click="confirmPassphrase()" class="btn" ng-disabled="!key" tabindex="3">Import</button>
|
||||
|
@ -61,6 +61,48 @@ define(function(require) {
|
||||
});
|
||||
});
|
||||
|
||||
describe('check passphrase quality', function() {
|
||||
it('should be too short', function() {
|
||||
scope.state.passphrase = '&§DG36abc';
|
||||
scope.checkPassphraseQuality();
|
||||
|
||||
expect(scope.passphraseMsg).to.equal('Too short');
|
||||
expect(scope.passphraseRating).to.equal(0);
|
||||
});
|
||||
|
||||
it('should be very weak', function() {
|
||||
scope.state.passphrase = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
|
||||
scope.checkPassphraseQuality();
|
||||
|
||||
expect(scope.passphraseMsg).to.equal('Very weak');
|
||||
expect(scope.passphraseRating).to.equal(0);
|
||||
});
|
||||
|
||||
it('should be weak', function() {
|
||||
scope.state.passphrase = 'asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdf';
|
||||
scope.checkPassphraseQuality();
|
||||
|
||||
expect(scope.passphraseMsg).to.equal('Weak');
|
||||
expect(scope.passphraseRating).to.equal(1);
|
||||
});
|
||||
|
||||
it('should be good', function() {
|
||||
scope.state.passphrase = 'asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdf5';
|
||||
scope.checkPassphraseQuality();
|
||||
|
||||
expect(scope.passphraseMsg).to.equal('Good');
|
||||
expect(scope.passphraseRating).to.equal(2);
|
||||
});
|
||||
|
||||
it('should be strong', function() {
|
||||
scope.state.passphrase = '&§DG36abcd';
|
||||
scope.checkPassphraseQuality();
|
||||
|
||||
expect(scope.passphraseMsg).to.equal('Strong');
|
||||
expect(scope.passphraseRating).to.equal(3);
|
||||
});
|
||||
});
|
||||
|
||||
describe('confirm passphrase', function() {
|
||||
var setStateStub;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user