[Typescript] Convert password generator (#366)
* Convert password generator to typescript. * Misc cleanup.
This commit is contained in:
parent
63af729b50
commit
bcf0f19aa2
|
@ -132,7 +132,6 @@ require('./settings/settingsAddFolderController.js');
|
||||||
require('./settings/settingsEditFolderController.js');
|
require('./settings/settingsEditFolderController.js');
|
||||||
require('./settings/settingsPremiumController.js');
|
require('./settings/settingsPremiumController.js');
|
||||||
require('./settings/settingsEnvironmentController.js');
|
require('./settings/settingsEnvironmentController.js');
|
||||||
require('./tools/toolsPasswordGeneratorController.js');
|
|
||||||
require('./tools/toolsPasswordGeneratorHistoryController.js');
|
require('./tools/toolsPasswordGeneratorHistoryController.js');
|
||||||
require('./tools/toolsExportController.js');
|
require('./tools/toolsExportController.js');
|
||||||
|
|
||||||
|
|
|
@ -167,8 +167,7 @@ angular
|
||||||
|
|
||||||
.state('passwordGenerator', {
|
.state('passwordGenerator', {
|
||||||
url: '/password-generator',
|
url: '/password-generator',
|
||||||
template: require('./tools/views/toolsPasswordGenerator.html'),
|
component: 'passwordGenerator',
|
||||||
controller: 'toolsPasswordGeneratorController',
|
|
||||||
data: { authorize: true },
|
data: { authorize: true },
|
||||||
params: { animation: null, addState: null, editState: null }
|
params: { animation: null, addState: null, editState: null }
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,84 +1,84 @@
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<a ng-click="close()" href="">{{i18n.close}}</a>
|
<a ng-click="$ctrl.close()" href="">{{$ctrl.i18n.close}}</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<a ng-click="select()" ng-show="showSelect" href="">{{i18n.select}}</a>
|
<a ng-click="$ctrl.select()" ng-show="$ctrl.showSelect" href="">{{$ctrl.i18n.select}}</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="title">{{i18n.generatePassword}}</div>
|
<div class="title">{{$ctrl.i18n.generatePassword}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="generate-password-block">
|
<div class="generate-password-block">
|
||||||
{{password}}
|
{{$ctrl.password}}
|
||||||
</div>
|
</div>
|
||||||
<div class="list" style="margin-top: 0;">
|
<div class="list" style="margin-top: 0;">
|
||||||
<div class="list-section" style="padding-top: 0;">
|
<div class="list-section" style="padding-top: 0;">
|
||||||
<div class="list-section-items">
|
<div class="list-section-items">
|
||||||
<a class="list-section-item text-primary" href="" ng-click="regenerate(true)">
|
<a class="list-section-item text-primary" href="" ng-click="$ctrl.regenerate(true)">
|
||||||
{{i18n.regeneratePassword}}
|
{{$ctrl.i18n.regeneratePassword}}
|
||||||
</a>
|
</a>
|
||||||
<a class="list-section-item text-primary" href="" ngclipboard ngclipboard-error="clipboardError(e)"
|
<a class="list-section-item text-primary" href="" ngclipboard ngclipboard-error="$ctrl.clipboardError(e)"
|
||||||
ngclipboard-success="clipboardSuccess(e)" data-clipboard-text="{{password}}">
|
ngclipboard-success="$ctrl.clipboardSuccess(e)" data-clipboard-text="{{$ctrl.password}}">
|
||||||
{{i18n.copyPassword}}
|
{{$ctrl.i18n.copyPassword}}
|
||||||
</a>
|
</a>
|
||||||
<a class="list-section-item text-primary" href="" ng-click="goHistory()">
|
<a class="list-section-item text-primary" href="" ng-click="$ctrl.goHistory()">
|
||||||
{{i18n.passwordHistory}}
|
{{$ctrl.i18n.passwordHistory}}
|
||||||
<i class="fa fa-chevron-right fa-lg"></i>
|
<i class="fa fa-chevron-right fa-lg"></i>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="list-section">
|
<div class="list-section">
|
||||||
<div class="list-section-header">
|
<div class="list-section-header">
|
||||||
{{i18n.options}}
|
{{$ctrl.i18n.options}}
|
||||||
</div>
|
</div>
|
||||||
<div class="list-section-items">
|
<div class="list-section-items">
|
||||||
<div class="list-section-item list-section-item-slider">
|
<div class="list-section-item list-section-item-slider">
|
||||||
<label for="length">{{i18n.length}}</label>
|
<label for="length">{{$ctrl.i18n.length}}</label>
|
||||||
<span class="slider-value">{{options.length}}</span>
|
<span class="slider-value">{{$ctrl.options.length}}</span>
|
||||||
<div class="slider-wrapper">
|
<div class="slider-wrapper">
|
||||||
<input id="length" type="range" min="5" max="128" step="1" ng-model="options.length"
|
<input id="length" type="range" min="5" max="128" step="1" ng-model="$ctrl.options.length"
|
||||||
ng-change="sliderMoved()">
|
ng-change="$ctrl.sliderMoved()">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="list-section-item list-section-item-checkbox">
|
<div class="list-section-item list-section-item-checkbox">
|
||||||
<label for="uppercase">A-Z</label>
|
<label for="uppercase">A-Z</label>
|
||||||
<input id="uppercase" type="checkbox" ng-model="options.uppercase" ng-change="saveOptions(options)">
|
<input id="uppercase" type="checkbox" ng-model="$ctrl.options.uppercase" ng-change="$ctrl.saveOptions($ctrl.options)">
|
||||||
</div>
|
</div>
|
||||||
<div class="list-section-item list-section-item-checkbox">
|
<div class="list-section-item list-section-item-checkbox">
|
||||||
<label for="lowercase">a-z</label>
|
<label for="lowercase">a-z</label>
|
||||||
<input id="lowercase" type="checkbox" ng-model="options.lowercase" ng-change="saveOptions(options)">
|
<input id="lowercase" type="checkbox" ng-model="$ctrl.options.lowercase" ng-change="$ctrl.saveOptions($ctrl.options)">
|
||||||
</div>
|
</div>
|
||||||
<div class="list-section-item list-section-item-checkbox">
|
<div class="list-section-item list-section-item-checkbox">
|
||||||
<label for="numbers">0-9</label>
|
<label for="numbers">0-9</label>
|
||||||
<input id="numbers" type="checkbox" ng-model="options.number" ng-change="saveOptions(options)">
|
<input id="numbers" type="checkbox" ng-model="$ctrl.options.number" ng-change="$ctrl.saveOptions($ctrl.options)">
|
||||||
</div>
|
</div>
|
||||||
<div class="list-section-item list-section-item-checkbox">
|
<div class="list-section-item list-section-item-checkbox">
|
||||||
<label for="special">!@#$%^&*</label>
|
<label for="special">!@#$%^&*</label>
|
||||||
<input id="special" type="checkbox" ng-model="options.special" ng-change="saveOptions(options)">
|
<input id="special" type="checkbox" ng-model="$ctrl.options.special" ng-change="$ctrl.saveOptions($ctrl.options)">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="list-section">
|
<div class="list-section">
|
||||||
<div class="list-section-items">
|
<div class="list-section-items">
|
||||||
<div class="list-section-item list-section-item-input">
|
<div class="list-section-item list-section-item-input">
|
||||||
<label for="min-numbers">{{i18n.minNumbers}}</label>
|
<label for="min-numbers">{{$ctrl.i18n.minNumbers}}</label>
|
||||||
<input id="min-numbers" type="number" min="0" max="5" ng-model="options.minNumber"
|
<input id="min-numbers" type="number" min="0" max="5" ng-model="$ctrl.options.minNumber"
|
||||||
ng-change="saveOptions(options)">
|
ng-change="$ctrl.saveOptions($ctrl.options)">
|
||||||
</div>
|
</div>
|
||||||
<div class="list-section-item list-section-item-input">
|
<div class="list-section-item list-section-item-input">
|
||||||
<label for="min-special">{{i18n.minSpecial}}</label>
|
<label for="min-special">{{$ctrl.i18n.minSpecial}}</label>
|
||||||
<input id="min-special" type="number" min="0" max="5" ng-model="options.minSpecial"
|
<input id="min-special" type="number" min="0" max="5" ng-model="$ctrl.options.minSpecial"
|
||||||
ng-change="saveOptions(options)">
|
ng-change="$ctrl.saveOptions($ctrl.options)">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="list-section">
|
<div class="list-section">
|
||||||
<div class="list-section-items">
|
<div class="list-section-items">
|
||||||
<div class="list-section-item list-section-item-checkbox">
|
<div class="list-section-item list-section-item-checkbox">
|
||||||
<label for="ambiguous">{{i18n.avoidAmbChar}}</label>
|
<label for="ambiguous">{{$ctrl.i18n.avoidAmbChar}}</label>
|
||||||
<input id="ambiguous" type="checkbox" ng-model="options.ambiguous"
|
<input id="ambiguous" type="checkbox" ng-model="$ctrl.options.ambiguous"
|
||||||
ng-true-value="false" ng-false-value="true"
|
ng-true-value="false" ng-false-value="true"
|
||||||
ng-change="saveOptions(options)">
|
ng-change="$ctrl.saveOptions($ctrl.options)">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
|
@ -0,0 +1,139 @@
|
||||||
|
import * as angular from 'angular';
|
||||||
|
import * as template from './password-generator.component.html';
|
||||||
|
|
||||||
|
export class PasswordGeneratorController {
|
||||||
|
$transition$: any;
|
||||||
|
options: any;
|
||||||
|
showSelect: any;
|
||||||
|
password: string = '-';
|
||||||
|
editState: any;
|
||||||
|
addState: any;
|
||||||
|
i18n: any;
|
||||||
|
|
||||||
|
constructor(private $state: any, private passwordGenerationService: any,
|
||||||
|
private toastr: any, utilsService: any, private $analytics: any,
|
||||||
|
private i18nService: any) {
|
||||||
|
this.i18n = i18nService;
|
||||||
|
|
||||||
|
utilsService.initListSectionItemListeners($(document), angular);
|
||||||
|
|
||||||
|
passwordGenerationService.getOptions().then((options: any) => {
|
||||||
|
this.options = options;
|
||||||
|
this.regenerate(false);
|
||||||
|
$analytics.eventTrack('Generated Password');
|
||||||
|
passwordGenerationService.addHistory(this.password);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Save password once the slider stop moving.
|
||||||
|
document.querySelector('#length').addEventListener('change', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
$analytics.eventTrack('Generated Password');
|
||||||
|
this.saveOptions(this.options, false);
|
||||||
|
passwordGenerationService.addHistory(this.password);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$onInit() {
|
||||||
|
const params = this.$transition$.params('to');
|
||||||
|
this.addState = params.addState;
|
||||||
|
this.editState = params.editState;
|
||||||
|
|
||||||
|
this.showSelect = this.addState || this.editState;
|
||||||
|
}
|
||||||
|
|
||||||
|
sliderMoved() {
|
||||||
|
this.regenerate(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
regenerate(trackEvent: any) {
|
||||||
|
this.password = this.passwordGenerationService.generatePassword(this.options);
|
||||||
|
|
||||||
|
if (trackEvent) {
|
||||||
|
this.$analytics.eventTrack('Regenerated Password');
|
||||||
|
this.passwordGenerationService.addHistory(this.password);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
saveOptions(options: any, regenerate: boolean = true) {
|
||||||
|
if (!options.uppercase && !options.lowercase && !options.number && !options.special) {
|
||||||
|
options.lowercase = this.options.lowercase = true;
|
||||||
|
}
|
||||||
|
if (!options.minNumber) {
|
||||||
|
options.minNumber = this.options.minNumber = 0;
|
||||||
|
}
|
||||||
|
if (!options.minSpecial) {
|
||||||
|
options.minSpecial = this.options.minSpecial = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.passwordGenerationService.saveOptions(options);
|
||||||
|
if (regenerate) {
|
||||||
|
this.regenerate(false);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
clipboardError(e: any, password: any) {
|
||||||
|
this.toastr.info(this.i18nService.browserNotSupportClipboard);
|
||||||
|
}
|
||||||
|
|
||||||
|
clipboardSuccess(e: any) {
|
||||||
|
this.$analytics.eventTrack('Copied Generated Password');
|
||||||
|
e.clearSelection();
|
||||||
|
this.toastr.info(this.i18nService.passwordCopied);
|
||||||
|
}
|
||||||
|
|
||||||
|
close() {
|
||||||
|
this.dismiss();
|
||||||
|
}
|
||||||
|
|
||||||
|
select() {
|
||||||
|
this.$analytics.eventTrack('Selected Generated Password');
|
||||||
|
|
||||||
|
if (this.addState) {
|
||||||
|
this.addState.cipher.login.password = this.password;
|
||||||
|
} else if (this.editState) {
|
||||||
|
this.editState.cipher.login.password = this.password;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dismiss();
|
||||||
|
}
|
||||||
|
|
||||||
|
goHistory() {
|
||||||
|
this.$state.go('^.passwordGeneratorHistory', {
|
||||||
|
animation: 'in-slide-left',
|
||||||
|
addState: this.addState,
|
||||||
|
editState: this.editState,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private dismiss() {
|
||||||
|
if (this.addState) {
|
||||||
|
this.$state.go('addCipher', {
|
||||||
|
animation: 'out-slide-down',
|
||||||
|
from: this.addState.from,
|
||||||
|
cipher: this.addState.cipher,
|
||||||
|
});
|
||||||
|
} else if (this.editState) {
|
||||||
|
this.$state.go('editCipher', {
|
||||||
|
animation: 'out-slide-down',
|
||||||
|
cipher: this.editState.cipher,
|
||||||
|
fromView: this.editState.fromView,
|
||||||
|
cipherId: this.editState.cipherId,
|
||||||
|
from: this.editState.from,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.$state.go('tabs.tools', {
|
||||||
|
animation: 'out-slide-down',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const PasswordGeneratorComponent = {
|
||||||
|
bindings: {
|
||||||
|
$transition$: '<',
|
||||||
|
},
|
||||||
|
controller: PasswordGeneratorController,
|
||||||
|
template,
|
||||||
|
};
|
|
@ -1,7 +1,11 @@
|
||||||
import * as angular from 'angular';
|
import * as angular from 'angular';
|
||||||
|
import { PasswordGeneratorComponent } from './password-generator.component';
|
||||||
import { ToolsComponent } from './tools.component';
|
import { ToolsComponent } from './tools.component';
|
||||||
|
|
||||||
export default angular
|
export default angular
|
||||||
.module('bit.tools', ['ngAnimate', 'ngclipboard', 'toastr', 'oitozero.ngSweetAlert'])
|
.module('bit.tools', ['ngAnimate', 'ngclipboard', 'toastr', 'oitozero.ngSweetAlert'])
|
||||||
|
|
||||||
.component('tools', ToolsComponent)
|
.component('tools', ToolsComponent)
|
||||||
|
.component('passwordGenerator', PasswordGeneratorComponent)
|
||||||
|
|
||||||
.name;
|
.name;
|
||||||
|
|
|
@ -1,116 +0,0 @@
|
||||||
angular
|
|
||||||
.module('bit.tools')
|
|
||||||
|
|
||||||
.controller('toolsPasswordGeneratorController', function ($scope, $state, $stateParams, passwordGenerationService,
|
|
||||||
toastr, utilsService, $analytics, i18nService) {
|
|
||||||
$scope.i18n = i18nService;
|
|
||||||
var addState = $stateParams.addState,
|
|
||||||
editState = $stateParams.editState;
|
|
||||||
|
|
||||||
$scope.showSelect = $stateParams.addState || $stateParams.editState;
|
|
||||||
|
|
||||||
utilsService.initListSectionItemListeners($(document), angular);
|
|
||||||
$scope.password = '-';
|
|
||||||
|
|
||||||
passwordGenerationService.getOptions().then(function (options) {
|
|
||||||
$scope.options = options;
|
|
||||||
$scope.regenerate(false);
|
|
||||||
$analytics.eventTrack('Generated Password');
|
|
||||||
passwordGenerationService.addHistory($scope.password);
|
|
||||||
});
|
|
||||||
|
|
||||||
$scope.sliderMoved = function () {
|
|
||||||
$scope.regenerate(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
$('#length').change(function (e) {
|
|
||||||
e.preventDefault();
|
|
||||||
$analytics.eventTrack('Generated Password');
|
|
||||||
$scope.saveOptions($scope.options);
|
|
||||||
passwordGenerationService.addHistory($scope.password);
|
|
||||||
});
|
|
||||||
|
|
||||||
$scope.regenerate = function (trackEvent) {
|
|
||||||
$scope.password = passwordGenerationService.generatePassword($scope.options);
|
|
||||||
|
|
||||||
if (trackEvent) {
|
|
||||||
$analytics.eventTrack('Regenerated Password');
|
|
||||||
passwordGenerationService.addHistory($scope.password);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
$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(false);
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.clipboardError = function (e, password) {
|
|
||||||
toastr.info(i18n.browserNotSupportClipboard);
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.clipboardSuccess = function (e) {
|
|
||||||
$analytics.eventTrack('Copied Generated Password');
|
|
||||||
e.clearSelection();
|
|
||||||
toastr.info(i18nService.passwordCopied);
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.close = function () {
|
|
||||||
dismiss();
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.select = function () {
|
|
||||||
$analytics.eventTrack('Selected Generated Password');
|
|
||||||
|
|
||||||
if (addState) {
|
|
||||||
addState.cipher.login.password = $scope.password;
|
|
||||||
}
|
|
||||||
else if (editState) {
|
|
||||||
editState.cipher.login.password = $scope.password;
|
|
||||||
}
|
|
||||||
|
|
||||||
dismiss();
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.goHistory = function () {
|
|
||||||
$state.go('^.passwordGeneratorHistory', {
|
|
||||||
animation: 'in-slide-left',
|
|
||||||
addState: $stateParams.addState,
|
|
||||||
editState: $stateParams.editState
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
function dismiss() {
|
|
||||||
if (addState) {
|
|
||||||
$state.go('addCipher', {
|
|
||||||
animation: 'out-slide-down',
|
|
||||||
from: addState.from,
|
|
||||||
cipher: addState.cipher
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else if (editState) {
|
|
||||||
$state.go('editCipher', {
|
|
||||||
animation: 'out-slide-down',
|
|
||||||
cipher: editState.cipher,
|
|
||||||
fromView: editState.fromView,
|
|
||||||
cipherId: editState.cipherId,
|
|
||||||
from: editState.from
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$state.go('tabs.tools', {
|
|
||||||
animation: 'out-slide-down'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
Loading…
Reference in New Issue