Fixed the SPA authentication flow
This commit is contained in:
360
dist/firefox/background.js
vendored
360
dist/firefox/background.js
vendored
@@ -222,7 +222,7 @@ function createBackgroundContracts() {
|
||||
const OPPTY_PRODUCTS_MAX_PAGES = 250;
|
||||
const OPPTY_PRODUCTS_CONCURRENCY = 4;
|
||||
const CUSTOMER_TOKEN_SERVICE_URL = "https://spa.oracle.com/oalcrm/web/api/g2m-consumer-application/consumerTokenService";
|
||||
const CUSTOMER_TOKEN_SESSION_URL = "https://spa.oracle.com/oalcrm/web/api/g2m-consumer-application/ui/index.html";
|
||||
const CUSTOMER_TOKEN_SESSION_URL = "https://spa.oracle.com/";
|
||||
const CUSTOMER_TOKEN_MAX_ATTEMPTS = 5;
|
||||
const CUSTOMER_TOKEN_RETRY_BASE_DELAY_MS = 750;
|
||||
const CUSTOMER_TOKEN_RETRY_MAX_DELAY_MS = 4000;
|
||||
@@ -294,9 +294,16 @@ function createAuthConsumerSession({
|
||||
fetchJson,
|
||||
supportsFirefoxCookieStoreTabs,
|
||||
tabsCreate,
|
||||
tabsUpdate,
|
||||
tabsRemove,
|
||||
responseHeaders,
|
||||
cookieChanges,
|
||||
inspectPage,
|
||||
setTimeout,
|
||||
clearTimeout,
|
||||
wait
|
||||
}) {
|
||||
const sessionTabs = new Map();
|
||||
async function requestConsumerTokenService(sender) {
|
||||
const debugRequests = [];
|
||||
|
||||
@@ -436,7 +443,8 @@ function createAuthConsumerSession({
|
||||
debugEntry.metadata.nextRetryDelayMs = String(retryDelayMs);
|
||||
}
|
||||
|
||||
await wait(retryDelayMs);
|
||||
if (sessionTab) await waitForConsumerTokenSession(sessionTab, debugEntry, retryDelayMs);
|
||||
else await wait(retryDelayMs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -446,7 +454,7 @@ function createAuthConsumerSession({
|
||||
const debugEntry = debugRequests[debugRequests.length - 1];
|
||||
|
||||
try {
|
||||
await tabsRemove(sessionTab.id);
|
||||
await closeConsumerTokenSessionTab(sessionTab.id);
|
||||
if (debugEntry) {
|
||||
debugEntry.metadata.sessionBootstrapState = receivedValidJson
|
||||
? "closed-after-valid-json"
|
||||
@@ -498,7 +506,7 @@ function createAuthConsumerSession({
|
||||
}
|
||||
}
|
||||
|
||||
function openConsumerTokenSessionTab(sender) {
|
||||
async function openConsumerTokenSessionTab(sender) {
|
||||
const details = {
|
||||
url: CUSTOMER_TOKEN_SESSION_URL,
|
||||
active: false
|
||||
@@ -512,10 +520,186 @@ function createAuthConsumerSession({
|
||||
details.cookieStoreId = sender.tab.cookieStoreId;
|
||||
}
|
||||
|
||||
return tabsCreate(details);
|
||||
const tab = await tabsCreate(details);
|
||||
if (Number.isInteger(tab?.id)) {
|
||||
const state = { failedStatus: 0, reloads: 0, lastReloadAt: -Infinity, readyVersion: 0, consumedVersion: 0, closed: false };
|
||||
const signal = reason => {
|
||||
state.readyVersion++;
|
||||
state.readyReason = reason;
|
||||
state.wake?.();
|
||||
};
|
||||
state.listener = details => {
|
||||
if (details.tabId !== tab.id
|
||||
|| !/^https:\/\/spa\.oracle\.com\//.test(details.url)) return;
|
||||
if (details.type === "main_frame") {
|
||||
if (details.statusCode === 401 || details.statusCode === 403) {
|
||||
state.failedStatus = details.statusCode;
|
||||
state.consumedVersion = state.readyVersion;
|
||||
state.wake?.();
|
||||
} else if (details.statusCode >= 200 && details.statusCode < 300) {
|
||||
state.failedStatus = 0;
|
||||
if (!details.url.startsWith("https://spa.oracle.com/cloudgate/")) signal("spa-document-response");
|
||||
}
|
||||
} else if (details.type === "xmlhttprequest" && details.statusCode === 200
|
||||
&& details.url.split("?")[0] === "https://spa.oracle.com/oalcrm/web/api/identity-management/users/current"
|
||||
&& details.responseHeaders?.some(header => header.name.toLowerCase() === "content-type" && /application\/json/i.test(header.value))) {
|
||||
state.failedStatus = 0;
|
||||
signal("spa-identity-json-response");
|
||||
}
|
||||
};
|
||||
state.cookieListener = change => {
|
||||
const cookie = change.cookie;
|
||||
if (change.removed || !cookie?.value || !cookie.secure || !cookie.httpOnly
|
||||
|| cookie.domain?.replace(/^\./, "") !== "spa.oracle.com" || !/session/i.test(cookie.name)
|
||||
|| (cookie.expirationDate != null && cookie.expirationDate <= Date.now() / 1000)
|
||||
|| (sender?.tab?.cookieStoreId && cookie.storeId !== sender.tab.cookieStoreId)) return;
|
||||
signal("spa-session-cookie-changed");
|
||||
};
|
||||
try {
|
||||
responseHeaders?.addListener(state.listener, { urls: ["https://spa.oracle.com/*"], types: ["main_frame", "xmlhttprequest"] }, ["responseHeaders"]);
|
||||
cookieChanges?.addListener(state.cookieListener);
|
||||
sessionTabs.set(tab.id, state);
|
||||
} catch (error) {
|
||||
responseHeaders?.removeListener?.(state.listener);
|
||||
cookieChanges?.removeListener(state.cookieListener);
|
||||
await tabsRemove(tab.id).catch(() => {});
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return tab;
|
||||
}
|
||||
|
||||
return { requestConsumerTokenService, fetchConsumerTokenServiceUntilJson, getConsumerTokenRetryDelay, openConsumerTokenSessionTabWithRetry, openConsumerTokenSessionTab };
|
||||
async function recoverConsumerTokenSessionTab(tab, debugEntry, reason = "") {
|
||||
const state = sessionTabs.get(tab.id);
|
||||
if (!state || (!state.failedStatus && !reason) || Date.now() - state.lastReloadAt < 2000) return false;
|
||||
const status = state.failedStatus;
|
||||
state.failedStatus = 0;
|
||||
state.consumedVersion = state.readyVersion;
|
||||
state.lastReloadAt = Date.now();
|
||||
state.reloads++;
|
||||
if (debugEntry) {
|
||||
debugEntry.metadata.sessionBootstrapReloadCount = String(state.reloads);
|
||||
debugEntry.metadata.sessionBootstrapReloadReason = reason || `SPA navigation returned HTTP ${status}`;
|
||||
}
|
||||
try {
|
||||
// Restart at the entry point; OAuth callback URLs may contain single-use state.
|
||||
await tabsUpdate(tab.id, { url: CUSTOMER_TOKEN_SESSION_URL, active: false });
|
||||
if (debugEntry) debugEntry.metadata.sessionBootstrapReloadState = "restarted-at-spa-home";
|
||||
return true;
|
||||
} catch (error) {
|
||||
state.failedStatus = status;
|
||||
if (debugEntry) debugEntry.metadata.sessionBootstrapReloadState = `restart-failed: ${error.message || "unknown error"}`;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async function waitForSpaPage(tab, debugEntry) {
|
||||
const startedAt = Date.now();
|
||||
const deadline = startedAt + 120000;
|
||||
let restartedDocument = null;
|
||||
let restarts = 0;
|
||||
if (debugEntry) {
|
||||
delete debugEntry.metadata.nextRetryDelayMs;
|
||||
debugEntry.metadata.sessionWaitTimeoutMs = "120000";
|
||||
debugEntry.metadata.sessionWaitReason = "inspecting-spa-document";
|
||||
}
|
||||
while (Date.now() < deadline) {
|
||||
const state = sessionTabs.get(tab.id);
|
||||
if (state?.closed) break;
|
||||
let page;
|
||||
try { page = await inspectPage(tab); } catch { /* Cross-origin SSO pages have no SPA receiver. */ }
|
||||
if (debugEntry) debugEntry.metadata.spaPageState = page?.status || "loading-or-login";
|
||||
const documentId = typeof page?.documentId === "string" ? page.documentId : null;
|
||||
const alreadyRead = documentId && documentId === tab.spaDocumentId;
|
||||
if (state?.failedStatus || page?.status === "error" || alreadyRead) {
|
||||
if (restarts < 3 && (state?.failedStatus || documentId !== restartedDocument)) {
|
||||
const previousReloads = state?.reloads || 0;
|
||||
const restarted = await recoverConsumerTokenSessionTab(tab, debugEntry,
|
||||
state?.failedStatus ? "" : alreadyRead ? "Identity rejected in this SPA document" : "SPA document displays an authorization error");
|
||||
restarts += (state?.reloads || 0) - previousReloads;
|
||||
if (restarted) restartedDocument = documentId;
|
||||
}
|
||||
} else if (page?.status === "ready" && documentId) {
|
||||
// Confirm a stable, fully loaded document, not a transient SAML page.
|
||||
await wait(500);
|
||||
let confirmed;
|
||||
try { confirmed = await inspectPage(tab); } catch { /* A redirect started during validation. */ }
|
||||
if (confirmed?.status === "ready" && confirmed.documentId === documentId && !state?.failedStatus) {
|
||||
tab.spaDocumentId = documentId;
|
||||
if (debugEntry) {
|
||||
debugEntry.metadata.sessionWaitReason = "spa-document-verified";
|
||||
debugEntry.metadata.sessionWaitDurationMs = String(Date.now() - startedAt);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
await wait(1000);
|
||||
}
|
||||
const error = new Error("SPA page did not finish authentication. No further identity request was sent.");
|
||||
error.code = "SPA_PAGE_NOT_READY";
|
||||
throw error;
|
||||
}
|
||||
|
||||
async function waitForConsumerTokenSession(tab, debugEntry, retryDelay) {
|
||||
const state = sessionTabs.get(tab.id);
|
||||
if (!state || !responseHeaders?.addListener || !setTimeout) return wait(retryDelay);
|
||||
const startedAt = Date.now();
|
||||
const deadline = startedAt + 20000;
|
||||
if (debugEntry) {
|
||||
delete debugEntry.metadata.nextRetryDelayMs;
|
||||
debugEntry.metadata.sessionWaitTimeoutMs = "20000";
|
||||
}
|
||||
let restarts = 0;
|
||||
let reason = "timeout-fallback";
|
||||
// Do not issue API probes while SSO redirects are still establishing the session.
|
||||
while (!state.closed && Date.now() < deadline) {
|
||||
if (state.failedStatus) {
|
||||
if (restarts >= 3) {
|
||||
await wait(Math.max(0, deadline - Date.now()));
|
||||
break;
|
||||
}
|
||||
await recoverConsumerTokenSessionTab(tab, debugEntry);
|
||||
restarts++;
|
||||
if (state.failedStatus) await wait(2000);
|
||||
continue;
|
||||
}
|
||||
if (state.readyVersion > state.consumedVersion) {
|
||||
await wait(250);
|
||||
if (state.failedStatus) continue;
|
||||
state.consumedVersion = state.readyVersion;
|
||||
reason = state.readyReason;
|
||||
break;
|
||||
}
|
||||
let timer;
|
||||
try {
|
||||
await new Promise(resolve => {
|
||||
state.wake = resolve;
|
||||
timer = setTimeout(resolve, Math.max(0, deadline - Date.now()));
|
||||
});
|
||||
} finally {
|
||||
clearTimeout?.(timer);
|
||||
state.wake = null;
|
||||
}
|
||||
}
|
||||
if (debugEntry) {
|
||||
debugEntry.metadata.sessionWaitReason = reason;
|
||||
debugEntry.metadata.sessionWaitDurationMs = String(Date.now() - startedAt);
|
||||
}
|
||||
}
|
||||
|
||||
async function closeConsumerTokenSessionTab(id) {
|
||||
const state = sessionTabs.get(id);
|
||||
sessionTabs.delete(id);
|
||||
if (state) {
|
||||
state.closed = true;
|
||||
state.wake?.();
|
||||
responseHeaders?.removeListener?.(state.listener);
|
||||
cookieChanges?.removeListener(state.cookieListener);
|
||||
}
|
||||
await tabsRemove(id);
|
||||
}
|
||||
|
||||
return { requestConsumerTokenService, fetchConsumerTokenServiceUntilJson, getConsumerTokenRetryDelay, openConsumerTokenSessionTabWithRetry, openConsumerTokenSessionTab, recoverConsumerTokenSessionTab, waitForConsumerTokenSession, waitForSpaPage, closeConsumerTokenSessionTab };
|
||||
}
|
||||
|
||||
// Source: src/auth/spa-credentials.js
|
||||
@@ -1558,28 +1742,131 @@ function createFusionSrCreate({ fetchJson, tokenHeaders, previewTokenHeaders, in
|
||||
}
|
||||
|
||||
// Source: src/services/spa/current-user.js
|
||||
function createSpaCurrentUser({ fetchJson }) {
|
||||
async function requestCurrentUser() {
|
||||
function createSpaCurrentUser({ fetchJson, fetchInTab, openSessionTab, waitForSession, closeSessionTab, sessionUrl }) {
|
||||
const pending = new Map();
|
||||
function requestCurrentUser(sender) {
|
||||
const key = JSON.stringify([sender?.tab?.windowId ?? null, sender?.tab?.cookieStoreId ?? "", Boolean(sender?.tab?.incognito)]);
|
||||
if (!pending.has(key)) {
|
||||
pending.set(key, loadCurrentUser(sender).finally(() => pending.delete(key)));
|
||||
}
|
||||
return pending.get(key);
|
||||
}
|
||||
|
||||
async function loadCurrentUser(sender) {
|
||||
const debugRequests = [];
|
||||
let user = null;
|
||||
let sessionTab = null;
|
||||
let receivedValidJson = false;
|
||||
try {
|
||||
const result = await fetchJson("https://spa.oracle.com/oalcrm/web/api/identity-management/users/current", {
|
||||
method: "GET", credentials: "include", cache: "no-store", headers: { Accept: "application/json" }
|
||||
}, "requestCurrentUser", debugRequests);
|
||||
if (!result?.user || !Array.isArray(result.user.roles) || result.user.roles.some(role => typeof role !== "string")) {
|
||||
throw new Error("requestCurrentUser returned invalid user roles.");
|
||||
// Bound each bootstrap cycle so a failed sign-in never leaves an orphan tab.
|
||||
// The content-side gate can start another cycle without releasing dependent requests.
|
||||
for (let attempt = 1; attempt <= 6; attempt++) {
|
||||
try {
|
||||
const result = sessionTab ? await fetchInTab(sessionTab, debugRequests) : await fetchJson("https://spa.oracle.com/oalcrm/web/api/identity-management/users/current", {
|
||||
method: "GET", credentials: "include", cache: "no-store", headers: { Accept: "application/json" }
|
||||
}, "requestCurrentUser", debugRequests);
|
||||
const validText = value => typeof value === "string" && value.trim().length > 0;
|
||||
if (!result || typeof result !== "object" || Array.isArray(result)
|
||||
|| !result.user || typeof result.user !== "object" || Array.isArray(result.user)
|
||||
|| !validText(result.user.id) || !validText(result.user.name) || !validText(result.token)
|
||||
|| !Array.isArray(result.user.roles) || result.user.roles.some(role => !validText(role))
|
||||
|| ["onWhiteList", "provisioned", "administrator"].some(key => key in result.user && typeof result.user[key] !== "boolean")) {
|
||||
const error = new Error("requestCurrentUser returned an invalid user/token response.");
|
||||
error.code = "INVALID_CURRENT_USER_RESPONSE";
|
||||
throw error;
|
||||
}
|
||||
const entry = debugRequests[debugRequests.length - 1];
|
||||
if (entry) entry.metadata.attempt = String(attempt);
|
||||
receivedValidJson = true;
|
||||
const user = { id: result.user.id, name: result.user.name, roles: result.user.roles };
|
||||
return { ok: true, user, debugRequests };
|
||||
} catch (error) {
|
||||
const entry = debugRequests[debugRequests.length - 1];
|
||||
if (entry) {
|
||||
entry.status = "failed";
|
||||
entry.error = error.message;
|
||||
entry.metadata.attempt = String(attempt);
|
||||
}
|
||||
const needsSession = error.code === "INVALID_JSON_RESPONSE" || error.code === "INVALID_CURRENT_USER_RESPONSE"
|
||||
|| error.httpStatus === 401 || error.httpStatus === 403 || !error.httpStatus;
|
||||
if (!needsSession || attempt === 6) {
|
||||
if (entry && needsSession) entry.metadata.retryLimitReached = "true";
|
||||
throw error;
|
||||
}
|
||||
if (entry) {
|
||||
entry.metadata.sessionBootstrapUrl = sessionUrl;
|
||||
entry.metadata.retryReason = "Current user requires a valid SPA session";
|
||||
}
|
||||
if (!sessionTab) {
|
||||
try {
|
||||
const tab = await openSessionTab(sender);
|
||||
if (!Number.isInteger(tab?.id)) throw new Error("SPA session tab was not created.");
|
||||
sessionTab = tab;
|
||||
if (entry) entry.metadata.sessionBootstrapState = "opened-inactive-tab";
|
||||
} catch (sessionError) {
|
||||
if (entry) entry.metadata.sessionBootstrapState = `tab-open-failed: ${sessionError.message || "unknown error"}`;
|
||||
throw sessionError;
|
||||
}
|
||||
} else if (entry) {
|
||||
entry.metadata.sessionBootstrapState = "waiting-for-valid-session";
|
||||
}
|
||||
await waitForSession(sessionTab, entry);
|
||||
}
|
||||
}
|
||||
user = { id: result.user.id, name: result.user.name, roles: result.user.roles };
|
||||
return { ok: true, user, debugRequests };
|
||||
} catch (error) {
|
||||
for (const entry of debugRequests) { entry.status = "failed"; entry.error = error.message; }
|
||||
error.debugRequests = debugRequests;
|
||||
throw error;
|
||||
} finally {
|
||||
if (sessionTab) {
|
||||
const entry = debugRequests[debugRequests.length - 1];
|
||||
try {
|
||||
await closeSessionTab(sessionTab.id);
|
||||
if (entry) entry.metadata.sessionBootstrapState = receivedValidJson
|
||||
? "closed-after-valid-json" : "closed-after-retry-finished";
|
||||
} catch (error) {
|
||||
if (entry) entry.metadata.sessionBootstrapState = `tab-close-failed: ${error.message || "unknown error"}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return { requestCurrentUser };
|
||||
}
|
||||
|
||||
// Source: src/services/spa/page-client.js
|
||||
function createSpaPageClient({ sendMessage, getHttp }) {
|
||||
const options = { frameId: 0 };
|
||||
const inspect = tab => sendMessage(tab.id, { type: "opportunitiesExtension.inspectSpaPage" }, options);
|
||||
async function requestIdentity(tab, debugRequests) {
|
||||
const http = getHttp();
|
||||
const url = "https://spa.oracle.com/oalcrm/web/api/identity-management/users/current";
|
||||
const entry = http.createBackgroundDebugEntry("requestCurrentUser", url,
|
||||
{ method: "GET", headers: { Accept: "application/json" } }, new Date());
|
||||
entry.metadata.executionContext = "spa-tab";
|
||||
try {
|
||||
const result = await sendMessage(tab.id, { type: "opportunitiesExtension.readSpaIdentity", documentId: tab.spaDocumentId }, options);
|
||||
if (!result || result.error || !Number.isInteger(result.status) || typeof result.body !== "string") {
|
||||
throw new Error(result?.error || "Invalid SPA identity response.");
|
||||
}
|
||||
const response = { status: result.status, statusText: result.statusText || "", ok: result.status >= 200 && result.status < 300,
|
||||
headers: { forEach: callback => Object.entries(result.headers || { "content-type": result.contentType || "" }).forEach(([key, value]) => callback(value, key)) } };
|
||||
http.completeBackgroundDebugEntry(entry, response, http.createDebugBody(result.body), "");
|
||||
entry.metadata.responseContentType = result.contentType || "(not provided)";
|
||||
entry.metadata.responseLength = String(result.body.length);
|
||||
if (result.status !== 200) {
|
||||
const error = new Error(`requestCurrentUser failed with status ${result.status}.`);
|
||||
error.httpStatus = result.status;
|
||||
throw error;
|
||||
}
|
||||
return http.parseJsonResponse(result.body, "requestCurrentUser");
|
||||
} catch (error) {
|
||||
if (!entry.completedAt) http.completeBackgroundDebugEntry(entry, null, { value: "", truncated: false }, error.message);
|
||||
entry.status = "failed";
|
||||
entry.error = error.message;
|
||||
throw error;
|
||||
} finally { debugRequests.push(entry); }
|
||||
}
|
||||
return { inspect, requestIdentity };
|
||||
}
|
||||
|
||||
// Source: src/services/spa/consumption.js
|
||||
function createSpaConsumption({
|
||||
CONSUMPTION_TREND_REQUESTS,
|
||||
@@ -2471,6 +2758,19 @@ function createPlatformBackgroundApi({
|
||||
});
|
||||
}
|
||||
|
||||
function tabsUpdate(tabId, details) {
|
||||
if (runtimeApi.tabs.update.length <= 2) {
|
||||
return runtimeApi.tabs.update(tabId, details);
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
runtimeApi.tabs.update(tabId, details, tab => {
|
||||
const lastError = runtimeApi.runtime.lastError;
|
||||
if (lastError) reject(new Error(lastError.message));
|
||||
else resolve(tab);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function tabsRemove(tabId) {
|
||||
if (runtimeApi.tabs.remove.length <= 1) {
|
||||
return runtimeApi.tabs.remove(tabId);
|
||||
@@ -2628,7 +2928,7 @@ function createPlatformBackgroundApi({
|
||||
);
|
||||
}
|
||||
|
||||
return { supportsFirefoxCookieStoreTabs, tabsCreate, tabsRemove, tabsSendMessage, storageLocalGet, storageLocalSet, wait, cookiesGetAll, cookiesGet, cookiesGetAllCookieStores, removeUndefinedValues };
|
||||
return { supportsFirefoxCookieStoreTabs, tabsCreate, tabsUpdate, tabsRemove, tabsSendMessage, storageLocalGet, storageLocalSet, wait, cookiesGetAll, cookiesGet, cookiesGetAllCookieStores, removeUndefinedValues };
|
||||
}
|
||||
|
||||
// Source: src/background/main.js
|
||||
@@ -2809,7 +3109,7 @@ runtimeApi.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||
}
|
||||
|
||||
if (message.type === messageTypes.requestCurrentUser) {
|
||||
requestCurrentUser().then(sendResponse).catch(error => sendResponse({
|
||||
requestCurrentUser(sender).then(sendResponse).catch(error => sendResponse({
|
||||
ok: false, error: error.message || "Unable to load current user.",
|
||||
debugRequests: Array.isArray(error.debugRequests) ? error.debugRequests : []
|
||||
}));
|
||||
@@ -2913,13 +3213,25 @@ function createBackgroundApplication(overrides = {}) {
|
||||
browser: globalThis.browser,
|
||||
chrome: globalThis.chrome,
|
||||
setTimeout: globalThis.setTimeout,
|
||||
clearTimeout: globalThis.clearTimeout,
|
||||
...overrides
|
||||
};
|
||||
const messageTypes = createMessageTypes();
|
||||
const timeEntries = createTimeEntries({ dates: createTimeDates(), fetchJson: (...args) => httpBackgroundJson.fetchJson(...args), getResourceUser: message => fusionSrCreate.getResourceUser(message), saveHeaders: url => srRequestHeaders.timeEntriesHeaders(url) });
|
||||
const spaCurrentUser = createSpaCurrentUser({ fetchJson: (...args) => httpBackgroundJson.fetchJson(...args) });
|
||||
const requestCurrentUser = () => spaCurrentUser.requestCurrentUser();
|
||||
const contracts = createBackgroundContracts();
|
||||
const spaPageClient = createSpaPageClient({
|
||||
sendMessage: (...args) => platformBackgroundApi.tabsSendMessage(...args),
|
||||
getHttp: () => httpBackgroundJson
|
||||
});
|
||||
const spaCurrentUser = createSpaCurrentUser({
|
||||
fetchJson: (...args) => httpBackgroundJson.fetchJson(...args),
|
||||
fetchInTab: (tab, logs) => spaPageClient.requestIdentity(tab, logs),
|
||||
openSessionTab: sender => authConsumerSession.openConsumerTokenSessionTab(sender),
|
||||
waitForSession: (tab, entry) => authConsumerSession.waitForSpaPage(tab, entry),
|
||||
closeSessionTab: id => authConsumerSession.closeConsumerTokenSessionTab(id),
|
||||
sessionUrl: contracts.CUSTOMER_TOKEN_SESSION_URL
|
||||
});
|
||||
const requestCurrentUser = sender => spaCurrentUser.requestCurrentUser(sender);
|
||||
const productsCacheState = createProductsCacheState();
|
||||
const authConsumerSession = createAuthConsumerSession({
|
||||
CUSTOMER_TOKEN_MAX_ATTEMPTS: contracts.CUSTOMER_TOKEN_MAX_ATTEMPTS,
|
||||
@@ -2931,7 +3243,13 @@ function createBackgroundApplication(overrides = {}) {
|
||||
fetchJson: (...args) => httpBackgroundJson.fetchJson(...args),
|
||||
supportsFirefoxCookieStoreTabs: (...args) => platformBackgroundApi.supportsFirefoxCookieStoreTabs(...args),
|
||||
tabsCreate: (...args) => platformBackgroundApi.tabsCreate(...args),
|
||||
tabsUpdate: (...args) => platformBackgroundApi.tabsUpdate(...args),
|
||||
tabsRemove: (...args) => platformBackgroundApi.tabsRemove(...args),
|
||||
responseHeaders: (environment.browser || environment.chrome)?.webRequest?.onHeadersReceived,
|
||||
cookieChanges: (environment.browser || environment.chrome)?.cookies?.onChanged,
|
||||
inspectPage: tab => spaPageClient.inspect(tab),
|
||||
setTimeout: environment.setTimeout,
|
||||
clearTimeout: environment.clearTimeout,
|
||||
wait: (...args) => platformBackgroundApi.wait(...args)
|
||||
});
|
||||
const authSpaCredentials = createAuthSpaCredentials({
|
||||
|
||||
Reference in New Issue
Block a user