diff --git a/src/app/accounts/accountsLoginController.js b/src/app/accounts/accountsLoginController.js index 81f93879f7..1917538c88 100644 --- a/src/app/accounts/accountsLoginController.js +++ b/src/app/accounts/accountsLoginController.js @@ -2,7 +2,7 @@ angular .module('bit.accounts') .controller('accountsLoginController', function ($scope, $rootScope, $cookies, apiService, cryptoService, authService, - $state, constants, $analytics) { + $state, constants, $analytics, $uibModal, $timeout) { $scope.state = $state; var returnState; @@ -24,8 +24,11 @@ angular }; } - var email, - masterPassword; + var _email, + _masterPassword; + + $scope.twoFactorProviders = null; + $scope.twoFactorProvider = null; $scope.login = function (model) { $scope.loginPromise = authService.logIn(model.email, model.masterPassword); @@ -44,12 +47,18 @@ angular $cookies.remove(constants.rememberedEmailCookieName); } - if (twoFactorProviders && twoFactorProviders.length > 0) { - email = model.email; - masterPassword = model.masterPassword; + if (twoFactorProviders && Object.keys(twoFactorProviders).length > 0) { + _email = model.email; + _masterPassword = model.masterPassword; + $scope.twoFactorProviders = twoFactorProviders; + $scope.twoFactorProvider = parseInt(Object.keys(twoFactorProviders)[0]); $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 { $analytics.eventTrack('Logged In'); @@ -58,9 +67,8 @@ angular }); }; - $scope.twoFactor = function (model) { - // Only supporting Authenticator (0) provider for now - $scope.twoFactorPromise = authService.logIn(email, masterPassword, model.code, 0); + $scope.twoFactor = function (token) { + $scope.twoFactorPromise = authService.logIn(_email, _masterPassword, token, $scope.twoFactorProvider); $scope.twoFactorPromise.then(function () { $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() { if (returnState) { $state.go(returnState.name, returnState.params); diff --git a/src/app/accounts/accountsTwoFactorMethodsController.js b/src/app/accounts/accountsTwoFactorMethodsController.js new file mode 100644 index 0000000000..50fd0a34a3 --- /dev/null +++ b/src/app/accounts/accountsTwoFactorMethodsController.js @@ -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'); + }; + }); diff --git a/src/app/accounts/views/accountsLoginTwoFactor.html b/src/app/accounts/views/accountsLoginTwoFactor.html index 0e33284132..ead9d22fc8 100644 --- a/src/app/accounts/views/accountsLoginTwoFactor.html +++ b/src/app/accounts/views/accountsLoginTwoFactor.html @@ -1,25 +1,59 @@ -

Enter your two-step verification code.

-
-
-

Errors have occurred

- -
-
- - - -
-
-
- Lost authenticator app? +
+ + + +
+

Errors have occurred

+
    +
  • {{e}}
  • +
-
- +
+ + +
-
- \ No newline at end of file +
+ +
+ +
+
+ +
+
+ +
+
+

Errors have occurred

+
    +
  • {{e}}
  • +
+
+
+ + +
+
+ +
+ +
+
+
+
diff --git a/src/app/accounts/views/accountsTwoFactorMethods.html b/src/app/accounts/views/accountsTwoFactorMethods.html new file mode 100644 index 0000000000..c1a7c59676 --- /dev/null +++ b/src/app/accounts/views/accountsTwoFactorMethods.html @@ -0,0 +1,15 @@ + + + diff --git a/src/app/services/authService.js b/src/app/services/authService.js index bf26d53a9f..024c3695bf 100644 --- a/src/app/services/authService.js +++ b/src/app/services/authService.js @@ -63,8 +63,9 @@ angular }, function (error) { _service.logOut(); - if (error.status === 400 && error.data.TwoFactorProviders && error.data.TwoFactorProviders.length) { - deferred.resolve(error.data.TwoFactorProviders); + if (error.status === 400 && error.data.TwoFactorProviders2 && + Object.keys(error.data.TwoFactorProviders2).length) { + deferred.resolve(error.data.TwoFactorProviders2); } else { deferred.reject(error); diff --git a/src/index.html b/src/index.html index e79e1f5899..41f1e7f806 100644 --- a/src/index.html +++ b/src/index.html @@ -147,6 +147,7 @@ +