Lint code harder.
This commit is contained in:
parent
f4aa14f968
commit
a347939896
|
@ -1,18 +1,20 @@
|
||||||
{
|
{
|
||||||
"extends": [
|
|
||||||
"eslint:recommended",
|
|
||||||
"plugin:import/errors",
|
|
||||||
"plugin:import/warnings",
|
|
||||||
"plugin:@typescript-eslint/recommended"
|
|
||||||
],
|
|
||||||
"plugins": [
|
"plugins": [
|
||||||
"sort-imports-es6-autofix",
|
"sort-imports-es6-autofix",
|
||||||
"@typescript-eslint"
|
"@typescript-eslint"
|
||||||
],
|
],
|
||||||
|
"extends": [
|
||||||
|
"eslint:recommended",
|
||||||
|
"plugin:import/errors",
|
||||||
|
"plugin:import/warnings",
|
||||||
|
"plugin:@typescript-eslint/recommended",
|
||||||
|
"plugin:@typescript-eslint/recommended-requiring-type-checking"
|
||||||
|
],
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"ecmaVersion": 12,
|
"ecmaVersion": 12,
|
||||||
"sourceType": "module",
|
"sourceType": "module",
|
||||||
"experimentalObjectRestSpread": true
|
"experimentalObjectRestSpread": true,
|
||||||
|
"project": "./tsconfig.json"
|
||||||
},
|
},
|
||||||
"globals": {
|
"globals": {
|
||||||
"pageContent": "writable",
|
"pageContent": "writable",
|
||||||
|
|
|
@ -71,7 +71,7 @@ export class PageState {
|
||||||
}
|
}
|
||||||
|
|
||||||
get currentSecretPath(): string[] {
|
get currentSecretPath(): string[] {
|
||||||
return JSON.parse(localStorage.getItem('currentSecretPath') || "[]");
|
return JSON.parse(localStorage.getItem('currentSecretPath') || "[]") as string[];
|
||||||
}
|
}
|
||||||
set currentSecretPath(value: string[]) {
|
set currentSecretPath(value: string[]) {
|
||||||
localStorage.setItem('currentSecretPath', JSON.stringify(value));
|
localStorage.setItem('currentSecretPath', JSON.stringify(value));
|
||||||
|
@ -104,14 +104,14 @@ export class PageState {
|
||||||
}
|
}
|
||||||
get currentPage(): Page | string {
|
get currentPage(): Page | string {
|
||||||
const curPage = localStorage.getItem('currentPage') || "HOME";
|
const curPage = localStorage.getItem('currentPage') || "HOME";
|
||||||
return (allPages as any)[curPage];
|
return allPages[curPage];
|
||||||
}
|
}
|
||||||
set currentPage(value: Page | string) {
|
set currentPage(value: Page | string) {
|
||||||
if (typeof value == 'object') {
|
if (typeof value == 'object') {
|
||||||
const key = getKeyByObjectPropertyValue(allPages, value);
|
const key = getKeyByObjectPropertyValue(allPages, value);
|
||||||
localStorage.setItem('currentPage', key);
|
localStorage.setItem('currentPage', key);
|
||||||
} else {
|
} else {
|
||||||
localStorage.setItem('currentPage', (value as string));
|
localStorage.setItem('currentPage', value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
import { pageState } from "../globalPageState";
|
import { pageState } from "../globalPageState";
|
||||||
|
|
||||||
export function getHeaders(): any {
|
export function getHeaders(): Record<string, string> {
|
||||||
return {
|
return {
|
||||||
"X-Vault-Token": pageState.token,
|
"X-Vault-Token": pageState.token,
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,13 +8,12 @@ export async function usernameLogin(username: string, password: string): Promise
|
||||||
},
|
},
|
||||||
body: JSON.stringify({ "username": username, "password": password })
|
body: JSON.stringify({ "username": username, "password": password })
|
||||||
});
|
});
|
||||||
return fetch(request).then(response => {
|
|
||||||
return response.json();
|
const resp = await fetch(request);
|
||||||
}).then(data => {
|
const data = await resp.json() as { auth?: { client_token: string }; errors?: string[] };
|
||||||
if ("auth" in data) {
|
if ("auth" in data) {
|
||||||
return data.auth.client_token;
|
return data.auth.client_token;
|
||||||
} else if ("errors" in data) {
|
} else if ("errors" in data) {
|
||||||
throw new Error(data.errors[0]);
|
throw new Error(data.errors[0]);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ export async function createOrUpdateSecret(
|
||||||
});
|
});
|
||||||
const response = await fetch(request);
|
const response = await fetch(request);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
const json = await response.json();
|
const json = await response.json() as {errors: string[]};
|
||||||
throw new Error(json.errors[0]);
|
throw new Error(json.errors[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,12 +32,12 @@ export async function deleteSecret(
|
||||||
secretURL = removeDoubleSlash(secretURL).replace(/\/$/, "");
|
secretURL = removeDoubleSlash(secretURL).replace(/\/$/, "");
|
||||||
request = new Request(appendAPIURL(secretURL), {
|
request = new Request(appendAPIURL(secretURL), {
|
||||||
method: "DELETE",
|
method: "DELETE",
|
||||||
headers: (getHeaders() as any),
|
headers: getHeaders(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const response = await fetch(request);
|
const response = await fetch(request);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
const json = await response.json();
|
const json = await response.json() as {errors: string[]};
|
||||||
throw new Error(json.errors[0]);
|
throw new Error(json.errors[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ export async function getSecret(
|
||||||
secretPath: string[],
|
secretPath: string[],
|
||||||
name: string,
|
name: string,
|
||||||
version: string|null = null
|
version: string|null = null
|
||||||
): Promise<Record<any, any>> {
|
): Promise<Record<string, unknown>> {
|
||||||
let secretURL = "";
|
let secretURL = "";
|
||||||
if (mountType == "kv-v2") {
|
if (mountType == "kv-v2") {
|
||||||
secretURL = `/v1/${baseMount}/data/${secretPath.join("")}/${name}`;
|
secretURL = `/v1/${baseMount}/data/${secretPath.join("")}/${name}`;
|
||||||
|
@ -16,12 +16,14 @@ export async function getSecret(
|
||||||
secretURL = `/v1/${baseMount}/${secretPath.join("")}/${name}`;
|
secretURL = `/v1/${baseMount}/${secretPath.join("")}/${name}`;
|
||||||
}
|
}
|
||||||
const request = new Request(appendAPIURL(secretURL), {
|
const request = new Request(appendAPIURL(secretURL), {
|
||||||
headers: (getHeaders() as any),
|
headers: getHeaders(),
|
||||||
});
|
});
|
||||||
|
|
||||||
return fetch(request).then(response => {
|
const resp = await fetch(request);
|
||||||
return response.json();
|
const data = await resp.json() as unknown;
|
||||||
}).then(data => {
|
if (mountType == "kv-v2") {
|
||||||
return mountType == "kv-v2" ? data.data.data : data.data;
|
return (data as {data: {data: Record<string, unknown>}}).data.data;
|
||||||
});
|
} else {
|
||||||
|
return (data as {data: Record<string, unknown>}).data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { appendAPIURL, getHeaders } from "../apiUtils";
|
import { appendAPIURL, getHeaders } from "../apiUtils";
|
||||||
|
|
||||||
type SecretMetadataType = {
|
type SecretMetadataType = {
|
||||||
versions: Record<string, Record<any, any>>
|
versions: Record<string, unknown>
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getSecretMetadata(
|
export async function getSecretMetadata(
|
||||||
|
@ -10,12 +10,10 @@ export async function getSecretMetadata(
|
||||||
name: string
|
name: string
|
||||||
): Promise<SecretMetadataType> {
|
): Promise<SecretMetadataType> {
|
||||||
const request = new Request(appendAPIURL(`/v1/${baseMount}/metadata/${secretPath.join("")}/${name}`), {
|
const request = new Request(appendAPIURL(`/v1/${baseMount}/metadata/${secretPath.join("")}/${name}`), {
|
||||||
headers: (getHeaders() as any),
|
headers: getHeaders(),
|
||||||
});
|
});
|
||||||
|
|
||||||
return fetch(request).then(response => {
|
const resp = await fetch(request);
|
||||||
return response.json();
|
const data = await resp.json() as {data: SecretMetadataType};
|
||||||
}).then(data => {
|
return data.data;
|
||||||
return data.data;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,8 @@ import { DoesNotExistError } from "../../types/internalErrors";
|
||||||
import { appendAPIURL, getHeaders } from "../apiUtils";
|
import { appendAPIURL, getHeaders } from "../apiUtils";
|
||||||
|
|
||||||
export async function getSecrets(
|
export async function getSecrets(
|
||||||
baseMount: string,
|
baseMount: string,
|
||||||
mountType: string,
|
mountType: string,
|
||||||
secretPath: string[]
|
secretPath: string[]
|
||||||
): Promise<string[]> {
|
): Promise<string[]> {
|
||||||
let secretURL = "";
|
let secretURL = "";
|
||||||
|
@ -14,14 +14,12 @@ export async function getSecrets(
|
||||||
secretURL = `/v1/${baseMount}/${secretPath.join("")}?list=true`;
|
secretURL = `/v1/${baseMount}/${secretPath.join("")}?list=true`;
|
||||||
}
|
}
|
||||||
const request = new Request(appendAPIURL(secretURL), {
|
const request = new Request(appendAPIURL(secretURL), {
|
||||||
headers: (getHeaders() as any),
|
headers: getHeaders(),
|
||||||
});
|
|
||||||
return fetch(request).then(response => {
|
|
||||||
if (response.status == 404) {
|
|
||||||
throw DoesNotExistError;
|
|
||||||
}
|
|
||||||
return response.json();
|
|
||||||
}).then(data => {
|
|
||||||
return data.data.keys;
|
|
||||||
});
|
});
|
||||||
|
const resp = await fetch(request);
|
||||||
|
if (resp.status == 404) {
|
||||||
|
throw DoesNotExistError;
|
||||||
|
}
|
||||||
|
const data = await resp.json() as { data: { keys: string[] } };
|
||||||
|
return data.data.keys;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ export async function undeleteSecret(
|
||||||
});
|
});
|
||||||
const response = await fetch(request);
|
const response = await fetch(request);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
const json = await response.json();
|
const json = await response.json() as {errors: string[]};
|
||||||
throw new Error(json.errors[0]);
|
throw new Error(json.errors[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,11 +15,9 @@ export async function getCapabilitiesPath(path: string): Promise<string[]> {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
return fetch(request).then(response => {
|
const response = await fetch(request);
|
||||||
return response.json();
|
const data = await response.json() as {capabilities: string[]};
|
||||||
}).then(data => {
|
return data.capabilities;
|
||||||
return data.capabilities;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getCapabilities(
|
export async function getCapabilities(
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
import { appendAPIURL, getHeaders } from "../apiUtils";
|
import { appendAPIURL, getHeaders } from "../apiUtils";
|
||||||
|
|
||||||
type MountsType = {
|
export type MountType = {
|
||||||
[key: string]: {
|
|
||||||
type: string
|
type: string
|
||||||
options: {
|
options: {
|
||||||
version: string
|
version: string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type MountsType = {
|
||||||
|
[key: string]: MountType;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getMounts(): Promise<MountsType> {
|
export async function getMounts(): Promise<MountsType> {
|
||||||
const request = new Request(appendAPIURL("/v1/sys/internal/ui/mounts"), {
|
const request = new Request(appendAPIURL("/v1/sys/internal/ui/mounts"), {
|
||||||
headers: (getHeaders() as any),
|
headers: getHeaders(),
|
||||||
});
|
|
||||||
return fetch(request).then(response => {
|
|
||||||
return response.json();
|
|
||||||
}).then(data => {
|
|
||||||
return data.data.secret;
|
|
||||||
});
|
});
|
||||||
|
const resp = await fetch(request);
|
||||||
|
const data = await resp.json() as {data: {secret: MountsType}};
|
||||||
|
return data.data.secret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,7 @@ export type SealStatusType = {
|
||||||
|
|
||||||
export async function getSealStatus(): Promise<SealStatusType> {
|
export async function getSealStatus(): Promise<SealStatusType> {
|
||||||
const request = new Request(appendAPIURL("/v1/sys/seal-status"));
|
const request = new Request(appendAPIURL("/v1/sys/seal-status"));
|
||||||
return fetch(request).then(response => {
|
const resp = await fetch(request)
|
||||||
return response.json();
|
const data = await resp.json() as SealStatusType;
|
||||||
}).then(data => {
|
return data;
|
||||||
return data;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,15 @@
|
||||||
import { appendAPIURL, getHeaders } from "../apiUtils";
|
|
||||||
import { TokenInfo } from "../types/token";
|
import { TokenInfo } from "../types/token";
|
||||||
|
import { appendAPIURL, getHeaders } from "../apiUtils";
|
||||||
|
|
||||||
export async function lookupSelf(): Promise<TokenInfo> {
|
export async function lookupSelf(): Promise<TokenInfo> {
|
||||||
const request = new Request(appendAPIURL("/v1/auth/token/lookup-self"), {
|
const request = new Request(appendAPIURL("/v1/auth/token/lookup-self"), {
|
||||||
headers: getHeaders(),
|
headers: getHeaders(),
|
||||||
});
|
});
|
||||||
return fetch(request).then(response => {
|
const resp = await fetch(request);
|
||||||
return response.json();
|
const data = await resp.json() as { data?: TokenInfo; errors?: string[] };
|
||||||
}).then(data => {
|
if ("data" in data) {
|
||||||
if ("data" in data) {
|
return data.data;
|
||||||
return data.data;
|
} else if ("errors" in data) {
|
||||||
} else if ("errors" in data) {
|
throw new Error(data.errors[0]);
|
||||||
throw new Error(data.errors[0]);
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,11 +9,9 @@ export async function renewSelf(): Promise<void> {
|
||||||
},
|
},
|
||||||
body: JSON.stringify({})
|
body: JSON.stringify({})
|
||||||
});
|
});
|
||||||
return fetch(request).then(response => {
|
const resp = await fetch(request)
|
||||||
return response.json();
|
const data = await resp.json() as { errors?: string[] };
|
||||||
}).then(data => {
|
if ("errors" in data) {
|
||||||
if ("errors" in data) {
|
throw new Error(data.errors[0]);
|
||||||
throw new Error(data.errors[0]);
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,9 @@ export async function sealVault(): Promise<void> {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
headers: getHeaders(),
|
headers: getHeaders(),
|
||||||
});
|
});
|
||||||
return fetch(request).then(response => {
|
const resp = await fetch(request)
|
||||||
return response.json();
|
const data = await resp.json() as { errors?: string[] };
|
||||||
}).then(data => {
|
if ("errors" in data) {
|
||||||
if ("errors" in data) {
|
throw new Error(data.errors[0]);
|
||||||
throw new Error(data.errors[0]);
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,9 +10,11 @@ export async function submitUnsealKey(key: string): Promise<void> {
|
||||||
"key": key
|
"key": key
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
const response = await fetch(request);
|
const resp = await fetch(request)
|
||||||
if (!response.ok) {
|
if (!resp.ok) {
|
||||||
const json = await response.json();
|
const data = await resp.json() as { errors?: string[] };
|
||||||
throw new Error(json.errors[0]);
|
if ("errors" in data) {
|
||||||
|
throw new Error(data.errors[0]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { appendAPIURL, getHeaders } from "../apiUtils";
|
import { appendAPIURL, getHeaders } from "../apiUtils";
|
||||||
import { removeDoubleSlash } from "../../utils";
|
import { removeDoubleSlash } from "../../utils";
|
||||||
|
|
||||||
|
|
||||||
export async function addNewTOTP(baseMount: string, parms: {name: string}): Promise<void> {
|
export async function addNewTOTP(baseMount: string, parms: {name: string}): Promise<void> {
|
||||||
const request = new Request(appendAPIURL(removeDoubleSlash(`/v1/${baseMount}/keys/${parms.name}`)), {
|
const request = new Request(appendAPIURL(removeDoubleSlash(`/v1/${baseMount}/keys/${parms.name}`)), {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
@ -11,9 +10,11 @@ export async function addNewTOTP(baseMount: string, parms: {name: string}): Prom
|
||||||
},
|
},
|
||||||
body: JSON.stringify(parms)
|
body: JSON.stringify(parms)
|
||||||
});
|
});
|
||||||
const response = await fetch(request);
|
const resp = await fetch(request)
|
||||||
if (!response.ok) {
|
if (!resp.ok) {
|
||||||
const json = await response.json();
|
const data = await resp.json() as { errors?: string[] };
|
||||||
throw new Error(json.errors[0]);
|
if ("errors" in data) {
|
||||||
|
throw new Error(data.errors[0]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,7 @@ export async function getTOTPCode(baseMount: string, name: string): Promise<stri
|
||||||
new Request(appendAPIURL(`/v1/${baseMount}/code/${name}`), {
|
new Request(appendAPIURL(`/v1/${baseMount}/code/${name}`), {
|
||||||
headers: getHeaders(),
|
headers: getHeaders(),
|
||||||
});
|
});
|
||||||
return fetch(request).then(response => {
|
const resp = await fetch(request)
|
||||||
return response.json();
|
const data = await resp.json() as {data: {code: string}};
|
||||||
}).then(data => {
|
return data.data.code;
|
||||||
return data.data.code;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,15 @@
|
||||||
import { DoesNotExistError } from "../../types/internalErrors";
|
import { DoesNotExistError } from "../../types/internalErrors";
|
||||||
import { appendAPIURL, getHeaders } from "../apiUtils";
|
import { appendAPIURL, getHeaders } from "../apiUtils";
|
||||||
|
|
||||||
|
|
||||||
export async function getTOTPKeys(baseMount: string): Promise<string[]> {
|
export async function getTOTPKeys(baseMount: string): Promise<string[]> {
|
||||||
const request = new Request(appendAPIURL(`/v1/${baseMount}/keys?list=true`), {
|
const request = new Request(appendAPIURL(`/v1/${baseMount}/keys?list=true`), {
|
||||||
headers: getHeaders(),
|
headers: getHeaders(),
|
||||||
});
|
});
|
||||||
return fetch(request).then(response => {
|
|
||||||
if (response.status == 404) {
|
const resp = await fetch(request);
|
||||||
throw DoesNotExistError;
|
if (resp.status == 404) {
|
||||||
}
|
throw DoesNotExistError;
|
||||||
return response.json();
|
}
|
||||||
}).then(data => {
|
const data = await resp.json() as {data: {keys: string[] }};
|
||||||
return data.data.keys;
|
return data.data.keys;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,16 @@
|
||||||
import { DoesNotExistError } from "../../types/internalErrors";
|
import { DoesNotExistError } from "../../types/internalErrors";
|
||||||
import { appendAPIURL, getHeaders } from "../apiUtils";
|
|
||||||
import { TransitKeyType } from "../types/transit";
|
import { TransitKeyType } from "../types/transit";
|
||||||
|
import { appendAPIURL, getHeaders } from "../apiUtils";
|
||||||
|
|
||||||
export async function getTransitKey(baseMount: string, name: string): Promise<TransitKeyType> {
|
export async function getTransitKey(baseMount: string, name: string): Promise<TransitKeyType> {
|
||||||
const request = new Request(appendAPIURL(`/v1/${baseMount}/keys/${name}`), {
|
const request = new Request(appendAPIURL(`/v1/${baseMount}/keys/${name}`), {
|
||||||
headers: getHeaders(),
|
headers: getHeaders(),
|
||||||
});
|
});
|
||||||
return fetch(request).then(response => {
|
|
||||||
if (response.status == 404) {
|
const resp = await fetch(request);
|
||||||
throw DoesNotExistError;
|
if (resp.status == 404) {
|
||||||
}
|
throw DoesNotExistError;
|
||||||
return response.json();
|
}
|
||||||
}).then(data => {
|
const data = await resp.json() as { data: TransitKeyType };
|
||||||
return data.data;
|
return data.data;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,12 +5,10 @@ export async function getTransitKeys(baseMount: string): Promise<string[]> {
|
||||||
const request = new Request(appendAPIURL(`/v1/${baseMount}/keys?list=true`), {
|
const request = new Request(appendAPIURL(`/v1/${baseMount}/keys?list=true`), {
|
||||||
headers: getHeaders(),
|
headers: getHeaders(),
|
||||||
});
|
});
|
||||||
return fetch(request).then(response => {
|
const resp = await fetch(request);
|
||||||
if (response.status == 404) {
|
if (resp.status == 404) {
|
||||||
throw DoesNotExistError;
|
throw DoesNotExistError;
|
||||||
}
|
}
|
||||||
return response.json();
|
const data = await resp.json() as { data: string[] };
|
||||||
}).then(data => {
|
return data.data;
|
||||||
return data.data.keys;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,12 +22,12 @@ export async function transitDecrypt(
|
||||||
},
|
},
|
||||||
body: JSON.stringify(payload)
|
body: JSON.stringify(payload)
|
||||||
});
|
});
|
||||||
|
|
||||||
const response = await fetch(request);
|
const response = await fetch(request);
|
||||||
|
const data = await response.json() as { errors?: string[]; data?: DecryptionResult; };
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
const json = await response.json();
|
throw new Error(data.errors[0]);
|
||||||
throw new Error(json.errors[0]);
|
|
||||||
} else {
|
} else {
|
||||||
const json = await response.json();
|
return data.data;
|
||||||
return json.data;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,12 +22,12 @@ export async function transitEncrypt(
|
||||||
},
|
},
|
||||||
body: JSON.stringify(payload)
|
body: JSON.stringify(payload)
|
||||||
});
|
});
|
||||||
|
|
||||||
const response = await fetch(request);
|
const response = await fetch(request);
|
||||||
|
const data = await response.json() as { errors?: string[]; data?: EncryptionResult; };
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
const json = await response.json();
|
throw new Error(data.errors[0]);
|
||||||
throw new Error(json.errors[0]);
|
|
||||||
} else {
|
} else {
|
||||||
const json = await response.json();
|
return data.data;
|
||||||
return json.data;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,12 +23,12 @@ export async function transitRewrap(
|
||||||
},
|
},
|
||||||
body: JSON.stringify(payload)
|
body: JSON.stringify(payload)
|
||||||
});
|
});
|
||||||
|
|
||||||
const response = await fetch(request);
|
const response = await fetch(request);
|
||||||
|
const data = await response.json() as { errors?: string[]; data?: RewrapResult; };
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
const json = await response.json();
|
throw new Error(data.errors[0]);
|
||||||
throw new Error(json.errors[0]);
|
|
||||||
} else {
|
} else {
|
||||||
const json = await response.json();
|
return data.data;
|
||||||
return json.data;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,11 +9,11 @@ export type TokenInfo = {
|
||||||
id: string;
|
id: string;
|
||||||
identity_policies: string[];
|
identity_policies: string[];
|
||||||
issue_time: string;
|
issue_time: string;
|
||||||
meta: any;
|
meta: Record<string, string>;
|
||||||
num_uses: number;
|
num_uses: number;
|
||||||
orphan: Boolean;
|
orphan: boolean;
|
||||||
path: string;
|
path: string;
|
||||||
policies: string[];
|
policies: string[];
|
||||||
renewable: Boolean;
|
renewable: boolean;
|
||||||
ttl: number;
|
ttl: number;
|
||||||
}
|
}
|
|
@ -14,10 +14,10 @@ export const enum TransitKeyTypes {
|
||||||
// Type when used to make new transit keys.
|
// Type when used to make new transit keys.
|
||||||
export type TransitKeyBaseType = {
|
export type TransitKeyBaseType = {
|
||||||
name: string;
|
name: string;
|
||||||
convergent_encryption: Boolean;
|
convergent_encryption: boolean;
|
||||||
derived: Boolean;
|
derived: boolean;
|
||||||
exportable: Boolean;
|
exportable: boolean;
|
||||||
allow_plaintext_backup: Boolean;
|
allow_plaintext_backup: boolean;
|
||||||
type: keyof typeof TransitKeyTypes;
|
type: keyof typeof TransitKeyTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,8 +28,8 @@ export type TransitKeyType = TransitKeyBaseType & {
|
||||||
};
|
};
|
||||||
min_decryption_version: number;
|
min_decryption_version: number;
|
||||||
min_encryption_version: number;
|
min_encryption_version: number;
|
||||||
supports_encryption: Boolean;
|
supports_encryption: boolean;
|
||||||
supports_decryption: Boolean;
|
supports_decryption: boolean;
|
||||||
supports_derivation: Boolean;
|
supports_derivation: boolean;
|
||||||
supports_signing: Boolean;
|
supports_signing: boolean;
|
||||||
}
|
}
|
|
@ -10,7 +10,7 @@ export interface CopyableInputBoxType extends HTMLElement {
|
||||||
|
|
||||||
export function CopyableInputBox(text: string, copyable = true): CopyableInputBoxType {
|
export function CopyableInputBox(text: string, copyable = true): CopyableInputBoxType {
|
||||||
const inputBoxDiv = (makeElement({ tag: "div" }) as CopyableInputBoxType);
|
const inputBoxDiv = (makeElement({ tag: "div" }) as CopyableInputBoxType);
|
||||||
let inputBoxCopyButton = null;
|
let inputBoxCopyButton: HTMLElement = null;
|
||||||
if (copyable) {
|
if (copyable) {
|
||||||
inputBoxCopyButton = makeElement({
|
inputBoxCopyButton = makeElement({
|
||||||
tag: "a",
|
tag: "a",
|
||||||
|
@ -30,8 +30,8 @@ export function CopyableInputBox(text: string, copyable = true): CopyableInputBo
|
||||||
const inputBoxInput = makeElement({
|
const inputBoxInput = makeElement({
|
||||||
tag: "input",
|
tag: "input",
|
||||||
class: ["uk-input", "uk-input-copyable"],
|
class: ["uk-input", "uk-input-copyable"],
|
||||||
attributes: { "readonly": true, "type": "text" },
|
attributes: { "readonly": "true", "type": "text" },
|
||||||
});
|
}) as HTMLInputElement;
|
||||||
|
|
||||||
const inputBoxInner = MarginInline([
|
const inputBoxInner = MarginInline([
|
||||||
inputBoxCopyButton,
|
inputBoxCopyButton,
|
||||||
|
@ -40,7 +40,7 @@ export function CopyableInputBox(text: string, copyable = true): CopyableInputBo
|
||||||
inputBoxDiv.appendChild(inputBoxInner);
|
inputBoxDiv.appendChild(inputBoxInner);
|
||||||
|
|
||||||
inputBoxDiv.setText = function (text) {
|
inputBoxDiv.setText = function (text) {
|
||||||
(inputBoxInput as HTMLInputElement).value = `${text}`;
|
inputBoxInput.value = `${text}`;
|
||||||
if (copyable) {
|
if (copyable) {
|
||||||
inputBoxCopyButton.dataset.clipboardText = `${text}`;
|
inputBoxCopyButton.dataset.clipboardText = `${text}`;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,19 @@ import { addClipboardNotifications } from "../pageUtils";
|
||||||
import { makeElement } from "../htmlUtils";
|
import { makeElement } from "../htmlUtils";
|
||||||
import ClipboardJS from "clipboard";
|
import ClipboardJS from "clipboard";
|
||||||
import FileSaver from 'file-saver';
|
import FileSaver from 'file-saver';
|
||||||
|
import UIkit from 'uikit/dist/js/uikit.min.js';
|
||||||
import i18next from 'i18next';
|
import i18next from 'i18next';
|
||||||
|
|
||||||
export function CopyableModal(name: string, contentString: string): Element {
|
type FileSaverType = {
|
||||||
return makeElement({
|
saveAs: (blob: Blob, name: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
type ModalType = HTMLElement & {
|
||||||
|
show: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function CopyableModal(name: string, contentString: string): ModalType {
|
||||||
|
const modal = makeElement({
|
||||||
tag: "div",
|
tag: "div",
|
||||||
class: "modal-sections",
|
class: "modal-sections",
|
||||||
attributes: {
|
attributes: {
|
||||||
|
@ -53,9 +62,9 @@ export function CopyableModal(name: string, contentString: string): Element {
|
||||||
"data-clipboard-text": contentString
|
"data-clipboard-text": contentString
|
||||||
},
|
},
|
||||||
text: i18next.t("copy_modal_download_btn"),
|
text: i18next.t("copy_modal_download_btn"),
|
||||||
onclick: _ => {
|
onclick: () => {
|
||||||
const blob = new Blob([contentString], {type: "text/plain;charset=utf-8"});
|
const blob = new Blob([contentString], { type: "text/plain;charset=utf-8" });
|
||||||
FileSaver.saveAs(blob, "result.txt");
|
(FileSaver as FileSaverType).saveAs(blob, "result.txt");
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
makeElement({
|
makeElement({
|
||||||
|
@ -82,5 +91,9 @@ export function CopyableModal(name: string, contentString: string): Element {
|
||||||
}),
|
}),
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
});
|
}) as ModalType;
|
||||||
|
modal.show = () => {
|
||||||
|
(UIkit as { modal: (ModalType) => { show: () => void } }).modal(modal).show();
|
||||||
|
}
|
||||||
|
return modal;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ export async function QRScanner(onScan: (code: string) => void): Promise<QRScann
|
||||||
if (lastSeenValue == value) return;
|
if (lastSeenValue == value) return;
|
||||||
onScan(value);
|
onScan(value);
|
||||||
});
|
});
|
||||||
qrScanner.start();
|
void qrScanner.start();
|
||||||
|
|
||||||
QRInput.deinit = () => {
|
QRInput.deinit = () => {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { makeElement } from "../htmlUtils";
|
import { makeElement } from "../htmlUtils";
|
||||||
|
|
||||||
type TileParams = {
|
type TileParams = {
|
||||||
condition: Boolean;
|
condition: boolean;
|
||||||
title: string;
|
title: string;
|
||||||
description: string;
|
description: string;
|
||||||
icon: string;
|
icon: string;
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
import { appendAPIURL, getHeaders } from "../api/apiUtils";
|
|
||||||
|
|
||||||
export async function renewSelf(): Promise<void> {
|
|
||||||
const request = new Request(appendAPIURL("/v1/auth/token/renew-self"), {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
...getHeaders(),
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
body: JSON.stringify({})
|
|
||||||
});
|
|
||||||
return fetch(request).then(response => {
|
|
||||||
return response.json();
|
|
||||||
}).then(data => {
|
|
||||||
if ("errors" in data) {
|
|
||||||
throw new Error(data.errors[0]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -2,7 +2,7 @@ import { de, enGB, fr, it, nl, ru } from 'date-fns/locale'
|
||||||
import { formatDistance as formatDistanceReal} from 'date-fns';
|
import { formatDistance as formatDistanceReal} from 'date-fns';
|
||||||
import { pageState } from "./globalPageState";
|
import { pageState } from "./globalPageState";
|
||||||
|
|
||||||
function getLocale(): any {
|
function getLocale(): Locale {
|
||||||
return {
|
return {
|
||||||
"en": enGB,
|
"en": enGB,
|
||||||
"fr": fr,
|
"fr": fr,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { getObjectKeys } from "./utils";
|
import { getObjectKeys } from "./utils";
|
||||||
|
|
||||||
type optionsFunctionsObject = {
|
type optionsFunctionsObject = {
|
||||||
[key: string]: (e: any, arg: any) => void
|
[key: string]: (e: Element, arg: unknown) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const optionsFunctions: optionsFunctionsObject = {
|
const optionsFunctions: optionsFunctionsObject = {
|
||||||
|
@ -13,9 +13,9 @@ const optionsFunctions: optionsFunctionsObject = {
|
||||||
},
|
},
|
||||||
"id": (e: Element, arg: string) => e.id = arg,
|
"id": (e: Element, arg: string) => e.id = arg,
|
||||||
"html": (e: Element, arg: string) => e.innerHTML = arg,
|
"html": (e: Element, arg: string) => e.innerHTML = arg,
|
||||||
"onclick": (e: HTMLButtonElement, arg: any) => e.onclick = arg,
|
"onclick": (e: Element, arg: () => void) => (e as HTMLButtonElement).onclick = arg,
|
||||||
"attributes": setElementAttributes,
|
"attributes": setElementAttributes,
|
||||||
"text": (e: HTMLParagraphElement, arg: string) => e.innerText = arg,
|
"text": (e: Element, arg: string) => (e as HTMLParagraphElement).innerText = arg,
|
||||||
"children": (e: Element, arg: Element | Element[]) => {
|
"children": (e: Element, arg: Element | Element[]) => {
|
||||||
if (Array.isArray(arg)) {
|
if (Array.isArray(arg)) {
|
||||||
arg.forEach(child => {
|
arg.forEach(child => {
|
||||||
|
@ -34,13 +34,12 @@ interface ElementInfo {
|
||||||
class?: string | string[];
|
class?: string | string[];
|
||||||
id?: string;
|
id?: string;
|
||||||
html?: string;
|
html?: string;
|
||||||
attributes?: {
|
attributes?: Record<string, string>;
|
||||||
[propName: string]: any
|
|
||||||
};
|
|
||||||
children?: Element | Element[];
|
children?: Element | Element[];
|
||||||
text?: string;
|
text?: string;
|
||||||
thenRun?: (e: Element) => void;
|
thenRun?: (e: Element) => void;
|
||||||
[propName: string]: any;
|
onclick?: () => void;
|
||||||
|
[propName: string]: unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function makeElement(elementInfo: ElementInfo): HTMLElement {
|
export function makeElement(elementInfo: ElementInfo): HTMLElement {
|
||||||
|
@ -49,14 +48,14 @@ export function makeElement(elementInfo: ElementInfo): HTMLElement {
|
||||||
|
|
||||||
for (const key of Object.getOwnPropertyNames(elementInfo)) {
|
for (const key of Object.getOwnPropertyNames(elementInfo)) {
|
||||||
if (getObjectKeys(optionsFunctions).includes(key)) {
|
if (getObjectKeys(optionsFunctions).includes(key)) {
|
||||||
(optionsFunctions as any)[key](element, elementInfo[key]);
|
optionsFunctions[key](element, elementInfo[key]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setElementAttributes(element: Element, attributes: { [propName: string]: any }): void {
|
export function setElementAttributes(element: Element, attributes: Record<string, string>): void {
|
||||||
for (const key of Object.getOwnPropertyNames(attributes)) {
|
for (const key of Object.getOwnPropertyNames(attributes)) {
|
||||||
element.setAttribute(key, attributes[key]);
|
element.setAttribute(key, attributes[key]);
|
||||||
}
|
}
|
||||||
|
|
50
src/main.ts
50
src/main.ts
|
@ -2,14 +2,16 @@
|
||||||
|
|
||||||
// JS & CSS
|
// JS & CSS
|
||||||
|
|
||||||
|
/* eslint-disable */
|
||||||
import "./scss/main.scss";
|
import "./scss/main.scss";
|
||||||
import Icons from 'uikit/dist/js/uikit-icons.min.js';
|
import Icons from 'uikit/dist/js/uikit-icons.min.js';
|
||||||
import UIkit from 'uikit/dist/js/uikit.min.js';
|
import UIkit from 'uikit/dist/js/uikit.min.js';
|
||||||
|
// @ts-ignore
|
||||||
UIkit.use(Icons);
|
UIkit.use(Icons);
|
||||||
|
|
||||||
/* eslint-disable */
|
|
||||||
import Prism from "prismjs";
|
import Prism from "prismjs";
|
||||||
import "prismjs/components/prism-json";
|
import "prismjs/components/prism-json";
|
||||||
|
// @ts-ignore
|
||||||
Prism.highlightAll();
|
Prism.highlightAll();
|
||||||
/* eslint-enable */
|
/* eslint-enable */
|
||||||
|
|
||||||
|
@ -29,14 +31,19 @@ import i18next from 'i18next';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import translations from './translations/index.mjs'
|
import translations from './translations/index.mjs'
|
||||||
|
|
||||||
function ListItem(children) {
|
function ListItem(children: Element[] | Element): HTMLElement {
|
||||||
return makeElement({
|
return makeElement({
|
||||||
tag: "li",
|
tag: "li",
|
||||||
children: children
|
children: children
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onLoad() {
|
declare global {
|
||||||
|
interface Window { pageContent: Element; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function onLoad(): void {
|
||||||
document.body.innerHTML = "";
|
document.body.innerHTML = "";
|
||||||
document.body.appendChild(makeElement({
|
document.body.appendChild(makeElement({
|
||||||
tag: "nav",
|
tag: "nav",
|
||||||
|
@ -52,17 +59,17 @@ async function onLoad() {
|
||||||
ListItem(makeElement({
|
ListItem(makeElement({
|
||||||
tag: "a",
|
tag: "a",
|
||||||
text: i18next.t("home_btn"),
|
text: i18next.t("home_btn"),
|
||||||
onclick: _ => { changePage("HOME"); }
|
onclick: () => { changePage("HOME"); }
|
||||||
})),
|
})),
|
||||||
ListItem(makeElement({
|
ListItem(makeElement({
|
||||||
tag: "a",
|
tag: "a",
|
||||||
text: i18next.t("back_btn"),
|
text: i18next.t("back_btn"),
|
||||||
onclick: _ => { (pageState.currentPage as Page).goBack(); }
|
onclick: () => { (pageState.currentPage as Page).goBack(); }
|
||||||
})),
|
})),
|
||||||
ListItem(makeElement({
|
ListItem(makeElement({
|
||||||
tag: "a",
|
tag: "a",
|
||||||
text: i18next.t("refresh_btn"),
|
text: i18next.t("refresh_btn"),
|
||||||
onclick: _ => { changePage(pageState.currentPageString); }
|
onclick: () => { changePage(pageState.currentPageString); }
|
||||||
})),
|
})),
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
@ -77,7 +84,7 @@ async function onLoad() {
|
||||||
ListItem(makeElement({
|
ListItem(makeElement({
|
||||||
tag: "a",
|
tag: "a",
|
||||||
text: i18next.t("me_btn"),
|
text: i18next.t("me_btn"),
|
||||||
onclick: _ => { changePage("ME"); }
|
onclick: () => { changePage("ME"); }
|
||||||
}))
|
}))
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
@ -105,43 +112,44 @@ async function onLoad() {
|
||||||
})
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
(window as any).pageContent = document.querySelector("#pageContent");
|
window.pageContent = document.querySelector("#pageContent");
|
||||||
|
|
||||||
if (process.env.NODE_ENV == "development") {
|
if (process.env.NODE_ENV == "development") {
|
||||||
await playground();
|
playground();
|
||||||
}
|
}
|
||||||
|
|
||||||
renderPage();
|
renderPage();
|
||||||
|
|
||||||
setInterval(async () => {
|
setInterval(() => {
|
||||||
if (pageState.currentPageString != "UNSEAL") {
|
if (pageState.currentPageString != "UNSEAL") {
|
||||||
if (pageState.apiURL.length != 0) { return; }
|
if (pageState.apiURL.length != 0) { return; }
|
||||||
const sealStatus = await getSealStatus();
|
void getSealStatus().then((sealStatus) => {
|
||||||
if (sealStatus.sealed) {
|
if (sealStatus.sealed) {
|
||||||
changePage("UNSEAL");
|
changePage("UNSEAL");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}, 5000);
|
}, 5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', async function () {
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
console.log("Loading...");
|
console.log("Loading...");
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
console.log("Build Data:", BUILD_STRING);
|
console.log("Build Data:", BUILD_STRING);
|
||||||
i18next.init({
|
void i18next.init({
|
||||||
lng: pageState.language,
|
lng: pageState.language,
|
||||||
fallbackLng: 'en',
|
fallbackLng: 'en',
|
||||||
debug: true,
|
debug: true,
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
resources: Object.fromEntries(Object.entries(translations).map(([k, v]) => [k, { translation: v }])),
|
resources: Object.fromEntries(Object.entries(translations).map(([k, v]) => [k, { translation: v }])),
|
||||||
interpolation: {
|
interpolation: {
|
||||||
format: function (value, format, _) {
|
format: function (value: unknown, format, _): string {
|
||||||
if (format === 'until_date' && value instanceof Date) return formatDistance(new Date(), new Date(value));
|
if (format === 'until_date' && value instanceof Date) return formatDistance(new Date(), new Date(value));
|
||||||
return value;
|
return value as string;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).then(async function (_) {
|
}).then(function (_) {
|
||||||
await onLoad();
|
onLoad();
|
||||||
});
|
});
|
||||||
}, false);
|
}, false);
|
||||||
|
|
|
@ -46,13 +46,13 @@ export async function prePageChecks(): Promise<boolean> {
|
||||||
|
|
||||||
export function addClipboardNotifications(clipboard: ClipboardJS, timeout = 1000): void {
|
export function addClipboardNotifications(clipboard: ClipboardJS, timeout = 1000): void {
|
||||||
clipboard.on('success', () => {
|
clipboard.on('success', () => {
|
||||||
(UIkit as any).notification(i18next.t("notification_copy_success"), {
|
(UIkit as {notification: (title: unknown, options: unknown) => void}).notification(i18next.t("notification_copy_success"), {
|
||||||
status: 'success',
|
status: 'success',
|
||||||
timeout: timeout
|
timeout: timeout
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
clipboard.on('error', function (e: Error) {
|
clipboard.on('error', function (e: Error) {
|
||||||
(UIkit as any).notification(i18next.t("notification_copy_error", {
|
(UIkit as {notification: (title: unknown, options: unknown) => void}).notification(i18next.t("notification_copy_error", {
|
||||||
"error": e.message
|
"error": e.message
|
||||||
}), {
|
}), {
|
||||||
status: 'danger',
|
status: 'danger',
|
||||||
|
@ -64,9 +64,9 @@ export function addClipboardNotifications(clipboard: ClipboardJS, timeout = 1000
|
||||||
export function setErrorText(text: string): void {
|
export function setErrorText(text: string): void {
|
||||||
const errorTextElement = document.querySelector("#errorText");
|
const errorTextElement = document.querySelector("#errorText");
|
||||||
if (errorTextElement) {
|
if (errorTextElement) {
|
||||||
(document.querySelector("#errorText") as HTMLElement).innerText = `Error: ${text}`;
|
(document.querySelector("#errorText") as HTMLParagraphElement).innerText = `Error: ${text}`;
|
||||||
}
|
}
|
||||||
(UIkit as any).notification({
|
(UIkit as {notification: (options: unknown) => void}).notification({
|
||||||
message: `Error: ${text}`,
|
message: `Error: ${text}`,
|
||||||
status: 'danger',
|
status: 'danger',
|
||||||
pos: 'top-center',
|
pos: 'top-center',
|
||||||
|
@ -87,13 +87,13 @@ export function changePage(page: string, shouldSwitch = true): void {
|
||||||
export function renderPage(): void {
|
export function renderPage(): void {
|
||||||
document.documentElement.dir = pageState.pageDirection;
|
document.documentElement.dir = pageState.pageDirection;
|
||||||
console.log("Rendering Page: ", (pageState.currentPage as Page).name);
|
console.log("Rendering Page: ", (pageState.currentPage as Page).name);
|
||||||
(document.querySelector("#pageContent") as HTMLElement).innerHTML = "";
|
(document.querySelector("#pageContent") ).innerHTML = "";
|
||||||
setPageTitle((pageState.currentPage as Page).name);
|
setPageTitle((pageState.currentPage as Page).name);
|
||||||
(pageState.currentPage as Page).render();
|
(pageState.currentPage as Page).render();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setPageTitle(title: string | HTMLElement): void {
|
export function setPageTitle(title: string | HTMLElement): void {
|
||||||
const pageTitle = (document.getElementById("pageTitle") as HTMLElement);
|
const pageTitle = (document.getElementById("pageTitle") );
|
||||||
pageTitle.innerHTML = "";
|
pageTitle.innerHTML = "";
|
||||||
if (typeof title === "string") {
|
if (typeof title === "string") {
|
||||||
pageTitle.innerText = title.toString();
|
pageTitle.innerText = title.toString();
|
||||||
|
@ -154,7 +154,7 @@ export function setTitleElement(pageState: PageState): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setPageContent(content: string | HTMLElement): void {
|
export function setPageContent(content: string | HTMLElement): void {
|
||||||
const pageContent = (document.getElementById("pageContent") as HTMLElement);
|
const pageContent = (document.getElementById("pageContent") );
|
||||||
if (typeof content === "string") {
|
if (typeof content === "string") {
|
||||||
pageContent.innerHTML = content;
|
pageContent.innerHTML = content;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
import { MountType, getMounts } from "../api/sys/getMounts";
|
||||||
import { Page } from "../types/Page";
|
import { Page } from "../types/Page";
|
||||||
import { changePage, prePageChecks, setErrorText, setPageContent } from "../pageUtils";
|
import { changePage, prePageChecks, setErrorText, setPageContent } from "../pageUtils";
|
||||||
import { getMounts } from "../api/sys/getMounts";
|
|
||||||
import { lookupSelf } from "../api/sys/lookupSelf";
|
import { lookupSelf } from "../api/sys/lookupSelf";
|
||||||
import { makeElement } from "../htmlUtils";
|
import { makeElement } from "../htmlUtils";
|
||||||
import { pageState } from "../globalPageState";
|
import { pageState } from "../globalPageState";
|
||||||
|
@ -48,9 +48,10 @@ export class HomePage extends Page {
|
||||||
tag: "li",
|
tag: "li",
|
||||||
text: i18next.t("your_token_expires_in", {"date": new Date(selfTokenInfo.expire_time)})
|
text: i18next.t("your_token_expires_in", {"date": new Date(selfTokenInfo.expire_time)})
|
||||||
}));
|
}));
|
||||||
} catch (e) {
|
} catch (e: unknown) {
|
||||||
setErrorText(e.message);
|
const error = e as Error;
|
||||||
if (e.message == "permission denied") {
|
setErrorText(error.message);
|
||||||
|
if (error.message == "permission denied") {
|
||||||
pageState.token = "";
|
pageState.token = "";
|
||||||
changePage("LOGIN");
|
changePage("LOGIN");
|
||||||
}
|
}
|
||||||
|
@ -68,7 +69,7 @@ export class HomePage extends Page {
|
||||||
// sort it by secretPath so it's in alphabetical order consistantly.
|
// sort it by secretPath so it's in alphabetical order consistantly.
|
||||||
const mountsMap = sortedObjectMap(mounts);
|
const mountsMap = sortedObjectMap(mounts);
|
||||||
|
|
||||||
mountsMap.forEach(function (mount, baseMount) {
|
mountsMap.forEach(function (mount: MountType, baseMount) {
|
||||||
if (typeof mount != 'object') return;
|
if (typeof mount != 'object') return;
|
||||||
if (mount == null) return;
|
if (mount == null) return;
|
||||||
if (!("type" in mount)) return;
|
if (!("type" in mount)) return;
|
||||||
|
@ -97,7 +98,7 @@ export class HomePage extends Page {
|
||||||
children: makeElement({
|
children: makeElement({
|
||||||
tag: "a",
|
tag: "a",
|
||||||
text: linkText,
|
text: linkText,
|
||||||
onclick: _ => {
|
onclick: () => {
|
||||||
pageState.currentBaseMount = baseMount;
|
pageState.currentBaseMount = baseMount;
|
||||||
pageState.currentMountType = mountType;
|
pageState.currentMountType = mountType;
|
||||||
changePage(linkPage);
|
changePage(linkPage);
|
||||||
|
|
|
@ -31,8 +31,8 @@ export class KeyValueDeletePage extends Page {
|
||||||
tag: "button",
|
tag: "button",
|
||||||
class: ["uk-button", "uk-button-danger"],
|
class: ["uk-button", "uk-button-danger"],
|
||||||
text: i18next.t("kv_delete_btn"),
|
text: i18next.t("kv_delete_btn"),
|
||||||
onclick: _ => {
|
onclick: () => {
|
||||||
deleteSecret(
|
void deleteSecret(
|
||||||
pageState.currentBaseMount,
|
pageState.currentBaseMount,
|
||||||
pageState.currentMountType,
|
pageState.currentMountType,
|
||||||
pageState.currentSecretPath,
|
pageState.currentSecretPath,
|
||||||
|
|
|
@ -29,7 +29,7 @@ export class KeyValueNewPage extends Page {
|
||||||
tag: "input",
|
tag: "input",
|
||||||
class: ["uk-input", "uk-form-width-medium"],
|
class: ["uk-input", "uk-form-width-medium"],
|
||||||
attributes: {
|
attributes: {
|
||||||
required: true,
|
required: "true",
|
||||||
type: "text",
|
type: "text",
|
||||||
placeholder: i18next.t("kv_new_path"),
|
placeholder: i18next.t("kv_new_path"),
|
||||||
name: "path"
|
name: "path"
|
||||||
|
@ -53,9 +53,9 @@ export class KeyValueNewPage extends Page {
|
||||||
}) as HTMLFormElement;
|
}) as HTMLFormElement;
|
||||||
setPageContent(this.addKVNewForm);
|
setPageContent(this.addKVNewForm);
|
||||||
|
|
||||||
this.addKVNewForm.addEventListener("submit", function (e) {
|
this.addKVNewForm.addEventListener("submit", function (e: Event) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.newKVSecretHandleForm();
|
(this as KeyValueNewPage).newKVSecretHandleForm();
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ export class KeyValueNewPage extends Page {
|
||||||
).then(_ => {
|
).then(_ => {
|
||||||
changePage("KEY_VALUE_VIEW");
|
changePage("KEY_VALUE_VIEW");
|
||||||
return;
|
return;
|
||||||
}).catch(e => {
|
}).catch((e: Error) => {
|
||||||
setErrorText(e.message);
|
setErrorText(e.message);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,7 @@ export class KeyValueSecretPage extends Page {
|
||||||
tag: "button",
|
tag: "button",
|
||||||
id: "deleteButton",
|
id: "deleteButton",
|
||||||
class: ["uk-button", "uk-button-danger"],
|
class: ["uk-button", "uk-button-danger"],
|
||||||
onclick: _ => { changePage("KEY_VALUE_DELETE"); },
|
onclick: () => { changePage("KEY_VALUE_DELETE"); },
|
||||||
text: deleteButtonText
|
text: deleteButtonText
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ export class KeyValueSecretPage extends Page {
|
||||||
tag: "button",
|
tag: "button",
|
||||||
id: "editButton",
|
id: "editButton",
|
||||||
class: ["uk-button", "uk-margin", "uk-button-primary"],
|
class: ["uk-button", "uk-margin", "uk-button-primary"],
|
||||||
onclick: _ => { changePage("KEY_VALUE_SECRET_EDIT"); },
|
onclick: () => { changePage("KEY_VALUE_SECRET_EDIT"); },
|
||||||
text: i18next.t("kv_secret_edit_btn")
|
text: i18next.t("kv_secret_edit_btn")
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
@ -86,12 +86,12 @@ export class KeyValueSecretPage extends Page {
|
||||||
tag: "button",
|
tag: "button",
|
||||||
id: "versionsButton",
|
id: "versionsButton",
|
||||||
class: ["uk-button", "uk-button-secondary"],
|
class: ["uk-button", "uk-button-secondary"],
|
||||||
onclick: _ => { changePage("KEY_VALUE_VERSIONS"); },
|
onclick: () => { changePage("KEY_VALUE_VERSIONS"); },
|
||||||
text: i18next.t("kv_secret_versions_btn")
|
text: i18next.t("kv_secret_versions_btn")
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
getSecret(
|
void getSecret(
|
||||||
pageState.currentBaseMount,
|
pageState.currentBaseMount,
|
||||||
pageState.currentMountType,
|
pageState.currentMountType,
|
||||||
pageState.currentSecretPath,
|
pageState.currentSecretPath,
|
||||||
|
@ -113,7 +113,7 @@ export class KeyValueSecretPage extends Page {
|
||||||
id: "restoreButton",
|
id: "restoreButton",
|
||||||
class: ["uk-button", "uk-button-primary"],
|
class: ["uk-button", "uk-button-primary"],
|
||||||
onclick: () => {
|
onclick: () => {
|
||||||
undeleteSecret(
|
void undeleteSecret(
|
||||||
pageState.currentBaseMount,
|
pageState.currentBaseMount,
|
||||||
pageState.currentSecretPath,
|
pageState.currentSecretPath,
|
||||||
pageState.currentSecret,
|
pageState.currentSecret,
|
||||||
|
@ -133,14 +133,18 @@ export class KeyValueSecretPage extends Page {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isSecretNestedJson) {
|
if (isSecretNestedJson) {
|
||||||
const jsonText = JSON.stringify(sortedObjectMap(secretsMap as Record<any, any>), null, 4);
|
const jsonText = JSON.stringify(
|
||||||
|
sortedObjectMap(secretsMap as unknown as Record<string, unknown>),
|
||||||
|
null,
|
||||||
|
4
|
||||||
|
);
|
||||||
kvList.appendChild(makeElement({
|
kvList.appendChild(makeElement({
|
||||||
tag: "pre",
|
tag: "pre",
|
||||||
class: ["code-block", "language-json", "line-numbers"],
|
class: ["code-block", "language-json", "line-numbers"],
|
||||||
html: Prism.highlight(jsonText, Prism.languages.json, 'json')
|
html: (Prism as { highlight: (text: string, language: null, languageStr: string) => string }).highlight(jsonText, null, 'json')
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
secretsMap.forEach((value, key) => {
|
secretsMap.forEach((value: string, key: string) => {
|
||||||
const kvListElement = this.makeKVListElement(key, value);
|
const kvListElement = this.makeKVListElement(key, value);
|
||||||
kvList.appendChild(kvListElement);
|
kvList.appendChild(kvListElement);
|
||||||
}, this);
|
}, this);
|
||||||
|
|
|
@ -43,7 +43,7 @@ export class KeyValueSecretEditPage extends Page {
|
||||||
saveButton
|
saveButton
|
||||||
]
|
]
|
||||||
}));
|
}));
|
||||||
getSecret(
|
void getSecret(
|
||||||
pageState.currentBaseMount,
|
pageState.currentBaseMount,
|
||||||
pageState.currentMountType,
|
pageState.currentMountType,
|
||||||
pageState.currentSecretPath,
|
pageState.currentSecretPath,
|
||||||
|
@ -70,7 +70,7 @@ export class KeyValueSecretEditPage extends Page {
|
||||||
).then(_ => {
|
).then(_ => {
|
||||||
changePage("KEY_VALUE_SECRET");
|
changePage("KEY_VALUE_SECRET");
|
||||||
return;
|
return;
|
||||||
}).catch(e => {
|
}).catch((e: Error) => {
|
||||||
setErrorText(e.message);
|
setErrorText(e.message);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -39,7 +39,7 @@ export class KeyValueVersionsPage extends Page {
|
||||||
children: makeElement({
|
children: makeElement({
|
||||||
tag: "a",
|
tag: "a",
|
||||||
text: `v${ver}`,
|
text: `v${ver}`,
|
||||||
onclick: _ => {
|
onclick: () => {
|
||||||
pageState.currentSecretVersion = ver;
|
pageState.currentSecretVersion = ver;
|
||||||
changePage("KEY_VALUE_SECRET");
|
changePage("KEY_VALUE_SECRET");
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,7 @@ export class KeyValueViewPage extends Page {
|
||||||
children: makeElement({
|
children: makeElement({
|
||||||
tag: "a",
|
tag: "a",
|
||||||
text: secret,
|
text: secret,
|
||||||
onclick: _ => {
|
onclick: () => {
|
||||||
if (secret.endsWith("/")) {
|
if (secret.endsWith("/")) {
|
||||||
pageState.pushCurrentSecretPath(secret);
|
pageState.pushCurrentSecretPath(secret);
|
||||||
changePage("KEY_VALUE_VIEW");
|
changePage("KEY_VALUE_VIEW");
|
||||||
|
@ -75,8 +75,9 @@ export class KeyValueViewPage extends Page {
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
}));
|
}));
|
||||||
} catch (e) {
|
} catch (e: unknown) {
|
||||||
if (e == DoesNotExistError) {
|
const error = e as Error;
|
||||||
|
if (error == DoesNotExistError) {
|
||||||
// getSecrets also 404's on no keys so dont go all the way back.
|
// getSecrets also 404's on no keys so dont go all the way back.
|
||||||
if (pageState.currentSecretPath.length != 0) {
|
if (pageState.currentSecretPath.length != 0) {
|
||||||
return this.goBack();
|
return this.goBack();
|
||||||
|
@ -87,7 +88,7 @@ export class KeyValueViewPage extends Page {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setErrorText(e.message);
|
setErrorText(error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ export class LoginPage extends Page {
|
||||||
tag: "input",
|
tag: "input",
|
||||||
class: ["uk-input", "uk-form-width-medium"],
|
class: ["uk-input", "uk-form-width-medium"],
|
||||||
attributes: {
|
attributes: {
|
||||||
required: true,
|
required: "true",
|
||||||
type: "password",
|
type: "password",
|
||||||
placeholder: i18next.t("token_input"),
|
placeholder: i18next.t("token_input"),
|
||||||
name: "token"
|
name: "token"
|
||||||
|
@ -45,7 +45,7 @@ export class LoginPage extends Page {
|
||||||
id: "usernameInput",
|
id: "usernameInput",
|
||||||
class: ["uk-input", "uk-form-width-medium"],
|
class: ["uk-input", "uk-form-width-medium"],
|
||||||
attributes: {
|
attributes: {
|
||||||
required: true,
|
required: "true",
|
||||||
type: "text",
|
type: "text",
|
||||||
placeholder: i18next.t("username_input"),
|
placeholder: i18next.t("username_input"),
|
||||||
name: "username"
|
name: "username"
|
||||||
|
@ -56,7 +56,7 @@ export class LoginPage extends Page {
|
||||||
id: "passwordInput",
|
id: "passwordInput",
|
||||||
class: ["uk-input", "uk-form-width-medium"],
|
class: ["uk-input", "uk-form-width-medium"],
|
||||||
attributes: {
|
attributes: {
|
||||||
required: true,
|
required: "true",
|
||||||
type: "password",
|
type: "password",
|
||||||
placeholder: i18next.t("password_input"),
|
placeholder: i18next.t("password_input"),
|
||||||
name: "password"
|
name: "password"
|
||||||
|
@ -127,7 +127,7 @@ export class LoginPage extends Page {
|
||||||
pageState.token = token as string;
|
pageState.token = token as string;
|
||||||
lookupSelf().then(_ => {
|
lookupSelf().then(_ => {
|
||||||
changePage("HOME");
|
changePage("HOME");
|
||||||
}).catch(e => {
|
}).catch((e: Error) => {
|
||||||
document.getElementById("tokenInput").classList.add("uk-form-danger");
|
document.getElementById("tokenInput").classList.add("uk-form-danger");
|
||||||
if (e.message == "permission denied") {
|
if (e.message == "permission denied") {
|
||||||
setErrorText(i18next.t("token_login_error"));
|
setErrorText(i18next.t("token_login_error"));
|
||||||
|
@ -145,7 +145,7 @@ export class LoginPage extends Page {
|
||||||
).then(res => {
|
).then(res => {
|
||||||
pageState.token = res;
|
pageState.token = res;
|
||||||
changePage("HOME");
|
changePage("HOME");
|
||||||
}).catch(e => {
|
}).catch((e: Error) => {
|
||||||
document.getElementById("usernameInput").classList.add("uk-form-danger");
|
document.getElementById("usernameInput").classList.add("uk-form-danger");
|
||||||
document.getElementById("passwordInput").classList.add("uk-form-danger");
|
document.getElementById("passwordInput").classList.add("uk-form-danger");
|
||||||
setErrorText(e.message);
|
setErrorText(e.message);
|
||||||
|
|
|
@ -53,7 +53,7 @@ export class MePage extends Page {
|
||||||
onclick: () => {
|
onclick: () => {
|
||||||
renewSelf().then(() => {
|
renewSelf().then(() => {
|
||||||
changePage("HOME");
|
changePage("HOME");
|
||||||
}).catch(e => {
|
}).catch((e: Error) => {
|
||||||
setErrorText(e.message);
|
setErrorText(e.message);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { CopyableInputBox, CopyableInputBoxType } from "../elements/CopyableInputBox";
|
import { CopyableInputBox, CopyableInputBoxType } from "../elements/CopyableInputBox";
|
||||||
import { Margin } from "../elements/Margin";
|
import { Margin } from "../elements/Margin";
|
||||||
|
import { Option } from "../elements/Option";
|
||||||
import { Page } from "../types/Page";
|
import { Page } from "../types/Page";
|
||||||
import { makeElement } from "../htmlUtils";
|
import { makeElement } from "../htmlUtils";
|
||||||
import { setPageContent } from "../pageUtils";
|
import { setPageContent } from "../pageUtils";
|
||||||
import i18next from 'i18next';
|
import i18next from 'i18next';
|
||||||
import { Option } from "../elements/Option";
|
|
||||||
|
|
||||||
const passwordLengthMin = 1;
|
const passwordLengthMin = 1;
|
||||||
const passwordLengthMax = 64;
|
const passwordLengthMax = 64;
|
||||||
|
@ -55,7 +55,7 @@ export class PwGenPage extends Page {
|
||||||
passwordAlphabet: HTMLSelectElement;
|
passwordAlphabet: HTMLSelectElement;
|
||||||
passwordForm: HTMLFormElement;
|
passwordForm: HTMLFormElement;
|
||||||
|
|
||||||
async render(): Promise<void> {
|
render(): void {
|
||||||
setPageContent("");
|
setPageContent("");
|
||||||
this.passwordBox = CopyableInputBox(genPassword(passwordOptionsDefault)) ;
|
this.passwordBox = CopyableInputBox(genPassword(passwordOptionsDefault)) ;
|
||||||
|
|
||||||
|
@ -70,9 +70,9 @@ export class PwGenPage extends Page {
|
||||||
class: ["uk-range", "uk-width-1-2"],
|
class: ["uk-range", "uk-width-1-2"],
|
||||||
attributes: {
|
attributes: {
|
||||||
type: "range",
|
type: "range",
|
||||||
value: passwordLengthDefault,
|
value: passwordLengthDefault.toString(),
|
||||||
max: passwordLengthMax,
|
max: passwordLengthMax.toString(),
|
||||||
min: passwordLengthMin,
|
min: passwordLengthMin.toString(),
|
||||||
},
|
},
|
||||||
}) as HTMLInputElement;
|
}) as HTMLInputElement;
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ export class PwGenPage extends Page {
|
||||||
this.passwordLengthTitle.innerText = this.getPasswordLengthText();
|
this.passwordLengthTitle.innerText = this.getPasswordLengthText();
|
||||||
this.passwordBox.setText(genPassword({
|
this.passwordBox.setText(genPassword({
|
||||||
length: (this.passwordLengthRange.value as unknown) as number,
|
length: (this.passwordLengthRange.value as unknown) as number,
|
||||||
alphabet: this.passwordAlphabet.value as string,
|
alphabet: this.passwordAlphabet.value ,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ export class SetLanguagePage extends Page {
|
||||||
const language = formData.get("language") as string;
|
const language = formData.get("language") as string;
|
||||||
pageState.language = language;
|
pageState.language = language;
|
||||||
console.log(pageState.language);
|
console.log(pageState.language);
|
||||||
i18next.changeLanguage(language).then((t) => {
|
void i18next.changeLanguage(language).then((t) => {
|
||||||
changePage("HOME", false);
|
changePage("HOME", false);
|
||||||
pageState.pageDirection = t("language_direction");
|
pageState.pageDirection = t("language_direction");
|
||||||
location.reload();
|
location.reload();
|
||||||
|
|
|
@ -19,7 +19,7 @@ export class SetVaultURLPage extends Page {
|
||||||
tag: "input",
|
tag: "input",
|
||||||
class: ["uk-input", "uk-form-width-medium"],
|
class: ["uk-input", "uk-form-width-medium"],
|
||||||
attributes: {
|
attributes: {
|
||||||
required: true,
|
required: "true",
|
||||||
type: "text",
|
type: "text",
|
||||||
placeholder: "Vault URL",
|
placeholder: "Vault URL",
|
||||||
name: "vaultURL"
|
name: "vaultURL"
|
||||||
|
|
|
@ -33,7 +33,7 @@ export class NewTOTPPage extends Page {
|
||||||
tag: "input",
|
tag: "input",
|
||||||
class: ["uk-input", "uk-form-width-medium"],
|
class: ["uk-input", "uk-form-width-medium"],
|
||||||
attributes: {
|
attributes: {
|
||||||
required: true,
|
required: "true",
|
||||||
type: "text",
|
type: "text",
|
||||||
placeholder: i18next.t("totp_new_name_text"),
|
placeholder: i18next.t("totp_new_name_text"),
|
||||||
name: "name"
|
name: "name"
|
||||||
|
@ -89,7 +89,7 @@ export class NewTOTPPage extends Page {
|
||||||
};
|
};
|
||||||
addNewTOTP(pageState.currentBaseMount, parms).then(_ => {
|
addNewTOTP(pageState.currentBaseMount, parms).then(_ => {
|
||||||
changePage("TOTP");
|
changePage("TOTP");
|
||||||
}).catch(e => {
|
}).catch((e: Error) => {
|
||||||
setErrorText(`API Error: ${e.message}`);
|
setErrorText(`API Error: ${e.message}`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -24,7 +24,7 @@ export class TOTPViewPage extends Page {
|
||||||
refresher: number;
|
refresher: number;
|
||||||
totpListElements: Record<string, TOTPListElement>;
|
totpListElements: Record<string, TOTPListElement>;
|
||||||
|
|
||||||
async render(): Promise<void> {
|
render(): void {
|
||||||
setTitleElement(pageState);
|
setTitleElement(pageState);
|
||||||
const totpList = makeElement({ tag: "div" });
|
const totpList = makeElement({ tag: "div" });
|
||||||
setPageContent(makeElement({
|
setPageContent(makeElement({
|
||||||
|
@ -33,7 +33,7 @@ export class TOTPViewPage extends Page {
|
||||||
makeElement({
|
makeElement({
|
||||||
tag: "a",
|
tag: "a",
|
||||||
text: i18next.t("totp_view_new_btn"),
|
text: i18next.t("totp_view_new_btn"),
|
||||||
onclick: _ => { changePage("NEW_TOTP"); }
|
onclick: () => { changePage("NEW_TOTP"); }
|
||||||
}),
|
}),
|
||||||
makeElement({
|
makeElement({
|
||||||
tag: "p",
|
tag: "p",
|
||||||
|
@ -48,14 +48,14 @@ export class TOTPViewPage extends Page {
|
||||||
|
|
||||||
|
|
||||||
getTOTPKeys(pageState.currentBaseMount).then(res => {
|
getTOTPKeys(pageState.currentBaseMount).then(res => {
|
||||||
res.forEach(async function (totpKeyName) {
|
res.forEach(function (totpKeyName) {
|
||||||
const totpListElement = this.makeTOTPListElement(totpKeyName);
|
const totpListElement = (this as TOTPViewPage).makeTOTPListElement(totpKeyName);
|
||||||
totpList.appendChild(totpListElement);
|
totpList.appendChild(totpListElement);
|
||||||
this.totpListElements[totpKeyName] = totpListElement;
|
(this as TOTPViewPage).totpListElements[totpKeyName] = totpListElement;
|
||||||
await this.updateTOTPElement(totpKeyName, totpListElement);
|
void (this as TOTPViewPage).updateTOTPElement(totpKeyName, totpListElement);
|
||||||
}, this);
|
}, this);
|
||||||
document.getElementById("loadingText").remove();
|
document.getElementById("loadingText").remove();
|
||||||
}).catch(e => {
|
}).catch((e: Error) => {
|
||||||
if (e == DoesNotExistError) {
|
if (e == DoesNotExistError) {
|
||||||
const loadingText = document.getElementById("loadingText");
|
const loadingText = document.getElementById("loadingText");
|
||||||
loadingText.innerText = i18next.t("totp_view_empty");
|
loadingText.innerText = i18next.t("totp_view_empty");
|
||||||
|
@ -64,12 +64,12 @@ export class TOTPViewPage extends Page {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const totpRefresher = async () => {
|
const totpRefresher = () => {
|
||||||
await Promise.all(Array.from(objectToMap(this.totpListElements)).map((kv) => {
|
void Promise.all(Array.from(objectToMap(this.totpListElements)).map((kv: [string, TOTPListElement]) => {
|
||||||
return this.updateTOTPElement(...kv);
|
return this.updateTOTPElement(...kv);
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
await totpRefresher();
|
void totpRefresher();
|
||||||
this.refresher = setInterval(totpRefresher, 3000) as unknown as number;
|
this.refresher = setInterval(totpRefresher, 3000) as unknown as number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ export class TOTPViewPage extends Page {
|
||||||
children: [totpKeyBox, totpValueBox]
|
children: [totpKeyBox, totpValueBox]
|
||||||
}) as TOTPListElement;
|
}) as TOTPListElement;
|
||||||
|
|
||||||
gridElement.setCode = totpValueBox.setText;
|
gridElement.setCode = (code: string) => totpValueBox.setText(code);
|
||||||
|
|
||||||
return gridElement;
|
return gridElement;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ import { changePage, setErrorText, setPageContent, setTitleElement } from "../..
|
||||||
import { fileToBase64, makeElement } from "../../htmlUtils";
|
import { fileToBase64, makeElement } from "../../htmlUtils";
|
||||||
import { pageState } from "../../globalPageState";
|
import { pageState } from "../../globalPageState";
|
||||||
import { transitDecrypt } from "../../api/transit/transitDecrypt";
|
import { transitDecrypt } from "../../api/transit/transitDecrypt";
|
||||||
import UIkit from 'uikit/dist/js/uikit.min.js';
|
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
export class TransitDecryptPage extends Page {
|
export class TransitDecryptPage extends Page {
|
||||||
|
@ -20,7 +19,7 @@ export class TransitDecryptPage extends Page {
|
||||||
|
|
||||||
transitDecryptForm: HTMLFormElement;
|
transitDecryptForm: HTMLFormElement;
|
||||||
|
|
||||||
async render(): Promise<void> {
|
render(): void {
|
||||||
setTitleElement(pageState);
|
setTitleElement(pageState);
|
||||||
setPageContent(makeElement({
|
setPageContent(makeElement({
|
||||||
tag: "div"
|
tag: "div"
|
||||||
|
@ -74,7 +73,7 @@ export class TransitDecryptPage extends Page {
|
||||||
setPageContent(this.transitDecryptForm);
|
setPageContent(this.transitDecryptForm);
|
||||||
this.transitDecryptForm.addEventListener("submit", async function (e: Event) {
|
this.transitDecryptForm.addEventListener("submit", async function (e: Event) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
await this.transitDecryptFormHandler();
|
await (this as TransitDecryptPage).transitDecryptFormHandler();
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,11 +86,11 @@ export class TransitDecryptPage extends Page {
|
||||||
|
|
||||||
const ciphertext_file = formData.get("ciphertext_file") as File;
|
const ciphertext_file = formData.get("ciphertext_file") as File;
|
||||||
if (ciphertext_file.size > 0) {
|
if (ciphertext_file.size > 0) {
|
||||||
ciphertext = atob((await fileToBase64(ciphertext_file) as string).replace("data:text/plain;base64,", ""));
|
ciphertext = atob((await fileToBase64(ciphertext_file) ).replace("data:text/plain;base64,", ""));
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let res = await transitDecrypt(
|
const res = await transitDecrypt(
|
||||||
pageState.currentBaseMount,
|
pageState.currentBaseMount,
|
||||||
pageState.currentSecret,
|
pageState.currentSecret,
|
||||||
{ ciphertext: ciphertext },
|
{ ciphertext: ciphertext },
|
||||||
|
@ -102,9 +101,10 @@ export class TransitDecryptPage extends Page {
|
||||||
}
|
}
|
||||||
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);
|
document.body.querySelector("#pageContent").appendChild(modal);
|
||||||
UIkit.modal(modal).show();
|
modal.show();
|
||||||
} catch (e) {
|
} catch (e: unknown) {
|
||||||
setErrorText(`API Error: ${e.message}`);
|
const error = e as Error;
|
||||||
|
setErrorText(`API Error: ${error.message}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ import { changePage, setErrorText, setPageContent, setTitleElement } from "../..
|
||||||
import { fileToBase64, makeElement } from "../../htmlUtils";
|
import { fileToBase64, makeElement } from "../../htmlUtils";
|
||||||
import { pageState } from "../../globalPageState";
|
import { pageState } from "../../globalPageState";
|
||||||
import { transitEncrypt } from "../../api/transit/transitEncrypt";
|
import { transitEncrypt } from "../../api/transit/transitEncrypt";
|
||||||
import UIkit from 'uikit/dist/js/uikit.min.js';
|
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,7 +21,7 @@ export class TransitEncryptPage extends Page {
|
||||||
transitEncryptForm: HTMLFormElement;
|
transitEncryptForm: HTMLFormElement;
|
||||||
|
|
||||||
|
|
||||||
async render(): Promise<void> {
|
render(): void {
|
||||||
setTitleElement(pageState);
|
setTitleElement(pageState);
|
||||||
setPageContent(makeElement({
|
setPageContent(makeElement({
|
||||||
tag: "div"
|
tag: "div"
|
||||||
|
@ -75,9 +74,9 @@ export class TransitEncryptPage extends Page {
|
||||||
}) as HTMLFormElement;
|
}) as HTMLFormElement;
|
||||||
setPageContent(this.transitEncryptForm);
|
setPageContent(this.transitEncryptForm);
|
||||||
|
|
||||||
this.transitEncryptForm.addEventListener("submit", async function (e) {
|
this.transitEncryptForm.addEventListener("submit", async function (e: Event) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
await this.transitEncryptFormHandler();
|
await (this as TransitEncryptPage).transitEncryptFormHandler();
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,23 +89,24 @@ export class TransitEncryptPage extends Page {
|
||||||
|
|
||||||
const plaintext_file = formData.get("plaintext_file") as File;
|
const plaintext_file = formData.get("plaintext_file") as File;
|
||||||
if (plaintext_file.size > 0) {
|
if (plaintext_file.size > 0) {
|
||||||
plaintext = (await fileToBase64(plaintext_file) as string).replace("data:text/plain;base64,", "");
|
plaintext = (await fileToBase64(plaintext_file) ).replace("data:text/plain;base64,", "");
|
||||||
plaintext = base64Checkbox == "on" ? atob(plaintext) : plaintext;
|
plaintext = base64Checkbox == "on" ? atob(plaintext) : plaintext;
|
||||||
} else {
|
} else {
|
||||||
plaintext = base64Checkbox == "on" ? plaintext : btoa(plaintext);
|
plaintext = base64Checkbox == "on" ? plaintext : btoa(plaintext);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let res = await transitEncrypt(
|
const res = await transitEncrypt(
|
||||||
pageState.currentBaseMount,
|
pageState.currentBaseMount,
|
||||||
pageState.currentSecret,
|
pageState.currentSecret,
|
||||||
{ plaintext: plaintext }
|
{ 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);
|
document.body.querySelector("#pageContent").appendChild(modal);
|
||||||
UIkit.modal(modal).show();
|
modal.show();
|
||||||
} catch (e) {
|
} catch (e: unknown) {
|
||||||
setErrorText(`API Error: ${e.message}`);
|
const error = e as Error;
|
||||||
|
setErrorText(`API Error: ${error.message}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,14 @@
|
||||||
import { CopyableModal } from "../../elements/CopyableModal";
|
import { CopyableModal } from "../../elements/CopyableModal";
|
||||||
import { FileUploadInput } from "../../elements/FileUploadInput";
|
|
||||||
import { Margin } from "../../elements/Margin";
|
import { Margin } from "../../elements/Margin";
|
||||||
|
import { Option } from "../../elements/Option";
|
||||||
import { Page } from "../../types/Page";
|
import { Page } from "../../types/Page";
|
||||||
import { changePage, setErrorText, setPageContent, setTitleElement } from "../../pageUtils";
|
import { changePage, setErrorText, setPageContent, setTitleElement } from "../../pageUtils";
|
||||||
import { makeElement } from "../../htmlUtils";
|
|
||||||
import { pageState } from "../../globalPageState";
|
|
||||||
import UIkit from 'uikit/dist/js/uikit.min.js';
|
|
||||||
import i18next from "i18next";
|
|
||||||
import { getTransitKey } from "../../api/transit/getTransitKey";
|
import { getTransitKey } from "../../api/transit/getTransitKey";
|
||||||
|
import { makeElement } from "../../htmlUtils";
|
||||||
import { objectToMap } from "../../utils";
|
import { objectToMap } from "../../utils";
|
||||||
import { Option } from "../../elements/Option";
|
import { pageState } from "../../globalPageState";
|
||||||
import { transitRewrap } from "../../api/transit/transitRewrap";
|
import { transitRewrap } from "../../api/transit/transitRewrap";
|
||||||
|
import i18next from "i18next";
|
||||||
|
|
||||||
type versionOption = { version: string; label: string }
|
type versionOption = { version: string; label: string }
|
||||||
|
|
||||||
|
@ -27,17 +25,17 @@ export class TransitRewrapPage extends Page {
|
||||||
|
|
||||||
async render(): Promise<void> {
|
async render(): Promise<void> {
|
||||||
setTitleElement(pageState);
|
setTitleElement(pageState);
|
||||||
let transitKey = await getTransitKey(pageState.currentBaseMount, pageState.currentSecret);
|
const transitKey = await getTransitKey(pageState.currentBaseMount, pageState.currentSecret);
|
||||||
|
|
||||||
let stringVersions = Array.from(objectToMap(transitKey.keys).keys()).reverse() as any as string[];
|
const stringVersions = Array.from(objectToMap(transitKey.keys).keys()).reverse() as unknown as string[];
|
||||||
let versions = stringVersions.map((val) => parseInt(val, 10)) as any as number[];
|
const versions = stringVersions.map((val): number => parseInt(val, 10));
|
||||||
|
|
||||||
// get the selectable version options in the same
|
// get the selectable version options in the same
|
||||||
// format the official UI uses.
|
// format the official UI uses.
|
||||||
// e.g: ["2 (latest)", "1"]
|
// e.g: ["2 (latest)", "1"]
|
||||||
|
|
||||||
let options: versionOption[] = versions.map((val): versionOption => {
|
const options: versionOption[] = versions.map((val): versionOption => {
|
||||||
let i18nkey = val == Math.max(...versions) ?
|
const i18nkey = val == Math.max(...versions) ?
|
||||||
"transit_rewrap_latest_version_option_text"
|
"transit_rewrap_latest_version_option_text"
|
||||||
:
|
:
|
||||||
"transit_rewrap_version_option_text";
|
"transit_rewrap_version_option_text";
|
||||||
|
@ -83,15 +81,14 @@ export class TransitRewrapPage extends Page {
|
||||||
setPageContent(this.transitRewrapForm);
|
setPageContent(this.transitRewrapForm);
|
||||||
this.transitRewrapForm.addEventListener("submit", async function (e: Event) {
|
this.transitRewrapForm.addEventListener("submit", async function (e: Event) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
await this.transitRewrapFormHandler();
|
await (this as TransitRewrapPage).transitRewrapFormHandler();
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
async transitRewrapFormHandler(): Promise<void> {
|
async transitRewrapFormHandler(): Promise<void> {
|
||||||
const formData = new FormData(this.transitRewrapForm);
|
const formData = new FormData(this.transitRewrapForm);
|
||||||
const ciphertext = formData.get("ciphertext") as string;
|
|
||||||
try {
|
try {
|
||||||
let res = await transitRewrap(
|
const res = await transitRewrap(
|
||||||
pageState.currentBaseMount,
|
pageState.currentBaseMount,
|
||||||
pageState.currentSecret,
|
pageState.currentSecret,
|
||||||
{
|
{
|
||||||
|
@ -101,9 +98,10 @@ export class TransitRewrapPage extends Page {
|
||||||
);
|
);
|
||||||
const modal = CopyableModal(i18next.t("transit_rewrap_result_modal_title"), res.ciphertext);
|
const modal = CopyableModal(i18next.t("transit_rewrap_result_modal_title"), res.ciphertext);
|
||||||
document.body.querySelector("#pageContent").appendChild(modal);
|
document.body.querySelector("#pageContent").appendChild(modal);
|
||||||
UIkit.modal(modal).show();
|
modal.show();
|
||||||
} catch (e) {
|
} catch (e: unknown) {
|
||||||
setErrorText(`API Error: ${e.message}`);
|
const error = e as Error;
|
||||||
|
setErrorText(`API Error: ${error.message}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ export class TransitViewPage extends Page {
|
||||||
children: makeElement({
|
children: makeElement({
|
||||||
tag: "a",
|
tag: "a",
|
||||||
text: secret,
|
text: secret,
|
||||||
onclick: _ => {
|
onclick: () => {
|
||||||
pageState.currentSecret = secret;
|
pageState.currentSecret = secret;
|
||||||
changePage("TRANSIT_VIEW_SECRET");
|
changePage("TRANSIT_VIEW_SECRET");
|
||||||
}
|
}
|
||||||
|
@ -55,14 +55,15 @@ export class TransitViewPage extends Page {
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
}));
|
}));
|
||||||
} catch (e) {
|
} catch (e: unknown) {
|
||||||
if (e == DoesNotExistError) {
|
const error = e as Error;
|
||||||
|
if (error == DoesNotExistError) {
|
||||||
transitViewContent.appendChild(makeElement({
|
transitViewContent.appendChild(makeElement({
|
||||||
tag: "p",
|
tag: "p",
|
||||||
text: i18next.t("transit_view_none_here_text")
|
text: i18next.t("transit_view_none_here_text")
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
setErrorText(e.message);
|
setErrorText(error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { Page } from "../../types/Page";
|
import { Page } from "../../types/Page";
|
||||||
|
import { Tile } from "../../elements/Tile";
|
||||||
import { changePage, setPageContent, setTitleElement } from "../../pageUtils";
|
import { changePage, setPageContent, setTitleElement } from "../../pageUtils";
|
||||||
|
import { getTransitKey } from "../../api/transit/getTransitKey";
|
||||||
import { makeElement } from "../../htmlUtils";
|
import { makeElement } from "../../htmlUtils";
|
||||||
import { pageState } from "../../globalPageState";
|
import { pageState } from "../../globalPageState";
|
||||||
import i18next from 'i18next';
|
import i18next from 'i18next';
|
||||||
import { getTransitKey } from "../../api/transit/getTransitKey";
|
|
||||||
import { Tile } from "../../elements/Tile";
|
|
||||||
|
|
||||||
export class TransitViewSecretPage extends Page {
|
export class TransitViewSecretPage extends Page {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -18,7 +18,7 @@ export class TransitViewSecretPage extends Page {
|
||||||
async render(): Promise<void> {
|
async render(): Promise<void> {
|
||||||
setTitleElement(pageState);
|
setTitleElement(pageState);
|
||||||
|
|
||||||
let transitKey = await getTransitKey(pageState.currentBaseMount, pageState.currentSecret);
|
const transitKey = await getTransitKey(pageState.currentBaseMount, pageState.currentSecret);
|
||||||
|
|
||||||
setPageContent(makeElement({
|
setPageContent(makeElement({
|
||||||
tag: "div",
|
tag: "div",
|
||||||
|
|
|
@ -41,9 +41,16 @@ export class UnsealPage extends Page {
|
||||||
}
|
}
|
||||||
|
|
||||||
makeRefresher(): void {
|
makeRefresher(): void {
|
||||||
this.refresher = setInterval(async function () {
|
const id = setInterval(() => {
|
||||||
this.updateSealProgress(await getSealStatus());
|
void (this as UnsealPage).doRefresh().then(() => {});
|
||||||
}.bind(this), 1000) as unknown as number;
|
return;
|
||||||
|
}, 1000);
|
||||||
|
this.refresher = id as unknown as number;
|
||||||
|
}
|
||||||
|
|
||||||
|
async doRefresh(): Promise<void> {
|
||||||
|
const status = await getSealStatus();
|
||||||
|
this.updateSealProgress(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
async render(): Promise<void> {
|
async render(): Promise<void> {
|
||||||
|
@ -58,7 +65,7 @@ export class UnsealPage extends Page {
|
||||||
}) as HTMLParagraphElement;
|
}) as HTMLParagraphElement;
|
||||||
this.unsealInputContent = makeElement({
|
this.unsealInputContent = makeElement({
|
||||||
tag: "div"
|
tag: "div"
|
||||||
}) as HTMLElement;
|
});
|
||||||
setPageContent(makeElement({
|
setPageContent(makeElement({
|
||||||
tag: "div",
|
tag: "div",
|
||||||
children: [
|
children: [
|
||||||
|
@ -103,7 +110,7 @@ export class UnsealPage extends Page {
|
||||||
this.deinitWebcam();
|
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.FORM_INPUT) this.makeUnsealForm();
|
||||||
if (method == UnsealInputModes.QR_INPUT) this.makeQRInput();
|
if (method == UnsealInputModes.QR_INPUT) void this.makeQRInput();
|
||||||
this.setButtons(method);
|
this.setButtons(method);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +122,7 @@ export class UnsealPage extends Page {
|
||||||
tag: "input",
|
tag: "input",
|
||||||
class: ["uk-input", "uk-form-width-medium"],
|
class: ["uk-input", "uk-form-width-medium"],
|
||||||
attributes: {
|
attributes: {
|
||||||
required: true,
|
required: "true",
|
||||||
type: "password",
|
type: "password",
|
||||||
placeholder: i18next.t("key_input_placeholder"),
|
placeholder: i18next.t("key_input_placeholder"),
|
||||||
name: "key"
|
name: "key"
|
||||||
|
@ -129,15 +136,15 @@ export class UnsealPage extends Page {
|
||||||
]
|
]
|
||||||
}) as HTMLFormElement;
|
}) as HTMLFormElement;
|
||||||
this.unsealInputContent.appendChild(this.unsealKeyForm);
|
this.unsealInputContent.appendChild(this.unsealKeyForm);
|
||||||
this.unsealKeyForm.addEventListener("submit", function (e) {
|
this.unsealKeyForm.addEventListener("submit", function (e: Event) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.handleKeySubmit();
|
void (this as UnsealPage).handleKeySubmit();
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
async makeQRInput(): Promise<void> {
|
async makeQRInput(): Promise<void> {
|
||||||
this.qrScanner = await QRScanner(function (code: string) {
|
this.qrScanner = await QRScanner(function (code: string) {
|
||||||
this.submitKey(code);
|
(this as UnsealPage).submitKey(code);
|
||||||
console.log('decoded qr code:', code)
|
console.log('decoded qr code:', code)
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
this.unsealInputContent.appendChild(this.qrScanner);
|
this.unsealInputContent.appendChild(this.qrScanner);
|
||||||
|
@ -162,15 +169,15 @@ export class UnsealPage extends Page {
|
||||||
|
|
||||||
submitKey(key: string): void {
|
submitKey(key: string): void {
|
||||||
submitUnsealKey(key).then(_ => {
|
submitUnsealKey(key).then(_ => {
|
||||||
getSealStatus().then(data => {
|
void getSealStatus().then(data => {
|
||||||
this.updateSealProgress(data);
|
void this.updateSealProgress(data);
|
||||||
});
|
});
|
||||||
}).catch(e => {
|
}).catch((e: Error) => {
|
||||||
setErrorText(e.message);
|
setErrorText(e.message);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async handleKeySubmit(): Promise<void> {
|
handleKeySubmit(): void {
|
||||||
const formData = new FormData(this.unsealKeyForm);
|
const formData = new FormData(this.unsealKeyForm);
|
||||||
|
|
||||||
this.submitKey(formData.get("key") as string)
|
this.submitKey(formData.get("key") as string)
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { PageState } from "./PageState";
|
||||||
import { pageState } from "./globalPageState";
|
import { pageState } from "./globalPageState";
|
||||||
import i18next from 'i18next';
|
import i18next from 'i18next';
|
||||||
|
|
||||||
|
@ -6,9 +7,13 @@ import i18next from 'i18next';
|
||||||
// before rendering.
|
// before rendering.
|
||||||
// Also it only runs when process.env.NODE_ENV == "development"
|
// Also it only runs when process.env.NODE_ENV == "development"
|
||||||
|
|
||||||
// Please empty this function before committing.
|
declare global {
|
||||||
export async function playground(): Promise<void> {
|
interface Window { pageState: PageState; i18next: unknown; }
|
||||||
console.log("Welcome to Playground!");
|
}
|
||||||
(window as any).pageState = pageState;
|
|
||||||
(window as any).i18next = i18next;
|
// Please empty this function before committing.
|
||||||
|
export function playground(): void {
|
||||||
|
console.log("Welcome to Playground!");
|
||||||
|
window.pageState = pageState;
|
||||||
|
window.i18next = i18next;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,9 @@ export class Page {
|
||||||
constructor() {
|
constructor() {
|
||||||
// Do Nothing
|
// Do Nothing
|
||||||
}
|
}
|
||||||
render(): any {
|
render(): unknown {
|
||||||
// Do Nothing
|
// Do Nothing
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
get name(): string {
|
get name(): string {
|
||||||
return "Page";
|
return "Page";
|
||||||
|
|
|
@ -5,13 +5,13 @@ export function removeDoubleSlash(str: string): string {
|
||||||
export const getObjectKeys =
|
export const getObjectKeys =
|
||||||
(obj: Record<string, unknown>): string[] => Object.getOwnPropertyNames(obj);
|
(obj: Record<string, unknown>): string[] => Object.getOwnPropertyNames(obj);
|
||||||
export const objectToMap =
|
export const objectToMap =
|
||||||
(obj: Record<any, any>): Map<any, any> => new Map(Object.entries(obj));
|
(obj: Record<string, unknown>): Map<string, unknown> => new Map(Object.entries(obj));
|
||||||
export const sortedObjectMap =
|
export const sortedObjectMap =
|
||||||
(obj: Record<string, unknown>): Map<any, any> => new Map(Object.entries(obj).sort());
|
(obj: Record<string, unknown>): Map<string, unknown> => new Map(Object.entries(obj).sort());
|
||||||
|
|
||||||
export function getKeyByObjectPropertyValue(map: Record<string, unknown>, searchValue: unknown): string {
|
export function getKeyByObjectPropertyValue(map: Record<string, unknown>, searchValue: unknown): string {
|
||||||
for (const key of getObjectKeys(map)) {
|
for (const key of getObjectKeys(map)) {
|
||||||
if ((map as any)[key] === searchValue)
|
if (map[key] === searchValue)
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue