mirror of
https://github.com/bitwarden/browser
synced 2026-02-07 20:24:01 +00:00
fix(redirect): [PM-26578] Https Redirection for Cloud Users - Made redirect uri not required for mobile webauthn
This commit is contained in:
@@ -40,7 +40,7 @@ function appLinkHost(): string {
|
||||
return "bitwarden.com";
|
||||
}
|
||||
|
||||
export function buildMobileCallbackUriFromParam(kind: "duo" | "webauthn"): string {
|
||||
export function buildMobileDeeplinkUriFromParam(kind: "duo" | "webauthn"): string {
|
||||
const scheme = (getQsParam("deeplinkScheme") || "").toLowerCase();
|
||||
const path = `${kind}-callback`;
|
||||
if (scheme === "https") {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { buildMobileCallbackUriFromParam, getQsParam } from "./common";
|
||||
import { buildMobileDeeplinkUriFromParam, getQsParam } from "./common";
|
||||
import { TranslationService } from "./translation.service";
|
||||
|
||||
const mobileDesktopCallback = "bitwarden://duo-callback";
|
||||
@@ -40,7 +40,7 @@ window.addEventListener("load", async () => {
|
||||
displayHandoffMessage(client);
|
||||
} else if (client === "mobile") {
|
||||
document.location.replace(
|
||||
buildMobileCallbackUriFromParam("duo") +
|
||||
buildMobileDeeplinkUriFromParam("duo") +
|
||||
"?code=" +
|
||||
encodeURIComponent(code) +
|
||||
"&state=" +
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { b64Decode, buildMobileCallbackUriFromParam, getQsParam } from "./common";
|
||||
import { b64Decode, getQsParam } from "./common";
|
||||
import { buildDataString, parseWebauthnJson } from "./common-webauthn";
|
||||
|
||||
let parsed = false;
|
||||
@@ -11,7 +11,7 @@ let btnAwaitingInteractionText: string = null;
|
||||
let btnReturnText: string = null;
|
||||
let parentUrl: string = null;
|
||||
let parentOrigin: string = null;
|
||||
let mobileResponse = false;
|
||||
let callbackUri: string = null;
|
||||
let stopWebAuthn = false;
|
||||
let sentSuccess = false;
|
||||
let obj: any = null;
|
||||
@@ -81,21 +81,8 @@ function parseParameters() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine if this is a mobile-initiated flow via query param
|
||||
const client: string | null = getQsParam("client");
|
||||
|
||||
if (client === "mobile") {
|
||||
mobileResponse = true;
|
||||
}
|
||||
|
||||
parentUrl = getQsParam("parent");
|
||||
if (!parentUrl) {
|
||||
// In non-mobile flows we must have a parent for postMessage handoff
|
||||
if (!mobileResponse) {
|
||||
error("No parent.");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (parentUrl) {
|
||||
parentUrl = decodeURIComponent(parentUrl);
|
||||
parentOrigin = new URL(parentUrl).origin;
|
||||
}
|
||||
@@ -107,6 +94,13 @@ function parseParameters() {
|
||||
} else {
|
||||
parseParametersV2();
|
||||
}
|
||||
|
||||
// Require at least one return mechanism
|
||||
if (!parentUrl && !callbackUri) {
|
||||
error("No return target provided.");
|
||||
return;
|
||||
}
|
||||
|
||||
parsed = true;
|
||||
}
|
||||
|
||||
@@ -131,7 +125,6 @@ function parseParametersV2() {
|
||||
btnText: string;
|
||||
btnReturnText: string;
|
||||
callbackUri?: string;
|
||||
mobile?: boolean;
|
||||
} = null;
|
||||
try {
|
||||
dataObj = JSON.parse(b64Decode(getQsParam("data")));
|
||||
@@ -142,8 +135,8 @@ function parseParametersV2() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Treat presence of callbackUri/mobile in payload as mobile, or preserve existing mobileResponse (e.g., set by client=mobile)
|
||||
mobileResponse = mobileResponse || dataObj.callbackUri != null || dataObj.mobile === true;
|
||||
// Use optional callbackUri to indicate deep-link return; otherwise we will use postMessage to parent
|
||||
callbackUri = dataObj.callbackUri ?? null;
|
||||
webauthnJson = dataObj.data;
|
||||
headerText = dataObj.headerText;
|
||||
btnText = dataObj.btnText;
|
||||
@@ -184,8 +177,8 @@ function start() {
|
||||
stopWebAuthn = false;
|
||||
|
||||
if (
|
||||
mobileResponse ||
|
||||
(navigator.userAgent.indexOf(" Safari/") !== -1 && navigator.userAgent.indexOf("Chrome") === -1)
|
||||
navigator.userAgent.indexOf(" Safari/") !== -1 &&
|
||||
navigator.userAgent.indexOf("Chrome") === -1
|
||||
) {
|
||||
// Safari and mobile chrome blocks non-user initiated WebAuthn requests.
|
||||
} else {
|
||||
@@ -208,7 +201,7 @@ function onMessage() {
|
||||
window.addEventListener(
|
||||
"message",
|
||||
(event) => {
|
||||
if (!event.origin || event.origin === "" || event.origin !== parentOrigin) {
|
||||
if (parentOrigin && (!event.origin || event.origin === "" || event.origin !== parentOrigin)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -224,11 +217,11 @@ function onMessage() {
|
||||
}
|
||||
|
||||
function error(message: string) {
|
||||
if (mobileResponse) {
|
||||
const callbackUri = buildMobileCallbackUriFromParam("webauthn");
|
||||
document.location.replace(callbackUri + "?error=" + encodeURIComponent(message));
|
||||
returnButton(callbackUri + "?error=" + encodeURIComponent(message));
|
||||
} else {
|
||||
if (callbackUri) {
|
||||
const uri = callbackUri + "?error=" + encodeURIComponent(message);
|
||||
document.location.replace(uri);
|
||||
returnButton(uri);
|
||||
} else if (parentUrl) {
|
||||
parent.postMessage("error|" + message, parentUrl);
|
||||
setDefaultWebAuthnButtonState();
|
||||
}
|
||||
@@ -241,18 +234,18 @@ function success(assertedCredential: PublicKeyCredential) {
|
||||
|
||||
const dataString = buildDataString(assertedCredential);
|
||||
|
||||
if (mobileResponse) {
|
||||
const callbackUri = buildMobileCallbackUriFromParam("webauthn");
|
||||
document.location.replace(callbackUri + "?data=" + encodeURIComponent(dataString));
|
||||
returnButton(callbackUri + "?data=" + encodeURIComponent(dataString));
|
||||
} else {
|
||||
if (callbackUri) {
|
||||
const uri = callbackUri + "?data=" + encodeURIComponent(dataString);
|
||||
document.location.replace(uri);
|
||||
returnButton(uri);
|
||||
} else if (parentUrl) {
|
||||
parent.postMessage("success|" + dataString, parentUrl);
|
||||
sentSuccess = true;
|
||||
}
|
||||
}
|
||||
|
||||
function info(message: string) {
|
||||
if (mobileResponse) {
|
||||
if (!parentUrl) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user