Skip to content

Commit

Permalink
Auth & Autofill / PM-5976 - Safari Browser SSO Initialization Race Co…
Browse files Browse the repository at this point in the history
…ndition Attempted Fix 2 (#7794)

* Implementing pinging system for SSO to address issue on Safari with race condition

* Implementing pinging system for SSO to address issue on Safari with race condition

* [PM-5976] Updating references within sso.ts

---------

Co-authored-by: Cesar Gonzalez <[email protected]>
  • Loading branch information
JaredSnider-Bitwarden and Cesar Gonzalez committed Feb 2, 2024
1 parent 76d730b commit 4990c53
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 8 deletions.
4 changes: 4 additions & 0 deletions apps/browser/src/autofill/content/content-message-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ class ContentMessageHandler implements ContentMessageHandlerInterface {
const { command } = data;
const referrer = source.location.hostname;

if (command === "checkIfReadyForAuthResult") {
window.postMessage({ command: "readyToReceiveAuthResult" }, "*");
}

if (command === "authResult") {
const { lastpass, code, state } = data;
chrome.runtime.sendMessage({ command, code, state, lastpass, referrer });
Expand Down
29 changes: 21 additions & 8 deletions apps/web/src/connectors/sso.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,30 @@ window.addEventListener("load", () => {
});

function initiateBrowserSsoIfDocumentReady(code: string, state: string, lastpass: boolean) {
if (document.readyState === "complete") {
initiateBrowserSso(code, state, lastpass);
return;
}
const MAX_ATTEMPTS = 200;
const TIMEOUT_MS = 50;
let attempts = 0;

const pingInterval = setInterval(() => {
if (attempts >= MAX_ATTEMPTS) {
clearInterval(pingInterval);
throw new Error("Failed to initiate browser SSO");
}

attempts++;
window.postMessage({ command: "checkIfReadyForAuthResult" }, "*");
}, TIMEOUT_MS);

const handleWindowMessage = (event: MessageEvent) => {
if (event.source === window && event.data?.command === "readyToReceiveAuthResult") {
clearInterval(pingInterval);
window.removeEventListener("message", handleWindowMessage);

const interval = setInterval(() => {
if (document.readyState === "complete") {
clearInterval(interval);
initiateBrowserSso(code, state, lastpass);
}
}, 50);
};

window.addEventListener("message", handleWindowMessage);
}

function initiateBrowserSso(code: string, state: string, lastpass: boolean) {
Expand Down

0 comments on commit 4990c53

Please sign in to comment.