Add typing to PwGen.ts.
This commit is contained in:
parent
dd9a63a8db
commit
fd46140ad2
|
@ -1,15 +1,15 @@
|
||||||
import { HomePage } from "./pages/Home.js";
|
import { HomePage } from "./pages/Home";
|
||||||
import { KeyValueDeletePage } from "./pages/KeyValue/KeyValueDelete.js";
|
import { KeyValueDeletePage } from "./pages/KeyValue/KeyValueDelete.js";
|
||||||
import { KeyValueNewPage } from "./pages/KeyValue/KeyValueNew.js";
|
import { KeyValueNewPage } from "./pages/KeyValue/KeyValueNew.js";
|
||||||
import { KeyValueSecretEditPage } from "./pages/KeyValue/KeyValueSecretsEdit.js";
|
import { KeyValueSecretEditPage } from "./pages/KeyValue/KeyValueSecretsEdit.js";
|
||||||
import { KeyValueSecretPage } from "./pages/KeyValue/KeyValueSecret.js";
|
import { KeyValueSecretPage } from "./pages/KeyValue/KeyValueSecret.js";
|
||||||
import { KeyValueVersionsPage } from "./pages/KeyValue/KeyValueVersions.js";
|
import { KeyValueVersionsPage } from "./pages/KeyValue/KeyValueVersions.js";
|
||||||
import { KeyValueViewPage } from "./pages/KeyValue/KeyValueView.js";
|
import { KeyValueViewPage } from "./pages/KeyValue/KeyValueView.js";
|
||||||
import { LoginPage } from "./pages/Login.js";
|
import { LoginPage } from "./pages/Login";
|
||||||
import { MePage } from "./pages/Me.js";
|
import { MePage } from "./pages/Me";
|
||||||
import { NewTOTPPage } from "./pages/TOTP/NewTOTP.js";
|
import { NewTOTPPage } from "./pages/TOTP/NewTOTP.js";
|
||||||
import { Page } from "./types/Page";
|
import { Page } from "./types/Page";
|
||||||
import { PwGenPage } from "./pages/PwGen.js";
|
import { PwGenPage } from "./pages/PwGen";
|
||||||
import { SetLanguagePage } from "./pages/SetLanguage.js";
|
import { SetLanguagePage } from "./pages/SetLanguage.js";
|
||||||
import { SetVaultURLPage } from "./pages/SetVaultURL.js";
|
import { SetVaultURLPage } from "./pages/SetVaultURL.js";
|
||||||
import { TOTPViewPage } from "./pages/TOTP/TOTPView.js";
|
import { TOTPViewPage } from "./pages/TOTP/TOTPView.js";
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { makeElement } from "../htmlUtils";
|
||||||
import ClipboardJS from "clipboard";
|
import ClipboardJS from "clipboard";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
interface CopyableInputBoxType extends HTMLElement {
|
export interface CopyableInputBoxType extends HTMLElement {
|
||||||
setText(text: string): void;
|
setText(text: string): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { Page } from "../types/Page";
|
import { Page } from "../types/Page";
|
||||||
import { changePage, prePageChecks, setErrorText } from "../pageUtils";
|
import { changePage, prePageChecks, setErrorText, setPageContent } from "../pageUtils";
|
||||||
import { getMounts } from "../api/getMounts";
|
import { getMounts } from "../api/getMounts";
|
||||||
import { lookupSelf } from "../api/lookupSelf";
|
import { lookupSelf } from "../api/lookupSelf";
|
||||||
import { makeElement } from "../htmlUtils";
|
import { makeElement } from "../htmlUtils";
|
||||||
import { pageState } from "../globalPageState.ts";
|
import { pageState } from "../globalPageState";
|
||||||
import { sortedObjectMap } from "../utils";
|
import { sortedObjectMap } from "../utils";
|
||||||
import i18next from 'i18next';
|
import i18next from 'i18next';
|
||||||
|
|
||||||
|
@ -11,10 +11,12 @@ export class HomePage extends Page {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
async render() {
|
async render(): Promise<void> {
|
||||||
pageContent.innerHTML = "";
|
setPageContent("");
|
||||||
if (!(await prePageChecks())) return;
|
if (!(await prePageChecks())) return;
|
||||||
|
|
||||||
|
const homePageContent = makeElement({tag: "div"});
|
||||||
|
setPageContent(homePageContent);
|
||||||
const textList = makeElement({
|
const textList = makeElement({
|
||||||
tag: "ul",
|
tag: "ul",
|
||||||
class: "uk-nav",
|
class: "uk-nav",
|
||||||
|
@ -38,10 +40,10 @@ export class HomePage extends Page {
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
pageContent.appendChild(textList);
|
homePageContent.appendChild(textList);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let selfTokenInfo = await lookupSelf();
|
const selfTokenInfo = await lookupSelf();
|
||||||
textList.appendChild(makeElement({
|
textList.appendChild(makeElement({
|
||||||
tag: "li",
|
tag: "li",
|
||||||
text: i18next.t("your_token_expires_in", {"date": new Date(selfTokenInfo.expire_time)})
|
text: i18next.t("your_token_expires_in", {"date": new Date(selfTokenInfo.expire_time)})
|
||||||
|
@ -60,9 +62,9 @@ export class HomePage extends Page {
|
||||||
pageState.currentSecretVersion = null;
|
pageState.currentSecretVersion = null;
|
||||||
|
|
||||||
const navList = makeElement({ tag: "ul", class: ["uk-nav", "uk-nav-default", "uk-margin-top"] });
|
const navList = makeElement({ tag: "ul", class: ["uk-nav", "uk-nav-default", "uk-margin-top"] });
|
||||||
pageContent.appendChild(navList);
|
homePageContent.appendChild(navList);
|
||||||
|
|
||||||
let mounts = await getMounts();
|
const mounts = await getMounts();
|
||||||
// sort it by secretPath so it's in alphabetical order consistantly.
|
// sort it by secretPath so it's in alphabetical order consistantly.
|
||||||
const mountsMap = sortedObjectMap(mounts);
|
const mountsMap = sortedObjectMap(mounts);
|
||||||
|
|
||||||
|
@ -72,7 +74,7 @@ export class HomePage extends Page {
|
||||||
if (!("type" in mount)) return;
|
if (!("type" in mount)) return;
|
||||||
if (!(["kv", "totp", "transit", "cubbyhole"].includes(mount.type))) return;
|
if (!(["kv", "totp", "transit", "cubbyhole"].includes(mount.type))) return;
|
||||||
|
|
||||||
let mountType = mount.type == "kv" ? "kv-v" + String(mount.options.version) : mount.type;
|
const mountType = mount.type == "kv" ? "kv-v" + String(mount.options.version) : mount.type;
|
||||||
|
|
||||||
let linkText = "";
|
let linkText = "";
|
||||||
let linkPage;
|
let linkPage;
|
||||||
|
@ -104,7 +106,7 @@ export class HomePage extends Page {
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
get name() {
|
get name(): string {
|
||||||
return i18next.t("home_page_title");
|
return i18next.t("home_page_title");
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,7 +4,7 @@ import { Page } from "../types/Page";
|
||||||
import { changePage, setErrorText, setPageContent } from "../pageUtils";
|
import { changePage, setErrorText, setPageContent } from "../pageUtils";
|
||||||
import { lookupSelf } from "../api/lookupSelf";
|
import { lookupSelf } from "../api/lookupSelf";
|
||||||
import { makeElement } from "../htmlUtils";
|
import { makeElement } from "../htmlUtils";
|
||||||
import { pageState } from "../globalPageState.ts";
|
import { pageState } from "../globalPageState";
|
||||||
import { usernameLogin } from "../api/usernameLogin";
|
import { usernameLogin } from "../api/usernameLogin";
|
||||||
import i18next from 'i18next';
|
import i18next from 'i18next';
|
||||||
|
|
||||||
|
@ -12,8 +12,8 @@ export class LoginPage extends Page {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
render() {
|
render(): void {
|
||||||
let tokenLoginForm = makeElement({
|
const tokenLoginForm = makeElement({
|
||||||
tag: "form",
|
tag: "form",
|
||||||
children: [
|
children: [
|
||||||
Margin(makeElement({
|
Margin(makeElement({
|
||||||
|
@ -35,9 +35,9 @@ export class LoginPage extends Page {
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
]
|
]
|
||||||
});
|
}) as HTMLFormElement;
|
||||||
|
|
||||||
let usernameLoginForm = makeElement({
|
const usernameLoginForm = makeElement({
|
||||||
tag: "form",
|
tag: "form",
|
||||||
children: [
|
children: [
|
||||||
Margin(makeElement({
|
Margin(makeElement({
|
||||||
|
@ -71,7 +71,7 @@ export class LoginPage extends Page {
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
]
|
]
|
||||||
});
|
}) as HTMLFormElement;
|
||||||
|
|
||||||
setPageContent(makeElement({
|
setPageContent(makeElement({
|
||||||
tag: "div",
|
tag: "div",
|
||||||
|
@ -122,9 +122,9 @@ export class LoginPage extends Page {
|
||||||
|
|
||||||
tokenLoginForm.addEventListener("submit", function (e) {
|
tokenLoginForm.addEventListener("submit", function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
let formData = new FormData(tokenLoginForm);
|
const formData = new FormData(tokenLoginForm);
|
||||||
const token = formData.get("token");
|
const token = formData.get("token");
|
||||||
pageState.token = token;
|
pageState.token = token as string;
|
||||||
lookupSelf().then(_ => {
|
lookupSelf().then(_ => {
|
||||||
changePage("HOME");
|
changePage("HOME");
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
|
@ -134,8 +134,11 @@ export class LoginPage extends Page {
|
||||||
});
|
});
|
||||||
usernameLoginForm.addEventListener("submit", function (e) {
|
usernameLoginForm.addEventListener("submit", function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
let formData = new FormData(usernameLoginForm);
|
const formData = new FormData(usernameLoginForm);
|
||||||
usernameLogin(formData.get("username"), formData.get("password")).then(res => {
|
usernameLogin(
|
||||||
|
formData.get("username") as string,
|
||||||
|
formData.get("password") as string,
|
||||||
|
).then(res => {
|
||||||
pageState.token = res;
|
pageState.token = res;
|
||||||
changePage("HOME");
|
changePage("HOME");
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
|
@ -146,7 +149,7 @@ export class LoginPage extends Page {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
get name() {
|
get name(): string {
|
||||||
return i18next.t("log_in_title");
|
return i18next.t("log_in_title");
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,7 +2,7 @@ import { Page } from "../types/Page";
|
||||||
import { addClipboardNotifications, changePage, prePageChecks, setErrorText, setPageContent } from "../pageUtils";
|
import { addClipboardNotifications, changePage, prePageChecks, setErrorText, setPageContent } from "../pageUtils";
|
||||||
import { getCapabilitiesPath } from "../api/getCapabilities";
|
import { getCapabilitiesPath } from "../api/getCapabilities";
|
||||||
import { makeElement } from "../htmlUtils";
|
import { makeElement } from "../htmlUtils";
|
||||||
import { pageState } from "../globalPageState.ts";
|
import { pageState } from "../globalPageState";
|
||||||
import { renewSelf } from "../api/renewSelf";
|
import { renewSelf } from "../api/renewSelf";
|
||||||
import { sealVault } from "../api/sealVault";
|
import { sealVault } from "../api/sealVault";
|
||||||
import ClipboardJS from "clipboard";
|
import ClipboardJS from "clipboard";
|
||||||
|
@ -14,7 +14,7 @@ export class MePage extends Page {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
async render() {
|
async render(): Promise<void> {
|
||||||
if (!(await prePageChecks())) return;
|
if (!(await prePageChecks())) return;
|
||||||
setPageContent(makeElement({
|
setPageContent(makeElement({
|
||||||
tag: "ul",
|
tag: "ul",
|
||||||
|
@ -40,7 +40,7 @@ export class MePage extends Page {
|
||||||
"data-clipboard-text": pageState.token,
|
"data-clipboard-text": pageState.token,
|
||||||
},
|
},
|
||||||
thenRun: (e) => {
|
thenRun: (e) => {
|
||||||
let clipboard = new ClipboardJS(e);
|
const clipboard = new ClipboardJS(e);
|
||||||
addClipboardNotifications(clipboard);
|
addClipboardNotifications(clipboard);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -65,7 +65,7 @@ export class MePage extends Page {
|
||||||
tag: "a",
|
tag: "a",
|
||||||
condition: await (async () => {
|
condition: await (async () => {
|
||||||
try {
|
try {
|
||||||
let caps = await getCapabilitiesPath("sys/seal");
|
const caps = await getCapabilitiesPath("sys/seal");
|
||||||
return caps.includes("sudo") && caps.includes("update");
|
return caps.includes("sudo") && caps.includes("update");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return !true;
|
return !true;
|
||||||
|
@ -92,7 +92,7 @@ export class MePage extends Page {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
get name() {
|
get name(): string {
|
||||||
return i18next.t("me_page_title");
|
return i18next.t("me_page_title");
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
import { CopyableInputBox } from "../elements/CopyableInputBox";
|
import { CopyableInputBox, CopyableInputBoxType } from "../elements/CopyableInputBox";
|
||||||
import { Margin } from "../elements/Margin";
|
import { Margin } from "../elements/Margin";
|
||||||
import { Page } from "../types/Page";
|
import { Page } from "../types/Page";
|
||||||
import { makeElement } from "../htmlUtils";
|
import { makeElement } from "../htmlUtils";
|
||||||
|
@ -35,7 +35,7 @@ const passwordOptionsDefault = {
|
||||||
|
|
||||||
function genPassword(options = passwordOptionsDefault) {
|
function genPassword(options = passwordOptionsDefault) {
|
||||||
let pw = "";
|
let pw = "";
|
||||||
options = {...passwordOptionsDefault, ...options}
|
options = { ...passwordOptionsDefault, ...options }
|
||||||
const pwArray = options.alphabet.split('');
|
const pwArray = options.alphabet.split('');
|
||||||
for (let i = 0; i < options.length; i++) {
|
for (let i = 0; i < options.length; i++) {
|
||||||
pw = pw.concat(pwArray[Math.floor(random() * pwArray.length)]);
|
pw = pw.concat(pwArray[Math.floor(random() * pwArray.length)]);
|
||||||
|
@ -54,21 +54,25 @@ function Option(label, value) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export class PwGenPage extends Page {
|
export class PwGenPage extends Page {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
passwordBox: CopyableInputBoxType;
|
||||||
|
passwordLengthTitle: HTMLTitleElement;
|
||||||
|
passwordLengthRange: HTMLInputElement;
|
||||||
|
passwordAlphabet: HTMLSelectElement;
|
||||||
|
passwordForm: HTMLFormElement;
|
||||||
|
|
||||||
async render() {
|
async render(): Promise<void> {
|
||||||
setPageContent("");
|
setPageContent("");
|
||||||
this.passwordBox = CopyableInputBox(genPassword(passwordOptionsDefault));
|
this.passwordBox = CopyableInputBox(genPassword(passwordOptionsDefault)) ;
|
||||||
|
|
||||||
this.passwordLengthTitle = makeElement({
|
this.passwordLengthTitle = makeElement({
|
||||||
tag: "h4",
|
tag: "h4",
|
||||||
text: this.getPasswordLengthText()
|
text: this.getPasswordLengthText()
|
||||||
})
|
}) as HTMLTitleElement;
|
||||||
|
|
||||||
this.passwordLengthRange = makeElement({
|
this.passwordLengthRange = makeElement({
|
||||||
tag: "input",
|
tag: "input",
|
||||||
|
@ -80,7 +84,8 @@ export class PwGenPage extends Page {
|
||||||
max: passwordLengthMax,
|
max: passwordLengthMax,
|
||||||
min: passwordLengthMin,
|
min: passwordLengthMin,
|
||||||
},
|
},
|
||||||
})
|
}) as HTMLInputElement;
|
||||||
|
|
||||||
this.passwordLengthRange.addEventListener('input', this.updatePassword.bind(this));
|
this.passwordLengthRange.addEventListener('input', this.updatePassword.bind(this));
|
||||||
|
|
||||||
this.passwordAlphabet = makeElement({
|
this.passwordAlphabet = makeElement({
|
||||||
|
@ -91,7 +96,7 @@ export class PwGenPage extends Page {
|
||||||
Option("a-z 0-9", alphabets.SMOL),
|
Option("a-z 0-9", alphabets.SMOL),
|
||||||
Option("A-F 1-9", alphabets.HEX),
|
Option("A-F 1-9", alphabets.HEX),
|
||||||
]
|
]
|
||||||
})
|
}) as HTMLSelectElement;
|
||||||
|
|
||||||
this.passwordForm = makeElement({
|
this.passwordForm = makeElement({
|
||||||
tag: "form",
|
tag: "form",
|
||||||
|
@ -104,36 +109,36 @@ export class PwGenPage extends Page {
|
||||||
tag: "button",
|
tag: "button",
|
||||||
text: i18next.t("gen_password_btn"),
|
text: i18next.t("gen_password_btn"),
|
||||||
class: ["uk-button", "uk-button-primary", "uk-margin-bottom"],
|
class: ["uk-button", "uk-button-primary", "uk-margin-bottom"],
|
||||||
attributes: {type: "submit"},
|
attributes: { type: "submit" },
|
||||||
}))
|
}))
|
||||||
]
|
]
|
||||||
});
|
}) as HTMLFormElement;
|
||||||
|
|
||||||
this.passwordForm.addEventListener("submit", (e) => this.formEvent(e));
|
this.passwordForm.addEventListener("submit", (e) => this.formEvent(e));
|
||||||
setPageContent(this.passwordForm);
|
setPageContent(this.passwordForm);
|
||||||
}
|
}
|
||||||
|
|
||||||
getPasswordLengthText() {
|
getPasswordLengthText(): string {
|
||||||
return i18next.t("password_length_title", {
|
return i18next.t("password_length_title", {
|
||||||
min: this?.passwordLengthRange?.value || 24,
|
min: this?.passwordLengthRange?.value || 24,
|
||||||
max: passwordLengthMax
|
max: passwordLengthMax
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
formEvent(e) {
|
formEvent(e: Event): void {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.updatePassword();
|
this.updatePassword();
|
||||||
}
|
}
|
||||||
|
|
||||||
updatePassword() {
|
updatePassword(): void {
|
||||||
this.passwordLengthTitle.innerText = this.getPasswordLengthText();
|
this.passwordLengthTitle.innerText = this.getPasswordLengthText();
|
||||||
this.passwordBox.setText(genPassword({
|
this.passwordBox.setText(genPassword({
|
||||||
length: this.passwordLengthRange.value,
|
length: (this.passwordLengthRange.value as unknown) as number,
|
||||||
alphabet: this.passwordAlphabet.value,
|
alphabet: this.passwordAlphabet.value as string,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup() {
|
cleanup(): void {
|
||||||
this.passwordBox = undefined;
|
this.passwordBox = undefined;
|
||||||
this.passwordLengthTitle = undefined;
|
this.passwordLengthTitle = undefined;
|
||||||
this.passwordLengthRange = undefined;
|
this.passwordLengthRange = undefined;
|
||||||
|
@ -141,7 +146,7 @@ export class PwGenPage extends Page {
|
||||||
this.passwordForm = undefined;
|
this.passwordForm = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
get name() {
|
get name(): string {
|
||||||
return i18next.t("password_generator_title");
|
return i18next.t("password_generator_title");
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -15,8 +15,8 @@ export class Page {
|
||||||
}
|
}
|
||||||
goBack(): void {
|
goBack(): void {
|
||||||
changePage("HOME");
|
changePage("HOME");
|
||||||
}
|
};
|
||||||
cleanup(): void {
|
cleanup(): void {
|
||||||
// Do Nothing
|
// Do Nothing
|
||||||
}
|
};
|
||||||
}
|
}
|
Loading…
Reference in a new issue