1
0
Fork 0

add a copy totp button on kv pages with __vaultui_totp_path

This commit is contained in:
Chaos 2022-11-23 16:45:04 +00:00
parent 760e16c371
commit 506fdbd1cb
No known key found for this signature in database
3 changed files with 56 additions and 8 deletions

View file

@ -10,6 +10,7 @@ VaultUI is a user interface for [Hashicorp Vault](https://www.hashicorp.com/prod
- Managing versions of secrets in v2 mounts.
- Editing and Viewing Key/Value secrets in JSON, JSON5, Yaml, etc with default settings for both.
- Search bar for easily finding a secret on mobile.
- Can add a `__vaultui_totp_path` attribute (example: `__vaultui_totp_path: "totp/gitlab"`) to KV secrets to add a link for viewing of affiliated TOTP paths.
### TOTP
- Can view and delete TOTP codes.
- Ability to scan a QR code, input a URI or input a key for adding TOTP codes.

View file

@ -167,7 +167,8 @@ module.exports = {
kv_secret_delete_all_btn: "Delete All Versions",
kv_secret_delete_version_btn: "Delete Version {{ version }}",
kv_secret_versions_btn: "Versions",
kv_secret_view_totp_btn: "View TOTP",
kv_secret_view_totp_btn: "View TOTP Entry",
kv_secret_copy_totp_btn: "Copy Current TOTP Code",
kv_secret_syntax: "Syntax",
// Key Value Secret Editor Page

View file

@ -1,3 +1,4 @@
import { API } from "../../../../api/API";
import { Button } from "../../../elements/Button";
import { CodeBlock } from "../../../elements/CodeBlock";
import { Component, JSX, createRef } from "preact";
@ -9,10 +10,12 @@ import { InputWithTitle } from "../../../elements/InputWithTitle";
import { SecretTitleElement } from "../SecretTitleElement";
import { Select, SelectOption } from "../../../elements/forms/Select";
import { SupportedLanguages, dumpData, toPrismCode } from "../../../../utils/dataInterchange";
import { addClipboardNotifications } from "../../../../utils/clipboardNotifs";
import { kvDeleteURL, kvEditURL, kvVersionsURL, totpListURL } from "../../pageLinks";
import { sendErrorNotification } from "../../../elements/ErrorMessage";
import { sortedObjectMap } from "../../../../utils";
import { splitKVPath } from "./kvPathUtils";
import ClipboardJS from "clipboard";
import i18next from "i18next";
type KVSecretViewDataProps = DefaultPageProps & { data: Map<string, unknown> };
@ -49,6 +52,46 @@ export class KVSecretCodeVew extends Component<KVSecretViewDataProps, { syntax:
}
}
class CopyTOTPButton extends Component<
{ baseMount: string; totpKey: string; api: API },
{ code: string }
> {
buttonRef = createRef<HTMLButtonElement>();
timer: unknown;
updateTOTPCode(): void {
void this.props.api.getTOTPCode(this.props.baseMount, this.props.totpKey).then((code) => {
this.setState({ code });
});
}
componentDidMount(): void {
this.updateTOTPCode();
this.timer = setInterval(() => {
this.updateTOTPCode();
}, 3000);
const clipboard = new ClipboardJS(this.buttonRef.current);
addClipboardNotifications(clipboard, 600);
}
componentWillUnmount(): void {
clearInterval(this.timer as number);
}
render(): JSX.Element {
return (
<Button
buttonRef={this.buttonRef}
text={i18next.t("kv_secret_copy_totp_btn")}
color="primary"
data-clipboard-text={this.state.code}
/>
);
}
}
export class KVSecretNormalVew extends Component<KVSecretViewDataProps> {
render() {
return (
@ -70,19 +113,22 @@ export class KVSecretNormalVew extends Component<KVSecretViewDataProps> {
</Grid>
);
})}
<br />
{(() => {
if (this.props.data.has("__vaultui_totp_path")) {
const value = this.props.data.get("__vaultui_totp_path") as string;
const baseMount = value.split("/")[0];
const secretItem = value.split("/")[1];
const totpKey = value.split("/")[1];
return (
<p>
<CopyTOTPButton api={this.props.api} baseMount={baseMount} totpKey={totpKey} />
<Button
text={i18next.t("kv_secret_view_totp_btn")}
color="primary"
route={totpListURL(baseMount, secretItem)}
color="secondary"
route={totpListURL(baseMount, totpKey)}
/>
</p>
);
}
})()}