Loading comcipapic to establish a session for SR requests
This commit is contained in:
210
dist/chromium/background.js
vendored
210
dist/chromium/background.js
vendored
@@ -18,6 +18,11 @@ function createMessageTypes() {
|
||||
requestActionFindLookup: "opportunitiesExtension.requestActionFindLookup",
|
||||
requestMgmtAction: "opportunitiesExtension.requestMgmtAction",
|
||||
requestInternalServiceRequest: "opportunitiesExtension.requestInternalServiceRequest",
|
||||
requestSrLookupPrimaryPillar: "opportunitiesExtension.requestSrLookupPrimaryPillar",
|
||||
prepareSrSession: "opportunitiesExtension.prepareSrSession",
|
||||
requestSrLookupLanguage: "opportunitiesExtension.requestSrLookupLanguage",
|
||||
requestSrLookupTechPlatform: "opportunitiesExtension.requestSrLookupTechPlatform",
|
||||
requestSrLookupOpportunityBusiness: "opportunitiesExtension.requestSrLookupOpportunityBusiness",
|
||||
requestCurrentUser: "opportunitiesExtension.requestCurrentUser",
|
||||
invalidateProductsCache: "opportunitiesExtension.invalidateProductsCache",
|
||||
requestConsumptionTrend: "opportunitiesExtension.requestConsumptionTrend",
|
||||
@@ -743,7 +748,149 @@ function createSpaActionOptions({ fetchJson }) {
|
||||
}
|
||||
|
||||
// Source: src/services/fusion/sr-details.js
|
||||
function createFusionSrDetails({ fetchJson }) {
|
||||
function createFusionSrDetails({ fetchJson, tabsCreate, tabsRemove, supportsFirefoxCookieStoreTabs, cookiesGetAll, cookieChanges, wait }) {
|
||||
const sessions = new Map();
|
||||
function cookiePart(cookie) {
|
||||
if (!cookie) return null;
|
||||
const match = /^ORA_OCIS_CG_SESSION_idcs-([a-zA-Z0-9-]+)_comcipapic-oalprod\.integration\.ocp\.oraclecloud\.com_([12])$/.exec(cookie.name);
|
||||
const domain = "comcipapic-oalprod.integration.ocp.oraclecloud.com";
|
||||
const cookieDomain = cookie.domain?.replace(/^\./, "");
|
||||
if (!match || (cookieDomain && cookieDomain !== domain && !domain.endsWith(`.${cookieDomain}`))) return null;
|
||||
return { key: `${match[1]}|${cookie.path || "/"}|${cookie.storeId || ""}`, part: match[2],
|
||||
valid: Boolean(cookie.value) && (cookie.expirationDate == null || cookie.expirationDate > Date.now() / 1000) };
|
||||
}
|
||||
function watchSession(session, sender) {
|
||||
const pairs = new Map();
|
||||
let available;
|
||||
session.cookieReady = new Promise(resolve => { available = resolve; });
|
||||
const listener = change => {
|
||||
const cookie = change.cookie;
|
||||
const part = cookiePart(cookie);
|
||||
if (!part) return;
|
||||
if (sender?.tab?.cookieStoreId && cookie.storeId !== sender.tab.cookieStoreId) return;
|
||||
if (!pairs.has(part.key)) pairs.set(part.key, new Map());
|
||||
const pair = pairs.get(part.key);
|
||||
if (change.removed || !part.valid) pair.delete(part.part);
|
||||
else pair.set(part.part, cookie);
|
||||
if (pair.size === 2 && [...pair.values()].every(item => cookiePart(item)?.valid)) available(new Set([part.key]));
|
||||
session.wake?.();
|
||||
};
|
||||
cookieChanges?.addListener(listener);
|
||||
session.unwatch = () => cookieChanges?.removeListener(listener);
|
||||
}
|
||||
function waitForSessionCookies(session, sender) {
|
||||
if (session.cookieWait) return session.cookieWait;
|
||||
session.cookieWait = (async () => {
|
||||
const deadline = Date.now() + 1000;
|
||||
for (let attempt = 0; attempt < 5; attempt += 1) {
|
||||
// Install the wake-up before reading so a renewal during getAll is not missed.
|
||||
const changed = new Promise(resolve => { session.wake = resolve; });
|
||||
const current = await sessionCookies(sender);
|
||||
const renewed = [...current].some(pair => !session.baseline.has(pair));
|
||||
if (renewed || Date.now() >= deadline) {
|
||||
session.baseline = current;
|
||||
return current;
|
||||
}
|
||||
await Promise.race([changed, wait(250)]);
|
||||
}
|
||||
return sessionCookies(sender);
|
||||
})().finally(() => { session.cookieWait = null; session.wake = null; });
|
||||
return session.cookieWait;
|
||||
}
|
||||
async function sessionCookies(sender) {
|
||||
const domain = "comcipapic-oalprod.integration.ocp.oraclecloud.com";
|
||||
const details = { domain };
|
||||
if (sender?.tab?.cookieStoreId) details.storeId = sender.tab.cookieStoreId;
|
||||
try {
|
||||
const groups = new Map();
|
||||
for (const cookie of await cookiesGetAll(details)) {
|
||||
const part = cookiePart(cookie);
|
||||
if (!part?.valid) continue;
|
||||
if (!groups.has(part.key)) groups.set(part.key, {});
|
||||
groups.get(part.key)[part.part] = [cookie.name, cookie.value, cookie.expirationDate ?? null];
|
||||
}
|
||||
// Fingerprints remain in memory only; the browser sends the actual Cookie header.
|
||||
return new Set([...groups.values()].filter(pair => pair[1] && pair[2]).map(pair => JSON.stringify([pair[1], pair[2]])));
|
||||
} catch { return new Set(); }
|
||||
}
|
||||
async function requestLookupWithSession(operation, message, sender, initialize = false) {
|
||||
const existingCookies = initialize ? await sessionCookies(sender) : null;
|
||||
if (existingCookies?.size) return { ok: true, debugRequests: [] };
|
||||
const logs = [];
|
||||
const query = async () => {
|
||||
try {
|
||||
const result = await operation(message);
|
||||
logs.push(...(result.debugRequests || []));
|
||||
return { ...result, debugRequests: logs };
|
||||
} catch (error) {
|
||||
logs.push(...(error.debugRequests || []));
|
||||
error.debugRequests = logs;
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
if (!initialize) {
|
||||
try { return await query(); } catch (error) { if (error.httpStatus !== 401) throw error; }
|
||||
}
|
||||
const key = sender?.tab?.cookieStoreId || "default";
|
||||
let session = sessions.get(key);
|
||||
if (!session) {
|
||||
const details = {
|
||||
url: "https://comcipapic-oalprod.integration.ocp.oraclecloud.com/ic/builder/rt/SeaaS_initiation/live/webApps/external/",
|
||||
active: false
|
||||
};
|
||||
if (Number.isInteger(sender?.tab?.windowId)) details.windowId = sender.tab.windowId;
|
||||
if (supportsFirefoxCookieStoreTabs() && sender?.tab?.cookieStoreId) details.cookieStoreId = sender.tab.cookieStoreId;
|
||||
session = { users: 0, closed: null, baseline: null };
|
||||
watchSession(session, sender);
|
||||
session.tab = (async () => {
|
||||
session.baseline = existingCookies || await sessionCookies(sender);
|
||||
return tabsCreate(details);
|
||||
})();
|
||||
sessions.set(key, session);
|
||||
}
|
||||
session.users += 1;
|
||||
let tab;
|
||||
try {
|
||||
tab = await session.tab;
|
||||
const deadline = Date.now() + 60000;
|
||||
for (let attempt = 0; attempt < 240 && Date.now() < deadline; attempt += 1) {
|
||||
const pendingCookies = initialize && attempt === 0
|
||||
? sessionCookies(sender) : waitForSessionCookies(session, sender);
|
||||
const cookies = await (initialize ? Promise.race([session.cookieReady, pendingCookies]) : pendingCookies);
|
||||
if (initialize) {
|
||||
// Proactive preparation observes cookies only; API requests belong to the form.
|
||||
if (!cookies.size) continue;
|
||||
await closeSessionTab();
|
||||
return { ok: true, debugRequests: [] };
|
||||
}
|
||||
try {
|
||||
const result = await query();
|
||||
// Any successful lookup confirms the shared session; stop the page immediately.
|
||||
await closeSessionTab();
|
||||
return result;
|
||||
} catch (error) {
|
||||
if (error.httpStatus !== 401) throw error;
|
||||
}
|
||||
}
|
||||
throw new Error("Service Request session could not be established after 60 seconds. Sign in to Oracle and retry.");
|
||||
} catch (error) {
|
||||
error.debugRequests = logs;
|
||||
throw error;
|
||||
} finally {
|
||||
session.users -= 1;
|
||||
if (session.users === 0) {
|
||||
sessions.delete(key);
|
||||
session.unwatch();
|
||||
await closeSessionTab();
|
||||
}
|
||||
}
|
||||
function closeSessionTab() {
|
||||
if (!session.closed && Number.isInteger(tab?.id)) {
|
||||
session.closed = tabsRemove(tab.id).catch(() => {});
|
||||
}
|
||||
return session.closed;
|
||||
}
|
||||
}
|
||||
async function requestInternalServiceRequest(message) {
|
||||
const debugRequests = [];
|
||||
try {
|
||||
@@ -772,7 +919,36 @@ function createFusionSrDetails({ fetchJson }) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return { requestInternalServiceRequest };
|
||||
async function requestLookup(lookupType, requestName) {
|
||||
const debugRequests = [];
|
||||
try {
|
||||
const url = `https://comcipapic-oalprod.integration.ocp.oraclecloud.com/ic/builder/rt/SeaaS_initiation/live;profile=PROD/services/auth/1.1/proxy/oke_seaas/uri/https/gxpap.oracle.com/oalcrm/service/set/seaas/crm/lookups?lookupType=${lookupType}&type=STANDARD`;
|
||||
const result = await fetchJson(url, { method: "GET", credentials: "include",
|
||||
headers: { Accept: "application/json", Authorization: "Session" }
|
||||
}, requestName, debugRequests);
|
||||
if (!Array.isArray(result?.items) || result.items.some(item => typeof item?.code !== "string" || typeof item?.name !== "string")) throw new Error(`Invalid ${requestName} response.`);
|
||||
const items = result.items.filter(item => item.enabledFlag !== "N")
|
||||
.sort((a, b) => (Number(a.displaySequence) || 0) - (Number(b.displaySequence) || 0))
|
||||
.map(({ code, name }) => ({ code, name }));
|
||||
return { ok: true, items, debugRequests };
|
||||
} catch (error) { error.debugRequests = debugRequests; throw error; }
|
||||
}
|
||||
async function requestSrLookupOpportunityBusiness(message) {
|
||||
const debugRequests = [];
|
||||
try {
|
||||
if (typeof message.emailAddress !== "string" || !message.emailAddress.trim()) throw new Error("Current user email is unavailable.");
|
||||
const url = "https://comcipapic-oalprod.integration.ocp.oraclecloud.com/ic/builder/rt/SeaaS_initiation/live;profile=PROD/services/auth/1.1/proxy/oke_seaas/uri/https/gxpap.oracle.com/oalcrm/service/set/seaas/crm/services"
|
||||
+ `?emailAddress=${encodeURIComponent(message.emailAddress.trim())}&salesObject=OPPORTUNITY&serviceType=BUSINESS`;
|
||||
const result = await fetchJson(url, { method: "GET", credentials: "include", headers: { Accept: "application/json", Authorization: "Session" } }, "requestSrLookupOpportunityBusiness", debugRequests);
|
||||
if (!Array.isArray(result?.items) || result.items.some(item => !/^\d+$/.test(String(item?.Id ?? "")) || typeof item?.RecordName !== "string")) throw new Error("Invalid Services response.");
|
||||
return { ok: true, items: result.items.map(({ Id, RecordName, Abstract_c }) => ({ Id: String(Id), RecordName, Abstract_c: Abstract_c == null ? "" : String(Abstract_c) })), debugRequests };
|
||||
} catch (error) { error.debugRequests = debugRequests; throw error; }
|
||||
}
|
||||
return { requestLookupWithSession, requestInternalServiceRequest, requestSrLookupOpportunityBusiness,
|
||||
prepareSession: sender => requestLookupWithSession(null, {}, sender, true),
|
||||
requestSrLookupPrimaryPillar: () => requestLookup("SENGG_PRIMARY_PILLAR", "requestSrLookupPrimaryPillar"),
|
||||
requestSrLookupLanguage: () => requestLookup("SENGG_LANGUAGE", "requestSrLookupLanguage"),
|
||||
requestSrLookupTechPlatform: () => requestLookup("SENGG_TECH_PLATFORM", "requestSrLookupTechPlatform") };
|
||||
}
|
||||
|
||||
// Source: src/services/spa/current-user.js
|
||||
@@ -1874,6 +2050,12 @@ function registerBackgroundMessages({
|
||||
requestActionFindLookup,
|
||||
requestMgmtAction,
|
||||
requestInternalServiceRequest,
|
||||
requestSrLookupPrimaryPillar,
|
||||
requestSrLookupWithSession,
|
||||
prepareSrSession,
|
||||
requestSrLookupLanguage,
|
||||
requestSrLookupTechPlatform,
|
||||
requestSrLookupOpportunityBusiness,
|
||||
requestCurrentUser,
|
||||
requestConsumerTokenService,
|
||||
requestConsumptionTrend,
|
||||
@@ -1886,6 +2068,22 @@ runtimeApi.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||
if (!message || !message.type) {
|
||||
return false;
|
||||
}
|
||||
if (message.type === messageTypes.prepareSrSession) {
|
||||
prepareSrSession(sender).then(sendResponse).catch(error => sendResponse({ ok: false,
|
||||
error: error.message, debugRequests: error.debugRequests || [] }));
|
||||
return true;
|
||||
}
|
||||
const srLookups = {
|
||||
[messageTypes.requestSrLookupPrimaryPillar]: requestSrLookupPrimaryPillar,
|
||||
[messageTypes.requestSrLookupLanguage]: requestSrLookupLanguage,
|
||||
[messageTypes.requestSrLookupTechPlatform]: requestSrLookupTechPlatform,
|
||||
[messageTypes.requestSrLookupOpportunityBusiness]: requestSrLookupOpportunityBusiness
|
||||
};
|
||||
if (Object.hasOwn(srLookups, message.type)) {
|
||||
requestSrLookupWithSession(srLookups[message.type], message, sender).then(sendResponse).catch(error => sendResponse({ ok: false,
|
||||
httpStatus: error.httpStatus, error: error.message, debugRequests: error.debugRequests || [] }));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (message.type === messageTypes.invalidateProductsCache) {
|
||||
invalidateProductsCache().then(() => sendResponse({ ok: true })).catch(error => sendResponse({ ok: false, error: error.message || "Unable to clear products cache." }));
|
||||
@@ -2178,10 +2376,16 @@ function createBackgroundApplication(overrides = {}) {
|
||||
const requestOpptyProducts = (...args) => productsBackgroundJobs.requestOpptyProducts(...args);
|
||||
const runtimeApi = environment.browser || environment.chrome;
|
||||
const fusionSrDetails = createFusionSrDetails({
|
||||
cookieChanges: runtimeApi?.cookies?.onChanged,
|
||||
cookiesGetAll: (...args) => platformBackgroundApi.cookiesGetAll(...args),
|
||||
tabsCreate: (...args) => platformBackgroundApi.tabsCreate(...args),
|
||||
tabsRemove: (...args) => platformBackgroundApi.tabsRemove(...args),
|
||||
supportsFirefoxCookieStoreTabs: () => platformBackgroundApi.supportsFirefoxCookieStoreTabs(),
|
||||
wait: (...args) => platformBackgroundApi.wait(...args),
|
||||
fetchJson: (...args) => httpBackgroundJson.fetchJson(...args)
|
||||
});
|
||||
function start() {
|
||||
startBackgroundApplication({ messageTypes, requestInternalServiceRequest: (message, sender) => fusionSrDetails.requestInternalServiceRequest(message, sender), requestMgmtAction: message => spaActionOptions.requestMgmtAction(message), invalidateProductsCache: () => productsCache.invalidate(), requestCurrentUser, getXsrfTokenCookie, refreshXsrfCookie, requestAccountPlans, requestInstallBase, requestCustomerServiceRequest, requestWlActions, requestActionTeamMembers, requestActionFindLookup, requestConsumerTokenService, requestConsumptionTrend, requestConsumptionPlanDetail, requestRatecardByPlan, requestOpptyProducts, runtimeApi });
|
||||
startBackgroundApplication({ prepareSrSession: sender => fusionSrDetails.prepareSession(sender), requestSrLookupWithSession: (...args) => fusionSrDetails.requestLookupWithSession(...args), messageTypes, requestSrLookupLanguage: () => fusionSrDetails.requestSrLookupLanguage(), requestSrLookupTechPlatform: () => fusionSrDetails.requestSrLookupTechPlatform(), requestSrLookupOpportunityBusiness: message => fusionSrDetails.requestSrLookupOpportunityBusiness(message), requestSrLookupPrimaryPillar: () => fusionSrDetails.requestSrLookupPrimaryPillar(), requestInternalServiceRequest: (message, sender) => fusionSrDetails.requestInternalServiceRequest(message, sender), requestMgmtAction: message => spaActionOptions.requestMgmtAction(message), invalidateProductsCache: () => productsCache.invalidate(), requestCurrentUser, getXsrfTokenCookie, refreshXsrfCookie, requestAccountPlans, requestInstallBase, requestCustomerServiceRequest, requestWlActions, requestActionTeamMembers, requestActionFindLookup, requestConsumerTokenService, requestConsumptionTrend, requestConsumptionPlanDetail, requestRatecardByPlan, requestOpptyProducts, runtimeApi });
|
||||
}
|
||||
return {
|
||||
start, contracts,
|
||||
|
||||
562
dist/chromium/content.js
vendored
562
dist/chromium/content.js
vendored
File diff suppressed because one or more lines are too long
210
dist/firefox/background.js
vendored
210
dist/firefox/background.js
vendored
@@ -18,6 +18,11 @@ function createMessageTypes() {
|
||||
requestActionFindLookup: "opportunitiesExtension.requestActionFindLookup",
|
||||
requestMgmtAction: "opportunitiesExtension.requestMgmtAction",
|
||||
requestInternalServiceRequest: "opportunitiesExtension.requestInternalServiceRequest",
|
||||
requestSrLookupPrimaryPillar: "opportunitiesExtension.requestSrLookupPrimaryPillar",
|
||||
prepareSrSession: "opportunitiesExtension.prepareSrSession",
|
||||
requestSrLookupLanguage: "opportunitiesExtension.requestSrLookupLanguage",
|
||||
requestSrLookupTechPlatform: "opportunitiesExtension.requestSrLookupTechPlatform",
|
||||
requestSrLookupOpportunityBusiness: "opportunitiesExtension.requestSrLookupOpportunityBusiness",
|
||||
requestCurrentUser: "opportunitiesExtension.requestCurrentUser",
|
||||
invalidateProductsCache: "opportunitiesExtension.invalidateProductsCache",
|
||||
requestConsumptionTrend: "opportunitiesExtension.requestConsumptionTrend",
|
||||
@@ -743,7 +748,149 @@ function createSpaActionOptions({ fetchJson }) {
|
||||
}
|
||||
|
||||
// Source: src/services/fusion/sr-details.js
|
||||
function createFusionSrDetails({ fetchJson }) {
|
||||
function createFusionSrDetails({ fetchJson, tabsCreate, tabsRemove, supportsFirefoxCookieStoreTabs, cookiesGetAll, cookieChanges, wait }) {
|
||||
const sessions = new Map();
|
||||
function cookiePart(cookie) {
|
||||
if (!cookie) return null;
|
||||
const match = /^ORA_OCIS_CG_SESSION_idcs-([a-zA-Z0-9-]+)_comcipapic-oalprod\.integration\.ocp\.oraclecloud\.com_([12])$/.exec(cookie.name);
|
||||
const domain = "comcipapic-oalprod.integration.ocp.oraclecloud.com";
|
||||
const cookieDomain = cookie.domain?.replace(/^\./, "");
|
||||
if (!match || (cookieDomain && cookieDomain !== domain && !domain.endsWith(`.${cookieDomain}`))) return null;
|
||||
return { key: `${match[1]}|${cookie.path || "/"}|${cookie.storeId || ""}`, part: match[2],
|
||||
valid: Boolean(cookie.value) && (cookie.expirationDate == null || cookie.expirationDate > Date.now() / 1000) };
|
||||
}
|
||||
function watchSession(session, sender) {
|
||||
const pairs = new Map();
|
||||
let available;
|
||||
session.cookieReady = new Promise(resolve => { available = resolve; });
|
||||
const listener = change => {
|
||||
const cookie = change.cookie;
|
||||
const part = cookiePart(cookie);
|
||||
if (!part) return;
|
||||
if (sender?.tab?.cookieStoreId && cookie.storeId !== sender.tab.cookieStoreId) return;
|
||||
if (!pairs.has(part.key)) pairs.set(part.key, new Map());
|
||||
const pair = pairs.get(part.key);
|
||||
if (change.removed || !part.valid) pair.delete(part.part);
|
||||
else pair.set(part.part, cookie);
|
||||
if (pair.size === 2 && [...pair.values()].every(item => cookiePart(item)?.valid)) available(new Set([part.key]));
|
||||
session.wake?.();
|
||||
};
|
||||
cookieChanges?.addListener(listener);
|
||||
session.unwatch = () => cookieChanges?.removeListener(listener);
|
||||
}
|
||||
function waitForSessionCookies(session, sender) {
|
||||
if (session.cookieWait) return session.cookieWait;
|
||||
session.cookieWait = (async () => {
|
||||
const deadline = Date.now() + 1000;
|
||||
for (let attempt = 0; attempt < 5; attempt += 1) {
|
||||
// Install the wake-up before reading so a renewal during getAll is not missed.
|
||||
const changed = new Promise(resolve => { session.wake = resolve; });
|
||||
const current = await sessionCookies(sender);
|
||||
const renewed = [...current].some(pair => !session.baseline.has(pair));
|
||||
if (renewed || Date.now() >= deadline) {
|
||||
session.baseline = current;
|
||||
return current;
|
||||
}
|
||||
await Promise.race([changed, wait(250)]);
|
||||
}
|
||||
return sessionCookies(sender);
|
||||
})().finally(() => { session.cookieWait = null; session.wake = null; });
|
||||
return session.cookieWait;
|
||||
}
|
||||
async function sessionCookies(sender) {
|
||||
const domain = "comcipapic-oalprod.integration.ocp.oraclecloud.com";
|
||||
const details = { domain };
|
||||
if (sender?.tab?.cookieStoreId) details.storeId = sender.tab.cookieStoreId;
|
||||
try {
|
||||
const groups = new Map();
|
||||
for (const cookie of await cookiesGetAll(details)) {
|
||||
const part = cookiePart(cookie);
|
||||
if (!part?.valid) continue;
|
||||
if (!groups.has(part.key)) groups.set(part.key, {});
|
||||
groups.get(part.key)[part.part] = [cookie.name, cookie.value, cookie.expirationDate ?? null];
|
||||
}
|
||||
// Fingerprints remain in memory only; the browser sends the actual Cookie header.
|
||||
return new Set([...groups.values()].filter(pair => pair[1] && pair[2]).map(pair => JSON.stringify([pair[1], pair[2]])));
|
||||
} catch { return new Set(); }
|
||||
}
|
||||
async function requestLookupWithSession(operation, message, sender, initialize = false) {
|
||||
const existingCookies = initialize ? await sessionCookies(sender) : null;
|
||||
if (existingCookies?.size) return { ok: true, debugRequests: [] };
|
||||
const logs = [];
|
||||
const query = async () => {
|
||||
try {
|
||||
const result = await operation(message);
|
||||
logs.push(...(result.debugRequests || []));
|
||||
return { ...result, debugRequests: logs };
|
||||
} catch (error) {
|
||||
logs.push(...(error.debugRequests || []));
|
||||
error.debugRequests = logs;
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
if (!initialize) {
|
||||
try { return await query(); } catch (error) { if (error.httpStatus !== 401) throw error; }
|
||||
}
|
||||
const key = sender?.tab?.cookieStoreId || "default";
|
||||
let session = sessions.get(key);
|
||||
if (!session) {
|
||||
const details = {
|
||||
url: "https://comcipapic-oalprod.integration.ocp.oraclecloud.com/ic/builder/rt/SeaaS_initiation/live/webApps/external/",
|
||||
active: false
|
||||
};
|
||||
if (Number.isInteger(sender?.tab?.windowId)) details.windowId = sender.tab.windowId;
|
||||
if (supportsFirefoxCookieStoreTabs() && sender?.tab?.cookieStoreId) details.cookieStoreId = sender.tab.cookieStoreId;
|
||||
session = { users: 0, closed: null, baseline: null };
|
||||
watchSession(session, sender);
|
||||
session.tab = (async () => {
|
||||
session.baseline = existingCookies || await sessionCookies(sender);
|
||||
return tabsCreate(details);
|
||||
})();
|
||||
sessions.set(key, session);
|
||||
}
|
||||
session.users += 1;
|
||||
let tab;
|
||||
try {
|
||||
tab = await session.tab;
|
||||
const deadline = Date.now() + 60000;
|
||||
for (let attempt = 0; attempt < 240 && Date.now() < deadline; attempt += 1) {
|
||||
const pendingCookies = initialize && attempt === 0
|
||||
? sessionCookies(sender) : waitForSessionCookies(session, sender);
|
||||
const cookies = await (initialize ? Promise.race([session.cookieReady, pendingCookies]) : pendingCookies);
|
||||
if (initialize) {
|
||||
// Proactive preparation observes cookies only; API requests belong to the form.
|
||||
if (!cookies.size) continue;
|
||||
await closeSessionTab();
|
||||
return { ok: true, debugRequests: [] };
|
||||
}
|
||||
try {
|
||||
const result = await query();
|
||||
// Any successful lookup confirms the shared session; stop the page immediately.
|
||||
await closeSessionTab();
|
||||
return result;
|
||||
} catch (error) {
|
||||
if (error.httpStatus !== 401) throw error;
|
||||
}
|
||||
}
|
||||
throw new Error("Service Request session could not be established after 60 seconds. Sign in to Oracle and retry.");
|
||||
} catch (error) {
|
||||
error.debugRequests = logs;
|
||||
throw error;
|
||||
} finally {
|
||||
session.users -= 1;
|
||||
if (session.users === 0) {
|
||||
sessions.delete(key);
|
||||
session.unwatch();
|
||||
await closeSessionTab();
|
||||
}
|
||||
}
|
||||
function closeSessionTab() {
|
||||
if (!session.closed && Number.isInteger(tab?.id)) {
|
||||
session.closed = tabsRemove(tab.id).catch(() => {});
|
||||
}
|
||||
return session.closed;
|
||||
}
|
||||
}
|
||||
async function requestInternalServiceRequest(message) {
|
||||
const debugRequests = [];
|
||||
try {
|
||||
@@ -772,7 +919,36 @@ function createFusionSrDetails({ fetchJson }) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return { requestInternalServiceRequest };
|
||||
async function requestLookup(lookupType, requestName) {
|
||||
const debugRequests = [];
|
||||
try {
|
||||
const url = `https://comcipapic-oalprod.integration.ocp.oraclecloud.com/ic/builder/rt/SeaaS_initiation/live;profile=PROD/services/auth/1.1/proxy/oke_seaas/uri/https/gxpap.oracle.com/oalcrm/service/set/seaas/crm/lookups?lookupType=${lookupType}&type=STANDARD`;
|
||||
const result = await fetchJson(url, { method: "GET", credentials: "include",
|
||||
headers: { Accept: "application/json", Authorization: "Session" }
|
||||
}, requestName, debugRequests);
|
||||
if (!Array.isArray(result?.items) || result.items.some(item => typeof item?.code !== "string" || typeof item?.name !== "string")) throw new Error(`Invalid ${requestName} response.`);
|
||||
const items = result.items.filter(item => item.enabledFlag !== "N")
|
||||
.sort((a, b) => (Number(a.displaySequence) || 0) - (Number(b.displaySequence) || 0))
|
||||
.map(({ code, name }) => ({ code, name }));
|
||||
return { ok: true, items, debugRequests };
|
||||
} catch (error) { error.debugRequests = debugRequests; throw error; }
|
||||
}
|
||||
async function requestSrLookupOpportunityBusiness(message) {
|
||||
const debugRequests = [];
|
||||
try {
|
||||
if (typeof message.emailAddress !== "string" || !message.emailAddress.trim()) throw new Error("Current user email is unavailable.");
|
||||
const url = "https://comcipapic-oalprod.integration.ocp.oraclecloud.com/ic/builder/rt/SeaaS_initiation/live;profile=PROD/services/auth/1.1/proxy/oke_seaas/uri/https/gxpap.oracle.com/oalcrm/service/set/seaas/crm/services"
|
||||
+ `?emailAddress=${encodeURIComponent(message.emailAddress.trim())}&salesObject=OPPORTUNITY&serviceType=BUSINESS`;
|
||||
const result = await fetchJson(url, { method: "GET", credentials: "include", headers: { Accept: "application/json", Authorization: "Session" } }, "requestSrLookupOpportunityBusiness", debugRequests);
|
||||
if (!Array.isArray(result?.items) || result.items.some(item => !/^\d+$/.test(String(item?.Id ?? "")) || typeof item?.RecordName !== "string")) throw new Error("Invalid Services response.");
|
||||
return { ok: true, items: result.items.map(({ Id, RecordName, Abstract_c }) => ({ Id: String(Id), RecordName, Abstract_c: Abstract_c == null ? "" : String(Abstract_c) })), debugRequests };
|
||||
} catch (error) { error.debugRequests = debugRequests; throw error; }
|
||||
}
|
||||
return { requestLookupWithSession, requestInternalServiceRequest, requestSrLookupOpportunityBusiness,
|
||||
prepareSession: sender => requestLookupWithSession(null, {}, sender, true),
|
||||
requestSrLookupPrimaryPillar: () => requestLookup("SENGG_PRIMARY_PILLAR", "requestSrLookupPrimaryPillar"),
|
||||
requestSrLookupLanguage: () => requestLookup("SENGG_LANGUAGE", "requestSrLookupLanguage"),
|
||||
requestSrLookupTechPlatform: () => requestLookup("SENGG_TECH_PLATFORM", "requestSrLookupTechPlatform") };
|
||||
}
|
||||
|
||||
// Source: src/services/spa/current-user.js
|
||||
@@ -1874,6 +2050,12 @@ function registerBackgroundMessages({
|
||||
requestActionFindLookup,
|
||||
requestMgmtAction,
|
||||
requestInternalServiceRequest,
|
||||
requestSrLookupPrimaryPillar,
|
||||
requestSrLookupWithSession,
|
||||
prepareSrSession,
|
||||
requestSrLookupLanguage,
|
||||
requestSrLookupTechPlatform,
|
||||
requestSrLookupOpportunityBusiness,
|
||||
requestCurrentUser,
|
||||
requestConsumerTokenService,
|
||||
requestConsumptionTrend,
|
||||
@@ -1886,6 +2068,22 @@ runtimeApi.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||
if (!message || !message.type) {
|
||||
return false;
|
||||
}
|
||||
if (message.type === messageTypes.prepareSrSession) {
|
||||
prepareSrSession(sender).then(sendResponse).catch(error => sendResponse({ ok: false,
|
||||
error: error.message, debugRequests: error.debugRequests || [] }));
|
||||
return true;
|
||||
}
|
||||
const srLookups = {
|
||||
[messageTypes.requestSrLookupPrimaryPillar]: requestSrLookupPrimaryPillar,
|
||||
[messageTypes.requestSrLookupLanguage]: requestSrLookupLanguage,
|
||||
[messageTypes.requestSrLookupTechPlatform]: requestSrLookupTechPlatform,
|
||||
[messageTypes.requestSrLookupOpportunityBusiness]: requestSrLookupOpportunityBusiness
|
||||
};
|
||||
if (Object.hasOwn(srLookups, message.type)) {
|
||||
requestSrLookupWithSession(srLookups[message.type], message, sender).then(sendResponse).catch(error => sendResponse({ ok: false,
|
||||
httpStatus: error.httpStatus, error: error.message, debugRequests: error.debugRequests || [] }));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (message.type === messageTypes.invalidateProductsCache) {
|
||||
invalidateProductsCache().then(() => sendResponse({ ok: true })).catch(error => sendResponse({ ok: false, error: error.message || "Unable to clear products cache." }));
|
||||
@@ -2178,10 +2376,16 @@ function createBackgroundApplication(overrides = {}) {
|
||||
const requestOpptyProducts = (...args) => productsBackgroundJobs.requestOpptyProducts(...args);
|
||||
const runtimeApi = environment.browser || environment.chrome;
|
||||
const fusionSrDetails = createFusionSrDetails({
|
||||
cookieChanges: runtimeApi?.cookies?.onChanged,
|
||||
cookiesGetAll: (...args) => platformBackgroundApi.cookiesGetAll(...args),
|
||||
tabsCreate: (...args) => platformBackgroundApi.tabsCreate(...args),
|
||||
tabsRemove: (...args) => platformBackgroundApi.tabsRemove(...args),
|
||||
supportsFirefoxCookieStoreTabs: () => platformBackgroundApi.supportsFirefoxCookieStoreTabs(),
|
||||
wait: (...args) => platformBackgroundApi.wait(...args),
|
||||
fetchJson: (...args) => httpBackgroundJson.fetchJson(...args)
|
||||
});
|
||||
function start() {
|
||||
startBackgroundApplication({ messageTypes, requestInternalServiceRequest: (message, sender) => fusionSrDetails.requestInternalServiceRequest(message, sender), requestMgmtAction: message => spaActionOptions.requestMgmtAction(message), invalidateProductsCache: () => productsCache.invalidate(), requestCurrentUser, getXsrfTokenCookie, refreshXsrfCookie, requestAccountPlans, requestInstallBase, requestCustomerServiceRequest, requestWlActions, requestActionTeamMembers, requestActionFindLookup, requestConsumerTokenService, requestConsumptionTrend, requestConsumptionPlanDetail, requestRatecardByPlan, requestOpptyProducts, runtimeApi });
|
||||
startBackgroundApplication({ prepareSrSession: sender => fusionSrDetails.prepareSession(sender), requestSrLookupWithSession: (...args) => fusionSrDetails.requestLookupWithSession(...args), messageTypes, requestSrLookupLanguage: () => fusionSrDetails.requestSrLookupLanguage(), requestSrLookupTechPlatform: () => fusionSrDetails.requestSrLookupTechPlatform(), requestSrLookupOpportunityBusiness: message => fusionSrDetails.requestSrLookupOpportunityBusiness(message), requestSrLookupPrimaryPillar: () => fusionSrDetails.requestSrLookupPrimaryPillar(), requestInternalServiceRequest: (message, sender) => fusionSrDetails.requestInternalServiceRequest(message, sender), requestMgmtAction: message => spaActionOptions.requestMgmtAction(message), invalidateProductsCache: () => productsCache.invalidate(), requestCurrentUser, getXsrfTokenCookie, refreshXsrfCookie, requestAccountPlans, requestInstallBase, requestCustomerServiceRequest, requestWlActions, requestActionTeamMembers, requestActionFindLookup, requestConsumerTokenService, requestConsumptionTrend, requestConsumptionPlanDetail, requestRatecardByPlan, requestOpptyProducts, runtimeApi });
|
||||
}
|
||||
return {
|
||||
start, contracts,
|
||||
|
||||
562
dist/firefox/content.js
vendored
562
dist/firefox/content.js
vendored
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user