Rework TOTPView.tsx.
This commit is contained in:
parent
23cc9b60c9
commit
8f2e91bf6b
|
@ -4,37 +4,36 @@ import { Page } from "../../../types/Page";
|
||||||
import { SecretTitleElement } from "../SecretTitleElement";
|
import { SecretTitleElement } from "../SecretTitleElement";
|
||||||
import { getTOTPCode } from "../../../api/totp/getTOTPCode";
|
import { getTOTPCode } from "../../../api/totp/getTOTPCode";
|
||||||
import { getTOTPKeys } from "../../../api/totp/getTOTPKeys";
|
import { getTOTPKeys } from "../../../api/totp/getTOTPKeys";
|
||||||
import { makeElement } from "z-makeelement";
|
|
||||||
import { objectToMap } from "../../../utils";
|
|
||||||
import { setErrorText } from "../../../pageUtils";
|
import { setErrorText } from "../../../pageUtils";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import { render, JSX } from "preact";
|
import { render, JSX, Component } from "preact";
|
||||||
|
|
||||||
export interface TOTPListElement extends HTMLElement {
|
|
||||||
setCode(code: string): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
function quickHash(str: string): string {
|
|
||||||
var hash = 0;
|
export class RefreshingTOTPGridItem extends Component<{ baseMount: string; totpKey: string }, { totpValue: string }> {
|
||||||
if (str.length == 0) {
|
constructor() {
|
||||||
return String(hash).toString();
|
super();
|
||||||
|
this.state = { totpValue: "" };
|
||||||
}
|
}
|
||||||
for (var i = 0; i < str.length; i++) {
|
timer: unknown;
|
||||||
var char = str.charCodeAt(i);
|
|
||||||
hash = ((hash << 5) - hash) + char;
|
componentDidMount(): void {
|
||||||
hash = hash & hash;
|
this.timer = setInterval(() => {
|
||||||
|
getTOTPCode(this.props.baseMount, this.props.totpKey).then((code) => {
|
||||||
|
this.setState({ totpValue: code });
|
||||||
|
})
|
||||||
|
this.setState({});
|
||||||
|
}, 3000);
|
||||||
}
|
}
|
||||||
return String(hash).toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
render(): JSX.Element {
|
||||||
export function TOTPGridItem(props: { item_key: string, item_value: string }): JSX.Element {
|
|
||||||
return (
|
return (
|
||||||
<div class="uk-grid uk-grid-small uk-text-left" uk-grid>
|
<div class="uk-grid uk-grid-small uk-text-left" uk-grid>
|
||||||
<CopyableInputBox text={props.item_key} copyable />
|
<CopyableInputBox text={this.props.totpKey} copyable />
|
||||||
<CopyableInputBox text={props.item_value} copyable />
|
<CopyableInputBox text={this.state.totpValue} copyable />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TOTPViewPage extends Page {
|
export class TOTPViewPage extends Page {
|
||||||
|
@ -50,8 +49,6 @@ export class TOTPViewPage extends Page {
|
||||||
}
|
}
|
||||||
|
|
||||||
async render(): Promise<void> {
|
async render(): Promise<void> {
|
||||||
console.log(quickHash("abc"));
|
|
||||||
|
|
||||||
render((
|
render((
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
|
@ -61,62 +58,36 @@ export class TOTPViewPage extends Page {
|
||||||
}}>
|
}}>
|
||||||
{i18next.t("totp_view_new_btn")}
|
{i18next.t("totp_view_new_btn")}
|
||||||
</button>
|
</button>
|
||||||
<p id="loadingText">{i18next.t("totp_view_loading")}</p>
|
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<div id="totpList"></div>
|
<div id="totpList">
|
||||||
</div>
|
{await (async () => {
|
||||||
), this.router.pageContentElement)
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.updateTOTPElements();
|
const elem = await Promise.all(Array.from(await getTOTPKeys(this.state.baseMount)).map(async (key) =>
|
||||||
document.getElementById("loadingText").remove();
|
<RefreshingTOTPGridItem
|
||||||
|
baseMount={this.state.baseMount}
|
||||||
|
totpKey={key}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
return elem;
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
const error = e as Error;
|
const error = e as Error;
|
||||||
if (error == DoesNotExistError) {
|
if (error == DoesNotExistError) {
|
||||||
const loadingText = document.getElementById("loadingText");
|
return <p>{i18next.t("totp_view_empty")}</p>
|
||||||
loadingText.innerText = i18next.t("totp_view_empty");
|
|
||||||
} else {
|
} else {
|
||||||
setErrorText(error.message);
|
setErrorText(error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
})()}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
), this.router.pageContentElement)
|
||||||
|
|
||||||
const totpRefresher = async () => {
|
|
||||||
await this.updateTOTPElements();
|
|
||||||
};
|
|
||||||
|
|
||||||
this.refresher = setInterval(async () => {
|
|
||||||
await totpRefresher();
|
|
||||||
}, 3000) as unknown as number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async cleanup(): Promise<void> {
|
|
||||||
clearInterval(this.refresher);
|
|
||||||
}
|
|
||||||
|
|
||||||
async updateTOTPElements(): Promise<void> {
|
|
||||||
render((
|
|
||||||
<>
|
|
||||||
{await Promise.all(Array.from(await getTOTPKeys(this.state.baseMount)).map(async (key) =>
|
|
||||||
<TOTPGridItem
|
|
||||||
item_key={String(key).toString()}
|
|
||||||
item_value={await getTOTPCode(this.state.baseMount, key)}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</>
|
|
||||||
), document.querySelector("#totpList"))
|
|
||||||
}
|
|
||||||
|
|
||||||
makeTOTPListElement(totpKeyName: string): TOTPListElement {
|
|
||||||
|
|
||||||
const gridElement = makeElement({
|
|
||||||
tag: "div",
|
|
||||||
class: ["uk-grid", "uk-grid-small", "uk-text-expand"],
|
|
||||||
}) as TOTPListElement;
|
|
||||||
|
|
||||||
|
|
||||||
return gridElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
async getPageTitle(): Promise<Element | string> {
|
async getPageTitle(): Promise<Element | string> {
|
||||||
return await SecretTitleElement(this.router);
|
return await SecretTitleElement(this.router);
|
||||||
|
|
Loading…
Reference in a new issue