From 9c50ca24327e48b50c435401f356ef81c7cfaa2e Mon Sep 17 00:00:00 2001 From: Kitteh Date: Wed, 12 May 2021 16:01:04 +0100 Subject: [PATCH] Run prettier when using eslint to make code consistantly formatted. --- .eslintrc.json | 32 +-- .prettierrc | 6 + package.json | 3 + src/PageState.ts | 55 +++-- src/allPages.ts | 6 +- src/api/apiUtils.ts | 4 +- src/api/auth/usernameLogin.ts | 11 +- src/api/kv/createOrUpdateSecret.ts | 10 +- src/api/kv/deleteSecret.ts | 8 +- src/api/kv/getSecret.ts | 11 +- src/api/kv/getSecretMetadata.ts | 17 +- src/api/kv/getSecrets.ts | 4 +- src/api/kv/undeleteSecret.ts | 14 +- src/api/sys/getCapabilities.ts | 21 +- src/api/sys/getMounts.ts | 14 +- src/api/sys/getSealStatus.ts | 6 +- src/api/sys/lookupSelf.ts | 2 +- src/api/sys/renewSelf.ts | 10 +- src/api/sys/sealVault.ts | 7 +- src/api/sys/submitUnsealKey.ts | 10 +- src/api/totp/addNewTOTP.ts | 23 +- src/api/totp/getTOTPCode.ts | 7 +- src/api/totp/getTOTPKeys.ts | 2 +- src/api/transit/getTransitKey.ts | 2 +- src/api/transit/getTransitKeys.ts | 2 +- src/api/transit/transitDecrypt.ts | 17 +- src/api/transit/transitEncrypt.ts | 17 +- src/api/transit/transitRewrap.ts | 17 +- src/api/types/token.ts | 2 +- src/api/types/transit.ts | 4 +- src/elements/CopyableInputBox.ts | 18 +- src/elements/CopyableModal.ts | 47 ++-- src/elements/FileUploadInput.ts | 20 +- src/elements/ListItem.ts | 2 +- src/elements/Margin.ts | 4 +- src/elements/MarginInline.ts | 2 +- src/elements/NavBar.ts | 71 +++--- src/elements/Option.ts | 6 +- src/elements/QRScanner.ts | 20 +- src/elements/Tile.ts | 20 +- src/formatDistance.ts | 18 +- src/globalPageState.ts | 2 +- src/htmlUtils.ts | 43 ++-- src/main.ts | 115 +++++----- src/pageUtils.ts | 63 +++--- src/pages/Home.ts | 75 ++++--- src/pages/KeyValue/KeyValueDelete.ts | 56 ++--- src/pages/KeyValue/KeyValueNew.ts | 25 ++- src/pages/KeyValue/KeyValueSecret.ts | 179 ++++++++------- src/pages/KeyValue/KeyValueSecretsEdit.ts | 58 ++--- src/pages/KeyValue/KeyValueVersions.ts | 33 +-- src/pages/KeyValue/KeyValueView.ts | 75 ++++--- src/pages/Login.ts | 251 ++++++++++++---------- src/pages/Me.ts | 161 +++++++------- src/pages/PwGen.ts | 63 +++--- src/pages/SetLanguage.ts | 39 ++-- src/pages/SetVaultURL.ts | 68 +++--- src/pages/TOTP/NewTOTP.ts | 106 ++++----- src/pages/TOTP/TOTPView.ts | 63 +++--- src/pages/Transit/TransitDecrypt.ts | 53 +++-- src/pages/Transit/TransitEncrypt.ts | 51 ++--- src/pages/Transit/TransitRewrap.ts | 62 +++--- src/pages/Transit/TransitView.ts | 54 ++--- src/pages/Transit/TransitViewSecret.ts | 74 ++++--- src/pages/Unseal.ts | 135 ++++++------ src/playground.ts | 7 +- src/translations/de.js | 31 ++- src/translations/en.js | 230 ++++++++++---------- src/translations/fr.js | 205 +++++++++--------- src/translations/nl.js | 30 +-- src/translations/ru.js | 229 ++++++++++---------- src/types/Page.ts | 2 +- src/types/internalErrors.ts | 2 +- src/utils.ts | 22 +- 74 files changed, 1700 insertions(+), 1534 deletions(-) create mode 100644 .prettierrc diff --git a/.eslintrc.json b/.eslintrc.json index 3f10ff4..47ce9c7 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,14 +1,12 @@ { - "plugins": [ - "sort-imports-es6-autofix", - "@typescript-eslint" - ], + "plugins": ["sort-imports-es6-autofix", "@typescript-eslint", "prettier"], "extends": [ "eslint:recommended", "plugin:import/errors", "plugin:import/warnings", "plugin:@typescript-eslint/recommended", - "plugin:@typescript-eslint/recommended-requiring-type-checking" + "plugin:@typescript-eslint/recommended-requiring-type-checking", + "prettier" ], "parserOptions": { "ecmaVersion": 12, @@ -23,9 +21,7 @@ "BUILD_STRING": "writable" }, "rules": { - "no-unused-vars": [ - "off" - ], + "no-unused-vars": ["off"], "@typescript-eslint/no-unused-vars": [ "error", { @@ -38,15 +34,10 @@ "allow": ["arrowFunctions"] } ], - "@typescript-eslint/ban-ts-comment": [ - "off" - ], - "sort-imports-es6-autofix/sort-imports-es6": [ - 2 - ], - "@typescript-eslint/no-explicit-any": [ - 2 - ] + "@typescript-eslint/ban-ts-comment": ["off"], + "sort-imports-es6-autofix/sort-imports-es6": [2], + "@typescript-eslint/no-explicit-any": [2], + "prettier/prettier": 2 }, "env": { "browser": true, @@ -57,11 +48,8 @@ "settings": { "import/resolver": { "node": { - "extensions": [ - ".js", - ".ts" - ] + "extensions": [".js", ".ts"] } } } -} \ No newline at end of file +} diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..33b8ab9 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,6 @@ +{ + "semi": true, + "trailingComma": "all", + "singleQuote": false, + "printWidth": 100 +} \ No newline at end of file diff --git a/package.json b/package.json index cc67c34..0444045 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,9 @@ "css-loader": "^5.2.4", "date-fns": "^2.21.3", "eslint": "^7.26.0", + "eslint-config-prettier": "^8.3.0", "eslint-plugin-import": "^2.22.1", + "eslint-plugin-prettier": "^3.4.0", "eslint-plugin-sort-imports-es6-autofix": "^0.6.0", "file-saver": "^2.0.5", "git-revision-webpack-plugin": "^5.0.0", @@ -18,6 +20,7 @@ "i18next": "^20.2.2", "mini-css-extract-plugin": "^1.6.0", "node-sass": "^5.0.0", + "prettier": "^2.3.0", "prismjs": "^1.23.0", "qr-scanner": "^1.2.0", "raw-loader": "^4.0.2", diff --git a/src/PageState.ts b/src/PageState.ts index f1037e8..7105515 100644 --- a/src/PageState.ts +++ b/src/PageState.ts @@ -1,8 +1,6 @@ import { Page } from "./types/Page"; -import { allPages } from "./allPages" -import { - getKeyByObjectPropertyValue, -} from "./utils"; +import { allPages } from "./allPages"; +import { getKeyByObjectPropertyValue } from "./utils"; export class PageState { constructor() { @@ -14,48 +12,47 @@ export class PageState { // example: currentSecretPath is a array so when you try to .push() to it // it will modify the object that was getted from this class // then when you try to access it again, there will be a different object. - // I guess you could make another class that emulates a Array or Map + // I guess you could make another class that emulates a Array or Map // by using a bunch of functions and modifying localStorage in order to remove some of // the clunkyness of this approach, but for now, this works. get apiURL(): string | null { - const apiurl = localStorage.getItem('apiURL') || ""; + const apiurl = localStorage.getItem("apiURL") || ""; return apiurl.length > 0 ? apiurl : null; } set apiURL(value: string) { - localStorage.setItem('apiURL', value); + localStorage.setItem("apiURL", value); } get token(): string | null { - const tok = localStorage.getItem('token') || ""; + const tok = localStorage.getItem("token") || ""; return tok.length > 0 ? tok : null; } set token(value: string) { - localStorage.setItem('token', value); + localStorage.setItem("token", value); } get pageDirection(): string { - return localStorage.getItem('pageDirection') || "ltr"; + return localStorage.getItem("pageDirection") || "ltr"; } set pageDirection(value: string) { - localStorage.setItem('pageDirection', value); + localStorage.setItem("pageDirection", value); } get language(): string { - return localStorage.getItem('language') || ""; + return localStorage.getItem("language") || ""; } set language(value: string) { - localStorage.setItem('language', value); + localStorage.setItem("language", value); } get currentBaseMount(): string { - return localStorage.getItem('currentBaseMount') || ""; + return localStorage.getItem("currentBaseMount") || ""; } set currentBaseMount(value: string) { - localStorage.setItem('currentBaseMount', value); + localStorage.setItem("currentBaseMount", value); } - // Since this is a array we can't act directly on it so we need // functions to do the same modifications. // See the note at the start o @@ -71,47 +68,47 @@ export class PageState { } get currentSecretPath(): string[] { - return JSON.parse(localStorage.getItem('currentSecretPath') || "[]") as string[]; + return JSON.parse(localStorage.getItem("currentSecretPath") || "[]") as string[]; } set currentSecretPath(value: string[]) { - localStorage.setItem('currentSecretPath', JSON.stringify(value)); + localStorage.setItem("currentSecretPath", JSON.stringify(value)); } get currentSecretVersion(): string | null { - const result = localStorage.getItem('currentSecretVersion') + const result = localStorage.getItem("currentSecretVersion"); return result != "null" ? result || null : null; } set currentSecretVersion(value: string) { - localStorage.setItem('currentSecretVersion', String(value)); + localStorage.setItem("currentSecretVersion", String(value)); } get currentSecret(): string { - return localStorage.getItem('currentSecret') || ""; + return localStorage.getItem("currentSecret") || ""; } set currentSecret(value: string) { - localStorage.setItem('currentSecret', value); + localStorage.setItem("currentSecret", value); } get currentMountType(): string { - return localStorage.getItem('currentMountType') || ""; + return localStorage.getItem("currentMountType") || ""; } set currentMountType(value: string) { - localStorage.setItem('currentMountType', value); + localStorage.setItem("currentMountType", value); } get currentPageString(): string { const key = getKeyByObjectPropertyValue(allPages, this.currentPage); return key; } get currentPage(): Page | string { - const curPage = localStorage.getItem('currentPage') || "HOME"; + const curPage = localStorage.getItem("currentPage") || "HOME"; return allPages[curPage]; } set currentPage(value: Page | string) { - if (typeof value == 'object') { + if (typeof value == "object") { const key = getKeyByObjectPropertyValue(allPages, value); - localStorage.setItem('currentPage', key); + localStorage.setItem("currentPage", key); } else { - localStorage.setItem('currentPage', value); + localStorage.setItem("currentPage", value); } } -} \ No newline at end of file +} diff --git a/src/allPages.ts b/src/allPages.ts index a692452..edb3469 100644 --- a/src/allPages.ts +++ b/src/allPages.ts @@ -21,8 +21,8 @@ import { TransitViewSecretPage } from "./pages/Transit/TransitViewSecret"; import { UnsealPage } from "./pages/Unseal"; type pagesList = { - [key: string]: Page -} + [key: string]: Page; +}; export const allPages: pagesList = { HOME: new HomePage(), @@ -45,4 +45,4 @@ export const allPages: pagesList = { KEY_VALUE_DELETE: new KeyValueDeletePage(), KEY_VALUE_SECRET_EDIT: new KeyValueSecretEditPage(), PW_GEN: new PwGenPage(), -}; \ No newline at end of file +}; diff --git a/src/api/apiUtils.ts b/src/api/apiUtils.ts index 7e2eef1..824839e 100644 --- a/src/api/apiUtils.ts +++ b/src/api/apiUtils.ts @@ -3,7 +3,7 @@ import { pageState } from "../globalPageState"; export function getHeaders(): Record { return { "X-Vault-Token": pageState.token, - } + }; } -export const appendAPIURL = (url: string): string => pageState.apiURL + url; \ No newline at end of file +export const appendAPIURL = (url: string): string => pageState.apiURL + url; diff --git a/src/api/auth/usernameLogin.ts b/src/api/auth/usernameLogin.ts index 71080e7..1784cc0 100644 --- a/src/api/auth/usernameLogin.ts +++ b/src/api/auth/usernameLogin.ts @@ -2,15 +2,18 @@ import { appendAPIURL } from "../apiUtils"; export async function usernameLogin(username: string, password: string): Promise { const request = new Request(appendAPIURL(`/v1/auth/userpass/login/${username}`), { - method: 'POST', + method: "POST", headers: { - 'Content-Type': 'application/json' + "Content-Type": "application/json", }, - body: JSON.stringify({ "username": username, "password": password }) + body: JSON.stringify({ username: username, password: password }), }); const resp = await fetch(request); - const data = await resp.json() as { auth?: { client_token: string }; errors?: string[] }; + 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) { diff --git a/src/api/kv/createOrUpdateSecret.ts b/src/api/kv/createOrUpdateSecret.ts index 2641ce0..5d2aba4 100644 --- a/src/api/kv/createOrUpdateSecret.ts +++ b/src/api/kv/createOrUpdateSecret.ts @@ -6,14 +6,14 @@ export async function createOrUpdateSecret( mountType: string, secretPath: string[], name: string, - data: Record + data: Record, ): Promise { let secretURL = ""; let APIData = {}; if (mountType == "kv-v2") { secretURL = `/v1/${baseMount}/data/${secretPath.join("/")}/${name}`; - APIData = { "data": data }; + APIData = { data: data }; } else { secretURL = `/v1/${baseMount}/${secretPath.join("/")}/${name}`; APIData = data; @@ -23,14 +23,14 @@ export async function createOrUpdateSecret( const request = new Request(appendAPIURL(secretURL), { method: "POST", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", ...getHeaders(), }, - body: JSON.stringify(APIData, null, 0) + body: JSON.stringify(APIData, null, 0), }); const response = await fetch(request); if (!response.ok) { - const json = await response.json() as {errors: string[]}; + const json = (await response.json()) as { errors: string[] }; throw new Error(json.errors[0]); } } diff --git a/src/api/kv/deleteSecret.ts b/src/api/kv/deleteSecret.ts index dae7fe2..03aa3d3 100644 --- a/src/api/kv/deleteSecret.ts +++ b/src/api/kv/deleteSecret.ts @@ -6,7 +6,7 @@ export async function deleteSecret( mountType: string, secretPath: string[], name: string, - version: string | null = null + version: string | null = null, ): Promise { let secretURL = ""; @@ -19,9 +19,9 @@ export async function deleteSecret( method: "POST", headers: { ...getHeaders(), - 'Content-Type': 'application/json', + "Content-Type": "application/json", }, - body: version != null ? JSON.stringify({ "versions": [version] }) : "{}" + body: version != null ? JSON.stringify({ versions: [version] }) : "{}", }); } else { if (mountType == "kv-v2") { @@ -37,7 +37,7 @@ export async function deleteSecret( } const response = await fetch(request); if (!response.ok) { - const json = await response.json() as {errors: string[]}; + const json = (await response.json()) as { errors: string[] }; throw new Error(json.errors[0]); } } diff --git a/src/api/kv/getSecret.ts b/src/api/kv/getSecret.ts index 34be9d2..0f01c7b 100644 --- a/src/api/kv/getSecret.ts +++ b/src/api/kv/getSecret.ts @@ -5,13 +5,12 @@ export async function getSecret( mountType: string, secretPath: string[], name: string, - version: string|null = null + version: string | null = null, ): Promise> { let secretURL = ""; if (mountType == "kv-v2") { secretURL = `/v1/${baseMount}/data/${secretPath.join("")}/${name}`; - if (version != null) - secretURL += `?version=${version}`; + if (version != null) secretURL += `?version=${version}`; } else { secretURL = `/v1/${baseMount}/${secretPath.join("")}/${name}`; } @@ -20,10 +19,10 @@ export async function getSecret( }); const resp = await fetch(request); - const data = await resp.json() as unknown; + const data = (await resp.json()) as unknown; if (mountType == "kv-v2") { - return (data as {data: {data: Record}}).data.data; + return (data as { data: { data: Record } }).data.data; } else { - return (data as {data: Record}).data; + return (data as { data: Record }).data; } } diff --git a/src/api/kv/getSecretMetadata.ts b/src/api/kv/getSecretMetadata.ts index 051ce14..2675c3c 100644 --- a/src/api/kv/getSecretMetadata.ts +++ b/src/api/kv/getSecretMetadata.ts @@ -1,19 +1,22 @@ import { appendAPIURL, getHeaders } from "../apiUtils"; type SecretMetadataType = { - versions: Record -} + versions: Record; +}; export async function getSecretMetadata( baseMount: string, secretPath: string[], - name: string + name: string, ): Promise { - const request = new Request(appendAPIURL(`/v1/${baseMount}/metadata/${secretPath.join("")}/${name}`), { - headers: getHeaders(), - }); + const request = new Request( + appendAPIURL(`/v1/${baseMount}/metadata/${secretPath.join("")}/${name}`), + { + headers: getHeaders(), + }, + ); const resp = await fetch(request); - const data = await resp.json() as {data: SecretMetadataType}; + const data = (await resp.json()) as { data: SecretMetadataType }; return data.data; } diff --git a/src/api/kv/getSecrets.ts b/src/api/kv/getSecrets.ts index bfab3ba..f513144 100644 --- a/src/api/kv/getSecrets.ts +++ b/src/api/kv/getSecrets.ts @@ -4,7 +4,7 @@ import { appendAPIURL, getHeaders } from "../apiUtils"; export async function getSecrets( baseMount: string, mountType: string, - secretPath: string[] + secretPath: string[], ): Promise { let secretURL = ""; if (mountType == "kv-v2") { @@ -20,6 +20,6 @@ export async function getSecrets( if (resp.status == 404) { throw DoesNotExistError; } - const data = await resp.json() as { data: { keys: string[] } }; + const data = (await resp.json()) as { data: { keys: string[] } }; return data.data.keys; } diff --git a/src/api/kv/undeleteSecret.ts b/src/api/kv/undeleteSecret.ts index 0cdd7bf..ba95454 100644 --- a/src/api/kv/undeleteSecret.ts +++ b/src/api/kv/undeleteSecret.ts @@ -6,16 +6,12 @@ export async function undeleteSecret( baseMount: string, secretPath: string[], name: string, - version: string|null = null + version: string | null = null, ): Promise { let secretURL = `/v1/${baseMount}/undelete/${secretPath.join("/")}/${name}`; secretURL = removeDoubleSlash(secretURL).replace(/\/$/, ""); if (version == null) { - const meta = await getSecretMetadata( - baseMount, - secretPath, - name - ); + const meta = await getSecretMetadata(baseMount, secretPath, name); const versions = getObjectKeys(meta.versions); version = String(versions[versions.length - 1]); } @@ -24,13 +20,13 @@ export async function undeleteSecret( method: "POST", headers: { ...getHeaders(), - 'Content-Type': 'application/json', + "Content-Type": "application/json", }, - body: JSON.stringify({ "versions": [version] }) + body: JSON.stringify({ versions: [version] }), }); const response = await fetch(request); if (!response.ok) { - const json = await response.json() as {errors: string[]}; + const json = (await response.json()) as { errors: string[] }; throw new Error(json.errors[0]); } } diff --git a/src/api/sys/getCapabilities.ts b/src/api/sys/getCapabilities.ts index cb814bc..cf5605a 100644 --- a/src/api/sys/getCapabilities.ts +++ b/src/api/sys/getCapabilities.ts @@ -1,29 +1,28 @@ import { appendAPIURL, getHeaders } from "../apiUtils"; import { removeDoubleSlash } from "../../utils"; - -export async function getCapabilitiesPath(path: string): Promise { +export async function getCapabilitiesPath(path: string): Promise { const request = new Request(appendAPIURL("/v1/sys/capabilities-self"), { method: "POST", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", ...getHeaders(), }, - body: JSON.stringify( - { - "paths": [removeDoubleSlash(path)] - } - ) + body: JSON.stringify({ + paths: [removeDoubleSlash(path)], + }), }); const response = await fetch(request); - const data = await response.json() as {capabilities: string[]}; + const data = (await response.json()) as { capabilities: string[] }; return data.capabilities; } export async function getCapabilities( baseMount: string, secretPath: string[], - name: string + name: string, ): Promise { - return await getCapabilitiesPath(removeDoubleSlash(baseMount + secretPath.join("/") + "/" + name)); + return await getCapabilitiesPath( + removeDoubleSlash(baseMount + secretPath.join("/") + "/" + name), + ); } diff --git a/src/api/sys/getMounts.ts b/src/api/sys/getMounts.ts index dfe8e07..1f4caa3 100644 --- a/src/api/sys/getMounts.ts +++ b/src/api/sys/getMounts.ts @@ -1,21 +1,21 @@ import { appendAPIURL, getHeaders } from "../apiUtils"; export type MountType = { - type: string - options: { - version: string - } -} + type: string; + options: { + version: string; + }; +}; export type MountsType = { [key: string]: MountType; -} +}; export async function getMounts(): Promise { const request = new Request(appendAPIURL("/v1/sys/internal/ui/mounts"), { headers: getHeaders(), }); const resp = await fetch(request); - const data = await resp.json() as {data: {secret: MountsType}}; + const data = (await resp.json()) as { data: { secret: MountsType } }; return data.data.secret; } diff --git a/src/api/sys/getSealStatus.ts b/src/api/sys/getSealStatus.ts index ca4591c..edbfbab 100644 --- a/src/api/sys/getSealStatus.ts +++ b/src/api/sys/getSealStatus.ts @@ -4,11 +4,11 @@ export type SealStatusType = { progress: number; t: number; sealed: boolean; -} +}; export async function getSealStatus(): Promise { const request = new Request(appendAPIURL("/v1/sys/seal-status")); - const resp = await fetch(request) - const data = await resp.json() as SealStatusType; + const resp = await fetch(request); + const data = (await resp.json()) as SealStatusType; return data; } diff --git a/src/api/sys/lookupSelf.ts b/src/api/sys/lookupSelf.ts index fad482c..5b3abd6 100644 --- a/src/api/sys/lookupSelf.ts +++ b/src/api/sys/lookupSelf.ts @@ -6,7 +6,7 @@ export async function lookupSelf(): Promise { headers: getHeaders(), }); const resp = await fetch(request); - const data = await resp.json() as { data?: TokenInfo; errors?: string[] }; + const data = (await resp.json()) as { data?: TokenInfo; errors?: string[] }; if ("data" in data) { return data.data; } else if ("errors" in data) { diff --git a/src/api/sys/renewSelf.ts b/src/api/sys/renewSelf.ts index e8fb802..2738ac8 100644 --- a/src/api/sys/renewSelf.ts +++ b/src/api/sys/renewSelf.ts @@ -2,15 +2,15 @@ import { appendAPIURL, getHeaders } from "../apiUtils"; export async function renewSelf(): Promise { const request = new Request(appendAPIURL("/v1/auth/token/renew-self"), { - method: 'POST', + method: "POST", headers: { ...getHeaders(), - 'Content-Type': 'application/json' + "Content-Type": "application/json", }, - body: JSON.stringify({}) + body: JSON.stringify({}), }); - const resp = await fetch(request) - const data = await resp.json() as { errors?: string[] }; + const resp = await fetch(request); + const data = (await resp.json()) as { errors?: string[] }; if ("errors" in data) { throw new Error(data.errors[0]); } diff --git a/src/api/sys/sealVault.ts b/src/api/sys/sealVault.ts index 0964c66..c68b27e 100644 --- a/src/api/sys/sealVault.ts +++ b/src/api/sys/sealVault.ts @@ -1,13 +1,12 @@ import { appendAPIURL, getHeaders } from "../apiUtils"; - export async function sealVault(): Promise { const request = new Request(appendAPIURL("/v1/sys/seal"), { - method: 'PUT', + method: "PUT", headers: getHeaders(), }); - const resp = await fetch(request) - const data = await resp.json() as { errors?: string[] }; + const resp = await fetch(request); + const data = (await resp.json()) as { errors?: string[] }; if ("errors" in data) { throw new Error(data.errors[0]); } diff --git a/src/api/sys/submitUnsealKey.ts b/src/api/sys/submitUnsealKey.ts index dcd23b6..b1090a7 100644 --- a/src/api/sys/submitUnsealKey.ts +++ b/src/api/sys/submitUnsealKey.ts @@ -4,15 +4,15 @@ export async function submitUnsealKey(key: string): Promise { const request = new Request(appendAPIURL("/v1/sys/unseal"), { method: "POST", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", }, body: JSON.stringify({ - "key": key - }) + key: key, + }), }); - const resp = await fetch(request) + const resp = await fetch(request); if (!resp.ok) { - const data = await resp.json() as { errors?: string[] }; + const data = (await resp.json()) as { errors?: string[] }; if ("errors" in data) { throw new Error(data.errors[0]); } diff --git a/src/api/totp/addNewTOTP.ts b/src/api/totp/addNewTOTP.ts index 3c914a3..5005eb1 100644 --- a/src/api/totp/addNewTOTP.ts +++ b/src/api/totp/addNewTOTP.ts @@ -1,18 +1,21 @@ import { appendAPIURL, getHeaders } from "../apiUtils"; import { removeDoubleSlash } from "../../utils"; -export async function addNewTOTP(baseMount: string, parms: {name: string}): Promise { - const request = new Request(appendAPIURL(removeDoubleSlash(`/v1/${baseMount}/keys/${parms.name}`)), { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - ...getHeaders(), +export async function addNewTOTP(baseMount: string, parms: { name: string }): Promise { + const request = new Request( + appendAPIURL(removeDoubleSlash(`/v1/${baseMount}/keys/${parms.name}`)), + { + method: "POST", + headers: { + "Content-Type": "application/json", + ...getHeaders(), + }, + body: JSON.stringify(parms), }, - body: JSON.stringify(parms) - }); - const resp = await fetch(request) + ); + const resp = await fetch(request); if (!resp.ok) { - const data = await resp.json() as { errors?: string[] }; + const data = (await resp.json()) as { errors?: string[] }; if ("errors" in data) { throw new Error(data.errors[0]); } diff --git a/src/api/totp/getTOTPCode.ts b/src/api/totp/getTOTPCode.ts index 2056a47..371b70c 100644 --- a/src/api/totp/getTOTPCode.ts +++ b/src/api/totp/getTOTPCode.ts @@ -1,11 +1,10 @@ import { appendAPIURL, getHeaders } from "../apiUtils"; export async function getTOTPCode(baseMount: string, name: string): Promise { - const request = - new Request(appendAPIURL(`/v1/${baseMount}/code/${name}`), { + const request = new Request(appendAPIURL(`/v1/${baseMount}/code/${name}`), { headers: getHeaders(), }); - const resp = await fetch(request) - const data = await resp.json() as {data: {code: string}}; + const resp = await fetch(request); + const data = (await resp.json()) as { data: { code: string } }; return data.data.code; } diff --git a/src/api/totp/getTOTPKeys.ts b/src/api/totp/getTOTPKeys.ts index 8b08144..a175b86 100644 --- a/src/api/totp/getTOTPKeys.ts +++ b/src/api/totp/getTOTPKeys.ts @@ -10,6 +10,6 @@ export async function getTOTPKeys(baseMount: string): Promise { if (resp.status == 404) { throw DoesNotExistError; } - const data = await resp.json() as {data: {keys: string[] }}; + const data = (await resp.json()) as { data: { keys: string[] } }; return data.data.keys; } diff --git a/src/api/transit/getTransitKey.ts b/src/api/transit/getTransitKey.ts index 7f0ce3a..9a197b5 100644 --- a/src/api/transit/getTransitKey.ts +++ b/src/api/transit/getTransitKey.ts @@ -11,6 +11,6 @@ export async function getTransitKey(baseMount: string, name: string): Promise { if (resp.status == 404) { throw DoesNotExistError; } - const data = await resp.json() as { data: string[] }; + const data = (await resp.json()) as { data: string[] }; return data.data; } diff --git a/src/api/transit/transitDecrypt.ts b/src/api/transit/transitDecrypt.ts index 6e42198..7e09b76 100644 --- a/src/api/transit/transitDecrypt.ts +++ b/src/api/transit/transitDecrypt.ts @@ -3,28 +3,31 @@ import { removeDoubleSlash } from "../../utils"; type DecryptionResult = { plaintext: string; -} +}; type DecryptionPayload = { ciphertext: string; -} +}; export async function transitDecrypt( baseMount: string, name: string, - payload: DecryptionPayload + payload: DecryptionPayload, ): Promise { const request = new Request(appendAPIURL(removeDoubleSlash(`/v1/${baseMount}/decrypt/${name}`)), { - method: 'POST', + method: "POST", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", ...getHeaders(), }, - body: JSON.stringify(payload) + body: JSON.stringify(payload), }); const response = await fetch(request); - const data = await response.json() as { errors?: string[]; data?: DecryptionResult; }; + const data = (await response.json()) as { + errors?: string[]; + data?: DecryptionResult; + }; if (!response.ok) { throw new Error(data.errors[0]); } else { diff --git a/src/api/transit/transitEncrypt.ts b/src/api/transit/transitEncrypt.ts index 2b97342..e3ee181 100644 --- a/src/api/transit/transitEncrypt.ts +++ b/src/api/transit/transitEncrypt.ts @@ -3,28 +3,31 @@ import { removeDoubleSlash } from "../../utils"; type EncryptionResult = { ciphertext: string; -} +}; type EncryptionPayload = { plaintext: string; -} +}; export async function transitEncrypt( baseMount: string, name: string, - payload: EncryptionPayload + payload: EncryptionPayload, ): Promise { const request = new Request(appendAPIURL(removeDoubleSlash(`/v1/${baseMount}/encrypt/${name}`)), { - method: 'POST', + method: "POST", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", ...getHeaders(), }, - body: JSON.stringify(payload) + body: JSON.stringify(payload), }); const response = await fetch(request); - const data = await response.json() as { errors?: string[]; data?: EncryptionResult; }; + const data = (await response.json()) as { + errors?: string[]; + data?: EncryptionResult; + }; if (!response.ok) { throw new Error(data.errors[0]); } else { diff --git a/src/api/transit/transitRewrap.ts b/src/api/transit/transitRewrap.ts index da8662b..8924069 100644 --- a/src/api/transit/transitRewrap.ts +++ b/src/api/transit/transitRewrap.ts @@ -3,29 +3,32 @@ import { removeDoubleSlash } from "../../utils"; type RewrapResult = { ciphertext: string; -} +}; type RewrapPayload = { ciphertext: string; key_version?: number; -} +}; export async function transitRewrap( baseMount: string, name: string, - payload: RewrapPayload + payload: RewrapPayload, ): Promise { const request = new Request(appendAPIURL(removeDoubleSlash(`/v1/${baseMount}/rewrap/${name}`)), { - method: 'POST', + method: "POST", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json", ...getHeaders(), }, - body: JSON.stringify(payload) + body: JSON.stringify(payload), }); const response = await fetch(request); - const data = await response.json() as { errors?: string[]; data?: RewrapResult; }; + const data = (await response.json()) as { + errors?: string[]; + data?: RewrapResult; + }; if (!response.ok) { throw new Error(data.errors[0]); } else { diff --git a/src/api/types/token.ts b/src/api/types/token.ts index 8541a3a..75b977c 100644 --- a/src/api/types/token.ts +++ b/src/api/types/token.ts @@ -16,4 +16,4 @@ export type TokenInfo = { policies: string[]; renewable: boolean; ttl: number; -} \ No newline at end of file +}; diff --git a/src/api/types/transit.ts b/src/api/types/transit.ts index 05c9ea1..8419928 100644 --- a/src/api/types/transit.ts +++ b/src/api/types/transit.ts @@ -19,7 +19,7 @@ export type TransitKeyBaseType = { exportable: boolean; allow_plaintext_backup: boolean; type: keyof typeof TransitKeyTypes; -} +}; // Type returned when calling getTransitKey export type TransitKeyType = TransitKeyBaseType & { @@ -32,4 +32,4 @@ export type TransitKeyType = TransitKeyBaseType & { supports_decryption: boolean; supports_derivation: boolean; supports_signing: boolean; -} \ No newline at end of file +}; diff --git a/src/elements/CopyableInputBox.ts b/src/elements/CopyableInputBox.ts index caf678a..71fdd84 100644 --- a/src/elements/CopyableInputBox.ts +++ b/src/elements/CopyableInputBox.ts @@ -9,7 +9,7 @@ export interface CopyableInputBoxType extends HTMLElement { } export function CopyableInputBox(text: string, copyable = true): CopyableInputBoxType { - const inputBoxDiv = (makeElement({ tag: "div" }) as CopyableInputBoxType); + const inputBoxDiv = makeElement({ tag: "div" }) as CopyableInputBoxType; let inputBoxCopyButton: HTMLElement = null; if (copyable) { inputBoxCopyButton = makeElement({ @@ -17,26 +17,23 @@ export function CopyableInputBox(text: string, copyable = true): CopyableInputBo class: "uk-form-icon", attributes: { "uk-icon": "icon: copy", - "role": "img", - "aria-label": i18next.t("copy_input_box_copy_icon_text") + role: "img", + "aria-label": i18next.t("copy_input_box_copy_icon_text"), }, thenRun: (e) => { const clipboard = new ClipboardJS(e); addClipboardNotifications(clipboard, 600); - } + }, }); } 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, - inputBoxInput - ]); + const inputBoxInner = MarginInline([inputBoxCopyButton, inputBoxInput]); inputBoxDiv.appendChild(inputBoxInner); inputBoxDiv.setText = function (text) { @@ -47,6 +44,5 @@ export function CopyableInputBox(text: string, copyable = true): CopyableInputBo }; inputBoxDiv.setText(text); - return inputBoxDiv; -} \ No newline at end of file +} diff --git a/src/elements/CopyableModal.ts b/src/elements/CopyableModal.ts index 1bf6cdc..71271ad 100644 --- a/src/elements/CopyableModal.ts +++ b/src/elements/CopyableModal.ts @@ -1,24 +1,24 @@ import { addClipboardNotifications } from "../pageUtils"; import { makeElement } from "../htmlUtils"; import ClipboardJS from "clipboard"; -import FileSaver from 'file-saver'; -import UIkit from 'uikit'; -import i18next from 'i18next'; +import FileSaver from "file-saver"; +import UIkit from "uikit"; +import i18next from "i18next"; 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: { - "uk-modal": "" + "uk-modal": "", }, children: makeElement({ tag: "div", @@ -29,8 +29,8 @@ export function CopyableModal(name: string, contentString: string): ModalType { class: "uk-modal-close-default", attributes: { "uk-close": "", - type: "button" - } + type: "button", + }, }), makeElement({ tag: "div", @@ -38,8 +38,8 @@ export function CopyableModal(name: string, contentString: string): ModalType { children: makeElement({ tag: "h2", class: "uk-modal-title", - text: name - }) + text: name, + }), }), makeElement({ tag: "div", @@ -47,8 +47,8 @@ export function CopyableModal(name: string, contentString: string): ModalType { children: makeElement({ tag: "pre", class: "wrap-pre", - text: contentString - }) + text: contentString, + }), }), makeElement({ tag: "div", @@ -59,41 +59,42 @@ export function CopyableModal(name: string, contentString: string): ModalType { class: ["uk-button", "uk-button-primary"], attributes: { type: "button", - "data-clipboard-text": contentString + "data-clipboard-text": contentString, }, text: i18next.t("copy_modal_download_btn"), onclick: () => { - const blob = new Blob([contentString], { type: "text/plain;charset=utf-8" }); + const blob = new Blob([contentString], { + type: "text/plain;charset=utf-8", + }); (FileSaver as FileSaverType).saveAs(blob, "result.txt"); - } + }, }), makeElement({ tag: "button", class: ["uk-button", "uk-button-primary"], attributes: { type: "button", - "data-clipboard-text": contentString + "data-clipboard-text": contentString, }, text: i18next.t("copy_modal_copy_btn"), thenRun: (e) => { const clipboard = new ClipboardJS(e); addClipboardNotifications(clipboard); - } + }, }), makeElement({ tag: "button", class: ["uk-button", "uk-button-secondary", "uk-modal-close"], attributes: { type: "button" }, - text: i18next.t("copy_modal_close_btn") + text: i18next.t("copy_modal_close_btn"), }), - - ] + ], }), - ] - }) + ], + }), }) as ModalType; modal.show = () => { UIkit.modal(modal).show(); - } + }; return modal; } diff --git a/src/elements/FileUploadInput.ts b/src/elements/FileUploadInput.ts index bd57144..2d2390d 100644 --- a/src/elements/FileUploadInput.ts +++ b/src/elements/FileUploadInput.ts @@ -6,8 +6,8 @@ export function FileUploadInput(name: string): Element { tag: "input", attributes: { name: name, - type: "file" - } + type: "file", + }, }); const selectInput = makeElement({ @@ -15,8 +15,8 @@ export function FileUploadInput(name: string): Element { class: ["uk-input", "uk-form-width-medium"], attributes: { type: "text", - placeholder: i18next.t("file_upload_input_btn") - } + placeholder: i18next.t("file_upload_input_btn"), + }, }); const fileIcon = makeElement({ @@ -24,19 +24,15 @@ export function FileUploadInput(name: string): Element { class: "uk-form-icon", attributes: { "uk-icon": "icon: upload", - "role": "img" + role: "img", }, }); return makeElement({ tag: "div", attributes: { - "uk-form-custom": "target: true" + "uk-form-custom": "target: true", }, - children: [ - fileIcon, - fileInput, - selectInput - ] + children: [fileIcon, fileInput, selectInput], }); -} \ No newline at end of file +} diff --git a/src/elements/ListItem.ts b/src/elements/ListItem.ts index 129055f..7139d50 100644 --- a/src/elements/ListItem.ts +++ b/src/elements/ListItem.ts @@ -3,6 +3,6 @@ import { makeElement } from "../htmlUtils"; export function ListItem(children: Element[] | Element): HTMLElement { return makeElement({ tag: "li", - children: children + children: children, }); } diff --git a/src/elements/Margin.ts b/src/elements/Margin.ts index 450ca99..390e965 100644 --- a/src/elements/Margin.ts +++ b/src/elements/Margin.ts @@ -4,6 +4,6 @@ export function Margin(children: Element | Element[]): Element { return makeElement({ tag: "div", class: "uk-margin", - children: children + children: children, }); -} \ No newline at end of file +} diff --git a/src/elements/MarginInline.ts b/src/elements/MarginInline.ts index 84e7b96..ea1247a 100644 --- a/src/elements/MarginInline.ts +++ b/src/elements/MarginInline.ts @@ -10,4 +10,4 @@ export function MarginInline(children: Element | Element[]): Element { children: children, }), }); -} \ No newline at end of file +} diff --git a/src/elements/NavBar.ts b/src/elements/NavBar.ts index 453aeed..a10e98d 100644 --- a/src/elements/NavBar.ts +++ b/src/elements/NavBar.ts @@ -18,23 +18,35 @@ export function NavBar(): HTMLElement { tag: "ul", class: "uk-navbar-nav", children: [ - ListItem(makeElement({ - tag: "a", - text: i18next.t("home_btn"), - onclick: () => { changePage("HOME"); } - })), - ListItem(makeElement({ - tag: "a", - text: i18next.t("back_btn"), - onclick: () => { (pageState.currentPage as Page).goBack(); } - })), - ListItem(makeElement({ - tag: "a", - text: i18next.t("refresh_btn"), - onclick: () => { changePage(pageState.currentPageString); } - })), - ] - }) + ListItem( + makeElement({ + tag: "a", + text: i18next.t("home_btn"), + onclick: () => { + changePage("HOME"); + }, + }), + ), + ListItem( + makeElement({ + tag: "a", + text: i18next.t("back_btn"), + onclick: () => { + (pageState.currentPage as Page).goBack(); + }, + }), + ), + ListItem( + makeElement({ + tag: "a", + text: i18next.t("refresh_btn"), + onclick: () => { + changePage(pageState.currentPageString); + }, + }), + ), + ], + }), }), makeElement({ tag: "div", @@ -43,19 +55,22 @@ export function NavBar(): HTMLElement { tag: "ul", class: "uk-navbar-nav", children: [ - ListItem(makeElement({ - tag: "a", - text: i18next.t("me_btn"), - onclick: () => { changePage("ME"); } - })) - ] - }) - }) - ] - }) + ListItem( + makeElement({ + tag: "a", + text: i18next.t("me_btn"), + onclick: () => { + changePage("ME"); + }, + }), + ), + ], + }), + }), + ], + }); } export function reloadNavBar(): void { document.querySelector("#navBar").replaceWith(NavBar()); } - diff --git a/src/elements/Option.ts b/src/elements/Option.ts index 0a5fad7..5f30a1a 100644 --- a/src/elements/Option.ts +++ b/src/elements/Option.ts @@ -7,6 +7,6 @@ export function Option(label: string, value: string): HTMLElement { attributes: { label: label, value: value, - } - }) -} \ No newline at end of file + }, + }); +} diff --git a/src/elements/QRScanner.ts b/src/elements/QRScanner.ts index 87af665..476cd20 100644 --- a/src/elements/QRScanner.ts +++ b/src/elements/QRScanner.ts @@ -1,31 +1,29 @@ import { Margin } from "./Margin"; import { makeElement } from "../htmlUtils"; -import QrScanner from 'qr-scanner'; +import QrScanner from "qr-scanner"; /* eslint-disable import/no-unresolved */ // @ts-ignore -import qrScannerWorkerSource from '!!raw-loader!qr-scanner/qr-scanner-worker.min.js'; +import qrScannerWorkerSource from "!!raw-loader!qr-scanner/qr-scanner-worker.min.js"; QrScanner.WORKER_PATH = URL.createObjectURL(new Blob([qrScannerWorkerSource])); export interface QRScannerType extends HTMLElement { deinit(): void; } -export async function QRScanner(onScan: (code: string) => void): Promise { +export async function QRScanner(onScan: (code: string) => void): Promise { const webcamVideo = makeElement({ - tag: "video" + tag: "video", }) as HTMLVideoElement; const QRInput = makeElement({ tag: "div", - children: [ - Margin(webcamVideo), - ] + children: [Margin(webcamVideo)], }) as QRScannerType; const stream = await navigator.mediaDevices.getUserMedia({ video: { - facingMode: 'environment', + facingMode: "environment", }, audio: false, }); @@ -36,16 +34,16 @@ export async function QRScanner(onScan: (code: string) => void): Promise { try { stream.getTracks().forEach(function (track) { track.stop(); }); } catch (_) { - ()=>{}; + () => {}; } }; return QRInput; -} \ No newline at end of file +} diff --git a/src/elements/Tile.ts b/src/elements/Tile.ts index 842c3cb..597f831 100644 --- a/src/elements/Tile.ts +++ b/src/elements/Tile.ts @@ -7,7 +7,7 @@ type TileParams = { icon: string; iconText: string; onclick: () => void; -} +}; export function Tile(params: TileParams): HTMLElement { if (!params.condition) return; @@ -28,17 +28,17 @@ export function Tile(params: TileParams): HTMLElement { class: ["uk-icon", "uk-margin-small-left"], attributes: { "uk-icon": `icon: ${params.icon}`, - "role": "img", - "aria-label": params.iconText - } - }) + role: "img", + "aria-label": params.iconText, + }, + }), }), makeElement({ tag: "span", class: "uk-text-muted", - text: params.description - }) - ] - }) + text: params.description, + }), + ], + }), }); -} \ No newline at end of file +} diff --git a/src/formatDistance.ts b/src/formatDistance.ts index de787f4..2893af8 100644 --- a/src/formatDistance.ts +++ b/src/formatDistance.ts @@ -1,18 +1,18 @@ -import { de, enGB, fr, it, nl, ru } from 'date-fns/locale' -import { formatDistance as formatDistanceReal} from 'date-fns'; +import { de, enGB, fr, it, nl, ru } from "date-fns/locale"; +import { formatDistance as formatDistanceReal } from "date-fns"; import { pageState } from "./globalPageState"; function getLocale(): Locale { return { - "en": enGB, - "fr": fr, - "nl": nl, - "ru": ru, - "de": de, - "it": it, + en: enGB, + fr: fr, + nl: nl, + ru: ru, + de: de, + it: it, }[pageState.language]; } export function formatDistance(d1: Date, d2: Date): string { return formatDistanceReal(d1, d2, { locale: getLocale() }); -} \ No newline at end of file +} diff --git a/src/globalPageState.ts b/src/globalPageState.ts index dd60325..63925e1 100644 --- a/src/globalPageState.ts +++ b/src/globalPageState.ts @@ -1,2 +1,2 @@ import { PageState } from "./PageState"; -export const pageState = new PageState(); \ No newline at end of file +export const pageState = new PageState(); diff --git a/src/htmlUtils.ts b/src/htmlUtils.ts index b149160..cd847d9 100644 --- a/src/htmlUtils.ts +++ b/src/htmlUtils.ts @@ -1,32 +1,32 @@ import { getObjectKeys } from "./utils"; type optionsFunctionsObject = { - [key: string]: (e: Element, arg: unknown) => void -} + [key: string]: (e: Element, arg: unknown) => void; +}; const optionsFunctions: optionsFunctionsObject = { - "class": (e: Element, arg: string | string[]) => { + class: (e: Element, arg: string | string[]) => { if (!Array.isArray(arg)) { arg = String(arg).split(" "); } e.classList.add(...arg); }, - "id": (e: Element, arg: string) => e.id = arg, - "html": (e: Element, arg: string) => e.innerHTML = arg, - "onclick": (e: Element, arg: () => void) => (e as HTMLButtonElement).onclick = arg, - "attributes": setElementAttributes, - "text": (e: Element, arg: string) => (e as HTMLParagraphElement).innerText = arg, - "children": (e: Element, arg: Element | Element[]) => { + id: (e: Element, arg: string) => (e.id = arg), + html: (e: Element, arg: string) => (e.innerHTML = arg), + onclick: (e: Element, arg: () => void) => ((e as HTMLButtonElement).onclick = arg), + attributes: setElementAttributes, + text: (e: Element, arg: string) => ((e as HTMLParagraphElement).innerText = arg), + children: (e: Element, arg: Element | Element[]) => { if (Array.isArray(arg)) { - arg.forEach(child => { + arg.forEach((child) => { if (child != null) e.appendChild(child); }); } else { if (arg != null) e.appendChild(arg); } }, - "thenRun": (e: Element, arg: (e: Element) => void) => arg(e), -} + thenRun: (e: Element, arg: (e: Element) => void) => arg(e), +}; interface ElementInfo { condition?: boolean; @@ -43,7 +43,11 @@ interface ElementInfo { } export function makeElement(elementInfo: ElementInfo): HTMLElement { - if ("condition" in elementInfo) { if (!elementInfo.condition) { return null; } } + if ("condition" in elementInfo) { + if (!elementInfo.condition) { + return null; + } + } const element = document.createElement(elementInfo.tag); for (const key of Object.getOwnPropertyNames(elementInfo)) { @@ -61,9 +65,10 @@ export function setElementAttributes(element: Element, attributes: Record => new Promise((resolve, reject) => { - const reader = new FileReader(); - reader.readAsDataURL(file); - reader.onload = () => resolve(reader.result as string); - reader.onerror = error => reject(error); -}); \ No newline at end of file +export const fileToBase64 = (file: File): Promise => + new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.readAsDataURL(file); + reader.onload = () => resolve(reader.result as string); + reader.onerror = (error) => reject(error); + }); diff --git a/src/main.ts b/src/main.ts index 52826d9..f90eb58 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,4 +1,4 @@ -'use strict'; +"use strict"; // JS & CSS @@ -17,51 +17,51 @@ import "prismjs/components/prism-json"; Prism.highlightAll(); /* eslint-enable */ -import { - changePage, - renderPage, -} from "./pageUtils"; +import { NavBar } from "./elements/NavBar"; +import { changePage, renderPage } from "./pageUtils"; import { getSealStatus } from "./api/sys/getSealStatus"; import { makeElement } from "./htmlUtils"; import { pageState } from "./globalPageState"; import { playground } from "./playground"; -import { NavBar } from "./elements/NavBar"; // Translations -import { formatDistance } from './formatDistance'; -import i18next from 'i18next'; +import { formatDistance } from "./formatDistance"; +import i18next from "i18next"; // @ts-ignore -import translations from './translations/index.mjs'; +import translations from "./translations/index.mjs"; declare global { - interface Window { pageContent: Element; } + interface Window { + pageContent: Element; + } } - function onLoad(): void { document.body.innerHTML = ""; document.body.appendChild(NavBar()); - document.body.appendChild(makeElement({ - tag: "div", - class: ["uk-container", "uk-container-medium", "uk-align-center"], - children: makeElement({ + document.body.appendChild( + makeElement({ tag: "div", - class: ["uk-card", "uk-card-body"], - children: [ - makeElement({ - tag: "h3", - class: "uk-card-title", - id: "pageTitle", - text: "" - }), - makeElement({ - tag: "div", - id: "pageContent" - }) - ] - }) - })); + class: ["uk-container", "uk-container-medium", "uk-align-center"], + children: makeElement({ + tag: "div", + class: ["uk-card", "uk-card-body"], + children: [ + makeElement({ + tag: "h3", + class: "uk-card-title", + id: "pageTitle", + text: "", + }), + makeElement({ + tag: "div", + id: "pageContent", + }), + ], + }), + }), + ); window.pageContent = document.querySelector("#pageContent"); @@ -73,34 +73,45 @@ function onLoad(): void { setInterval(() => { if (pageState.currentPageString != "UNSEAL") { - if (pageState.apiURL.length != 0) { return; } + if (pageState.apiURL.length != 0) { + return; + } void getSealStatus().then((sealStatus) => { if (sealStatus.sealed) { changePage("UNSEAL"); return; - } + } }); } }, 5000); } -document.addEventListener('DOMContentLoaded', function () { - console.log("Loading..."); - // @ts-expect-error - console.log("Build Data:", BUILD_STRING); - 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: unknown, format, _): string { - if (format === 'until_date' && value instanceof Date) return formatDistance(new Date(), new Date(value)); - return value as string; - } - } - }).then(function (_) { - onLoad(); - }); -}, false); +document.addEventListener( + "DOMContentLoaded", + function () { + console.log("Loading..."); + // @ts-expect-error + console.log("Build Data:", BUILD_STRING); + 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: unknown, format, _): string { + if (format === "until_date" && value instanceof Date) + return formatDistance(new Date(), new Date(value)); + return value as string; + }, + }, + }) + .then(function (_) { + onLoad(); + }); + }, + false, +); diff --git a/src/pageUtils.ts b/src/pageUtils.ts index fbabdc8..bd47694 100644 --- a/src/pageUtils.ts +++ b/src/pageUtils.ts @@ -5,8 +5,8 @@ import { lookupSelf } from "./api/sys/lookupSelf"; import { makeElement } from "./htmlUtils"; import { pageState } from "./globalPageState"; import ClipboardJS from "clipboard"; -import UIkit from 'uikit'; -import i18next from 'i18next'; +import UIkit from "uikit"; +import i18next from "i18next"; async function prePageChecksReal() { if (pageState.language.length == 0) { @@ -27,7 +27,7 @@ async function prePageChecksReal() { try { await lookupSelf(); } catch (e) { - changePage("LOGIN") + changePage("LOGIN"); throw e; } } @@ -36,26 +36,29 @@ export async function prePageChecks(): Promise { try { await prePageChecksReal(); } catch (e) { - console.log("OHNO", e) + console.log("OHNO", e); return false; } return true; } export function addClipboardNotifications(clipboard: ClipboardJS, timeout = 1000): void { - clipboard.on('success', () => { + clipboard.on("success", () => { UIkit.notification(i18next.t("notification_copy_success"), { - status: 'success', - timeout: timeout + status: "success", + timeout: timeout, }); }); - clipboard.on('error', function (e: Error) { - UIkit.notification(i18next.t("notification_copy_error", { - "error": e.message - }), { - status: 'danger', - timeout: timeout - }); + clipboard.on("error", function (e: Error) { + UIkit.notification( + i18next.t("notification_copy_error", { + error: e.message, + }), + { + status: "danger", + timeout: timeout, + }, + ); }); } @@ -69,9 +72,9 @@ export function setErrorText(text: string): void { } UIkit.notification({ message: `Error: ${text}`, - status: 'danger', - pos: 'top-center', - timeout: 2000 + status: "danger", + pos: "top-center", + timeout: 2000, }); } @@ -88,13 +91,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") ).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") ); + const pageTitle = document.getElementById("pageTitle"); pageTitle.innerHTML = ""; if (typeof title === "string") { pageTitle.innerText = title.toString(); @@ -106,7 +109,8 @@ export function setPageTitle(title: string | HTMLElement): void { function currentTitleSecretText() { let currentSecretText = pageState.currentSecret; currentSecretText += (pageState.currentPage as Page).titleSuffix; - if (pageState.currentSecretVersion !== null) currentSecretText += ` (v${pageState.currentSecretVersion})`; + if (pageState.currentSecretVersion !== null) + currentSecretText += ` (v${pageState.currentSecretVersion})`; return currentSecretText; } @@ -122,14 +126,17 @@ export function setTitleElement(pageState: PageState): void { pageState.currentSecret = ""; pageState.currentSecretVersion = null; - if (pageState.currentMountType.startsWith("kv") || pageState.currentMountType == "cubbyhole") { + if ( + pageState.currentMountType.startsWith("kv") || + pageState.currentMountType == "cubbyhole" + ) { changePage("KEY_VALUE_VIEW"); } else if (pageState.currentMountType == "totp") { changePage("TOTP"); } else if (pageState.currentMountType == "transit") { changePage("TRANSIT_VIEW"); } - } + }, }), ...pageState.currentSecretPath.map(function (secretPath, index, secretPaths) { return makeElement({ @@ -141,25 +148,25 @@ export function setTitleElement(pageState: PageState): void { pageState.currentSecretPath = secretPaths.slice(0, index + 1); changePage("KEY_VALUE_VIEW"); } - } + }, }); }), makeElement({ tag: "span", condition: pageState.currentSecret.length != 0, - text: currentTitleSecretText() - }) - ] + text: currentTitleSecretText(), + }), + ], }); setPageTitle(titleElement); } export function setPageContent(content: string | HTMLElement): void { - const pageContent = (document.getElementById("pageContent") ); + const pageContent = document.getElementById("pageContent"); if (typeof content === "string") { pageContent.innerHTML = content; } else { pageContent.innerHTML = ""; pageContent.appendChild(content); } -} \ No newline at end of file +} diff --git a/src/pages/Home.ts b/src/pages/Home.ts index dbdda78..c25ee0a 100644 --- a/src/pages/Home.ts +++ b/src/pages/Home.ts @@ -5,7 +5,7 @@ import { lookupSelf } from "../api/sys/lookupSelf"; import { makeElement } from "../htmlUtils"; import { pageState } from "../globalPageState"; import { sortedObjectMap } from "../utils"; -import i18next from 'i18next'; +import i18next from "i18next"; export class HomePage extends Page { constructor() { @@ -15,7 +15,7 @@ export class HomePage extends Page { setPageContent(""); if (!(await prePageChecks())) return; - const homePageContent = makeElement({tag: "div"}); + const homePageContent = makeElement({ tag: "div" }); setPageContent(homePageContent); const textList = makeElement({ tag: "ul", @@ -25,8 +25,8 @@ export class HomePage extends Page { tag: "li", children: makeElement({ tag: "span", - html: i18next.t("vaulturl_text", {"text": pageState.apiURL}) - }) + html: i18next.t("vaulturl_text", { text: pageState.apiURL }), + }), }), makeElement({ tag: "li", @@ -35,19 +35,23 @@ export class HomePage extends Page { text: i18next.t("password_generator_btn"), onclick: () => { changePage("PW_GEN"); - } - }) - }) - ] + }, + }), + }), + ], }); homePageContent.appendChild(textList); try { const selfTokenInfo = await lookupSelf(); - textList.appendChild(makeElement({ - tag: "li", - text: i18next.t("your_token_expires_in", {"date": new Date(selfTokenInfo.expire_time)}) - })); + textList.appendChild( + makeElement({ + tag: "li", + text: i18next.t("your_token_expires_in", { + date: new Date(selfTokenInfo.expire_time), + }), + }), + ); } catch (e: unknown) { const error = e as Error; setErrorText(error.message); @@ -62,18 +66,21 @@ export class HomePage extends Page { pageState.currentSecret = ""; 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"], + }); homePageContent.appendChild(navList); 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); mountsMap.forEach(function (mount: MountType, baseMount) { - if (typeof mount != 'object') return; + if (typeof mount != "object") return; if (mount == null) return; if (!("type" in mount)) return; - if (!(["kv", "totp", "transit", "cubbyhole"].includes(mount.type))) return; + if (!["kv", "totp", "transit", "cubbyhole"].includes(mount.type)) return; const mountType = mount.type == "kv" ? "kv-v" + String(mount.options.version) : mount.type; @@ -85,29 +92,31 @@ export class HomePage extends Page { } else if (mount.type == "totp") { linkText = `TOTP - ${baseMount}`; linkPage = "TOTP"; - } else if (mount.type == "transit"){ + } else if (mount.type == "transit") { linkText = `Transit - ${baseMount}`; - linkPage = "TRANSIT_VIEW"; - } else if (mount.type == "cubbyhole"){ + linkPage = "TRANSIT_VIEW"; + } else if (mount.type == "cubbyhole") { linkText = `Cubbyhole - ${baseMount}`; - linkPage = "KEY_VALUE_VIEW"; + linkPage = "KEY_VALUE_VIEW"; } - navList.appendChild(makeElement({ - tag: "li", - children: makeElement({ - tag: "a", - text: linkText, - onclick: () => { - pageState.currentBaseMount = baseMount; - pageState.currentMountType = mountType; - changePage(linkPage); - } - }) - })); + navList.appendChild( + makeElement({ + tag: "li", + children: makeElement({ + tag: "a", + text: linkText, + onclick: () => { + pageState.currentBaseMount = baseMount; + pageState.currentMountType = mountType; + changePage(linkPage); + }, + }), + }), + ); }); } get name(): string { return i18next.t("home_page_title"); } -} \ No newline at end of file +} diff --git a/src/pages/KeyValue/KeyValueDelete.ts b/src/pages/KeyValue/KeyValueDelete.ts index 3d26fa6..21342ec 100644 --- a/src/pages/KeyValue/KeyValueDelete.ts +++ b/src/pages/KeyValue/KeyValueDelete.ts @@ -3,7 +3,7 @@ import { changePage, setPageContent, setTitleElement } from "../../pageUtils"; import { deleteSecret } from "../../api/kv/deleteSecret"; import { makeElement } from "../../htmlUtils"; import { pageState } from "../../globalPageState"; -import i18next from 'i18next'; +import i18next from "i18next"; export class KeyValueDeletePage extends Page { constructor() { @@ -20,31 +20,33 @@ export class KeyValueDeletePage extends Page { } render(): void { setTitleElement(pageState); - setPageContent(makeElement({ - tag: "div", - children: [ - makeElement({ - tag: "h5", - text: i18next.t("kv_delete_text") - }), - makeElement({ - tag: "button", - class: ["uk-button", "uk-button-danger"], - text: i18next.t("kv_delete_btn"), - onclick: () => { - void deleteSecret( - pageState.currentBaseMount, - pageState.currentMountType, - pageState.currentSecretPath, - pageState.currentSecret, - pageState.currentSecretVersion, - ).then(() => { - this.goBack(); - }); - } - }), - ] - })); + setPageContent( + makeElement({ + tag: "div", + children: [ + makeElement({ + tag: "h5", + text: i18next.t("kv_delete_text"), + }), + makeElement({ + tag: "button", + class: ["uk-button", "uk-button-danger"], + text: i18next.t("kv_delete_btn"), + onclick: () => { + void deleteSecret( + pageState.currentBaseMount, + pageState.currentMountType, + pageState.currentSecretPath, + pageState.currentSecret, + pageState.currentSecretVersion, + ).then(() => { + this.goBack(); + }); + }, + }), + ], + }), + ); } get titleSuffix(): string { return i18next.t("kv_delete_suffix"); @@ -52,4 +54,4 @@ export class KeyValueDeletePage extends Page { get name(): string { return i18next.t("kv_delete_title"); } -} \ No newline at end of file +} diff --git a/src/pages/KeyValue/KeyValueNew.ts b/src/pages/KeyValue/KeyValueNew.ts index 32872e1..9c88feb 100644 --- a/src/pages/KeyValue/KeyValueNew.ts +++ b/src/pages/KeyValue/KeyValueNew.ts @@ -3,7 +3,7 @@ import { changePage, setErrorText, setPageContent, setTitleElement } from "../.. import { createOrUpdateSecret } from "../../api/kv/createOrUpdateSecret"; import { makeElement } from "../../htmlUtils"; import { pageState } from "../../globalPageState"; -import i18next from 'i18next'; +import i18next from "i18next"; export class KeyValueNewPage extends Page { constructor() { @@ -32,14 +32,14 @@ export class KeyValueNewPage extends Page { required: "true", type: "text", placeholder: i18next.t("kv_new_path"), - name: "path" - } - }) + name: "path", + }, + }), }), makeElement({ tag: "p", id: "errorText", - class: "uk-text-danger" + class: "uk-text-danger", }), makeElement({ tag: "button", @@ -47,9 +47,9 @@ export class KeyValueNewPage extends Page { text: i18next.t("kv_new_create_btn"), attributes: { type: "submit", - } - }) - ] + }, + }), + ], }) as HTMLFormElement; setPageContent(this.addKVNewForm); @@ -65,7 +65,7 @@ export class KeyValueNewPage extends Page { let keyData = {}; if (["kv-v1", "cubbyhole"].includes(pageState.currentMountType)) { - keyData = { "key": "value" }; + keyData = { key: "value" }; } try { @@ -74,14 +74,13 @@ export class KeyValueNewPage extends Page { pageState.currentMountType, pageState.currentSecretPath, path, - keyData - ) + keyData, + ); changePage("KEY_VALUE_VIEW"); } catch (e: unknown) { const error = e as Error; setErrorText(error.message); } - } get titleSuffix(): string { @@ -91,4 +90,4 @@ export class KeyValueNewPage extends Page { get name(): string { return i18next.t("kv_new_title"); } -} \ No newline at end of file +} diff --git a/src/pages/KeyValue/KeyValueSecret.ts b/src/pages/KeyValue/KeyValueSecret.ts index d3ae64c..4ab8565 100644 --- a/src/pages/KeyValue/KeyValueSecret.ts +++ b/src/pages/KeyValue/KeyValueSecret.ts @@ -8,8 +8,7 @@ import { pageState } from "../../globalPageState"; import { sortedObjectMap } from "../../utils"; import { undeleteSecret } from "../../api/kv/undeleteSecret"; import Prism from "prismjs"; -import i18next from 'i18next'; - +import i18next from "i18next"; export class KeyValueSecretPage extends Page { constructor() { @@ -23,72 +22,86 @@ export class KeyValueSecretPage extends Page { pageState.currentSecret = ""; changePage("KEY_VALUE_VIEW"); } - } async render(): Promise { setTitleElement(pageState); - setPageContent(makeElement({ - tag: "div", - children: [ - makeElement({ - tag: "p", - id: "buttonsBlock" - }), - makeElement({ - tag: "p", - text: i18next.t("kv_secret_loading"), - id: "loadingText" - }), - makeElement({ - tag: "div", - id: "kvList" - }), - ] - })); + setPageContent( + makeElement({ + tag: "div", + children: [ + makeElement({ + tag: "p", + id: "buttonsBlock", + }), + makeElement({ + tag: "p", + text: i18next.t("kv_secret_loading"), + id: "loadingText", + }), + makeElement({ + tag: "div", + id: "kvList", + }), + ], + }), + ); const buttonsBlock = document.querySelector("#buttonsBlock"); const kvList = document.querySelector("#kvList"); let isSecretNestedJson = false; - const caps = await getCapabilities(pageState.currentBaseMount, pageState.currentSecretPath, pageState.currentSecret); + const caps = await getCapabilities( + pageState.currentBaseMount, + pageState.currentSecretPath, + pageState.currentSecret, + ); if (caps.includes("delete")) { let deleteButtonText = i18next.t("kv_secret_delete_btn"); if (pageState.currentMountType == "kv-v2" && pageState.currentSecretVersion == null) { deleteButtonText = i18next.t("kv_secret_delete_all_btn"); } else if (pageState.currentMountType == "kv-v2" && pageState.currentSecretVersion != null) { - deleteButtonText = i18next.t( - "kv_secret_delete_version_btn", - { - "version": pageState.currentSecretVersion - } - ); + deleteButtonText = i18next.t("kv_secret_delete_version_btn", { + version: pageState.currentSecretVersion, + }); } - buttonsBlock.appendChild(makeElement({ - tag: "button", - id: "deleteButton", - class: ["uk-button", "uk-button-danger"], - onclick: () => { changePage("KEY_VALUE_DELETE"); }, - text: deleteButtonText - })); + buttonsBlock.appendChild( + makeElement({ + tag: "button", + id: "deleteButton", + class: ["uk-button", "uk-button-danger"], + onclick: () => { + changePage("KEY_VALUE_DELETE"); + }, + text: deleteButtonText, + }), + ); } if (caps.includes("update")) { if (pageState.currentSecretVersion == null) { - buttonsBlock.appendChild(makeElement({ - tag: "button", - id: "editButton", - class: ["uk-button", "uk-margin", "uk-button-primary"], - onclick: () => { changePage("KEY_VALUE_SECRET_EDIT"); }, - text: i18next.t("kv_secret_edit_btn") - })); + buttonsBlock.appendChild( + makeElement({ + tag: "button", + id: "editButton", + class: ["uk-button", "uk-margin", "uk-button-primary"], + onclick: () => { + changePage("KEY_VALUE_SECRET_EDIT"); + }, + text: i18next.t("kv_secret_edit_btn"), + }), + ); } } if (pageState.currentMountType == "kv-v2") { - buttonsBlock.appendChild(makeElement({ - tag: "button", - id: "versionsButton", - class: ["uk-button", "uk-button-secondary"], - onclick: () => { changePage("KEY_VALUE_VERSIONS"); }, - text: i18next.t("kv_secret_versions_btn") - })); + buttonsBlock.appendChild( + makeElement({ + tag: "button", + id: "versionsButton", + class: ["uk-button", "uk-button-secondary"], + onclick: () => { + changePage("KEY_VALUE_VERSIONS"); + }, + text: i18next.t("kv_secret_versions_btn"), + }), + ); } void getSecret( @@ -96,53 +109,59 @@ export class KeyValueSecretPage extends Page { pageState.currentMountType, pageState.currentSecretPath, pageState.currentSecret, - pageState.currentSecretVersion - ).then(secretInfo => { + pageState.currentSecretVersion, + ).then((secretInfo) => { if (secretInfo == null && pageState.currentMountType == "kv-v2") { document.querySelector("#buttonsBlock").remove(); document.getElementById("loadingText").remove(); - kvList.appendChild(makeElement({ - tag: "p", - text: i18next.t("kv_secret_deleted_text") - })); + kvList.appendChild( + makeElement({ + tag: "p", + text: i18next.t("kv_secret_deleted_text"), + }), + ); - kvList.appendChild(makeElement({ - tag: "button", - text: i18next.t("kv_secret_restore_btn"), - id: "restoreButton", - class: ["uk-button", "uk-button-primary"], - onclick: () => { - void undeleteSecret( - pageState.currentBaseMount, - pageState.currentSecretPath, - pageState.currentSecret, - pageState.currentSecretVersion - ).then(_ => { - changePage(pageState.currentPageString); - }); - }, - })); + kvList.appendChild( + makeElement({ + tag: "button", + text: i18next.t("kv_secret_restore_btn"), + id: "restoreButton", + class: ["uk-button", "uk-button-primary"], + onclick: () => { + void undeleteSecret( + pageState.currentBaseMount, + pageState.currentSecretPath, + pageState.currentSecret, + pageState.currentSecretVersion, + ).then((_) => { + changePage(pageState.currentPageString); + }); + }, + }), + ); return; } const secretsMap = sortedObjectMap(secretInfo); for (const value of secretsMap.values()) { - if (typeof value == 'object') isSecretNestedJson = true; + if (typeof value == "object") isSecretNestedJson = true; } if (isSecretNestedJson) { const jsonText = JSON.stringify( sortedObjectMap(secretsMap as unknown as Record), null, - 4 + 4, + ); + kvList.appendChild( + makeElement({ + tag: "pre", + class: ["code-block", "language-json", "line-numbers"], + html: Prism.highlight(jsonText, Prism.languages.json, "json"), + }), ); - kvList.appendChild(makeElement({ - tag: "pre", - class: ["code-block", "language-json", "line-numbers"], - html: Prism.highlight(jsonText, Prism.languages.json, 'json') - })); } else { secretsMap.forEach((value: string, key: string) => { const kvListElement = this.makeKVListElement(key, value); @@ -156,11 +175,11 @@ export class KeyValueSecretPage extends Page { return makeElement({ tag: "div", class: ["uk-grid", "uk-grid-small", "uk-text-left"], - children: [CopyableInputBox(key), CopyableInputBox(value)] + children: [CopyableInputBox(key), CopyableInputBox(value)], }); } get name(): string { return i18next.t("kv_secret_title"); } -} \ No newline at end of file +} diff --git a/src/pages/KeyValue/KeyValueSecretsEdit.ts b/src/pages/KeyValue/KeyValueSecretsEdit.ts index 95798c5..b6ffe92 100644 --- a/src/pages/KeyValue/KeyValueSecretsEdit.ts +++ b/src/pages/KeyValue/KeyValueSecretsEdit.ts @@ -6,7 +6,7 @@ import { getSecret } from "../../api/kv/getSecret"; import { makeElement } from "../../htmlUtils"; import { pageState } from "../../globalPageState"; import { sortedObjectMap, verifyJSONString } from "../../utils"; -import i18next from 'i18next'; +import i18next from "i18next"; export class KeyValueSecretEditPage extends Page { constructor() { @@ -19,41 +19,43 @@ export class KeyValueSecretEditPage extends Page { setTitleElement(pageState); const loadingText = makeElement({ tag: "p", - text: i18next.t("kv_sec_edit_loading") + text: i18next.t("kv_sec_edit_loading"), }); const editor = makeElement({ tag: "div", - class: ["editor", "language-json"] + class: ["editor", "language-json"], }); const saveButton = makeElement({ tag: "button", class: ["uk-button", "uk-button-primary"], - text: i18next.t("kv_sec_edit_btn") + text: i18next.t("kv_sec_edit_btn"), }); - setPageContent(makeElement({ - tag: "div", - children: [ - loadingText, - editor, - makeElement({ - tag: "p", - id: "errorText", - class: ["uk-text-danger", "uk-margin-top"] - }), - saveButton - ] - })); + setPageContent( + makeElement({ + tag: "div", + children: [ + loadingText, + editor, + makeElement({ + tag: "p", + id: "errorText", + class: ["uk-text-danger", "uk-margin-top"], + }), + saveButton, + ], + }), + ); void getSecret( pageState.currentBaseMount, pageState.currentMountType, pageState.currentSecretPath, pageState.currentSecret, - ).then(secretInfo => { + ).then((secretInfo) => { loadingText.remove(); const secretsJSON = JSON.stringify(sortedObjectMap(secretInfo), null, 4); - const jar = CodeJar(editor, () => { }, { tab: ' '.repeat(4) }); + const jar = CodeJar(editor, () => {}, { tab: " ".repeat(4) }); jar.updateCode(secretsJSON); saveButton.onclick = function () { if (!verifyJSONString(jar.toString())) { @@ -66,13 +68,15 @@ export class KeyValueSecretEditPage extends Page { pageState.currentMountType, pageState.currentSecretPath, pageState.currentSecret, - JSON.parse(jar.toString()) - ).then(_ => { - changePage("KEY_VALUE_SECRET"); - return; - }).catch((e: Error) => { - setErrorText(e.message); - }); + JSON.parse(jar.toString()), + ) + .then((_) => { + changePage("KEY_VALUE_SECRET"); + return; + }) + .catch((e: Error) => { + setErrorText(e.message); + }); }; }); } @@ -84,4 +88,4 @@ export class KeyValueSecretEditPage extends Page { get name(): string { return i18next.t("kv_sec_edit_title"); } -} \ No newline at end of file +} diff --git a/src/pages/KeyValue/KeyValueVersions.ts b/src/pages/KeyValue/KeyValueVersions.ts index 627b83e..08bcc01 100644 --- a/src/pages/KeyValue/KeyValueVersions.ts +++ b/src/pages/KeyValue/KeyValueVersions.ts @@ -4,8 +4,7 @@ import { getSecretMetadata } from "../../api/kv/getSecretMetadata"; import { makeElement } from "../../htmlUtils"; import { objectToMap } from "../../utils"; import { pageState } from "../../globalPageState"; -import i18next from 'i18next'; - +import i18next from "i18next"; export class KeyValueVersionsPage extends Page { constructor() { @@ -23,28 +22,30 @@ export class KeyValueVersionsPage extends Page { const versionsList = makeElement({ tag: "ul", id: "versionsList", - class: ["uk-nav", "uk-nav-default"] + class: ["uk-nav", "uk-nav-default"], }); setPageContent(versionsList); const metadata = await getSecretMetadata( pageState.currentBaseMount, pageState.currentSecretPath, - pageState.currentSecret + pageState.currentSecret, ); objectToMap(metadata.versions).forEach((_, ver) => { - versionsList.appendChild(makeElement({ - tag: "li", - children: makeElement({ - tag: "a", - text: `v${ver}`, - onclick: () => { - pageState.currentSecretVersion = ver; - changePage("KEY_VALUE_SECRET"); - } - }) - })); + versionsList.appendChild( + makeElement({ + tag: "li", + children: makeElement({ + tag: "a", + text: `v${ver}`, + onclick: () => { + pageState.currentSecretVersion = ver; + changePage("KEY_VALUE_SECRET"); + }, + }), + }), + ); }); } @@ -55,4 +56,4 @@ export class KeyValueVersionsPage extends Page { get name(): string { return i18next.t("kv_sec_versions_title"); } -} \ No newline at end of file +} diff --git a/src/pages/KeyValue/KeyValueView.ts b/src/pages/KeyValue/KeyValueView.ts index 10892da..1c02489 100644 --- a/src/pages/KeyValue/KeyValueView.ts +++ b/src/pages/KeyValue/KeyValueView.ts @@ -4,8 +4,7 @@ import { changePage, setErrorText, setPageContent, setTitleElement } from "../.. import { getSecrets } from "../../api/kv/getSecrets"; import { makeElement } from "../../htmlUtils"; import { pageState } from "../../globalPageState"; -import i18next from 'i18next'; - +import i18next from "i18next"; export class KeyValueViewPage extends Page { constructor() { @@ -28,10 +27,12 @@ export class KeyValueViewPage extends Page { setPageContent(kvViewPageContent); if (pageState.currentMountType == "cubbyhole") { - kvViewPageContent.appendChild(makeElement({ - tag: "p", - text: i18next.t("kv_view_cubbyhole_text"), - })); + kvViewPageContent.appendChild( + makeElement({ + tag: "p", + text: i18next.t("kv_view_cubbyhole_text"), + }), + ); } const newButton = makeElement({ @@ -40,7 +41,7 @@ export class KeyValueViewPage extends Page { class: ["uk-button", "uk-button-primary", "uk-margin-bottom"], onclick: () => { changePage("KEY_VALUE_NEW_SECRET"); - } + }, }); kvViewPageContent.appendChild(newButton); @@ -51,30 +52,32 @@ export class KeyValueViewPage extends Page { pageState.currentSecretPath, ); - kvViewPageContent.appendChild(makeElement({ - tag: "ul", - class: ["uk-nav", "uk-nav-default"], - children: [ - ...res.map(function (secret) { - return makeElement({ - tag: "li", - children: makeElement({ - tag: "a", - text: secret, - onclick: () => { - if (secret.endsWith("/")) { - pageState.pushCurrentSecretPath(secret); - changePage("KEY_VALUE_VIEW"); - } else { - pageState.currentSecret = secret; - changePage("KEY_VALUE_SECRET"); - } - } - }) - }); - }) - ] - })); + kvViewPageContent.appendChild( + makeElement({ + tag: "ul", + class: ["uk-nav", "uk-nav-default"], + children: [ + ...res.map(function (secret) { + return makeElement({ + tag: "li", + children: makeElement({ + tag: "a", + text: secret, + onclick: () => { + if (secret.endsWith("/")) { + pageState.pushCurrentSecretPath(secret); + changePage("KEY_VALUE_VIEW"); + } else { + pageState.currentSecret = secret; + changePage("KEY_VALUE_SECRET"); + } + }, + }), + }); + }), + ], + }), + ); } catch (e: unknown) { const error = e as Error; if (error == DoesNotExistError) { @@ -82,10 +85,12 @@ export class KeyValueViewPage extends Page { if (pageState.currentSecretPath.length != 0) { return this.goBack(); } else { - kvViewPageContent.appendChild(makeElement({ - tag: "p", - text: i18next.t("kv_view_none_here_text") - })); + kvViewPageContent.appendChild( + makeElement({ + tag: "p", + text: i18next.t("kv_view_none_here_text"), + }), + ); } } else { setErrorText(error.message); diff --git a/src/pages/Login.ts b/src/pages/Login.ts index 8451e96..7fc44ab 100644 --- a/src/pages/Login.ts +++ b/src/pages/Login.ts @@ -6,7 +6,7 @@ import { lookupSelf } from "../api/sys/lookupSelf"; import { makeElement } from "../htmlUtils"; import { pageState } from "../globalPageState"; import { usernameLogin } from "../api/auth/usernameLogin"; -import i18next from 'i18next'; +import i18next from "i18next"; export class LoginPage extends Page { constructor() { @@ -16,144 +16,157 @@ export class LoginPage extends Page { const tokenLoginForm = makeElement({ tag: "form", children: [ - Margin(makeElement({ - tag: "input", - class: ["uk-input", "uk-form-width-medium"], - attributes: { - required: "true", - type: "password", - placeholder: i18next.t("token_input"), - name: "token" - } - })), - MarginInline(makeElement({ - tag: "button", - class: ["uk-button", "uk-button-primary"], - text: i18next.t("log_in_btn"), - attributes: { - type: "submit" - } - })) - ] + Margin( + makeElement({ + tag: "input", + class: ["uk-input", "uk-form-width-medium"], + attributes: { + required: "true", + type: "password", + placeholder: i18next.t("token_input"), + name: "token", + }, + }), + ), + MarginInline( + makeElement({ + tag: "button", + class: ["uk-button", "uk-button-primary"], + text: i18next.t("log_in_btn"), + attributes: { + type: "submit", + }, + }), + ), + ], }) as HTMLFormElement; const usernameLoginForm = makeElement({ tag: "form", children: [ - Margin(makeElement({ - tag: "input", - id: "usernameInput", - class: ["uk-input", "uk-form-width-medium"], - attributes: { - required: "true", - type: "text", - placeholder: i18next.t("username_input"), - name: "username" - } - })), - Margin(makeElement({ - tag: "input", - id: "passwordInput", - class: ["uk-input", "uk-form-width-medium"], - attributes: { - required: "true", - type: "password", - placeholder: i18next.t("password_input"), - name: "password" - } - })), - MarginInline(makeElement({ - tag: "button", - class: ["uk-button", "uk-button-primary"], - text: i18next.t("log_in_btn"), - attributes: { - type: "submit" - } - })) - ] + Margin( + makeElement({ + tag: "input", + id: "usernameInput", + class: ["uk-input", "uk-form-width-medium"], + attributes: { + required: "true", + type: "text", + placeholder: i18next.t("username_input"), + name: "username", + }, + }), + ), + Margin( + makeElement({ + tag: "input", + id: "passwordInput", + class: ["uk-input", "uk-form-width-medium"], + attributes: { + required: "true", + type: "password", + placeholder: i18next.t("password_input"), + name: "password", + }, + }), + ), + MarginInline( + makeElement({ + tag: "button", + class: ["uk-button", "uk-button-primary"], + text: i18next.t("log_in_btn"), + attributes: { + type: "submit", + }, + }), + ), + ], }) as HTMLFormElement; - setPageContent(makeElement({ - tag: "div", - children: [ - makeElement({ - tag: "ul", - class: ["uk-subnav", "uk-subnav-pill"], - attributes: { "uk-switcher": "" }, - children: [ - makeElement({ - tag: "li", - id: "tokenInput", - children: makeElement({ - tag: "a", - text: i18next.t("log_in_with_token") - }) - }), - makeElement({ - tag: "li", - children: makeElement({ - tag: "a", - text: i18next.t("log_in_with_username") - }) - }) - ] - }), - makeElement({ - tag: "p", - id: "errorText", - class: "uk-text-danger" - }), - makeElement({ - tag: "ul", - class: ["uk-switcher", "uk-margin"], - children: [ - makeElement({ - tag: "li", - children: tokenLoginForm - }), - makeElement({ - tag: "li", - children: usernameLoginForm - }) - ] - }) - ] - })); + setPageContent( + makeElement({ + tag: "div", + children: [ + makeElement({ + tag: "ul", + class: ["uk-subnav", "uk-subnav-pill"], + attributes: { "uk-switcher": "" }, + children: [ + makeElement({ + tag: "li", + id: "tokenInput", + children: makeElement({ + tag: "a", + text: i18next.t("log_in_with_token"), + }), + }), + makeElement({ + tag: "li", + children: makeElement({ + tag: "a", + text: i18next.t("log_in_with_username"), + }), + }), + ], + }), + makeElement({ + tag: "p", + id: "errorText", + class: "uk-text-danger", + }), + makeElement({ + tag: "ul", + class: ["uk-switcher", "uk-margin"], + children: [ + makeElement({ + tag: "li", + children: tokenLoginForm, + }), + makeElement({ + tag: "li", + children: usernameLoginForm, + }), + ], + }), + ], + }), + ); tokenLoginForm.addEventListener("submit", function (e) { e.preventDefault(); const formData = new FormData(tokenLoginForm); const token = formData.get("token"); pageState.token = token as string; - lookupSelf().then(_ => { - changePage("HOME"); - }).catch((e: Error) => { - document.getElementById("tokenInput").classList.add("uk-form-danger"); - if (e.message == "permission denied") { - setErrorText(i18next.t("token_login_error")); - } else { - setErrorText(e.message); - } - }); + lookupSelf() + .then((_) => { + changePage("HOME"); + }) + .catch((e: Error) => { + document.getElementById("tokenInput").classList.add("uk-form-danger"); + if (e.message == "permission denied") { + setErrorText(i18next.t("token_login_error")); + } else { + setErrorText(e.message); + } + }); }); usernameLoginForm.addEventListener("submit", function (e) { e.preventDefault(); const formData = new FormData(usernameLoginForm); - usernameLogin( - formData.get("username") as string, - formData.get("password") as string, - ).then(res => { - pageState.token = res; - changePage("HOME"); - }).catch((e: Error) => { - document.getElementById("usernameInput").classList.add("uk-form-danger"); - document.getElementById("passwordInput").classList.add("uk-form-danger"); - setErrorText(e.message); - }); + usernameLogin(formData.get("username") as string, formData.get("password") as string) + .then((res) => { + pageState.token = res; + changePage("HOME"); + }) + .catch((e: Error) => { + document.getElementById("usernameInput").classList.add("uk-form-danger"); + document.getElementById("passwordInput").classList.add("uk-form-danger"); + setErrorText(e.message); + }); }); } get name(): string { return i18next.t("log_in_title"); } -} \ No newline at end of file +} diff --git a/src/pages/Me.ts b/src/pages/Me.ts index a5fc400..748e2c9 100644 --- a/src/pages/Me.ts +++ b/src/pages/Me.ts @@ -1,13 +1,18 @@ 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/sys/getCapabilities"; import { makeElement } from "../htmlUtils"; import { pageState } from "../globalPageState"; import { renewSelf } from "../api/sys/renewSelf"; import { sealVault } from "../api/sys/sealVault"; import ClipboardJS from "clipboard"; -import i18next from 'i18next'; - +import i18next from "i18next"; export class MePage extends Page { constructor() { @@ -16,80 +21,84 @@ export class MePage extends Page { async render(): Promise { if (!(await prePageChecks())) return; - setPageContent(makeElement({ - tag: "ul", - class: "uk-nav", - children: [ - makeElement({ - tag: "li", - children: makeElement({ - tag: "a", - text: i18next.t("log_out_btn"), - onclick: () => { - pageState.token = ""; - changePage("HOME"); - } - }) - }), - makeElement({ - tag: "li", - children: makeElement({ - tag: "a", - text: i18next.t("copy_token_btn"), - attributes: { - "data-clipboard-text": pageState.token, - }, - thenRun: (e) => { - const clipboard = new ClipboardJS(e); - addClipboardNotifications(clipboard); - } - }) - }), - makeElement({ - tag: "li", - children: makeElement({ - tag: "a", - text: i18next.t("renew_lease_btn"), - onclick: () => { - renewSelf().then(() => { + setPageContent( + makeElement({ + tag: "ul", + class: "uk-nav", + children: [ + makeElement({ + tag: "li", + children: makeElement({ + tag: "a", + text: i18next.t("log_out_btn"), + onclick: () => { + pageState.token = ""; changePage("HOME"); - }).catch((e: Error) => { - setErrorText(e.message); - }); - } - }) - }), - makeElement({ - tag: "li", - children: makeElement({ - tag: "a", - condition: await (async () => { - try { - const caps = await getCapabilitiesPath("sys/seal"); - return caps.includes("sudo") && caps.includes("update"); - } catch (e) { - return !true; - } - })(), - text: i18next.t("seal_vault_btn"), - onclick: async () => { - await sealVault(); - changePage("UNSEAL_VAULT"); - } - }) - }), - makeElement({ - tag: "li", - children: makeElement({ - tag: "a", - text: i18next.t("change_language_btn"), - onclick: () => { - changePage("SET_LANGUAGE"); - } - }) - }), - ] - })); + }, + }), + }), + makeElement({ + tag: "li", + children: makeElement({ + tag: "a", + text: i18next.t("copy_token_btn"), + attributes: { + "data-clipboard-text": pageState.token, + }, + thenRun: (e) => { + const clipboard = new ClipboardJS(e); + addClipboardNotifications(clipboard); + }, + }), + }), + makeElement({ + tag: "li", + children: makeElement({ + tag: "a", + text: i18next.t("renew_lease_btn"), + onclick: () => { + renewSelf() + .then(() => { + changePage("HOME"); + }) + .catch((e: Error) => { + setErrorText(e.message); + }); + }, + }), + }), + makeElement({ + tag: "li", + children: makeElement({ + tag: "a", + condition: await (async () => { + try { + const caps = await getCapabilitiesPath("sys/seal"); + return caps.includes("sudo") && caps.includes("update"); + } catch (e) { + return !true; + } + })(), + text: i18next.t("seal_vault_btn"), + onclick: async () => { + await sealVault(); + changePage("UNSEAL_VAULT"); + }, + }), + }), + makeElement({ + tag: "li", + children: makeElement({ + tag: "a", + text: i18next.t("change_language_btn"), + onclick: () => { + changePage("SET_LANGUAGE"); + }, + }), + }), + ], + }), + ); } get name(): string { diff --git a/src/pages/PwGen.ts b/src/pages/PwGen.ts index 46158fc..80c63e5 100644 --- a/src/pages/PwGen.ts +++ b/src/pages/PwGen.ts @@ -4,40 +4,43 @@ import { Option } from "../elements/Option"; import { Page } from "../types/Page"; import { makeElement } from "../htmlUtils"; import { setPageContent } from "../pageUtils"; -import i18next from 'i18next'; +import i18next from "i18next"; const passwordLengthMin = 1; const passwordLengthMax = 64; const passwordLengthDefault = 24; function random() { - if (typeof window.crypto?.getRandomValues === 'function' && typeof window.Uint32Array === 'function') { + if ( + typeof window.crypto?.getRandomValues === "function" && + typeof window.Uint32Array === "function" + ) { return window.crypto.getRandomValues(new Uint32Array(1))[0] / 4294967295; } return Math.random(); } -const lowerCase = 'abcdefghijklmnopqrstuvwxyz'; -const upperCase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; -const numbers = '1234567890'; -const special = '!#$%&()*+,-./:;<=>?@[]^_{|}~'; +const lowerCase = "abcdefghijklmnopqrstuvwxyz"; +const upperCase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; +const numbers = "1234567890"; +const special = "!#$%&()*+,-./:;<=>?@[]^_{|}~"; const alphabets = { SECURE: lowerCase + upperCase + numbers + special, SMOL: lowerCase + numbers, - HEX: '123456789ABCDEF', -} + HEX: "123456789ABCDEF", +}; const passwordOptionsDefault = { length: passwordLengthDefault, alphabet: alphabets.SECURE, -} +}; function genPassword(options = passwordOptionsDefault) { let pw = ""; - options = { ...passwordOptionsDefault, ...options } - const pwArray = options.alphabet.split(''); + options = { ...passwordOptionsDefault, ...options }; + const pwArray = options.alphabet.split(""); for (let i = 0; i < options.length; i++) { pw = pw.concat(pwArray[Math.floor(random() * pwArray.length)]); } @@ -57,11 +60,11 @@ export class PwGenPage extends Page { render(): void { setPageContent(""); - this.passwordBox = CopyableInputBox(genPassword(passwordOptionsDefault)) ; + this.passwordBox = CopyableInputBox(genPassword(passwordOptionsDefault)); this.passwordLengthTitle = makeElement({ tag: "h4", - text: this.getPasswordLengthText() + text: this.getPasswordLengthText(), }) as HTMLTitleElement; this.passwordLengthRange = makeElement({ @@ -76,7 +79,7 @@ export class PwGenPage extends Page { }, }) as HTMLInputElement; - this.passwordLengthRange.addEventListener('input', this.updatePassword.bind(this)); + this.passwordLengthRange.addEventListener("input", this.updatePassword.bind(this)); this.passwordAlphabet = makeElement({ tag: "select", @@ -85,7 +88,7 @@ export class PwGenPage extends Page { Option("a-z a-Z 0-9 specials", alphabets.SECURE), Option("a-z 0-9", alphabets.SMOL), Option("A-F 1-9", alphabets.HEX), - ] + ], }) as HTMLSelectElement; this.passwordForm = makeElement({ @@ -95,13 +98,15 @@ export class PwGenPage extends Page { Margin(this.passwordLengthRange), Margin(this.passwordAlphabet), Margin(this.passwordBox), - Margin(makeElement({ - tag: "button", - text: i18next.t("gen_password_btn"), - class: ["uk-button", "uk-button-primary", "uk-margin-bottom"], - attributes: { type: "submit" }, - })) - ] + Margin( + makeElement({ + tag: "button", + text: i18next.t("gen_password_btn"), + class: ["uk-button", "uk-button-primary", "uk-margin-bottom"], + attributes: { type: "submit" }, + }), + ), + ], }) as HTMLFormElement; this.passwordForm.addEventListener("submit", (e) => this.formEvent(e)); @@ -111,7 +116,7 @@ export class PwGenPage extends Page { getPasswordLengthText(): string { return i18next.t("password_length_title", { min: this?.passwordLengthRange?.value || 24, - max: passwordLengthMax + max: passwordLengthMax, }); } @@ -122,10 +127,12 @@ export class PwGenPage extends Page { updatePassword(): void { this.passwordLengthTitle.innerText = this.getPasswordLengthText(); - this.passwordBox.setText(genPassword({ - length: (this.passwordLengthRange.value as unknown) as number, - alphabet: this.passwordAlphabet.value , - })); + this.passwordBox.setText( + genPassword({ + length: this.passwordLengthRange.value as unknown as number, + alphabet: this.passwordAlphabet.value, + }), + ); } cleanup(): void { @@ -139,4 +146,4 @@ export class PwGenPage extends Page { get name(): string { return i18next.t("password_generator_title"); } -} \ No newline at end of file +} diff --git a/src/pages/SetLanguage.ts b/src/pages/SetLanguage.ts index 3477366..fd10999 100644 --- a/src/pages/SetLanguage.ts +++ b/src/pages/SetLanguage.ts @@ -3,8 +3,8 @@ import { Page } from "../types/Page"; import { changePage, setPageContent } from "../pageUtils"; import { makeElement } from "../htmlUtils"; import { pageState } from "../globalPageState"; -import i18next from 'i18next'; import { reloadNavBar } from "../elements/NavBar"; +import i18next from "i18next"; // @ts-ignore import translations from "../translations/index.mjs"; @@ -20,25 +20,26 @@ export class SetLanguagePage extends Page { tag: "form", id: "setLanguageForm", children: [ - Margin(makeElement({ - tag: "select", - class: ["uk-select", "uk-form-width-large"], - attributes: { - name: "language" - }, - children: languageIDs.map(function (languageID) { - return makeElement({ - tag: "option", - text: i18next.getFixedT(languageID, null)("language_name"), - attributes: { value: languageID } - }) - }) - }) + Margin( + makeElement({ + tag: "select", + class: ["uk-select", "uk-form-width-large"], + attributes: { + name: "language", + }, + children: languageIDs.map(function (languageID) { + return makeElement({ + tag: "option", + text: i18next.getFixedT(languageID, null)("language_name"), + attributes: { value: languageID }, + }); + }), + }), ), makeElement({ tag: "p", id: "errorText", - class: "uk-text-danger" + class: "uk-text-danger", }), makeElement({ tag: "button", @@ -46,9 +47,9 @@ export class SetLanguagePage extends Page { text: i18next.t("set_language_btn"), attributes: { type: "submit", - } - }) - ] + }, + }), + ], }) as HTMLFormElement; setPageContent(setLanguageForm); setLanguageForm.addEventListener("submit", function (e) { diff --git a/src/pages/SetVaultURL.ts b/src/pages/SetVaultURL.ts index 586fa4c..f03ca51 100644 --- a/src/pages/SetVaultURL.ts +++ b/src/pages/SetVaultURL.ts @@ -8,42 +8,44 @@ export class SetVaultURLPage extends Page { super(); } render(): void { - setPageContent(makeElement({ - tag: "form", - id: "setVaultURLForm", - children: [ - makeElement({ - tag: "div", - class: "uk-margin", - children: makeElement({ - tag: "input", - class: ["uk-input", "uk-form-width-medium"], + setPageContent( + makeElement({ + tag: "form", + id: "setVaultURLForm", + children: [ + makeElement({ + tag: "div", + class: "uk-margin", + children: makeElement({ + tag: "input", + class: ["uk-input", "uk-form-width-medium"], + attributes: { + required: "true", + type: "text", + placeholder: "Vault URL", + name: "vaultURL", + }, + }), + }), + makeElement({ + tag: "p", + id: "errorText", + class: "uk-text-danger", + }), + makeElement({ + tag: "button", + class: ["uk-button", "uk-button-primary"], + text: "Set", attributes: { - required: "true", - type: "text", - placeholder: "Vault URL", - name: "vaultURL" - } - }) - }), - makeElement({ - tag: "p", - id: "errorText", - class: "uk-text-danger" - }), - makeElement({ - tag: "button", - class: ["uk-button", "uk-button-primary"], - text: "Set", - attributes: { - type: "submit", - } - }) - ] - })); + type: "submit", + }, + }), + ], + }), + ); document.getElementById("setVaultURLForm").addEventListener("submit", function (e) { e.preventDefault(); - const formData = new FormData(document.querySelector('#setVaultURLForm')); + const formData = new FormData(document.querySelector("#setVaultURLForm")); pageState.apiURL = formData.get("vaultURL") as string; changePage("HOME"); }); diff --git a/src/pages/TOTP/NewTOTP.ts b/src/pages/TOTP/NewTOTP.ts index dbf8158..1f783b3 100644 --- a/src/pages/TOTP/NewTOTP.ts +++ b/src/pages/TOTP/NewTOTP.ts @@ -5,10 +5,10 @@ import { addNewTOTP } from "../../api/totp/addNewTOTP"; import { changePage, setErrorText, setPageContent, setTitleElement } from "../../pageUtils"; import { makeElement } from "../../htmlUtils"; import { pageState } from "../../globalPageState"; -import i18next from 'i18next'; +import i18next from "i18next"; function replaceAll(str: string, replace: string, replaceWith: string): string { - return str.replace(new RegExp(replace, 'g'), replaceWith); + return str.replace(new RegExp(replace, "g"), replaceWith); } function removeDashSpaces(str: string): string { str = replaceAll(str, "-", ""); @@ -29,52 +29,60 @@ export class NewTOTPPage extends Page { const totpForm = makeElement({ tag: "form", children: [ - Margin(makeElement({ - tag: "input", - class: ["uk-input", "uk-form-width-medium"], - attributes: { - required: "true", - type: "text", - placeholder: i18next.t("totp_new_name_text"), - name: "name" - } - })), + Margin( + makeElement({ + tag: "input", + class: ["uk-input", "uk-form-width-medium"], + attributes: { + required: "true", + type: "text", + placeholder: i18next.t("totp_new_name_text"), + name: "name", + }, + }), + ), makeElement({ tag: "p", - text: i18next.t("totp_new_info") + text: i18next.t("totp_new_info"), }), - Margin(makeElement({ - tag: "input", - class: ["uk-input", "uk-form-width-medium"], - attributes: { - type: "text", - placeholder: i18next.t("totp_new_uri_input"), - name: "uri" - } - })), - Margin(makeElement({ - tag: "input", - class: ["uk-input", "uk-form-width-medium"], - attributes: { - type: "text", - placeholder: i18next.t("totp_new_key_input"), - name: "key" - } - })), + Margin( + makeElement({ + tag: "input", + class: ["uk-input", "uk-form-width-medium"], + attributes: { + type: "text", + placeholder: i18next.t("totp_new_uri_input"), + name: "uri", + }, + }), + ), + Margin( + makeElement({ + tag: "input", + class: ["uk-input", "uk-form-width-medium"], + attributes: { + type: "text", + placeholder: i18next.t("totp_new_key_input"), + name: "key", + }, + }), + ), makeElement({ tag: "p", id: "errorText", - class: "uk-text-danger" + class: "uk-text-danger", }), - MarginInline(makeElement({ - tag: "button", - class: ["uk-button", "uk-button-primary"], - text: i18next.t("totp_new_add_btn"), - attributes: { - type: "submit" - } - })) - ] + MarginInline( + makeElement({ + tag: "button", + class: ["uk-button", "uk-button-primary"], + text: i18next.t("totp_new_add_btn"), + attributes: { + type: "submit", + }, + }), + ), + ], }) as HTMLFormElement; setPageContent(totpForm); @@ -85,13 +93,15 @@ export class NewTOTPPage extends Page { url: formData.get("uri") as string, key: removeDashSpaces(formData.get("key") as string).toUpperCase(), name: formData.get("name") as string, - generate: false + generate: false, }; - addNewTOTP(pageState.currentBaseMount, parms).then(_ => { - changePage("TOTP"); - }).catch((e: Error) => { - setErrorText(`API Error: ${e.message}`); - }); + addNewTOTP(pageState.currentBaseMount, parms) + .then((_) => { + changePage("TOTP"); + }) + .catch((e: Error) => { + setErrorText(`API Error: ${e.message}`); + }); }); } @@ -102,4 +112,4 @@ export class NewTOTPPage extends Page { get name(): string { return i18next.t("totp_new_title"); } -} \ No newline at end of file +} diff --git a/src/pages/TOTP/TOTPView.ts b/src/pages/TOTP/TOTPView.ts index 94be27e..29539b1 100644 --- a/src/pages/TOTP/TOTPView.ts +++ b/src/pages/TOTP/TOTPView.ts @@ -7,13 +7,12 @@ import { getTOTPKeys } from "../../api/totp/getTOTPKeys"; import { makeElement } from "../../htmlUtils"; import { objectToMap } from "../../utils"; import { pageState } from "../../globalPageState"; -import i18next from 'i18next'; +import i18next from "i18next"; export interface TOTPListElement extends HTMLElement { setCode(code: string): void; } - export class TOTPViewPage extends Page { constructor() { super(); @@ -27,25 +26,28 @@ export class TOTPViewPage extends Page { async render(): Promise { setTitleElement(pageState); const totpList = makeElement({ tag: "div" }); - setPageContent(makeElement({ - tag: "div", - children: [ - makeElement({ - tag: "a", - text: i18next.t("totp_view_new_btn"), - onclick: () => { changePage("NEW_TOTP"); } - }), - makeElement({ - tag: "p", - id: "loadingText", - text: i18next.t("totp_view_loading"), - }), - makeElement({ tag: "br" }), - makeElement({ tag: "br" }), - totpList - ] - })); - + setPageContent( + makeElement({ + tag: "div", + children: [ + makeElement({ + tag: "a", + text: i18next.t("totp_view_new_btn"), + onclick: () => { + changePage("NEW_TOTP"); + }, + }), + makeElement({ + tag: "p", + id: "loadingText", + text: i18next.t("totp_view_loading"), + }), + makeElement({ tag: "br" }), + makeElement({ tag: "br" }), + totpList, + ], + }), + ); try { const res = await getTOTPKeys(pageState.currentBaseMount); @@ -66,14 +68,17 @@ export class TOTPViewPage extends Page { } } - const totpRefresher = async () => { - await Promise.all(Array.from(objectToMap(this.totpListElements)).map((kv: [string, TOTPListElement]) => { - return this.updateTOTPElement(...kv); - })) - } + await Promise.all( + Array.from(objectToMap(this.totpListElements)).map((kv: [string, TOTPListElement]) => { + return this.updateTOTPElement(...kv); + }), + ); + }; await totpRefresher(); - this.refresher = setInterval(() => { void totpRefresher(); }, 3000) as unknown as number; + this.refresher = setInterval(() => { + void totpRefresher(); + }, 3000) as unknown as number; } cleanup(): void { @@ -92,7 +97,7 @@ export class TOTPViewPage extends Page { const gridElement = makeElement({ tag: "div", class: ["uk-grid", "uk-grid-small", "uk-text-expand"], - children: [totpKeyBox, totpValueBox] + children: [totpKeyBox, totpValueBox], }) as TOTPListElement; gridElement.setCode = (code: string) => totpValueBox.setText(code); @@ -103,4 +108,4 @@ export class TOTPViewPage extends Page { get name(): string { return i18next.t("totp_view_title"); } -} \ No newline at end of file +} diff --git a/src/pages/Transit/TransitDecrypt.ts b/src/pages/Transit/TransitDecrypt.ts index 68d338c..0b33ec3 100644 --- a/src/pages/Transit/TransitDecrypt.ts +++ b/src/pages/Transit/TransitDecrypt.ts @@ -21,20 +21,24 @@ export class TransitDecryptPage extends Page { render(): void { setTitleElement(pageState); - setPageContent(makeElement({ - tag: "div" - })); + setPageContent( + makeElement({ + tag: "div", + }), + ); this.transitDecryptForm = makeElement({ tag: "form", children: [ - Margin(makeElement({ - tag: "textarea", - class: ["uk-textarea", "uk-form-width-medium"], - attributes: { - placeholder: i18next.t("transit_decrypt_input_placeholder"), - name: "ciphertext", - } - })), + Margin( + makeElement({ + tag: "textarea", + class: ["uk-textarea", "uk-form-width-medium"], + attributes: { + placeholder: i18next.t("transit_decrypt_input_placeholder"), + name: "ciphertext", + }, + }), + ), Margin(FileUploadInput("ciphertext_file")), Margin([ makeElement({ @@ -51,14 +55,14 @@ export class TransitDecryptPage extends Page { attributes: { type: "checkbox", name: "decodeBase64Checkbox", - } + }, }), }), ]), makeElement({ tag: "p", id: "errorText", - class: "uk-text-danger" + class: "uk-text-danger", }), makeElement({ tag: "button", @@ -66,9 +70,9 @@ export class TransitDecryptPage extends Page { text: i18next.t("transit_decrypt_decrypt_btn"), attributes: { type: "submit", - } - }) - ] + }, + }), + ], }) as HTMLFormElement; setPageContent(this.transitDecryptForm); this.transitDecryptForm.addEventListener("submit", (e: Event) => { @@ -86,20 +90,23 @@ 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) ).replace("data:text/plain;base64,", "")); + ciphertext = atob( + (await fileToBase64(ciphertext_file)).replace("data:text/plain;base64,", ""), + ); } try { - const res = await transitDecrypt( - pageState.currentBaseMount, - pageState.currentSecret, - { ciphertext: ciphertext }, - ); + const res = await transitDecrypt(pageState.currentBaseMount, pageState.currentSecret, { + ciphertext: ciphertext, + }); let plaintext = res.plaintext; if (decodeBase64 == "on") { plaintext = atob(plaintext); } - const modal = CopyableModal(i18next.t("transit_decrypt_decryption_result_modal_title"), plaintext); + const modal = CopyableModal( + i18next.t("transit_decrypt_decryption_result_modal_title"), + plaintext, + ); document.body.querySelector("#pageContent").appendChild(modal); modal.show(); } catch (e: unknown) { diff --git a/src/pages/Transit/TransitEncrypt.ts b/src/pages/Transit/TransitEncrypt.ts index a36e537..2bbd413 100644 --- a/src/pages/Transit/TransitEncrypt.ts +++ b/src/pages/Transit/TransitEncrypt.ts @@ -8,7 +8,6 @@ import { pageState } from "../../globalPageState"; import { transitEncrypt } from "../../api/transit/transitEncrypt"; import i18next from "i18next"; - export class TransitEncryptPage extends Page { constructor() { super(); @@ -20,23 +19,26 @@ export class TransitEncryptPage extends Page { transitEncryptForm: HTMLFormElement; - render(): void { setTitleElement(pageState); - setPageContent(makeElement({ - tag: "div" - })); + setPageContent( + makeElement({ + tag: "div", + }), + ); this.transitEncryptForm = makeElement({ tag: "form", children: [ - Margin(makeElement({ - tag: "textarea", - class: ["uk-textarea", "uk-form-width-medium"], - attributes: { - placeholder: i18next.t("transit_encrypt_input_placeholder"), - name: "plaintext", - } - })), + Margin( + makeElement({ + tag: "textarea", + class: ["uk-textarea", "uk-form-width-medium"], + attributes: { + placeholder: i18next.t("transit_encrypt_input_placeholder"), + name: "plaintext", + }, + }), + ), Margin(FileUploadInput("plaintext_file")), Margin([ makeElement({ @@ -53,14 +55,14 @@ export class TransitEncryptPage extends Page { attributes: { type: "checkbox", name: "base64Checkbox", - } + }, }), }), ]), makeElement({ tag: "p", id: "errorText", - class: "uk-text-danger" + class: "uk-text-danger", }), makeElement({ tag: "button", @@ -68,9 +70,9 @@ export class TransitEncryptPage extends Page { text: i18next.t("transit_encrypt_encrypt_btn"), attributes: { type: "submit", - } - }) - ] + }, + }), + ], }) as HTMLFormElement; setPageContent(this.transitEncryptForm); @@ -89,19 +91,20 @@ export class TransitEncryptPage extends Page { const plaintext_file = formData.get("plaintext_file") as File; if (plaintext_file.size > 0) { - plaintext = (await fileToBase64(plaintext_file) ).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 { - const res = await transitEncrypt( - pageState.currentBaseMount, - pageState.currentSecret, - { plaintext: plaintext } + const res = await transitEncrypt(pageState.currentBaseMount, pageState.currentSecret, { + plaintext: plaintext, + }); + const modal = CopyableModal( + i18next.t("transit_encrypt_encryption_result_modal_title"), + res.ciphertext, ); - const modal = CopyableModal(i18next.t("transit_encrypt_encryption_result_modal_title"), res.ciphertext); document.body.querySelector("#pageContent").appendChild(modal); modal.show(); } catch (e: unknown) { diff --git a/src/pages/Transit/TransitRewrap.ts b/src/pages/Transit/TransitRewrap.ts index 69541fd..ab90975 100644 --- a/src/pages/Transit/TransitRewrap.ts +++ b/src/pages/Transit/TransitRewrap.ts @@ -10,7 +10,7 @@ import { pageState } from "../../globalPageState"; import { transitRewrap } from "../../api/transit/transitRewrap"; import i18next from "i18next"; -type versionOption = { version: string; label: string } +type versionOption = { version: string; label: string }; export class TransitRewrapPage extends Page { constructor() { @@ -27,23 +27,25 @@ export class TransitRewrapPage extends Page { setTitleElement(pageState); const transitKey = await getTransitKey(pageState.currentBaseMount, pageState.currentSecret); - const stringVersions = Array.from(objectToMap(transitKey.keys).keys()).reverse() as unknown as string[]; + 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. + // get the selectable version options in the same + // format the official UI uses. // e.g: ["2 (latest)", "1"] const options: versionOption[] = versions.map((val): versionOption => { - const i18nkey = val == Math.max(...versions) ? - "transit_rewrap_latest_version_option_text" - : - "transit_rewrap_version_option_text"; + const i18nkey = + val == Math.max(...versions) + ? "transit_rewrap_latest_version_option_text" + : "transit_rewrap_version_option_text"; return { version: String(val), label: i18next.t(i18nkey, { version_num: String(val) }), - } - }) + }; + }); setPageContent(""); this.transitRewrapForm = makeElement({ @@ -53,20 +55,22 @@ export class TransitRewrapPage extends Page { tag: "select", name: "version", class: ["uk-select", "uk-width-1-2"], - children: options.map((option): HTMLElement => Option(option.label, option.version)) + children: options.map((option): HTMLElement => Option(option.label, option.version)), }), - Margin(makeElement({ - tag: "textarea", - class: ["uk-textarea", "uk-width-1-2"], - attributes: { - placeholder: i18next.t("transit_rewrap_input_placeholder"), - name: "ciphertext", - } - })), + Margin( + makeElement({ + tag: "textarea", + class: ["uk-textarea", "uk-width-1-2"], + attributes: { + placeholder: i18next.t("transit_rewrap_input_placeholder"), + name: "ciphertext", + }, + }), + ), makeElement({ tag: "p", id: "errorText", - class: "uk-text-danger" + class: "uk-text-danger", }), makeElement({ tag: "button", @@ -74,9 +78,9 @@ export class TransitRewrapPage extends Page { text: i18next.t("transit_rewrap_rewrap_btn"), attributes: { type: "submit", - } - }) - ] + }, + }), + ], }) as HTMLFormElement; setPageContent(this.transitRewrapForm); @@ -89,14 +93,10 @@ export class TransitRewrapPage extends Page { async transitRewrapFormHandler(): Promise { const formData = new FormData(this.transitRewrapForm); try { - const res = await transitRewrap( - pageState.currentBaseMount, - pageState.currentSecret, - { - ciphertext: formData.get("ciphertext") as string, - key_version: parseInt(formData.get("version") as string, 10), - } - ); + const res = await transitRewrap(pageState.currentBaseMount, pageState.currentSecret, { + ciphertext: formData.get("ciphertext") as string, + key_version: parseInt(formData.get("version") as string, 10), + }); const modal = CopyableModal(i18next.t("transit_rewrap_result_modal_title"), res.ciphertext); document.body.querySelector("#pageContent").appendChild(modal); modal.show(); diff --git a/src/pages/Transit/TransitView.ts b/src/pages/Transit/TransitView.ts index 2d8da32..c9b86ed 100644 --- a/src/pages/Transit/TransitView.ts +++ b/src/pages/Transit/TransitView.ts @@ -4,7 +4,7 @@ import { changePage, setErrorText, setPageContent, setTitleElement } from "../.. import { getTransitKeys } from "../../api/transit/getTransitKeys"; import { makeElement } from "../../htmlUtils"; import { pageState } from "../../globalPageState"; -import i18next from 'i18next'; +import i18next from "i18next"; export class TransitViewPage extends Page { constructor() { @@ -29,39 +29,43 @@ export class TransitViewPage extends Page { class: ["uk-button", "uk-button-primary", "uk-margin-bottom"], onclick: () => { changePage("TRANSIT_NEW_KEY"); - } + }, }); transitViewContent.appendChild(newButton); try { const res = await getTransitKeys(pageState.currentBaseMount); - transitViewContent.appendChild(makeElement({ - tag: "ul", - class: ["uk-nav", "uk-nav-default"], - children: [ - ...res.map(function (secret) { - return makeElement({ - tag: "li", - children: makeElement({ - tag: "a", - text: secret, - onclick: () => { - pageState.currentSecret = secret; - changePage("TRANSIT_VIEW_SECRET"); - } - }) - }); - }) - ] - })); + transitViewContent.appendChild( + makeElement({ + tag: "ul", + class: ["uk-nav", "uk-nav-default"], + children: [ + ...res.map(function (secret) { + return makeElement({ + tag: "li", + children: makeElement({ + tag: "a", + text: secret, + onclick: () => { + pageState.currentSecret = secret; + changePage("TRANSIT_VIEW_SECRET"); + }, + }), + }); + }), + ], + }), + ); } catch (e: unknown) { const error = e as Error; if (error == DoesNotExistError) { - transitViewContent.appendChild(makeElement({ - tag: "p", - text: i18next.t("transit_view_none_here_text") - })); + transitViewContent.appendChild( + makeElement({ + tag: "p", + text: i18next.t("transit_view_none_here_text"), + }), + ); } else { setErrorText(error.message); } diff --git a/src/pages/Transit/TransitViewSecret.ts b/src/pages/Transit/TransitViewSecret.ts index 17369af..e655655 100644 --- a/src/pages/Transit/TransitViewSecret.ts +++ b/src/pages/Transit/TransitViewSecret.ts @@ -4,7 +4,7 @@ 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 i18next from "i18next"; export class TransitViewSecretPage extends Page { constructor() { @@ -20,40 +20,48 @@ export class TransitViewSecretPage extends Page { const transitKey = await getTransitKey(pageState.currentBaseMount, pageState.currentSecret); - setPageContent(makeElement({ - tag: "div", - class: "uk-child-width-1-1@s uk-child-width-1-2@m uk-grid-small uk-grid-match", - attributes: { "uk-grid": "" }, - children: [ - Tile({ - condition: transitKey.supports_encryption, - title: i18next.t("transit_view_encrypt_text"), - description: i18next.t("transit_view_encrypt_description"), - icon: "lock", - iconText: i18next.t("transit_view_encrypt_icon_text"), - onclick: () => { changePage("TRANSIT_ENCRYPT"); } - }), - Tile({ - condition: transitKey.supports_decryption, - title: i18next.t("transit_view_decrypt_text"), - description: i18next.t("transit_view_decrypt_description"), - icon: "mail", - iconText: i18next.t("transit_view_decrypt_icon_text"), - onclick: () => { changePage("TRANSIT_DECRYPT"); } - }), - Tile({ - condition: transitKey.supports_decryption, - title: i18next.t("transit_view_rewrap_text"), - description: i18next.t("transit_view_rewrap_description"), - icon: "code", - iconText: i18next.t("transit_view_rewrap_icon_text"), - onclick: () => { changePage("TRANSIT_REWRAP"); } - }), - ] - })); + setPageContent( + makeElement({ + tag: "div", + class: "uk-child-width-1-1@s uk-child-width-1-2@m uk-grid-small uk-grid-match", + attributes: { "uk-grid": "" }, + children: [ + Tile({ + condition: transitKey.supports_encryption, + title: i18next.t("transit_view_encrypt_text"), + description: i18next.t("transit_view_encrypt_description"), + icon: "lock", + iconText: i18next.t("transit_view_encrypt_icon_text"), + onclick: () => { + changePage("TRANSIT_ENCRYPT"); + }, + }), + Tile({ + condition: transitKey.supports_decryption, + title: i18next.t("transit_view_decrypt_text"), + description: i18next.t("transit_view_decrypt_description"), + icon: "mail", + iconText: i18next.t("transit_view_decrypt_icon_text"), + onclick: () => { + changePage("TRANSIT_DECRYPT"); + }, + }), + Tile({ + condition: transitKey.supports_decryption, + title: i18next.t("transit_view_rewrap_text"), + description: i18next.t("transit_view_rewrap_description"), + icon: "code", + iconText: i18next.t("transit_view_rewrap_icon_text"), + onclick: () => { + changePage("TRANSIT_REWRAP"); + }, + }), + ], + }), + ); } get name(): string { return i18next.t("transit_view_secret_title"); } -} \ No newline at end of file +} diff --git a/src/pages/Unseal.ts b/src/pages/Unseal.ts index cefe481..531fe8b 100644 --- a/src/pages/Unseal.ts +++ b/src/pages/Unseal.ts @@ -5,13 +5,12 @@ import { SealStatusType, getSealStatus } from "../api/sys/getSealStatus"; import { changePage, setErrorText, setPageContent } from "../pageUtils"; import { makeElement } from "../htmlUtils"; import { submitUnsealKey } from "../api/sys/submitUnsealKey"; -import i18next from 'i18next'; - +import i18next from "i18next"; const UnsealInputModes = { FORM_INPUT: "FORM_INPUT", - QR_INPUT: "QR_INPUT" -} + QR_INPUT: "QR_INPUT", +}; export class UnsealPage extends Page { constructor() { @@ -57,28 +56,33 @@ export class UnsealPage extends Page { this.unsealProgress = makeElement({ tag: "progress", class: "uk-progress", - attributes: { value: "0", max: "0" } + attributes: { value: "0", max: "0" }, }) as HTMLProgressElement; this.unsealProgressText = makeElement({ tag: "p", - text: i18next.t("unseal_keys_progress", { progress: "0", keys_needed: "0" }), + text: i18next.t("unseal_keys_progress", { + progress: "0", + keys_needed: "0", + }), }) as HTMLParagraphElement; this.unsealInputContent = makeElement({ - tag: "div" - }); - setPageContent(makeElement({ tag: "div", - children: [ - this.unsealProgress, - makeElement({ - tag: "p", - id: "errorText", - class: ["uk-text-danger", "uk-margin-top"] - }), - this.unsealProgressText, - this.unsealInputContent - ] - })); + }); + setPageContent( + makeElement({ + tag: "div", + children: [ + this.unsealProgress, + makeElement({ + tag: "p", + id: "errorText", + class: ["uk-text-danger", "uk-margin-top"], + }), + this.unsealProgressText, + this.unsealInputContent, + ], + }), + ); this.switchInputMode(this.mode); this.updateSealProgress(await getSealStatus()); this.makeRefresher(); @@ -86,29 +90,28 @@ export class UnsealPage extends Page { setButtons(method: string): void { const newMethod: string = - method == UnsealInputModes.FORM_INPUT ? - UnsealInputModes.QR_INPUT - : - UnsealInputModes.FORM_INPUT; + method == UnsealInputModes.FORM_INPUT + ? UnsealInputModes.QR_INPUT + : UnsealInputModes.FORM_INPUT; const buttonText: string = - newMethod == UnsealInputModes.FORM_INPUT ? - i18next.t("unseal_input_btn") - : - i18next.t("unseal_qr_btn"); - this.unsealInputContent.appendChild(makeElement({ - tag: "button", - class: ["uk-button", "uk-button-primary"], - text: buttonText, - onclick: () => { - this.switchInputMode(newMethod); - } - })) + newMethod == UnsealInputModes.FORM_INPUT + ? i18next.t("unseal_input_btn") + : i18next.t("unseal_qr_btn"); + this.unsealInputContent.appendChild( + makeElement({ + tag: "button", + class: ["uk-button", "uk-button-primary"], + text: buttonText, + onclick: () => { + this.switchInputMode(newMethod); + }, + }), + ); } - switchInputMode(method: string): void { this.deinitWebcam(); - this.unsealInputContent.querySelectorAll('*').forEach(n => n.remove()) + this.unsealInputContent.querySelectorAll("*").forEach((n) => n.remove()); if (method == UnsealInputModes.FORM_INPUT) this.makeUnsealForm(); if (method == UnsealInputModes.QR_INPUT) void this.makeQRInput(); this.setButtons(method); @@ -118,22 +121,26 @@ export class UnsealPage extends Page { this.unsealKeyForm = makeElement({ tag: "form", children: [ - MarginInline(makeElement({ - tag: "input", - class: ["uk-input", "uk-form-width-medium"], - attributes: { - required: "true", - type: "password", - placeholder: i18next.t("key_input_placeholder"), - name: "key" - } - })), - MarginInline(makeElement({ - tag: "button", - class: ["uk-button", "uk-button-primary"], - text: i18next.t("submit_key_btn") - })), - ] + MarginInline( + makeElement({ + tag: "input", + class: ["uk-input", "uk-form-width-medium"], + attributes: { + required: "true", + type: "password", + placeholder: i18next.t("key_input_placeholder"), + name: "key", + }, + }), + ), + MarginInline( + makeElement({ + tag: "button", + class: ["uk-button", "uk-button-primary"], + text: i18next.t("submit_key_btn"), + }), + ), + ], }) as HTMLFormElement; this.unsealInputContent.appendChild(this.unsealKeyForm); this.unsealKeyForm.addEventListener("submit", (e: Event) => { @@ -155,7 +162,7 @@ export class UnsealPage extends Page { const text = this.unsealProgressText; text.innerText = i18next.t("unseal_keys_progress", { progress: String(progress), - keys_needed: String(keysNeeded) + keys_needed: String(keysNeeded), }); const progressBar = this.unsealProgress; progressBar.value = progress; @@ -167,21 +174,23 @@ export class UnsealPage extends Page { } submitKey(key: string): void { - submitUnsealKey(key).then(_ => { - void getSealStatus().then(data => { - void this.updateSealProgress(data); + submitUnsealKey(key) + .then((_) => { + void getSealStatus().then((data) => { + void this.updateSealProgress(data); + }); + }) + .catch((e: Error) => { + setErrorText(e.message); }); - }).catch((e: Error) => { - setErrorText(e.message); - }); } handleKeySubmit(): void { const formData = new FormData(this.unsealKeyForm); - this.submitKey(formData.get("key") as string) + this.submitKey(formData.get("key") as string); } get name(): string { return i18next.t("unseal_vault_text"); } -} \ No newline at end of file +} diff --git a/src/playground.ts b/src/playground.ts index c66cc3b..eb4568e 100644 --- a/src/playground.ts +++ b/src/playground.ts @@ -1,6 +1,6 @@ import { PageState } from "./PageState"; import { pageState } from "./globalPageState"; -import i18next from 'i18next'; +import i18next from "i18next"; // Playground is a way to debug and test things. // Anything you put in here is gonna be run on page initial load @@ -8,7 +8,10 @@ import i18next from 'i18next'; // Also it only runs when process.env.NODE_ENV == "development" declare global { - interface Window { pageState: PageState; i18next: unknown; } + interface Window { + pageState: PageState; + i18next: unknown; + } } // Please empty this function before committing. diff --git a/src/translations/de.js b/src/translations/de.js index 89541a5..64257cf 100644 --- a/src/translations/de.js +++ b/src/translations/de.js @@ -1,25 +1,24 @@ module.exports = { // The localised name for the language - "language_name": "Deutsche", + language_name: "Deutsche", // Internal: The direction of text (ltr or rtl) - "language_direction": "ltr", + language_direction: "ltr", // These are the buttons on the top bar. - "home_btn": "Startseite", - "back_btn": "Zurück", - "refresh_btn": "Neu laden", - "me_btn": "Profil/Einstellungen", + home_btn: "Startseite", + back_btn: "Zurück", + refresh_btn: "Neu laden", + me_btn: "Profil/Einstellungen", // These are the page titles - "me_page_title": "Proil/Einstellungen", - "home_page_title": "Startseite", + me_page_title: "Proil/Einstellungen", + home_page_title: "Startseite", // These are all o the other translations - "log_out_btn": "Abmelden", - "copy_token_btn": "Token kopieren", - "renew_lease_btn": "Token erneuern", + log_out_btn: "Abmelden", + copy_token_btn: "Token kopieren", + renew_lease_btn: "Token erneuern", - "vaulturl_text": "Tresor-URL: {{text}}", - "password_generator_btn": "Passwortgenerator", - "your_token_expires_in": "Ihr Token läuft in {{date, until_date}} ab" - -} + vaulturl_text: "Tresor-URL: {{text}}", + password_generator_btn: "Passwortgenerator", + your_token_expires_in: "Ihr Token läuft in {{date, until_date}} ab", +}; diff --git a/src/translations/en.js b/src/translations/en.js index bdc4bd0..ac874a9 100644 --- a/src/translations/en.js +++ b/src/translations/en.js @@ -1,164 +1,168 @@ module.exports = { // The localised name for the language - "language_name": "English", + language_name: "English", // Internal: The direction of text (ltr or rtl) - "language_direction": "ltr", + language_direction: "ltr", // These are the buttons on the top bar. - "home_btn": "Home", - "back_btn": "Back", - "refresh_btn": "Refresh", - "me_btn": "Me/Settings", + home_btn: "Home", + back_btn: "Back", + refresh_btn: "Refresh", + me_btn: "Me/Settings", // General Notification Messages - "notification_copy_success": "Copied to clipboard.", + notification_copy_success: "Copied to clipboard.", // Copyable Modal - "copy_modal_download_btn": "Download", - "copy_modal_copy_btn": "Copy", - "copy_modal_close_btn": "Close", + copy_modal_download_btn: "Download", + copy_modal_copy_btn: "Copy", + copy_modal_close_btn: "Close", // Copyable Input Box - "copy_input_box_copy_icon_text": "Copy Button", + copy_input_box_copy_icon_text: "Copy Button", // File Upload Input - "file_upload_input_btn": "Upload File", + file_upload_input_btn: "Upload File", // Me Page - "me_page_title": "Me/Settings", - "log_out_btn": "Log Out", - "seal_vault_btn": "Seal Vault", - "copy_token_btn": "Copy Token", - "renew_lease_btn": "Renew Token Lease", - "change_language_btn": "Change Language", + me_page_title: "Me/Settings", + log_out_btn: "Log Out", + seal_vault_btn: "Seal Vault", + copy_token_btn: "Copy Token", + renew_lease_btn: "Renew Token Lease", + change_language_btn: "Change Language", // Home Page - "home_page_title": "Home", - "vaulturl_text": "Vault URL: {{text}}", - "password_generator_btn": "Password Generator", - "your_token_expires_in": "Your token expires in {{date, until_date}}", + home_page_title: "Home", + vaulturl_text: "Vault URL: {{text}}", + password_generator_btn: "Password Generator", + your_token_expires_in: "Your token expires in {{date, until_date}}", // Unseal Page - "unseal_vault_text": "Unseal the Vault", - "submit_key_btn": "Submit Key", - "unseal_input_btn": "Switch to Manual Key Input", - "unseal_qr_btn": "Switch to QR Key Input", - "key_input_placeholder": "Key", - "unseal_keys_progress": "Keys: {{progress}}/{{keys_needed}}", + unseal_vault_text: "Unseal the Vault", + submit_key_btn: "Submit Key", + unseal_input_btn: "Switch to Manual Key Input", + unseal_qr_btn: "Switch to QR Key Input", + key_input_placeholder: "Key", + unseal_keys_progress: "Keys: {{progress}}/{{keys_needed}}", // Language Selector Page - "set_language_title": "Set Language", - "set_language_btn": "Set Language", + set_language_title: "Set Language", + set_language_btn: "Set Language", // Password Generator Page - "password_generator_title": "Password Generator", - "password_length_title": "Password Length ({{min}}/{{max}})", - "gen_password_btn": "Generate Password", + password_generator_title: "Password Generator", + password_length_title: "Password Length ({{min}}/{{max}})", + gen_password_btn: "Generate Password", // Login Page - "log_in_title": "Login", - "log_in_with_token": "Token", - "log_in_with_username": "Username", - "token_input": "Token", - "username_input": "Username", - "password_input": "Password", - "log_in_btn": "Login", - "token_login_error": "Invalid Token", + log_in_title: "Login", + log_in_with_token: "Token", + log_in_with_username: "Username", + token_input: "Token", + username_input: "Username", + password_input: "Password", + log_in_btn: "Login", + token_login_error: "Invalid Token", // Key Value Delete Page - "kv_delete_title": "K/V Delete", - "kv_delete_text": "Are you sure you want to delete this?", - "kv_delete_btn": "Delete", - "kv_delete_suffix": " (delete)", + kv_delete_title: "K/V Delete", + kv_delete_text: "Are you sure you want to delete this?", + kv_delete_btn: "Delete", + kv_delete_suffix: " (delete)", // Key Value New Page - "kv_new_title": "K/V New", - "kv_new_suffix": " (new)", - "kv_new_path": "Relative Path", - "kv_new_create_btn": "Create Empty Secret", + kv_new_title: "K/V New", + kv_new_suffix: " (new)", + kv_new_path: "Relative Path", + kv_new_create_btn: "Create Empty Secret", // Key Value Secret Page - "kv_secret_title": "K/V Secret", - "kv_secret_deleted_text": "This secret version has been soft deleted but remains restorable, do you want to restore it?", - "kv_secret_restore_btn": "Restore Secret Version", - "kv_secret_loading": "Loading Secret..", - "kv_secret_delete_btn": "Delete", - "kv_secret_delete_all_btn": "Delete All Versions", - "kv_secret_delete_version_btn": "Delete Version {{ version }}", - "kv_secret_edit_btn": "Edit", - "kv_secret_versions_btn": "Versions", + kv_secret_title: "K/V Secret", + kv_secret_deleted_text: + "This secret version has been soft deleted but remains restorable, do you want to restore it?", + kv_secret_restore_btn: "Restore Secret Version", + kv_secret_loading: "Loading Secret..", + kv_secret_delete_btn: "Delete", + kv_secret_delete_all_btn: "Delete All Versions", + kv_secret_delete_version_btn: "Delete Version {{ version }}", + kv_secret_edit_btn: "Edit", + kv_secret_versions_btn: "Versions", // Key Value Secret Editor Page - "kv_sec_edit_title": "K/V Edit", - "kv_sec_edit_btn": "Edit", - "kv_sec_edit_loading": "Loading Editor..", - "kv_sec_edit_invalid_json_err": "Invalid JSON", - "kv_sec_edit_suffix": " (edit)", + kv_sec_edit_title: "K/V Edit", + kv_sec_edit_btn: "Edit", + kv_sec_edit_loading: "Loading Editor..", + kv_sec_edit_invalid_json_err: "Invalid JSON", + kv_sec_edit_suffix: " (edit)", // Key Value Secret Versions Page - "kv_sec_versions_title": "K/V Versions", - "kv_sec_versions_suffix": " (versions)", + kv_sec_versions_title: "K/V Versions", + kv_sec_versions_suffix: " (versions)", // Key Value View/List Secrets Page - "kv_view_title": "K/V View", - "kv_view_cubbyhole_text": "In cubbyhole, secrets can be stored as long as the lease of your token is valid. They will be deleted when lease is expired and can only be viewed by your current token.", - "kv_view_new_btn": "New", - "kv_view_none_here_text": "You seem to have no secrets here, would you like to create one?", + kv_view_title: "K/V View", + kv_view_cubbyhole_text: + "In cubbyhole, secrets can be stored as long as the lease of your token is valid. They will be deleted when lease is expired and can only be viewed by your current token.", + kv_view_new_btn: "New", + kv_view_none_here_text: "You seem to have no secrets here, would you like to create one?", // TOTP View Page - "totp_view_title": "TOTP", - "totp_view_new_btn": "Add new TOTP key", - "totp_view_loading": "Loading TOTP Codes..", - "totp_view_empty": "You seem to have no TOTP codes here, would you like to create one?", - "totp_view_loading_box": "Loading..", + totp_view_title: "TOTP", + totp_view_new_btn: "Add new TOTP key", + totp_view_loading: "Loading TOTP Codes..", + totp_view_empty: "You seem to have no TOTP codes here, would you like to create one?", + totp_view_loading_box: "Loading..", // New TOTP Key Page - "totp_new_title": "New TOTP Key", - "totp_new_suffix": " (new)", - "totp_new_name_text": "TOTP Key Name", - "totp_new_info": "You need either a key or a URI, URI prefered but may not work. Just scan the QR code and copy the URL.", - "totp_new_uri_input": "URI", - "totp_new_key_input": "Key", - "totp_new_add_btn": "Add TOTP Key", + totp_new_title: "New TOTP Key", + totp_new_suffix: " (new)", + totp_new_name_text: "TOTP Key Name", + totp_new_info: + "You need either a key or a URI, URI prefered but may not work. Just scan the QR code and copy the URL.", + totp_new_uri_input: "URI", + totp_new_key_input: "Key", + totp_new_add_btn: "Add TOTP Key", // Transit View Page - "transit_view_title": "Transit View", - "transit_view_none_here_text": "You seem to have no transit keys here, would you like to create one?", + transit_view_title: "Transit View", + transit_view_none_here_text: + "You seem to have no transit keys here, would you like to create one?", // Transit View Secret Page - "transit_view_secret_title": "Transit Secret View", - "transit_view_encrypt_text": "Encrypt", - "transit_view_encrypt_icon_text": "Encryption Icon", - "transit_view_encrypt_description": "Encrypt some plaintext or base64 encoded binary.", - "transit_view_decrypt_text": "Decrypt", - "transit_view_decrypt_description": "Decrypt some cyphertext.", - "transit_view_decrypt_icon_text": "Decryption Icon", - "transit_view_rewrap_text": "Rewrap", - "transit_view_rewrap_description": "Rewrap ciphertext using a different key version.", - "transit_view_rewrap_icon_text": "Rewrap Icon", + transit_view_secret_title: "Transit Secret View", + transit_view_encrypt_text: "Encrypt", + transit_view_encrypt_icon_text: "Encryption Icon", + transit_view_encrypt_description: "Encrypt some plaintext or base64 encoded binary.", + transit_view_decrypt_text: "Decrypt", + transit_view_decrypt_description: "Decrypt some cyphertext.", + transit_view_decrypt_icon_text: "Decryption Icon", + transit_view_rewrap_text: "Rewrap", + transit_view_rewrap_description: "Rewrap ciphertext using a different key version.", + transit_view_rewrap_icon_text: "Rewrap Icon", // Transit Encrypt Page - "transit_encrypt_title": "Transit Encrypt", - "transit_encrypt_suffix": " (encrypt)", - "transit_encrypt_input_placeholder": "Plaintext or base64", - "transit_encrypt_already_encoded_checkbox": "Is the data already encoded in base64?", - "transit_encrypt_encrypt_btn": "Encrypt", - "transit_encrypt_encryption_result_modal_title": "Encryption Result", + transit_encrypt_title: "Transit Encrypt", + transit_encrypt_suffix: " (encrypt)", + transit_encrypt_input_placeholder: "Plaintext or base64", + transit_encrypt_already_encoded_checkbox: "Is the data already encoded in base64?", + transit_encrypt_encrypt_btn: "Encrypt", + transit_encrypt_encryption_result_modal_title: "Encryption Result", // Transit Decrypt Page - "transit_decrypt_title": "Transit Decrypt", - "transit_decrypt_suffix": " (decrypt)", - "transit_decrypt_input_placeholder": "Cyphertext", - "transit_decrypt_decode_checkbox": "Should the plaintext be base64 decoded?", - "transit_decrypt_decrypt_btn": "Decrypt", - "transit_decrypt_decryption_result_modal_title": "Decryption Result", + transit_decrypt_title: "Transit Decrypt", + transit_decrypt_suffix: " (decrypt)", + transit_decrypt_input_placeholder: "Cyphertext", + transit_decrypt_decode_checkbox: "Should the plaintext be base64 decoded?", + transit_decrypt_decrypt_btn: "Decrypt", + transit_decrypt_decryption_result_modal_title: "Decryption Result", // Transit Rewrap Page - "transit_rewrap_title": "Transit Rewrap", - "transit_rewrap_suffix": " (rewrap)", - "transit_rewrap_version_option_text": "{{version_num}}", - "transit_rewrap_latest_version_option_text": "{{version_num}} (latest)", - "transit_rewrap_input_placeholder": "Cyphertext", - "transit_rewrap_rewrap_btn": "Rewrap", - "transit_rewrap_result_modal_title": "Rewrap Result", -} \ No newline at end of file + transit_rewrap_title: "Transit Rewrap", + transit_rewrap_suffix: " (rewrap)", + transit_rewrap_version_option_text: "{{version_num}}", + transit_rewrap_latest_version_option_text: "{{version_num}} (latest)", + transit_rewrap_input_placeholder: "Cyphertext", + transit_rewrap_rewrap_btn: "Rewrap", + transit_rewrap_result_modal_title: "Rewrap Result", +}; diff --git a/src/translations/fr.js b/src/translations/fr.js index 1c5191c..041dd8f 100644 --- a/src/translations/fr.js +++ b/src/translations/fr.js @@ -1,147 +1,152 @@ module.exports = { // The localised name for the language - "language_name": "Français", + language_name: "Français", // Internal: The direction of text (ltr or rtl) - "language_direction": "ltr", + language_direction: "ltr", // These are the buttons on the top bar. - "home_btn": "Accueil", - "back_btn": "Retour", - "refresh_btn": "Rafraichir", - "me_btn": "Profil/Paramètres", + home_btn: "Accueil", + back_btn: "Retour", + refresh_btn: "Rafraichir", + me_btn: "Profil/Paramètres", // General Notification Messages - "notification_copy_success": "Copié dans le presse-papiers.", + notification_copy_success: "Copié dans le presse-papiers.", // Copyable Modal - "copy_modal_download_btn": "Télécharger", - "copy_modal_copy_btn": "Copier", - "copy_modal_close_btn": "Fermer", + copy_modal_download_btn: "Télécharger", + copy_modal_copy_btn: "Copier", + copy_modal_close_btn: "Fermer", // Copyable Input Box - "copy_input_box_copy_icon_text": "Bouton Copier", + copy_input_box_copy_icon_text: "Bouton Copier", // Me Page - "me_page_title": "Profil/Paramètres", - "log_out_btn": "Déconnexion", - "seal_vault_btn": "Verrouiller le coffre", - "copy_token_btn": "Copier le jeton", - "renew_lease_btn": "Renouveler le jeton", - "change_language_btn": "Changer la langue", + me_page_title: "Profil/Paramètres", + log_out_btn: "Déconnexion", + seal_vault_btn: "Verrouiller le coffre", + copy_token_btn: "Copier le jeton", + renew_lease_btn: "Renouveler le jeton", + change_language_btn: "Changer la langue", // Home Page - "home_page_title": "Accueil", - "vaulturl_text": "Adresse du Vault: {{text}}", - "password_generator_btn": "Générateur de mot de passe", - "your_token_expires_in": "Votre jeton expire dans {{date, until_date}}", + home_page_title: "Accueil", + vaulturl_text: "Adresse du Vault: {{text}}", + password_generator_btn: "Générateur de mot de passe", + your_token_expires_in: "Votre jeton expire dans {{date, until_date}}", // Unseal Page - "unseal_vault_text": "Ouvrir le Vault", - "submit_key_btn": "Ajouter la clé", - "unseal_input_btn": "Basculer en entrée de clé manuelle", - "unseal_qr_btn": "Basculer en entrée de QR code", - "key_input_placeholder": "Clé", - "unseal_keys_progress": "Clés: {{progress}}/{{keys_needed}}", + unseal_vault_text: "Ouvrir le Vault", + submit_key_btn: "Ajouter la clé", + unseal_input_btn: "Basculer en entrée de clé manuelle", + unseal_qr_btn: "Basculer en entrée de QR code", + key_input_placeholder: "Clé", + unseal_keys_progress: "Clés: {{progress}}/{{keys_needed}}", // Language Selector Page - "set_language_title": "Langue", - "set_language_btn": "Changer la langue", + set_language_title: "Langue", + set_language_btn: "Changer la langue", // Password Generator Page - "password_generator_title": "Générateur de mot de passe", - "gen_password_btn": "Générer le mot de passe", + password_generator_title: "Générateur de mot de passe", + gen_password_btn: "Générer le mot de passe", // Login Page - "log_in_title": "Connexion", - "log_in_with_token": "Jeton", - "log_in_with_username": "Nom d'utilisateur", - "token_input": "Jeton", - "username_input": "Nom d'utilisateur", - "password_input": "Mot de passe", - "log_in_btn": "Se connecter", + log_in_title: "Connexion", + log_in_with_token: "Jeton", + log_in_with_username: "Nom d'utilisateur", + token_input: "Jeton", + username_input: "Nom d'utilisateur", + password_input: "Mot de passe", + log_in_btn: "Se connecter", // Key Value Delete Page - "kv_delete_title": "Suppression clé/valeur", - "kv_delete_text": "Voulez-vous vraiment supprimer ceci ?", - "kv_delete_btn": "Supprimer", - "kv_delete_suffix": " (supprimé)", + kv_delete_title: "Suppression clé/valeur", + kv_delete_text: "Voulez-vous vraiment supprimer ceci ?", + kv_delete_btn: "Supprimer", + kv_delete_suffix: " (supprimé)", // Key Value New Page - "kv_new_title": "Nouvelle clé/valeur", - "kv_new_suffix": " (nouveau)", - "kv_new_path": "Chemin relatif", - "kv_new_create_btn": "Créer un secret vide", + kv_new_title: "Nouvelle clé/valeur", + kv_new_suffix: " (nouveau)", + kv_new_path: "Chemin relatif", + kv_new_create_btn: "Créer un secret vide", // Key Value Secret Page - "kv_secret_title": "Clé/valeur secrète", - "kv_secret_deleted_text": "Cette version secrète a été supprimée temporairement mais reste restaurable, voulez-vous la restaurer ?", - "kv_secret_restore_btn": "Restaurer la version secrète", - "kv_secret_loading": "Chargement du secret..", - "kv_secret_delete_btn": "Supprimer", - "kv_secret_delete_all_btn": "Supprimer toutes les versions", - "kv_secret_delete_version_btn": "Supprimer la version {{ version }}", - "kv_secret_edit_btn": "Éditer", - "kv_secret_versions_btn": "Versions", + kv_secret_title: "Clé/valeur secrète", + kv_secret_deleted_text: + "Cette version secrète a été supprimée temporairement mais reste restaurable, voulez-vous la restaurer ?", + kv_secret_restore_btn: "Restaurer la version secrète", + kv_secret_loading: "Chargement du secret..", + kv_secret_delete_btn: "Supprimer", + kv_secret_delete_all_btn: "Supprimer toutes les versions", + kv_secret_delete_version_btn: "Supprimer la version {{ version }}", + kv_secret_edit_btn: "Éditer", + kv_secret_versions_btn: "Versions", // Key Value Secret Editor Page - "kv_sec_edit_title": "Édition clé/valeur", - "kv_sec_edit_btn": "Éditer", - "kv_sec_edit_loading": "Chargement de l'éditeur..", - "kv_sec_edit_invalid_json_err": "Code JSON invalide", - "kv_sec_edit_suffix": " (édité)", + kv_sec_edit_title: "Édition clé/valeur", + kv_sec_edit_btn: "Éditer", + kv_sec_edit_loading: "Chargement de l'éditeur..", + kv_sec_edit_invalid_json_err: "Code JSON invalide", + kv_sec_edit_suffix: " (édité)", // Key Value Secret Versions Page - "kv_sec_versions_title": "Versions clé/valeur", - "kv_sec_versions_suffix": " (versions)", + kv_sec_versions_title: "Versions clé/valeur", + kv_sec_versions_suffix: " (versions)", // Key Value View/List Secrets Page - "kv_view_title": "Visionneuse clé/valeur", - "kv_view_cubbyhole_text": "Dans cubbyhole, les secrets peuvent être stockés aussi longtemps que la validité de votre jeton. Ils seront supprimés quand le délai est expiré et ne peuvent être lus qu'avec votre jeton actuel.", - "kv_view_new_btn": "Nouveau", - "kv_view_none_here_text": "Vous semblez ne pas avoir de secrets ici, voulez-vous en créer un ?", + kv_view_title: "Visionneuse clé/valeur", + kv_view_cubbyhole_text: + "Dans cubbyhole, les secrets peuvent être stockés aussi longtemps que la validité de votre jeton. Ils seront supprimés quand le délai est expiré et ne peuvent être lus qu'avec votre jeton actuel.", + kv_view_new_btn: "Nouveau", + kv_view_none_here_text: "Vous semblez ne pas avoir de secrets ici, voulez-vous en créer un ?", // TOTP View Page - "totp_view_title": "TOTP", - "totp_view_new_btn": "Ajouter une clé TOTP", - "totp_view_loading": "Chargement des codes TOTP..", - "totp_view_empty": "Vous ne semblez pas avoir de code TOTP ici, voulez-vous en créer un ?", - "totp_view_loading_box": "Chargement..", + totp_view_title: "TOTP", + totp_view_new_btn: "Ajouter une clé TOTP", + totp_view_loading: "Chargement des codes TOTP..", + totp_view_empty: "Vous ne semblez pas avoir de code TOTP ici, voulez-vous en créer un ?", + totp_view_loading_box: "Chargement..", // New TOTP Key Page - "totp_new_title": "Nouvelle clé TOTP", - "totp_new_suffix": " (nouveau)", - "totp_new_name_text": "Nom de clé TOTP", - "totp_new_info": "Vous avez besoin soit d'une clé ou d'une URI, une URI est recommandée mais peut ne pas fonctionner. Scannez simplement le QR code et copiez l'adresse.", - "totp_new_uri_input": "URI", - "totp_new_key_input": "Clé", - "totp_new_add_btn": "Ajouter clé TOTP", + totp_new_title: "Nouvelle clé TOTP", + totp_new_suffix: " (nouveau)", + totp_new_name_text: "Nom de clé TOTP", + totp_new_info: + "Vous avez besoin soit d'une clé ou d'une URI, une URI est recommandée mais peut ne pas fonctionner. Scannez simplement le QR code et copiez l'adresse.", + totp_new_uri_input: "URI", + totp_new_key_input: "Clé", + totp_new_add_btn: "Ajouter clé TOTP", // Transit View Page - "transit_view_title": "Fenêtre Transit", - "transit_view_none_here_text": "Vous semblez ne pas avoir de clés de transit ici, voulez-vous en créer une ?", + transit_view_title: "Fenêtre Transit", + transit_view_none_here_text: + "Vous semblez ne pas avoir de clés de transit ici, voulez-vous en créer une ?", // Transit View Secret Page - "transit_view_secret_title": "Transit Secret", - "transit_view_encrypt_text": "Chiffrer", - "transit_view_encrypt_icon_text": "Icône chiffrement", - "transit_view_encrypt_description": "Chiffrer du texte brut ou données binaires encodées en base64.", - "transit_view_decrypt_text": "Déchiffrer", - "transit_view_decrypt_description": "Déchiffrer du texte chiffré.", - "transit_view_decrypt_icon_text": "Icône déchiffrement", + transit_view_secret_title: "Transit Secret", + transit_view_encrypt_text: "Chiffrer", + transit_view_encrypt_icon_text: "Icône chiffrement", + transit_view_encrypt_description: + "Chiffrer du texte brut ou données binaires encodées en base64.", + transit_view_decrypt_text: "Déchiffrer", + transit_view_decrypt_description: "Déchiffrer du texte chiffré.", + transit_view_decrypt_icon_text: "Icône déchiffrement", // Transit Encrypt Page - "transit_encrypt_title": "Chiffrement Transit", - "transit_encrypt_suffix": " (chiffrer)", - "transit_encrypt_input_placeholder": "Texte brut ou base64", - "transit_encrypt_already_encoded_checkbox": "Les données sont-elles déjà encodées en base64 ?", - "transit_encrypt_encrypt_btn": "Chiffrer", - "transit_encrypt_encryption_result_modal_title": "Résultat chiffré", + transit_encrypt_title: "Chiffrement Transit", + transit_encrypt_suffix: " (chiffrer)", + transit_encrypt_input_placeholder: "Texte brut ou base64", + transit_encrypt_already_encoded_checkbox: "Les données sont-elles déjà encodées en base64 ?", + transit_encrypt_encrypt_btn: "Chiffrer", + transit_encrypt_encryption_result_modal_title: "Résultat chiffré", // Transit decrypt Page - "transit_decrypt_title": "Déchiffrement Transit", - "transit_decrypt_suffix": " (déchiffrer)", - "transit_decrypt_input_placeholder": "Message chiffré", - "transit_decrypt_decode_checkbox": "Est-ce que le texte brut doit être encodé en base64 ?", - "transit_decrypt_decrypt_btn": "Déchiffrer", - "transit_decrypt_decryption_result_modal_title": "Résultat déchiffré", -} \ No newline at end of file + transit_decrypt_title: "Déchiffrement Transit", + transit_decrypt_suffix: " (déchiffrer)", + transit_decrypt_input_placeholder: "Message chiffré", + transit_decrypt_decode_checkbox: "Est-ce que le texte brut doit être encodé en base64 ?", + transit_decrypt_decrypt_btn: "Déchiffrer", + transit_decrypt_decryption_result_modal_title: "Résultat déchiffré", +}; diff --git a/src/translations/nl.js b/src/translations/nl.js index 65d320c..0a87241 100644 --- a/src/translations/nl.js +++ b/src/translations/nl.js @@ -1,24 +1,24 @@ module.exports = { // The localised name for the language - "language_name": "Nederlands", + language_name: "Nederlands", // Internal: The direction of text (ltr or rtl) - "language_direction": "ltr", + language_direction: "ltr", // These are the buttons on the top bar. - "home_btn": "Homepagina", - "back_btn": "Terug", - "refresh_btn": "Ververs", - "me_btn": "Profiel/Instellingen", + home_btn: "Homepagina", + back_btn: "Terug", + refresh_btn: "Ververs", + me_btn: "Profiel/Instellingen", // These are the page titles - "me_page_title": "Profiel/Instellingen", - "home_page_title": "Homepagina", + me_page_title: "Profiel/Instellingen", + home_page_title: "Homepagina", // These are all o the other translations - "log_out_btn": "Log Uit", - "copy_token_btn": "Kopieer Token", - "renew_lease_btn": "Vernieuw Token-lease", + log_out_btn: "Log Uit", + copy_token_btn: "Kopieer Token", + renew_lease_btn: "Vernieuw Token-lease", - "vaulturl_text": "Vault URL: {{text}}", - "password_generator_btn": "Wachtwoordgenerator", - "your_token_expires_in": "Uw token vervalt in {{date, until_date}}" -} + vaulturl_text: "Vault URL: {{text}}", + password_generator_btn: "Wachtwoordgenerator", + your_token_expires_in: "Uw token vervalt in {{date, until_date}}", +}; diff --git a/src/translations/ru.js b/src/translations/ru.js index 7b87731..c57d3b9 100644 --- a/src/translations/ru.js +++ b/src/translations/ru.js @@ -1,164 +1,167 @@ module.exports = { // The localised name for the language - "language_name": "русский", + language_name: "русский", // Internal: The direction of text (ltr or rtl) - "language_direction": "ltr", + language_direction: "ltr", // These are the buttons on the top bar. - "home_btn": "Главная страница", - "back_btn": "Назад", - "refresh_btn": "Обновить", - "me_btn": "Профиль/параметры", + home_btn: "Главная страница", + back_btn: "Назад", + refresh_btn: "Обновить", + me_btn: "Профиль/параметры", // General Notification Messages - "notification_copy_success": "Текст скопирован в буфер обмена.", + notification_copy_success: "Текст скопирован в буфер обмена.", // Copyable Modal - "copy_modal_download_btn": "Загрузить", - "copy_modal_copy_btn": "Копировать", - "copy_modal_close_btn": "Закрыть", + copy_modal_download_btn: "Загрузить", + copy_modal_copy_btn: "Копировать", + copy_modal_close_btn: "Закрыть", // Copyable Input Box - "copy_input_box_copy_icon_text": "Копировать", + copy_input_box_copy_icon_text: "Копировать", // File Upload Input - "file_upload_input_btn": "Загрузить файл", + file_upload_input_btn: "Загрузить файл", // Me Page - "me_page_title": "Профиль/параметры", - "log_out_btn": "Выход", - "seal_vault_btn": "Закрыть хранилище", - "copy_token_btn": "Копировать код доступа", - "renew_lease_btn": "Продлить действие кода доступа", - "change_language_btn": "Выбор языка", + me_page_title: "Профиль/параметры", + log_out_btn: "Выход", + seal_vault_btn: "Закрыть хранилище", + copy_token_btn: "Копировать код доступа", + renew_lease_btn: "Продлить действие кода доступа", + change_language_btn: "Выбор языка", // Home Page - "home_page_title": "Главная страница", - "vaulturl_text": "Адрес хранилища: {{text}}", - "password_generator_btn": "Генератор паролей", - "your_token_expires_in": "Продолжительность ключа: {{date, until_date}}", + home_page_title: "Главная страница", + vaulturl_text: "Адрес хранилища: {{text}}", + password_generator_btn: "Генератор паролей", + your_token_expires_in: "Продолжительность ключа: {{date, until_date}}", // Unseal Page - "unseal_vault_text": "Раскрыть хранилище", - "submit_key_btn": "Отправить ключ", - "unseal_input_btn": "Ввести ключ вручную", - "unseal_qr_btn": "Ввести ключ через QR-код", - "key_input_placeholder": "Ключ", - "unseal_keys_progress": "Ключи: {{progress}}/{{keys_needed}}", + unseal_vault_text: "Раскрыть хранилище", + submit_key_btn: "Отправить ключ", + unseal_input_btn: "Ввести ключ вручную", + unseal_qr_btn: "Ввести ключ через QR-код", + key_input_placeholder: "Ключ", + unseal_keys_progress: "Ключи: {{progress}}/{{keys_needed}}", // Language Selector Page - "set_language_title": "Выбор языка", - "set_language_btn": "Выбрать язык", + set_language_title: "Выбор языка", + set_language_btn: "Выбрать язык", // Password Generator Page - "password_generator_title": "Генератор паролей", - "password_length_title": "Длина пароля ({{min}}/{{max}})", - "gen_password_btn": "Генерировать", + password_generator_title: "Генератор паролей", + password_length_title: "Длина пароля ({{min}}/{{max}})", + gen_password_btn: "Генерировать", // Login Page - "log_in_title": "Вход", - "log_in_with_token": "Вход с кодом доступа", - "log_in_with_username": "Вход по имени", - "token_input": "Код доступа", - "username_input": "Имя пользователя", - "password_input": "Пароль", - "log_in_btn": "Войти", - "token_login_error": "Неправильный код доступа", + log_in_title: "Вход", + log_in_with_token: "Вход с кодом доступа", + log_in_with_username: "Вход по имени", + token_input: "Код доступа", + username_input: "Имя пользователя", + password_input: "Пароль", + log_in_btn: "Войти", + token_login_error: "Неправильный код доступа", // Key Value Delete Page - "kv_delete_title": "Удаление ключа/значения", - "kv_delete_text": "Вы уверены, что хотите удалить это?", - "kv_delete_btn": "Удалить", - "kv_delete_suffix": " (удалить)", + kv_delete_title: "Удаление ключа/значения", + kv_delete_text: "Вы уверены, что хотите удалить это?", + kv_delete_btn: "Удалить", + kv_delete_suffix: " (удалить)", // Key Value New Page - "kv_new_title": "Новый ключ/значение", - "kv_new_suffix": " (новый)", - "kv_new_path": "Относительный путь", - "kv_new_create_btn": "Создать пустые тайные данные", + kv_new_title: "Новый ключ/значение", + kv_new_suffix: " (новый)", + kv_new_path: "Относительный путь", + kv_new_create_btn: "Создать пустые тайные данные", // Key Value Secret Page - "kv_secret_title": "Тайные ключи/значения", - "kv_secret_deleted_text": "Тайная версия данных была удалена, но может быть восстановлена. Вы хотите восстановить её?", - "kv_secret_restore_btn": "Восстановить тайную версию", - "kv_secret_loading": "Загрузка тайных данных..", - "kv_secret_delete_btn": "Удалить", - "kv_secret_delete_all_btn": "Удалить все версии", - "kv_secret_delete_version_btn": "Удалить версию {{ version }}", - "kv_secret_edit_btn": "Редактировать", - "kv_secret_versions_btn": "Версии", + kv_secret_title: "Тайные ключи/значения", + kv_secret_deleted_text: + "Тайная версия данных была удалена, но может быть восстановлена. Вы хотите восстановить её?", + kv_secret_restore_btn: "Восстановить тайную версию", + kv_secret_loading: "Загрузка тайных данных..", + kv_secret_delete_btn: "Удалить", + kv_secret_delete_all_btn: "Удалить все версии", + kv_secret_delete_version_btn: "Удалить версию {{ version }}", + kv_secret_edit_btn: "Редактировать", + kv_secret_versions_btn: "Версии", // Key Value Secret Editor Page - "kv_sec_edit_title": "Редактировать ключи/значения", - "kv_sec_edit_btn": "Редактировать", - "kv_sec_edit_loading": "Загрузка редактора..", - "kv_sec_edit_invalid_json_err": "Некорректный JSON", - "kv_sec_edit_suffix": " (редакт.)", + kv_sec_edit_title: "Редактировать ключи/значения", + kv_sec_edit_btn: "Редактировать", + kv_sec_edit_loading: "Загрузка редактора..", + kv_sec_edit_invalid_json_err: "Некорректный JSON", + kv_sec_edit_suffix: " (редакт.)", // Key Value Secret Versions Page - "kv_sec_versions_title": "Версии ключей/значений", - "kv_sec_versions_suffix": " (версии)", + kv_sec_versions_title: "Версии ключей/значений", + kv_sec_versions_suffix: " (версии)", // Key Value View/List Secrets Page - "kv_view_title": "Просмотр ключей/значений", - "kv_view_cubbyhole_text": "При использовании cubbyhole, тайные данные можно хранить до тех пор, пока действителен ваш код доступа. Они будут удалены при истечении кода и могут быть просмотрены только с использованием этого кода.", - "kv_view_new_btn": "Создать", - "kv_view_none_here_text": "У вас на данный момент нет тайных данных. Хотите ли вы их создать?", + kv_view_title: "Просмотр ключей/значений", + kv_view_cubbyhole_text: + "При использовании cubbyhole, тайные данные можно хранить до тех пор, пока действителен ваш код доступа. Они будут удалены при истечении кода и могут быть просмотрены только с использованием этого кода.", + kv_view_new_btn: "Создать", + kv_view_none_here_text: "У вас на данный момент нет тайных данных. Хотите ли вы их создать?", // TOTP View Page - "totp_view_title": "TOTP", - "totp_view_new_btn": "Добавить ключ TOTP", - "totp_view_loading": "Загрузка кодов TOTP..", - "totp_view_empty": "У вас на данный момент нет кодов TOTP. Хотите ли вы их создать?", - "totp_view_loading_box": "Загрузка..", + totp_view_title: "TOTP", + totp_view_new_btn: "Добавить ключ TOTP", + totp_view_loading: "Загрузка кодов TOTP..", + totp_view_empty: "У вас на данный момент нет кодов TOTP. Хотите ли вы их создать?", + totp_view_loading_box: "Загрузка..", // New TOTP Key Page - "totp_new_title": "Новый ключ TOTP", - "totp_new_suffix": " (новый)", - "totp_new_name_text": "Имя ключа TOTP", - "totp_new_info": "Необходим либо ключ, либо адрес URI. Лучше всего использовать URI, но он может не сработать. Отсканируйте QR-код и скопируйте его адрес.", - "totp_new_uri_input": "URI", - "totp_new_key_input": "Ключ", - "totp_new_add_btn": "Добавить ключ TOTP", + totp_new_title: "Новый ключ TOTP", + totp_new_suffix: " (новый)", + totp_new_name_text: "Имя ключа TOTP", + totp_new_info: + "Необходим либо ключ, либо адрес URI. Лучше всего использовать URI, но он может не сработать. Отсканируйте QR-код и скопируйте его адрес.", + totp_new_uri_input: "URI", + totp_new_key_input: "Ключ", + totp_new_add_btn: "Добавить ключ TOTP", // Transit View Page - "transit_view_title": "Ключи Transit", - "transit_view_none_here_text": "У вас нет ключей Transit, хотите ли вы их создать?", + transit_view_title: "Ключи Transit", + transit_view_none_here_text: "У вас нет ключей Transit, хотите ли вы их создать?", // Transit View Secret Page - "transit_view_secret_title": "Просмотр тайных данных Transit", - "transit_view_encrypt_text": "Зашифровать", - "transit_view_encrypt_icon_text": "Значок шифрования", - "transit_view_encrypt_description": "Зашифровать текст или двоичные данные, закодированные base64.", - "transit_view_decrypt_text": "Расшифровать", - "transit_view_decrypt_description": "Расшифровать шифр-текст.", - "transit_view_decrypt_icon_text": "Значок расшифрования", - "transit_view_rewrap_text": "Перешифровать", - "transit_view_rewrap_description": "Перешифровать шифр-текст, используя другую версию ключа.", - "transit_view_rewrap_icon_text": "Значок перешифрования", + transit_view_secret_title: "Просмотр тайных данных Transit", + transit_view_encrypt_text: "Зашифровать", + transit_view_encrypt_icon_text: "Значок шифрования", + transit_view_encrypt_description: "Зашифровать текст или двоичные данные, закодированные base64.", + transit_view_decrypt_text: "Расшифровать", + transit_view_decrypt_description: "Расшифровать шифр-текст.", + transit_view_decrypt_icon_text: "Значок расшифрования", + transit_view_rewrap_text: "Перешифровать", + transit_view_rewrap_description: "Перешифровать шифр-текст, используя другую версию ключа.", + transit_view_rewrap_icon_text: "Значок перешифрования", // Transit Encrypt Page - "transit_encrypt_title": "Шифрование Transit", - "transit_encrypt_suffix": " (шифр.)", - "transit_encrypt_input_placeholder": "Текст или base64", - "transit_encrypt_already_encoded_checkbox": "Данные уже закодированы в base64?", - "transit_encrypt_encrypt_btn": "Зашифровать", - "transit_encrypt_encryption_result_modal_title": "Результат шифрования", + transit_encrypt_title: "Шифрование Transit", + transit_encrypt_suffix: " (шифр.)", + transit_encrypt_input_placeholder: "Текст или base64", + transit_encrypt_already_encoded_checkbox: "Данные уже закодированы в base64?", + transit_encrypt_encrypt_btn: "Зашифровать", + transit_encrypt_encryption_result_modal_title: "Результат шифрования", // Transit Decrypt Page - "transit_decrypt_title": "Расшифрование Transit", - "transit_decrypt_suffix": " (расшифр.)", - "transit_decrypt_input_placeholder": "Шифр-текст", - "transit_decrypt_decode_checkbox": "Нужно ли раскодировать текст из base64?", - "transit_decrypt_decrypt_btn": "Расшифровать", - "transit_decrypt_decryption_result_modal_title": "Результат расшифрования", + transit_decrypt_title: "Расшифрование Transit", + transit_decrypt_suffix: " (расшифр.)", + transit_decrypt_input_placeholder: "Шифр-текст", + transit_decrypt_decode_checkbox: "Нужно ли раскодировать текст из base64?", + transit_decrypt_decrypt_btn: "Расшифровать", + transit_decrypt_decryption_result_modal_title: "Результат расшифрования", // Transit Rewrap Page - "transit_rewrap_title": "Перешифрование Transit", - "transit_rewrap_suffix": " (перешифр.)", - "transit_rewrap_version_option_text": "{{version_num}}", - "transit_rewrap_latest_version_option_text": "{{version_num}} (последняя версия)", - "transit_rewrap_input_placeholder": "Шифр-текст", - "transit_rewrap_rewrap_btn": "Перешифровать", - "transit_rewrap_result_modal_title": "Результат перешифрования", -} + transit_rewrap_title: "Перешифрование Transit", + transit_rewrap_suffix: " (перешифр.)", + transit_rewrap_version_option_text: "{{version_num}}", + transit_rewrap_latest_version_option_text: "{{version_num}} (последняя версия)", + transit_rewrap_input_placeholder: "Шифр-текст", + transit_rewrap_rewrap_btn: "Перешифровать", + transit_rewrap_result_modal_title: "Результат перешифрования", +}; diff --git a/src/types/Page.ts b/src/types/Page.ts index b7be66e..3b8d6a5 100644 --- a/src/types/Page.ts +++ b/src/types/Page.ts @@ -20,4 +20,4 @@ export class Page { cleanup(): void { // Do Nothing } -} \ No newline at end of file +} diff --git a/src/types/internalErrors.ts b/src/types/internalErrors.ts index dedf068..a3ffcf5 100644 --- a/src/types/internalErrors.ts +++ b/src/types/internalErrors.ts @@ -1,4 +1,4 @@ // These are all errors that the user won't see // but are used internally. -export const DoesNotExistError: Error = new Error("Does not exist.") \ No newline at end of file +export const DoesNotExistError: Error = new Error("Does not exist."); diff --git a/src/utils.ts b/src/utils.ts index f5b5845..9d2a858 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -2,17 +2,19 @@ export function removeDoubleSlash(str: string): string { return str.replace(/\/\/+/g, "/"); } -export const getObjectKeys = - (obj: Record): string[] => Object.getOwnPropertyNames(obj); -export const objectToMap = - (obj: Record): Map => new Map(Object.entries(obj)); -export const sortedObjectMap = - (obj: Record): Map => new Map(Object.entries(obj).sort()); +export const getObjectKeys = (obj: Record): string[] => + Object.getOwnPropertyNames(obj); +export const objectToMap = (obj: Record): Map => + new Map(Object.entries(obj)); +export const sortedObjectMap = (obj: Record): Map => + new Map(Object.entries(obj).sort()); -export function getKeyByObjectPropertyValue(map: Record, searchValue: unknown): string { +export function getKeyByObjectPropertyValue( + map: Record, + searchValue: unknown, +): string { for (const key of getObjectKeys(map)) { - if (map[key] === searchValue) - return key; + if (map[key] === searchValue) return key; } } @@ -23,4 +25,4 @@ export function verifyJSONString(str: string): boolean { return false; } return true; -} \ No newline at end of file +}