@mcp-native/mcp 0.5.0 → 0.6.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/README.md +172 -4
- package/dist/.tsbuildinfo +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +98 -11
- package/dist/index.js.map +1 -1
- package/dist/lifecycle.d.ts +103 -0
- package/dist/lifecycle.d.ts.map +1 -0
- package/dist/lifecycle.js +425 -0
- package/dist/lifecycle.js.map +1 -0
- package/dist/oauth-error.d.ts +6 -0
- package/dist/oauth-error.d.ts.map +1 -0
- package/dist/oauth-error.js +9 -0
- package/dist/oauth-error.js.map +1 -0
- package/dist/oauth-native.d.ts +66 -0
- package/dist/oauth-native.d.ts.map +1 -0
- package/dist/oauth-native.js +499 -0
- package/dist/oauth-native.js.map +1 -0
- package/dist/oauth-url.d.ts +9 -0
- package/dist/oauth-url.d.ts.map +1 -0
- package/dist/oauth-url.js +38 -0
- package/dist/oauth-url.js.map +1 -0
- package/dist/oauth.d.ts +147 -0
- package/dist/oauth.d.ts.map +1 -0
- package/dist/oauth.js +1183 -0
- package/dist/oauth.js.map +1 -0
- package/package.json +7 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-native.d.ts","sourceRoot":"","sources":["../src/oauth-native.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,499 @@
|
|
|
1
|
+
import { McpNativeOAuthError } from "./oauth-error.js";
|
|
2
|
+
import { assertOAuthRedirectParameterBudget, isLoopbackHostname, MAX_AUTHORIZATION_URL_CODE_UNITS, MAX_CALLBACK_CODE_UNITS, MAX_OAUTH_ISSUER_CODE_UNITS, } from "./oauth-url.js";
|
|
3
|
+
const MAX_SECRET_CODE_UNITS = 32_768;
|
|
4
|
+
const NAMESPACE_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/u;
|
|
5
|
+
const PKCE_VERIFIER_PATTERN = /^[A-Za-z0-9._~-]{43,128}$/u;
|
|
6
|
+
const OAUTH_STATE_PATTERN = /^[A-Za-z0-9._~-]{32,512}$/u;
|
|
7
|
+
const PRIVATE_USE_REDIRECT_SCHEME_PATTERN = /^[a-z][a-z0-9]*(?:[.-][a-z0-9]+)+:$/u;
|
|
8
|
+
const RESERVED_REDIRECT_SCHEMES = new Set([
|
|
9
|
+
"about:",
|
|
10
|
+
"blob:",
|
|
11
|
+
"chrome-extension:",
|
|
12
|
+
"chrome:",
|
|
13
|
+
"content:",
|
|
14
|
+
"data:",
|
|
15
|
+
"file:",
|
|
16
|
+
"ftp:",
|
|
17
|
+
"http:",
|
|
18
|
+
"https:",
|
|
19
|
+
"intent:",
|
|
20
|
+
"javascript:",
|
|
21
|
+
"mailto:",
|
|
22
|
+
"tel:",
|
|
23
|
+
"vbscript:",
|
|
24
|
+
"ws:",
|
|
25
|
+
"wss:",
|
|
26
|
+
]);
|
|
27
|
+
const CALLBACK_PARAMETER_NAMES = new Set([
|
|
28
|
+
"code",
|
|
29
|
+
"error",
|
|
30
|
+
"error_description",
|
|
31
|
+
"error_uri",
|
|
32
|
+
"iss",
|
|
33
|
+
"state",
|
|
34
|
+
]);
|
|
35
|
+
const CLAIMED_STATE_MARKER = "mcp-native:claimed";
|
|
36
|
+
const STATE_LOCKS = new Map();
|
|
37
|
+
const STATE_OWNERS = new Map();
|
|
38
|
+
/**
|
|
39
|
+
* Bounded reference implementation of the OAuth store contract over a native secret backend.
|
|
40
|
+
* One namespace represents one protected-resource authorization context. State operations are
|
|
41
|
+
* serialized across store objects using the same fixed namespaced service in this JS runtime,
|
|
42
|
+
* and a claimed state keeps the reservation exclusive until it is explicitly cleared.
|
|
43
|
+
*/
|
|
44
|
+
export class McpNativeOAuthPlatformSecureStore {
|
|
45
|
+
#backend;
|
|
46
|
+
#services;
|
|
47
|
+
constructor(options) {
|
|
48
|
+
if (typeof options.namespace !== "string" || !NAMESPACE_PATTERN.test(options.namespace)) {
|
|
49
|
+
throw new McpNativeOAuthError("invalid-configuration", "OAuth secure-store namespace must contain 1 to 64 safe app-owned characters");
|
|
50
|
+
}
|
|
51
|
+
if (typeof options.backend?.read !== "function" ||
|
|
52
|
+
typeof options.backend.write !== "function" ||
|
|
53
|
+
typeof options.backend.remove !== "function") {
|
|
54
|
+
throw new McpNativeOAuthError("invalid-configuration", "OAuth secure-store backend must implement read, write, and remove");
|
|
55
|
+
}
|
|
56
|
+
this.#backend = options.backend;
|
|
57
|
+
const prefix = `${options.namespace}.mcp-native.oauth.v1`;
|
|
58
|
+
this.#services = Object.freeze({
|
|
59
|
+
authorization: `${prefix}.authorization`,
|
|
60
|
+
client: `${prefix}.client`,
|
|
61
|
+
discovery: `${prefix}.discovery`,
|
|
62
|
+
state: `${prefix}.state`,
|
|
63
|
+
tokens: `${prefix}.tokens`,
|
|
64
|
+
verifier: `${prefix}.verifier`,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
async loadClientInformation(issuer) {
|
|
68
|
+
assertIssuer(issuer);
|
|
69
|
+
const record = await this.#readIssuerRecord("client");
|
|
70
|
+
return record?.issuer === issuer ? record.value : undefined;
|
|
71
|
+
}
|
|
72
|
+
async saveClientInformation(issuer, information) {
|
|
73
|
+
assertIssuer(issuer);
|
|
74
|
+
await this.#writeJson("client", { issuer, value: information });
|
|
75
|
+
}
|
|
76
|
+
async loadTokens(issuer) {
|
|
77
|
+
if (issuer !== undefined)
|
|
78
|
+
assertIssuer(issuer);
|
|
79
|
+
const record = await this.#readIssuerRecord("tokens");
|
|
80
|
+
return issuer === undefined || record?.issuer === issuer ? record?.value : undefined;
|
|
81
|
+
}
|
|
82
|
+
async saveTokens(issuer, tokens) {
|
|
83
|
+
assertIssuer(issuer);
|
|
84
|
+
await this.#writeJson("tokens", { issuer, value: tokens });
|
|
85
|
+
}
|
|
86
|
+
async loadCodeVerifier() {
|
|
87
|
+
const verifier = await this.#read("verifier");
|
|
88
|
+
if (verifier !== undefined && !PKCE_VERIFIER_PATTERN.test(verifier)) {
|
|
89
|
+
throw new McpNativeOAuthError("invalid-storage", "Stored OAuth PKCE verifier is invalid");
|
|
90
|
+
}
|
|
91
|
+
return verifier;
|
|
92
|
+
}
|
|
93
|
+
async saveCodeVerifier(verifier) {
|
|
94
|
+
if (typeof verifier !== "string" || !PKCE_VERIFIER_PATTERN.test(verifier)) {
|
|
95
|
+
throw new McpNativeOAuthError("invalid-storage", "OAuth PKCE verifier is invalid");
|
|
96
|
+
}
|
|
97
|
+
await this.#backend.write(this.#services.verifier, verifier);
|
|
98
|
+
}
|
|
99
|
+
async loadPendingAuthorization() {
|
|
100
|
+
return this.#readJson("authorization");
|
|
101
|
+
}
|
|
102
|
+
async savePendingAuthorization(record) {
|
|
103
|
+
await this.#writeJson("authorization", record);
|
|
104
|
+
}
|
|
105
|
+
async reserveOAuthState(owner) {
|
|
106
|
+
assertAttemptOwner(owner);
|
|
107
|
+
await this.#withStateLock(async () => {
|
|
108
|
+
const service = this.#services.state;
|
|
109
|
+
if (STATE_OWNERS.has(service) || (await this.#read("state")) !== undefined) {
|
|
110
|
+
throw new McpNativeOAuthError("invalid-storage", "Another OAuth authorization state is already reserved for this namespace");
|
|
111
|
+
}
|
|
112
|
+
STATE_OWNERS.set(service, owner);
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
async saveOAuthState(state, owner) {
|
|
116
|
+
assertAttemptOwner(owner);
|
|
117
|
+
if (typeof state !== "string" || !OAUTH_STATE_PATTERN.test(state)) {
|
|
118
|
+
throw new McpNativeOAuthError("invalid-storage", "OAuth state is invalid");
|
|
119
|
+
}
|
|
120
|
+
await this.#withStateLock(async () => {
|
|
121
|
+
const service = this.#services.state;
|
|
122
|
+
const currentOwner = STATE_OWNERS.get(service);
|
|
123
|
+
if ((currentOwner !== undefined && currentOwner !== owner) ||
|
|
124
|
+
(await this.#read("state")) !== undefined) {
|
|
125
|
+
throw new McpNativeOAuthError("invalid-storage", "Another OAuth authorization state is already reserved for this namespace");
|
|
126
|
+
}
|
|
127
|
+
await this.#backend.write(service, state);
|
|
128
|
+
STATE_OWNERS.set(service, owner);
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
async claimOAuthStateForCleanup(owner) {
|
|
132
|
+
assertAttemptOwner(owner);
|
|
133
|
+
await this.#withStateLock(async () => {
|
|
134
|
+
const service = this.#services.state;
|
|
135
|
+
const currentOwner = STATE_OWNERS.get(service);
|
|
136
|
+
if (currentOwner !== undefined && currentOwner !== owner) {
|
|
137
|
+
throw new McpNativeOAuthError("invalid-storage", "Another OAuth provider owns the authorization state reservation");
|
|
138
|
+
}
|
|
139
|
+
STATE_OWNERS.set(service, owner);
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
async clearOAuthState(owner) {
|
|
143
|
+
assertAttemptOwner(owner);
|
|
144
|
+
await this.#withStateLock(async () => {
|
|
145
|
+
const service = this.#services.state;
|
|
146
|
+
if (STATE_OWNERS.get(service) !== owner) {
|
|
147
|
+
throw new McpNativeOAuthError("invalid-storage", "OAuth state reservation is not owned by this provider");
|
|
148
|
+
}
|
|
149
|
+
await this.#backend.remove(service);
|
|
150
|
+
STATE_OWNERS.delete(service);
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
async consumeOAuthState(state, owner) {
|
|
154
|
+
assertAttemptOwner(owner);
|
|
155
|
+
if (typeof state !== "string" || !OAUTH_STATE_PATTERN.test(state))
|
|
156
|
+
return false;
|
|
157
|
+
return this.#withStateLock(async () => {
|
|
158
|
+
const service = this.#services.state;
|
|
159
|
+
const currentOwner = STATE_OWNERS.get(service);
|
|
160
|
+
if (currentOwner !== undefined && currentOwner !== owner)
|
|
161
|
+
return false;
|
|
162
|
+
const stored = await this.#read("state");
|
|
163
|
+
if (stored !== state)
|
|
164
|
+
return false;
|
|
165
|
+
await this.#backend.write(service, CLAIMED_STATE_MARKER);
|
|
166
|
+
STATE_OWNERS.set(service, owner);
|
|
167
|
+
return true;
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
async loadDiscoveryState() {
|
|
171
|
+
const value = await this.#readJson("discovery");
|
|
172
|
+
return value;
|
|
173
|
+
}
|
|
174
|
+
async saveDiscoveryState(state) {
|
|
175
|
+
await this.#writeJson("discovery", state);
|
|
176
|
+
}
|
|
177
|
+
async invalidate(scope, issuer) {
|
|
178
|
+
if (issuer !== undefined)
|
|
179
|
+
assertIssuer(issuer);
|
|
180
|
+
switch (scope) {
|
|
181
|
+
case "all":
|
|
182
|
+
await this.#withStateLock(async () => {
|
|
183
|
+
await Promise.all(["authorization", "client", "discovery", "state", "tokens", "verifier"].map((slot) => this.#backend.remove(this.#services[slot])));
|
|
184
|
+
STATE_OWNERS.delete(this.#services.state);
|
|
185
|
+
});
|
|
186
|
+
return;
|
|
187
|
+
case "client":
|
|
188
|
+
case "tokens":
|
|
189
|
+
await this.#removeIssuerRecord(scope, issuer);
|
|
190
|
+
return;
|
|
191
|
+
case "discovery":
|
|
192
|
+
await this.#removeDiscovery(issuer);
|
|
193
|
+
return;
|
|
194
|
+
case "verifier":
|
|
195
|
+
await Promise.all([
|
|
196
|
+
this.#backend.remove(this.#services.authorization),
|
|
197
|
+
this.#backend.remove(this.#services.verifier),
|
|
198
|
+
]);
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
async #read(slot) {
|
|
203
|
+
const value = await this.#backend.read(this.#services[slot]);
|
|
204
|
+
if (value !== undefined &&
|
|
205
|
+
(typeof value !== "string" || value.length > MAX_SECRET_CODE_UNITS)) {
|
|
206
|
+
throw new McpNativeOAuthError("invalid-storage", `Stored OAuth ${slot} value is invalid`);
|
|
207
|
+
}
|
|
208
|
+
return value;
|
|
209
|
+
}
|
|
210
|
+
async #readJson(slot) {
|
|
211
|
+
const serialized = await this.#read(slot);
|
|
212
|
+
if (serialized === undefined)
|
|
213
|
+
return undefined;
|
|
214
|
+
let value;
|
|
215
|
+
try {
|
|
216
|
+
value = JSON.parse(serialized);
|
|
217
|
+
}
|
|
218
|
+
catch (error) {
|
|
219
|
+
throw new McpNativeOAuthError("invalid-storage", `Stored OAuth ${slot} JSON is invalid`, {
|
|
220
|
+
cause: error,
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
224
|
+
throw new McpNativeOAuthError("invalid-storage", `Stored OAuth ${slot} value is invalid`);
|
|
225
|
+
}
|
|
226
|
+
return value;
|
|
227
|
+
}
|
|
228
|
+
async #readIssuerRecord(slot) {
|
|
229
|
+
const value = await this.#readJson(slot);
|
|
230
|
+
if (value === undefined)
|
|
231
|
+
return undefined;
|
|
232
|
+
if (Object.keys(value).length !== 2 ||
|
|
233
|
+
!Object.hasOwn(value, "issuer") ||
|
|
234
|
+
!Object.hasOwn(value, "value") ||
|
|
235
|
+
typeof value.issuer !== "string" ||
|
|
236
|
+
value.value === null ||
|
|
237
|
+
typeof value.value !== "object" ||
|
|
238
|
+
Array.isArray(value.value)) {
|
|
239
|
+
throw new McpNativeOAuthError("invalid-storage", `Stored OAuth ${slot} record is invalid`);
|
|
240
|
+
}
|
|
241
|
+
assertIssuer(value.issuer);
|
|
242
|
+
return { issuer: value.issuer, value: value.value };
|
|
243
|
+
}
|
|
244
|
+
async #writeJson(slot, value) {
|
|
245
|
+
let serialized;
|
|
246
|
+
try {
|
|
247
|
+
serialized = JSON.stringify(value);
|
|
248
|
+
}
|
|
249
|
+
catch (error) {
|
|
250
|
+
throw new McpNativeOAuthError("invalid-storage", `OAuth ${slot} value is not serializable`, {
|
|
251
|
+
cause: error,
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
if (serialized.length > MAX_SECRET_CODE_UNITS) {
|
|
255
|
+
throw new McpNativeOAuthError("invalid-storage", `OAuth ${slot} value exceeds the secure-store limit`);
|
|
256
|
+
}
|
|
257
|
+
await this.#backend.write(this.#services[slot], serialized);
|
|
258
|
+
}
|
|
259
|
+
async #removeIssuerRecord(slot, issuer) {
|
|
260
|
+
if (issuer === undefined) {
|
|
261
|
+
await this.#backend.remove(this.#services[slot]);
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
let record;
|
|
265
|
+
try {
|
|
266
|
+
record = await this.#readIssuerRecord(slot);
|
|
267
|
+
}
|
|
268
|
+
catch (error) {
|
|
269
|
+
await this.#backend.remove(this.#services[slot]);
|
|
270
|
+
throw error;
|
|
271
|
+
}
|
|
272
|
+
if (record?.issuer === issuer)
|
|
273
|
+
await this.#backend.remove(this.#services[slot]);
|
|
274
|
+
}
|
|
275
|
+
async #removeDiscovery(issuer) {
|
|
276
|
+
if (issuer === undefined) {
|
|
277
|
+
await this.#backend.remove(this.#services.discovery);
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
let discovery;
|
|
281
|
+
try {
|
|
282
|
+
discovery = await this.#readJson("discovery");
|
|
283
|
+
}
|
|
284
|
+
catch (error) {
|
|
285
|
+
await this.#backend.remove(this.#services.discovery);
|
|
286
|
+
throw error;
|
|
287
|
+
}
|
|
288
|
+
if (discovery?.authorizationServerUrl === issuer) {
|
|
289
|
+
await this.#backend.remove(this.#services.discovery);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
#withStateLock(operation) {
|
|
293
|
+
const service = this.#services.state;
|
|
294
|
+
const previous = STATE_LOCKS.get(service) ?? Promise.resolve();
|
|
295
|
+
const result = previous.then(operation, operation);
|
|
296
|
+
const tail = result.then(() => undefined, () => undefined);
|
|
297
|
+
STATE_LOCKS.set(service, tail);
|
|
298
|
+
void tail.then(() => {
|
|
299
|
+
if (STATE_LOCKS.get(service) === tail)
|
|
300
|
+
STATE_LOCKS.delete(service);
|
|
301
|
+
});
|
|
302
|
+
return result;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
export function createMcpNativeOAuthPlatformSecureStore(options) {
|
|
306
|
+
return new McpNativeOAuthPlatformSecureStore(options);
|
|
307
|
+
}
|
|
308
|
+
/** Closed adapter for ASWebAuthenticationSession / Android Custom Tab callback results. */
|
|
309
|
+
export class McpNativeOAuthAuthorizationSession {
|
|
310
|
+
#redirectUrl;
|
|
311
|
+
#open;
|
|
312
|
+
#callbackUrl;
|
|
313
|
+
#finishing = false;
|
|
314
|
+
#running = false;
|
|
315
|
+
constructor(options) {
|
|
316
|
+
this.#redirectUrl = parseRedirectUrl(options.redirectUrl);
|
|
317
|
+
if (typeof options.open !== "function") {
|
|
318
|
+
throw new McpNativeOAuthError("invalid-configuration", "OAuth authorization-session opener is required");
|
|
319
|
+
}
|
|
320
|
+
this.#open = options.open;
|
|
321
|
+
}
|
|
322
|
+
openAuthorization = async (authorizationUrl) => {
|
|
323
|
+
if (this.#running || this.#finishing || this.#callbackUrl !== undefined) {
|
|
324
|
+
throw new McpNativeOAuthError("invalid-configuration", "Another OAuth authorization session or callback is already pending");
|
|
325
|
+
}
|
|
326
|
+
const serializedAuthorizationUrl = authorizationUrl.href;
|
|
327
|
+
if (serializedAuthorizationUrl.length > MAX_AUTHORIZATION_URL_CODE_UNITS) {
|
|
328
|
+
throw new McpNativeOAuthError("invalid-configuration", "OAuth authorization URL exceeds the supported size");
|
|
329
|
+
}
|
|
330
|
+
const authorization = parseSecureUrl(serializedAuthorizationUrl, "OAuth authorization URL");
|
|
331
|
+
this.#running = true;
|
|
332
|
+
try {
|
|
333
|
+
let result;
|
|
334
|
+
try {
|
|
335
|
+
result = await this.#open(new URL(authorization.href), new URL(this.#redirectUrl.href));
|
|
336
|
+
}
|
|
337
|
+
catch (error) {
|
|
338
|
+
throw new McpNativeOAuthError("authorization-denied", "The platform authorization session did not complete", { cause: error });
|
|
339
|
+
}
|
|
340
|
+
if (!isPlainObject(result) || !hasExactSessionResultKeys(result)) {
|
|
341
|
+
throw new McpNativeOAuthError("invalid-callback", "The platform authorization session returned an invalid result");
|
|
342
|
+
}
|
|
343
|
+
if (result.type !== "success") {
|
|
344
|
+
throw new McpNativeOAuthError("authorization-denied", "The platform authorization session was cancelled");
|
|
345
|
+
}
|
|
346
|
+
if (typeof result.url !== "string" || result.url.length > MAX_CALLBACK_CODE_UNITS) {
|
|
347
|
+
throw new McpNativeOAuthError("invalid-callback", "The platform authorization callback is invalid");
|
|
348
|
+
}
|
|
349
|
+
const callback = parseCallbackUrl(result.url, this.#redirectUrl);
|
|
350
|
+
this.#callbackUrl = callback;
|
|
351
|
+
}
|
|
352
|
+
finally {
|
|
353
|
+
this.#running = false;
|
|
354
|
+
}
|
|
355
|
+
};
|
|
356
|
+
hasPendingCallback() {
|
|
357
|
+
return this.#callbackUrl !== undefined;
|
|
358
|
+
}
|
|
359
|
+
async finishAuthorization(provider, finisher) {
|
|
360
|
+
const callback = this.#callbackUrl;
|
|
361
|
+
if (callback === undefined || this.#finishing) {
|
|
362
|
+
throw new McpNativeOAuthError("invalid-callback", "No platform authorization callback is pending");
|
|
363
|
+
}
|
|
364
|
+
this.#finishing = true;
|
|
365
|
+
this.#callbackUrl = undefined;
|
|
366
|
+
try {
|
|
367
|
+
await provider.finishAuthorization(finisher, callback);
|
|
368
|
+
}
|
|
369
|
+
finally {
|
|
370
|
+
this.#finishing = false;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
export function createMcpNativeOAuthAuthorizationSession(options) {
|
|
375
|
+
return new McpNativeOAuthAuthorizationSession(options);
|
|
376
|
+
}
|
|
377
|
+
function assertAttemptOwner(owner) {
|
|
378
|
+
if (typeof owner !== "object" || owner === null) {
|
|
379
|
+
throw new McpNativeOAuthError("invalid-storage", "OAuth state owner is invalid");
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
function assertIssuer(issuer) {
|
|
383
|
+
if (typeof issuer !== "string" ||
|
|
384
|
+
issuer.length === 0 ||
|
|
385
|
+
issuer.length > MAX_OAUTH_ISSUER_CODE_UNITS) {
|
|
386
|
+
throw new McpNativeOAuthError("invalid-storage", "OAuth issuer is invalid or too large");
|
|
387
|
+
}
|
|
388
|
+
let url;
|
|
389
|
+
try {
|
|
390
|
+
url = new URL(issuer);
|
|
391
|
+
}
|
|
392
|
+
catch (error) {
|
|
393
|
+
throw new McpNativeOAuthError("invalid-storage", "OAuth issuer is invalid", { cause: error });
|
|
394
|
+
}
|
|
395
|
+
if (url.username !== "" ||
|
|
396
|
+
url.password !== "" ||
|
|
397
|
+
(url.protocol !== "https:" &&
|
|
398
|
+
!(url.protocol === "http:" && isLoopbackHostname(url.hostname))) ||
|
|
399
|
+
url.href.includes("?") ||
|
|
400
|
+
url.href.includes("#")) {
|
|
401
|
+
throw new McpNativeOAuthError("invalid-storage", "OAuth issuer is invalid");
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
function isPlainObject(value) {
|
|
405
|
+
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
406
|
+
return false;
|
|
407
|
+
const prototype = Object.getPrototypeOf(value);
|
|
408
|
+
return prototype === Object.prototype || prototype === null;
|
|
409
|
+
}
|
|
410
|
+
function hasExactSessionResultKeys(value) {
|
|
411
|
+
const keys = Object.keys(value);
|
|
412
|
+
if (value.type === "success") {
|
|
413
|
+
return keys.length === 2 && Object.hasOwn(value, "type") && Object.hasOwn(value, "url");
|
|
414
|
+
}
|
|
415
|
+
return ((value.type === "cancel" || value.type === "dismiss") &&
|
|
416
|
+
keys.length === 1 &&
|
|
417
|
+
Object.hasOwn(value, "type"));
|
|
418
|
+
}
|
|
419
|
+
function parseRedirectUrl(value) {
|
|
420
|
+
const url = parseUrl(value, "OAuth redirect URL");
|
|
421
|
+
if (url.username !== "" || url.password !== "" || url.href.includes("#")) {
|
|
422
|
+
throw new McpNativeOAuthError("invalid-configuration", "OAuth redirect URL must not contain credentials or a fragment");
|
|
423
|
+
}
|
|
424
|
+
if (!isSupportedRedirectLocation(url)) {
|
|
425
|
+
throw new McpNativeOAuthError("invalid-configuration", "OAuth redirect URL must use HTTPS, HTTP loopback, or a safe private-use app scheme");
|
|
426
|
+
}
|
|
427
|
+
assertUniqueRedirectParameters(url);
|
|
428
|
+
for (const name of CALLBACK_PARAMETER_NAMES) {
|
|
429
|
+
if (url.searchParams.has(name)) {
|
|
430
|
+
throw new McpNativeOAuthError("invalid-configuration", `OAuth redirect URL must not predefine callback parameter ${name}`);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
assertOAuthRedirectParameterBudget(url);
|
|
434
|
+
return url;
|
|
435
|
+
}
|
|
436
|
+
function assertUniqueRedirectParameters(url) {
|
|
437
|
+
const names = new Set();
|
|
438
|
+
for (const name of url.searchParams.keys()) {
|
|
439
|
+
if (names.has(name)) {
|
|
440
|
+
throw new McpNativeOAuthError("invalid-configuration", "OAuth redirect URL must not contain duplicate query parameter names");
|
|
441
|
+
}
|
|
442
|
+
names.add(name);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
function parseSecureUrl(value, label) {
|
|
446
|
+
const url = parseUrl(value, label);
|
|
447
|
+
if (url.username !== "" || url.password !== "") {
|
|
448
|
+
throw new McpNativeOAuthError("invalid-configuration", `${label} must not contain credentials`);
|
|
449
|
+
}
|
|
450
|
+
if (url.protocol !== "https:" &&
|
|
451
|
+
!(url.protocol === "http:" && isLoopbackHostname(url.hostname))) {
|
|
452
|
+
throw new McpNativeOAuthError("invalid-configuration", `${label} must use HTTPS or an HTTP loopback address`);
|
|
453
|
+
}
|
|
454
|
+
if (url.href.includes("#")) {
|
|
455
|
+
throw new McpNativeOAuthError("invalid-configuration", `${label} must not contain a fragment`);
|
|
456
|
+
}
|
|
457
|
+
return url;
|
|
458
|
+
}
|
|
459
|
+
function parseCallbackUrl(value, redirectUrl) {
|
|
460
|
+
let callback;
|
|
461
|
+
try {
|
|
462
|
+
callback = new URL(value);
|
|
463
|
+
}
|
|
464
|
+
catch (error) {
|
|
465
|
+
throw new McpNativeOAuthError("invalid-callback", "OAuth callback must be an absolute URL", {
|
|
466
|
+
cause: error,
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
if (callback.href.includes("#") ||
|
|
470
|
+
callback.protocol !== redirectUrl.protocol ||
|
|
471
|
+
callback.username !== redirectUrl.username ||
|
|
472
|
+
callback.password !== redirectUrl.password ||
|
|
473
|
+
callback.host !== redirectUrl.host ||
|
|
474
|
+
callback.pathname !== redirectUrl.pathname) {
|
|
475
|
+
throw new McpNativeOAuthError("callback-mismatch", "OAuth callback URL does not match the configured redirect URL");
|
|
476
|
+
}
|
|
477
|
+
return callback;
|
|
478
|
+
}
|
|
479
|
+
function parseUrl(value, label) {
|
|
480
|
+
try {
|
|
481
|
+
return new URL(value instanceof URL ? value.href : value);
|
|
482
|
+
}
|
|
483
|
+
catch (error) {
|
|
484
|
+
throw new McpNativeOAuthError("invalid-configuration", `${label} must be an absolute URL`, {
|
|
485
|
+
cause: error,
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
function isSupportedRedirectLocation(url) {
|
|
490
|
+
if (url.protocol === "https:")
|
|
491
|
+
return true;
|
|
492
|
+
if (url.protocol === "http:")
|
|
493
|
+
return isLoopbackHostname(url.hostname);
|
|
494
|
+
return (!RESERVED_REDIRECT_SCHEMES.has(url.protocol) &&
|
|
495
|
+
PRIVATE_USE_REDIRECT_SCHEME_PATTERN.test(url.protocol) &&
|
|
496
|
+
url.hostname !== "" &&
|
|
497
|
+
url.port === "");
|
|
498
|
+
}
|
|
499
|
+
//# sourceMappingURL=oauth-native.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-native.js","sourceRoot":"","sources":["../src/oauth-native.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const MAX_AUTHORIZATION_URL_CODE_UNITS = 8192;
|
|
2
|
+
export declare const MAX_CALLBACK_CODE_UNITS = 8192;
|
|
3
|
+
export declare const MAX_CALLBACK_PARAMETERS = 16;
|
|
4
|
+
export declare const MAX_CALLBACK_PARAMETER_NAME_CODE_UNITS = 128;
|
|
5
|
+
export declare const MAX_CALLBACK_PARAMETER_VALUE_CODE_UNITS = 4096;
|
|
6
|
+
export declare const MAX_OAUTH_ISSUER_CODE_UNITS = 2048;
|
|
7
|
+
export declare function assertOAuthRedirectParameterBudget(url: URL): void;
|
|
8
|
+
export declare function isLoopbackHostname(hostname: string): boolean;
|
|
9
|
+
//# sourceMappingURL=oauth-url.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-url.d.ts","sourceRoot":"","sources":["../src/oauth-url.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,gCAAgC,OAAQ,CAAC;AACtD,eAAO,MAAM,uBAAuB,OAAQ,CAAC;AAC7C,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAC1C,eAAO,MAAM,sCAAsC,MAAM,CAAC;AAC1D,eAAO,MAAM,uCAAuC,OAAQ,CAAC;AAC7D,eAAO,MAAM,2BAA2B,OAAQ,CAAC;AAMjD,wBAAgB,kCAAkC,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAmCjE;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAS5D"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { McpNativeOAuthError } from "./oauth-error.js";
|
|
2
|
+
export const MAX_AUTHORIZATION_URL_CODE_UNITS = 8_192;
|
|
3
|
+
export const MAX_CALLBACK_CODE_UNITS = 8_192;
|
|
4
|
+
export const MAX_CALLBACK_PARAMETERS = 16;
|
|
5
|
+
export const MAX_CALLBACK_PARAMETER_NAME_CODE_UNITS = 128;
|
|
6
|
+
export const MAX_CALLBACK_PARAMETER_VALUE_CODE_UNITS = 4_096;
|
|
7
|
+
export const MAX_OAUTH_ISSUER_CODE_UNITS = 2_048;
|
|
8
|
+
const MAX_CALLBACK_CODE_VALUE_CODE_UNITS = 4_096;
|
|
9
|
+
const MAX_CALLBACK_STATE_VALUE_CODE_UNITS = 512;
|
|
10
|
+
const RESERVED_CALLBACK_PARAMETERS = 2;
|
|
11
|
+
export function assertOAuthRedirectParameterBudget(url) {
|
|
12
|
+
const parameters = [...url.searchParams];
|
|
13
|
+
if (parameters.length > MAX_CALLBACK_PARAMETERS - RESERVED_CALLBACK_PARAMETERS) {
|
|
14
|
+
throw new McpNativeOAuthError("invalid-configuration", "OAuth redirect URL leaves insufficient callback parameter capacity");
|
|
15
|
+
}
|
|
16
|
+
for (const [name, value] of parameters) {
|
|
17
|
+
if (name.length > MAX_CALLBACK_PARAMETER_NAME_CODE_UNITS ||
|
|
18
|
+
value.length > MAX_CALLBACK_PARAMETER_VALUE_CODE_UNITS) {
|
|
19
|
+
throw new McpNativeOAuthError("invalid-configuration", "OAuth redirect URL contains a parameter that exceeds the callback budget");
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
const maximumSuccessCallback = new URL(url.href);
|
|
23
|
+
maximumSuccessCallback.searchParams.append("code", "c".repeat(MAX_CALLBACK_CODE_VALUE_CODE_UNITS));
|
|
24
|
+
maximumSuccessCallback.searchParams.append("state", "s".repeat(MAX_CALLBACK_STATE_VALUE_CODE_UNITS));
|
|
25
|
+
if (maximumSuccessCallback.href.length > MAX_CALLBACK_CODE_UNITS) {
|
|
26
|
+
throw new McpNativeOAuthError("invalid-configuration", "OAuth redirect URL leaves insufficient callback URL capacity");
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export function isLoopbackHostname(hostname) {
|
|
30
|
+
const normalized = hostname.toLowerCase();
|
|
31
|
+
if (normalized === "localhost" || normalized === "[::1]")
|
|
32
|
+
return true;
|
|
33
|
+
const octets = normalized.split(".");
|
|
34
|
+
return (octets.length === 4 &&
|
|
35
|
+
octets[0] === "127" &&
|
|
36
|
+
octets.slice(1).every((octet) => /^(?:0|[1-9][0-9]{0,2})$/u.test(octet) && Number(octet) <= 255));
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=oauth-url.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-url.js","sourceRoot":"","sources":["../src/oauth-url.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEvD,MAAM,CAAC,MAAM,gCAAgC,GAAG,KAAK,CAAC;AACtD,MAAM,CAAC,MAAM,uBAAuB,GAAG,KAAK,CAAC;AAC7C,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,CAAC;AAC1C,MAAM,CAAC,MAAM,sCAAsC,GAAG,GAAG,CAAC;AAC1D,MAAM,CAAC,MAAM,uCAAuC,GAAG,KAAK,CAAC;AAC7D,MAAM,CAAC,MAAM,2BAA2B,GAAG,KAAK,CAAC;AAEjD,MAAM,kCAAkC,GAAG,KAAK,CAAC;AACjD,MAAM,mCAAmC,GAAG,GAAG,CAAC;AAChD,MAAM,4BAA4B,GAAG,CAAC,CAAC;AAEvC,MAAM,UAAU,kCAAkC,CAAC,GAAQ;IACzD,MAAM,UAAU,GAAG,CAAC,GAAG,GAAG,CAAC,YAAY,CAAC,CAAC;IACzC,IAAI,UAAU,CAAC,MAAM,GAAG,uBAAuB,GAAG,4BAA4B,EAAE,CAAC;QAC/E,MAAM,IAAI,mBAAmB,CAC3B,uBAAuB,EACvB,oEAAoE,CACrE,CAAC;IACJ,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,UAAU,EAAE,CAAC;QACvC,IACE,IAAI,CAAC,MAAM,GAAG,sCAAsC;YACpD,KAAK,CAAC,MAAM,GAAG,uCAAuC,EACtD,CAAC;YACD,MAAM,IAAI,mBAAmB,CAC3B,uBAAuB,EACvB,0EAA0E,CAC3E,CAAC;QACJ,CAAC;IACH,CAAC;IAED,MAAM,sBAAsB,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACjD,sBAAsB,CAAC,YAAY,CAAC,MAAM,CACxC,MAAM,EACN,GAAG,CAAC,MAAM,CAAC,kCAAkC,CAAC,CAC/C,CAAC;IACF,sBAAsB,CAAC,YAAY,CAAC,MAAM,CACxC,OAAO,EACP,GAAG,CAAC,MAAM,CAAC,mCAAmC,CAAC,CAChD,CAAC;IACF,IAAI,sBAAsB,CAAC,IAAI,CAAC,MAAM,GAAG,uBAAuB,EAAE,CAAC;QACjE,MAAM,IAAI,mBAAmB,CAC3B,uBAAuB,EACvB,8DAA8D,CAC/D,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IACjD,MAAM,UAAU,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IAC1C,IAAI,UAAU,KAAK,WAAW,IAAI,UAAU,KAAK,OAAO;QAAE,OAAO,IAAI,CAAC;IACtE,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACrC,OAAO,CACL,MAAM,CAAC,MAAM,KAAK,CAAC;QACnB,MAAM,CAAC,CAAC,CAAC,KAAK,KAAK;QACnB,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,0BAA0B,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CACjG,CAAC;AACJ,CAAC"}
|