mirror of
https://github.com/bitwarden/desktop.git
synced 2024-11-14 10:16:02 +01:00
Generate andcopy passwords. Save password options
This commit is contained in:
parent
4105d2b5ad
commit
350d671c26
@ -6,6 +6,7 @@ var siteService = new SiteService(cryptoService, userService, apiService);
|
||||
var folderService = new FolderService(cryptoService, userService, apiService);
|
||||
var syncService = new SyncService(siteService, folderService, userService, apiService);
|
||||
var autofillService = new AutofillService();
|
||||
var passwordGenerationService = new PasswordGenerationService();
|
||||
|
||||
function buildContextMenu() {
|
||||
chrome.contextMenus.removeAll();
|
||||
|
@ -89,7 +89,7 @@
|
||||
templateUrl: 'app/vault/views/vaultAddSite.html',
|
||||
controller: 'vaultAddSiteController',
|
||||
data: { authorize: true },
|
||||
params: { animation: null, returnScrollY: 0, returnSearchText: null, name: null, uri: null }
|
||||
params: { animation: null, returnScrollY: 0, returnSearchText: null, name: null, uri: null, site: null }
|
||||
})
|
||||
.state('editSite', {
|
||||
url: '/edit-site?siteId',
|
||||
@ -104,7 +104,7 @@
|
||||
templateUrl: 'app/tools/views/toolsPasswordGenerator.html',
|
||||
controller: 'toolsPasswordGeneratorController',
|
||||
data: { authorize: true },
|
||||
params: { animation: null, fromAdd: false, fromEdit: null }
|
||||
params: { animation: null, addState: null, editState: null }
|
||||
});
|
||||
})
|
||||
.run(function ($rootScope, userService, loginService, tokenService, $state) {
|
||||
|
@ -1,2 +1,2 @@
|
||||
angular
|
||||
.module('bit.tools', []);
|
||||
.module('bit.tools', ['ngAnimate', 'ngclipboard', 'toastr']);
|
||||
|
@ -1,6 +1,63 @@
|
||||
angular
|
||||
.module('bit.tools')
|
||||
|
||||
.controller('toolsPasswordGeneratorController', function ($scope, $state, $stateParams) {
|
||||
.controller('toolsPasswordGeneratorController', function ($scope, $state, $stateParams, passwordGenerationService, toastr, $q) {
|
||||
var addState = $stateParams.addState,
|
||||
editState = $stateParams.editState;
|
||||
|
||||
popupUtils.initListSectionItemListeners();
|
||||
$scope.password = '-';
|
||||
|
||||
$q.when(passwordGenerationService.getOptions()).then(function (options) {
|
||||
$scope.options = options;
|
||||
$scope.regenerate();
|
||||
});
|
||||
|
||||
$scope.regenerate = function () {
|
||||
$scope.password = passwordGenerationService.generatePassword($scope.options);
|
||||
};
|
||||
|
||||
$scope.saveOptions = function (options) {
|
||||
if (!options.uppercase && !options.lowercase && !options.number && !options.special) {
|
||||
options.lowercase = $scope.options.lowercase = true;
|
||||
}
|
||||
if (!options.minNumber) {
|
||||
options.minNumber = $scope.options.minNumber = 0;
|
||||
}
|
||||
if (!options.minSpecial) {
|
||||
options.minSpecial = $scope.options.minSpecial = 0;
|
||||
}
|
||||
|
||||
passwordGenerationService.saveOptions(options);
|
||||
$scope.regenerate();
|
||||
};
|
||||
|
||||
$scope.clipboardError = function (e, password) {
|
||||
toastr.info('Your web browser does not support easy clipboard copying. Copy it manually instead.');
|
||||
};
|
||||
|
||||
$scope.clipboardSuccess = function (e) {
|
||||
e.clearSelection();
|
||||
toastr.info('Password copied!');
|
||||
};
|
||||
|
||||
$scope.close = function () {
|
||||
if (addState) {
|
||||
$state.go('addSite', {
|
||||
animation: 'out-slide-down',
|
||||
site: addState
|
||||
});
|
||||
}
|
||||
else if (editState) {
|
||||
$state.go('editSite', {
|
||||
animation: 'out-slide-down',
|
||||
siteId: editState
|
||||
});
|
||||
}
|
||||
else {
|
||||
$state.go('tabs.tools', {
|
||||
animation: 'out-slide-down'
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
@ -9,15 +9,16 @@
|
||||
</div>
|
||||
<div class="content">
|
||||
<div style="margin: 20px; font-size: 20px; text-align: center;">
|
||||
<span id="generated-password">*&Houhdasdy87</span>
|
||||
<span id="generated-password">{{password}}</span>
|
||||
</div>
|
||||
<div class="list" style="margin-top: 0;">
|
||||
<div class="list-section" style="padding-top: 0;">
|
||||
<div class="list-section-items">
|
||||
<a class="list-section-item" href="#">
|
||||
<a class="list-section-item text-primary" href="" ng-click="regenerate()">
|
||||
Regenerate Password
|
||||
</a>
|
||||
<a class="list-section-item" href="#">
|
||||
<a class="list-section-item text-primary" href="" ngclipboard ngclipboard-error="clipboardError(e)"
|
||||
ngclipboard-success="clipboardSuccess(e)" data-clipboard-target="#generated-password">
|
||||
Copy Password
|
||||
</a>
|
||||
</div>
|
||||
@ -32,19 +33,19 @@
|
||||
</div>
|
||||
<div class="list-section-item list-section-item-checkbox">
|
||||
<label for="uppercase">A-Z</label>
|
||||
<input id="uppercase" type="checkbox">
|
||||
<input id="uppercase" type="checkbox" ng-model="options.uppercase" ng-change="saveOptions(options)">
|
||||
</div>
|
||||
<div class="list-section-item list-section-item-checkbox">
|
||||
<label for="lowercase">a-z</label>
|
||||
<input id="lowercase" type="checkbox">
|
||||
<input id="lowercase" type="checkbox" ng-model="options.lowercase" ng-change="saveOptions(options)">
|
||||
</div>
|
||||
<div class="list-section-item list-section-item-checkbox">
|
||||
<label for="numbers">0-9</label>
|
||||
<input id="numbers" type="checkbox">
|
||||
<input id="numbers" type="checkbox" ng-model="options.number" ng-change="saveOptions(options)">
|
||||
</div>
|
||||
<div class="list-section-item list-section-item-checkbox">
|
||||
<label for="special">!@#$%^&*</label>
|
||||
<input id="special" type="checkbox">
|
||||
<input id="special" type="checkbox" ng-model="options.special" ng-change="saveOptions(options)">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -52,11 +53,11 @@
|
||||
<div class="list-section-items">
|
||||
<div class="list-section-item list-section-item-input">
|
||||
<label for="min-numbers">Minimum Numbers</label>
|
||||
<input id="min-numbers" type="number" min="0" max="5">
|
||||
<input id="min-numbers" type="number" min="0" max="5" ng-model="options.minNumber" ng-change="saveOptions(options)">
|
||||
</div>
|
||||
<div class="list-section-item list-section-item-input">
|
||||
<label for="min-special">Minimum Special</label>
|
||||
<input id="min-special" type="number" min="0" max="5">
|
||||
<input id="min-special" type="number" min="0" max="5" ng-model="options.minSpecial" ng-change="saveOptions(options)">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -64,7 +65,7 @@
|
||||
<div class="list-section-items">
|
||||
<div class="list-section-item list-section-item-checkbox">
|
||||
<label for="ambiguous">Avoid Ambiguous Characters</label>
|
||||
<input id="ambiguous" type="checkbox">
|
||||
<input id="ambiguous" type="checkbox" ng-model="options.ambiguous" ng-change="saveOptions(options)">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -200,6 +200,10 @@
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
|
||||
&.text-primary {
|
||||
color: @brand-primary !important;
|
||||
}
|
||||
|
||||
&:not(.wrap) {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
|
@ -24,6 +24,9 @@
|
||||
}
|
||||
else if (checkbox.length > 0) {
|
||||
checkbox.prop('checked', !checkbox.is(':checked'));
|
||||
if (angular) {
|
||||
angular.element(checkbox[0]).triggerHandler('click');
|
||||
}
|
||||
}
|
||||
else if (select.length > 0) {
|
||||
select.openSelect();
|
||||
|
@ -1,10 +1,12 @@
|
||||
function PasswordGenerationService() {
|
||||
this.optionsCache = null;
|
||||
|
||||
initPasswordGenerationService();
|
||||
};
|
||||
|
||||
function initPasswordGenerationService() {
|
||||
PasswordGenerationService.prototype.generatePassword = function (options) {
|
||||
var defaults = {
|
||||
var optionsKey = 'passwordGenerationOptions';
|
||||
var defaultOptions = {
|
||||
length: 10,
|
||||
ambiguous: false,
|
||||
number: true,
|
||||
@ -17,8 +19,9 @@ function initPasswordGenerationService() {
|
||||
minSpecial: 1
|
||||
};
|
||||
|
||||
PasswordGenerationService.prototype.generatePassword = function (options) {
|
||||
// overload defaults with given options
|
||||
var o = angular.extend({}, defaults, options);
|
||||
var o = extend({}, defaultOptions, options);
|
||||
|
||||
// sanitize
|
||||
if (o.uppercase && o.minUppercase < 0) o.minUppercase = 1;
|
||||
@ -99,4 +102,52 @@ function initPasswordGenerationService() {
|
||||
function randomInt(min, max) {
|
||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
}
|
||||
|
||||
function extend() {
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
for (var key in arguments[i]) {
|
||||
if (arguments[i].hasOwnProperty(key)) {
|
||||
arguments[0][key] = arguments[i][key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return arguments[0];
|
||||
}
|
||||
|
||||
PasswordGenerationService.prototype.getOptions = function () {
|
||||
var deferred = Q.defer();
|
||||
var self = this;
|
||||
|
||||
if (self.optionsCache) {
|
||||
deferred.resolve(self.optionsCache);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
chrome.storage.local.get(optionsKey, function (obj) {
|
||||
var options = obj[optionsKey];
|
||||
if (!options) {
|
||||
options = defaultOptions;
|
||||
}
|
||||
|
||||
self.optionsCache = options;
|
||||
deferred.resolve(self.optionsCache);
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
PasswordGenerationService.prototype.saveOptions = function (options) {
|
||||
var deferred = Q.defer();
|
||||
var self = this;
|
||||
|
||||
var obj = {};
|
||||
obj[optionsKey] = options;
|
||||
chrome.storage.local.set(obj, function () {
|
||||
self.optionsCache = options;
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user