1
0
Fork 0
VaultUI/src/ui/pages/Secrets/TOTP/TOTPNewGenerated.tsx
2022-01-16 20:29:57 +00:00

170 lines
5.5 KiB
TypeScript

import { Component, JSX, createRef } from "preact";
import { CopyableInputBox } from "../../../elements/CopyableInputBox";
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
import { Form } from "../../../elements/Form";
import { InputWithTitle } from "../../../elements/InputWithTitle";
import { Margin } from "../../../elements/Margin";
import { MarginInline } from "../../../elements/MarginInline";
import { NewTOTPResp } from "../../../../api/types/totp";
import { SecretTitleElement } from "../SecretTitleElement";
import { route } from "preact-router";
import { setErrorText } from "../../../../pageUtils";
import i18next from "i18next";
export class TOTPNewGeneratedForm extends Component<
{ baseMount: string } & DefaultPageProps,
{ exportedData: NewTOTPResp }
> {
uriInputRef = createRef<HTMLInputElement>();
render(): JSX.Element {
if (!this.state.exportedData) {
return (
<Form onSubmit={(data) => this.onSubmit(data)}>
<Margin>
<InputWithTitle title={i18next.t("common_name")}>
<input
class="uk-input uk-form-width-medium"
name="name"
type="text"
placeholder={i18next.t("common_name")}
required
/>
</InputWithTitle>
</Margin>
<Margin>
<InputWithTitle title={i18next.t("totp_new_generated_issuer")}>
<input class="uk-input uk-form-width-medium" name="issuer" type="text" required />
</InputWithTitle>
</Margin>
<Margin>
<InputWithTitle title={i18next.t("totp_new_generated_account_name")}>
<input
class="uk-input uk-form-width-medium"
name="account_name"
type="text"
required
/>
</InputWithTitle>
</Margin>
<Margin>
<InputWithTitle title={i18next.t("totp_new_generated_algorithm")}>
<select class="uk-select uk-form-width-medium" name="algorithm">
{["SHA512", "SHA256", "SHA1"].map((type) => (
<option label={type} value={type}>
{type}
</option>
))}
</select>
</InputWithTitle>
</Margin>
<Margin>
<InputWithTitle title={i18next.t("totp_new_generated_key_size")}>
<input
class="uk-input uk-form-width-medium"
name="key_size"
type="number"
value="20"
/>
</InputWithTitle>
</Margin>
<Margin>
<InputWithTitle title={i18next.t("totp_new_generated_period")}>
<input class="uk-input uk-form-width-medium" name="period" type="text" value="30s" />
</InputWithTitle>
</Margin>
<Margin>
<InputWithTitle title={i18next.t("totp_new_generated_digits")}>
<input class="uk-input uk-form-width-medium" name="digits" type="number" value="6" />
</InputWithTitle>
</Margin>
<Margin>
<InputWithTitle title={i18next.t("totp_new_generated_export")}>
<input class="uk-checkbox" name="exported" type="checkbox" value="yes" checked />
</InputWithTitle>
</Margin>
<p id="errorText" class="uk-text-danger" />
<MarginInline>
<button class="uk-button uk-button-primary" type="submit">
{i18next.t("common_create")}
</button>
</MarginInline>
</Form>
);
} else {
return (
<>
<p>{i18next.t("totp_new_generated_warning")}</p>
<img src={"data:image/png;base64," + this.state.exportedData.barcode} />
<CopyableInputBox copyable text={this.state.exportedData.url} />
<button
class="uk-button uk-button-primary"
onClick={async () => {
route("/secrets/totp/list/" + this.props.baseMount);
}}
>
{i18next.t("common_back")}
</button>
</>
);
}
}
async onSubmit(data: FormData): Promise<void> {
const isExported = data.get("exported") == "yes" ? true : false;
const parms = {
generate: true,
name: data.get("name") as string,
issuer: data.get("issuer") as string,
account_name: data.get("account_name") as string,
exported: isExported,
key_size: parseInt(data.get("key_size") as string),
period: data.get("period") as string,
algorithm: data.get("algorithm") as string,
digits: parseInt(data.get("digits") as string),
};
try {
const ret = await this.props.api.addNewTOTP(this.props.baseMount, parms);
if (!isExported) {
route("/secrets/totp/list/" + this.props.baseMount);
} else {
this.setState({ exportedData: ret });
}
} catch (e: unknown) {
const error = e as Error;
setErrorText(`API Error: ${error.message}`);
}
}
}
export class TOTPNewGenerated extends Component<DefaultPageProps> {
render() {
const baseMount = this.props.matches["baseMount"];
return (
<>
<SecretTitleElement
type="totp"
baseMount={baseMount}
suffix={i18next.t("totp_new_generated_suffix")}
/>
<TOTPNewGeneratedForm
settings={this.props.settings}
api={this.props.api}
baseMount={baseMount}
/>
</>
);
}
}