The sessions required for Internal SR API calls are now loaded via an iframe
This commit is contained in:
69
dist/firefox/content.js
vendored
69
dist/firefox/content.js
vendored
@@ -2620,6 +2620,62 @@ function createCrmSrPopover({ MODAL_ID, createCopyButton, createCloseIcon, reque
|
||||
return { bind, close };
|
||||
}
|
||||
|
||||
// Source: src/features/opportunities/internal-sr-session.js
|
||||
function createInternalSrSession({ query, environment }) {
|
||||
const { document, setTimeout } = environment;
|
||||
let recovery = null;
|
||||
const wait = duration => new Promise(resolve => setTimeout(resolve, duration));
|
||||
const now = () => environment.performance?.now() ?? Date.now();
|
||||
async function warmSession(id) {
|
||||
const frame = document.createElement("iframe");
|
||||
frame.src = "https://eeho.fa.us2.oraclecloud.com/fscmUI/redwood/service/ec/container/sr/edit?srNumber=SR0001421040&srId=302963804324543&view=showisr";
|
||||
frame.title = "Internal SR session initialization";
|
||||
frame.tabIndex = -1;
|
||||
frame.setAttribute("aria-hidden", "true");
|
||||
frame.setAttribute("sandbox", "allow-scripts allow-same-origin allow-forms");
|
||||
frame.style.cssText = "position:fixed;width:1px;height:1px;left:-10000px;top:0;border:0;opacity:0;pointer-events:none;";
|
||||
let blocked = false;
|
||||
let loaded = false;
|
||||
frame.addEventListener("error", () => { blocked = true; });
|
||||
frame.addEventListener("load", () => { loaded = true; });
|
||||
try {
|
||||
if (!document.body) throw new Error("The current page cannot initialize the Internal SR session.");
|
||||
document.body.append(frame);
|
||||
const deadline = now() + 60000;
|
||||
for (let attempt = 0; now() < deadline; attempt += 1) {
|
||||
// Check immediately, then briefly poll faster before backing off.
|
||||
if (attempt > 0) await wait(Math.min(attempt <= 4 ? 250 : 1000, deadline - now()));
|
||||
if (now() >= deadline) break;
|
||||
if (blocked) throw new Error("The Internal SR session iframe could not be loaded. Sign in manually and try again.");
|
||||
const result = await query(id);
|
||||
if (result?.ok) return { id, result };
|
||||
if (result?.httpStatus !== 401) throw new Error(result?.error || "Unable to load Internal SR details.");
|
||||
}
|
||||
throw new Error(`Internal SR session timed out after 60 seconds: the API still returned HTTP 401. ${loaded ? "The iframe emitted a load event, but authentication was not confirmed." : "The iframe did not emit a load event."} Sign in manually and try again.`);
|
||||
} finally {
|
||||
// Stop remaining page resources without stopping the caller's page.
|
||||
try { frame.contentWindow?.stop(); } catch { /* Redirects can make the frame cross-origin. */ }
|
||||
frame.src = "about:blank";
|
||||
frame.remove();
|
||||
}
|
||||
}
|
||||
async function request(id) {
|
||||
let result = await query(id);
|
||||
if (!result?.ok && result?.httpStatus === 401) {
|
||||
if (!recovery) {
|
||||
recovery = warmSession(id);
|
||||
const pending = recovery;
|
||||
pending.finally(() => { if (recovery === pending) recovery = null; }).catch(() => {});
|
||||
}
|
||||
const recovered = await recovery;
|
||||
result = recovered.id === id ? recovered.result : await query(id);
|
||||
}
|
||||
if (!result?.ok) throw new Error(result?.error || "Unable to load Internal SR details.");
|
||||
return result.items;
|
||||
}
|
||||
return { request };
|
||||
}
|
||||
|
||||
// Source: src/features/opportunities/workload-actions.js
|
||||
function createOpportunityWorkloadActions({ authSessionState, allowsCrmActivities, requestConsumerTokenServiceOnce, sendRuntimeMessage,
|
||||
appendBackgroundRequestLog, queueProductsTableRender, productsContentState, messageTypes, reportProgress, activityCache, createActionButton, closeActionForm, setBadgeContent, environment }) {
|
||||
@@ -8061,13 +8117,16 @@ function createContentApplication(overrides = {}) {
|
||||
readResponseBodyForDebug: (...args) => debugContentLog.readResponseBodyForDebug(...args),
|
||||
maskToken: (...args) => debugContentLog.maskToken(...args), environment
|
||||
});
|
||||
const crmSrPopover = createCrmSrPopover({
|
||||
requestDetails: async srId => {
|
||||
const internalSrSession = createInternalSrSession({
|
||||
environment,
|
||||
query: async srId => {
|
||||
const result = await platformContentMessages.sendRuntimeMessage({ type: messageTypes.requestInternalServiceRequest, srId });
|
||||
debugContentLog.appendBackgroundRequestLog(result?.debugRequests || []);
|
||||
if (!result?.ok) throw new Error(result?.error || "Unable to load SR details.");
|
||||
return result.items;
|
||||
},
|
||||
return result;
|
||||
}
|
||||
});
|
||||
const crmSrPopover = createCrmSrPopover({
|
||||
requestDetails: srId => internalSrSession.request(srId),
|
||||
MODAL_ID: contracts.MODAL_ID,
|
||||
createCopyButton: (...args) => opportunitiesLinks.createCopyOpportunityButton(...args),
|
||||
createCloseIcon: (...args) => contentIcons.createCloseIcon(...args), environment
|
||||
|
||||
Reference in New Issue
Block a user