mirror of
https://github.com/bitwarden/browser
synced 2025-12-20 10:13:31 +00:00
Move web to apps/web and bitwarden_license/bit-web
This commit is contained in:
164
apps/web/src/connectors/webauthn-fallback.ts
Normal file
164
apps/web/src/connectors/webauthn-fallback.ts
Normal file
@@ -0,0 +1,164 @@
|
||||
import { b64Decode, getQsParam } from "./common";
|
||||
import { buildDataString, parseWebauthnJson } from "./common-webauthn";
|
||||
|
||||
require("./webauthn.scss");
|
||||
|
||||
let parsed = false;
|
||||
let webauthnJson: any;
|
||||
let parentUrl: string = null;
|
||||
let sentSuccess = false;
|
||||
let locale = "en";
|
||||
|
||||
let locales: any = {};
|
||||
|
||||
function parseParameters() {
|
||||
if (parsed) {
|
||||
return;
|
||||
}
|
||||
|
||||
parentUrl = getQsParam("parent");
|
||||
if (!parentUrl) {
|
||||
error("No parent.");
|
||||
return;
|
||||
} else {
|
||||
parentUrl = decodeURIComponent(parentUrl);
|
||||
}
|
||||
|
||||
locale = getQsParam("locale").replace("-", "_");
|
||||
|
||||
const version = getQsParam("v");
|
||||
|
||||
if (version === "1") {
|
||||
parseParametersV1();
|
||||
} else {
|
||||
parseParametersV2();
|
||||
}
|
||||
parsed = true;
|
||||
}
|
||||
|
||||
function parseParametersV1() {
|
||||
const data = getQsParam("data");
|
||||
if (!data) {
|
||||
error("No data.");
|
||||
return;
|
||||
}
|
||||
|
||||
webauthnJson = b64Decode(data);
|
||||
}
|
||||
|
||||
function parseParametersV2() {
|
||||
let dataObj: { data: any; btnText: string } = null;
|
||||
try {
|
||||
dataObj = JSON.parse(b64Decode(getQsParam("data")));
|
||||
} catch (e) {
|
||||
error("Cannot parse data.");
|
||||
return;
|
||||
}
|
||||
|
||||
webauthnJson = dataObj.data;
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", async () => {
|
||||
parseParameters();
|
||||
try {
|
||||
locales = await loadLocales(locale);
|
||||
} catch {
|
||||
// eslint-disable-next-line
|
||||
console.error("Failed to load the locale", locale);
|
||||
locales = await loadLocales("en");
|
||||
}
|
||||
|
||||
document.getElementById("msg").innerText = translate("webAuthnFallbackMsg");
|
||||
document.getElementById("remember-label").innerText = translate("rememberMe");
|
||||
|
||||
const button = document.getElementById("webauthn-button");
|
||||
button.innerText = translate("webAuthnAuthenticate");
|
||||
button.onclick = start;
|
||||
|
||||
document.getElementById("spinner").classList.add("d-none");
|
||||
const content = document.getElementById("content");
|
||||
content.classList.add("d-block");
|
||||
content.classList.remove("d-none");
|
||||
});
|
||||
|
||||
async function loadLocales(newLocale: string) {
|
||||
const filePath = `locales/${newLocale}/messages.json?cache=${process.env.CACHE_TAG}`;
|
||||
const localesResult = await fetch(filePath);
|
||||
return await localesResult.json();
|
||||
}
|
||||
|
||||
function translate(id: string) {
|
||||
return locales[id]?.message || "";
|
||||
}
|
||||
|
||||
function start() {
|
||||
if (sentSuccess) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!("credentials" in navigator)) {
|
||||
error(translate("webAuthnNotSupported"));
|
||||
return;
|
||||
}
|
||||
|
||||
parseParameters();
|
||||
if (!webauthnJson) {
|
||||
error("No data.");
|
||||
return;
|
||||
}
|
||||
|
||||
let json: any;
|
||||
try {
|
||||
json = parseWebauthnJson(webauthnJson);
|
||||
} catch (e) {
|
||||
error("Cannot parse data.");
|
||||
return;
|
||||
}
|
||||
|
||||
initWebAuthn(json);
|
||||
}
|
||||
|
||||
async function initWebAuthn(obj: any) {
|
||||
try {
|
||||
const assertedCredential = (await navigator.credentials.get({
|
||||
publicKey: obj,
|
||||
})) as PublicKeyCredential;
|
||||
|
||||
if (sentSuccess) {
|
||||
return;
|
||||
}
|
||||
|
||||
const dataString = buildDataString(assertedCredential);
|
||||
const remember = (document.getElementById("remember") as HTMLInputElement).checked;
|
||||
window.postMessage({ command: "webAuthnResult", data: dataString, remember: remember }, "*");
|
||||
|
||||
sentSuccess = true;
|
||||
success(translate("webAuthnSuccess"));
|
||||
} catch (err) {
|
||||
error(err);
|
||||
}
|
||||
}
|
||||
|
||||
function error(message: string) {
|
||||
const el = document.getElementById("msg");
|
||||
resetMsgBox(el);
|
||||
el.textContent = message;
|
||||
el.classList.add("alert");
|
||||
el.classList.add("alert-danger");
|
||||
}
|
||||
|
||||
function success(message: string) {
|
||||
(document.getElementById("webauthn-button") as HTMLButtonElement).disabled = true;
|
||||
|
||||
const el = document.getElementById("msg");
|
||||
resetMsgBox(el);
|
||||
el.textContent = message;
|
||||
el.classList.add("alert");
|
||||
el.classList.add("alert-success");
|
||||
}
|
||||
|
||||
function resetMsgBox(el: HTMLElement) {
|
||||
el.classList.remove("alert");
|
||||
el.classList.remove("alert-danger");
|
||||
el.classList.remove("alert-success");
|
||||
}
|
||||
Reference in New Issue
Block a user