53 lines
2.8 KiB
JavaScript
53 lines
2.8 KiB
JavaScript
function createSpaPage() {
|
|
function start() {
|
|
if (location.origin !== "https://spa.oracle.com" || window.top !== window) return;
|
|
const runtime = (globalThis.browser || globalThis.chrome)?.runtime;
|
|
if (!runtime) return;
|
|
const documentId = `${performance.timeOrigin}:${location.pathname}`;
|
|
let identityRequest = null;
|
|
|
|
function inspect() {
|
|
const text = `${document.title}\n${document.body?.innerText || ""}`.trim();
|
|
let status = "loading";
|
|
if (/\b(?:401\s+(?:authorization required|unauthorized)|403\s+forbidden|access denied|authorization required|authentication failed|internal server error|service unavailable|bad gateway)\b/i.test(text)) status = "error";
|
|
else if (/^\/(?:cloudgate|login|signin|sso|oauth)(?:\/|$)/i.test(location.pathname)
|
|
|| /\b(?:sign(?:ing)? in|log in|single sign.on|oracle access manager)\b/i.test(document.title)
|
|
|| document.querySelector('input[name="SAMLResponse"], input[name="SAMLRequest"], input[type="password"], form[action*="/sso"], form[action*="/login"], meta[http-equiv="refresh" i]')) status = "login";
|
|
else if ((document.readyState === "interactive" || document.readyState === "complete") && text
|
|
&& document.querySelector('a[href], button, input, [role="main"], main, nav')) status = "ready";
|
|
return { status, documentId };
|
|
}
|
|
|
|
runtime.onMessage.addListener((message, sender, reply) => {
|
|
if (sender.id !== runtime.id) return false;
|
|
if (message?.type === "opportunitiesExtension.inspectSpaPage") {
|
|
reply(inspect());
|
|
return false;
|
|
}
|
|
if (message?.type !== "opportunitiesExtension.readSpaIdentity") return false;
|
|
const page = inspect();
|
|
if (page.status !== "ready" || page.documentId !== message.documentId) {
|
|
reply({ error: "SPA page is not ready or has navigated." });
|
|
return false;
|
|
}
|
|
// A document is probed at most once; failed identity reads require a fresh navigation.
|
|
if (!identityRequest) identityRequest = (async () => {
|
|
const controller = new AbortController();
|
|
const timer = setTimeout(() => controller.abort(), 15000);
|
|
try {
|
|
const response = await fetch("https://spa.oracle.com/oalcrm/web/api/identity-management/users/current", {
|
|
method: "GET", credentials: "include", cache: "no-store", headers: { Accept: "application/json" }, signal: controller.signal
|
|
});
|
|
return { status: response.status, statusText: response.statusText, headers: Object.fromEntries(response.headers),
|
|
contentType: response.headers.get("content-type") || "", body: await response.text() };
|
|
} catch (error) {
|
|
return { error: error.message || "Unable to read SPA identity." };
|
|
} finally { clearTimeout(timer); }
|
|
})();
|
|
identityRequest.then(reply);
|
|
return true;
|
|
});
|
|
}
|
|
return { start };
|
|
}
|