diff --git a/src/app/constants.js b/src/app/constants.js index c81c135b69..b0e4ce69ff 100644 --- a/src/app/constants.js +++ b/src/app/constants.js @@ -26,7 +26,8 @@ angular.module('bit') duo: 2, authenticator: 0, email: 1, - remember: 5 + remember: 5, + organizationDuo: 6 }, cipherType: { login: 1, @@ -153,6 +154,19 @@ angular.module('bit') requiresUsb: false } ], + orgTwoFactorProviderInfo: [ + { + type: 6, + name: 'Duo', + description: 'Verify with Duo Security using the Duo Mobile app, SMS, phone call, or U2F security key.', + enabled: false, + active: true, + image: 'duo.png', + displayOrder: 1, + priority: 0, + requiresUsb: false + } + ], plans: { free: { basePrice: 0, diff --git a/src/app/organization/organizationSettingsController.js b/src/app/organization/organizationSettingsController.js index df08f98a44..1ce066f644 100644 --- a/src/app/organization/organizationSettingsController.js +++ b/src/app/organization/organizationSettingsController.js @@ -2,11 +2,14 @@ .module('bit.organization') .controller('organizationSettingsController', function ($scope, $state, apiService, toastr, authService, $uibModal, - $analytics, appSettings) { + $analytics, appSettings, constants, $filter) { $scope.selfHosted = appSettings.selfHosted; $scope.model = {}; + $scope.twoStepProviders = constants.orgTwoFactorProviderInfo; + $scope.use2fa = false; + $scope.$on('$viewContentLoaded', function () { - apiService.organizations.get({ id: $state.params.orgId }, function (org) { + apiService.organizations.get({ id: $state.params.orgId }).$promise.then(function (org) { $scope.model = { name: org.Name, billingEmail: org.BillingEmail, @@ -17,6 +20,29 @@ businessCountry: org.BusinessCountry, businessTaxNumber: org.BusinessTaxNumber }; + + $scope.use2fa = org.Use2fa; + if (org.Use2fa) { + return apiService.twoFactor.listOrganization({ orgId: $state.params.orgId }).$promise; + } + else { + return null; + } + }).then(function (response) { + if (!response || !response.Data) { + return; + } + + for (var i = 0; i < response.Data.length; i++) { + if (!response.Data[i].Enabled) { + continue; + } + + var provider = $filter('filter')($scope.twoStepProviders, { type: response.Data[i].Type }); + if (provider.length) { + provider[0].enabled = true; + } + } }); }); @@ -56,4 +82,30 @@ controller: 'organizationDeleteController' }); }; + + $scope.edit = function (provider) { + if (provider.type === constants.twoFactorProvider.organizationDuo) { + typeName = 'Duo'; + } + else { + return; + } + + var modal = $uibModal.open({ + animation: true, + templateUrl: 'app/settings/views/settingsTwoStep' + typeName + '.html', + controller: 'settingsTwoStep' + typeName + 'Controller', + resolve: { + enabled: function () { return provider.enabled; }, + orgId: function () { return $state.params.orgId; } + } + }); + + modal.result.then(function (enabled) { + if (enabled || enabled === false) { + // do not adjust when undefined or null + provider.enabled = enabled; + } + }); + }; }); diff --git a/src/app/organization/views/organizationSettings.html b/src/app/organization/views/organizationSettings.html index 7894248570..55cf237982 100644 --- a/src/app/organization/views/organizationSettings.html +++ b/src/app/organization/views/organizationSettings.html @@ -63,6 +63,36 @@ +
+ + + + | +
+ {{::provider.name}}
+ {{::provider.description}}
+ |
+ + + {{provider.enabled ? 'Enabled' : 'Disabled'}} + + | +