@poe-platform/safe-js 0.1.808 → 0.1.812
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/dist/safe-js/chunks/{chunk-E7V44LSN.js → chunk-5KAVJF3R.js} +111 -45
- package/dist/safe-js/chunks/{chunk-7RGEML7S.js → chunk-EUKAVPB5.js} +1 -1
- package/dist/safe-js/chunks/{cli-runtime-EV4DQ7UW.js → cli-runtime-UC3OADSS.js} +2 -2
- package/dist/safe-js/chunks/{mcp-DSJET2K4.js → mcp-IOBUSD2E.js} +2 -2
- package/dist/safe-js/cli.js +2 -2
- package/dist/safe-js/index.js +2 -2
- package/dist/safe-js/workerd.js +92 -40
- package/package.json +2 -2
|
@@ -5145,11 +5145,25 @@ function normalizeBearerTokenType(value) {
|
|
|
5145
5145
|
|
|
5146
5146
|
// packages/mcp-oauth/src/client/register-client.ts
|
|
5147
5147
|
async function registerOAuthClient(input) {
|
|
5148
|
-
if (
|
|
5149
|
-
|
|
5148
|
+
if (input.redirectUri !== void 0 && input.redirectUris !== void 0)
|
|
5149
|
+
throw new Error("Specify either redirectUri or redirectUris, not both");
|
|
5150
|
+
const redirects = input.redirectUris === void 0 ? [input.redirectUri] : input.redirectUris;
|
|
5151
|
+
if (!Array.isArray(redirects) || redirects.length === 0 || redirects.length > 32)
|
|
5152
|
+
throw new Error("OAuth registration requires one to 32 redirect URIs");
|
|
5153
|
+
const redirectUris = [];
|
|
5154
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5155
|
+
for (const redirectUri of redirects) {
|
|
5156
|
+
if (typeof redirectUri !== "string" || redirectUri.length === 0)
|
|
5157
|
+
throw new Error("Invalid OAuth registration redirect URI");
|
|
5158
|
+
if (seen.has(redirectUri)) throw new Error("Duplicate OAuth registration redirect URI");
|
|
5159
|
+
if (new URL(redirectUri).protocol === "https:") validateHostedOAuthRedirect(redirectUri);
|
|
5160
|
+
else loopbackTarget({ redirectUri });
|
|
5161
|
+
seen.add(redirectUri);
|
|
5162
|
+
redirectUris.push(redirectUri);
|
|
5163
|
+
}
|
|
5150
5164
|
const body = JSON.stringify(buildClientRegistrationBody(
|
|
5151
5165
|
input.metadata,
|
|
5152
|
-
|
|
5166
|
+
redirectUris,
|
|
5153
5167
|
normalizeOAuthTokenEndpointAuthMethod(input.tokenEndpointAuthMethod) ?? "none"
|
|
5154
5168
|
));
|
|
5155
5169
|
if (new TextEncoder().encode(body).byteLength > 65536) throw new Error("OAuth registration request is too large");
|
|
@@ -5168,9 +5182,9 @@ function getOwnString2(input, key2) {
|
|
|
5168
5182
|
const descriptor = Object.getOwnPropertyDescriptor(input, key2);
|
|
5169
5183
|
return descriptor !== void 0 && "value" in descriptor && typeof descriptor.value === "string" ? descriptor.value : void 0;
|
|
5170
5184
|
}
|
|
5171
|
-
function buildClientRegistrationBody(metadata,
|
|
5185
|
+
function buildClientRegistrationBody(metadata, redirectUris, tokenEndpointAuthMethod) {
|
|
5172
5186
|
const body = {
|
|
5173
|
-
redirect_uris:
|
|
5187
|
+
redirect_uris: redirectUris,
|
|
5174
5188
|
grant_types: ["authorization_code", "refresh_token"],
|
|
5175
5189
|
response_types: ["code"],
|
|
5176
5190
|
token_endpoint_auth_method: tokenEndpointAuthMethod
|
|
@@ -6576,19 +6590,38 @@ function createParameterHeaders(definitions, argumentsValue) {
|
|
|
6576
6590
|
// packages/tiny-mcp-client/src/oauth-discovery.ts
|
|
6577
6591
|
var metadataErrorBrand = /* @__PURE__ */ Symbol.for("poe-platform.tiny-mcp-client.OAuthMetadataError");
|
|
6578
6592
|
var OAuthMetadataError = class extends Error {
|
|
6579
|
-
constructor(phase, message, status) {
|
|
6593
|
+
constructor(phase, message, status, reason = status === void 0 ? "invalid-metadata" : "http-error", failures = []) {
|
|
6580
6594
|
super(message);
|
|
6581
6595
|
this.phase = phase;
|
|
6582
6596
|
this.status = status;
|
|
6597
|
+
this.reason = reason;
|
|
6598
|
+
this.failures = failures;
|
|
6583
6599
|
this.name = "OAuthMetadataError";
|
|
6600
|
+
this.category = reason === "invalid-json" ? "json" : reason === "http-error" ? "http" : reason === "network-error" ? "network" : "validation";
|
|
6584
6601
|
Object.defineProperty(this, metadataErrorBrand, { value: true });
|
|
6585
6602
|
}
|
|
6586
6603
|
phase;
|
|
6587
6604
|
status;
|
|
6605
|
+
reason;
|
|
6606
|
+
failures;
|
|
6588
6607
|
static is(value) {
|
|
6589
6608
|
return value instanceof Error && Object.getOwnPropertyDescriptor(value, metadataErrorBrand)?.value === true;
|
|
6590
6609
|
}
|
|
6610
|
+
category;
|
|
6591
6611
|
};
|
|
6612
|
+
function metadataFailure(error, phase, reason) {
|
|
6613
|
+
return OAuthMetadataError.is(error) ? error : new OAuthMetadataError(
|
|
6614
|
+
phase,
|
|
6615
|
+
error instanceof Error ? error.message : String(error),
|
|
6616
|
+
void 0,
|
|
6617
|
+
reason
|
|
6618
|
+
);
|
|
6619
|
+
}
|
|
6620
|
+
function aggregateMetadataFailures(phase, errors2, message) {
|
|
6621
|
+
const primary = errors2.find((error) => error.category === "validation") ?? errors2[0];
|
|
6622
|
+
const failures = errors2.map(({ phase: phase2, category, reason, status }) => Object.freeze({ phase: phase2, category, reason, status }));
|
|
6623
|
+
return new OAuthMetadataError(phase, message, primary.status, primary.reason, Object.freeze(failures));
|
|
6624
|
+
}
|
|
6592
6625
|
function defaultOAuthMetadataFetch(input, init) {
|
|
6593
6626
|
return fetch(input, init);
|
|
6594
6627
|
}
|
|
@@ -6654,14 +6687,16 @@ function validateAuthorizationServerMetadata(value, issuer) {
|
|
|
6654
6687
|
if (value.issuer !== issuer) {
|
|
6655
6688
|
throw new OAuthMetadataError(
|
|
6656
6689
|
"authorization-server",
|
|
6657
|
-
`Authorization server metadata issuer mismatch: expected ${issuer}, received ${value.issuer}
|
|
6690
|
+
`Authorization server metadata issuer mismatch: expected ${issuer}, received ${value.issuer}`,
|
|
6691
|
+
void 0,
|
|
6692
|
+
"issuer-mismatch"
|
|
6658
6693
|
);
|
|
6659
6694
|
}
|
|
6660
6695
|
if (typeof value.authorization_endpoint !== "string" || value.authorization_endpoint.length === 0) {
|
|
6661
|
-
throw new
|
|
6696
|
+
throw new OAuthMetadataError("authorization-server", "Authorization server metadata must include authorization_endpoint", void 0, "invalid-endpoint");
|
|
6662
6697
|
}
|
|
6663
6698
|
if (typeof value.token_endpoint !== "string" || value.token_endpoint.length === 0) {
|
|
6664
|
-
throw new
|
|
6699
|
+
throw new OAuthMetadataError("authorization-server", "Authorization server metadata must include token_endpoint", void 0, "invalid-endpoint");
|
|
6665
6700
|
}
|
|
6666
6701
|
for (const field of ["authorization_endpoint", "token_endpoint", "registration_endpoint"]) {
|
|
6667
6702
|
if (field === "registration_endpoint" && value[field] === void 0) {
|
|
@@ -6673,19 +6708,25 @@ function validateAuthorizationServerMetadata(value, issuer) {
|
|
|
6673
6708
|
throw new Error();
|
|
6674
6709
|
}
|
|
6675
6710
|
endpoint = new URL(value[field]);
|
|
6676
|
-
|
|
6677
|
-
|
|
6711
|
+
assertSecureUrl2(endpoint, `Authorization server metadata ${field}`);
|
|
6712
|
+
} catch (error) {
|
|
6713
|
+
throw new OAuthMetadataError("authorization-server", `Authorization server metadata ${field} must be an absolute URL: ${error instanceof Error ? error.message : "invalid URL"}`, void 0, "invalid-endpoint");
|
|
6678
6714
|
}
|
|
6679
|
-
assertSecureUrl2(endpoint, `Authorization server metadata ${field}`);
|
|
6680
6715
|
}
|
|
6681
6716
|
if (!isStringArray(value.response_types_supported) || !value.response_types_supported.includes("code")) {
|
|
6682
|
-
throw new
|
|
6683
|
-
"
|
|
6717
|
+
throw new OAuthMetadataError(
|
|
6718
|
+
"authorization-server",
|
|
6719
|
+
"Authorization server metadata must include response_types_supported containing code",
|
|
6720
|
+
void 0,
|
|
6721
|
+
"response-type-unsupported"
|
|
6684
6722
|
);
|
|
6685
6723
|
}
|
|
6686
6724
|
if (!isStringArray(value.code_challenge_methods_supported) || !value.code_challenge_methods_supported.includes("S256")) {
|
|
6687
|
-
throw new
|
|
6688
|
-
"
|
|
6725
|
+
throw new OAuthMetadataError(
|
|
6726
|
+
"authorization-server",
|
|
6727
|
+
"Authorization server metadata must include code_challenge_methods_supported containing S256",
|
|
6728
|
+
void 0,
|
|
6729
|
+
"pkce-unsupported"
|
|
6689
6730
|
);
|
|
6690
6731
|
}
|
|
6691
6732
|
return value;
|
|
@@ -6701,19 +6742,24 @@ async function readJsonResponse(response, phase, signal) {
|
|
|
6701
6742
|
try {
|
|
6702
6743
|
return JSON.parse(text);
|
|
6703
6744
|
} catch {
|
|
6704
|
-
throw new
|
|
6745
|
+
throw new OAuthMetadataError(phase, `${label} response must be valid JSON`, void 0, "invalid-json");
|
|
6705
6746
|
}
|
|
6706
6747
|
}
|
|
6707
6748
|
async function fetchMetadata(fetch2, location, phase, parentSignal) {
|
|
6708
6749
|
parentSignal?.throwIfAborted();
|
|
6709
6750
|
const deadline = AbortSignal.timeout(1e4);
|
|
6710
6751
|
const signal = parentSignal === void 0 ? deadline : AbortSignal.any([deadline, parentSignal]);
|
|
6711
|
-
|
|
6712
|
-
|
|
6713
|
-
|
|
6714
|
-
|
|
6715
|
-
|
|
6716
|
-
|
|
6752
|
+
try {
|
|
6753
|
+
const response = await fetchMcpResponse(fetch2, location, {
|
|
6754
|
+
method: "GET",
|
|
6755
|
+
headers: { Accept: "application/json" },
|
|
6756
|
+
signal
|
|
6757
|
+
});
|
|
6758
|
+
return await readJsonResponse(response, phase, signal);
|
|
6759
|
+
} catch (error) {
|
|
6760
|
+
parentSignal?.throwIfAborted();
|
|
6761
|
+
throw metadataFailure(error, phase, "network-error");
|
|
6762
|
+
}
|
|
6717
6763
|
}
|
|
6718
6764
|
function resolveWellKnownMetadataUrl(inputUrl, suffix) {
|
|
6719
6765
|
const url = new URL(typeof inputUrl === "string" ? inputUrl : inputUrl.toString());
|
|
@@ -6823,7 +6869,7 @@ var OAuthMetadataDiscovery = class {
|
|
|
6823
6869
|
if (resourceMetadataUrl === void 0) {
|
|
6824
6870
|
locations.add(new URL("/.well-known/oauth-protected-resource", resource).toString());
|
|
6825
6871
|
}
|
|
6826
|
-
|
|
6872
|
+
const errors2 = [];
|
|
6827
6873
|
for (const location of locations) {
|
|
6828
6874
|
try {
|
|
6829
6875
|
const metadata = validateProtectedResourceMetadata(
|
|
@@ -6833,17 +6879,18 @@ var OAuthMetadataDiscovery = class {
|
|
|
6833
6879
|
return { location, metadata };
|
|
6834
6880
|
} catch (error) {
|
|
6835
6881
|
signal?.throwIfAborted();
|
|
6836
|
-
|
|
6882
|
+
errors2.push(metadataFailure(error, "protected-resource", "invalid-metadata"));
|
|
6837
6883
|
}
|
|
6838
6884
|
}
|
|
6839
|
-
throw
|
|
6885
|
+
throw aggregateMetadataFailures("protected-resource", errors2, errors2.at(-1).message);
|
|
6840
6886
|
}
|
|
6841
|
-
async discover(resourceUrl, { resourceMetadataUrl, signal } = {}) {
|
|
6887
|
+
async discover(resourceUrl, { resourceMetadataUrl, signal, expectedIssuer } = {}) {
|
|
6842
6888
|
signal?.throwIfAborted();
|
|
6889
|
+
if (expectedIssuer !== void 0) validateAuthorizationServerIssuer(expectedIssuer);
|
|
6843
6890
|
const cacheKey = canonicalizeResourceIndicator(resourceUrl);
|
|
6844
6891
|
resolveProtectedResourceMetadataUrl(resourceUrl, resourceMetadataUrl);
|
|
6845
6892
|
const memoryCachedResult = this.memoryCache.get(cacheKey);
|
|
6846
|
-
if (memoryCachedResult !== void 0 && resourceMetadataUrl === void 0) {
|
|
6893
|
+
if (memoryCachedResult !== void 0 && resourceMetadataUrl === void 0 && (expectedIssuer === void 0 || memoryCachedResult.authorizationServer === expectedIssuer)) {
|
|
6847
6894
|
return structuredClone(memoryCachedResult);
|
|
6848
6895
|
}
|
|
6849
6896
|
const sharedCachedResult = resourceMetadataUrl === void 0 ? await waitForCache(this.cache?.get(cacheKey), signal) : void 0;
|
|
@@ -6851,44 +6898,63 @@ var OAuthMetadataDiscovery = class {
|
|
|
6851
6898
|
if (sharedCachedResult !== null && sharedCachedResult !== void 0 && resourceMetadataUrl === void 0) {
|
|
6852
6899
|
try {
|
|
6853
6900
|
const result = validateCachedDiscovery(sharedCachedResult, cacheKey);
|
|
6854
|
-
|
|
6855
|
-
|
|
6901
|
+
if (expectedIssuer === void 0 || result.authorizationServer === expectedIssuer) {
|
|
6902
|
+
this.memoryCache.set(cacheKey, structuredClone(result));
|
|
6903
|
+
return result;
|
|
6904
|
+
}
|
|
6856
6905
|
} catch {
|
|
6857
6906
|
await waitForCache(this.cache?.delete?.(cacheKey), signal);
|
|
6858
6907
|
}
|
|
6859
6908
|
}
|
|
6860
6909
|
const { location: resourceMetadataLocation, metadata: resourceMetadata } = await this.discoverProtectedResource(cacheKey, resourceMetadataUrl, signal);
|
|
6861
6910
|
const authorizationServerErrors = [];
|
|
6862
|
-
|
|
6863
|
-
|
|
6911
|
+
const failures = [];
|
|
6912
|
+
if (expectedIssuer !== void 0 && !resourceMetadata.authorization_servers.includes(expectedIssuer)) {
|
|
6913
|
+
throw new OAuthMetadataError("authorization-server", "Expected issuer was not advertised by the protected resource", void 0, "issuer-mismatch");
|
|
6914
|
+
}
|
|
6915
|
+
const authorizationServers = expectedIssuer === void 0 ? resourceMetadata.authorization_servers : [expectedIssuer];
|
|
6916
|
+
for (const authorizationServer of authorizationServers) {
|
|
6917
|
+
let normalizedAuthorizationServer;
|
|
6918
|
+
try {
|
|
6919
|
+
normalizedAuthorizationServer = validateAuthorizationServerIssuer(authorizationServer);
|
|
6920
|
+
} catch (error) {
|
|
6921
|
+
const failure = metadataFailure(error, "authorization-server", "invalid-metadata");
|
|
6922
|
+
failures.push(failure);
|
|
6923
|
+
authorizationServerErrors.push(failure.message);
|
|
6924
|
+
continue;
|
|
6925
|
+
}
|
|
6864
6926
|
const metadataLocations = authorizationServerMetadataLocations(normalizedAuthorizationServer);
|
|
6865
6927
|
for (const authorizationServerMetadataUrl of metadataLocations) {
|
|
6928
|
+
let authorizationServerMetadata;
|
|
6866
6929
|
try {
|
|
6867
|
-
|
|
6930
|
+
authorizationServerMetadata = validateAuthorizationServerMetadata(
|
|
6868
6931
|
await fetchMetadata(this.fetchImpl, authorizationServerMetadataUrl, "authorization-server", signal),
|
|
6869
6932
|
normalizedAuthorizationServer
|
|
6870
6933
|
);
|
|
6871
|
-
const result = {
|
|
6872
|
-
resource: resourceMetadata.resource,
|
|
6873
|
-
resourceMetadataUrl: resourceMetadataLocation,
|
|
6874
|
-
resourceMetadata,
|
|
6875
|
-
authorizationServer: normalizedAuthorizationServer,
|
|
6876
|
-
authorizationServerMetadataUrl,
|
|
6877
|
-
authorizationServerMetadata
|
|
6878
|
-
};
|
|
6879
|
-
this.memoryCache.set(cacheKey, structuredClone(result));
|
|
6880
|
-
await waitForCache(this.cache?.set(cacheKey, structuredClone(result)), signal);
|
|
6881
|
-
return result;
|
|
6882
6934
|
} catch (error) {
|
|
6883
6935
|
signal?.throwIfAborted();
|
|
6936
|
+
failures.push(metadataFailure(error, "authorization-server", "invalid-metadata"));
|
|
6884
6937
|
authorizationServerErrors.push(
|
|
6885
6938
|
`${authorizationServerMetadataUrl}: ${error instanceof Error ? error.message : String(error)}`
|
|
6886
6939
|
);
|
|
6940
|
+
continue;
|
|
6887
6941
|
}
|
|
6942
|
+
const result = {
|
|
6943
|
+
resource: resourceMetadata.resource,
|
|
6944
|
+
resourceMetadataUrl: resourceMetadataLocation,
|
|
6945
|
+
resourceMetadata,
|
|
6946
|
+
authorizationServer: normalizedAuthorizationServer,
|
|
6947
|
+
authorizationServerMetadataUrl,
|
|
6948
|
+
authorizationServerMetadata
|
|
6949
|
+
};
|
|
6950
|
+
await waitForCache(this.cache?.set(cacheKey, structuredClone(result)), signal);
|
|
6951
|
+
this.memoryCache.set(cacheKey, structuredClone(result));
|
|
6952
|
+
return result;
|
|
6888
6953
|
}
|
|
6889
6954
|
}
|
|
6890
|
-
throw
|
|
6955
|
+
throw aggregateMetadataFailures(
|
|
6891
6956
|
"authorization-server",
|
|
6957
|
+
failures,
|
|
6892
6958
|
`Unable to load authorization server metadata for ${cacheKey}: ${authorizationServerErrors.join(
|
|
6893
6959
|
"; "
|
|
6894
6960
|
)}`
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
} from "./chunk-XQOJJA4C.js";
|
|
9
9
|
import {
|
|
10
10
|
parseMcpConfig
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-5KAVJF3R.js";
|
|
12
12
|
import {
|
|
13
13
|
lint,
|
|
14
14
|
makeEnvModule,
|
|
@@ -296,7 +296,7 @@ async function runScriptFile(filepath, parsed, options) {
|
|
|
296
296
|
import("./dump-OX7M4C56.js"),
|
|
297
297
|
import("./runtime-modules-UOVJSSD7.js"),
|
|
298
298
|
import("../modules/fs.js"),
|
|
299
|
-
import("./mcp-
|
|
299
|
+
import("./mcp-IOBUSD2E.js")
|
|
300
300
|
]);
|
|
301
301
|
const loaded = loadExecutableSource(filepath, await options.readFile(filepath, "utf8"));
|
|
302
302
|
const meta = {
|
package/dist/safe-js/cli.js
CHANGED
|
@@ -13,7 +13,7 @@ import { createHostFileSystem } from "@poe-platform/safe-fs/node";
|
|
|
13
13
|
import { fileURLToPath } from "node:url";
|
|
14
14
|
async function runCli(argv, options = {}) {
|
|
15
15
|
if (!argv.includes("--help") && !argv.includes("-h")) {
|
|
16
|
-
const runtime = await import("./chunks/cli-runtime-
|
|
16
|
+
const runtime = await import("./chunks/cli-runtime-UC3OADSS.js");
|
|
17
17
|
return runtime.runCli(argv, options, createUsage());
|
|
18
18
|
}
|
|
19
19
|
const brokenPipe = createBrokenPipeState();
|
|
@@ -32,7 +32,7 @@ async function runCli(argv, options = {}) {
|
|
|
32
32
|
stderr.write(`${error instanceof Error ? error.message : String(error)}
|
|
33
33
|
`);
|
|
34
34
|
if (brokenPipe.closed) return 0;
|
|
35
|
-
const { exitCodeForError } = await import("./chunks/cli-runtime-
|
|
35
|
+
const { exitCodeForError } = await import("./chunks/cli-runtime-UC3OADSS.js");
|
|
36
36
|
return exitCodeForError(error);
|
|
37
37
|
}
|
|
38
38
|
}
|
package/dist/safe-js/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
} from "./chunks/chunk-425IYA26.js";
|
|
9
9
|
import {
|
|
10
10
|
makeMcpModule
|
|
11
|
-
} from "./chunks/chunk-
|
|
11
|
+
} from "./chunks/chunk-EUKAVPB5.js";
|
|
12
12
|
import {
|
|
13
13
|
AgentSpawnError,
|
|
14
14
|
SPAWN_MODES,
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
} from "./chunks/chunk-XQOJJA4C.js";
|
|
25
25
|
import {
|
|
26
26
|
parseMcpConfig
|
|
27
|
-
} from "./chunks/chunk-
|
|
27
|
+
} from "./chunks/chunk-5KAVJF3R.js";
|
|
28
28
|
import {
|
|
29
29
|
captureHostContext,
|
|
30
30
|
deepCopyFromSandbox,
|
package/dist/safe-js/workerd.js
CHANGED
|
@@ -81716,19 +81716,38 @@ function createParameterHeaders(definitions2, argumentsValue) {
|
|
|
81716
81716
|
// packages/tiny-mcp-client/src/oauth-discovery.ts
|
|
81717
81717
|
var metadataErrorBrand = /* @__PURE__ */ Symbol.for("poe-platform.tiny-mcp-client.OAuthMetadataError");
|
|
81718
81718
|
var OAuthMetadataError = class extends Error {
|
|
81719
|
-
constructor(phase, message, status) {
|
|
81719
|
+
constructor(phase, message, status, reason = status === void 0 ? "invalid-metadata" : "http-error", failures = []) {
|
|
81720
81720
|
super(message);
|
|
81721
81721
|
this.phase = phase;
|
|
81722
81722
|
this.status = status;
|
|
81723
|
+
this.reason = reason;
|
|
81724
|
+
this.failures = failures;
|
|
81723
81725
|
this.name = "OAuthMetadataError";
|
|
81726
|
+
this.category = reason === "invalid-json" ? "json" : reason === "http-error" ? "http" : reason === "network-error" ? "network" : "validation";
|
|
81724
81727
|
Object.defineProperty(this, metadataErrorBrand, { value: true });
|
|
81725
81728
|
}
|
|
81726
81729
|
phase;
|
|
81727
81730
|
status;
|
|
81731
|
+
reason;
|
|
81732
|
+
failures;
|
|
81728
81733
|
static is(value) {
|
|
81729
81734
|
return value instanceof Error && Object.getOwnPropertyDescriptor(value, metadataErrorBrand)?.value === true;
|
|
81730
81735
|
}
|
|
81736
|
+
category;
|
|
81731
81737
|
};
|
|
81738
|
+
function metadataFailure(error, phase, reason) {
|
|
81739
|
+
return OAuthMetadataError.is(error) ? error : new OAuthMetadataError(
|
|
81740
|
+
phase,
|
|
81741
|
+
error instanceof Error ? error.message : String(error),
|
|
81742
|
+
void 0,
|
|
81743
|
+
reason
|
|
81744
|
+
);
|
|
81745
|
+
}
|
|
81746
|
+
function aggregateMetadataFailures(phase, errors, message) {
|
|
81747
|
+
const primary = errors.find((error) => error.category === "validation") ?? errors[0];
|
|
81748
|
+
const failures = errors.map(({ phase: phase2, category, reason, status }) => Object.freeze({ phase: phase2, category, reason, status }));
|
|
81749
|
+
return new OAuthMetadataError(phase, message, primary.status, primary.reason, Object.freeze(failures));
|
|
81750
|
+
}
|
|
81732
81751
|
function defaultOAuthMetadataFetch(input, init) {
|
|
81733
81752
|
return fetch(input, init);
|
|
81734
81753
|
}
|
|
@@ -81794,14 +81813,16 @@ function validateAuthorizationServerMetadata(value, issuer) {
|
|
|
81794
81813
|
if (value.issuer !== issuer) {
|
|
81795
81814
|
throw new OAuthMetadataError(
|
|
81796
81815
|
"authorization-server",
|
|
81797
|
-
`Authorization server metadata issuer mismatch: expected ${issuer}, received ${value.issuer}
|
|
81816
|
+
`Authorization server metadata issuer mismatch: expected ${issuer}, received ${value.issuer}`,
|
|
81817
|
+
void 0,
|
|
81818
|
+
"issuer-mismatch"
|
|
81798
81819
|
);
|
|
81799
81820
|
}
|
|
81800
81821
|
if (typeof value.authorization_endpoint !== "string" || value.authorization_endpoint.length === 0) {
|
|
81801
|
-
throw new
|
|
81822
|
+
throw new OAuthMetadataError("authorization-server", "Authorization server metadata must include authorization_endpoint", void 0, "invalid-endpoint");
|
|
81802
81823
|
}
|
|
81803
81824
|
if (typeof value.token_endpoint !== "string" || value.token_endpoint.length === 0) {
|
|
81804
|
-
throw new
|
|
81825
|
+
throw new OAuthMetadataError("authorization-server", "Authorization server metadata must include token_endpoint", void 0, "invalid-endpoint");
|
|
81805
81826
|
}
|
|
81806
81827
|
for (const field of ["authorization_endpoint", "token_endpoint", "registration_endpoint"]) {
|
|
81807
81828
|
if (field === "registration_endpoint" && value[field] === void 0) {
|
|
@@ -81813,19 +81834,25 @@ function validateAuthorizationServerMetadata(value, issuer) {
|
|
|
81813
81834
|
throw new Error();
|
|
81814
81835
|
}
|
|
81815
81836
|
endpoint = new URL(value[field]);
|
|
81816
|
-
|
|
81817
|
-
|
|
81837
|
+
assertSecureUrl(endpoint, `Authorization server metadata ${field}`);
|
|
81838
|
+
} catch (error) {
|
|
81839
|
+
throw new OAuthMetadataError("authorization-server", `Authorization server metadata ${field} must be an absolute URL: ${error instanceof Error ? error.message : "invalid URL"}`, void 0, "invalid-endpoint");
|
|
81818
81840
|
}
|
|
81819
|
-
assertSecureUrl(endpoint, `Authorization server metadata ${field}`);
|
|
81820
81841
|
}
|
|
81821
81842
|
if (!isStringArray(value.response_types_supported) || !value.response_types_supported.includes("code")) {
|
|
81822
|
-
throw new
|
|
81823
|
-
"
|
|
81843
|
+
throw new OAuthMetadataError(
|
|
81844
|
+
"authorization-server",
|
|
81845
|
+
"Authorization server metadata must include response_types_supported containing code",
|
|
81846
|
+
void 0,
|
|
81847
|
+
"response-type-unsupported"
|
|
81824
81848
|
);
|
|
81825
81849
|
}
|
|
81826
81850
|
if (!isStringArray(value.code_challenge_methods_supported) || !value.code_challenge_methods_supported.includes("S256")) {
|
|
81827
|
-
throw new
|
|
81828
|
-
"
|
|
81851
|
+
throw new OAuthMetadataError(
|
|
81852
|
+
"authorization-server",
|
|
81853
|
+
"Authorization server metadata must include code_challenge_methods_supported containing S256",
|
|
81854
|
+
void 0,
|
|
81855
|
+
"pkce-unsupported"
|
|
81829
81856
|
);
|
|
81830
81857
|
}
|
|
81831
81858
|
return value;
|
|
@@ -81841,19 +81868,24 @@ async function readJsonResponse(response, phase, signal) {
|
|
|
81841
81868
|
try {
|
|
81842
81869
|
return JSON.parse(text);
|
|
81843
81870
|
} catch {
|
|
81844
|
-
throw new
|
|
81871
|
+
throw new OAuthMetadataError(phase, `${label} response must be valid JSON`, void 0, "invalid-json");
|
|
81845
81872
|
}
|
|
81846
81873
|
}
|
|
81847
81874
|
async function fetchMetadata(fetch2, location, phase, parentSignal) {
|
|
81848
81875
|
parentSignal?.throwIfAborted();
|
|
81849
81876
|
const deadline = AbortSignal.timeout(1e4);
|
|
81850
81877
|
const signal = parentSignal === void 0 ? deadline : AbortSignal.any([deadline, parentSignal]);
|
|
81851
|
-
|
|
81852
|
-
|
|
81853
|
-
|
|
81854
|
-
|
|
81855
|
-
|
|
81856
|
-
|
|
81878
|
+
try {
|
|
81879
|
+
const response = await fetchMcpResponse(fetch2, location, {
|
|
81880
|
+
method: "GET",
|
|
81881
|
+
headers: { Accept: "application/json" },
|
|
81882
|
+
signal
|
|
81883
|
+
});
|
|
81884
|
+
return await readJsonResponse(response, phase, signal);
|
|
81885
|
+
} catch (error) {
|
|
81886
|
+
parentSignal?.throwIfAborted();
|
|
81887
|
+
throw metadataFailure(error, phase, "network-error");
|
|
81888
|
+
}
|
|
81857
81889
|
}
|
|
81858
81890
|
function resolveWellKnownMetadataUrl(inputUrl, suffix) {
|
|
81859
81891
|
const url = new URL(typeof inputUrl === "string" ? inputUrl : inputUrl.toString());
|
|
@@ -81963,7 +81995,7 @@ var OAuthMetadataDiscovery = class {
|
|
|
81963
81995
|
if (resourceMetadataUrl === void 0) {
|
|
81964
81996
|
locations.add(new URL("/.well-known/oauth-protected-resource", resource).toString());
|
|
81965
81997
|
}
|
|
81966
|
-
|
|
81998
|
+
const errors = [];
|
|
81967
81999
|
for (const location of locations) {
|
|
81968
82000
|
try {
|
|
81969
82001
|
const metadata = validateProtectedResourceMetadata(
|
|
@@ -81973,17 +82005,18 @@ var OAuthMetadataDiscovery = class {
|
|
|
81973
82005
|
return { location, metadata };
|
|
81974
82006
|
} catch (error) {
|
|
81975
82007
|
signal?.throwIfAborted();
|
|
81976
|
-
|
|
82008
|
+
errors.push(metadataFailure(error, "protected-resource", "invalid-metadata"));
|
|
81977
82009
|
}
|
|
81978
82010
|
}
|
|
81979
|
-
throw
|
|
82011
|
+
throw aggregateMetadataFailures("protected-resource", errors, errors.at(-1).message);
|
|
81980
82012
|
}
|
|
81981
|
-
async discover(resourceUrl, { resourceMetadataUrl, signal } = {}) {
|
|
82013
|
+
async discover(resourceUrl, { resourceMetadataUrl, signal, expectedIssuer } = {}) {
|
|
81982
82014
|
signal?.throwIfAborted();
|
|
82015
|
+
if (expectedIssuer !== void 0) validateAuthorizationServerIssuer(expectedIssuer);
|
|
81983
82016
|
const cacheKey = canonicalizeResourceIndicator(resourceUrl);
|
|
81984
82017
|
resolveProtectedResourceMetadataUrl(resourceUrl, resourceMetadataUrl);
|
|
81985
82018
|
const memoryCachedResult = this.memoryCache.get(cacheKey);
|
|
81986
|
-
if (memoryCachedResult !== void 0 && resourceMetadataUrl === void 0) {
|
|
82019
|
+
if (memoryCachedResult !== void 0 && resourceMetadataUrl === void 0 && (expectedIssuer === void 0 || memoryCachedResult.authorizationServer === expectedIssuer)) {
|
|
81987
82020
|
return structuredClone(memoryCachedResult);
|
|
81988
82021
|
}
|
|
81989
82022
|
const sharedCachedResult = resourceMetadataUrl === void 0 ? await waitForCache(this.cache?.get(cacheKey), signal) : void 0;
|
|
@@ -81991,44 +82024,63 @@ var OAuthMetadataDiscovery = class {
|
|
|
81991
82024
|
if (sharedCachedResult !== null && sharedCachedResult !== void 0 && resourceMetadataUrl === void 0) {
|
|
81992
82025
|
try {
|
|
81993
82026
|
const result = validateCachedDiscovery(sharedCachedResult, cacheKey);
|
|
81994
|
-
|
|
81995
|
-
|
|
82027
|
+
if (expectedIssuer === void 0 || result.authorizationServer === expectedIssuer) {
|
|
82028
|
+
this.memoryCache.set(cacheKey, structuredClone(result));
|
|
82029
|
+
return result;
|
|
82030
|
+
}
|
|
81996
82031
|
} catch {
|
|
81997
82032
|
await waitForCache(this.cache?.delete?.(cacheKey), signal);
|
|
81998
82033
|
}
|
|
81999
82034
|
}
|
|
82000
82035
|
const { location: resourceMetadataLocation, metadata: resourceMetadata } = await this.discoverProtectedResource(cacheKey, resourceMetadataUrl, signal);
|
|
82001
82036
|
const authorizationServerErrors = [];
|
|
82002
|
-
|
|
82003
|
-
|
|
82037
|
+
const failures = [];
|
|
82038
|
+
if (expectedIssuer !== void 0 && !resourceMetadata.authorization_servers.includes(expectedIssuer)) {
|
|
82039
|
+
throw new OAuthMetadataError("authorization-server", "Expected issuer was not advertised by the protected resource", void 0, "issuer-mismatch");
|
|
82040
|
+
}
|
|
82041
|
+
const authorizationServers = expectedIssuer === void 0 ? resourceMetadata.authorization_servers : [expectedIssuer];
|
|
82042
|
+
for (const authorizationServer of authorizationServers) {
|
|
82043
|
+
let normalizedAuthorizationServer;
|
|
82044
|
+
try {
|
|
82045
|
+
normalizedAuthorizationServer = validateAuthorizationServerIssuer(authorizationServer);
|
|
82046
|
+
} catch (error) {
|
|
82047
|
+
const failure = metadataFailure(error, "authorization-server", "invalid-metadata");
|
|
82048
|
+
failures.push(failure);
|
|
82049
|
+
authorizationServerErrors.push(failure.message);
|
|
82050
|
+
continue;
|
|
82051
|
+
}
|
|
82004
82052
|
const metadataLocations = authorizationServerMetadataLocations(normalizedAuthorizationServer);
|
|
82005
82053
|
for (const authorizationServerMetadataUrl of metadataLocations) {
|
|
82054
|
+
let authorizationServerMetadata;
|
|
82006
82055
|
try {
|
|
82007
|
-
|
|
82056
|
+
authorizationServerMetadata = validateAuthorizationServerMetadata(
|
|
82008
82057
|
await fetchMetadata(this.fetchImpl, authorizationServerMetadataUrl, "authorization-server", signal),
|
|
82009
82058
|
normalizedAuthorizationServer
|
|
82010
82059
|
);
|
|
82011
|
-
const result = {
|
|
82012
|
-
resource: resourceMetadata.resource,
|
|
82013
|
-
resourceMetadataUrl: resourceMetadataLocation,
|
|
82014
|
-
resourceMetadata,
|
|
82015
|
-
authorizationServer: normalizedAuthorizationServer,
|
|
82016
|
-
authorizationServerMetadataUrl,
|
|
82017
|
-
authorizationServerMetadata
|
|
82018
|
-
};
|
|
82019
|
-
this.memoryCache.set(cacheKey, structuredClone(result));
|
|
82020
|
-
await waitForCache(this.cache?.set(cacheKey, structuredClone(result)), signal);
|
|
82021
|
-
return result;
|
|
82022
82060
|
} catch (error) {
|
|
82023
82061
|
signal?.throwIfAborted();
|
|
82062
|
+
failures.push(metadataFailure(error, "authorization-server", "invalid-metadata"));
|
|
82024
82063
|
authorizationServerErrors.push(
|
|
82025
82064
|
`${authorizationServerMetadataUrl}: ${error instanceof Error ? error.message : String(error)}`
|
|
82026
82065
|
);
|
|
82066
|
+
continue;
|
|
82027
82067
|
}
|
|
82068
|
+
const result = {
|
|
82069
|
+
resource: resourceMetadata.resource,
|
|
82070
|
+
resourceMetadataUrl: resourceMetadataLocation,
|
|
82071
|
+
resourceMetadata,
|
|
82072
|
+
authorizationServer: normalizedAuthorizationServer,
|
|
82073
|
+
authorizationServerMetadataUrl,
|
|
82074
|
+
authorizationServerMetadata
|
|
82075
|
+
};
|
|
82076
|
+
await waitForCache(this.cache?.set(cacheKey, structuredClone(result)), signal);
|
|
82077
|
+
this.memoryCache.set(cacheKey, structuredClone(result));
|
|
82078
|
+
return result;
|
|
82028
82079
|
}
|
|
82029
82080
|
}
|
|
82030
|
-
throw
|
|
82081
|
+
throw aggregateMetadataFailures(
|
|
82031
82082
|
"authorization-server",
|
|
82083
|
+
failures,
|
|
82032
82084
|
`Unable to load authorization server metadata for ${cacheKey}: ${authorizationServerErrors.join(
|
|
82033
82085
|
"; "
|
|
82034
82086
|
)}`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@poe-platform/safe-js",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.812",
|
|
4
4
|
"description": "Budgeted JavaScript interpreter with explicit host capabilities and resumable execution",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
"access": "public"
|
|
83
83
|
},
|
|
84
84
|
"dependencies": {
|
|
85
|
-
"@poe-platform/safe-fs": "0.1.
|
|
85
|
+
"@poe-platform/safe-fs": "0.1.812",
|
|
86
86
|
"@petamoriken/float16": "^3.9.3",
|
|
87
87
|
"@noble/hashes": "2.4.0",
|
|
88
88
|
"@formatjs/intl-localematcher": "0.8.13",
|