1
0
Fork 0

Lint code harder.

This commit is contained in:
Kitteh 2021-05-10 11:35:14 +01:00
parent f4aa14f968
commit a347939896
59 changed files with 345 additions and 341 deletions

View file

@ -1,18 +1,20 @@
{
"extends": [
"eslint:recommended",
"plugin:import/errors",
"plugin:import/warnings",
"plugin:@typescript-eslint/recommended"
],
"plugins": [
"sort-imports-es6-autofix",
"@typescript-eslint"
],
"extends": [
"eslint:recommended",
"plugin:import/errors",
"plugin:import/warnings",
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/recommended-requiring-type-checking"
],
"parserOptions": {
"ecmaVersion": 12,
"sourceType": "module",
"experimentalObjectRestSpread": true
"experimentalObjectRestSpread": true,
"project": "./tsconfig.json"
},
"globals": {
"pageContent": "writable",

View file

@ -71,7 +71,7 @@ export class PageState {
}
get currentSecretPath(): string[] {
return JSON.parse(localStorage.getItem('currentSecretPath') || "[]");
return JSON.parse(localStorage.getItem('currentSecretPath') || "[]") as string[];
}
set currentSecretPath(value: string[]) {
localStorage.setItem('currentSecretPath', JSON.stringify(value));
@ -104,14 +104,14 @@ export class PageState {
}
get currentPage(): Page | string {
const curPage = localStorage.getItem('currentPage') || "HOME";
return (allPages as any)[curPage];
return allPages[curPage];
}
set currentPage(value: Page | string) {
if (typeof value == 'object') {
const key = getKeyByObjectPropertyValue(allPages, value);
localStorage.setItem('currentPage', key);
} else {
localStorage.setItem('currentPage', (value as string));
localStorage.setItem('currentPage', value);
}
}
}

View file

@ -1,6 +1,6 @@
import { pageState } from "../globalPageState";
export function getHeaders(): any {
export function getHeaders(): Record<string, string> {
return {
"X-Vault-Token": pageState.token,
}

View file

@ -8,13 +8,12 @@ export async function usernameLogin(username: string, password: string): Promise
},
body: JSON.stringify({ "username": username, "password": password })
});
return fetch(request).then(response => {
return response.json();
}).then(data => {
if ("auth" in data) {
return data.auth.client_token;
} else if ("errors" in data) {
throw new Error(data.errors[0]);
}
});
const resp = await fetch(request);
const data = await resp.json() as { auth?: { client_token: string }; errors?: string[] };
if ("auth" in data) {
return data.auth.client_token;
} else if ("errors" in data) {
throw new Error(data.errors[0]);
}
}

View file

@ -30,7 +30,7 @@ export async function createOrUpdateSecret(
});
const response = await fetch(request);
if (!response.ok) {
const json = await response.json();
const json = await response.json() as {errors: string[]};
throw new Error(json.errors[0]);
}
}

View file

@ -32,12 +32,12 @@ export async function deleteSecret(
secretURL = removeDoubleSlash(secretURL).replace(/\/$/, "");
request = new Request(appendAPIURL(secretURL), {
method: "DELETE",
headers: (getHeaders() as any),
headers: getHeaders(),
});
}
const response = await fetch(request);
if (!response.ok) {
const json = await response.json();
const json = await response.json() as {errors: string[]};
throw new Error(json.errors[0]);
}
}

View file

@ -6,7 +6,7 @@ export async function getSecret(
secretPath: string[],
name: string,
version: string|null = null
): Promise<Record<any, any>> {
): Promise<Record<string, unknown>> {
let secretURL = "";
if (mountType == "kv-v2") {
secretURL = `/v1/${baseMount}/data/${secretPath.join("")}/${name}`;
@ -16,12 +16,14 @@ export async function getSecret(
secretURL = `/v1/${baseMount}/${secretPath.join("")}/${name}`;
}
const request = new Request(appendAPIURL(secretURL), {
headers: (getHeaders() as any),
headers: getHeaders(),
});
return fetch(request).then(response => {
return response.json();
}).then(data => {
return mountType == "kv-v2" ? data.data.data : data.data;
});
const resp = await fetch(request);
const data = await resp.json() as unknown;
if (mountType == "kv-v2") {
return (data as {data: {data: Record<string, unknown>}}).data.data;
} else {
return (data as {data: Record<string, unknown>}).data;
}
}

View file

@ -1,7 +1,7 @@
import { appendAPIURL, getHeaders } from "../apiUtils";
type SecretMetadataType = {
versions: Record<string, Record<any, any>>
versions: Record<string, unknown>
}
export async function getSecretMetadata(
@ -10,12 +10,10 @@ export async function getSecretMetadata(
name: string
): Promise<SecretMetadataType> {
const request = new Request(appendAPIURL(`/v1/${baseMount}/metadata/${secretPath.join("")}/${name}`), {
headers: (getHeaders() as any),
headers: getHeaders(),
});
return fetch(request).then(response => {
return response.json();
}).then(data => {
return data.data;
});
const resp = await fetch(request);
const data = await resp.json() as {data: SecretMetadataType};
return data.data;
}

View file

@ -2,8 +2,8 @@ import { DoesNotExistError } from "../../types/internalErrors";
import { appendAPIURL, getHeaders } from "../apiUtils";
export async function getSecrets(
baseMount: string,
mountType: string,
baseMount: string,
mountType: string,
secretPath: string[]
): Promise<string[]> {
let secretURL = "";
@ -14,14 +14,12 @@ export async function getSecrets(
secretURL = `/v1/${baseMount}/${secretPath.join("")}?list=true`;
}
const request = new Request(appendAPIURL(secretURL), {
headers: (getHeaders() as any),
});
return fetch(request).then(response => {
if (response.status == 404) {
throw DoesNotExistError;
}
return response.json();
}).then(data => {
return data.data.keys;
headers: getHeaders(),
});
const resp = await fetch(request);
if (resp.status == 404) {
throw DoesNotExistError;
}
const data = await resp.json() as { data: { keys: string[] } };
return data.data.keys;
}

View file

@ -30,7 +30,7 @@ export async function undeleteSecret(
});
const response = await fetch(request);
if (!response.ok) {
const json = await response.json();
const json = await response.json() as {errors: string[]};
throw new Error(json.errors[0]);
}
}

View file

