function createAuthXsrfRecovery({ COOKIE_REFRESH_POLL_MS, COOKIE_REFRESH_TIMEOUT_MS, OPPORTUNITIES_LIST_URL, getXsrfTokenCookie, supportsFirefoxCookieStoreTabs, tabsCreate, tabsRemove, wait }) { async function refreshXsrfCookie(sender) { const startedAt = Date.now(); const previous = (await getXsrfTokenCookie()).cookie; const createProperties = { url: OPPORTUNITIES_LIST_URL, active: false }; if (sender && sender.tab && Number.isInteger(sender.tab.windowId)) { createProperties.windowId = sender.tab.windowId; } if (supportsFirefoxCookieStoreTabs() && sender && sender.tab && sender.tab.cookieStoreId) { createProperties.cookieStoreId = sender.tab.cookieStoreId; } let refreshTab; try { refreshTab = await tabsCreate(createProperties); const current = await waitForXsrfCookieChange(previous); const refreshed = hasCookieChanged(previous, current); return { ok: Boolean(current), refreshed, cookieName: current ? current.name : "", durationMs: Date.now() - startedAt, error: refreshed ? "" : "XSRF cookie was not created or changed before timeout." }; } finally { if (refreshTab && Number.isInteger(refreshTab.id)) { try { await tabsRemove(refreshTab.id); } catch (error) { // The temporary tab may already have been closed. } } } } async function waitForXsrfCookieChange(previousCookie) { const deadline = Date.now() + COOKIE_REFRESH_TIMEOUT_MS; let currentCookie = null; while (Date.now() < deadline) { currentCookie = (await getXsrfTokenCookie()).cookie; if (hasCookieChanged(previousCookie, currentCookie)) { return currentCookie; } await wait(COOKIE_REFRESH_POLL_MS); } return currentCookie; } function hasCookieChanged(previousCookie, currentCookie) { if (!currentCookie || !currentCookie.value) { return false; } if (!previousCookie) { return true; } return previousCookie.name !== currentCookie.name || previousCookie.value !== currentCookie.value || previousCookie.expirationDate !== currentCookie.expirationDate; } return { refreshXsrfCookie, waitForXsrfCookieChange, hasCookieChanged }; }