const assert = require("node:assert/strict"); const { test } = require("node:test"); const { loadBackground, response } = require("./support/characterization.cjs"); const { loadApplication } = require("./support/application.cjs"); const type = "opportunitiesExtension.requestCurrentUser"; for (const family of ["chrome", "firefox"]) { test(`${family}: current user GET preserves identity token only in debug data for explicit reveal`, async () => { const calls = []; const app = loadBackground({ family, fetch: async (url, options) => { calls.push({ url, options }); return response({ user: { id: "synthetic@example.invalid", roles: ["SALES_REP", "SIMPLE_USER"] }, token: "synthetic-secret" }); } }); const result = await app.dispatch({ type }); assert.equal(result.ok, true); assert.equal(calls.length, 1); assert.equal(calls[0].url, "https://spa.oracle.com/oalcrm/web/api/identity-management/users/current"); assert.equal(calls[0].options.method, "GET"); assert.equal(calls[0].options.credentials, "include"); assert.equal(calls[0].options.cache, "no-store"); assert.equal(result.debugRequests[0].name, "requestCurrentUser"); assert.equal(result.debugRequests[0].httpStatus, 200); assert.equal(JSON.parse(result.debugRequests[0].responseBody).token, "synthetic-secret"); const content = loadApplication("content"); assert.doesNotMatch(content.debugContentLog.formatDebugBody(result.debugRequests[0].responseBody, "requestCurrentUser"), /synthetic-secret/); content.debugState.debugSecretsVisible = true; assert.match(content.debugContentLog.formatDebugBody(result.debugRequests[0].responseBody, "requestCurrentUser"), /synthetic-secret/); assert.equal(result.token, undefined); }); } test("identity failures retain diagnostics but hide response tokens by default", async () => { for (const fetch of [ async () => new Response("synthetic-secretfallback"), async () => response({ token: "synthetic-secret", user: {} }), async () => response({ token: "synthetic-secret", user: { roles: [null] } }), async () => response({ token: "synthetic-secret" }, 401), async () => { throw new Error("Synthetic network failure"); } ]) { const app = loadBackground({ fetch }); const result = await app.dispatch({ type }); assert.equal(result.ok, false); assert.equal(result.debugRequests[0].status, "failed"); const content = loadApplication("content"); assert.doesNotMatch(content.debugContentLog.formatDebugBody(result.debugRequests[0].responseBody, "requestCurrentUser"), /synthetic-secret/); } }); function content(identity) { const app = loadApplication("content", { document: { createElement: () => ({ setAttribute() {} }) } }); app.debugContentView.renderDebugPanel = () => {}; const calls = []; app.platformContentMessages.sendRuntimeMessage = async message => { calls.push(message.type); if (message.type === type) return identity(); return { ok: true, actions: [], hasNext: false }; }; app.authContentSession.requestTokenRelayOnce = async () => { calls.push("tokenrelay"); return "synthetic"; }; app.authContentSession.requestConsumerTokenServiceOnce = async () => ({ workloadActions: { value: "synthetic" } }); app.fusionCrmServiceRequests.requestCrmServiceRequest = async () => { calls.push("crm"); return []; }; app.fusionOpportunities.requestOpportunitiesPage = async () => { calls.push("opportunities"); return []; }; app.productsContentJobs.renderProductsProgress = () => {}; app.productsContentJobs.requestOpptyProductsInBackground = () => {}; app.productsContentJobs.queueProductsTableRender = () => {}; app.opportunitiesTable.setOpportunitiesTableState = () => {}; app.preferencesState.selectedOpportunityTypeValues = new Set(["ORA_ALLOPTIES"]); return { app, calls }; } for (const [roles, allowed] of [[ ["SALES_REP", "SIMPLE_USER"], false ], [ ["SOLUTION_ENG_NOTERR"], true ], [ [], true ]]) { test(`identity runs first, once; CRM/Actions enabled=${allowed} for ${JSON.stringify(roles)}`, async () => { let finish; const { app, calls } = content(() => new Promise(resolve => { finish = resolve; })); const first = app.opportunitiesController.requestOpportunitiesForPeriod("Current Quarter"); assert.deepEqual(calls, [type]); assert.equal(app.currentUser.allowsCrmActivities(), false); const same = app.currentUser.ensure(); assert.equal(same, app.currentUser.ensure()); finish({ ok: true, user: { roles } }); await first; assert.deepEqual(calls, [type, "tokenrelay", "opportunities"]); app.productsContentState.currentProductsRequestId = "products-cycle"; app.productActivities.begin("products-cycle", "synthetic"); const products = { items: [{ RevnId: "123" }] }; app.productsContentState.opptyProductsByNumber.set("OP", products); app.productActivities.complete("products-cycle"); await new Promise(resolve => setImmediate(resolve)); assert.equal(calls.includes("opportunitiesExtension.requestWlActions"), allowed); if (!allowed) { assert.equal(app.opportunityCrmServiceRequests.createBadge("OP"), null); assert.equal(app.opportunityWorkloadActions.createBadge("OP"), null); } await app.opportunitiesController.requestOpportunitiesForPeriod("Next Quarter"); app.opportunityCrmServiceRequests.reset(); app.opportunityWorkloadActions.reopen(); await app.currentUser.ensure(); assert.equal(calls.filter(value => value === type).length, 1); }); } test("identity failure disables only CRM/Actions and does not retry on Reference changes", async () => { for (const identity of [async () => ({ ok: false }), async () => ({ ok: true, user: {} }), async () => { throw new Error("Offline"); }]) { const { app, calls } = content(identity); await app.opportunitiesController.requestOpportunitiesForPeriod("Current Quarter"); await app.opportunitiesController.requestOpportunitiesForPeriod("Next Quarter"); assert.equal(calls.filter(value => value === type).length, 1); assert.equal(calls.filter(value => value === "opportunities").length, 2); assert.equal(calls.includes("crm"), false); app.opportunityWorkloadActions.loadProducts({ items: [{ RevnId: "123" }] }); assert.equal(calls.includes("opportunitiesExtension.requestWlActions"), false); } });