@the-open-engine/zeroshot 6.29.0 → 6.30.0
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/CHANGELOG.md +4 -0
- package/cli/index.js +2 -4
- package/lib/agent-cli-provider/adapters/codex.d.ts.map +1 -1
- package/lib/agent-cli-provider/adapters/codex.js +0 -1
- package/lib/agent-cli-provider/adapters/codex.js.map +1 -1
- package/lib/agent-cli-provider/contract-actions.d.ts +1 -1
- package/lib/agent-cli-provider/contract-actions.d.ts.map +1 -1
- package/lib/agent-cli-provider/contract-actions.js +5 -5
- package/lib/agent-cli-provider/contract-actions.js.map +1 -1
- package/lib/agent-cli-provider/contract-invoke.d.ts +1 -1
- package/lib/agent-cli-provider/contract-invoke.d.ts.map +1 -1
- package/lib/agent-cli-provider/contract-invoke.js +2 -2
- package/lib/agent-cli-provider/contract-invoke.js.map +1 -1
- package/lib/agent-cli-provider/contract-support.d.ts +1 -1
- package/lib/agent-cli-provider/contract-support.d.ts.map +1 -1
- package/lib/agent-cli-provider/contract-support.js +2 -2
- package/lib/agent-cli-provider/contract-support.js.map +1 -1
- package/lib/agent-cli-provider/contract.d.ts +1 -0
- package/lib/agent-cli-provider/contract.d.ts.map +1 -1
- package/lib/agent-cli-provider/contract.js +1 -1
- package/lib/agent-cli-provider/contract.js.map +1 -1
- package/lib/agent-cli-provider/index.d.ts +1 -1
- package/lib/agent-cli-provider/index.d.ts.map +1 -1
- package/lib/agent-cli-provider/index.js +2 -1
- package/lib/agent-cli-provider/index.js.map +1 -1
- package/lib/agent-cli-provider/provider-registry.d.ts +1 -0
- package/lib/agent-cli-provider/provider-registry.d.ts.map +1 -1
- package/lib/agent-cli-provider/provider-registry.js +4 -0
- package/lib/agent-cli-provider/provider-registry.js.map +1 -1
- package/lib/agent-cli-provider/single-agent-runtime.d.ts +3 -3
- package/lib/agent-cli-provider/single-agent-runtime.d.ts.map +1 -1
- package/lib/agent-cli-provider/single-agent-runtime.js +22 -48
- package/lib/agent-cli-provider/single-agent-runtime.js.map +1 -1
- package/lib/cluster/client.cjs +30 -7
- package/lib/cluster/client.d.cts +52 -0
- package/lib/cluster/client.d.mts +52 -0
- package/lib/cluster/client.d.ts +4 -6
- package/lib/cluster/client.mjs +32 -9
- package/lib/cluster/connection-state.cjs +25 -0
- package/lib/cluster/connection-state.d.cts +13 -0
- package/lib/cluster/connection-state.d.mts +13 -0
- package/lib/cluster/connection-state.d.ts +13 -0
- package/lib/cluster/connection-state.mjs +21 -0
- package/lib/{target/hosted-run/contracts.js → cluster/connection-types.cjs} +0 -1
- package/lib/cluster/connection-types.d.cts +33 -0
- package/lib/cluster/connection-types.d.mts +33 -0
- package/lib/cluster/connection-types.d.ts +33 -0
- package/lib/cluster/connection-types.mjs +1 -0
- package/lib/cluster/connection.cjs +18 -46
- package/lib/cluster/connection.d.cts +26 -0
- package/lib/cluster/connection.d.mts +26 -0
- package/lib/cluster/connection.d.ts +7 -25
- package/lib/cluster/connection.mjs +12 -42
- package/lib/cluster/errors.cjs +9 -1
- package/lib/cluster/errors.d.cts +29 -0
- package/lib/cluster/errors.d.mts +29 -0
- package/lib/cluster/errors.d.ts +4 -0
- package/lib/cluster/errors.mjs +7 -0
- package/lib/cluster/frames.d.cts +12 -0
- package/lib/cluster/frames.d.mts +12 -0
- package/lib/cluster/generated/protocol-schema.d.cts +1 -0
- package/lib/cluster/generated/protocol-schema.d.mts +1 -0
- package/lib/cluster/generated/protocol.d.cts +781 -0
- package/lib/cluster/generated/protocol.d.mts +781 -0
- package/lib/cluster/index.cjs +2 -2
- package/lib/cluster/index.d.cts +13 -0
- package/lib/cluster/index.d.mts +13 -0
- package/lib/cluster/index.d.ts +3 -3
- package/lib/cluster/index.mjs +2 -2
- package/lib/cluster/json-source.cjs +1 -0
- package/lib/cluster/json-source.d.cts +5 -0
- package/lib/cluster/json-source.d.mts +5 -0
- package/lib/cluster/json-source.d.ts +1 -0
- package/lib/cluster/json-source.mjs +1 -0
- package/lib/cluster/payload-value.cjs +1 -0
- package/lib/cluster/payload-value.d.cts +8 -0
- package/lib/cluster/payload-value.d.mts +8 -0
- package/lib/cluster/payload-value.d.ts +1 -0
- package/lib/cluster/payload-value.mjs +1 -0
- package/lib/cluster/queue.d.cts +15 -0
- package/lib/cluster/queue.d.mts +15 -0
- package/lib/cluster/socket.cjs +8 -0
- package/lib/cluster/socket.d.cts +13 -0
- package/lib/cluster/socket.d.mts +13 -0
- package/lib/cluster/socket.d.ts +2 -0
- package/lib/cluster/socket.mjs +7 -0
- package/lib/cluster/subscriptions.d.cts +73 -0
- package/lib/cluster/subscriptions.d.mts +73 -0
- package/lib/cluster/subscriptions.d.ts +5 -1
- package/lib/cluster/validators.cjs +1 -0
- package/lib/cluster/validators.d.cts +7 -0
- package/lib/cluster/validators.d.mts +7 -0
- package/lib/cluster/validators.d.ts +1 -0
- package/lib/cluster/validators.mjs +1 -0
- package/lib/cluster-worker/engine-adapter-common.js +37 -0
- package/lib/cluster-worker/engine-adapter.js +24 -30
- package/lib/cluster-worker/engine-start.js +59 -0
- package/lib/cluster-worker/index.js +49 -67
- package/lib/cluster-worker/profiles.js +1 -42
- package/lib/cluster-worker/runtime-dependencies.js +49 -0
- package/lib/cluster-worker/runtime-support.js +2 -34
- package/lib/cluster-worker/terminal-normalizer.js +9 -10
- package/lib/hosted-session/authority.cjs +61 -0
- package/lib/hosted-session/authority.d.cts +3 -0
- package/lib/hosted-session/authority.d.mts +3 -0
- package/lib/hosted-session/authority.d.ts +3 -0
- package/lib/hosted-session/authority.mjs +57 -0
- package/lib/hosted-session/coordinator.cjs +78 -51
- package/lib/hosted-session/coordinator.d.cts +11 -0
- package/lib/hosted-session/coordinator.d.mts +11 -0
- package/lib/hosted-session/coordinator.d.ts +4 -2
- package/lib/hosted-session/coordinator.mjs +75 -51
- package/lib/hosted-session/errors.cjs +25 -0
- package/lib/hosted-session/errors.d.cts +10 -0
- package/lib/hosted-session/errors.d.mts +10 -0
- package/lib/hosted-session/errors.d.ts +10 -0
- package/lib/hosted-session/errors.mjs +19 -0
- package/lib/hosted-session/index.cjs +4 -1
- package/lib/hosted-session/index.d.cts +2 -0
- package/lib/hosted-session/index.d.mts +2 -0
- package/lib/hosted-session/index.d.ts +2 -2
- package/lib/hosted-session/index.mjs +1 -1
- package/lib/hosted-session/reconnecting-watch.cjs +131 -0
- package/lib/hosted-session/reconnecting-watch.d.cts +13 -0
- package/lib/hosted-session/reconnecting-watch.d.mts +13 -0
- package/lib/hosted-session/reconnecting-watch.d.ts +13 -0
- package/lib/hosted-session/reconnecting-watch.mjs +127 -0
- package/lib/hosted-session/types.d.cts +32 -0
- package/lib/hosted-session/types.d.mts +32 -0
- package/lib/hosted-session/types.d.ts +19 -7
- package/lib/hosted-target/access-url.cjs +44 -0
- package/lib/hosted-target/access-url.d.cts +2 -0
- package/lib/hosted-target/access-url.d.mts +2 -0
- package/lib/hosted-target/access-url.d.ts +2 -0
- package/lib/hosted-target/access-url.mjs +41 -0
- package/lib/hosted-target/adapter-request.cjs +12 -0
- package/lib/hosted-target/adapter-request.d.cts +17 -0
- package/lib/hosted-target/adapter-request.d.mts +17 -0
- package/lib/hosted-target/adapter-request.d.ts +17 -0
- package/lib/hosted-target/adapter-request.mjs +9 -0
- package/lib/hosted-target/adapter-types.cjs +2 -0
- package/lib/hosted-target/adapter-types.d.cts +27 -0
- package/lib/hosted-target/adapter-types.d.mts +27 -0
- package/lib/hosted-target/adapter-types.d.ts +27 -0
- package/lib/hosted-target/adapter-types.mjs +1 -0
- package/lib/hosted-target/bounds.cjs +10 -0
- package/lib/hosted-target/bounds.d.cts +7 -0
- package/lib/hosted-target/bounds.d.mts +7 -0
- package/lib/hosted-target/bounds.d.ts +7 -0
- package/lib/hosted-target/bounds.mjs +7 -0
- package/lib/hosted-target/capsule-error-response.cjs +76 -0
- package/lib/hosted-target/capsule-error-response.d.cts +2 -0
- package/lib/hosted-target/capsule-error-response.d.mts +2 -0
- package/lib/hosted-target/capsule-error-response.d.ts +2 -0
- package/lib/hosted-target/capsule-error-response.mjs +73 -0
- package/lib/hosted-target/errors.cjs +88 -0
- package/lib/hosted-target/errors.d.cts +36 -0
- package/lib/hosted-target/errors.d.mts +36 -0
- package/lib/hosted-target/errors.d.ts +36 -0
- package/lib/hosted-target/errors.mjs +75 -0
- package/lib/hosted-target/index.cjs +16 -0
- package/lib/hosted-target/index.d.cts +3 -0
- package/lib/hosted-target/index.d.mts +3 -0
- package/lib/hosted-target/index.d.ts +3 -0
- package/lib/hosted-target/index.mjs +2 -0
- package/lib/hosted-target/response-validation.cjs +169 -0
- package/lib/hosted-target/response-validation.d.cts +5 -0
- package/lib/hosted-target/response-validation.d.mts +5 -0
- package/lib/hosted-target/response-validation.d.ts +5 -0
- package/lib/hosted-target/response-validation.mjs +163 -0
- package/lib/hosted-target/retry-executor.cjs +51 -0
- package/lib/hosted-target/retry-executor.d.cts +8 -0
- package/lib/hosted-target/retry-executor.d.mts +8 -0
- package/lib/hosted-target/retry-executor.d.ts +8 -0
- package/lib/hosted-target/retry-executor.mjs +48 -0
- package/lib/hosted-target/retry.cjs +78 -0
- package/lib/hosted-target/retry.d.cts +9 -0
- package/lib/hosted-target/retry.d.mts +9 -0
- package/lib/hosted-target/retry.d.ts +9 -0
- package/lib/hosted-target/retry.mjs +73 -0
- package/lib/hosted-target/target-adapter.cjs +10 -0
- package/lib/hosted-target/target-adapter.d.cts +3 -0
- package/lib/hosted-target/target-adapter.d.mts +3 -0
- package/lib/hosted-target/target-adapter.d.ts +3 -0
- package/lib/hosted-target/target-adapter.mjs +7 -0
- package/lib/hosted-target/types.cjs +4 -0
- package/lib/hosted-target/types.d.cts +50 -0
- package/lib/hosted-target/types.d.mts +50 -0
- package/lib/hosted-target/types.d.ts +50 -0
- package/lib/hosted-target/types.mjs +1 -0
- package/lib/hosted-target/zero-cloud-v1-adapter.cjs +185 -0
- package/lib/hosted-target/zero-cloud-v1-adapter.d.cts +13 -0
- package/lib/hosted-target/zero-cloud-v1-adapter.d.mts +13 -0
- package/lib/hosted-target/zero-cloud-v1-adapter.d.ts +13 -0
- package/lib/hosted-target/zero-cloud-v1-adapter.mjs +181 -0
- package/lib/start-cluster.js +3 -3
- package/lib/target/bounded-response.cjs +51 -0
- package/lib/target/bounded-response.d.cts +1 -0
- package/lib/target/bounded-response.d.mts +1 -0
- package/lib/target/bounded-response.d.ts +1 -0
- package/lib/target/bounded-response.js +51 -0
- package/lib/target/bounded-response.mjs +48 -0
- package/lib/target/credential-lock.js +1 -3
- package/lib/target/credential-store.js +9 -4
- package/lib/target/device-flow.cjs +213 -0
- package/lib/target/device-flow.d.cts +54 -0
- package/lib/target/device-flow.d.mts +54 -0
- package/lib/target/device-flow.d.ts +26 -14
- package/lib/target/device-flow.js +162 -58
- package/lib/target/device-flow.mjs +203 -0
- package/lib/target/discovery-errors.cjs +10 -0
- package/lib/target/discovery-errors.d.cts +3 -0
- package/lib/target/discovery-errors.d.mts +3 -0
- package/lib/target/discovery-errors.d.ts +3 -0
- package/lib/target/discovery-errors.js +10 -0
- package/lib/target/discovery-errors.mjs +6 -0
- package/lib/target/discovery-sections.cjs +191 -0
- package/lib/target/discovery-sections.d.cts +52 -0
- package/lib/target/discovery-sections.d.mts +52 -0
- package/lib/target/discovery-sections.d.ts +52 -0
- package/lib/target/discovery-sections.js +191 -0
- package/lib/target/discovery-sections.mjs +179 -0
- package/lib/target/discovery-validation.cjs +109 -0
- package/lib/target/discovery-validation.d.cts +28 -0
- package/lib/target/discovery-validation.d.mts +28 -0
- package/lib/target/discovery-validation.d.ts +28 -0
- package/lib/target/discovery-validation.js +109 -0
- package/lib/target/discovery-validation.mjs +99 -0
- package/lib/target/discovery.cjs +112 -0
- package/lib/target/discovery.d.cts +74 -0
- package/lib/target/discovery.d.mts +74 -0
- package/lib/target/discovery.d.ts +67 -5
- package/lib/target/discovery.js +94 -79
- package/lib/target/discovery.mjs +105 -0
- package/lib/target/index.d.ts +6 -6
- package/lib/target/index.js +36 -36
- package/lib/target/oauth-http.d.ts +2 -0
- package/lib/target/oauth-http.js +25 -0
- package/lib/target/refresh-exchange.d.ts +11 -0
- package/lib/target/refresh-exchange.js +24 -0
- package/lib/target/refresh-revocation.d.ts +8 -0
- package/lib/target/refresh-revocation.js +19 -0
- package/lib/target/route-template.cjs +85 -0
- package/lib/target/route-template.d.cts +7 -0
- package/lib/target/route-template.d.mts +7 -0
- package/lib/target/route-template.d.ts +7 -0
- package/lib/target/route-template.js +85 -0
- package/lib/target/route-template.mjs +81 -0
- package/lib/target/session-errors.d.ts +4 -0
- package/lib/target/session-errors.js +12 -0
- package/lib/target/session-verification.d.ts +10 -0
- package/lib/target/session-verification.js +42 -0
- package/lib/target/target-registry.d.ts +7 -3
- package/lib/target/target-registry.js +41 -10
- package/lib/target/target-session-manager.d.ts +48 -0
- package/lib/target/target-session-manager.js +226 -0
- package/lib/target/target-session.d.ts +39 -32
- package/lib/target/target-session.js +63 -151
- package/lib/target/token-response.cjs +51 -0
- package/lib/target/token-response.d.cts +7 -0
- package/lib/target/token-response.d.mts +7 -0
- package/lib/target/token-response.d.ts +7 -0
- package/lib/target/token-response.js +51 -0
- package/lib/target/token-response.mjs +48 -0
- package/package.json +14 -7
- package/protocol/openengine-cluster/v1/worker.schema.json +171 -9
- package/scripts/build-cluster.js +23 -3
- package/scripts/opcore-introduced-check.js +0 -2
- package/src/agent-cli-provider/adapters/codex.ts +0 -1
- package/src/agent-cli-provider/contract-actions.ts +9 -5
- package/src/agent-cli-provider/contract-invoke.ts +3 -2
- package/src/agent-cli-provider/contract-support.ts +12 -6
- package/src/agent-cli-provider/contract.ts +6 -1
- package/src/agent-cli-provider/index.ts +1 -0
- package/src/agent-cli-provider/provider-registry.ts +4 -0
- package/src/agent-cli-provider/single-agent-runtime.ts +32 -45
- package/src/cluster/client.ts +42 -15
- package/src/cluster/connection-state.ts +33 -0
- package/src/cluster/connection-types.ts +28 -0
- package/src/cluster/connection.ts +37 -68
- package/src/cluster/errors.ts +5 -0
- package/src/cluster/index.ts +3 -1
- package/src/cluster/json-source.ts +1 -0
- package/src/cluster/payload-value.ts +1 -0
- package/src/cluster/socket.ts +13 -0
- package/src/cluster/subscriptions.ts +7 -2
- package/src/cluster/validators.ts +1 -0
- package/src/cluster/ws.d.ts +1 -1
- package/src/hosted-session/authority.ts +77 -0
- package/src/hosted-session/coordinator.ts +113 -56
- package/src/hosted-session/errors.ts +21 -0
- package/src/hosted-session/index.ts +14 -2
- package/src/hosted-session/reconnecting-watch.ts +148 -0
- package/src/hosted-session/types.ts +22 -8
- package/src/hosted-target/access-url.ts +46 -0
- package/src/hosted-target/adapter-request.ts +28 -0
- package/src/hosted-target/adapter-types.ts +39 -0
- package/src/hosted-target/bounds.ts +1 -0
- package/src/hosted-target/capsule-error-response.ts +107 -0
- package/src/hosted-target/errors.ts +36 -35
- package/src/hosted-target/index.ts +10 -23
- package/src/hosted-target/response-validation.ts +170 -62
- package/src/hosted-target/retry-executor.ts +62 -0
- package/src/hosted-target/retry.ts +47 -11
- package/src/hosted-target/target-adapter.ts +12 -8
- package/src/hosted-target/types.ts +19 -18
- package/src/hosted-target/zero-cloud-v1-adapter.ts +229 -316
- package/src/isolation-manager.js +1 -16
- package/src/target/bounded-response.ts +68 -0
- package/src/target/credential-lock.ts +1 -3
- package/src/target/credential-store.ts +14 -10
- package/src/target/device-flow.ts +209 -85
- package/src/target/discovery-errors.ts +6 -0
- package/src/target/discovery-sections.ts +251 -0
- package/src/target/discovery-validation.ts +144 -0
- package/src/target/discovery.ts +163 -97
- package/src/target/index.ts +15 -11
- package/src/target/oauth-http.ts +27 -0
- package/src/target/refresh-exchange.ts +36 -0
- package/src/target/refresh-revocation.ts +29 -0
- package/src/target/route-template.ts +105 -0
- package/src/target/session-errors.ts +9 -0
- package/src/target/session-verification.ts +51 -0
- package/src/target/target-registry.ts +60 -27
- package/src/target/target-session-manager.ts +285 -0
- package/src/target/target-session.ts +105 -226
- package/src/target/token-response.ts +62 -0
- package/docker/zeroshot-oecp/Cargo.toml +0 -12
- package/docker/zeroshot-oecp/Dockerfile +0 -65
- package/docker/zeroshot-oecp/src/main.rs +0 -32
- package/lib/target/bounded-json.d.ts +0 -6
- package/lib/target/bounded-json.js +0 -43
- package/lib/target/hosted-run/client.d.ts +0 -26
- package/lib/target/hosted-run/client.js +0 -158
- package/lib/target/hosted-run/commands.d.ts +0 -4
- package/lib/target/hosted-run/commands.js +0 -113
- package/lib/target/hosted-run/contracts.d.ts +0 -49
- package/lib/target/hosted-run/input.d.ts +0 -5
- package/lib/target/hosted-run/input.js +0 -200
- package/lib/target/hosted-run.d.ts +0 -4
- package/lib/target/hosted-run.js +0 -12
- package/src/target/bounded-json.ts +0 -48
- package/src/target/hosted-run/client.ts +0 -198
- package/src/target/hosted-run/commands.ts +0 -140
- package/src/target/hosted-run/contracts.ts +0 -53
- package/src/target/hosted-run/input.ts +0 -199
- package/src/target/hosted-run.ts +0 -8
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.expandRoute = exports.TargetDiscoveryError = void 0;
|
|
4
|
+
exports.discoverTarget = discoverTarget;
|
|
5
|
+
exports.discoverTargetSessionEndpoints = discoverTargetSessionEndpoints;
|
|
6
|
+
const bounded_response_js_1 = require("./bounded-response.cjs");
|
|
7
|
+
const discovery_errors_js_1 = require("./discovery-errors.cjs");
|
|
8
|
+
const discovery_validation_js_1 = require("./discovery-validation.cjs");
|
|
9
|
+
const discovery_sections_js_1 = require("./discovery-sections.cjs");
|
|
10
|
+
var discovery_errors_js_2 = require("./discovery-errors.cjs");
|
|
11
|
+
Object.defineProperty(exports, "TargetDiscoveryError", { enumerable: true, get: function () { return discovery_errors_js_2.TargetDiscoveryError; } });
|
|
12
|
+
var route_template_js_1 = require("./route-template.cjs");
|
|
13
|
+
Object.defineProperty(exports, "expandRoute", { enumerable: true, get: function () { return route_template_js_1.expandRoute; } });
|
|
14
|
+
const DISCOVERY_PATH = '/.well-known/openengine-hosted-target';
|
|
15
|
+
const MAX_DISCOVERY_BYTES = 64 * 1024;
|
|
16
|
+
const DEVICE_GRANT = 'urn:ietf:params:oauth:grant-type:device_code';
|
|
17
|
+
const CAPSULE_AUDIENCE = 'capsule';
|
|
18
|
+
const ROOT_FIELDS = [
|
|
19
|
+
'kind',
|
|
20
|
+
'adapter',
|
|
21
|
+
'protocol',
|
|
22
|
+
'binding',
|
|
23
|
+
'endpoint',
|
|
24
|
+
'pagination',
|
|
25
|
+
'cache_policy',
|
|
26
|
+
'schema_links',
|
|
27
|
+
'capsule_protocol',
|
|
28
|
+
'oauth',
|
|
29
|
+
'organization_binding',
|
|
30
|
+
'capability_flags',
|
|
31
|
+
'sizes',
|
|
32
|
+
'session',
|
|
33
|
+
'transport',
|
|
34
|
+
'extensions',
|
|
35
|
+
];
|
|
36
|
+
async function readBoundedJson(response) {
|
|
37
|
+
return (0, bounded_response_js_1.readBoundedResponseJson)(response, MAX_DISCOVERY_BYTES, (kind) => new discovery_errors_js_1.TargetDiscoveryError(kind === 'size' ? 'response exceeds the size limit' : 'response is not valid UTF-8 JSON'));
|
|
38
|
+
}
|
|
39
|
+
async function fetchDocument(http, url) {
|
|
40
|
+
const response = await http.fetch(url, {
|
|
41
|
+
method: 'GET',
|
|
42
|
+
headers: { Accept: 'application/json' },
|
|
43
|
+
redirect: 'error',
|
|
44
|
+
});
|
|
45
|
+
if (response.url && new URL(response.url).href !== url) {
|
|
46
|
+
await response.body?.cancel().catch(() => undefined);
|
|
47
|
+
throw new discovery_errors_js_1.TargetDiscoveryError('request changed target route or authority');
|
|
48
|
+
}
|
|
49
|
+
if (!response.ok) {
|
|
50
|
+
await response.body?.cancel().catch(() => undefined);
|
|
51
|
+
throw new discovery_errors_js_1.TargetDiscoveryError(`request failed with status ${response.status}`);
|
|
52
|
+
}
|
|
53
|
+
return (0, discovery_validation_js_1.record)(await readBoundedJson(response), 'response');
|
|
54
|
+
}
|
|
55
|
+
async function discoverTarget(targetUrl, http) {
|
|
56
|
+
const target = new URL(targetUrl);
|
|
57
|
+
const origin = target.origin;
|
|
58
|
+
const discovery = await fetchDocument(http, new URL(DISCOVERY_PATH, target).href);
|
|
59
|
+
(0, discovery_validation_js_1.exact)(discovery.kind, 'openengine.hosted-target/v1', 'kind');
|
|
60
|
+
const adapter = (0, discovery_sections_js_1.parseAdapter)(discovery);
|
|
61
|
+
const endpoint = (0, discovery_sections_js_1.parseEndpoint)(discovery, origin);
|
|
62
|
+
const capsule = (0, discovery_sections_js_1.parseCapsule)(discovery, origin);
|
|
63
|
+
const oauth = (0, discovery_sections_js_1.parseOAuth)(discovery, origin);
|
|
64
|
+
(0, discovery_validation_js_1.exact)(discovery.organization_binding, 'device_approval', 'organization_binding');
|
|
65
|
+
const capabilityFlags = (0, discovery_validation_js_1.exactStringSet)(discovery.capability_flags, 'capability_flags', [
|
|
66
|
+
'capsule_allocate',
|
|
67
|
+
'capsule_read',
|
|
68
|
+
'capsule_terminate',
|
|
69
|
+
'capsule_access',
|
|
70
|
+
'connections_onboarding',
|
|
71
|
+
]);
|
|
72
|
+
const sizes = (0, discovery_sections_js_1.parseSizes)(discovery);
|
|
73
|
+
const session = (0, discovery_sections_js_1.parseSession)(discovery);
|
|
74
|
+
const transport = (0, discovery_sections_js_1.parseTransport)(discovery);
|
|
75
|
+
const credentialInstall = (0, discovery_sections_js_1.parseExtensions)(discovery, origin);
|
|
76
|
+
const metadata = await fetchDocument(http, oauth.metadataUrl);
|
|
77
|
+
(0, discovery_sections_js_1.validateOAuthMetadata)(metadata, origin, [
|
|
78
|
+
oauth.deviceAuthorizationEndpoint,
|
|
79
|
+
oauth.tokenEndpoint,
|
|
80
|
+
oauth.revocationEndpoint,
|
|
81
|
+
]);
|
|
82
|
+
const additional = Object.freeze(Object.fromEntries(Object.entries(discovery).filter(([key]) => !ROOT_FIELDS.includes(key))));
|
|
83
|
+
return Object.freeze({
|
|
84
|
+
origin,
|
|
85
|
+
adapter,
|
|
86
|
+
endpoint: endpoint.url,
|
|
87
|
+
endpointCapabilities: endpoint.capabilities,
|
|
88
|
+
pagination: endpoint.pagination,
|
|
89
|
+
sizes,
|
|
90
|
+
oauth,
|
|
91
|
+
session,
|
|
92
|
+
capsule,
|
|
93
|
+
transport,
|
|
94
|
+
capabilityFlags,
|
|
95
|
+
credentialInstall,
|
|
96
|
+
additional,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
async function discoverTargetSessionEndpoints(targetUrl, http) {
|
|
100
|
+
const descriptor = await discoverTarget(targetUrl, http);
|
|
101
|
+
return Object.freeze({
|
|
102
|
+
deviceAuthorizationEndpoint: descriptor.oauth.deviceAuthorizationEndpoint,
|
|
103
|
+
tokenEndpoint: descriptor.oauth.tokenEndpoint,
|
|
104
|
+
revocationEndpoint: descriptor.oauth.revocationEndpoint,
|
|
105
|
+
clientId: descriptor.oauth.clientId,
|
|
106
|
+
capsuleApiBaseUrl: descriptor.capsule.baseUrl.replace(/\/$/, ''),
|
|
107
|
+
deviceGrantType: descriptor.oauth.deviceGrantType,
|
|
108
|
+
audience: descriptor.oauth.audience,
|
|
109
|
+
sessionEndpoint: new URL(descriptor.session.routeTemplate.template, descriptor.origin).href,
|
|
110
|
+
descriptor,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { HttpTransport } from './device-flow.js';
|
|
2
|
+
import type { RouteTemplate } from './route-template.js';
|
|
3
|
+
import { type CredentialInstallDescriptor } from './discovery-validation.js';
|
|
4
|
+
export type { CredentialInstallDescriptor } from './discovery-validation.js';
|
|
5
|
+
export { TargetDiscoveryError } from './discovery-errors.js';
|
|
6
|
+
export { expandRoute, type RouteTemplate } from './route-template.js';
|
|
7
|
+
declare const DEVICE_GRANT = "urn:ietf:params:oauth:grant-type:device_code";
|
|
8
|
+
declare const CAPSULE_AUDIENCE = "capsule";
|
|
9
|
+
export interface TargetDiscoveryDescriptor {
|
|
10
|
+
readonly origin: string;
|
|
11
|
+
readonly adapter: {
|
|
12
|
+
readonly name: 'fargate' | 'docker' | 'local';
|
|
13
|
+
readonly majorVersion: 1;
|
|
14
|
+
};
|
|
15
|
+
readonly endpoint: string;
|
|
16
|
+
readonly endpointCapabilities: readonly ['exec', 'log_stream'];
|
|
17
|
+
readonly pagination: {
|
|
18
|
+
readonly defaultPageSize: number;
|
|
19
|
+
readonly maxPageSize: number;
|
|
20
|
+
};
|
|
21
|
+
readonly sizes: {
|
|
22
|
+
readonly catalog: readonly ('tiny' | 'small' | 'standard' | 'large')[];
|
|
23
|
+
readonly default: 'tiny' | 'small' | 'standard' | 'large';
|
|
24
|
+
};
|
|
25
|
+
readonly oauth: {
|
|
26
|
+
readonly metadataUrl: string;
|
|
27
|
+
readonly deviceAuthorizationEndpoint: string;
|
|
28
|
+
readonly tokenEndpoint: string;
|
|
29
|
+
readonly revocationEndpoint: string;
|
|
30
|
+
readonly clientId: string;
|
|
31
|
+
readonly deviceGrantType: typeof DEVICE_GRANT;
|
|
32
|
+
readonly audience: typeof CAPSULE_AUDIENCE;
|
|
33
|
+
};
|
|
34
|
+
readonly session: {
|
|
35
|
+
readonly routeTemplate: RouteTemplate;
|
|
36
|
+
readonly method: 'GET';
|
|
37
|
+
};
|
|
38
|
+
readonly capsule: {
|
|
39
|
+
readonly baseUrl: string;
|
|
40
|
+
readonly routes: {
|
|
41
|
+
readonly allocate: RouteTemplate;
|
|
42
|
+
readonly list: RouteTemplate;
|
|
43
|
+
readonly inspect: RouteTemplate;
|
|
44
|
+
readonly terminate: RouteTemplate;
|
|
45
|
+
readonly limits: RouteTemplate;
|
|
46
|
+
readonly access: RouteTemplate;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
readonly transport: {
|
|
50
|
+
readonly websocketRouteTemplate: RouteTemplate;
|
|
51
|
+
readonly unauthorizedStatus: 401;
|
|
52
|
+
readonly closeCodes: {
|
|
53
|
+
readonly expired: 4401;
|
|
54
|
+
readonly revoked: 4403;
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
readonly capabilityFlags: readonly string[];
|
|
58
|
+
readonly credentialInstall: CredentialInstallDescriptor | null;
|
|
59
|
+
readonly additional: Readonly<Record<string, unknown>>;
|
|
60
|
+
}
|
|
61
|
+
/** Compatibility projection. New callers should retain the complete descriptor. */
|
|
62
|
+
export interface TargetSessionEndpoints {
|
|
63
|
+
readonly deviceAuthorizationEndpoint: string;
|
|
64
|
+
readonly tokenEndpoint: string;
|
|
65
|
+
readonly revocationEndpoint: string;
|
|
66
|
+
readonly clientId: string;
|
|
67
|
+
readonly capsuleApiBaseUrl: string;
|
|
68
|
+
readonly deviceGrantType: typeof DEVICE_GRANT;
|
|
69
|
+
readonly audience: typeof CAPSULE_AUDIENCE;
|
|
70
|
+
readonly sessionEndpoint: string;
|
|
71
|
+
readonly descriptor: TargetDiscoveryDescriptor;
|
|
72
|
+
}
|
|
73
|
+
export declare function discoverTarget(targetUrl: string, http: HttpTransport): Promise<TargetDiscoveryDescriptor>;
|
|
74
|
+
export declare function discoverTargetSessionEndpoints(targetUrl: string, http: HttpTransport): Promise<TargetSessionEndpoints>;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { HttpTransport } from './device-flow.js';
|
|
2
|
+
import type { RouteTemplate } from './route-template.js';
|
|
3
|
+
import { type CredentialInstallDescriptor } from './discovery-validation.js';
|
|
4
|
+
export type { CredentialInstallDescriptor } from './discovery-validation.js';
|
|
5
|
+
export { TargetDiscoveryError } from './discovery-errors.js';
|
|
6
|
+
export { expandRoute, type RouteTemplate } from './route-template.js';
|
|
7
|
+
declare const DEVICE_GRANT = "urn:ietf:params:oauth:grant-type:device_code";
|
|
8
|
+
declare const CAPSULE_AUDIENCE = "capsule";
|
|
9
|
+
export interface TargetDiscoveryDescriptor {
|
|
10
|
+
readonly origin: string;
|
|
11
|
+
readonly adapter: {
|
|
12
|
+
readonly name: 'fargate' | 'docker' | 'local';
|
|
13
|
+
readonly majorVersion: 1;
|
|
14
|
+
};
|
|
15
|
+
readonly endpoint: string;
|
|
16
|
+
readonly endpointCapabilities: readonly ['exec', 'log_stream'];
|
|
17
|
+
readonly pagination: {
|
|
18
|
+
readonly defaultPageSize: number;
|
|
19
|
+
readonly maxPageSize: number;
|
|
20
|
+
};
|
|
21
|
+
readonly sizes: {
|
|
22
|
+
readonly catalog: readonly ('tiny' | 'small' | 'standard' | 'large')[];
|
|
23
|
+
readonly default: 'tiny' | 'small' | 'standard' | 'large';
|
|
24
|
+
};
|
|
25
|
+
readonly oauth: {
|
|
26
|
+
readonly metadataUrl: string;
|
|
27
|
+
readonly deviceAuthorizationEndpoint: string;
|
|
28
|
+
readonly tokenEndpoint: string;
|
|
29
|
+
readonly revocationEndpoint: string;
|
|
30
|
+
readonly clientId: string;
|
|
31
|
+
readonly deviceGrantType: typeof DEVICE_GRANT;
|
|
32
|
+
readonly audience: typeof CAPSULE_AUDIENCE;
|
|
33
|
+
};
|
|
34
|
+
readonly session: {
|
|
35
|
+
readonly routeTemplate: RouteTemplate;
|
|
36
|
+
readonly method: 'GET';
|
|
37
|
+
};
|
|
38
|
+
readonly capsule: {
|
|
39
|
+
readonly baseUrl: string;
|
|
40
|
+
readonly routes: {
|
|
41
|
+
readonly allocate: RouteTemplate;
|
|
42
|
+
readonly list: RouteTemplate;
|
|
43
|
+
readonly inspect: RouteTemplate;
|
|
44
|
+
readonly terminate: RouteTemplate;
|
|
45
|
+
readonly limits: RouteTemplate;
|
|
46
|
+
readonly access: RouteTemplate;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
readonly transport: {
|
|
50
|
+
readonly websocketRouteTemplate: RouteTemplate;
|
|
51
|
+
readonly unauthorizedStatus: 401;
|
|
52
|
+
readonly closeCodes: {
|
|
53
|
+
readonly expired: 4401;
|
|
54
|
+
readonly revoked: 4403;
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
readonly capabilityFlags: readonly string[];
|
|
58
|
+
readonly credentialInstall: CredentialInstallDescriptor | null;
|
|
59
|
+
readonly additional: Readonly<Record<string, unknown>>;
|
|
60
|
+
}
|
|
61
|
+
/** Compatibility projection. New callers should retain the complete descriptor. */
|
|
62
|
+
export interface TargetSessionEndpoints {
|
|
63
|
+
readonly deviceAuthorizationEndpoint: string;
|
|
64
|
+
readonly tokenEndpoint: string;
|
|
65
|
+
readonly revocationEndpoint: string;
|
|
66
|
+
readonly clientId: string;
|
|
67
|
+
readonly capsuleApiBaseUrl: string;
|
|
68
|
+
readonly deviceGrantType: typeof DEVICE_GRANT;
|
|
69
|
+
readonly audience: typeof CAPSULE_AUDIENCE;
|
|
70
|
+
readonly sessionEndpoint: string;
|
|
71
|
+
readonly descriptor: TargetDiscoveryDescriptor;
|
|
72
|
+
}
|
|
73
|
+
export declare function discoverTarget(targetUrl: string, http: HttpTransport): Promise<TargetDiscoveryDescriptor>;
|
|
74
|
+
export declare function discoverTargetSessionEndpoints(targetUrl: string, http: HttpTransport): Promise<TargetSessionEndpoints>;
|
|
@@ -1,12 +1,74 @@
|
|
|
1
|
-
import type { HttpTransport } from './device-flow.
|
|
1
|
+
import type { HttpTransport } from './device-flow.js';
|
|
2
|
+
import type { RouteTemplate } from './route-template.js';
|
|
3
|
+
import { type CredentialInstallDescriptor } from './discovery-validation.js';
|
|
4
|
+
export type { CredentialInstallDescriptor } from './discovery-validation.js';
|
|
5
|
+
export { TargetDiscoveryError } from './discovery-errors.js';
|
|
6
|
+
export { expandRoute, type RouteTemplate } from './route-template.js';
|
|
7
|
+
declare const DEVICE_GRANT = "urn:ietf:params:oauth:grant-type:device_code";
|
|
8
|
+
declare const CAPSULE_AUDIENCE = "capsule";
|
|
9
|
+
export interface TargetDiscoveryDescriptor {
|
|
10
|
+
readonly origin: string;
|
|
11
|
+
readonly adapter: {
|
|
12
|
+
readonly name: 'fargate' | 'docker' | 'local';
|
|
13
|
+
readonly majorVersion: 1;
|
|
14
|
+
};
|
|
15
|
+
readonly endpoint: string;
|
|
16
|
+
readonly endpointCapabilities: readonly ['exec', 'log_stream'];
|
|
17
|
+
readonly pagination: {
|
|
18
|
+
readonly defaultPageSize: number;
|
|
19
|
+
readonly maxPageSize: number;
|
|
20
|
+
};
|
|
21
|
+
readonly sizes: {
|
|
22
|
+
readonly catalog: readonly ('tiny' | 'small' | 'standard' | 'large')[];
|
|
23
|
+
readonly default: 'tiny' | 'small' | 'standard' | 'large';
|
|
24
|
+
};
|
|
25
|
+
readonly oauth: {
|
|
26
|
+
readonly metadataUrl: string;
|
|
27
|
+
readonly deviceAuthorizationEndpoint: string;
|
|
28
|
+
readonly tokenEndpoint: string;
|
|
29
|
+
readonly revocationEndpoint: string;
|
|
30
|
+
readonly clientId: string;
|
|
31
|
+
readonly deviceGrantType: typeof DEVICE_GRANT;
|
|
32
|
+
readonly audience: typeof CAPSULE_AUDIENCE;
|
|
33
|
+
};
|
|
34
|
+
readonly session: {
|
|
35
|
+
readonly routeTemplate: RouteTemplate;
|
|
36
|
+
readonly method: 'GET';
|
|
37
|
+
};
|
|
38
|
+
readonly capsule: {
|
|
39
|
+
readonly baseUrl: string;
|
|
40
|
+
readonly routes: {
|
|
41
|
+
readonly allocate: RouteTemplate;
|
|
42
|
+
readonly list: RouteTemplate;
|
|
43
|
+
readonly inspect: RouteTemplate;
|
|
44
|
+
readonly terminate: RouteTemplate;
|
|
45
|
+
readonly limits: RouteTemplate;
|
|
46
|
+
readonly access: RouteTemplate;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
readonly transport: {
|
|
50
|
+
readonly websocketRouteTemplate: RouteTemplate;
|
|
51
|
+
readonly unauthorizedStatus: 401;
|
|
52
|
+
readonly closeCodes: {
|
|
53
|
+
readonly expired: 4401;
|
|
54
|
+
readonly revoked: 4403;
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
readonly capabilityFlags: readonly string[];
|
|
58
|
+
readonly credentialInstall: CredentialInstallDescriptor | null;
|
|
59
|
+
readonly additional: Readonly<Record<string, unknown>>;
|
|
60
|
+
}
|
|
61
|
+
/** Compatibility projection. New callers should retain the complete descriptor. */
|
|
2
62
|
export interface TargetSessionEndpoints {
|
|
3
63
|
readonly deviceAuthorizationEndpoint: string;
|
|
4
64
|
readonly tokenEndpoint: string;
|
|
5
|
-
readonly revocationEndpoint
|
|
65
|
+
readonly revocationEndpoint: string;
|
|
6
66
|
readonly clientId: string;
|
|
7
67
|
readonly capsuleApiBaseUrl: string;
|
|
68
|
+
readonly deviceGrantType: typeof DEVICE_GRANT;
|
|
69
|
+
readonly audience: typeof CAPSULE_AUDIENCE;
|
|
70
|
+
readonly sessionEndpoint: string;
|
|
71
|
+
readonly descriptor: TargetDiscoveryDescriptor;
|
|
8
72
|
}
|
|
9
|
-
export declare
|
|
10
|
-
constructor(message: string);
|
|
11
|
-
}
|
|
73
|
+
export declare function discoverTarget(targetUrl: string, http: HttpTransport): Promise<TargetDiscoveryDescriptor>;
|
|
12
74
|
export declare function discoverTargetSessionEndpoints(targetUrl: string, http: HttpTransport): Promise<TargetSessionEndpoints>;
|
package/lib/target/discovery.js
CHANGED
|
@@ -1,48 +1,40 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.TargetDiscoveryError = void 0;
|
|
3
|
+
exports.expandRoute = exports.TargetDiscoveryError = void 0;
|
|
4
|
+
exports.discoverTarget = discoverTarget;
|
|
4
5
|
exports.discoverTargetSessionEndpoints = discoverTargetSessionEndpoints;
|
|
5
|
-
const
|
|
6
|
+
const bounded_response_js_1 = require("./bounded-response.js");
|
|
7
|
+
const discovery_errors_js_1 = require("./discovery-errors.js");
|
|
8
|
+
const discovery_validation_js_1 = require("./discovery-validation.js");
|
|
9
|
+
const discovery_sections_js_1 = require("./discovery-sections.js");
|
|
10
|
+
var discovery_errors_js_2 = require("./discovery-errors.js");
|
|
11
|
+
Object.defineProperty(exports, "TargetDiscoveryError", { enumerable: true, get: function () { return discovery_errors_js_2.TargetDiscoveryError; } });
|
|
12
|
+
var route_template_js_1 = require("./route-template.js");
|
|
13
|
+
Object.defineProperty(exports, "expandRoute", { enumerable: true, get: function () { return route_template_js_1.expandRoute; } });
|
|
6
14
|
const DISCOVERY_PATH = '/.well-known/openengine-hosted-target';
|
|
7
15
|
const MAX_DISCOVERY_BYTES = 64 * 1024;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
function
|
|
29
|
-
|
|
30
|
-
throw new TargetDiscoveryError(`${field} must be an absolute URL`);
|
|
31
|
-
}
|
|
32
|
-
let endpoint;
|
|
33
|
-
try {
|
|
34
|
-
endpoint = new URL(value);
|
|
35
|
-
}
|
|
36
|
-
catch {
|
|
37
|
-
throw new TargetDiscoveryError(`${field} must be an absolute URL`);
|
|
38
|
-
}
|
|
39
|
-
if (endpoint.username || endpoint.password || endpoint.search || endpoint.hash) {
|
|
40
|
-
throw new TargetDiscoveryError(`${field} contains forbidden URL components`);
|
|
41
|
-
}
|
|
42
|
-
if (endpoint.origin !== serviceOrigin) {
|
|
43
|
-
throw new TargetDiscoveryError(`${field} must remain on the target origin`);
|
|
44
|
-
}
|
|
45
|
-
return endpoint.href;
|
|
16
|
+
const DEVICE_GRANT = 'urn:ietf:params:oauth:grant-type:device_code';
|
|
17
|
+
const CAPSULE_AUDIENCE = 'capsule';
|
|
18
|
+
const ROOT_FIELDS = [
|
|
19
|
+
'kind',
|
|
20
|
+
'adapter',
|
|
21
|
+
'protocol',
|
|
22
|
+
'binding',
|
|
23
|
+
'endpoint',
|
|
24
|
+
'pagination',
|
|
25
|
+
'cache_policy',
|
|
26
|
+
'schema_links',
|
|
27
|
+
'capsule_protocol',
|
|
28
|
+
'oauth',
|
|
29
|
+
'organization_binding',
|
|
30
|
+
'capability_flags',
|
|
31
|
+
'sizes',
|
|
32
|
+
'session',
|
|
33
|
+
'transport',
|
|
34
|
+
'extensions',
|
|
35
|
+
];
|
|
36
|
+
async function readBoundedJson(response) {
|
|
37
|
+
return (0, bounded_response_js_1.readBoundedResponseJson)(response, MAX_DISCOVERY_BYTES, (kind) => new discovery_errors_js_1.TargetDiscoveryError(kind === 'size' ? 'response exceeds the size limit' : 'response is not valid UTF-8 JSON'));
|
|
46
38
|
}
|
|
47
39
|
async function fetchDocument(http, url) {
|
|
48
40
|
const response = await http.fetch(url, {
|
|
@@ -50,48 +42,71 @@ async function fetchDocument(http, url) {
|
|
|
50
42
|
headers: { Accept: 'application/json' },
|
|
51
43
|
redirect: 'error',
|
|
52
44
|
});
|
|
45
|
+
if (response.url && new URL(response.url).href !== url) {
|
|
46
|
+
await response.body?.cancel().catch(() => undefined);
|
|
47
|
+
throw new discovery_errors_js_1.TargetDiscoveryError('request changed target route or authority');
|
|
48
|
+
}
|
|
53
49
|
if (!response.ok) {
|
|
54
|
-
|
|
50
|
+
await response.body?.cancel().catch(() => undefined);
|
|
51
|
+
throw new discovery_errors_js_1.TargetDiscoveryError(`request failed with status ${response.status}`);
|
|
55
52
|
}
|
|
56
|
-
|
|
57
|
-
tooLarge: () => new TargetDiscoveryError('response exceeds the size limit'),
|
|
58
|
-
invalid: () => new TargetDiscoveryError('response is not valid JSON'),
|
|
59
|
-
});
|
|
60
|
-
return record(body, 'response');
|
|
53
|
+
return (0, discovery_validation_js_1.record)(await readBoundedJson(response), 'response');
|
|
61
54
|
}
|
|
62
|
-
async function
|
|
55
|
+
async function discoverTarget(targetUrl, http) {
|
|
63
56
|
const target = new URL(targetUrl);
|
|
57
|
+
const origin = target.origin;
|
|
64
58
|
const discovery = await fetchDocument(http, new URL(DISCOVERY_PATH, target).href);
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
const
|
|
79
|
-
const
|
|
80
|
-
const
|
|
81
|
-
const
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
59
|
+
(0, discovery_validation_js_1.exact)(discovery.kind, 'openengine.hosted-target/v1', 'kind');
|
|
60
|
+
const adapter = (0, discovery_sections_js_1.parseAdapter)(discovery);
|
|
61
|
+
const endpoint = (0, discovery_sections_js_1.parseEndpoint)(discovery, origin);
|
|
62
|
+
const capsule = (0, discovery_sections_js_1.parseCapsule)(discovery, origin);
|
|
63
|
+
const oauth = (0, discovery_sections_js_1.parseOAuth)(discovery, origin);
|
|
64
|
+
(0, discovery_validation_js_1.exact)(discovery.organization_binding, 'device_approval', 'organization_binding');
|
|
65
|
+
const capabilityFlags = (0, discovery_validation_js_1.exactStringSet)(discovery.capability_flags, 'capability_flags', [
|
|
66
|
+
'capsule_allocate',
|
|
67
|
+
'capsule_read',
|
|
68
|
+
'capsule_terminate',
|
|
69
|
+
'capsule_access',
|
|
70
|
+
'connections_onboarding',
|
|
71
|
+
]);
|
|
72
|
+
const sizes = (0, discovery_sections_js_1.parseSizes)(discovery);
|
|
73
|
+
const session = (0, discovery_sections_js_1.parseSession)(discovery);
|
|
74
|
+
const transport = (0, discovery_sections_js_1.parseTransport)(discovery);
|
|
75
|
+
const credentialInstall = (0, discovery_sections_js_1.parseExtensions)(discovery, origin);
|
|
76
|
+
const metadata = await fetchDocument(http, oauth.metadataUrl);
|
|
77
|
+
(0, discovery_sections_js_1.validateOAuthMetadata)(metadata, origin, [
|
|
78
|
+
oauth.deviceAuthorizationEndpoint,
|
|
79
|
+
oauth.tokenEndpoint,
|
|
80
|
+
oauth.revocationEndpoint,
|
|
81
|
+
]);
|
|
82
|
+
const additional = Object.freeze(Object.fromEntries(Object.entries(discovery).filter(([key]) => !ROOT_FIELDS.includes(key))));
|
|
83
|
+
return Object.freeze({
|
|
84
|
+
origin,
|
|
85
|
+
adapter,
|
|
86
|
+
endpoint: endpoint.url,
|
|
87
|
+
endpointCapabilities: endpoint.capabilities,
|
|
88
|
+
pagination: endpoint.pagination,
|
|
89
|
+
sizes,
|
|
90
|
+
oauth,
|
|
91
|
+
session,
|
|
92
|
+
capsule,
|
|
93
|
+
transport,
|
|
94
|
+
capabilityFlags,
|
|
95
|
+
credentialInstall,
|
|
96
|
+
additional,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
async function discoverTargetSessionEndpoints(targetUrl, http) {
|
|
100
|
+
const descriptor = await discoverTarget(targetUrl, http);
|
|
101
|
+
return Object.freeze({
|
|
102
|
+
deviceAuthorizationEndpoint: descriptor.oauth.deviceAuthorizationEndpoint,
|
|
103
|
+
tokenEndpoint: descriptor.oauth.tokenEndpoint,
|
|
104
|
+
revocationEndpoint: descriptor.oauth.revocationEndpoint,
|
|
105
|
+
clientId: descriptor.oauth.clientId,
|
|
106
|
+
capsuleApiBaseUrl: descriptor.capsule.baseUrl.replace(/\/$/, ''),
|
|
107
|
+
deviceGrantType: descriptor.oauth.deviceGrantType,
|
|
108
|
+
audience: descriptor.oauth.audience,
|
|
109
|
+
sessionEndpoint: new URL(descriptor.session.routeTemplate.template, descriptor.origin).href,
|
|
110
|
+
descriptor,
|
|
111
|
+
});
|
|
97
112
|
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { readBoundedResponseJson } from './bounded-response.mjs';
|
|
2
|
+
import { TargetDiscoveryError } from './discovery-errors.mjs';
|
|
3
|
+
import { exact, exactStringSet, record, } from './discovery-validation.mjs';
|
|
4
|
+
import { parseAdapter, parseCapsule, parseEndpoint, parseExtensions, parseOAuth, parseSession, parseSizes, parseTransport, validateOAuthMetadata, } from './discovery-sections.mjs';
|
|
5
|
+
export { TargetDiscoveryError } from './discovery-errors.mjs';
|
|
6
|
+
export { expandRoute } from './route-template.mjs';
|
|
7
|
+
const DISCOVERY_PATH = '/.well-known/openengine-hosted-target';
|
|
8
|
+
const MAX_DISCOVERY_BYTES = 64 * 1024;
|
|
9
|
+
const DEVICE_GRANT = 'urn:ietf:params:oauth:grant-type:device_code';
|
|
10
|
+
const CAPSULE_AUDIENCE = 'capsule';
|
|
11
|
+
const ROOT_FIELDS = [
|
|
12
|
+
'kind',
|
|
13
|
+
'adapter',
|
|
14
|
+
'protocol',
|
|
15
|
+
'binding',
|
|
16
|
+
'endpoint',
|
|
17
|
+
'pagination',
|
|
18
|
+
'cache_policy',
|
|
19
|
+
'schema_links',
|
|
20
|
+
'capsule_protocol',
|
|
21
|
+
'oauth',
|
|
22
|
+
'organization_binding',
|
|
23
|
+
'capability_flags',
|
|
24
|
+
'sizes',
|
|
25
|
+
'session',
|
|
26
|
+
'transport',
|
|
27
|
+
'extensions',
|
|
28
|
+
];
|
|
29
|
+
async function readBoundedJson(response) {
|
|
30
|
+
return readBoundedResponseJson(response, MAX_DISCOVERY_BYTES, (kind) => new TargetDiscoveryError(kind === 'size' ? 'response exceeds the size limit' : 'response is not valid UTF-8 JSON'));
|
|
31
|
+
}
|
|
32
|
+
async function fetchDocument(http, url) {
|
|
33
|
+
const response = await http.fetch(url, {
|
|
34
|
+
method: 'GET',
|
|
35
|
+
headers: { Accept: 'application/json' },
|
|
36
|
+
redirect: 'error',
|
|
37
|
+
});
|
|
38
|
+
if (response.url && new URL(response.url).href !== url) {
|
|
39
|
+
await response.body?.cancel().catch(() => undefined);
|
|
40
|
+
throw new TargetDiscoveryError('request changed target route or authority');
|
|
41
|
+
}
|
|
42
|
+
if (!response.ok) {
|
|
43
|
+
await response.body?.cancel().catch(() => undefined);
|
|
44
|
+
throw new TargetDiscoveryError(`request failed with status ${response.status}`);
|
|
45
|
+
}
|
|
46
|
+
return record(await readBoundedJson(response), 'response');
|
|
47
|
+
}
|
|
48
|
+
export async function discoverTarget(targetUrl, http) {
|
|
49
|
+
const target = new URL(targetUrl);
|
|
50
|
+
const origin = target.origin;
|
|
51
|
+
const discovery = await fetchDocument(http, new URL(DISCOVERY_PATH, target).href);
|
|
52
|
+
exact(discovery.kind, 'openengine.hosted-target/v1', 'kind');
|
|
53
|
+
const adapter = parseAdapter(discovery);
|
|
54
|
+
const endpoint = parseEndpoint(discovery, origin);
|
|
55
|
+
const capsule = parseCapsule(discovery, origin);
|
|
56
|
+
const oauth = parseOAuth(discovery, origin);
|
|
57
|
+
exact(discovery.organization_binding, 'device_approval', 'organization_binding');
|
|
58
|
+
const capabilityFlags = exactStringSet(discovery.capability_flags, 'capability_flags', [
|
|
59
|
+
'capsule_allocate',
|
|
60
|
+
'capsule_read',
|
|
61
|
+
'capsule_terminate',
|
|
62
|
+
'capsule_access',
|
|
63
|
+
'connections_onboarding',
|
|
64
|
+
]);
|
|
65
|
+
const sizes = parseSizes(discovery);
|
|
66
|
+
const session = parseSession(discovery);
|
|
67
|
+
const transport = parseTransport(discovery);
|
|
68
|
+
const credentialInstall = parseExtensions(discovery, origin);
|
|
69
|
+
const metadata = await fetchDocument(http, oauth.metadataUrl);
|
|
70
|
+
validateOAuthMetadata(metadata, origin, [
|
|
71
|
+
oauth.deviceAuthorizationEndpoint,
|
|
72
|
+
oauth.tokenEndpoint,
|
|
73
|
+
oauth.revocationEndpoint,
|
|
74
|
+
]);
|
|
75
|
+
const additional = Object.freeze(Object.fromEntries(Object.entries(discovery).filter(([key]) => !ROOT_FIELDS.includes(key))));
|
|
76
|
+
return Object.freeze({
|
|
77
|
+
origin,
|
|
78
|
+
adapter,
|
|
79
|
+
endpoint: endpoint.url,
|
|
80
|
+
endpointCapabilities: endpoint.capabilities,
|
|
81
|
+
pagination: endpoint.pagination,
|
|
82
|
+
sizes,
|
|
83
|
+
oauth,
|
|
84
|
+
session,
|
|
85
|
+
capsule,
|
|
86
|
+
transport,
|
|
87
|
+
capabilityFlags,
|
|
88
|
+
credentialInstall,
|
|
89
|
+
additional,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
export async function discoverTargetSessionEndpoints(targetUrl, http) {
|
|
93
|
+
const descriptor = await discoverTarget(targetUrl, http);
|
|
94
|
+
return Object.freeze({
|
|
95
|
+
deviceAuthorizationEndpoint: descriptor.oauth.deviceAuthorizationEndpoint,
|
|
96
|
+
tokenEndpoint: descriptor.oauth.tokenEndpoint,
|
|
97
|
+
revocationEndpoint: descriptor.oauth.revocationEndpoint,
|
|
98
|
+
clientId: descriptor.oauth.clientId,
|
|
99
|
+
capsuleApiBaseUrl: descriptor.capsule.baseUrl.replace(/\/$/, ''),
|
|
100
|
+
deviceGrantType: descriptor.oauth.deviceGrantType,
|
|
101
|
+
audience: descriptor.oauth.audience,
|
|
102
|
+
sessionEndpoint: new URL(descriptor.session.routeTemplate.template, descriptor.origin).href,
|
|
103
|
+
descriptor,
|
|
104
|
+
});
|
|
105
|
+
}
|
package/lib/target/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { CredentialStoreUnavailableError, KeyringCredentialStore, FakeCredentialStore, targetServiceKey, TARGET_ACCOUNT, type TargetCredentialStore, } from './credential-store.
|
|
2
|
-
export { acquireTargetLock } from './credential-lock.
|
|
3
|
-
export { requestDeviceCode, pollForToken, DeviceFlowDeniedError, DeviceFlowExpiredError, UnboundSessionError, type DeviceCodeResponse, type TokenResponse, type HttpTransport, type Clock, } from './device-flow.
|
|
4
|
-
export { addTarget, removeTarget, getTarget, listTargets, updateTargetOrganization, validateTargetName, normalizeAndValidateUrl, TargetNameInvalidError, TargetNameExistsError, TargetNotFoundError, TargetUrlInvalidError, type TargetRecord, type SettingsPort, } from './target-registry.
|
|
5
|
-
export {
|
|
6
|
-
export { discoverTargetSessionEndpoints, TargetDiscoveryError, type TargetSessionEndpoints, } from './discovery.
|
|
1
|
+
export { CredentialStoreUnavailableError, KeyringCredentialStore, FakeCredentialStore, targetServiceKey, TARGET_ACCOUNT, type TargetCredentialStore, } from './credential-store.js';
|
|
2
|
+
export { acquireTargetLock } from './credential-lock.js';
|
|
3
|
+
export { requestDeviceCode, pollForToken, parseTokenResponse, DeviceFlowDeniedError, DeviceFlowExpiredError, UnboundSessionError, type DeviceCodeResponse, type DeviceExchangeContext, type TokenResponse, type HttpTransport, type Clock, } from './device-flow.js';
|
|
4
|
+
export { addTarget, removeTarget, getTarget, listTargets, updateTargetOrganization, validateTargetName, normalizeAndValidateUrl, TargetNameInvalidError, TargetNameExistsError, TargetNotFoundError, TargetUrlInvalidError, type TargetRecord, type SettingsPort, } from './target-registry.js';
|
|
5
|
+
export { TargetSessionManager, LoginRequiredError, type BrowserOpener, type TargetSessionDeps, type TargetSessionManagerInit, } from './target-session.js';
|
|
6
|
+
export { discoverTarget, discoverTargetSessionEndpoints, expandRoute, TargetDiscoveryError, type CredentialInstallDescriptor, type RouteTemplate, type TargetDiscoveryDescriptor, type TargetSessionEndpoints, } from './discovery.js';
|