1
0
Fork 0
VaultUI/src/pages/Unseal.js
2021-05-07 23:33:58 +01:00

166 lines
4.4 KiB
JavaScript

import { MarginInline } from "../elements/MarginInline.js";
import { Page } from "../types/Page";
import { QRScanner } from "../elements/QRScanner.js";
import { changePage, setErrorText, setPageContent } from "../pageUtils";
import { getSealStatus } from "../api/getSealStatus.js";
import { makeElement } from "../htmlUtils";
import { submitUnsealKey } from "../api/submitUnsealKey.js";
import i18next from 'i18next';
const UnsealInputModes = {
FORM_INPUT: "FORM_INPUT",
QR_INPUT: "QR_INPUT"
}
export class UnsealPage extends Page {
constructor() {
super();
this.mode = UnsealInputModes.FORM_INPUT;
}
cleanup() {
this.deinitWebcam()
clearInterval(this.refresher);
}
deinitWebcam() {
try {
this.qrScanner.deinit();
} catch (_) {
// Do Nothing
}
}
makeRefresher() {
this.refresher = setInterval(async function () {
this.updateSealProgress(await getSealStatus());
}.bind(this), 1000);
}
async render() {
this.unsealProgress = makeElement({
tag: "progress",
class: "uk-progress",
attributes: { value: "0", max: "0" }
});
this.unsealProgressText = makeElement({
tag: "p",
text: i18next.t("unseal_keys_progress", { progress: "0", keys_needed: "0" }),
});
this.unsealInputContent = makeElement({
tag: "div"
})
setPageContent(makeElement({
tag: "div",
children: [
this.unsealProgress,
makeElement({
tag: "p",
id: "errorText",
class: ["uk-text-danger", "uk-margin-top"]
}),
this.unsealProgressText,
this.unsealInputContent
]
}));
this.switchInputMode(this.mode);
this.updateSealProgress(await getSealStatus());
this.makeRefresher();
}
setButtons(method) {
let newMethod;
let buttonText;
newMethod = method == UnsealInputModes.FORM_INPUT ? UnsealInputModes.QR_INPUT : UnsealInputModes.FORM_INPUT;
buttonText = newMethod == UnsealInputModes.FORM_INPUT ? i18next.t("unseal_input_btn") : i18next.t("unseal_qr_btn");
this.unsealInputContent.appendChild(makeElement({
tag: "button",
class: ["uk-button", "uk-button-primary"],
text: buttonText,
onclick: () => {
this.switchInputMode(newMethod);
}
}))
}
switchInputMode(method) {
this.deinitWebcam();
this.unsealInputContent.querySelectorAll('*').forEach(n => n.remove())
if (method == UnsealInputModes.FORM_INPUT) this.makeUnsealForm();
if (method == UnsealInputModes.QR_INPUT) this.makeQRInput();
this.setButtons(method);
}
makeUnsealForm() {
this.unsealKeyForm = makeElement({
tag: "form",
children: [
MarginInline(makeElement({
tag: "input",
class: ["uk-input", "uk-form-width-medium"],
attributes: {
required: true,
type: "password",
placeholder: i18next.t("key_input_placeholder"),
name: "key"
}
})),
MarginInline(makeElement({
tag: "button",
class: ["uk-button", "uk-button-primary"],
text: i18next.t("submit_key_btn")
})),
]
});
this.unsealInputContent.appendChild(this.unsealKeyForm);
this.unsealKeyForm.addEventListener("submit", function (e) {
e.preventDefault();
this.handleKeySubmit();
}.bind(this));
}
async makeQRInput() {
this.qrScanner = await QRScanner(function (code) {
this.submitKey(code);
console.log('decoded qr code:', code)
}.bind(this));
this.unsealInputContent.appendChild(this.qrScanner);
}
updateSealProgress(data) {
let progress = data.progress;
let keysNeeded = data.t;
let text = this.unsealProgressText;
text.innerText = i18next.t("unseal_keys_progress", {
progress: String(progress),
keys_needed: String(keysNeeded)
});
let progressBar = this.unsealProgress;
progressBar.value = progress;
progressBar.max = keysNeeded;
if (!data.sealed) {
progressBar.value = keysNeeded;
changePage("HOME");
}
}
submitKey(key) {
submitUnsealKey(key).then(_ => {
getSealStatus().then(data => {
this.updateSealProgress(data);
});
}).catch(e => {
setErrorText(e.message);
});
}
async handleKeySubmit() {
let formData = new FormData(this.unsealKeyForm);
this.submitKey(formData.get("key"))
}
get name() {
return i18next.t("unseal_vault_text");
}
}