mirror of
https://github.com/bitwarden/browser.git
synced 2024-11-27 12:36:14 +01:00
Yubikey 2fa setup
This commit is contained in:
parent
4db5c96781
commit
cf5b0635e4
@ -115,9 +115,11 @@
|
||||
list: { method: 'GET', params: {} },
|
||||
getEmail: { url: _apiUri + '/two-factor/get-email', method: 'POST', params: {} },
|
||||
getAuthenticator: { url: _apiUri + '/two-factor/get-authenticator', method: 'POST', params: {} },
|
||||
getYubi: { url: _apiUri + '/two-factor/get-yubikey', method: 'POST', params: {} },
|
||||
sendEmail: { url: _apiUri + '/two-factor/send-email', method: 'POST', params: {} },
|
||||
putEmail: { url: _apiUri + '/two-factor/email', method: 'POST', params: {} },
|
||||
putAuthenticator: { url: _apiUri + '/two-factor/authenticator', method: 'POST', params: {} },
|
||||
putYubi: { url: _apiUri + '/two-factor/yubikey', method: 'POST', params: {} },
|
||||
disable: { url: _apiUri + '/two-factor/disable', method: 'POST', params: {} },
|
||||
recover: { url: _apiUri + '/two-factor/recover', method: 'POST', params: {} },
|
||||
});
|
||||
|
@ -81,6 +81,20 @@
|
||||
|
||||
emailModal.result.then(function () {
|
||||
|
||||
});
|
||||
}
|
||||
else if (provider.type === constants.twoFactorProvider.yubikey) {
|
||||
var yubiModal = $uibModal.open({
|
||||
animation: true,
|
||||
templateUrl: 'app/settings/views/settingsTwoStepYubi.html',
|
||||
controller: 'settingsTwoStepYubiController',
|
||||
resolve: {
|
||||
enabled: function () { return provider.enabled; }
|
||||
}
|
||||
});
|
||||
|
||||
yubiModal.result.then(function () {
|
||||
|
||||
});
|
||||
}
|
||||
};
|
||||
|
107
src/app/settings/settingsTwoStepYubiController.js
Normal file
107
src/app/settings/settingsTwoStepYubiController.js
Normal file
@ -0,0 +1,107 @@
|
||||
angular
|
||||
.module('bit.settings')
|
||||
|
||||
.controller('settingsTwoStepYubiController', function ($scope, apiService, $uibModalInstance, cryptoService,
|
||||
authService, toastr, $analytics, constants) {
|
||||
$analytics.eventTrack('settingsTwoStepYubiController', { category: 'Modal' });
|
||||
var _profile = null,
|
||||
_masterPasswordHash;
|
||||
|
||||
$scope.auth = function (model) {
|
||||
_masterPasswordHash = cryptoService.hashPassword(model.masterPassword);
|
||||
|
||||
var response = null;
|
||||
$scope.authPromise = apiService.twoFactor.getYubi({}, {
|
||||
masterPasswordHash: _masterPasswordHash
|
||||
}).$promise.then(function (apiResponse) {
|
||||
response = apiResponse;
|
||||
return authService.getUserProfile();
|
||||
}).then(function (profile) {
|
||||
_profile = profile;
|
||||
processResult(response);
|
||||
$scope.authed = true;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.remove = function (model) {
|
||||
model.key = null;
|
||||
model.existingKey = null;
|
||||
};
|
||||
|
||||
$scope.submit = function (model) {
|
||||
$scope.submitPromise = apiService.twoFactor.putYubi({}, {
|
||||
key1: model.key1.key,
|
||||
key2: model.key2.key,
|
||||
key3: model.key3.key,
|
||||
key4: model.key4.key,
|
||||
key5: model.key5.key,
|
||||
masterPasswordHash: _masterPasswordHash
|
||||
}, function (response) {
|
||||
$analytics.eventTrack('Saved Two-step YubiKey');
|
||||
toastr.success('YubiKey saved.');
|
||||
processResult(response);
|
||||
}).$promise;
|
||||
};
|
||||
|
||||
$scope.disable = function () {
|
||||
if (!confirm('Are you sure you want to disable the YubiKey provider?')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$scope.disableLoading = true;
|
||||
$scope.submitPromise = apiService.twoFactor.disable({}, {
|
||||
masterPasswordHash: _masterPasswordHash,
|
||||
type: constants.twoFactorProvider.yubikey
|
||||
}, function (response) {
|
||||
$scope.disableLoading = false;
|
||||
$analytics.eventTrack('Disabled Two-step YubiKey');
|
||||
toastr.success('YubiKey has been disabled.');
|
||||
$scope.close();
|
||||
}, function (response) {
|
||||
toastr.error('Failed to disable.');
|
||||
$scope.disableLoading = false;
|
||||
}).$promise;
|
||||
}
|
||||
|
||||
function processResult(response) {
|
||||
$scope.enabled = response.Enabled;
|
||||
$scope.updateModel = {
|
||||
key1: {
|
||||
key: response.Key1,
|
||||
existingKey: padRight(response.Key1, '*', 44)
|
||||
},
|
||||
key2: {
|
||||
key: response.Key2,
|
||||
existingKey: padRight(response.Key2, '*', 44)
|
||||
},
|
||||
key3: {
|
||||
key: response.Key3,
|
||||
existingKey: padRight(response.Key3, '*', 44)
|
||||
},
|
||||
key4: {
|
||||
key: response.Key4,
|
||||
existingKey: padRight(response.Key4, '*', 44)
|
||||
},
|
||||
key5: {
|
||||
key: response.Key5,
|
||||
existingKey: padRight(response.Key5, '*', 44)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function padRight(str, character, size) {
|
||||
if (!str || !character || str.length >= size) {
|
||||
return str;
|
||||
}
|
||||
|
||||
var max = (size - str.length) / character.length;
|
||||
for (var i = 0; i < max; i++) {
|
||||
str += character;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
$scope.close = function () {
|
||||
$uibModalInstance.close();
|
||||
};
|
||||
});
|
@ -34,8 +34,11 @@
|
||||
<div class="callout callout-success">
|
||||
<h4><i class="fa fa-check-circle"></i> Enabled</h4>
|
||||
<p>
|
||||
Two-step log in is enabled on your account. Incase you need to add it to another device, below is the QR
|
||||
code (or key) required by your authenticator app.
|
||||
Two-step login via authenticator app is enabled on your account.
|
||||
</p>
|
||||
<p>
|
||||
Incase you need to add it to another device, below is the QR code (or key) required by your
|
||||
authenticator app.
|
||||
</p>
|
||||
</div>
|
||||
<p>Need a two-step authenticator app? Download one of the following:</p>
|
||||
|
121
src/app/settings/views/settingsTwoStepYubi.html
Normal file
121
src/app/settings/views/settingsTwoStepYubi.html
Normal file
@ -0,0 +1,121 @@
|
||||
<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 Login <small>yubikey</small>
|
||||
</h4>
|
||||
</div>
|
||||
<form name="authTwoStepForm" ng-submit="authTwoStepForm.$valid && auth(authModel)" api-form="authPromise"
|
||||
ng-if="!authed">
|
||||
<div class="modal-body">
|
||||
<p>Enter your master password to modify two-step login settings.</p>
|
||||
<div class="callout callout-danger validation-errors" ng-show="authTwoStepForm.$errors">
|
||||
<h4>Errors have occurred</h4>
|
||||
<ul>
|
||||
<li ng-repeat="e in authTwoStepForm.$errors">{{e}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="form-group" show-errors>
|
||||
<label for="masterPassword">Master Password</label>
|
||||
<input type="password" id="masterPassword" name="MasterPasswordHash" ng-model="authModel.masterPassword"
|
||||
class="form-control" required api-field />
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" class="btn btn-primary btn-flat" ng-disabled="authTwoStepForm.$loading">
|
||||
<i class="fa fa-refresh fa-spin loading-icon" ng-show="authTwoStepForm.$loading"></i>Continue
|
||||
</button>
|
||||
<button type="button" class="btn btn-default btn-flat" ng-click="close()">Close</button>
|
||||
</div>
|
||||
</form>
|
||||
<form name="submitTwoStepForm" ng-submit="submitTwoStepForm.$valid && submit(updateModel)" api-form="submitPromise"
|
||||
ng-if="authed">
|
||||
<div class="modal-body">
|
||||
<div ng-if="enabled">
|
||||
<div class="callout callout-success">
|
||||
<h4><i class="fa fa-check-circle"></i> Enabled</h4>
|
||||
<p>Two-step log via YubiKey is enabled on your account.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="callout callout-danger validation-errors" ng-show="submitTwoStepForm.$errors">
|
||||
<h4>Errors have occurred</h4>
|
||||
<ul>
|
||||
<li ng-repeat="e in submitTwoStepForm.$errors">{{e}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<p>To add a new YubiKey to your account:</p>
|
||||
<ol>
|
||||
<li>Plug the YubiKey into your USB port.</li>
|
||||
<li>Select in the first empty <b>Key</b> field below.</li>
|
||||
<li>Touch the YubiKey's button.</li>
|
||||
<li>Finally, save the form.</li>
|
||||
</ol>
|
||||
<hr />
|
||||
<div class="form-group" show-errors>
|
||||
<label for="key1">Key #1</label>
|
||||
<span ng-if="updateModel.key1.existingKey">
|
||||
<a href="#" class="btn btn-link btn-xs" stop-click ng-click="remove(updateModel.key1)">[remove]</a>
|
||||
</span>
|
||||
<div ng-if="updateModel.key1.existingKey" class="monospaced">
|
||||
{{updateModel.key1.existingKey}}
|
||||
</div>
|
||||
<input type="password" id="key1" name="Key1" ng-model="updateModel.key1.key" class="form-control" api-field
|
||||
ng-show="!updateModel.key1.existingKey" />
|
||||
</div>
|
||||
<div class="form-group" show-errors>
|
||||
<label for="key2">Key #2</label>
|
||||
<span ng-if="updateModel.key2.existingKey">
|
||||
<a href="#" class="btn btn-link btn-xs" stop-click ng-click="remove(updateModel.key2)">[remove]</a>
|
||||
</span>
|
||||
<div ng-if="updateModel.key2.existingKey" class="monospaced">
|
||||
{{updateModel.key2.existingKey}}
|
||||
</div>
|
||||
<input type="password" id="key2" name="Key2" ng-model="updateModel.key2.key" class="form-control" api-field
|
||||
ng-show="!updateModel.key2.existingKey" />
|
||||
</div>
|
||||
<div class="form-group" show-errors>
|
||||
<label for="key3">Key #3</label>
|
||||
<span ng-if="updateModel.key3.existingKey">
|
||||
<a href="#" class="btn btn-link btn-xs" stop-click ng-click="remove(updateModel.key3)">[remove]</a>
|
||||
</span>
|
||||
<div ng-if="updateModel.key3.existingKey" class="monospaced">
|
||||
{{updateModel.key3.existingKey}}
|
||||
</div>
|
||||
<input type="password" id="key3" name="Key3" ng-model="updateModel.key3.key" class="form-control" api-field
|
||||
ng-show="!updateModel.key3.existingKey" />
|
||||
</div>
|
||||
<div class="form-group" show-errors>
|
||||
<label for="key4">Key #4</label>
|
||||
<span ng-if="updateModel.key4.existingKey">
|
||||
<a href="#" class="btn btn-link btn-xs" stop-click ng-click="remove(updateModel.key4)">[remove]</a>
|
||||
</span>
|
||||
<div ng-if="updateModel.key4.existingKey" class="monospaced">
|
||||
{{updateModel.key4.existingKey}}
|
||||
</div>
|
||||
<input type="password" id="key4" name="Key4" ng-model="updateModel.key4.key" class="form-control" api-field
|
||||
ng-show="!updateModel.key4.existingKey" />
|
||||
</div>
|
||||
<div class="form-group" show-errors>
|
||||
<label for="key5">Key #5</label>
|
||||
<span ng-if="updateModel.key5.existingKey">
|
||||
<a href="#" class="btn btn-link btn-xs" stop-click ng-click="remove(updateModel.key5)">[remove]</a>
|
||||
</span>
|
||||
<div ng-if="updateModel.key5.existingKey" class="monospaced">
|
||||
{{updateModel.key5.existingKey}}
|
||||
</div>
|
||||
<input type="password" id="key5" name="Key5" ng-model="updateModel.key5.key" class="form-control" api-field
|
||||
ng-show="!updateModel.key5.existingKey" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" class="btn btn-primary btn-flat" ng-disabled="submitTwoStepForm.$loading || disableLoading">
|
||||
<i class="fa fa-refresh fa-spin loading-icon" ng-show="submitTwoStepForm.$loading"></i>
|
||||
Save
|
||||
</button>
|
||||
<button type="button" class="btn btn-default btn-flat" ng-click="disable()" ng-disabled="disableLoading"
|
||||
ng-if="enabled">
|
||||
<i class="fa fa-refresh fa-spin loading-icon" ng-show="disableLoading"></i>
|
||||
Disable All Keys
|
||||
</button>
|
||||
<button type="button" class="btn btn-default btn-flat" ng-click="close()">Close</button>
|
||||
</div>
|
||||
</form>
|
@ -190,6 +190,7 @@
|
||||
<script src="app/settings/settingsChangeEmailController.js"></script>
|
||||
<script src="app/settings/settingsTwoStepAuthenticatorController.js"></script>
|
||||
<script src="app/settings/settingsTwoStepEmailController.js"></script>
|
||||
<script src="app/settings/settingsTwoStepYubiController.js"></script>
|
||||
<script src="app/settings/settingsSessionsController.js"></script>
|
||||
<script src="app/settings/settingsDomainsController.js"></script>
|
||||
<script src="app/settings/settingsTwoStepController.js"></script>
|
||||
|
@ -519,6 +519,10 @@ h1, h2, h3, h4, h5, h6 {
|
||||
color: @text-muted;
|
||||
}
|
||||
|
||||
.monospaced {
|
||||
font-family: @font-family-monospace;
|
||||
}
|
||||
|
||||
.tooltip-wrapper {
|
||||
display: inline-block;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user