2fa method selection
This commit is contained in:
parent
cf5b0635e4
commit
2f3035a08f
|
@ -2,7 +2,7 @@ angular
|
||||||
.module('bit.accounts')
|
.module('bit.accounts')
|
||||||
|
|
||||||
.controller('accountsLoginController', function ($scope, $rootScope, $cookies, apiService, cryptoService, authService,
|
.controller('accountsLoginController', function ($scope, $rootScope, $cookies, apiService, cryptoService, authService,
|
||||||
$state, constants, $analytics) {
|
$state, constants, $analytics, $uibModal, $timeout) {
|
||||||
$scope.state = $state;
|
$scope.state = $state;
|
||||||
|
|
||||||
var returnState;
|
var returnState;
|
||||||
|
@ -24,8 +24,11 @@ angular
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
var email,
|
var _email,
|
||||||
masterPassword;
|
_masterPassword;
|
||||||
|
|
||||||
|
$scope.twoFactorProviders = null;
|
||||||
|
$scope.twoFactorProvider = null;
|
||||||
|
|
||||||
$scope.login = function (model) {
|
$scope.login = function (model) {
|
||||||
$scope.loginPromise = authService.logIn(model.email, model.masterPassword);
|
$scope.loginPromise = authService.logIn(model.email, model.masterPassword);
|
||||||
|
@ -44,12 +47,18 @@ angular
|
||||||
$cookies.remove(constants.rememberedEmailCookieName);
|
$cookies.remove(constants.rememberedEmailCookieName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (twoFactorProviders && twoFactorProviders.length > 0) {
|
if (twoFactorProviders && Object.keys(twoFactorProviders).length > 0) {
|
||||||
email = model.email;
|
_email = model.email;
|
||||||
masterPassword = model.masterPassword;
|
_masterPassword = model.masterPassword;
|
||||||
|
$scope.twoFactorProviders = twoFactorProviders;
|
||||||
|
$scope.twoFactorProvider = parseInt(Object.keys(twoFactorProviders)[0]);
|
||||||
|
|
||||||
$analytics.eventTrack('Logged In To Two-step');
|
$analytics.eventTrack('Logged In To Two-step');
|
||||||
$state.go('frontend.login.twoFactor', { returnState: returnState });
|
$state.go('frontend.login.twoFactor', { returnState: returnState }).then(function () {
|
||||||
|
$timeout(function () {
|
||||||
|
$("#code").focus();
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$analytics.eventTrack('Logged In');
|
$analytics.eventTrack('Logged In');
|
||||||
|
@ -58,9 +67,8 @@ angular
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.twoFactor = function (model) {
|
$scope.twoFactor = function (token) {
|
||||||
// Only supporting Authenticator (0) provider for now
|
$scope.twoFactorPromise = authService.logIn(_email, _masterPassword, token, $scope.twoFactorProvider);
|
||||||
$scope.twoFactorPromise = authService.logIn(email, masterPassword, model.code, 0);
|
|
||||||
|
|
||||||
$scope.twoFactorPromise.then(function () {
|
$scope.twoFactorPromise.then(function () {
|
||||||
$analytics.eventTrack('Logged In From Two-step');
|
$analytics.eventTrack('Logged In From Two-step');
|
||||||
|
@ -68,6 +76,24 @@ angular
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$scope.anotherMethod = function () {
|
||||||
|
var modal = $uibModal.open({
|
||||||
|
animation: true,
|
||||||
|
templateUrl: 'app/accounts/views/accountsTwoFactorMethods.html',
|
||||||
|
controller: 'accountsTwoFactorMethodsController',
|
||||||
|
resolve: {
|
||||||
|
providers: function () { return $scope.twoFactorProviders; }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
modal.result.then(function (provider) {
|
||||||
|
$scope.twoFactorProvider = provider;
|
||||||
|
$timeout(function () {
|
||||||
|
$("#code").focus();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
function loggedInGo() {
|
function loggedInGo() {
|
||||||
if (returnState) {
|
if (returnState) {
|
||||||
$state.go(returnState.name, returnState.params);
|
$state.go(returnState.name, returnState.params);
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
angular
|
||||||
|
.module('bit.accounts')
|
||||||
|
|
||||||
|
.controller('accountsTwoFactorMethodsController', function ($scope, $uibModalInstance, $analytics, providers, constants) {
|
||||||
|
$analytics.eventTrack('accountsTwoFactorMethodsController', { category: 'Modal' });
|
||||||
|
|
||||||
|
$scope.providers = [];
|
||||||
|
|
||||||
|
if (providers.hasOwnProperty(constants.twoFactorProvider.authenticator)) {
|
||||||
|
$scope.providers.push({
|
||||||
|
id: constants.twoFactorProvider.authenticator,
|
||||||
|
name: 'Authenticator App'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (providers.hasOwnProperty(constants.twoFactorProvider.yubikey)) {
|
||||||
|
$scope.providers.push({
|
||||||
|
id: constants.twoFactorProvider.yubikey,
|
||||||
|
name: 'YubiKey'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (providers.hasOwnProperty(constants.twoFactorProvider.email)) {
|
||||||
|
$scope.providers.push({
|
||||||
|
id: constants.twoFactorProvider.email,
|
||||||
|
name: 'Email'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (providers.hasOwnProperty(constants.twoFactorProvider.duo)) {
|
||||||
|
$scope.providers.push({
|
||||||
|
id: constants.twoFactorProvider.duo,
|
||||||
|
name: 'Duo'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (providers.hasOwnProperty(constants.twoFactorProvider.u2f)) {
|
||||||
|
$scope.providers.push({
|
||||||
|
id: constants.twoFactorProvider.u2f,
|
||||||
|
name: 'FIDO U2F Security Key'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.choose = function (provider) {
|
||||||
|
$uibModalInstance.close(provider.id);
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.close = function () {
|
||||||
|
$uibModalInstance.dismiss('close');
|
||||||
|
};
|
||||||
|
});
|
|
@ -1,25 +1,59 @@
|
||||||
<p class="login-box-msg">Enter your two-step verification code.</p>
|
<div ng-if="twoFactorProvider === 0 || twoFactorProvider === 1">
|
||||||
<form name="twoFactorForm" ng-submit="twoFactorForm.$valid && twoFactor(model)" api-form="twoFactorPromise">
|
<p class="login-box-msg" ng-if="twoFactorProvider === 0">
|
||||||
<div class="callout callout-danger validation-errors" ng-show="twoFactorForm.$errors">
|
Enter the 6 digit verification code from your authenticator app.
|
||||||
<h4>Errors have occurred</h4>
|
</p>
|
||||||
<ul>
|
<p class="login-box-msg" ng-if="twoFactorProvider === 1">
|
||||||
<li ng-repeat="e in twoFactorForm.$errors">{{e}}</li>
|
Enter the 6 digit verification code that was emailed to you.
|
||||||
</ul>
|
</p>
|
||||||
</div>
|
<form name="twoFactorForm" ng-submit="twoFactorForm.$valid && twoFactor(token)" api-form="twoFactorPromise">
|
||||||
<div class="form-group has-feedback" show-errors>
|
<div class="callout callout-danger validation-errors" ng-show="twoFactorForm.$errors">
|
||||||
<label for="code" class="sr-only">Code</label>
|
<h4>Errors have occurred</h4>
|
||||||
<input type="text" id="code" name="Code" class="form-control" placeholder="Verification code" ng-model="model.code"
|
<ul>
|
||||||
required api-field />
|
<li ng-repeat="e in twoFactorForm.$errors">{{e}}</li>
|
||||||
<span class="fa fa-lock form-control-feedback"></span>
|
</ul>
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-xs-7">
|
|
||||||
<a ui-sref="frontend.recover">Lost authenticator app?</a>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-5">
|
<div class="form-group has-feedback" show-errors>
|
||||||
<button type="submit" class="btn btn-primary btn-block btn-flat" ng-disabled="twoFactorForm.$loading">
|
<label for="code" class="sr-only">Code</label>
|
||||||
<i class="fa fa-refresh fa-spin loading-icon" ng-show="twoFactorForm.$loading"></i>Log In
|
<input type="text" id="code" name="Code" class="form-control" placeholder="Verification code"
|
||||||
</button>
|
ng-model="token" required api-field />
|
||||||
|
<span class="fa fa-lock form-control-feedback"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="row">
|
||||||
</form>
|
<div class="col-xs-7">
|
||||||
|
<a stop-click href="#" ng-click="anotherMethod()">Use another method?</a>
|
||||||
|
</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>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div ng-if="twoFactorProvider === 3">
|
||||||
|
<p class="login-box-msg">
|
||||||
|
Insert your YubiKey into a USB slot and touch its gold button.
|
||||||
|
</p>
|
||||||
|
<form name="twoFactorForm" ng-submit="twoFactorForm.$valid && twoFactor(token)" 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>
|
||||||
|
<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>
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" ng-click="close()" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||||
|
<h4 class="modal-title"><i class="fa fa-key"></i> Two-step Providers</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body no-padding">
|
||||||
|
<div class="list-group" ng-repeat="provider in providers">
|
||||||
|
<a href="#" stop-click class="list-group-item" ng-click="choose(provider)">
|
||||||
|
<h4 class="list-group-item-heading">{{::provider.name}}</h4>
|
||||||
|
<p class="list-group-item-text">{{::provider.description}}</p>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-default btn-flat" ng-click="close()">Close</button>
|
||||||
|
</div>
|
|
@ -63,8 +63,9 @@ angular
|
||||||
}, function (error) {
|
}, function (error) {
|
||||||
_service.logOut();
|
_service.logOut();
|
||||||
|
|
||||||
if (error.status === 400 && error.data.TwoFactorProviders && error.data.TwoFactorProviders.length) {
|
if (error.status === 400 && error.data.TwoFactorProviders2 &&
|
||||||
deferred.resolve(error.data.TwoFactorProviders);
|
Object.keys(error.data.TwoFactorProviders2).length) {
|
||||||
|
deferred.resolve(error.data.TwoFactorProviders2);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
deferred.reject(error);
|
deferred.reject(error);
|
||||||
|
|
|
@ -147,6 +147,7 @@
|
||||||
<script src="app/accounts/accountsPasswordHintController.js"></script>
|
<script src="app/accounts/accountsPasswordHintController.js"></script>
|
||||||
<script src="app/accounts/accountsRecoverController.js"></script>
|
<script src="app/accounts/accountsRecoverController.js"></script>
|
||||||
<script src="app/accounts/accountsOrganizationAcceptController.js"></script>
|
<script src="app/accounts/accountsOrganizationAcceptController.js"></script>
|
||||||
|
<script src="app/accounts/accountsTwoFactorMethodsController.js"></script>
|
||||||
|
|
||||||
<script src="app/vault/vaultModule.js"></script>
|
<script src="app/vault/vaultModule.js"></script>
|
||||||
<script src="app/vault/vaultController.js"></script>
|
<script src="app/vault/vaultController.js"></script>
|
||||||
|
|
Loading…
Reference in New Issue