1
0
Fork 0
VaultUI/src/pages/PwGen.ts

142 lines
4 KiB
TypeScript
Raw Normal View History

2021-05-08 01:45:35 +01:00
import { CopyableInputBox, CopyableInputBoxType } from "../elements/CopyableInputBox";
import { Margin } from "../elements/Margin";
2021-05-07 23:33:58 +01:00
import { Page } from "../types/Page";
import { makeElement } from "../htmlUtils";
2021-05-07 23:21:38 +01:00
import { setPageContent } from "../pageUtils";
import i18next from 'i18next';
2021-05-09 16:02:04 +01:00
import { Option } from "../elements/Option";
const passwordLengthMin = 1;
const passwordLengthMax = 64;
const passwordLengthDefault = 24;
2021-04-15 13:01:58 +01:00
function random() {
if (typeof window.crypto?.getRandomValues === 'function' && typeof window.Uint32Array === 'function') {
2021-04-15 15:37:52 +01:00
return window.crypto.getRandomValues(new Uint32Array(1))[0] / 4294967295;
}
2021-04-15 13:01:58 +01:00
2021-04-15 15:37:52 +01:00
return Math.random();
2021-04-15 13:01:58 +01:00
}
const lowerCase = 'abcdefghijklmnopqrstuvwxyz';
const upperCase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
const numbers = '1234567890';
const special = '!#$%&()*+,-./:;<=>?@[]^_{|}~';
const alphabets = {
SECURE: lowerCase + upperCase + numbers + special,
SMOL: lowerCase + numbers,
HEX: '123456789ABCDEF',
}
const passwordOptionsDefault = {
length: passwordLengthDefault,
alphabet: alphabets.SECURE,
}
2021-04-15 13:01:58 +01:00
function genPassword(options = passwordOptionsDefault) {
2021-04-15 15:37:52 +01:00
let pw = "";
2021-05-08 01:45:35 +01:00
options = { ...passwordOptionsDefault, ...options }
const pwArray = options.alphabet.split('');
for (let i = 0; i < options.length; i++) {
2021-04-15 15:37:52 +01:00
pw = pw.concat(pwArray[Math.floor(random() * pwArray.length)]);
}
return pw;
2021-04-15 13:01:58 +01:00
}
export class PwGenPage extends Page {
2021-04-15 15:37:52 +01:00
constructor() {
super();
}
2021-05-08 01:45:35 +01:00
passwordBox: CopyableInputBoxType;
passwordLengthTitle: HTMLTitleElement;
passwordLengthRange: HTMLInputElement;
passwordAlphabet: HTMLSelectElement;
passwordForm: HTMLFormElement;
2021-05-08 01:45:35 +01:00
async render(): Promise<void> {
setPageContent("");
2021-05-08 01:45:35 +01:00
this.passwordBox = CopyableInputBox(genPassword(passwordOptionsDefault)) ;
this.passwordLengthTitle = makeElement({
tag: "h4",
text: this.getPasswordLengthText()
2021-05-08 01:45:35 +01:00
}) as HTMLTitleElement;
this.passwordLengthRange = makeElement({
tag: "input",
name: "length",
class: ["uk-range", "uk-width-1-2"],
attributes: {
type: "range",
value: passwordLengthDefault,
max: passwordLengthMax,
min: passwordLengthMin,
},
2021-05-08 01:45:35 +01:00
}) as HTMLInputElement;
this.passwordLengthRange.addEventListener('input', this.updatePassword.bind(this));
this.passwordAlphabet = makeElement({
tag: "select",
class: ["uk-select", "uk-width-1-2"],
children: [
Option("a-z a-Z 0-9 specials", alphabets.SECURE),
Option("a-z 0-9", alphabets.SMOL),
Option("A-F 1-9", alphabets.HEX),
]
2021-05-08 01:45:35 +01:00
}) as HTMLSelectElement;
this.passwordForm = makeElement({
tag: "form",
2021-04-15 15:37:52 +01:00
children: [
this.passwordLengthTitle,
Margin(this.passwordLengthRange),
Margin(this.passwordAlphabet),
Margin(this.passwordBox),
Margin(makeElement({
2021-04-15 15:37:52 +01:00
tag: "button",
text: i18next.t("gen_password_btn"),
2021-04-15 15:37:52 +01:00
class: ["uk-button", "uk-button-primary", "uk-margin-bottom"],
2021-05-08 01:45:35 +01:00
attributes: { type: "submit" },
}))
2021-04-15 15:37:52 +01:00
]
2021-05-08 01:45:35 +01:00
}) as HTMLFormElement;
this.passwordForm.addEventListener("submit", (e) => this.formEvent(e));
setPageContent(this.passwordForm);
}
2021-05-08 01:45:35 +01:00
getPasswordLengthText(): string {
return i18next.t("password_length_title", {
min: this?.passwordLengthRange?.value || 24,
max: passwordLengthMax
});
}
2021-05-08 01:45:35 +01:00
formEvent(e: Event): void {
e.preventDefault();
this.updatePassword();
}
2021-05-08 01:45:35 +01:00
updatePassword(): void {
this.passwordLengthTitle.innerText = this.getPasswordLengthText();
this.passwordBox.setText(genPassword({
2021-05-08 01:45:35 +01:00
length: (this.passwordLengthRange.value as unknown) as number,
alphabet: this.passwordAlphabet.value as string,
}));
2021-04-15 15:37:52 +01:00
}
2021-05-08 01:45:35 +01:00
cleanup(): void {
this.passwordBox = undefined;
this.passwordLengthTitle = undefined;
this.passwordLengthRange = undefined;
this.passwordAlphabet = undefined;
this.passwordForm = undefined;
}
2021-05-08 01:45:35 +01:00
get name(): string {
return i18next.t("password_generator_title");
2021-04-15 15:37:52 +01:00
}
2021-04-15 13:01:58 +01:00
}