Implement deleting of TOTP codes. Closes #2.
This commit is contained in:
parent
4d04070446
commit
1ccb432cbc
|
@ -26,6 +26,7 @@ import { PwGenPage } from "./pages/PwGen";
|
|||
import { SecretsHomePage } from "./pages/Secrets/SecretsHome";
|
||||
import { SetLanguagePage } from "./pages/SetLanguage";
|
||||
import { SetVaultURLPage } from "./pages/SetVaultURL";
|
||||
import { TOTPDeletePage } from "./pages/Secrets/TOTP/TOTPDelete";
|
||||
import { TOTPViewPage } from "./pages/Secrets/TOTP/TOTPView";
|
||||
import { TransitDecryptPage } from "./pages/Secrets/Transit/TransitDecrypt";
|
||||
import { TransitEncryptPage } from "./pages/Secrets/Transit/TransitEncrypt";
|
||||
|
@ -58,6 +59,7 @@ export const allPages: pagesList = {
|
|||
ME: new MePage(),
|
||||
TOTP: new TOTPViewPage(),
|
||||
NEW_TOTP: new NewTOTPPage(),
|
||||
TOTP_DELETE: new TOTPDeletePage(),
|
||||
LOGIN: new LoginPage(),
|
||||
SET_VAULT_URL: new SetVaultURLPage(),
|
||||
UNSEAL: new UnsealPage(),
|
||||
|
|
15
src/api/totp/deleteTOTP.ts
Normal file
15
src/api/totp/deleteTOTP.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
import { appendAPIURL, getHeaders } from "../apiUtils";
|
||||
|
||||
export async function deleteTOTP(baseMount: string, name: string): Promise<void> {
|
||||
const request = new Request(appendAPIURL(`/v1/${baseMount}/keys/${name}`), {
|
||||
method: "DELETE",
|
||||
headers: getHeaders(),
|
||||
});
|
||||
const resp = await fetch(request);
|
||||
if (!resp.ok) {
|
||||
const data = (await resp.json()) as { errors?: string[] };
|
||||
if ("errors" in data) {
|
||||
throw new Error(data.errors[0]);
|
||||
}
|
||||
}
|
||||
}
|
45
src/pages/Secrets/TOTP/TOTPDelete.tsx
Normal file
45
src/pages/Secrets/TOTP/TOTPDelete.tsx
Normal file
|
@ -0,0 +1,45 @@
|
|||
import { Page } from "../../../types/Page";
|
||||
import { SecretTitleElement } from "../SecretTitleElement";
|
||||
import { deleteTOTP } from "../../../api/totp/deleteTOTP";
|
||||
import { render } from "preact";
|
||||
import i18next from "i18next";
|
||||
|
||||
export class TOTPDeletePage extends Page {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
async cleanup(): Promise<void> {
|
||||
this.state.secretItem = "";
|
||||
}
|
||||
|
||||
async goBack(): Promise<void> {
|
||||
this.state.secretItem = "";
|
||||
await this.router.changePage("TOTP");
|
||||
}
|
||||
async render(): Promise<void> {
|
||||
render(
|
||||
<div>
|
||||
<h5>{i18next.t("totp_delete_text")}</h5>
|
||||
<button
|
||||
class="uk-button uk-button-danger"
|
||||
onClick={async () => {
|
||||
await deleteTOTP(this.state.baseMount, this.state.secretItem);
|
||||
await this.goBack();
|
||||
}}
|
||||
>
|
||||
{i18next.t("kv_delete_btn")}
|
||||
</button>
|
||||
</div>,
|
||||
this.router.pageContentElement,
|
||||
);
|
||||
}
|
||||
|
||||
async getPageTitle(): Promise<Element | string> {
|
||||
return await SecretTitleElement(this.router, i18next.t("totp_delete_suffix"));
|
||||
}
|
||||
|
||||
get name(): string {
|
||||
return i18next.t("totp_delete_title");
|
||||
}
|
||||
}
|
|
@ -1,7 +1,10 @@
|
|||
import { Component, JSX, render } from "preact";
|
||||
import { CopyableInputBox } from "../../../elements/ReactCopyableInputBox";
|
||||
import { DoesNotExistError } from "../../../types/internalErrors";
|
||||
import { MarginInline } from "../../../elements/ReactMarginInline";
|
||||
import { Page } from "../../../types/Page";
|
||||
import { PageRouter } from "z-pagerouter";
|
||||
import { PageState } from "../../../PageState";
|
||||
import { SecretTitleElement } from "../SecretTitleElement";
|
||||
import { getTOTPCode } from "../../../api/totp/getTOTPCode";
|
||||
import { getTOTPKeys } from "../../../api/totp/getTOTPKeys";
|
||||
|
@ -9,7 +12,7 @@ import { setErrorText } from "../../../pageUtils";
|
|||
import i18next from "i18next";
|
||||
|
||||
export class RefreshingTOTPGridItem extends Component<
|
||||
{ baseMount: string; totpKey: string },
|
||||
{ baseMount: string; totpKey: string; router: PageRouter },
|
||||
{ totpValue: string }
|
||||
> {
|
||||
constructor() {
|
||||
|
@ -36,6 +39,20 @@ export class RefreshingTOTPGridItem extends Component<
|
|||
<div class="uk-grid uk-grid-small uk-text-left" uk-grid>
|
||||
<CopyableInputBox text={this.props.totpKey} copyable />
|
||||
<CopyableInputBox text={this.state.totpValue} copyable />
|
||||
<div>
|
||||
<MarginInline>
|
||||
<button
|
||||
class="uk-button uk-button-danger"
|
||||
onClick={async () => {
|
||||
const state = this.props.router.state as PageState;
|
||||
state.secretItem = this.props.totpKey;
|
||||
await this.props.router.changePage("TOTP_DELETE");
|
||||
}}
|
||||
>
|
||||
{i18next.t("totp_view_delete_btn")}
|
||||
</button>
|
||||
</MarginInline>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -54,6 +71,7 @@ export class TOTPViewPage extends Page {
|
|||
}
|
||||
|
||||
async render(): Promise<void> {
|
||||
this.state.secretItem = "";
|
||||
render(
|
||||
<div>
|
||||
<button
|
||||
|
@ -72,7 +90,11 @@ export class TOTPViewPage extends Page {
|
|||
try {
|
||||
const elem = await Promise.all(
|
||||
Array.from(await getTOTPKeys(this.state.baseMount)).map(async (key) => (
|
||||
<RefreshingTOTPGridItem baseMount={this.state.baseMount} totpKey={key} />
|
||||
<RefreshingTOTPGridItem
|
||||
baseMount={this.state.baseMount}
|
||||
totpKey={key}
|
||||
router={this.router}
|
||||
/>
|
||||
)),
|
||||
);
|
||||
return elem;
|
||||
|
|
7
src/translations/en.js
vendored
7
src/translations/en.js
vendored
|
@ -146,6 +146,7 @@ module.exports = {
|
|||
// TOTP View Page
|
||||
totp_view_title: "TOTP",
|
||||
totp_view_new_btn: "New",
|
||||
totp_view_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..",
|
||||
|
@ -160,6 +161,12 @@ module.exports = {
|
|||
totp_new_key_input: "Key",
|
||||
totp_new_add_btn: "Add TOTP Key",
|
||||
|
||||
// TOTP Delete Page
|
||||
totp_delete_title: "Delete TOTP Key",
|
||||
totp_delete_suffix: " (delete)",
|
||||
totp_delete_text: "Are you sure you want to delete this TOTP secret?",
|
||||
totp_delete_button: "Delete",
|
||||
|
||||
// Transit View Page
|
||||
transit_view_title: "Transit View",
|
||||
transit_view_none_here_text:
|
||||
|
|
Loading…
Reference in a new issue