toolcraft 0.0.92 → 0.0.93
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/composition.json +1 -6
- package/dist/composition.json +1 -6
- package/node_modules/@poe-code/agent-defs/package.json +9 -5
- package/node_modules/@poe-code/agent-human-in-loop/package.json +8 -4
- package/node_modules/@poe-code/agent-mcp-config/package.json +8 -4
- package/node_modules/@poe-code/config-mutations/package.json +8 -4
- package/node_modules/@poe-code/frontmatter/package.json +8 -4
- package/node_modules/@poe-code/process-runner/package.json +8 -4
- package/node_modules/@poe-code/task-list/package.json +8 -4
- package/node_modules/auth-store/package.json +3 -4
- package/node_modules/tiny-mcp-client/.turbo/turbo-build.log +1 -1
- package/node_modules/tiny-mcp-client/dist/index.d.ts +660 -2
- package/node_modules/tiny-mcp-client/dist/index.js +3870 -1
- package/node_modules/tiny-mcp-client/package.json +8 -4
- package/node_modules/tiny-mcp-client/scripts/build.mjs +63 -0
- package/node_modules/toolcraft-design/package.json +3 -7
- package/package.json +4 -6
- package/node_modules/mcp-oauth/LICENSE +0 -21
- package/node_modules/mcp-oauth/README.md +0 -31
- package/node_modules/mcp-oauth/dist/client/auth-store-session-store.d.ts +0 -14
- package/node_modules/mcp-oauth/dist/client/auth-store-session-store.js +0 -169
- package/node_modules/mcp-oauth/dist/client/authorization-state.d.ts +0 -8
- package/node_modules/mcp-oauth/dist/client/authorization-state.js +0 -47
- package/node_modules/mcp-oauth/dist/client/default-oauth-client-provider.d.ts +0 -3
- package/node_modules/mcp-oauth/dist/client/default-oauth-client-provider.js +0 -627
- package/node_modules/mcp-oauth/dist/client/loopback-authorization.d.ts +0 -20
- package/node_modules/mcp-oauth/dist/client/loopback-authorization.js +0 -207
- package/node_modules/mcp-oauth/dist/client/pkce.d.ts +0 -2
- package/node_modules/mcp-oauth/dist/client/pkce.js +0 -7
- package/node_modules/mcp-oauth/dist/client/token-endpoint.d.ts +0 -40
- package/node_modules/mcp-oauth/dist/client/token-endpoint.js +0 -164
- package/node_modules/mcp-oauth/dist/client/types.d.ts +0 -113
- package/node_modules/mcp-oauth/dist/client/types.js +0 -1
- package/node_modules/mcp-oauth/dist/index.d.ts +0 -10
- package/node_modules/mcp-oauth/dist/index.js +0 -7
- package/node_modules/mcp-oauth/dist/resource-indicator.d.ts +0 -1
- package/node_modules/mcp-oauth/dist/resource-indicator.js +0 -11
- package/node_modules/mcp-oauth/dist/server/jwks-token-verifier.d.ts +0 -28
- package/node_modules/mcp-oauth/dist/server/jwks-token-verifier.js +0 -304
- package/node_modules/mcp-oauth/dist/types.compile-check.d.ts +0 -1
- package/node_modules/mcp-oauth/dist/types.compile-check.js +0 -22
- package/node_modules/mcp-oauth/package.json +0 -32
- package/node_modules/tiny-mcp-client/dist/internal.d.ts +0 -556
- package/node_modules/tiny-mcp-client/dist/internal.js +0 -2688
- package/node_modules/tiny-mcp-client/dist/jsonrpc-types.compile-check.d.ts +0 -1
- package/node_modules/tiny-mcp-client/dist/jsonrpc-types.compile-check.js +0 -37
- package/node_modules/tiny-mcp-client/dist/mcp-lifecycle-types.compile-check.d.ts +0 -1
- package/node_modules/tiny-mcp-client/dist/mcp-lifecycle-types.compile-check.js +0 -50
- package/node_modules/tiny-mcp-client/dist/mcp-prompt-types.compile-check.d.ts +0 -1
- package/node_modules/tiny-mcp-client/dist/mcp-prompt-types.compile-check.js +0 -50
- package/node_modules/tiny-mcp-client/dist/mcp-resource-types.compile-check.d.ts +0 -1
- package/node_modules/tiny-mcp-client/dist/mcp-resource-types.compile-check.js +0 -51
- package/node_modules/tiny-mcp-client/dist/mcp-tool-types.compile-check.d.ts +0 -1
- package/node_modules/tiny-mcp-client/dist/mcp-tool-types.compile-check.js +0 -99
- package/node_modules/tiny-mcp-client/dist/mcp-transport-types.compile-check.d.ts +0 -1
- package/node_modules/tiny-mcp-client/dist/mcp-transport-types.compile-check.js +0 -56
- package/node_modules/tiny-mcp-client/dist/mcp-utility-types.compile-check.d.ts +0 -1
- package/node_modules/tiny-mcp-client/dist/mcp-utility-types.compile-check.js +0 -145
- package/node_modules/tiny-mcp-client/dist/oauth-discovery.d.ts +0 -24
- package/node_modules/tiny-mcp-client/dist/oauth-discovery.js +0 -382
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
import http from "node:http";
|
|
2
|
-
import { parseAuthorizationState } from "./authorization-state.js";
|
|
3
|
-
export async function createLoopbackAuthorizationSession(options = {}) {
|
|
4
|
-
const callbackPath = options.callbackPath ?? "/callback";
|
|
5
|
-
const server = options.createServer ? options.createServer() : http.createServer();
|
|
6
|
-
const port = await startServer(server);
|
|
7
|
-
const redirectUri = `http://127.0.0.1:${port}${callbackPath}`;
|
|
8
|
-
return {
|
|
9
|
-
redirectUri,
|
|
10
|
-
async waitForCode(authorizationUrl) {
|
|
11
|
-
return waitForAuthorizationCode(server, authorizationUrl, options, callbackPath);
|
|
12
|
-
},
|
|
13
|
-
close() {
|
|
14
|
-
server.closeAllConnections?.();
|
|
15
|
-
server.close();
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
async function startServer(server) {
|
|
20
|
-
return new Promise((resolve, reject) => {
|
|
21
|
-
const handleError = (error) => {
|
|
22
|
-
server.off("error", handleError);
|
|
23
|
-
reject(error);
|
|
24
|
-
};
|
|
25
|
-
server.once("error", handleError);
|
|
26
|
-
server.listen(0, "127.0.0.1", () => {
|
|
27
|
-
server.off("error", handleError);
|
|
28
|
-
const address = server.address();
|
|
29
|
-
resolve(address.port);
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
function waitForAuthorizationCode(server, authorizationUrl, options, callbackPath) {
|
|
34
|
-
const expectedAuthorization = readExpectedAuthorizationCallback(authorizationUrl);
|
|
35
|
-
return new Promise((resolve, reject) => {
|
|
36
|
-
let settled = false;
|
|
37
|
-
const settle = (fn) => {
|
|
38
|
-
if (!settled) {
|
|
39
|
-
settled = true;
|
|
40
|
-
fn();
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
server.on("request", (req, res) => {
|
|
44
|
-
const url = new URL(req.url ?? "/", "http://127.0.0.1");
|
|
45
|
-
if (url.pathname !== callbackPath) {
|
|
46
|
-
res.writeHead(404);
|
|
47
|
-
res.end("Not found");
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
const callbackParameters = {
|
|
51
|
-
code: url.searchParams.get("code"),
|
|
52
|
-
error: url.searchParams.get("error"),
|
|
53
|
-
errorDescription: url.searchParams.get("error_description"),
|
|
54
|
-
state: url.searchParams.get("state"),
|
|
55
|
-
iss: url.searchParams.get("iss")
|
|
56
|
-
};
|
|
57
|
-
try {
|
|
58
|
-
validateAuthorizationCallbackBinding(callbackParameters, expectedAuthorization);
|
|
59
|
-
}
|
|
60
|
-
catch (error) {
|
|
61
|
-
res.writeHead(400);
|
|
62
|
-
res.end(error instanceof Error ? error.message : "Invalid OAuth callback");
|
|
63
|
-
settle(() => reject(error instanceof Error ? error : new Error(String(error))));
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
const authorizationError = callbackParameters.error;
|
|
67
|
-
if (authorizationError !== null) {
|
|
68
|
-
const description = callbackParameters.errorDescription ?? authorizationError;
|
|
69
|
-
res.writeHead(400);
|
|
70
|
-
res.end(`Authorization failed: ${description}`);
|
|
71
|
-
settle(() => reject(createAuthorizationError(authorizationError, description)));
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
try {
|
|
75
|
-
const code = validateAuthorizationCallbackParameters(callbackParameters, expectedAuthorization);
|
|
76
|
-
res.writeHead(200, { "Content-Type": "text/html" });
|
|
77
|
-
res.end(buildSuccessPage(options.landingPage));
|
|
78
|
-
settle(() => resolve(code));
|
|
79
|
-
}
|
|
80
|
-
catch (error) {
|
|
81
|
-
res.writeHead(400);
|
|
82
|
-
res.end(error instanceof Error ? error.message : "Invalid OAuth callback");
|
|
83
|
-
settle(() => reject(error instanceof Error ? error : new Error(String(error))));
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
if (options.readLine !== undefined) {
|
|
87
|
-
options
|
|
88
|
-
.readLine()
|
|
89
|
-
.then((input) => {
|
|
90
|
-
const callbackParameters = extractCallbackParametersFromInput(input);
|
|
91
|
-
if (callbackParameters === null) {
|
|
92
|
-
settle(() => reject(new Error("OAuth callback missing authorization code")));
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
try {
|
|
96
|
-
validateAuthorizationCallbackBinding(callbackParameters, expectedAuthorization);
|
|
97
|
-
if (callbackParameters.error !== null) {
|
|
98
|
-
const description = callbackParameters.errorDescription ?? callbackParameters.error;
|
|
99
|
-
throw createAuthorizationError(callbackParameters.error, description);
|
|
100
|
-
}
|
|
101
|
-
const code = validateAuthorizationCallbackParameters(callbackParameters, expectedAuthorization);
|
|
102
|
-
settle(() => resolve(code));
|
|
103
|
-
}
|
|
104
|
-
catch (error) {
|
|
105
|
-
settle(() => reject(error instanceof Error ? error : new Error(String(error))));
|
|
106
|
-
}
|
|
107
|
-
})
|
|
108
|
-
.catch((error) => {
|
|
109
|
-
settle(() => reject(error instanceof Error ? error : new Error(String(error))));
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
if (options.openBrowser !== undefined) {
|
|
113
|
-
options.openBrowser(authorizationUrl).catch((error) => {
|
|
114
|
-
settle(() => reject(error));
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
export function extractCodeFromInput(input) {
|
|
120
|
-
return extractCallbackParametersFromInput(input)?.code ?? null;
|
|
121
|
-
}
|
|
122
|
-
function extractCallbackParametersFromInput(input) {
|
|
123
|
-
const trimmed = input.replaceAll("\r", "").replaceAll("\n", "").trim();
|
|
124
|
-
if (trimmed.length === 0) {
|
|
125
|
-
return null;
|
|
126
|
-
}
|
|
127
|
-
try {
|
|
128
|
-
const url = new URL(trimmed);
|
|
129
|
-
return {
|
|
130
|
-
code: url.searchParams.get("code"),
|
|
131
|
-
error: url.searchParams.get("error"),
|
|
132
|
-
errorDescription: url.searchParams.get("error_description"),
|
|
133
|
-
state: url.searchParams.get("state"),
|
|
134
|
-
iss: url.searchParams.get("iss")
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
catch {
|
|
138
|
-
return {
|
|
139
|
-
code: trimmed,
|
|
140
|
-
error: null,
|
|
141
|
-
errorDescription: null,
|
|
142
|
-
state: null,
|
|
143
|
-
iss: null
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
function readExpectedAuthorizationCallback(authorizationUrl) {
|
|
148
|
-
const url = new URL(authorizationUrl);
|
|
149
|
-
const state = url.searchParams.get("state");
|
|
150
|
-
const parsedState = parseAuthorizationState(state);
|
|
151
|
-
return {
|
|
152
|
-
state,
|
|
153
|
-
issuer: parsedState?.issuer ?? null,
|
|
154
|
-
requireIssuer: parsedState?.requireIssuer ?? false
|
|
155
|
-
};
|
|
156
|
-
}
|
|
157
|
-
function validateAuthorizationCallbackParameters(callback, expected) {
|
|
158
|
-
validateAuthorizationCallbackBinding(callback, expected);
|
|
159
|
-
if (callback.code === null || callback.code.length === 0) {
|
|
160
|
-
throw new Error("OAuth callback missing authorization code");
|
|
161
|
-
}
|
|
162
|
-
return callback.code;
|
|
163
|
-
}
|
|
164
|
-
function validateAuthorizationCallbackBinding(callback, expected) {
|
|
165
|
-
if (expected.state !== null) {
|
|
166
|
-
if (callback.state === null || callback.state.length === 0) {
|
|
167
|
-
throw new Error("OAuth callback missing state");
|
|
168
|
-
}
|
|
169
|
-
if (callback.state !== expected.state) {
|
|
170
|
-
throw new Error("OAuth callback state mismatch");
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
if (expected.requireIssuer) {
|
|
174
|
-
if (callback.iss === null || callback.iss.length === 0) {
|
|
175
|
-
throw new Error("OAuth callback missing issuer");
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
if (callback.iss !== null &&
|
|
179
|
-
callback.iss.length > 0 &&
|
|
180
|
-
expected.issuer !== null &&
|
|
181
|
-
callback.iss !== expected.issuer) {
|
|
182
|
-
throw new Error("OAuth callback issuer mismatch");
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
function createAuthorizationError(error, description) {
|
|
186
|
-
return new Error(`OAuth authorization failed: ${error} — ${description}`);
|
|
187
|
-
}
|
|
188
|
-
function escapeHtml(text) {
|
|
189
|
-
return text
|
|
190
|
-
.replaceAll("&", "&")
|
|
191
|
-
.replaceAll("<", "<")
|
|
192
|
-
.replaceAll(">", ">")
|
|
193
|
-
.replaceAll('"', """);
|
|
194
|
-
}
|
|
195
|
-
export function buildSuccessPage(landingPage) {
|
|
196
|
-
const title = landingPage?.title ?? "Connected";
|
|
197
|
-
const body = landingPage?.body ?? "You can close this tab and return to your terminal.";
|
|
198
|
-
return [
|
|
199
|
-
"<!DOCTYPE html>",
|
|
200
|
-
`<html><head><meta charset=utf-8><title>${escapeHtml(title)}</title></head>`,
|
|
201
|
-
'<body style="font-family:system-ui,sans-serif;display:flex;align-items:center;justify-content:center;min-height:100vh;margin:0">',
|
|
202
|
-
'<div style="text-align:center">',
|
|
203
|
-
`<h1>${escapeHtml(title)}</h1>`,
|
|
204
|
-
`<p style="color:#666">${escapeHtml(body)}</p>`,
|
|
205
|
-
"</div></body></html>"
|
|
206
|
-
].join("");
|
|
207
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import type { OAuthMetadataFetch, StoredOAuthTokens } from "./types.js";
|
|
2
|
-
interface OAuthErrorShape {
|
|
3
|
-
error: string;
|
|
4
|
-
error_description?: string;
|
|
5
|
-
error_uri?: string;
|
|
6
|
-
}
|
|
7
|
-
export declare class OAuthError extends Error {
|
|
8
|
-
readonly error: string;
|
|
9
|
-
readonly errorDescription: string | undefined;
|
|
10
|
-
readonly errorUri: string | undefined;
|
|
11
|
-
readonly error_description: string | undefined;
|
|
12
|
-
readonly error_uri: string | undefined;
|
|
13
|
-
readonly status: number;
|
|
14
|
-
readonly retryable: boolean;
|
|
15
|
-
readonly terminal: boolean;
|
|
16
|
-
constructor(shape: OAuthErrorShape, status: number);
|
|
17
|
-
}
|
|
18
|
-
export declare function isRetryableOAuthError(error: unknown): error is OAuthError;
|
|
19
|
-
export declare function exchangeAuthorizationCode(input: {
|
|
20
|
-
tokenEndpoint: string;
|
|
21
|
-
clientId: string;
|
|
22
|
-
clientSecret?: string;
|
|
23
|
-
code: string;
|
|
24
|
-
codeVerifier: string;
|
|
25
|
-
redirectUri: string;
|
|
26
|
-
resource: string;
|
|
27
|
-
fetch: OAuthMetadataFetch;
|
|
28
|
-
now: () => number;
|
|
29
|
-
}): Promise<StoredOAuthTokens>;
|
|
30
|
-
export declare function refreshAccessToken(input: {
|
|
31
|
-
tokenEndpoint: string;
|
|
32
|
-
clientId: string;
|
|
33
|
-
clientSecret?: string;
|
|
34
|
-
refreshToken: string;
|
|
35
|
-
resource: string;
|
|
36
|
-
fetch: OAuthMetadataFetch;
|
|
37
|
-
now: () => number;
|
|
38
|
-
}): Promise<StoredOAuthTokens>;
|
|
39
|
-
export declare function readOAuthJsonObjectResponse(response: Response): Promise<Record<string, unknown>>;
|
|
40
|
-
export {};
|
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
import { canonicalizeResourceIndicator } from "../resource-indicator.js";
|
|
2
|
-
const MAX_JS_DATE_MS = 8_640_000_000_000_000;
|
|
3
|
-
export class OAuthError extends Error {
|
|
4
|
-
error;
|
|
5
|
-
errorDescription;
|
|
6
|
-
errorUri;
|
|
7
|
-
error_description;
|
|
8
|
-
error_uri;
|
|
9
|
-
status;
|
|
10
|
-
retryable;
|
|
11
|
-
terminal;
|
|
12
|
-
constructor(shape, status) {
|
|
13
|
-
super(shape.error_description ?? shape.error);
|
|
14
|
-
this.name = "OAuthError";
|
|
15
|
-
this.error = shape.error;
|
|
16
|
-
this.errorDescription = shape.error_description;
|
|
17
|
-
this.errorUri = shape.error_uri;
|
|
18
|
-
this.error_description = shape.error_description;
|
|
19
|
-
this.error_uri = shape.error_uri;
|
|
20
|
-
this.status = status;
|
|
21
|
-
this.retryable = isRetryableOAuthError(this);
|
|
22
|
-
this.terminal = !this.retryable;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
export function isRetryableOAuthError(error) {
|
|
26
|
-
return (error instanceof OAuthError &&
|
|
27
|
-
(error.status >= 500 ||
|
|
28
|
-
error.error === "server_error" ||
|
|
29
|
-
error.error === "temporarily_unavailable"));
|
|
30
|
-
}
|
|
31
|
-
export async function exchangeAuthorizationCode(input) {
|
|
32
|
-
const resource = canonicalizeResourceIndicator(input.resource);
|
|
33
|
-
return requestTokens({
|
|
34
|
-
tokenEndpoint: input.tokenEndpoint,
|
|
35
|
-
clientId: input.clientId,
|
|
36
|
-
clientSecret: input.clientSecret,
|
|
37
|
-
params: {
|
|
38
|
-
grant_type: "authorization_code",
|
|
39
|
-
code: input.code,
|
|
40
|
-
code_verifier: input.codeVerifier,
|
|
41
|
-
redirect_uri: input.redirectUri,
|
|
42
|
-
resource
|
|
43
|
-
},
|
|
44
|
-
fetch: input.fetch,
|
|
45
|
-
now: input.now
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
export async function refreshAccessToken(input) {
|
|
49
|
-
const resource = canonicalizeResourceIndicator(input.resource);
|
|
50
|
-
return requestTokens({
|
|
51
|
-
tokenEndpoint: input.tokenEndpoint,
|
|
52
|
-
clientId: input.clientId,
|
|
53
|
-
clientSecret: input.clientSecret,
|
|
54
|
-
params: {
|
|
55
|
-
grant_type: "refresh_token",
|
|
56
|
-
refresh_token: input.refreshToken,
|
|
57
|
-
resource
|
|
58
|
-
},
|
|
59
|
-
fetch: input.fetch,
|
|
60
|
-
now: input.now
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
async function requestTokens(input) {
|
|
64
|
-
const body = new URLSearchParams({
|
|
65
|
-
client_id: input.clientId,
|
|
66
|
-
...input.params
|
|
67
|
-
});
|
|
68
|
-
if (input.clientSecret !== undefined) {
|
|
69
|
-
body.set("client_secret", input.clientSecret);
|
|
70
|
-
}
|
|
71
|
-
const response = await input.fetch(input.tokenEndpoint, {
|
|
72
|
-
method: "POST",
|
|
73
|
-
headers: {
|
|
74
|
-
"Content-Type": "application/x-www-form-urlencoded"
|
|
75
|
-
},
|
|
76
|
-
body: body.toString()
|
|
77
|
-
});
|
|
78
|
-
const payload = await readOAuthJsonObjectResponse(response);
|
|
79
|
-
const accessToken = getOwnEntry(payload, "access_token");
|
|
80
|
-
if (typeof accessToken !== "string" || accessToken.trim().length === 0) {
|
|
81
|
-
throw new Error("OAuth token response missing access_token");
|
|
82
|
-
}
|
|
83
|
-
const normalizedAccessToken = accessToken.trim();
|
|
84
|
-
const tokenType = normalizeBearerTokenType(getOwnEntry(payload, "token_type"));
|
|
85
|
-
if (tokenType === null) {
|
|
86
|
-
throw new Error("OAuth token response missing token_type=Bearer");
|
|
87
|
-
}
|
|
88
|
-
const expiresIn = getOwnEntry(payload, "expires_in");
|
|
89
|
-
let expiresAt = null;
|
|
90
|
-
if (expiresIn !== undefined) {
|
|
91
|
-
if (typeof expiresIn !== "number" ||
|
|
92
|
-
!Number.isFinite(expiresIn) ||
|
|
93
|
-
!Number.isInteger(expiresIn) ||
|
|
94
|
-
expiresIn < 0) {
|
|
95
|
-
throw new Error("OAuth token response has invalid expires_in");
|
|
96
|
-
}
|
|
97
|
-
expiresAt = input.now() + expiresIn * 1000;
|
|
98
|
-
if (!Number.isSafeInteger(expiresAt) ||
|
|
99
|
-
expiresAt > MAX_JS_DATE_MS ||
|
|
100
|
-
!Number.isFinite(new Date(expiresAt).getTime())) {
|
|
101
|
-
throw new Error("OAuth token response has invalid expires_in");
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
const refreshToken = getOwnEntry(payload, "refresh_token");
|
|
105
|
-
const scope = getOwnEntry(payload, "scope");
|
|
106
|
-
const normalizedRefreshToken = typeof refreshToken === "string" && refreshToken.trim().length > 0
|
|
107
|
-
? refreshToken.trim()
|
|
108
|
-
: undefined;
|
|
109
|
-
const normalizedScope = typeof scope === "string" && scope.trim().length > 0 ? scope.trim() : undefined;
|
|
110
|
-
return {
|
|
111
|
-
accessToken: normalizedAccessToken,
|
|
112
|
-
refreshToken: normalizedRefreshToken === undefined ? undefined : normalizedRefreshToken,
|
|
113
|
-
tokenType,
|
|
114
|
-
expiresAt,
|
|
115
|
-
scope: normalizedScope === undefined ? undefined : normalizedScope
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
export async function readOAuthJsonObjectResponse(response) {
|
|
119
|
-
const fallbackError = createFallbackOAuthError(response.status);
|
|
120
|
-
let payload;
|
|
121
|
-
try {
|
|
122
|
-
payload = await response.json();
|
|
123
|
-
}
|
|
124
|
-
catch {
|
|
125
|
-
if (!response.ok) {
|
|
126
|
-
throw fallbackError;
|
|
127
|
-
}
|
|
128
|
-
throw new Error("OAuth response must be a JSON object");
|
|
129
|
-
}
|
|
130
|
-
if (typeof payload !== "object" || payload === null || Array.isArray(payload)) {
|
|
131
|
-
if (!response.ok) {
|
|
132
|
-
throw fallbackError;
|
|
133
|
-
}
|
|
134
|
-
throw new Error("OAuth response must be a JSON object");
|
|
135
|
-
}
|
|
136
|
-
const record = payload;
|
|
137
|
-
if (!response.ok) {
|
|
138
|
-
throw new OAuthError(readOAuthError(record, fallbackError.error), response.status);
|
|
139
|
-
}
|
|
140
|
-
return record;
|
|
141
|
-
}
|
|
142
|
-
function readOAuthError(payload, fallbackError = "server_error") {
|
|
143
|
-
const error = getOwnEntry(payload, "error");
|
|
144
|
-
const errorDescription = getOwnEntry(payload, "error_description");
|
|
145
|
-
const errorUri = getOwnEntry(payload, "error_uri");
|
|
146
|
-
return {
|
|
147
|
-
error: typeof error === "string" ? error : fallbackError,
|
|
148
|
-
error_description: typeof errorDescription === "string" ? errorDescription : undefined,
|
|
149
|
-
error_uri: typeof errorUri === "string" ? errorUri : undefined
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
function getOwnEntry(record, key) {
|
|
153
|
-
return Object.prototype.hasOwnProperty.call(record, key) ? record[key] : undefined;
|
|
154
|
-
}
|
|
155
|
-
function createFallbackOAuthError(status) {
|
|
156
|
-
const error = status === 503 ? "temporarily_unavailable" : "server_error";
|
|
157
|
-
return new OAuthError({ error }, status);
|
|
158
|
-
}
|
|
159
|
-
function normalizeBearerTokenType(value) {
|
|
160
|
-
if (typeof value !== "string") {
|
|
161
|
-
return null;
|
|
162
|
-
}
|
|
163
|
-
return value.toLowerCase() === "bearer" ? "Bearer" : null;
|
|
164
|
-
}
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import type http from "node:http";
|
|
2
|
-
import type { CreateSecretStoreInput } from "auth-store";
|
|
3
|
-
export type OAuthMetadataFetch = (input: string | URL, init?: RequestInit) => Promise<Response>;
|
|
4
|
-
export interface OAuthProtectedResourceMetadata extends Record<string, unknown> {
|
|
5
|
-
resource: string;
|
|
6
|
-
authorization_servers: string[];
|
|
7
|
-
}
|
|
8
|
-
export interface OAuthAuthorizationServerMetadata extends Record<string, unknown> {
|
|
9
|
-
issuer: string;
|
|
10
|
-
authorization_endpoint: string;
|
|
11
|
-
token_endpoint: string;
|
|
12
|
-
registration_endpoint?: string;
|
|
13
|
-
response_types_supported: string[];
|
|
14
|
-
code_challenge_methods_supported: string[];
|
|
15
|
-
authorization_response_iss_parameter_supported?: boolean;
|
|
16
|
-
}
|
|
17
|
-
export interface OAuthDiscoveryResult {
|
|
18
|
-
resource: string;
|
|
19
|
-
resourceMetadataUrl: string;
|
|
20
|
-
resourceMetadata: OAuthProtectedResourceMetadata;
|
|
21
|
-
authorizationServer: string;
|
|
22
|
-
authorizationServerMetadataUrl: string;
|
|
23
|
-
authorizationServerMetadata: OAuthAuthorizationServerMetadata;
|
|
24
|
-
}
|
|
25
|
-
export interface OAuthUnauthorizedChallenge {
|
|
26
|
-
scheme: "Bearer";
|
|
27
|
-
params: Record<string, string>;
|
|
28
|
-
raw: string;
|
|
29
|
-
}
|
|
30
|
-
export interface OAuthClientProvider {
|
|
31
|
-
authorizeRequest?(input: {
|
|
32
|
-
requestUrl: URL;
|
|
33
|
-
headers: Headers;
|
|
34
|
-
fetch: OAuthMetadataFetch;
|
|
35
|
-
}): Promise<void> | void;
|
|
36
|
-
handleUnauthorized(input: {
|
|
37
|
-
requestUrl: URL;
|
|
38
|
-
response: Response;
|
|
39
|
-
challenge: OAuthUnauthorizedChallenge | null;
|
|
40
|
-
discovery: OAuthDiscoveryResult;
|
|
41
|
-
fetch: OAuthMetadataFetch;
|
|
42
|
-
}): Promise<{
|
|
43
|
-
action: "retry";
|
|
44
|
-
} | {
|
|
45
|
-
action: "fail";
|
|
46
|
-
error?: Error;
|
|
47
|
-
}> | {
|
|
48
|
-
action: "retry";
|
|
49
|
-
} | {
|
|
50
|
-
action: "fail";
|
|
51
|
-
error?: Error;
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
export interface OAuthClientMetadata {
|
|
55
|
-
clientName?: string;
|
|
56
|
-
scope?: string;
|
|
57
|
-
softwareId?: string;
|
|
58
|
-
softwareVersion?: string;
|
|
59
|
-
}
|
|
60
|
-
export interface StoredOAuthTokens {
|
|
61
|
-
accessToken: string;
|
|
62
|
-
refreshToken?: string;
|
|
63
|
-
tokenType: "Bearer";
|
|
64
|
-
expiresAt: number | null;
|
|
65
|
-
scope?: string;
|
|
66
|
-
}
|
|
67
|
-
export interface StoredOAuthSession {
|
|
68
|
-
resource: string;
|
|
69
|
-
authorizationServer: string;
|
|
70
|
-
client: {
|
|
71
|
-
clientId: string;
|
|
72
|
-
clientSecret?: string;
|
|
73
|
-
};
|
|
74
|
-
tokens?: StoredOAuthTokens;
|
|
75
|
-
discovery: {
|
|
76
|
-
resourceMetadataUrl: string;
|
|
77
|
-
resourceMetadata: Record<string, unknown>;
|
|
78
|
-
authorizationServerMetadata: Record<string, unknown>;
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
export interface OAuthSessionStore {
|
|
82
|
-
load(resource: string): Promise<StoredOAuthSession | null>;
|
|
83
|
-
save(resource: string, session: StoredOAuthSession): Promise<void>;
|
|
84
|
-
clear(resource: string): Promise<void>;
|
|
85
|
-
}
|
|
86
|
-
export interface DefaultOAuthClientProviderOptions {
|
|
87
|
-
client: {
|
|
88
|
-
mode: "dynamic";
|
|
89
|
-
clientId?: string;
|
|
90
|
-
clientSecret?: string;
|
|
91
|
-
metadata?: OAuthClientMetadata;
|
|
92
|
-
} | {
|
|
93
|
-
mode: "static";
|
|
94
|
-
clientId: string;
|
|
95
|
-
clientSecret?: string;
|
|
96
|
-
metadata?: OAuthClientMetadata;
|
|
97
|
-
};
|
|
98
|
-
browser: {
|
|
99
|
-
openBrowser(url: string): Promise<void>;
|
|
100
|
-
readLine?: () => Promise<string>;
|
|
101
|
-
createServer?: () => http.Server;
|
|
102
|
-
landingPage?: {
|
|
103
|
-
title: string;
|
|
104
|
-
body: string;
|
|
105
|
-
};
|
|
106
|
-
};
|
|
107
|
-
sessionStore?: OAuthSessionStore;
|
|
108
|
-
authStore?: CreateSecretStoreInput;
|
|
109
|
-
now?: () => number;
|
|
110
|
-
}
|
|
111
|
-
export type OAuthClientProviderOptions = {
|
|
112
|
-
provider: OAuthClientProvider;
|
|
113
|
-
} | DefaultOAuthClientProviderOptions;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export { createAuthStoreSessionStore, } from "./client/auth-store-session-store.js";
|
|
2
|
-
export { createDefaultOAuthClientProvider, createOAuthClientProvider, } from "./client/default-oauth-client-provider.js";
|
|
3
|
-
export { buildSuccessPage, createLoopbackAuthorizationSession, extractCodeFromInput, } from "./client/loopback-authorization.js";
|
|
4
|
-
export { generateCodeChallenge, generateCodeVerifier, } from "./client/pkce.js";
|
|
5
|
-
export { OAuthError, } from "./client/token-endpoint.js";
|
|
6
|
-
export { canonicalizeResourceIndicator, } from "./resource-indicator.js";
|
|
7
|
-
export { createJwksTokenVerifier, } from "./server/jwks-token-verifier.js";
|
|
8
|
-
export type { DefaultOAuthClientProviderOptions, OAuthAuthorizationServerMetadata, OAuthClientMetadata, OAuthClientProvider, OAuthClientProviderOptions, OAuthDiscoveryResult, OAuthMetadataFetch, OAuthProtectedResourceMetadata, OAuthSessionStore, OAuthUnauthorizedChallenge, StoredOAuthSession, StoredOAuthTokens, } from "./client/types.js";
|
|
9
|
-
export type { JwksTokenVerifier, JwksTokenVerifierOptions, JwksVerifiedAccessToken, } from "./server/jwks-token-verifier.js";
|
|
10
|
-
export type { LoopbackAuthorizationOptions, LoopbackAuthorizationSession, OAuthLandingPage, } from "./client/loopback-authorization.js";
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
export { createAuthStoreSessionStore, } from "./client/auth-store-session-store.js";
|
|
2
|
-
export { createDefaultOAuthClientProvider, createOAuthClientProvider, } from "./client/default-oauth-client-provider.js";
|
|
3
|
-
export { buildSuccessPage, createLoopbackAuthorizationSession, extractCodeFromInput, } from "./client/loopback-authorization.js";
|
|
4
|
-
export { generateCodeChallenge, generateCodeVerifier, } from "./client/pkce.js";
|
|
5
|
-
export { OAuthError, } from "./client/token-endpoint.js";
|
|
6
|
-
export { canonicalizeResourceIndicator, } from "./resource-indicator.js";
|
|
7
|
-
export { createJwksTokenVerifier, } from "./server/jwks-token-verifier.js";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function canonicalizeResourceIndicator(value: string | URL): string;
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export function canonicalizeResourceIndicator(value) {
|
|
2
|
-
let url;
|
|
3
|
-
try {
|
|
4
|
-
url = value instanceof URL ? new URL(value.toString()) : new URL(value);
|
|
5
|
-
}
|
|
6
|
-
catch {
|
|
7
|
-
throw new Error("Resource indicator must be an absolute URL");
|
|
8
|
-
}
|
|
9
|
-
url.hash = "";
|
|
10
|
-
return url.toString();
|
|
11
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
type FetchLike = typeof fetch;
|
|
2
|
-
export interface JwksTokenVerifierOptions {
|
|
3
|
-
jwksUrl: string | URL;
|
|
4
|
-
clockSkewSeconds?: number;
|
|
5
|
-
allowedAlgorithms?: readonly string[];
|
|
6
|
-
jwksCacheTtlMs?: number;
|
|
7
|
-
fetch?: FetchLike;
|
|
8
|
-
}
|
|
9
|
-
export interface JwksVerifiedAccessToken {
|
|
10
|
-
token: string;
|
|
11
|
-
issuer: string;
|
|
12
|
-
audience: string[];
|
|
13
|
-
scopes: string[];
|
|
14
|
-
expiresAt: number;
|
|
15
|
-
claims: Record<string, unknown>;
|
|
16
|
-
subject?: string;
|
|
17
|
-
clientId?: string;
|
|
18
|
-
}
|
|
19
|
-
export interface JwksTokenVerifier {
|
|
20
|
-
verify(input: {
|
|
21
|
-
token: string;
|
|
22
|
-
resource: string;
|
|
23
|
-
authorizationServers: readonly string[];
|
|
24
|
-
requiredScopes: readonly string[];
|
|
25
|
-
}): Promise<JwksVerifiedAccessToken>;
|
|
26
|
-
}
|
|
27
|
-
export declare function createJwksTokenVerifier(options: JwksTokenVerifierOptions): JwksTokenVerifier;
|
|
28
|
-
export {};
|