Source: component/verify.js

/*! meta-client/modules/component/verify */
/*jslint
    browser, long
*/
/*global
*/
/**
 * verify component.
 *
 * @module meta-client/modules/component/verify
 */
import ko from "knockout";
import Logger from "js-logger";
import protocol from "meta-core/modules/protocol";
import qrcodegen from "nayuki-qr-code-generator";
import template from "./verify.html";
import ui from "util-web/modules/ui";

const LOG = Logger.get("meta-client/component/verify");
const TOTP_QR_CANVAS_ID = "TotpQr";

export default Object.freeze({
    template,
    viewModel: {
        createViewModel: function ({id, onVerify, onVerifyDone}) {
            const vm = {};

            let verifyPromiseResolve;
            let verifyPromiseReject;

            vm.id = id;
            vm.totpQrCanvasId = id + TOTP_QR_CANVAS_ID;

            vm.isVerifyActive = ko.observable(false);
            vm.totpUri = ko.observable();
            vm.totpKey = ko.observable();
            vm.verifyOtp = ko.observable();
            vm.hasVerifyOtpFocus = ko.observable(false);

            vm.showTotpKey = function (totpIssuer, totpKey, user) {
                LOG.debug(`showTotpKey, user=${user}`);
                vm.totpKey(totpKey);
                const totpUri = protocol.getTotpKeyUri(totpKey, totpIssuer, user);
                const qr = qrcodegen.QrCode.encodeText(totpUri, qrcodegen.QrCode.Ecc.MEDIUM);
                ui.drawQrToCanvas(0, document.getElementById(vm.totpQrCanvasId), qr, 8);
                vm.totpUri(totpUri);
            };

            vm.startVerify = function ({
                totpIssuer,
                totpKey = null,
                user = null
            }) {
                LOG.debug("startVerify");
                vm.verifyOtp(undefined);
                vm.isVerifyActive(true);
                return new Promise(function (resolve, reject) {
                    verifyPromiseResolve = resolve;
                    verifyPromiseReject = reject;
                    if (totpKey) {
                        vm.showTotpKey(totpIssuer, totpKey, user);
                    }
                    vm.hasVerifyOtpFocus(true);
                });
            };

            vm.verify = function (form) {
                if (ui.validateForm(form) === false) {
                    return;
                }
                LOG.debug("verify");
                vm.isVerifyActive(false);
                verifyPromiseResolve(vm.verifyOtp());
                verifyPromiseResolve = undefined;
                verifyPromiseReject = undefined;
                ui.resetForm(form);
            };

            vm.cancelVerify = function () {
                LOG.debug("cancelVerify");
                vm.isVerifyActive(false);
                verifyPromiseReject();
                verifyPromiseResolve = undefined;
                verifyPromiseReject = undefined;
            };

            onVerify.subscribe(function (verifyOptions) {
                if (verifyOptions) {
                    vm.startVerify(verifyOptions).then(function (otp) {
                        onVerifyDone({otp});
                    }, function () {
                        onVerifyDone({});
                    }).then(function () {
                        onVerify(undefined);
                    });
                }
            });

            return Object.freeze(vm);
        }
    }
});