import { CopyableInputBox } from "../../elements/CopyableInputBox.js"; import { DoesNotExistError } from "../../types/internalErrors.js"; import { Page } from "../../types/Page.js"; import { changePage, setErrorText, setPageContent, setTitleElement } from "../../pageUtils.js"; import { getTOTPCode } from "../../api/getTOTPCode"; import { getTOTPKeys } from "../../api/getTOTPKeys"; import { makeElement } from "../../htmlUtils"; import { objectToMap } from "../../utils"; import { pageState } from "../../globalPageState.js"; import i18next from 'i18next'; export class TOTPViewPage extends Page { constructor() { super(); this.refresher = undefined; this.totpListElements = {}; } async render() { setTitleElement(pageState); let totpList = makeElement({ tag: "div" }); setPageContent(makeElement({ tag: "div", children: [ makeElement({ tag: "a", text: i18next.t("totp_view_new_btn"), onclick: _ => { changePage("NEW_TOTP"); } }), makeElement({ tag: "p", id: "loadingText", text: i18next.t("totp_view_loading"), }), makeElement({ tag: "br" }), makeElement({ tag: "br" }), totpList ] })); getTOTPKeys(pageState.currentBaseMount, pageState.currentSecretPath).then(res => { res.forEach(async function (totpKeyName) { let totpListElement = this.makeTOTPListElement(totpKeyName); totpList.appendChild(totpListElement); this.totpListElements[totpKeyName] = totpListElement; await this.updateTOTPElement(totpKeyName, totpListElement); }, this); document.getElementById("loadingText").remove(); }).catch(e => { if (e == DoesNotExistError) { let loadingText = document.getElementById("loadingText"); loadingText.innerText = i18next.t("totp_view_empty"); } else { setErrorText(e.message); } }); let totpRefresher = async () => { await Promise.all(Array.from(objectToMap(this.totpListElements)).map((kv) => { return this.updateTOTPElement(...kv); })) } await totpRefresher(); this.refresher = setInterval(totpRefresher, 3000); } cleanup() { clearInterval(this.refresher); this.totpListElements = {}; } async updateTOTPElement(totpKeyName, totpListElement) { totpListElement.setCode(await getTOTPCode(pageState.currentBaseMount, totpKeyName)); } makeTOTPListElement(totpKeyName) { let totpKeyBox = CopyableInputBox(totpKeyName, false); let totpValueBox = CopyableInputBox(i18next.t("totp_view_loading_box")); let gridElement = makeElement({ tag: "div", class: ["uk-grid", "uk-grid-small", "uk-text-expand"], children: [totpKeyBox, totpValueBox] }); gridElement.setCode = totpValueBox.setText; return gridElement; } get name() { return i18next.t("totp_view_title"); } }