@ -15,11 +15,9 @@ export async function getCapabilitiesPath(path: string): Promise<string[]> {
}
)
});
return fetch(request).then(response => {
return response.json();
}).then(data => {
return data.capabilities;
});
const response = await fetch(request);
const data = await response.json() as {capabilities: string[]};
return data.capabilities;
}
export async function getCapabilities(

View file

@ -1,21 +1,21 @@
import { appendAPIURL, getHeaders } from "../apiUtils";
type MountsType = {
[key: string]: {
export type MountType = {
type: string
options: {
version: string
}
}
}
export type MountsType = {
[key: string]: MountType;
}
export async function getMounts(): Promise<MountsType> {
const request = new Request(appendAPIURL("/v1/sys/internal/ui/mounts"), {
headers: (getHeaders() as any),
});
return fetch(request).then(response => {
return response.json();
}).then(data => {
return data.data.secret;
headers: getHeaders(),
});
const resp = await fetch(request);
const data = await resp.json() as {data: {secret: MountsType}};
return data.data.secret;
}

View file

@ -8,9 +8,7 @@ export type SealStatusType = {
export async function getSealStatus(): Promise<SealStatusType> {
const request = new Request(appendAPIURL("/v1/sys/seal-status"));
return fetch(request).then(response => {
return response.json();
}).then(data => {
return data;
});
const resp = await fetch(request)
const data = await resp.json() as SealStatusType;
return data;
}

View file

@ -1,17 +1,15 @@
import { appendAPIURL, getHeaders } from "../apiUtils";
import { TokenInfo } from "../types/token";
import { appendAPIURL, getHeaders } from "../apiUtils";
export async function lookupSelf(): Promise<TokenInfo> {
const request = new Request(appendAPIURL("/v1/auth/token/lookup-self"), {
headers: getHeaders(),
});
return fetch(request).then(response => {
return response.json();
}).then(data => {
if ("data" in data) {
return data.data;
} else if ("errors" in data) {
throw new Error(data.errors[0]);
}
});
const resp = await fetch(request);
const data = await resp.json() as { data?: TokenInfo; errors?: string[] };
if ("data" in data) {
return data.data;
} else if ("errors" in data) {
throw new Error(data.errors[0]);
}
}

View file

@ -9,11 +9,9 @@ export async function renewSelf(): Promise<void> {
},
body: JSON.stringify({})
});
return fetch(request).then(response => {
return response.json();
}).then(data => {
if ("errors" in data) {
throw new Error(data.errors[0]);
}
});
const resp = await fetch(request)
const data = await resp.json() as { errors?: string[] };
if ("errors" in data) {
throw new Error(data.errors[0]);
}
}

View file

@ -6,11 +6,9 @@ export async function sealVault(): Promise<void> {
method: 'PUT',
headers: getHeaders(),
});
return fetch(request).then(response => {
return response.json();
}).then(data => {
if ("errors" in data) {
throw new Error(data.errors[0]);
}
});
const resp = await fetch(request)
const data = await resp.json() as { errors?: string[] };
if ("errors" in data) {
throw new Error(data.errors[0]);
}
}

View file

@ -10,9 +10,11 @@ export async function submitUnsealKey(key: string): Promise<void> {
"key": key
})
});
const response = await fetch(request);
if (!response.ok) {
const json = await response.json();
throw new Error(json.errors[0]);
const resp = await fetch(request)
if (!resp.ok) {
const data = await resp.json() as { errors?: string[] };
if ("errors" in data) {
throw new Error(data.errors[0]);
}
}
}

View file

@ -1,7 +1,6 @@
import { appendAPIURL, getHeaders } from "../apiUtils";
import { removeDoubleSlash } from "../../utils";
export async function addNewTOTP(baseMount: string, parms: {name: string}): Promise<void> {
const request = new Request(appendAPIURL(removeDoubleSlash(`/v1/${baseMount}/keys/${parms.name}`)), {
method: 'POST',
@ -11,9 +10,11 @@ export async function addNewTOTP(baseMount: string, parms: {name: string}): Prom
},
body: JSON.stringify(parms)
});
const response = await fetch(request);
if (!response.ok) {
const json = await response.json();
throw new Error(json.errors[0]);
const resp = await fetch(request)
if (!resp.ok) {
const data = await resp.json() as { errors?: string[] };
if ("errors" in data) {
throw new Error(data.errors[0]);
}
}
}

View file

@ -5,9 +5,7 @@ export async function getTOTPCode(baseMount: string, name: string): Promise<stri
new Request(appendAPIURL(`/v1/${baseMount}/code/${name}`), {
headers: getHeaders(),
});
return fetch(request).then(response => {
return response.json();
}).then(data => {
return data.data.code;
});
const resp = await fetch(request)
const data = await resp.json() as {data: {code: string}};
return data.data.code;
}

View file

@ -1,17 +1,15 @@
import { DoesNotExistError } from "../../types/internalErrors";
import { appendAPIURL, getHeaders } from "../apiUtils";
export async function getTOTPKeys(baseMount: string): Promise<string[]> {
const request = new Request(appendAPIURL(`/v1/${baseMount}/keys?list=true`), {
headers: getHeaders(),
});
return fetch(request).then(response => {
if (response.status == 404) {
throw DoesNotExistError;
}
return response.json();
}).then(data => {
return data.data.keys;
});
const resp = await fetch(request);
if (resp.status == 404) {
throw DoesNotExistError;
}
const data = await resp.json() as {data: {keys: string[] }};
return data.data.keys;
}

View file

@ -1,17 +1,16 @@
import { DoesNotExistError } from "../../types/internalErrors";
import { appendAPIURL, getHeaders } from "../apiUtils";
import { TransitKeyType } from "../types/transit";
import { appendAPIURL, getHeaders } from "../apiUtils";
export async function getTransitKey(baseMount: string, name: string): Promise<TransitKeyType> {
const request = new Request(appendAPIURL(`/v1/${baseMount}/keys/${name}`), {
headers: getHeaders(),
});
return fetch(request).then(response => {
if (response.status == 404) {
throw DoesNotExistError;
}
return response.json();
}).then(data => {
return data.data;
});
const resp = await fetch(request);
if (resp.status == 404) {
throw DoesNotExistError;
}
const data = await resp.json() as { data: TransitKeyType };
return data.data;
}

View file

@ -5,12 +5,10 @@ export async function getTransitKeys(baseMount: string): Promise<string[]> {
const request = new Request(appendAPIURL(`/v1/${baseMount}/keys?list=true`), {
headers: getHeaders(),
});
return fetch(request).then(response => {
if (response.status == 404) {
throw DoesNotExistError;
}
return response.json();
}).then(data => {
return data.data.keys;
});
const resp = await fetch(request);
if (resp.status == 404) {
throw DoesNotExistError;
}
const data = await resp.json() as { data: string[] };
return data.data;
}

View file

@ -22,12 +22,12 @@ export async function transitDecrypt(
},
body: JSON.stringify(payload)
});
const response = await fetch(request);
const data = await response.json() as { errors?: string[]; data?: DecryptionResult; };
if (!response.ok) {
const json = await response.json();
throw new Error(json.errors[0]);
throw new Error(data.errors[0]);
} else {
const json = await response.json();
return json.data;
return data.data;
}
}

View file

@ -22,12 +22,12 @@ export async function transitEncrypt(
},
body: JSON.stringify(payload)
});
const response = await fetch(request);
const data = await response.json() as { errors?: string[]; data?: EncryptionResult; };
if (!response.ok) {
const json = await response.json();
throw new Error(json.errors[0]);
throw new Error(data.errors[0]);
} else {
const json = await response.json();
return json.data;
return data.data;
}
}

