From df796d35067230a766f2c3584711ccf06a5eb73a Mon Sep 17 00:00:00 2001 From: Kitteh Date: Sun, 30 May 2021 10:02:20 +0100 Subject: [PATCH] Add secret engine deletion page. --- src/allPages.ts | 3 ++ src/api/sys/deleteMount.ts | 10 +++++ src/main.tsx | 1 - src/pages/Secrets/DeleteSecretsEngine.tsx | 48 +++++++++++++++++++++ src/pages/Secrets/KeyValue/KeyValueView.tsx | 16 +++++-- src/pages/Secrets/SecretsHome.tsx | 1 - src/pages/Secrets/TOTP/TOTPView.tsx | 28 ++++++++---- src/pages/Secrets/Transit/TransitView.tsx | 8 ++++ src/translations/en.js | 9 ++++ src/translations/ru.js | 2 +- 10 files changed, 111 insertions(+), 15 deletions(-) create mode 100644 src/api/sys/deleteMount.ts create mode 100644 src/pages/Secrets/DeleteSecretsEngine.tsx diff --git a/src/allPages.ts b/src/allPages.ts index 71d97b1..1c83a47 100644 --- a/src/allPages.ts +++ b/src/allPages.ts @@ -6,6 +6,7 @@ import { PageType } from "z-pagerouter"; import { AccessHomePage } from "./pages/Access/AccessHome"; import { AuthHomePage } from "./pages/Access/Auth/AuthHome"; import { AuthViewConfigPage } from "./pages/Access/Auth/AuthViewConfig"; +import { DeleteSecretsEnginePage } from "./pages/Secrets/DeleteSecretsEngine"; import { HomePage } from "./pages/Home"; import { KeyValueDeletePage } from "./pages/Secrets/KeyValue/KeyValueDelete"; import { KeyValueNewPage } from "./pages/Secrets/KeyValue/KeyValueNew"; @@ -96,6 +97,8 @@ export const allPages: pagesList = { KEY_VALUE_DELETE: new KeyValueDeletePage(), KEY_VALUE_SECRET_EDIT: new KeyValueSecretEditPage(), + DELETE_SECRET_ENGINE: new DeleteSecretsEnginePage(), + NEW_SECRETS_ENGINE: new NewSecretsEnginePage(), NEW_KV_ENGINE: new NewKVEnginePage(), NEW_TOTP_ENGINE: new NewTOTPEnginePage(), diff --git a/src/api/sys/deleteMount.ts b/src/api/sys/deleteMount.ts new file mode 100644 index 0000000..4b88d34 --- /dev/null +++ b/src/api/sys/deleteMount.ts @@ -0,0 +1,10 @@ +import { appendAPIURL, checkResponse, getHeaders } from "../apiUtils"; + +export async function deleteMount(mountPath: string): Promise { + const request = new Request(appendAPIURL("/v1/sys/mounts/" + mountPath), { + method: "DELETE", + headers: getHeaders(), + }); + const resp = await fetch(request); + await checkResponse(resp); +} diff --git a/src/main.tsx b/src/main.tsx index 82505e5..0ee5f22 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -54,7 +54,6 @@ async function onLoad(): Promise { resetElementContent: !true, }); - reloadNavBar(pageRouter); pageRouter.addEventListener("pageChanged", async function (_) { diff --git a/src/pages/Secrets/DeleteSecretsEngine.tsx b/src/pages/Secrets/DeleteSecretsEngine.tsx new file mode 100644 index 0000000..cbfda08 --- /dev/null +++ b/src/pages/Secrets/DeleteSecretsEngine.tsx @@ -0,0 +1,48 @@ +import { Form } from "../../elements/Form"; +import { MarginInline } from "../../elements/MarginInline"; +import { Page } from "../../types/Page"; +import { deleteMount } from "../../api/sys/deleteMount"; +import { render } from "preact"; +import { setErrorText } from "../../pageUtils"; +import i18next from "i18next"; + +export class DeleteSecretsEnginePage extends Page { + constructor() { + super(); + } + + async render(): Promise { + render( +
{ + await this.onSubmit(); + }} + > +

{i18next.t("delete_secrets_engine_message")}

+ +

+ + + + +

, + this.router.pageContentElement, + ); + } + + async onSubmit(): Promise { + try { + await deleteMount(this.state.baseMount); + await this.router.changePage("SECRETS_HOME"); + } catch (e: unknown) { + const error = e as Error; + setErrorText(error.message); + } + } + + get name(): string { + return i18next.t("delete_secrets_engine_title", { mount: this.state.baseMount }); + } +} diff --git a/src/pages/Secrets/KeyValue/KeyValueView.tsx b/src/pages/Secrets/KeyValue/KeyValueView.tsx index d7171e3..2f01a0a 100644 --- a/src/pages/Secrets/KeyValue/KeyValueView.tsx +++ b/src/pages/Secrets/KeyValue/KeyValueView.tsx @@ -126,16 +126,26 @@ export class KeyValueViewPage extends Page { async render(): Promise { render( <> -
+

-

+ {this.state.secretPath.length == 0 && ( + + )} +

{this.state.secretMountType == "cubbyhole" &&

{i18next.t("kv_view_cubbyhole_text")}

} { - await this.router.setPageContent(""); if (!(await prePageChecks(this.router))) return; this.state.baseMount = ""; diff --git a/src/pages/Secrets/TOTP/TOTPView.tsx b/src/pages/Secrets/TOTP/TOTPView.tsx index 59dee44..258b5e9 100644 --- a/src/pages/Secrets/TOTP/TOTPView.tsx +++ b/src/pages/Secrets/TOTP/TOTPView.tsx @@ -55,7 +55,7 @@ export class RefreshingTOTPGridItem extends Component< await page.router.changePage("TOTP_DELETE"); }} > - {i18next.t("totp_view_delete_btn")} + {i18next.t("totp_view_secret_delete_btn")} )} @@ -81,14 +81,24 @@ export class TOTPViewPage extends Page { this.state.secretItem = ""; render(
- +

+ + +



diff --git a/src/pages/Secrets/Transit/TransitView.tsx b/src/pages/Secrets/Transit/TransitView.tsx index 85a017d..6e6c453 100644 --- a/src/pages/Secrets/Transit/TransitView.tsx +++ b/src/pages/Secrets/Transit/TransitView.tsx @@ -90,6 +90,14 @@ export class TransitViewPage extends Page { > {i18next.t("transit_view_new_btn")} +

, diff --git a/src/translations/en.js b/src/translations/en.js index 38aa15e..3c29f9b 100644 --- a/src/translations/en.js +++ b/src/translations/en.js @@ -146,12 +146,14 @@ module.exports = { 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_delete_btn: "Delete", 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: "New", totp_view_delete_btn: "Delete", + totp_view_secret_delete_btn: "Delete", 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..", @@ -177,6 +179,7 @@ module.exports = { // Transit View Page transit_view_title: "Transit View", transit_view_new_btn: "New", + transit_view_delete_btn: "Delete", transit_view_none_here_text: "You seem to have no transit keys here, would you like to create one?", @@ -222,6 +225,12 @@ module.exports = { transit_rewrap_rewrap_btn: "Rewrap", transit_rewrap_result_modal_title: "Rewrap Result", + // Delete Secret Engine Page + delete_secrets_engine_title: "Delete Secret Engine ({{mount}})", + delete_secrets_engine_message: + "Are you sure you want to delete this secrets engine and all the data stored within? This can't be reversed.", + delete_secrets_engine_delete_btn: "Delete", + // Access Home access_home_page_title: "Access", access_auth_methods_title: "Authentication Methods", diff --git a/src/translations/ru.js b/src/translations/ru.js index 50cf703..a4df8e6 100644 --- a/src/translations/ru.js +++ b/src/translations/ru.js @@ -152,7 +152,7 @@ module.exports = { // TOTP View Page totp_view_title: "TOTP", totp_view_new_btn: "Добавить", - totp_view_delete_btn: "Удалить", + totp_view_secret_delete_btn: "Удалить", totp_view_loading: "Загрузка кодов TOTP..", totp_view_empty: "У вас на данный момент нет кодов TOTP. Хотите ли вы их создать?", totp_view_loading_box: "Загрузка..",