@nuvlore/extension-access-bamboo 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/README.md +3 -0
- package/package.json +54 -0
- package/tools/bamboo_sso_latest_result.mjs +33 -0
- package/tools/bamboo_sso_plan.mjs +33 -0
- package/tools/bamboo_sso_plan_results.mjs +35 -0
- package/tools/bamboo_sso_plans.mjs +32 -0
- package/tools/bamboo_sso_read.mjs +49 -0
- package/tools/bamboo_sso_result.mjs +33 -0
- package/tools/bamboo_sso_text_download.mjs +71 -0
- package/tools/bamboo_sso_verify.mjs +26 -0
- package/vendor/extension-sso/LICENSE +202 -0
- package/vendor/extension-sso/README.md +35 -0
- package/vendor/extension-sso/commands/okta-login.md +10 -0
- package/vendor/extension-sso/package.json +51 -0
- package/vendor/extension-sso/skills/workday-okta-auth/SKILL.md +20 -0
- package/vendor/extension-sso/src/autoAuth.mjs +25 -0
- package/vendor/extension-sso/src/browserLogin.mjs +1 -0
- package/vendor/extension-sso/src/chromeCookies.mjs +1 -0
- package/vendor/extension-sso/src/cookieJar.mjs +1 -0
- package/vendor/extension-sso/src/extensionAccess.mjs +173 -0
- package/vendor/extension-sso/src/htmlSessionExtract.mjs +1 -0
- package/vendor/extension-sso/src/oktaAppAccess.mjs +133 -0
- package/vendor/extension-sso/src/oktaAppCatalog.mjs +118 -0
- package/vendor/extension-sso/src/oktaAppRead.mjs +119 -0
- package/vendor/extension-sso/src/oktaConfig.mjs +12 -0
- package/vendor/extension-sso/src/oktaSession.mjs +32 -0
- package/vendor/extension-sso/src/serviceOperations.mjs +407 -0
- package/vendor/extension-sso/src/serviceReadSearch.mjs +395 -0
- package/vendor/extension-sso/src/serviceReads.mjs +109 -0
- package/vendor/extension-sso/src/serviceRegistry.mjs +497 -0
- package/vendor/extension-sso/src/sessionAuth.mjs +339 -0
- package/vendor/extension-sso/src/sessionManager.mjs +212 -0
- package/vendor/extension-sso/src/sessionValidate.mjs +74 -0
- package/vendor/extension-sso/src/ssoConfig.mjs +31 -0
- package/vendor/extension-sso/src/ssoHttpRead.mjs +292 -0
- package/vendor/extension-sso/tools/extension-access-tools.shared.mjs +16 -0
- package/vendor/extension-sso/tools/okta-app-tools.shared.mjs +5 -0
- package/vendor/extension-sso/tools/okta-tools.shared.mjs +18 -0
- package/vendor/extension-sso/tools/workday_extension_read.mjs +51 -0
- package/vendor/extension-sso/tools/workday_extension_read_access.mjs +65 -0
- package/vendor/extension-sso/tools/workday_list_extension_access.mjs +39 -0
- package/vendor/extension-sso/tools/workday_list_okta_apps.mjs +18 -0
- package/vendor/extension-sso/tools/workday_list_service_operations.mjs +41 -0
- package/vendor/extension-sso/tools/workday_list_service_read_search_capabilities.mjs +34 -0
- package/vendor/extension-sso/tools/workday_list_services.mjs +31 -0
- package/vendor/extension-sso/tools/workday_okta_app_probe_all.mjs +24 -0
- package/vendor/extension-sso/tools/workday_okta_app_read.mjs +30 -0
- package/vendor/extension-sso/tools/workday_okta_app_read_access.mjs +25 -0
- package/vendor/extension-sso/tools/workday_okta_auth_header.mjs +58 -0
- package/vendor/extension-sso/tools/workday_okta_login.mjs +65 -0
- package/vendor/extension-sso/tools/workday_okta_open_app.mjs +63 -0
- package/vendor/extension-sso/tools/workday_okta_open_service.mjs +63 -0
- package/vendor/extension-sso/tools/workday_okta_status.mjs +35 -0
- package/vendor/extension-sso/tools/workday_service_auth.mjs +65 -0
- package/vendor/extension-sso/tools/workday_service_operation_read.mjs +51 -0
- package/vendor/extension-sso/tools/workday_service_read.mjs +56 -0
- package/vendor/extension-sso/tools/workday_service_search.mjs +62 -0
- package/vendor/extension-sso/tools/workday_sso_cookie_header.mjs +59 -0
- package/vendor/extension-sso/vendor/extension-browser-sso/LICENSE +202 -0
- package/vendor/extension-sso/vendor/extension-browser-sso/README.md +16 -0
- package/vendor/extension-sso/vendor/extension-browser-sso/package.json +47 -0
- package/vendor/extension-sso/vendor/extension-browser-sso/src/autoAuth.mjs +47 -0
- package/vendor/extension-sso/vendor/extension-browser-sso/src/browserHttpRead.mjs +76 -0
- package/vendor/extension-sso/vendor/extension-browser-sso/src/browserLogin.mjs +24 -0
- package/vendor/extension-sso/vendor/extension-browser-sso/src/chromeCookies.mjs +192 -0
- package/vendor/extension-sso/vendor/extension-browser-sso/src/cookieJar.mjs +132 -0
- package/vendor/extension-sso/vendor/extension-browser-sso/src/extensions/toolkit/devops-data-paths.mjs +222 -0
- package/vendor/extension-sso/vendor/extension-browser-sso/src/extensions/toolkit/devops-diagnostics.mjs +440 -0
- package/vendor/extension-sso/vendor/extension-browser-sso/src/extensions/toolkit/enterprise-api-read.mjs +180 -0
- package/vendor/extension-sso/vendor/extension-browser-sso/src/extensions/toolkit/read-only-command-pack.mjs +1 -0
- package/vendor/extension-sso/vendor/extension-browser-sso/src/extensions/toolkit/read-only-plan.mjs +45 -0
- package/vendor/extension-sso/vendor/extension-browser-sso/src/extensions/toolkit/read-only-shell-policy.d.mts +26 -0
- package/vendor/extension-sso/vendor/extension-browser-sso/src/extensions/toolkit/read-only-shell-policy.mjs +170 -0
- package/vendor/extension-sso/vendor/extension-browser-sso/src/htmlSessionExtract.mjs +64 -0
- package/vendor/extension-sso/vendor/extension-read-only-toolkit/LICENSE +202 -0
- package/vendor/extension-sso/vendor/extension-read-only-toolkit/README.md +29 -0
- package/vendor/extension-sso/vendor/extension-read-only-toolkit/package.json +43 -0
- package/vendor/extension-sso/vendor/extension-read-only-toolkit/src/devops-data-paths.mjs +222 -0
- package/vendor/extension-sso/vendor/extension-read-only-toolkit/src/devops-diagnostics.mjs +440 -0
- package/vendor/extension-sso/vendor/extension-read-only-toolkit/src/enterprise-api-read.mjs +180 -0
- package/vendor/extension-sso/vendor/extension-read-only-toolkit/src/read-only-command-pack.mjs +1 -0
- package/vendor/extension-sso/vendor/extension-read-only-toolkit/src/read-only-plan.mjs +45 -0
- package/vendor/extension-sso/vendor/extension-read-only-toolkit/src/read-only-shell-policy.d.mts +26 -0
- package/vendor/extension-sso/vendor/extension-read-only-toolkit/src/read-only-shell-policy.mjs +170 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* All apps visible on https://workday.okta.com/app/UserHome
|
|
3
|
+
* Read-only access only — probe paths are GET.
|
|
4
|
+
*/
|
|
5
|
+
export const OKTA_USER_HOME_APPS = {
|
|
6
|
+
Workday: {
|
|
7
|
+
serviceId: "sso",
|
|
8
|
+
domains: ["workday.okta.com"],
|
|
9
|
+
defaultBaseUrl: "https://workday.okta.com",
|
|
10
|
+
probePath: "/app/UserHome"
|
|
11
|
+
},
|
|
12
|
+
JIRA2: { serviceId: "jira", domains: ["jira2.workday.com"], defaultBaseUrl: "https://jira2.workday.com", probePath: "/rest/api/latest/myself" },
|
|
13
|
+
Bitbucket: { serviceId: "bitbucket", domains: ["bitbucket.workday.com"], defaultBaseUrl: "https://bitbucket.workday.com", probePath: "/" },
|
|
14
|
+
Confluence: { serviceId: "confluence", domains: ["confluence.workday.com"], defaultBaseUrl: "https://confluence.workday.com", probePath: "/rest/api/user/current" },
|
|
15
|
+
Pharos: { serviceId: "pharos", domains: ["grafana.produs.us.wdpharos.io"], defaultBaseUrl: "https://grafana.produs.us.wdpharos.io", probePath: "/login" },
|
|
16
|
+
"GitHub EMU Cloud": { serviceId: "github", domains: ["ghe.megaleo.com"], defaultBaseUrl: "https://ghe.megaleo.com", probePath: "/" },
|
|
17
|
+
PagerDuty: { serviceId: "pagerduty", domains: ["workday.pagerduty.com"], defaultBaseUrl: "https://workday.pagerduty.com", probePath: "/" },
|
|
18
|
+
"Amazon Web Services - AWS": { serviceId: "workday-infra-access", platform: "aws", domains: ["signin.aws.amazon.com"], defaultBaseUrl: "https://signin.aws.amazon.com", probePath: "/", mode: "cli-readonly" },
|
|
19
|
+
Slack: {
|
|
20
|
+
domains: ["workday.enterprise.slack.com", "workday.slack.com", "workday-dev.slack.com", "slack.com", "app.slack.com"],
|
|
21
|
+
defaultBaseUrl: "https://workday.enterprise.slack.com",
|
|
22
|
+
probePath: "/"
|
|
23
|
+
},
|
|
24
|
+
Zoom: { domains: ["workday.zoom.us", "zoom.us", "us.telemetry.zoom.us"], defaultBaseUrl: "https://workday.zoom.us", probePath: "/" },
|
|
25
|
+
Horizon: { domains: ["horizon.workdayinternal.com"], defaultBaseUrl: "https://horizon.workdayinternal.com", probePath: "/" },
|
|
26
|
+
"On Horizon": { domains: ["horizon.workdayinternal.com"], defaultBaseUrl: "https://horizon.workdayinternal.com", probePath: "/" },
|
|
27
|
+
"People & Purpose on Horizon": { domains: ["horizon.workdayinternal.com"], defaultBaseUrl: "https://horizon.workdayinternal.com", probePath: "/" },
|
|
28
|
+
"Workday Service Hub": { domains: ["workday.service-now.com"], defaultBaseUrl: "https://workday.service-now.com", probePath: "/" },
|
|
29
|
+
"Analytics Hub": { domains: ["console.cloud.google.com"], defaultBaseUrl: "https://console.cloud.google.com", probePath: "/", mode: "cli-readonly" },
|
|
30
|
+
"Internal Analytics": { domains: ["console.cloud.google.com"], defaultBaseUrl: "https://console.cloud.google.com", probePath: "/", mode: "cli-readonly" },
|
|
31
|
+
"Workday - Google Apps Drive": {
|
|
32
|
+
domains: ["drive.google.com", "accounts.google.com", "google.com"],
|
|
33
|
+
defaultBaseUrl: "https://drive.google.com",
|
|
34
|
+
probePath: "/drive/"
|
|
35
|
+
},
|
|
36
|
+
Sana: {
|
|
37
|
+
domains: ["workday.sana.ai", "sana.ai", "sanalabs.com"],
|
|
38
|
+
defaultBaseUrl: "https://workday.sana.ai",
|
|
39
|
+
agentsUrl: "https://sana.ai/tPNxyS5GyK1r",
|
|
40
|
+
agentsWorkspaceId: "tPNxyS5GyK1r",
|
|
41
|
+
probePath: "/",
|
|
42
|
+
launchViaUserHome: true
|
|
43
|
+
},
|
|
44
|
+
Peakon: { domains: ["workday.peakon.com", "peakon.com"], defaultBaseUrl: "https://workday.peakon.com", probePath: "/" },
|
|
45
|
+
"Workday Community": { domains: ["community.workday.com"], defaultBaseUrl: "https://community.workday.com", probePath: "/" },
|
|
46
|
+
Achievers: { domains: ["workday.achievers.com"], defaultBaseUrl: "https://workday.achievers.com", probePath: "/" },
|
|
47
|
+
Workboard: { domains: ["workboard.com"], defaultBaseUrl: "https://www.workboard.com", probePath: "/" },
|
|
48
|
+
"Eptura Office Space Tool & Desk Reservations": { domains: ["workday.iofficeconnect.com"], defaultBaseUrl: "https://workday.iofficeconnect.com", probePath: "/" },
|
|
49
|
+
Miro: { domains: ["miro.com", "www.miro.com"], defaultBaseUrl: "https://miro.com", probePath: "/app/dashboard/" },
|
|
50
|
+
OneTrust: { domains: ["app.onetrust.com"], defaultBaseUrl: "https://app.onetrust.com", probePath: "/" },
|
|
51
|
+
"Collibra Data Intelligence Platform": { domains: ["workday.collibra.com"], defaultBaseUrl: "https://workday.collibra.com", probePath: "/" },
|
|
52
|
+
Snyk: { domains: ["app.snyk.io"], defaultBaseUrl: "https://app.snyk.io", probePath: "/" },
|
|
53
|
+
Seismic: { domains: ["workday.seismic.com"], defaultBaseUrl: "https://workday.seismic.com", probePath: "/" },
|
|
54
|
+
Togglr: { domains: ["togglr.io"], defaultBaseUrl: "https://togglr.io", probePath: "/" },
|
|
55
|
+
"Togglr - Internal": { domains: ["togglr.io"], defaultBaseUrl: "https://togglr.io", probePath: "/" },
|
|
56
|
+
"Metrics Portal": { domains: ["metrics.workday.com"], defaultBaseUrl: "https://metrics.workday.com", probePath: "/" },
|
|
57
|
+
"Security Portal": { domains: ["security.workday.com"], defaultBaseUrl: "https://security.workday.com", probePath: "/" },
|
|
58
|
+
"Microsoft Office 365 Office Portal": { domains: ["office.com"], defaultBaseUrl: "https://www.office.com", probePath: "/" },
|
|
59
|
+
"Microsoft Outlook": { domains: ["outlook.office.com"], defaultBaseUrl: "https://outlook.office.com", probePath: "/" },
|
|
60
|
+
Mixpanel: { domains: ["mixpanel.com"], defaultBaseUrl: "https://mixpanel.com", probePath: "/" },
|
|
61
|
+
"Secure Code Warrior": { domains: ["securecodewarrior.com"], defaultBaseUrl: "https://portal.securecodewarrior.com", probePath: "/" },
|
|
62
|
+
"Proofpoint Security Education Platform": { domains: ["proofpoint.com"], defaultBaseUrl: "https://www.proofpoint.com", probePath: "/" },
|
|
63
|
+
"HackerRank For Work": { domains: ["hackerrank.com"], defaultBaseUrl: "https://www.hackerrank.com", probePath: "/" },
|
|
64
|
+
"Visitor Registration": { domains: ["envoy.com"], defaultBaseUrl: "https://envoy.com", probePath: "/" },
|
|
65
|
+
"Healthy Working": { domains: ["cardinus.com"], defaultBaseUrl: "https://www.cardinus.com", probePath: "/" },
|
|
66
|
+
Meetingselect: { domains: ["meetingselect.com"], defaultBaseUrl: "https://www.meetingselect.com", probePath: "/" },
|
|
67
|
+
EveryoneSocial: { domains: ["everyonesocial.com"], defaultBaseUrl: "https://everyonesocial.com", probePath: "/" },
|
|
68
|
+
Aperian: { domains: ["aperianglobal.com"], defaultBaseUrl: "https://www.aperianglobal.com", probePath: "/" },
|
|
69
|
+
"BT diagramming": { domains: ["lucid.co"], defaultBaseUrl: "https://lucid.co", probePath: "/" },
|
|
70
|
+
"Fragomen Nomadic": { domains: ["fragomen.com"], defaultBaseUrl: "https://www.fragomen.com", probePath: "/" },
|
|
71
|
+
"6120 Meeting Center Booking": { domains: ["briefingsource.com"], defaultBaseUrl: "https://www.briefingsource.com", probePath: "/" },
|
|
72
|
+
"WCP Dev Site": { domains: ["workday.com"], defaultBaseUrl: "https://developer.workday.com", probePath: "/" },
|
|
73
|
+
"Workday Procurement": { domains: ["workday.com"], defaultBaseUrl: "https://www.workday.com", probePath: "/" },
|
|
74
|
+
"Workday Travel Tool - US": { domains: ["workday.com"], defaultBaseUrl: "https://www.workday.com", probePath: "/" },
|
|
75
|
+
"Workday Policies": { domains: ["workday.com"], defaultBaseUrl: "https://www.workday.com", probePath: "/" },
|
|
76
|
+
"Workday Pattern Library": { domains: ["workday.com"], defaultBaseUrl: "https://canvas.workday.com", probePath: "/" },
|
|
77
|
+
"Canvas Design System": { domains: ["workday.com"], defaultBaseUrl: "https://canvas.workday.com", probePath: "/" },
|
|
78
|
+
"Global Records Retention Schedule": { domains: ["workday.com"], defaultBaseUrl: "https://www.workday.com", probePath: "/" },
|
|
79
|
+
"Digital Event Library": { domains: ["workday.com"], defaultBaseUrl: "https://www.workday.com", probePath: "/" },
|
|
80
|
+
"Employee Event Registration": { domains: ["workday.com"], defaultBaseUrl: "https://www.workday.com", probePath: "/" },
|
|
81
|
+
DevCon: { domains: ["workday.com"], defaultBaseUrl: "https://www.workday.com", probePath: "/" },
|
|
82
|
+
WOAH: { domains: ["workday.com"], defaultBaseUrl: "https://www.workday.com", probePath: "/" },
|
|
83
|
+
"VitalSource eBooks": { domains: ["vitalsource.com"], defaultBaseUrl: "https://www.vitalsource.com", probePath: "/" },
|
|
84
|
+
"P&T Planner": { domains: ["workday.com"], defaultBaseUrl: "https://www.workday.com", probePath: "/" },
|
|
85
|
+
"P&T Okta Password Check": { domains: ["workday.okta.com"], defaultBaseUrl: "https://workday.okta.com", probePath: "/" },
|
|
86
|
+
"INF-IDM": { domains: ["workday.okta.com"], defaultBaseUrl: "https://workday.okta.com", probePath: "/" },
|
|
87
|
+
ISD: { domains: ["workday.okta.com"], defaultBaseUrl: "https://workday.okta.com", probePath: "/", mode: "oidc-app" },
|
|
88
|
+
"SkyLab Portal": { domains: ["workday.okta.com"], defaultBaseUrl: "https://workday.okta.com", probePath: "/", mode: "oidc-app" },
|
|
89
|
+
"Prod LDAP Password Tool": { domains: ["workday.okta.com"], defaultBaseUrl: "https://workday.okta.com", probePath: "/", mode: "oidc-app" },
|
|
90
|
+
"PRM-Wallboard": { domains: ["workday.okta.com"], defaultBaseUrl: "https://workday.okta.com", probePath: "/", mode: "oidc-app" },
|
|
91
|
+
Osprey: { domains: ["workday.okta.com"], defaultBaseUrl: "https://workday.okta.com", probePath: "/", mode: "oidc-app" },
|
|
92
|
+
ArcPrime: { domains: ["workday.okta.com"], defaultBaseUrl: "https://workday.okta.com", probePath: "/", mode: "oidc-app" },
|
|
93
|
+
"Google Gemini": { domains: ["gemini.google.com"], defaultBaseUrl: "https://gemini.google.com", probePath: "/", mode: "bookmark" },
|
|
94
|
+
NotebookLM: { domains: ["notebooklm.google.com"], defaultBaseUrl: "https://notebooklm.google.com", probePath: "/", mode: "bookmark" },
|
|
95
|
+
Lovable: { domains: ["lovable.dev"], defaultBaseUrl: "https://lovable.dev", probePath: "/", mode: "bookmark" }
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export function listOktaApps() {
|
|
99
|
+
return Object.entries(OKTA_USER_HOME_APPS).map(([name, app]) => ({
|
|
100
|
+
name,
|
|
101
|
+
readOnly: true,
|
|
102
|
+
...app,
|
|
103
|
+
mode: app.mode ?? (app.serviceId ? "extension" : "cookie-http")
|
|
104
|
+
}));
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export function getOktaApp(name) {
|
|
108
|
+
const app = OKTA_USER_HOME_APPS[name];
|
|
109
|
+
if (!app) {
|
|
110
|
+
throw new Error(`Unknown Okta app: ${name}`);
|
|
111
|
+
}
|
|
112
|
+
return { name, readOnly: true, ...app, mode: app.mode ?? (app.serviceId ? "extension" : "cookie-http") };
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export function getOktaAppByServiceId(serviceId) {
|
|
116
|
+
const match = listOktaApps().find((app) => app.serviceId === serviceId);
|
|
117
|
+
return match ?? null;
|
|
118
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { buildRequestUrl, normalizeBaseUrl, parseResponseBody } from "@nuvlore/extension-read-only-toolkit/enterprise-api-read";
|
|
2
|
+
import { assertReadOnlyHttpRequest } from "./extensionAccess.mjs";
|
|
3
|
+
import { resolveBestCookieHost } from "./cookieJar.mjs";
|
|
4
|
+
import { isAuthStatusResponse, resolveAutoAuthOptions, shouldRetryAuthAfterFailure } from "./autoAuth.mjs";
|
|
5
|
+
import { ensureOktaAppSession } from "./sessionAuth.mjs";
|
|
6
|
+
import { getSsoConfig } from "./ssoConfig.mjs";
|
|
7
|
+
import { getOktaApp } from "./oktaAppCatalog.mjs";
|
|
8
|
+
import { extractHtmlSession, extractEmbeddedJson } from "./htmlSessionExtract.mjs";
|
|
9
|
+
|
|
10
|
+
/** Default read targets for Okta-only apps (GET, read-only). */
|
|
11
|
+
export const OKTA_APP_READ_TARGETS = {
|
|
12
|
+
Slack: {
|
|
13
|
+
defaultPath: "/messages",
|
|
14
|
+
extract: "generic",
|
|
15
|
+
extraHeaders: { accept: "text/html,application/json" }
|
|
16
|
+
},
|
|
17
|
+
Zoom: { defaultPath: "/", extract: "generic" },
|
|
18
|
+
Horizon: { defaultPath: "/", extract: "generic" },
|
|
19
|
+
"Workday Service Hub": {
|
|
20
|
+
defaultPath: "/api/now/table/sys_user?sysparm_limit=1&sysparm_fields=user_name,name",
|
|
21
|
+
accept: "application/json"
|
|
22
|
+
},
|
|
23
|
+
"Workday - Google Apps Drive": { defaultPath: "/drive/home", extract: "generic" },
|
|
24
|
+
Sana: { defaultPath: "/", extract: "generic" },
|
|
25
|
+
Peakon: { defaultPath: "/", extract: "generic" },
|
|
26
|
+
Miro: { defaultPath: "/app/dashboard/", extract: "generic" },
|
|
27
|
+
"Microsoft Outlook": { defaultPath: "/mail/", extract: "generic" }
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export async function oktaAppHttpRead(appName, input = {}, options = {}) {
|
|
31
|
+
assertReadOnlyHttpRequest({ method: "GET", path: input.restPath || "/" });
|
|
32
|
+
const app = getOktaApp(appName);
|
|
33
|
+
const target = OKTA_APP_READ_TARGETS[appName] ?? {};
|
|
34
|
+
const authOptions = resolveAutoAuthOptions(options);
|
|
35
|
+
const config = authOptions.config ?? getSsoConfig();
|
|
36
|
+
const session = await ensureOktaAppSession(appName, { ...authOptions, config });
|
|
37
|
+
const { jar } = session;
|
|
38
|
+
const { host, cookie, hasCookies } = resolveBestCookieHost(jar, app.domains ?? []);
|
|
39
|
+
if (!hasCookies || !cookie) {
|
|
40
|
+
if (session.openedBrowser) {
|
|
41
|
+
throw new Error(
|
|
42
|
+
`Okta app "${appName}" auth incomplete. Finish login in Chrome (${session.authUrl}), then retry.`
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
throw new Error(
|
|
46
|
+
`No SSO cookies for Okta app "${appName}". Set WORKDAY_SSO_AUTO_AUTH=true or run workday_okta_login.`
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const baseUrl = normalizeBaseUrl(input.baseUrl || app.defaultBaseUrl || `https://${host}`);
|
|
51
|
+
const restPath = String(input.restPath || target.defaultPath || app.probePath || "/").trim();
|
|
52
|
+
const url = buildRequestUrl(baseUrl, restPath, input.query);
|
|
53
|
+
const fetchImpl = options.fetchImpl ?? globalThis.fetch;
|
|
54
|
+
const follow = input.followRedirects ?? target.followRedirects ?? true;
|
|
55
|
+
|
|
56
|
+
const response = await fetchImpl(url.toString(), {
|
|
57
|
+
method: "GET",
|
|
58
|
+
redirect: follow ? "follow" : "manual",
|
|
59
|
+
headers: {
|
|
60
|
+
accept: target.accept ?? input.accept ?? "application/json,text/html",
|
|
61
|
+
cookie,
|
|
62
|
+
"user-agent": `Mozilla/5.0 nuvlore/0.1 okta-${appName.replace(/\s+/g, "-").toLowerCase()}-read`,
|
|
63
|
+
...(target.extraHeaders ?? {}),
|
|
64
|
+
...(input.headers ?? {})
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const text = await response.text();
|
|
69
|
+
const contentType = response.headers.get("content-type") || "";
|
|
70
|
+
const isJson = contentType.includes("json") || (text.trim().startsWith("{") || text.trim().startsWith("["));
|
|
71
|
+
|
|
72
|
+
let data = isJson ? parseResponseBody(text) : null;
|
|
73
|
+
let extracted = null;
|
|
74
|
+
if (!isJson || input.extractHtml) {
|
|
75
|
+
const extractKind = input.extract || target.extract || "generic";
|
|
76
|
+
extracted = extractHtmlSession(extractKind, text, { url: response.url || url.toString() });
|
|
77
|
+
if (target.embeddedJsonMarker) {
|
|
78
|
+
const embedded = extractEmbeddedJson(text, target.embeddedJsonMarker);
|
|
79
|
+
if (embedded) extracted = { ...extracted, embedded };
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (
|
|
84
|
+
!response.ok &&
|
|
85
|
+
!extracted?.authenticated &&
|
|
86
|
+
isAuthStatusResponse(response.status) &&
|
|
87
|
+
shouldRetryAuthAfterFailure({ status: response.status }, authOptions)
|
|
88
|
+
) {
|
|
89
|
+
await ensureOktaAppSession(appName, {
|
|
90
|
+
...authOptions,
|
|
91
|
+
config,
|
|
92
|
+
forceBrowser: true,
|
|
93
|
+
openBrowserOnMissing: true
|
|
94
|
+
});
|
|
95
|
+
return oktaAppHttpRead(appName, input, { ...authOptions, _retriedAuth: true });
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (!response.ok && !extracted?.authenticated) {
|
|
99
|
+
throw new Error(
|
|
100
|
+
`Okta app "${appName}" read failed (${response.status}) at ${restPath}. Open ${session.authUrl} in Chrome to refresh login.`
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
readOnly: true,
|
|
106
|
+
method: "GET",
|
|
107
|
+
oktaApp: appName,
|
|
108
|
+
service: app.serviceId,
|
|
109
|
+
baseUrl,
|
|
110
|
+
host,
|
|
111
|
+
restPath,
|
|
112
|
+
url: (response.url || url).toString(),
|
|
113
|
+
status: response.status,
|
|
114
|
+
contentType,
|
|
115
|
+
data: data ?? (extracted ? undefined : text.slice(0, 4000)),
|
|
116
|
+
extracted,
|
|
117
|
+
bodyLength: text.length
|
|
118
|
+
};
|
|
119
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { getSsoConfig } from "./ssoConfig.mjs";
|
|
2
|
+
|
|
3
|
+
/** @deprecated Use getSsoConfig — kept for backward compatibility. */
|
|
4
|
+
export function getOktaConfig(env = process.env) {
|
|
5
|
+
return getSsoConfig(env);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function assertOktaConfig(config = getSsoConfig()) {
|
|
9
|
+
if (!config.domain) {
|
|
10
|
+
throw new Error("Missing WORKDAY_OKTA_DOMAIN. Copy .env.example to .env and set your Okta org domain.");
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildCookieHeader,
|
|
3
|
+
isValidationFresh,
|
|
4
|
+
jarSummary,
|
|
5
|
+
loadCookieJar,
|
|
6
|
+
saveCookieJar
|
|
7
|
+
} from "./cookieJar.mjs";
|
|
8
|
+
import { getSsoConfig } from "./ssoConfig.mjs";
|
|
9
|
+
|
|
10
|
+
/** @deprecated Use loadCookieJar — session is now a browser cookie jar. */
|
|
11
|
+
export async function loadSession(sessionPath) {
|
|
12
|
+
const config = getSsoConfig();
|
|
13
|
+
return loadCookieJar(sessionPath ?? config.cookieJarPath);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** @deprecated Use saveCookieJar */
|
|
17
|
+
export async function saveSession(sessionPath, session) {
|
|
18
|
+
return saveCookieJar(sessionPath, session);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** @deprecated Use jar validation via sessionManager */
|
|
22
|
+
export function isSessionValid(jar, now = Date.now()) {
|
|
23
|
+
if (!jar?.cookies?.length) return false;
|
|
24
|
+
const config = getSsoConfig();
|
|
25
|
+
if (jar.authenticated && isValidationFresh(jar, config.validateTtlMs, now)) return true;
|
|
26
|
+
return Boolean(buildCookieHeader(jar.cookies, config.domain));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** @deprecated Use jarSummary */
|
|
30
|
+
export function sessionSummary(jar, config) {
|
|
31
|
+
return jarSummary(jar, config ?? getSsoConfig());
|
|
32
|
+
}
|