mirror of
https://github.com/bitwarden/browser.git
synced 2024-12-29 17:38:04 +01:00
u2f cleanup
This commit is contained in:
parent
dda64b301e
commit
b8e9567501
@ -2,9 +2,10 @@ angular
|
||||
.module('bit.accounts')
|
||||
|
||||
.controller('accountsLoginController', function ($scope, $rootScope, $cookies, apiService, cryptoService, authService,
|
||||
$state, constants, $analytics, $uibModal, $timeout, $window) {
|
||||
$state, constants, $analytics, $uibModal, $timeout, $window, $filter) {
|
||||
$scope.state = $state;
|
||||
$scope.twoFactorProviderConstants = constants.twoFactorProvider;
|
||||
$scope.rememberTwoFactor = { checked: false };
|
||||
|
||||
var returnState;
|
||||
if (!$state.params.returnState && $state.params.org) {
|
||||
@ -52,7 +53,7 @@ angular
|
||||
_email = model.email;
|
||||
_masterPassword = model.masterPassword;
|
||||
$scope.twoFactorProviders = twoFactorProviders;
|
||||
$scope.twoFactorProvider = parseInt(Object.keys(twoFactorProviders)[0]);
|
||||
$scope.twoFactorProvider = getDefaultProvider(twoFactorProviders);
|
||||
|
||||
$analytics.eventTrack('Logged In To Two-step');
|
||||
$state.go('frontend.login.twoFactor', { returnState: returnState }).then(function () {
|
||||
@ -66,11 +67,27 @@ angular
|
||||
$analytics.eventTrack('Logged In');
|
||||
loggedInGo();
|
||||
}
|
||||
|
||||
model.masterPassword = '';
|
||||
});
|
||||
};
|
||||
|
||||
function getDefaultProvider(twoFactorProviders) {
|
||||
var keys = Object.keys(twoFactorProviders);
|
||||
var providerType = null;
|
||||
var providerPriority = -1;
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var provider = $filter('filter')(constants.twoFactorProviderInfo, { type: keys[i], active: true });
|
||||
if (provider.length && provider[0].priority > providerPriority) {
|
||||
providerType = provider[0].type;
|
||||
}
|
||||
}
|
||||
return parseInt(providerType);
|
||||
}
|
||||
|
||||
$scope.twoFactor = function (token) {
|
||||
$scope.twoFactorPromise = authService.logIn(_email, _masterPassword, token, $scope.twoFactorProvider, true);
|
||||
$scope.twoFactorPromise = authService.logIn(_email, _masterPassword, token, $scope.twoFactorProvider,
|
||||
$scope.rememberTwoFactor.checked || false);
|
||||
|
||||
$scope.twoFactorPromise.then(function () {
|
||||
$analytics.eventTrack('Logged In From Two-step');
|
||||
@ -110,7 +127,7 @@ angular
|
||||
if ($scope.twoFactorProvider === constants.twoFactorProvider.duo) {
|
||||
var params = $scope.twoFactorProviders[constants.twoFactorProvider.duo];
|
||||
|
||||
Duo.init({
|
||||
$window.Duo.init({
|
||||
host: params.Host,
|
||||
sig_request: params.Signature,
|
||||
submit_callback: function (theForm) {
|
||||
@ -122,18 +139,36 @@ angular
|
||||
else if ($scope.twoFactorProvider === constants.twoFactorProvider.u2f) {
|
||||
var params = $scope.twoFactorProviders[constants.twoFactorProvider.u2f];
|
||||
var challenges = JSON.parse(params.Challenges);
|
||||
if (challenges.length < 1) {
|
||||
|
||||
initU2f(challenges);
|
||||
}
|
||||
}
|
||||
|
||||
function initU2f(challenges) {
|
||||
if (challenges.length < 1 || $scope.twoFactorProvider !== constants.twoFactorProvider.u2f) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('listening for u2f key...');
|
||||
|
||||
$window.u2f.sign(challenges[0].appId, challenges[0].challenge, [{
|
||||
version: challenges[0].version,
|
||||
keyHandle: challenges[0].keyHandle
|
||||
}], function (data) {
|
||||
console.log('call back data:');
|
||||
console.log(data);
|
||||
if ($scope.twoFactorProvider !== constants.twoFactorProvider.u2f) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (data.errorCode) {
|
||||
console.log(data.errorCode);
|
||||
|
||||
if (data.errorCode === 5) {
|
||||
initU2f(challenges);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
$scope.twoFactor(JSON.stringify(data));
|
||||
});
|
||||
}
|
||||
}, 5);
|
||||
}
|
||||
});
|
||||
|
@ -21,7 +21,11 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-7">
|
||||
<a stop-click href="#" ng-click="anotherMethod()">Use another method?</a>
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" id="rememberMe" ng-model="rememberTwoFactor.checked" /> Remember Me
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-5">
|
||||
<button type="submit" class="btn btn-primary btn-block btn-flat" ng-disabled="twoFactorForm.$loading">
|
||||
@ -34,7 +38,7 @@
|
||||
|
||||
<div ng-if="twoFactorProvider === twoFactorProviderConstants.yubikey">
|
||||
<p class="login-box-msg">
|
||||
Insert your YubiKey into a USB slot and touch its gold button.
|
||||
Complete logging in with YubiKey.
|
||||
</p>
|
||||
<form name="twoFactorForm" ng-submit="twoFactorForm.$valid && twoFactor(token)" api-form="twoFactorPromise">
|
||||
<div class="callout callout-danger validation-errors" ng-show="twoFactorForm.$errors">
|
||||
@ -43,13 +47,21 @@
|
||||
<li ng-repeat="e in twoFactorForm.$errors">{{e}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<p>Insert your YubiKey into your computer's USB port, then tap it's button.</p>
|
||||
<p>
|
||||
<img src="images/two-factor/yubikey.jpg" alt="" class="img-rounded img-responsive" />
|
||||
</p>
|
||||
<div class="form-group" show-errors>
|
||||
<label for="code" class="sr-only">Token</label>
|
||||
<input type="password" id="code" name="Token" class="form-control" ng-model="token" required api-field />
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-7">
|
||||
<a stop-click href="#" ng-click="anotherMethod()">Use another method?</a>
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" id="rememberMe" ng-model="rememberTwoFactor.checked" /> Remember Me
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-5">
|
||||
<button type="submit" class="btn btn-primary btn-block btn-flat" ng-disabled="twoFactorForm.$loading">
|
||||
@ -76,12 +88,16 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-7">
|
||||
<a stop-click href="#" ng-click="anotherMethod()">Use another method?</a>
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" id="rememberMe" ng-model="rememberTwoFactor.checked" /> Remember Me
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-5">
|
||||
<button type="submit" class="btn btn-primary btn-block btn-flat" ng-disabled="twoFactorForm.$loading">
|
||||
<i class="fa fa-refresh fa-spin loading-icon" ng-show="twoFactorForm.$loading"></i>Log In
|
||||
</button>
|
||||
<span ng-show="twoFactorForm.$loading">
|
||||
<i class="fa fa-refresh fa-spin loading-icon"></i> Logging in...
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@ -89,25 +105,42 @@
|
||||
|
||||
<div ng-if="twoFactorProvider === twoFactorProviderConstants.u2f">
|
||||
<p class="login-box-msg">
|
||||
Complete logging in with U2F.
|
||||
Complete logging in with FIDO U2F.
|
||||
</p>
|
||||
<form name="twoFactorForm" ng-submit="twoFactorForm.$valid && twoFactor(token)" api-form="twoFactorPromise">
|
||||
<form name="twoFactorForm" api-form="twoFactorPromise">
|
||||
<div class="callout callout-danger validation-errors" ng-show="twoFactorForm.$errors">
|
||||
<h4>Errors have occurred</h4>
|
||||
<ul>
|
||||
<li ng-repeat="e in twoFactorForm.$errors">{{e}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<p>Press the button on your security key to continue.</p>
|
||||
<p>Insert your Security Key into your computer's USB port. If it has a button, tap it.</p>
|
||||
<p>
|
||||
<img src="images/two-factor/u2fkey.jpg" alt="" class="img-rounded img-responsive" />
|
||||
</p>
|
||||
<div class="row">
|
||||
<div class="col-xs-7">
|
||||
<a stop-click href="#" ng-click="anotherMethod()">Use another method?</a>
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" id="rememberMe" ng-model="rememberTwoFactor.checked" /> Remember Me
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-5">
|
||||
<button type="submit" class="btn btn-primary btn-block btn-flat" ng-disabled="twoFactorForm.$loading">
|
||||
<i class="fa fa-refresh fa-spin loading-icon" ng-show="twoFactorForm.$loading"></i>Log In
|
||||
</button>
|
||||
<span ng-show="twoFactorForm.$loading">
|
||||
<i class="fa fa-refresh fa-spin loading-icon"></i> Logging in...
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
<ul>
|
||||
<li>
|
||||
<a stop-click href="#" ng-click="anotherMethod()">Use another two-step method</a>
|
||||
</li>
|
||||
<li>
|
||||
<a ui-sref="frontend.login.info({returnState: returnState})">Back to log in</a>
|
||||
</li>
|
||||
</ul>
|
@ -3,7 +3,7 @@
|
||||
<h4 class="modal-title"><i class="fa fa-key"></i> Two-step Providers</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="list-group" ng-repeat="provider in providers">
|
||||
<div class="list-group" ng-repeat="provider in providers | orderBy: 'displayOrder'">
|
||||
<a href="#" stop-click class="list-group-item" ng-click="choose(provider)">
|
||||
<img alt="{{::provider.name}}" ng-src="{{'images/two-factor/' + provider.image}}" class="pull-right hidden-xs" />
|
||||
<h4 class="list-group-item-heading">{{::provider.name}}</h4>
|
||||
|
@ -21,11 +21,11 @@ angular.module('bit')
|
||||
confirmed: 2
|
||||
},
|
||||
twoFactorProvider: {
|
||||
u2f: 4,
|
||||
yubikey: 3,
|
||||
duo: 2,
|
||||
authenticator: 0,
|
||||
email: 1,
|
||||
duo: 2,
|
||||
yubikey: 3,
|
||||
u2f: 4,
|
||||
remember: 5
|
||||
},
|
||||
twoFactorProviderInfo: [
|
||||
@ -35,36 +35,51 @@ angular.module('bit')
|
||||
description: 'Use an authenticator app (such as Authy or Google Authenticator) to generate time-based ' +
|
||||
'verification codes.',
|
||||
enabled: false,
|
||||
active: true,
|
||||
free: true,
|
||||
image: 'authapp.png'
|
||||
image: 'authapp.png',
|
||||
displayOrder: 0,
|
||||
priority: 3
|
||||
},
|
||||
{
|
||||
type: 3,
|
||||
name: 'YubiKey OTP Security Key',
|
||||
description: 'Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices.',
|
||||
enabled: false,
|
||||
image: 'yubico.png'
|
||||
active: true,
|
||||
image: 'yubico.png',
|
||||
displayOrder: 1,
|
||||
priority: 1
|
||||
},
|
||||
{
|
||||
type: 2,
|
||||
name: 'Duo',
|
||||
description: 'Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.',
|
||||
enabled: false,
|
||||
image: 'duo.png'
|
||||
active: true,
|
||||
image: 'duo.png',
|
||||
displayOrder: 2,
|
||||
priority: 2
|
||||
},
|
||||
{
|
||||
type: 4,
|
||||
name: 'FIDO U2F Security Key',
|
||||
description: 'Use any FIDO U2F enabled security key to access your account.',
|
||||
enabled: false,
|
||||
image: 'fido.png'
|
||||
active: true,
|
||||
image: 'fido.png',
|
||||
displayOrder: 3,
|
||||
priority: 0
|
||||
},
|
||||
{
|
||||
type: 1,
|
||||
name: 'Email',
|
||||
description: 'Verification codes will be emailed to you.',
|
||||
enabled: false,
|
||||
image: 'gmail.png'
|
||||
active: true,
|
||||
image: 'gmail.png',
|
||||
displayOrder: 4,
|
||||
priority: 4
|
||||
}
|
||||
],
|
||||
plans: {
|
||||
|
@ -2,21 +2,25 @@
|
||||
.module('bit.settings')
|
||||
|
||||
.controller('settingsSessionsController', function ($scope, $state, apiService, $uibModalInstance, cryptoService,
|
||||
authService, toastr, $analytics) {
|
||||
authService, tokenService, toastr, $analytics) {
|
||||
$analytics.eventTrack('settingsSessionsController', { category: 'Modal' });
|
||||
$scope.submit = function (model) {
|
||||
var request = {
|
||||
masterPasswordHash: cryptoService.hashPassword(model.masterPassword)
|
||||
};
|
||||
|
||||
$scope.submitPromise = apiService.accounts.putSecurityStamp(request, function () {
|
||||
$scope.submitPromise =
|
||||
authService.getUserProfile().then(function (profile) {
|
||||
apiService.accounts.putSecurityStamp(request, function () {
|
||||
$uibModalInstance.dismiss('cancel');
|
||||
authService.logOut();
|
||||
tokenService.clearTwoFactorToken(profile.email);
|
||||
$analytics.eventTrack('Deauthorized Sessions');
|
||||
$state.go('frontend.login.info').then(function () {
|
||||
toastr.success('Please log back in.', 'All Sessions Deauthorized');
|
||||
});
|
||||
}).$promise;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.close = function () {
|
||||
|
@ -6,10 +6,14 @@
|
||||
<div class="modal-body">
|
||||
<p>Concerned your account is logged in on another device?</p>
|
||||
<p>Proceed below to deauthorize all computers or devices that you have previously used.</p>
|
||||
<p>This security step is recommended if you previously used a public PC or accidentally saved your password on a device that isn't yours.</p>
|
||||
<p>
|
||||
This security step is recommended if you previously used a public PC or accidentally saved your password
|
||||
on a device that isn't yours. This step will also clear all previously remembered two-step login sessions.
|
||||
</p>
|
||||
<div class="callout callout-warning">
|
||||
<h4><i class="fa fa-warning"></i> Warning</h4>
|
||||
Proceeding will log you out of your current session as well, requiring you to log back in.
|
||||
Proceeding will also log you out of your current session, requiring you to log back in. You will also be prompted
|
||||
for two-step login again, if enabled.
|
||||
</div>
|
||||
<div class="callout callout-danger validation-errors" ng-show="logoutSessionsForm.$errors">
|
||||
<h4>Errors have occurred</h4>
|
||||
|
@ -18,7 +18,7 @@
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-hover table-vmiddle">
|
||||
<tbody>
|
||||
<tr ng-repeat="provider in providers">
|
||||
<tr ng-repeat="provider in providers | orderBy: 'displayOrder'">
|
||||
<td style="width: 120px; height: 75px;" align="center">
|
||||
<img alt="{{::provider.name}}" ng-src="{{'images/two-factor/' + provider.image}}" />
|
||||
</td>
|
||||
|
BIN
src/images/two-factor/u2fkey.jpg
Normal file
BIN
src/images/two-factor/u2fkey.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 174 KiB |
BIN
src/images/two-factor/yubikey.jpg
Normal file
BIN
src/images/two-factor/yubikey.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
Loading…
Reference in New Issue
Block a user