Auth & Autofill / PM-5976 - Safari Browser SSO Initialization Race Condition 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 <cgonzalez@bitwarden.com>
This commit is contained in:
Jared Snider 2024-02-02 16:23:15 -05:00 committed by GitHub
parent cb8849c355
commit d047723f04
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 25 additions and 8 deletions

View File

@ -35,6 +35,10 @@ class ContentMessageHandler implements ContentMessageHandlerInterface {
const { command } = data; const { command } = data;
const referrer = source.location.hostname; const referrer = source.location.hostname;
if (command === "checkIfReadyForAuthResult") {
window.postMessage({ command: "readyToReceiveAuthResult" }, "*");
}
if (command === "authResult") { if (command === "authResult") {
const { lastpass, code, state } = data; const { lastpass, code, state } = data;
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.

View File

@ -24,17 +24,30 @@ window.addEventListener("load", () => {
}); });
function initiateBrowserSsoIfDocumentReady(code: string, state: string, lastpass: boolean) { function initiateBrowserSsoIfDocumentReady(code: string, state: string, lastpass: boolean) {
if (document.readyState === "complete") { const MAX_ATTEMPTS = 200;
initiateBrowserSso(code, state, lastpass); const TIMEOUT_MS = 50;
return; 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); initiateBrowserSso(code, state, lastpass);
} }
}, 50); };
window.addEventListener("message", handleWindowMessage);
} }
function initiateBrowserSso(code: string, state: string, lastpass: boolean) { function initiateBrowserSso(code: string, state: string, lastpass: boolean) {