View file

@ -23,12 +23,12 @@ export async function transitRewrap(
},
body: JSON.stringify(payload)
});
const response = await fetch(request);
const data = await response.json() as { errors?: string[]; data?: RewrapResult; };
if (!response.ok) {
const json = await response.json();
throw new Error(json.errors[0]);
throw new Error(data.errors[0]);
} else {
const json = await response.json();
return json.data;
return data.data;
}
}

View file

@ -9,11 +9,11 @@ export type TokenInfo = {
id: string;
identity_policies: string[];
issue_time: string;
meta: any;
meta: Record<string, string>;
num_uses: number;
orphan: Boolean;
orphan: boolean;
path: string;
policies: string[];
renewable: Boolean;
renewable: boolean;
ttl: number;
}

View file

@ -14,10 +14,10 @@ export const enum TransitKeyTypes {
// Type when used to make new transit keys.
export type TransitKeyBaseType = {
name: string;
convergent_encryption: Boolean;
derived: Boolean;
exportable: Boolean;
allow_plaintext_backup: Boolean;
convergent_encryption: boolean;
derived: boolean;
exportable: boolean;
allow_plaintext_backup: boolean;
type: keyof typeof TransitKeyTypes;
}
@ -28,8 +28,8 @@ export type TransitKeyType = TransitKeyBaseType & {
};
min_decryption_version: number;
min_encryption_version: number;
supports_encryption: Boolean;
supports_decryption: Boolean;
supports_derivation: Boolean;
supports_signing: Boolean;
supports_encryption: boolean;
supports_decryption: boolean;
supports_derivation: boolean;
supports_signing: boolean;
}

View file

