1
0
Fork 0

Add ability to add totp codes by scanning a QR code. Closes #30.

This commit is contained in:
Kitteh 2021-05-25 12:36:10 +01:00
parent 4927707450
commit 64e3e9911b
2 changed files with 82 additions and 32 deletions

View file

@ -1,31 +1,54 @@
import { Component, JSX, createRef, render } from "preact";
import { Form } from "../../../elements/Form";
import { Margin } from "../../../elements/Margin";
import { MarginInline } from "../../../elements/MarginInline";
import { Page } from "../../../types/Page";
import { QRScanner } from "../../../elements/QRScanner";
import { SecretTitleElement } from "../SecretTitleElement";
import { addNewTOTP } from "../../../api/totp/addNewTOTP";
import { render } from "preact";
import { setErrorText } from "../../../pageUtils";
import i18next from "i18next";
function replaceAll(str: string, replace: string, replaceWith: string): string {
return str.replace(new RegExp(replace, "g"), replaceWith);
}
function removeDashSpaces(str: string): string {
str = replaceAll(str, "-", "");
str = replaceAll(str, " ", "");
return str;
}
export class TOTPNewPage extends Page {
export class TOTPNewForm extends Component<{ page: Page }, { qrMode: boolean }> {
constructor() {
super();
this.state = {
qrMode: false,
};
}
async goBack(): Promise<void> {
await this.router.changePage("TOTP_VIEW");
uriInputRef = createRef<HTMLInputElement>();
async onSubmit(data: FormData): Promise<void> {
const page = this.props.page;
const parms = {
url: data.get("uri") as string,
key: removeDashSpaces(data.get("key") as string).toUpperCase(),
name: data.get("name") as string,
generate: false,
};
try {
await addNewTOTP(page.state.baseMount, parms);
await page.router.changePage("TOTP_VIEW");
} catch (e: unknown) {
const error = e as Error;
setErrorText(`API Error: ${error.message}`);
}
}
async render(): Promise<void> {
render(
render(): JSX.Element {
return (
<Form onSubmit={(data) => this.onSubmit(data)}>
<Margin>
<input
@ -36,49 +59,74 @@ export class TOTPNewPage extends Page {
required
/>
</Margin>
<p>{i18next.t("totp_new_info")}</p>
<Margin>
<input
class="uk-input uk-form-width-medium"
name="uri"
type="text"
placeholder={i18next.t("totp_new_uri_input")}
/>
</Margin>
<p hidden={this.state.qrMode}>{i18next.t("totp_new_info")}</p>
<Margin>
<input
class="uk-input uk-form-width-medium"
name="key"
type="text"
hidden={this.state.qrMode}
placeholder={i18next.t("totp_new_key_input")}
/>
</Margin>
<Margin>
<input
class="uk-input uk-form-width-medium"
ref={this.uriInputRef}
name="uri"
type="text"
hidden={this.state.qrMode}
placeholder={i18next.t("totp_new_uri_input")}
/>
</Margin>
{this.state.qrMode && (
<QRScanner
onScan={(uri) => {
this.uriInputRef.current.value = uri;
this.setState({ qrMode: !this.state.qrMode });
}}
/>
)}
<MarginInline>
<button
class="uk-button uk-button-primary"
type="button"
onClick={() => {
this.setState({ qrMode: !this.state.qrMode });
}}
>
{!this.state.qrMode
? i18next.t("totp_new_switch_to_qr_btn")
: i18next.t("totp_new_switch_back_to_manual_input_btn")}
</button>
</MarginInline>
<p id="errorText" class="uk-text-danger" />
<MarginInline>
<button class="uk-button uk-button-primary" type="submit">
{i18next.t("totp_new_add_btn")}
</button>
</MarginInline>
</Form>,
this.router.pageContentElement,
</Form>
);
}
}
async onSubmit(data: FormData): Promise<void> {
const parms = {
url: data.get("uri") as string,
key: removeDashSpaces(data.get("key") as string).toUpperCase(),
name: data.get("name") as string,
generate: false,
};
try {
await addNewTOTP(this.state.baseMount, parms);
await this.router.changePage("TOTP_VIEW");
} catch (e: unknown) {
const error = e as Error;
setErrorText(`API Error: ${error.message}`);
}
export class TOTPNewPage extends Page {
constructor() {
super();
}
async goBack(): Promise<void> {
await this.router.changePage("TOTP_VIEW");
}
async render(): Promise<void> {
render(<TOTPNewForm page={this} />, this.router.pageContentElement);
}
async renderPageTitle(): Promise<void> {

View file

@ -163,6 +163,8 @@ module.exports = {
totp_new_uri_input: "URI",
totp_new_key_input: "Key",
totp_new_add_btn: "Add TOTP Key",
totp_new_switch_to_qr_btn: "Switch to QR Input",
totp_new_switch_back_to_manual_input_btn: "Switch back to manual input",
// TOTP Delete Page
totp_delete_title: "Delete TOTP Key",