const PLUGIN_ID = "app"; const CHANNEL_ID = `${PLUGIN_ID}-auth-cookie-expires-at`; const MIN_BASE_DELAY_MS = 5 * 6e4; const ERROR_BACKOFF_START = 5e3; const ERROR_BACKOFF_FACTOR = 2; const ERROR_BACKOFF_MAX = 5 * 6e4; function startCookieAuthRefresh({ discoveryApi, fetchApi, errorApi }) { let stopped = false; let timeout; let firstError = true; let errorBackoff = ERROR_BACKOFF_START; const channel = "BroadcastChannel" in window ? new BroadcastChannel(CHANNEL_ID) : void 0; const getDelay = (expiresAt) => { const margin = (1 + 3 * Math.random()) * 6e4; const delay = Math.max(expiresAt - Date.now(), MIN_BASE_DELAY_MS) - margin; return delay; }; const refresh = async () => { try { const baseUrl = await discoveryApi.getBaseUrl(PLUGIN_ID); const requestUrl = `${baseUrl}/.backstage/auth/v1/cookie`; const res = await fetchApi.fetch(requestUrl, { credentials: "include" }); if (!res.ok) { throw new Error( `Request failed with status ${res.status} ${res.statusText}, see request towards ${requestUrl} for more details` ); } const data = await res.json(); if (!data.expiresAt) { throw new Error("No expiration date in response"); } const expiresAt = Date.parse(data.expiresAt); if (Number.isNaN(expiresAt)) { throw new Error("Invalid expiration date in response"); } firstError = true; channel?.postMessage({ action: "COOKIE_REFRESH_SUCCESS", payload: { expiresAt: new Date(expiresAt).toISOString() } }); scheduleRefresh(getDelay(expiresAt)); } catch (error) { if (firstError) { firstError = false; errorBackoff = ERROR_BACKOFF_START; } else { errorBackoff = Math.min( ERROR_BACKOFF_MAX, errorBackoff * ERROR_BACKOFF_FACTOR ); console.error("Session cookie refresh failed", error); errorApi.post( new Error( `Session refresh failed, see developer console for details` ) ); } scheduleRefresh(errorBackoff); } }; const onMessage = (event) => { const { data } = event; if (data === null || typeof data !== "object") { return; } if ("action" in data && data.action === "COOKIE_REFRESH_SUCCESS") { const expiresAt = Date.parse(data.payload.expiresAt); if (Number.isNaN(expiresAt)) { console.warn( "Received invalid expiration from session refresh channel" ); return; } scheduleRefresh(getDelay(expiresAt)); } }; function scheduleRefresh(delayMs) { if (stopped) { return; } if (timeout) { clearTimeout(timeout); } timeout = setTimeout(refresh, delayMs); } channel?.addEventListener("message", onMessage); refresh(); return () => { stopped = true; if (timeout) { clearTimeout(timeout); } channel?.removeEventListener("message", onMessage); channel?.close(); }; } export { startCookieAuthRefresh }; //# sourceMappingURL=startCookieAuthRefresh.esm.js.map