@ -10,7 +10,7 @@ export interface CopyableInputBoxType extends HTMLElement {
export function CopyableInputBox(text: string, copyable = true): CopyableInputBoxType {
const inputBoxDiv = (makeElement({ tag: "div" }) as CopyableInputBoxType);
let inputBoxCopyButton = null;
let inputBoxCopyButton: HTMLElement = null;
if (copyable) {
inputBoxCopyButton = makeElement({
tag: "a",
@ -30,8 +30,8 @@ export function CopyableInputBox(text: string, copyable = true): CopyableInputBo
const inputBoxInput = makeElement({
tag: "input",
class: ["uk-input", "uk-input-copyable"],
attributes: { "readonly": true, "type": "text" },
});
attributes: { "readonly": "true", "type": "text" },
}) as HTMLInputElement;
const inputBoxInner = MarginInline([
inputBoxCopyButton,
@ -40,7 +40,7 @@ export function CopyableInputBox(text: string, copyable = true): CopyableInputBo
inputBoxDiv.appendChild(inputBoxInner);
inputBoxDiv.setText = function (text) {
(inputBoxInput as HTMLInputElement).value = `${text}`;
inputBoxInput.value = `${text}`;
if (copyable) {
inputBoxCopyButton.dataset.clipboardText = `${text}`;
}

View file

@ -2,10 +2,19 @@ import { addClipboardNotifications } from "../pageUtils";
import { makeElement } from "../htmlUtils";
import ClipboardJS from "clipboard";
import FileSaver from 'file-saver';
import UIkit from 'uikit/dist/js/uikit.min.js';
import i18next from 'i18next';
export function CopyableModal(name: string, contentString: string): Element {
return makeElement({
type FileSaverType = {
saveAs: (blob: Blob, name: string) => void;
}
type ModalType = HTMLElement & {
show: () => void;
}
export function CopyableModal(name: string, contentString: string): ModalType {
const modal = makeElement({
tag: "div",
class: "modal-sections",
attributes: {
@ -53,9 +62,9 @@ export function CopyableModal(name: string, contentString: string): Element {
"data-clipboard-text": contentString
},
text: i18next.t("copy_modal_download_btn"),
onclick: _ => {
const blob = new Blob([contentString], {type: "text/plain;charset=utf-8"});
FileSaver.saveAs(blob, "result.txt");
onclick: () => {
const blob = new Blob([contentString], { type: "text/plain;charset=utf-8" });
(FileSaver as FileSaverType).saveAs(blob, "result.txt");
}
}),
makeElement({
@ -82,5 +91,9 @@ export function CopyableModal(name: string, contentString: string): Element {
}),
]
})
});
}) as ModalType;
modal.show = () => {
(UIkit as { modal: (ModalType) => { show: () => void } }).modal(modal).show();
}
return modal;
}

View file

@ -35,7 +35,7 @@ export async function QRScanner(onScan: (code: string) => void): Promise<QRScann
if (lastSeenValue == value) return;
onScan(value);
});
qrScanner.start();
void qrScanner.start();
QRInput.deinit = () => {
try {

View file

@ -1,7 +1,7 @@
import { makeElement } from "../htmlUtils";
type TileParams = {
condition: Boolean;
condition: boolean;
title: string;
description: string;
icon: string;

View file

@ -1,19 +0,0 @@
import { appendAPIURL, getHeaders } from "../api/apiUtils";
export async function renewSelf(): Promise<void> {
const request = new Request(appendAPIURL("/v1/auth/token/renew-self"), {
method: 'POST',
headers: {
...getHeaders(),
'Content-Type': 'application/json'
},
body: JSON.stringify({})
});
return fetch(request).then(response => {
return response.json();
}).then(data => {
if ("errors" in data) {
throw new Error(data.errors[0]);
}
});
}

View file

@ -2,7 +2,7 @@ import { de, enGB, fr, it, nl, ru } from 'date-fns/locale'
import { formatDistance as formatDistanceReal} from 'date-fns';
import { pageState } from "./globalPageState";
function getLocale(): any {
function getLocale(): Locale {
return {
"en": enGB,
"fr": fr,

View file

@ -1,7 +1,7 @@
import { getObjectKeys } from "./utils";
type optionsFunctionsObject = {
[key: string]: (e: any, arg: any) => void
[key: string]: (e: Element, arg: unknown) => void
}
const optionsFunctions: optionsFunctionsObject = {
@ -13,9 +13,9 @@ const optionsFunctions: optionsFunctionsObject = {
},
"id": (e: Element, arg: string) => e.id = arg,
"html": (e: Element, arg: string) => e.innerHTML = arg,
"onclick": (e: HTMLButtonElement, arg: any) => e.onclick = arg,
"onclick": (e: Element, arg: () => void) => (e as HTMLButtonElement).onclick = arg,
"attributes": setElementAttributes,
"text": (e: HTMLParagraphElement, arg: string) => e.innerText = arg,
"text": (e: Element, arg: string) => (e as HTMLParagraphElement).innerText = arg,
"children": (e: Element, arg: Element | Element[]) => {
if (Array.isArray(arg)) {
arg.forEach(child => {
@ -34,13 +34,12 @@ interface ElementInfo {
class?: string | string[];
id?: string;
html?: string;
attributes?: {
[propName: string]: any
};
attributes?: Record<string, string>;
children?: Element | Element[];
text?: string;
thenRun?: (e: Element) => void;
[propName: string]: any;
onclick?: () => void;
[propName: string]: unknown;
}
export function makeElement(elementInfo: ElementInfo): HTMLElement {
@ -49,14 +48,14 @@ export function makeElement(elementInfo: ElementInfo): HTMLElement {
for (const key of Object.getOwnPropertyNames(elementInfo)) {
if (getObjectKeys(optionsFunctions).includes(key)) {
(optionsFunctions as any)[key](element, elementInfo[key]);
optionsFunctions[key](element, elementInfo[key]);
}
}
return element;
}
export function setElementAttributes(element: Element, attributes: { [propName: string]: any }): void {
export function setElementAttributes(element: Element, attributes: Record<string, string>): void {
for (const key of Object.getOwnPropertyNames(attributes)) {
element.setAttribute(key, attributes[key]);
}

View file

@ -2,14 +2,16 @@
// JS & CSS
/* eslint-disable */
import "./scss/main.scss";
import Icons from 'uikit/dist/js/uikit-icons.min.js';
import UIkit from 'uikit/dist/js/uikit.min.js';
// @ts-ignore
UIkit.use(Icons);
/* eslint-disable */
import Prism from "prismjs";
import "prismjs/components/prism-json";
// @ts-ignore
Prism.highlightAll();
/* eslint-enable */
@ -29,14 +31,19 @@ import i18next from 'i18next';
// @ts-ignore
import translations from './translations/index.mjs'
function ListItem(children) {
function ListItem(children: Element[] | Element): HTMLElement {
return makeElement({
tag: "li",
children: children
});
}
async function onLoad() {
declare global {
interface Window { pageContent: Element; }
}
function onLoad(): void {
document.body.innerHTML = "";
document.body.appendChild(makeElement({
tag: "nav",
@ -52,17 +59,17 @@ async function onLoad() {
ListItem(makeElement({
tag: "a",
text: i18next.t("home_btn"),
onclick: _ => { changePage("HOME"); }
onclick: () => { changePage("HOME"); }
})),
ListItem(makeElement({
tag: "a",
text: i18next.t("back_btn"),
onclick: _ => { (pageState.currentPage as Page).goBack(); }
onclick: () => { (pageState.currentPage as Page).goBack(); }
})),
ListItem(makeElement({
tag: "a",
text: i18next.t("refresh_btn"),
onclick: _ => { changePage(pageState.currentPageString); }
onclick: () => { changePage(pageState.currentPageString); }
})),
]
})
@ -77,7 +84,7 @@ async function onLoad() {
ListItem(makeElement({
tag: "a",
text: i18next.t("me_btn"),
onclick: _ => { changePage("ME"); }
onclick: () => { changePage("ME"); }
}))
]
})
@ -105,43 +112,44 @@ async function onLoad() {
})
}));
(window as any).pageContent = document.querySelector("#pageContent");
window.pageContent = document.querySelector("#pageContent");
if (process.env.NODE_ENV == "development") {
await playground();
playground();
}
renderPage();
setInterval(async () => {
setInterval(() => {
if (pageState.currentPageString != "UNSEAL") {
if (pageState.apiURL.length != 0) { return; }
const sealStatus = await getSealStatus();
if (sealStatus.sealed) {
changePage("UNSEAL");
return;
}
void getSealStatus().then((sealStatus) => {
if (sealStatus.sealed) {
changePage("UNSEAL");
return;
}
});
}
}, 5000);
}
document.addEventListener('DOMContentLoaded', async function () {
document.addEventListener('DOMContentLoaded', function () {
console.log("Loading...");
// @ts-expect-error
console.log("Build Data:", BUILD_STRING);
i18next.init({
void i18next.init({
lng: pageState.language,
fallbackLng: 'en',
debug: true,
// @ts-ignore
resources: Object.fromEntries(Object.entries(translations).map(([k, v]) => [k, { translation: v }])),
interpolation: {
format: function (value, format, _) {
format: function (value: unknown, format, _): string {
if (format === 'until_date' && value instanceof Date) return formatDistance(new Date(), new Date(value));
return value;
return value as string;
}
}
}).then(async function (_) {
await onLoad();
}).then(function (_) {
onLoad();
});
}, false);

View file

@ -46,13 +46,13 @@ export async function prePageChecks(): Promise<boolean> {
export function addClipboardNotifications(clipboard: ClipboardJS, timeout = 1000): void {
clipboard.on('success', () => {
(UIkit as any).notification(i18next.t("notification_copy_success"), {
(UIkit as {notification: (title: unknown, options: unknown) => void}).notification(i18next.t("notification_copy_success"), {
status: 'success',
timeout: timeout
});
});
clipboard.on('error', function (e: Error) {
(UIkit as any).notification(i18next.t("notification_copy_error", {
(UIkit as {notification: (title: unknown, options: unknown) => void}).notification(i18next.t("notification_copy_error", {
"error": e.message
}), {
status: 'danger',
@ -64,9 +64,9 @@ export function addClipboardNotifications(clipboard: ClipboardJS, timeout = 1000
export function setErrorText(text: string): void {
const errorTextElement = document.querySelector("#errorText");
if (errorTextElement) {
(document.querySelector("#errorText") as HTMLElement).innerText = `Error: ${text}`;
(document.querySelector("#errorText") as HTMLParagraphElement).innerText = `Error: ${text}`;
}
(UIkit as any).notification({
(UIkit as {notification: (options: unknown) => void}).notification({
message: `Error: ${text}`,
status: 'danger',
pos: 'top-center',
@ -87,13 +87,13 @@ export function changePage(page: string, shouldSwitch = true): void {
export function renderPage(): void {
document.documentElement.dir = pageState.pageDirection;
console.log("Rendering Page: ", (pageState.currentPage as Page).name);
(document.querySelector("#pageContent") as HTMLElement).innerHTML = "";
(document.querySelector("#pageContent") ).innerHTML = "";
setPageTitle((pageState.currentPage as Page).name);
(pageState.currentPage as Page).render();
}
export function setPageTitle(title: string | HTMLElement): void {
const pageTitle = (document.getElementById("pageTitle") as HTMLElement);
const pageTitle = (document.getElementById("pageTitle") );
pageTitle.innerHTML = "";
if (typeof title === "string") {
pageTitle.innerText = title.toString();
@ -154,7 +154,7 @@ export function setTitleElement(pageState: PageState): void {
}
export function setPageContent(content: string | HTMLElement): void {
const pageContent = (document.getElementById("pageContent") as HTMLElement);
const pageContent = (document.getElementById("pageContent") );
if (typeof content === "string") {
pageContent.innerHTML = content;
} else {

View file

@ -1,6 +1,6 @@
import { MountType, getMounts } from "../api/sys/getMounts";
import { Page } from "../types/Page";
import { changePage, prePageChecks, setErrorText, setPageContent } from "../pageUtils";
import { getMounts } from "../api/sys/getMounts";
import { lookupSelf } from "../api/sys/lookupSelf";
import { makeElement } from "../htmlUtils";
import { pageState } from "../globalPageState";
@ -48,9 +48,10 @@ export class HomePage extends Page {
tag: "li",
text: i18next.t("your_token_expires_in", {"date": new Date(selfTokenInfo.expire_time)})
}));
} catch (e) {
setErrorText(e.message);
if (e.message == "permission denied") {
} catch (e: unknown) {
const error = e as Error;
setErrorText(error.message);
if (error.message == "permission denied") {
pageState.token = "";
changePage("LOGIN");
}
@ -68,7 +69,7 @@ export class HomePage extends Page {
// sort it by secretPath so it's in alphabetical order consistantly.
const mountsMap = sortedObjectMap(mounts);
mountsMap.forEach(function (mount, baseMount) {
mountsMap.forEach(function (mount: MountType, baseMount) {
if (typeof mount != 'object') return;
if (mount == null) return;
if (!("type" in mount)) return;
@ -97,7 +98,7 @@ export class HomePage extends Page {
children: makeElement({
tag: "a",
text: linkText,
onclick: _ => {
onclick: () => {
pageState.currentBaseMount = baseMount;
pageState.currentMountType = mountType;
changePage(linkPage);

View file

@ -31,8 +31,8 @@ export class KeyValueDeletePage extends Page {
tag: "button",
class: ["uk-button", "uk-button-danger"],
text: i18next.t("kv_delete_btn"),
onclick: _ => {
deleteSecret(
onclick: () => {
void deleteSecret(
pageState.currentBaseMount,
pageState.currentMountType,
pageState.currentSecretPath,

View file

@ -29,7 +29,7 @@ export class KeyValueNewPage extends Page {
tag: "input",
class: ["uk-input", "uk-form-width-medium"],
attributes: {
required: true,
required: "true",
type: "text",
placeholder: i18next.t("kv_new_path"),
name: "path"
@ -53,9 +53,9 @@ export class KeyValueNewPage extends Page {
}) as HTMLFormElement;
setPageContent(this.addKVNewForm);
this.addKVNewForm.addEventListener("submit", function (e) {
this.addKVNewForm.addEventListener("submit", function (e: Event) {
e.preventDefault();
this.newKVSecretHandleForm();
(this as KeyValueNewPage).newKVSecretHandleForm();
}.bind(this));
}
@ -77,7 +77,7 @@ export class KeyValueNewPage extends Page {
).then(_ => {
changePage("KEY_VALUE_VIEW");
return;
}).catch(e => {
}).catch((e: Error) => {
setErrorText(e.message);
});
}

View file

@ -66,7 +66,7 @@ export class KeyValueSecretPage extends Page {
tag: "button",
id: "deleteButton",
class: ["uk-button", "uk-button-danger"],
onclick: _ => { changePage("KEY_VALUE_DELETE"); },
onclick: () => { changePage("KEY_VALUE_DELETE"); },
text: deleteButtonText
}));
}
@ -76,7 +76,7 @@ export class KeyValueSecretPage extends Page {
tag: "button",
id: "editButton",
class: ["uk-button", "uk-margin", "uk-button-primary"],
onclick: _ => { changePage("KEY_VALUE_SECRET_EDIT"); },
onclick: () => { changePage("KEY_VALUE_SECRET_EDIT"); },
text: i18next.t("kv_secret_edit_btn")
}));
}
@ -86,12 +86,12 @@ export class KeyValueSecretPage extends Page {
tag: "button",
id: "versionsButton",
class: ["uk-button", "uk-button-secondary"],
onclick: _ => { changePage("KEY_VALUE_VERSIONS"); },
onclick: () => { changePage("KEY_VALUE_VERSIONS"); },
text: i18next.t("kv_secret_versions_btn")
}));
}
getSecret(
void getSecret(
pageState.currentBaseMount,
pageState.currentMountType,
pageState.currentSecretPath,
@ -113,7 +113,7 @@ export class KeyValueSecretPage extends Page {
id: "restoreButton",
class: ["uk-button", "uk-button-primary"],
onclick: () => {
undeleteSecret(
void undeleteSecret(
pageState.currentBaseMount,
pageState.currentSecretPath,
pageState.currentSecret,
@ -133,14 +133,18 @@ export class KeyValueSecretPage extends Page {
}
if (isSecretNestedJson) {
const jsonText = JSON.stringify(sortedObjectMap(secretsMap as Record<any, any>), null, 4);
const jsonText = JSON.stringify(
sortedObjectMap(secretsMap as unknown as Record<string, unknown>),
null,
4
);
kvList.appendChild(makeElement({
tag: "pre",
class: ["code-block", "language-json", "line-numbers"],
html: Prism.highlight(jsonText, Prism.languages.json, 'json')
html: (Prism as { highlight: (text: string, language: null, languageStr: string) => string }).highlight(jsonText, null, 'json')
}));
} else {
secretsMap.forEach((value, key) => {
secretsMap.forEach((value: string, key: string) => {
const kvListElement = this.makeKVListElement(key, value);
kvList.appendChild(kvListElement);
}, this);

View file

@ -43,7 +43,7 @@ export class KeyValueSecretEditPage extends Page {
saveButton
]
}));
getSecret(
void getSecret(
pageState.currentBaseMount,
pageState.currentMountType,
pageState.currentSecretPath,
@ -70,7 +70,7 @@ export class KeyValueSecretEditPage extends Page {
).then(_ => {
changePage("KEY_VALUE_SECRET");
return;
}).catch(e => {
}).catch((e: Error) => {
setErrorText(e.message);
});
};

View file

@ -39,7 +39,7 @@ export class KeyValueVersionsPage extends Page {
children: makeElement({
tag: "a",
text: `v${ver}`,
onclick: _ => {
onclick: () => {
pageState.currentSecretVersion = ver;
changePage("KEY_VALUE_SECRET");
}

View file

@ -61,7 +61,7 @@ export class KeyValueViewPage extends Page {
children: makeElement({
tag: "a",
text: secret,
onclick: _ => {
onclick: () => {
if (secret.endsWith("/")) {
pageState.pushCurrentSecretPath(secret);
changePage("KEY_VALUE_VIEW");
@ -75,8 +75,9 @@ export class KeyValueViewPage extends Page {
})
]
}));
} catch (e) {
if (e == DoesNotExistError) {
} catch (e: unknown) {
const error = e as Error;
if (error == DoesNotExistError) {
// getSecrets also 404's on no keys so dont go all the way back.
if (pageState.currentSecretPath.length != 0) {
return this.goBack();
@ -87,7 +88,7 @@ export class KeyValueViewPage extends Page {
}));
}
} else {
setErrorText(e.message);
setErrorText(error.message);
}
}
}

View file

@ -20,7 +20,7 @@ export class LoginPage extends Page {
tag: "input",
class: ["uk-input", "uk-form-width-medium"],
attributes: {
required: true,
required: "true",
type: "password",
placeholder: i18next.t("token_input"),
name: "token"
@ -45,7 +45,7 @@ export class LoginPage extends Page {
id: "usernameInput",
class: ["uk-input", "uk-form-width-medium"],
attributes: {
required: true,
required: "true",
type: "text",
placeholder: i18next.t("username_input"),
name: "username"
@ -56,7 +56,7 @@ export class LoginPage extends Page {
id: "passwordInput",
class: ["uk-input", "uk-form-width-medium"],
attributes: {
required: true,
required: "true",
type: "password",
placeholder: i18next.t("password_input"),
name: "password"
@ -127,7 +127,7 @@ export class LoginPage extends Page {
pageState.token = token as string;
lookupSelf().then(_ => {
changePage("HOME");
}).catch(e => {
}).catch((e: Error) => {
document.getElementById("tokenInput").classList.add("uk-form-danger");
if (e.message == "permission denied") {
setErrorText(i18next.t("token_login_error"));
@ -145,7 +145,7 @@ export class LoginPage extends Page {
).then(res => {
pageState.token = res;
changePage("HOME");
}).catch(e => {
}).catch((e: Error) => {
document.getElementById("usernameInput").classList.add("uk-form-danger");
document.getElementById("passwordInput").classList.add("uk-form-danger");
setErrorText(e.message);

View file

@ -53,7 +53,7 @@ export class MePage extends Page {
onclick: () => {
renewSelf().then(() => {
changePage("HOME");
}).catch(e => {
}).catch((e: Error) => {
setErrorText(e.message);
});
}

View file

@ -1,10 +1,10 @@
import { CopyableInputBox, CopyableInputBoxType } from "../elements/CopyableInputBox";
import { Margin } from "../elements/Margin";
import { Option } from "../elements/Option";
import { Page } from "../types/Page";
import { makeElement } from "../htmlUtils";
import { setPageContent } from "../pageUtils";
import i18next from 'i18next';
import { Option } from "../elements/Option";
const passwordLengthMin = 1;
const passwordLengthMax = 64;
@ -55,7 +55,7 @@ export class PwGenPage extends Page {
passwordAlphabet: HTMLSelectElement;
passwordForm: HTMLFormElement;
async render(): Promise<void> {
render(): void {
setPageContent("");
this.passwordBox = CopyableInputBox(genPassword(passwordOptionsDefault)) ;
@ -70,9 +70,9 @@ export class PwGenPage extends Page {
class: ["uk-range", "uk-width-1-2"],
attributes: {
type: "range",
value: passwordLengthDefault,
max: passwordLengthMax,
min: passwordLengthMin,
value: passwordLengthDefault.toString(),
max: passwordLengthMax.toString(),
min: passwordLengthMin.toString(),
},
}) as HTMLInputElement;
@ -124,7 +124,7 @@ export class PwGenPage extends Page {
this.passwordLengthTitle.innerText = this.getPasswordLengthText();
this.passwordBox.setText(genPassword({
length: (this.passwordLengthRange.value as unknown) as number,
alphabet: this.passwordAlphabet.value as string,
alphabet: this.passwordAlphabet.value ,
}));
}

View file

@ -55,7 +55,7 @@ export class SetLanguagePage extends Page {
const language = formData.get("language") as string;
pageState.language = language;
console.log(pageState.language);
i18next.changeLanguage(language).then((t) => {
void i18next.changeLanguage(language).then((t) => {
changePage("HOME", false);
pageState.pageDirection = t("language_direction");
location.reload();

View file

@ -19,7 +19,7 @@ export class SetVaultURLPage extends Page {
tag: "input",
class: ["uk-input", "uk-form-width-medium"],
attributes: {
required: true,
required: "true",
type: "text",
placeholder: "Vault URL",
name: "vaultURL"

View file

@ -33,7 +33,7 @@ export class NewTOTPPage extends Page {
tag: "input",
class: ["uk-input", "uk-form-width-medium"],
attributes: {
required: true,
required: "true",
type: "text",
placeholder: i18next.t("totp_new_name_text"),
name: "name"
@ -89,7 +89,7 @@ export class NewTOTPPage extends Page {
};
addNewTOTP(pageState.currentBaseMount, parms).then(_ => {
changePage("TOTP");
}).catch(e => {
}).catch((e: Error) => {
setErrorText(`API Error: ${e.message}`);
});
});

View file

@ -24,7 +24,7 @@ export class TOTPViewPage extends Page {
refresher: number;
totpListElements: Record<string, TOTPListElement>;
async render(): Promise<void> {
render(): void {
setTitleElement(pageState);
const totpList = makeElement({ tag: "div" });
setPageContent(makeElement({
@ -33,7 +33,7 @@ export class TOTPViewPage extends Page {
makeElement({
tag: "a",
text: i18next.t("totp_view_new_btn"),
onclick: _ => { changePage("NEW_TOTP"); }
onclick: () => { changePage("NEW_TOTP"); }
}),
makeElement({
tag: "p",
@ -48,14 +48,14 @@ export class TOTPViewPage extends Page {
getTOTPKeys(pageState.currentBaseMount).then(res => {
res.forEach(async function (totpKeyName) {
const totpListElement = this.makeTOTPListElement(totpKeyName);
res.forEach(function (totpKeyName) {
const totpListElement = (this as TOTPViewPage).makeTOTPListElement(totpKeyName);
totpList.appendChild(totpListElement);
this.totpListElements[totpKeyName] = totpListElement;
await this.updateTOTPElement(totpKeyName, totpListElement);
(this as TOTPViewPage).totpListElements[totpKeyName] = totpListElement;
void (this as TOTPViewPage).updateTOTPElement(totpKeyName, totpListElement);
}, this);
document.getElementById("loadingText").remove();
}).catch(e => {
}).catch((e: Error) => {
if (e == DoesNotExistError) {
const loadingText = document.getElementById("loadingText");
loadingText.innerText = i18next.t("totp_view_empty");
@ -64,12 +64,12 @@ export class TOTPViewPage extends Page {
}
});
const totpRefresher = async () => {
await Promise.all(Array.from(objectToMap(this.totpListElements)).map((kv) => {
const totpRefresher = () => {
void Promise.all(Array.from(objectToMap(this.totpListElements)).map((kv: [string, TOTPListElement]) => {
return this.updateTOTPElement(...kv);
}))
}
await totpRefresher();
void totpRefresher();
this.refresher = setInterval(totpRefresher, 3000) as unknown as number;
}
@ -92,7 +92,7 @@ export class TOTPViewPage extends Page {
children: [totpKeyBox, totpValueBox]
}) as TOTPListElement;
gridElement.setCode = totpValueBox.setText;
gridElement.setCode = (code: string) => totpValueBox.setText(code);
return gridElement;
}

View file

@ -6,7 +6,6 @@ import { changePage, setErrorText, setPageContent, setTitleElement } from "../..
import { fileToBase64, makeElement } from "../../htmlUtils";
import { pageState } from "../../globalPageState";
import { transitDecrypt } from "../../api/transit/transitDecrypt";
import UIkit from 'uikit/dist/js/uikit.min.js';
import i18next from "i18next";
export class TransitDecryptPage extends Page {
@ -20,7 +19,7 @@ export class TransitDecryptPage extends Page {
transitDecryptForm: HTMLFormElement;
async render(): Promise<void> {
render(): void {
setTitleElement(pageState);
setPageContent(makeElement({
tag: "div"
@ -74,7 +73,7 @@ export class TransitDecryptPage extends Page {
setPageContent(this.transitDecryptForm);
this.transitDecryptForm.addEventListener("submit", async function (e: Event) {
e.preventDefault();
await this.transitDecryptFormHandler();
await (this as TransitDecryptPage).transitDecryptFormHandler();
}.bind(this));
}
@ -87,11 +86,11 @@ export class TransitDecryptPage extends Page {
const ciphertext_file = formData.get("ciphertext_file") as File;
if (ciphertext_file.size > 0) {
ciphertext = atob((await fileToBase64(ciphertext_file) as string).replace("data:text/plain;base64,", ""));
ciphertext = atob((await fileToBase64(ciphertext_file) ).replace("data:text/plain;base64,", ""));
}
try {
let res = await transitDecrypt(
const res = await transitDecrypt(
pageState.currentBaseMount,
pageState.currentSecret,
{ ciphertext: ciphertext },
@ -102,9 +101,10 @@ export class TransitDecryptPage extends Page {
}
const modal = CopyableModal(i18next.t("transit_decrypt_decryption_result_modal_title"), plaintext);
document.body.querySelector("#pageContent").appendChild(modal);
UIkit.modal(modal).show();
} catch (e) {
setErrorText(`API Error: ${e.message}`);
modal.show();
} catch (e: unknown) {
const error = e as Error;
setErrorText(`API Error: ${error.message}`);
}
}

View file

@ -6,7 +6,6 @@ import { changePage, setErrorText, setPageContent, setTitleElement } from "../..
import { fileToBase64, makeElement } from "../../htmlUtils";
import { pageState } from "../../globalPageState";
import { transitEncrypt } from "../../api/transit/transitEncrypt";
import UIkit from 'uikit/dist/js/uikit.min.js';
import i18next from "i18next";
@ -22,7 +21,7 @@ export class TransitEncryptPage extends Page {
transitEncryptForm: HTMLFormElement;
async render(): Promise<void> {
render(): void {
setTitleElement(pageState);
setPageContent(makeElement({
tag: "div"
@ -75,9 +74,9 @@ export class TransitEncryptPage extends Page {
}) as HTMLFormElement;
setPageContent(this.transitEncryptForm);
this.transitEncryptForm.addEventListener("submit", async function (e) {
this.transitEncryptForm.addEventListener("submit", async function (e: Event) {
e.preventDefault();
await this.transitEncryptFormHandler();
await (this as TransitEncryptPage).transitEncryptFormHandler();
}.bind(this));
}
@ -90,23 +89,24 @@ export class TransitEncryptPage extends Page {
const plaintext_file = formData.get("plaintext_file") as File;
if (plaintext_file.size > 0) {
plaintext = (await fileToBase64(plaintext_file) as string).replace("data:text/plain;base64,", "");
plaintext = (await fileToBase64(plaintext_file) ).replace("data:text/plain;base64,", "");
plaintext = base64Checkbox == "on" ? atob(plaintext) : plaintext;
} else {
plaintext = base64Checkbox == "on" ? plaintext : btoa(plaintext);
}
try {
let res = await transitEncrypt(
const res = await transitEncrypt(
pageState.currentBaseMount,
pageState.currentSecret,
{ plaintext: plaintext }
);
const modal = CopyableModal(i18next.t("transit_encrypt_encryption_result_modal_title"), res.ciphertext);
document.body.querySelector("#pageContent").appendChild(modal);
UIkit.modal(modal).show();
} catch (e) {
setErrorText(`API Error: ${e.message}`);
modal.show();
} catch (e: unknown) {
const error = e as Error;
setErrorText(`API Error: ${error.message}`);
}
}

View file

@ -1,16 +1,14 @@
import { CopyableModal } from "../../elements/CopyableModal";
import { FileUploadInput } from "../../elements/FileUploadInput";
import { Margin } from "../../elements/Margin";
import { Option } from "../../elements/Option";
import { Page } from "../../types/Page";
import { changePage, setErrorText, setPageContent, setTitleElement } from "../../pageUtils";
import { makeElement } from "../../htmlUtils";
import { pageState } from "../../globalPageState";
import UIkit from 'uikit/dist/js/uikit.min.js';
import i18next from "i18next";
import { getTransitKey } from "../../api/transit/getTransitKey";
import { makeElement } from "../../htmlUtils";
import { objectToMap } from "../../utils";
import { Option } from "../../elements/Option";
import { pageState } from "../../globalPageState";
import { transitRewrap } from "../../api/transit/transitRewrap";
import i18next from "i18next";
type versionOption = { version: string; label: string }
@ -27,17 +25,17 @@ export class TransitRewrapPage extends Page {
async render(): Promise<void> {
setTitleElement(pageState);
let transitKey = await getTransitKey(pageState.currentBaseMount, pageState.currentSecret);
const transitKey = await getTransitKey(pageState.currentBaseMount, pageState.currentSecret);
let stringVersions = Array.from(objectToMap(transitKey.keys).keys()).reverse() as any as string[];
let versions = stringVersions.map((val) => parseInt(val, 10)) as any as number[];
const stringVersions = Array.from(objectToMap(transitKey.keys).keys()).reverse() as unknown as string[];
const versions = stringVersions.map((val): number => parseInt(val, 10));
// get the selectable version options in the same
// format the official UI uses.
// e.g: ["2 (latest)", "1"]
let options: versionOption[] = versions.map((val): versionOption => {
let i18nkey = val == Math.max(...versions) ?
const options: versionOption[] = versions.map((val): versionOption => {
const i18nkey = val == Math.max(...versions) ?
"transit_rewrap_latest_version_option_text"
:
"transit_rewrap_version_option_text";
@ -83,15 +81,14 @@ export class TransitRewrapPage extends Page {
setPageContent(this.transitRewrapForm);
this.transitRewrapForm.addEventListener("submit", async function (e: Event) {
e.preventDefault();
await this.transitRewrapFormHandler();
await (this as TransitRewrapPage).transitRewrapFormHandler();
}.bind(this));
}
async transitRewrapFormHandler(): Promise<void> {
const formData = new FormData(this.transitRewrapForm);
const ciphertext = formData.get("ciphertext") as string;
try {
let res = await transitRewrap(
const res = await transitRewrap(
pageState.currentBaseMount,
pageState.currentSecret,
{
@ -101,9 +98,10 @@ export class TransitRewrapPage extends Page {
);
const modal = CopyableModal(i18next.t("transit_rewrap_result_modal_title"), res.ciphertext);
document.body.querySelector("#pageContent").appendChild(modal);
UIkit.modal(modal).show();
} catch (e) {
setErrorText(`API Error: ${e.message}`);
modal.show();
} catch (e: unknown) {
const error = e as Error;
setErrorText(`API Error: ${error.message}`);
}
}

View file

@ -46,7 +46,7 @@ export class TransitViewPage extends Page {
children: makeElement({
tag: "a",
text: secret,
onclick: _ => {
onclick: () => {
pageState.currentSecret = secret;
changePage("TRANSIT_VIEW_SECRET");
}
@ -55,14 +55,15 @@ export class TransitViewPage extends Page {
})
]
}));
} catch (e) {
if (e == DoesNotExistError) {
} catch (e: unknown) {
const error = e as Error;
if (error == DoesNotExistError) {
transitViewContent.appendChild(makeElement({
tag: "p",
text: i18next.t("transit_view_none_here_text")
}));
} else {
setErrorText(e.message);
setErrorText(error.message);
}
}
}

View file

@ -1,10 +1,10 @@
import { Page } from "../../types/Page";
import { Tile } from "../../elements/Tile";
import { changePage, setPageContent, setTitleElement } from "../../pageUtils";
import { getTransitKey } from "../../api/transit/getTransitKey";
import { makeElement } from "../../htmlUtils";
import { pageState } from "../../globalPageState";
import i18next from 'i18next';
import { getTransitKey } from "../../api/transit/getTransitKey";
import { Tile } from "../../elements/Tile";
export class TransitViewSecretPage extends Page {
constructor() {
@ -18,7 +18,7 @@ export class TransitViewSecretPage extends Page {
async render(): Promise<void> {
setTitleElement(pageState);
let transitKey = await getTransitKey(pageState.currentBaseMount, pageState.currentSecret);
const transitKey = await getTransitKey(pageState.currentBaseMount, pageState.currentSecret);
setPageContent(makeElement({
tag: "div",

View file

@ -41,9 +41,16 @@ export class UnsealPage extends Page {
}
makeRefresher(): void {
this.refresher = setInterval(async function () {
this.updateSealProgress(await getSealStatus());
}.bind(this), 1000) as unknown as number;
const id = setInterval(() => {
void (this as UnsealPage).doRefresh().then(() => {});
return;
}, 1000);
this.refresher = id as unknown as number;
}
async doRefresh(): Promise<void> {
const status = await getSealStatus();
this.updateSealProgress(status);
}
async render(): Promise<void> {
@ -58,7 +65,7 @@ export class UnsealPage extends Page {
}) as HTMLParagraphElement;
this.unsealInputContent = makeElement({
tag: "div"
}) as HTMLElement;
});
setPageContent(makeElement({
tag: "div",
children: [
@ -103,7 +110,7 @@ export class UnsealPage extends Page {
this.deinitWebcam();
this.unsealInputContent.querySelectorAll('*').forEach(n => n.remove())
if (method == UnsealInputModes.FORM_INPUT) this.makeUnsealForm();
if (method == UnsealInputModes.QR_INPUT) this.makeQRInput();
if (method == UnsealInputModes.QR_INPUT) void this.makeQRInput();
this.setButtons(method);
}
@ -115,7 +122,7 @@ export class UnsealPage extends Page {
tag: "input",
class: ["uk-input", "uk-form-width-medium"],
attributes: {
required: true,
required: "true",
type: "password",
placeholder: i18next.t("key_input_placeholder"),
name: "key"
@ -129,15 +136,15 @@ export class UnsealPage extends Page {
]
}) as HTMLFormElement;
this.unsealInputContent.appendChild(this.unsealKeyForm);
this.unsealKeyForm.addEventListener("submit", function (e) {
this.unsealKeyForm.addEventListener("submit", function (e: Event) {
e.preventDefault();
this.handleKeySubmit();
void (this as UnsealPage).handleKeySubmit();
}.bind(this));
}
async makeQRInput(): Promise<void> {
this.qrScanner = await QRScanner(function (code: string) {
this.submitKey(code);
(this as UnsealPage).submitKey(code);
console.log('decoded qr code:', code)
}.bind(this));
this.unsealInputContent.appendChild(this.qrScanner);
@ -162,15 +169,15 @@ export class UnsealPage extends Page {
submitKey(key: string): void {
submitUnsealKey(key).then(_ => {
getSealStatus().then(data => {
this.updateSealProgress(data);
void getSealStatus().then(data => {
void this.updateSealProgress(data);
});
}).catch(e => {
}).catch((e: Error) => {
setErrorText(e.message);
});
}
async handleKeySubmit(): Promise<void> {
handleKeySubmit(): void {
const formData = new FormData(this.unsealKeyForm);
this.submitKey(formData.get("key") as string)

View file

@ -1,3 +1,4 @@
import { PageState } from "./PageState";
import { pageState } from "./globalPageState";
import i18next from 'i18next';
@ -6,9 +7,13 @@ import i18next from 'i18next';
// before rendering.
// Also it only runs when process.env.NODE_ENV == "development"
// Please empty this function before committing.
export async function playground(): Promise<void> {
console.log("Welcome to Playground!");
(window as any).pageState = pageState;
(window as any).i18next = i18next;
declare global {
interface Window { pageState: PageState; i18next: unknown; }
}
// Please empty this function before committing.
export function playground(): void {
console.log("Welcome to Playground!");
window.pageState = pageState;
window.i18next = i18next;
}

View file

@ -4,8 +4,9 @@ export class Page {
constructor() {
// Do Nothing
}
render(): any {
render(): unknown {
// Do Nothing
return null;
}
get name(): string {
return "Page";

View file

@ -5,13 +5,13 @@ export function removeDoubleSlash(str: string): string {
export const getObjectKeys =
(obj: Record<string, unknown>): string[] => Object.getOwnPropertyNames(obj);
export const objectToMap =
(obj: Record<any, any>): Map<any, any> => new Map(Object.entries(obj));
(obj: Record<string, unknown>): Map<string, unknown> => new Map(Object.entries(obj));
export const sortedObjectMap =
(obj: Record<string, unknown>): Map<any, any> => new Map(Object.entries(obj).sort());
(obj: Record<string, unknown>): Map<string, unknown> => new Map(Object.entries(obj).sort());
export function getKeyByObjectPropertyValue(map: Record<string, unknown>, searchValue: unknown): string {
for (const key of getObjectKeys(map)) {
if ((map as any)[key] === searchValue)
if (map[key] === searchValue)
return key;
}
}