@trops/dash-core 0.1.610 → 0.1.611
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/electron/index.js +1977 -1427
- package/dist/electron/index.js.map +1 -1
- package/dist/index.esm.js +237 -50
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +238 -49
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/electron/index.js
CHANGED
|
@@ -19,20 +19,20 @@ var require$$6 = require('csv-parser');
|
|
|
19
19
|
var require$$0$6 = require('quickjs-emscripten');
|
|
20
20
|
var require$$11 = require('https');
|
|
21
21
|
var require$$0$8 = require('@modelcontextprotocol/sdk/client/index.js');
|
|
22
|
-
var require$$1$
|
|
22
|
+
var require$$1$6 = require('@modelcontextprotocol/sdk/client/stdio.js');
|
|
23
23
|
var require$$0$7 = require('pkce-challenge');
|
|
24
24
|
var require$$12 = require('child_process');
|
|
25
|
+
var require$$1$5 = require('http');
|
|
25
26
|
var require$$2$2 = require('algoliasearch');
|
|
26
27
|
var require$$3$2 = require('node:path');
|
|
27
28
|
var require$$0$9 = require('openai');
|
|
28
|
-
var require$$0$
|
|
29
|
+
var require$$0$b = require('@anthropic-ai/sdk');
|
|
29
30
|
var require$$2$3 = require('zod-to-json-schema');
|
|
30
31
|
var require$$8$1 = require('zod');
|
|
31
|
-
var require$$
|
|
32
|
-
var require$$1$6 = require('http2');
|
|
32
|
+
var require$$1$7 = require('http2');
|
|
33
33
|
var require$$2$4 = require('node-forge');
|
|
34
|
-
var require$$0$
|
|
35
|
-
var require$$1$
|
|
34
|
+
var require$$0$a = require('css');
|
|
35
|
+
var require$$1$8 = require('node-vibrant/node');
|
|
36
36
|
var require$$3$3 = require('ws');
|
|
37
37
|
|
|
38
38
|
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
@@ -411,6 +411,10 @@ const MCP_RUN_AUTH$1 = "mcp-run-auth";
|
|
|
411
411
|
const MCP_RUN_AUTH_COMPLETE = "mcp-run-auth-complete";
|
|
412
412
|
const MCP_RUN_AUTH_ERROR = "mcp-run-auth-error";
|
|
413
413
|
|
|
414
|
+
const MCP_AUTHORIZE$1 = "mcp-authorize";
|
|
415
|
+
const MCP_AUTHORIZE_COMPLETE = "mcp-authorize-complete";
|
|
416
|
+
const MCP_AUTHORIZE_ERROR = "mcp-authorize-error";
|
|
417
|
+
|
|
414
418
|
var mcpEvents$1 = {
|
|
415
419
|
MCP_START_SERVER: MCP_START_SERVER$1,
|
|
416
420
|
MCP_START_SERVER_COMPLETE,
|
|
@@ -442,6 +446,9 @@ var mcpEvents$1 = {
|
|
|
442
446
|
MCP_RUN_AUTH: MCP_RUN_AUTH$1,
|
|
443
447
|
MCP_RUN_AUTH_COMPLETE,
|
|
444
448
|
MCP_RUN_AUTH_ERROR,
|
|
449
|
+
MCP_AUTHORIZE: MCP_AUTHORIZE$1,
|
|
450
|
+
MCP_AUTHORIZE_COMPLETE,
|
|
451
|
+
MCP_AUTHORIZE_ERROR,
|
|
445
452
|
};
|
|
446
453
|
|
|
447
454
|
/**
|
|
@@ -18748,6 +18755,14 @@ function requireProviderController () {
|
|
|
18748
18755
|
providerEntry.isDefaultForType = true;
|
|
18749
18756
|
}
|
|
18750
18757
|
|
|
18758
|
+
// Preserve any OAuth state (tokens / DCR client info / PKCE verifier)
|
|
18759
|
+
// written out-of-band by saveOAuthState. A fresh providerEntry would
|
|
18760
|
+
// otherwise drop it, wiping tokens whenever the user edits/re-saves an
|
|
18761
|
+
// OAuth MCP provider.
|
|
18762
|
+
if (prev.oauth) {
|
|
18763
|
+
providerEntry.oauth = prev.oauth;
|
|
18764
|
+
}
|
|
18765
|
+
|
|
18751
18766
|
// Single-winner invariant: when flipping this provider's flag to
|
|
18752
18767
|
// true, clear it on every other provider with the same type. Run
|
|
18753
18768
|
// this BEFORE we set `providers[providerName] = providerEntry` so
|
|
@@ -19025,6 +19040,86 @@ function requireProviderController () {
|
|
|
19025
19040
|
};
|
|
19026
19041
|
}
|
|
19027
19042
|
},
|
|
19043
|
+
|
|
19044
|
+
/**
|
|
19045
|
+
* saveOAuthState
|
|
19046
|
+
* Persist an MCP OAuth session blob (tokens, DCR client info, PKCE
|
|
19047
|
+
* verifier) encrypted alongside the provider entry. Used by the SDK
|
|
19048
|
+
* OAuthClientProvider (mcpOAuthProvider.js). Creates a minimal MCP
|
|
19049
|
+
* provider entry if one doesn't exist yet, so "Authorize" can run
|
|
19050
|
+
* before the provider is formally saved (the later saveProvider
|
|
19051
|
+
* preserves this blob).
|
|
19052
|
+
*
|
|
19053
|
+
* @param {BrowserWindow} win the main window (unused; signature parity)
|
|
19054
|
+
* @param {string} appId the application id
|
|
19055
|
+
* @param {string} providerName the provider/server name
|
|
19056
|
+
* @param {object} oauthState { tokens?, clientInformation?, codeVerifier? }
|
|
19057
|
+
*/
|
|
19058
|
+
saveOAuthState: (win, appId, providerName, oauthState) => {
|
|
19059
|
+
try {
|
|
19060
|
+
const filename = path.join(
|
|
19061
|
+
app.getPath("userData"),
|
|
19062
|
+
appName,
|
|
19063
|
+
appId,
|
|
19064
|
+
configFilename,
|
|
19065
|
+
);
|
|
19066
|
+
ensureDirectoryExistence(filename);
|
|
19067
|
+
|
|
19068
|
+
const providers = getFileContents(filename, {});
|
|
19069
|
+
const encrypted = safeStorage
|
|
19070
|
+
.encryptString(JSON.stringify(oauthState || {}))
|
|
19071
|
+
.toString("base64");
|
|
19072
|
+
|
|
19073
|
+
const prev = providers[providerName] || {};
|
|
19074
|
+
providers[providerName] = {
|
|
19075
|
+
...prev,
|
|
19076
|
+
providerClass: prev.providerClass || "mcp",
|
|
19077
|
+
oauth: encrypted,
|
|
19078
|
+
dateCreated: prev.dateCreated || new Date().toISOString(),
|
|
19079
|
+
dateUpdated: new Date().toISOString(),
|
|
19080
|
+
};
|
|
19081
|
+
|
|
19082
|
+
writeFileSync(filename, JSON.stringify(providers, null, 2), {
|
|
19083
|
+
mode: 0o600,
|
|
19084
|
+
});
|
|
19085
|
+
|
|
19086
|
+
return { success: true };
|
|
19087
|
+
} catch (error) {
|
|
19088
|
+
console.error("[providerController] Error saving OAuth state:", error);
|
|
19089
|
+
return { error: true, message: error.message };
|
|
19090
|
+
}
|
|
19091
|
+
},
|
|
19092
|
+
|
|
19093
|
+
/**
|
|
19094
|
+
* getOAuthState
|
|
19095
|
+
* Read and decrypt the OAuth session blob for a provider, or `{}` if
|
|
19096
|
+
* none exists. Main-process only — never surfaced to the renderer.
|
|
19097
|
+
*
|
|
19098
|
+
* @param {BrowserWindow} win the main window (unused; signature parity)
|
|
19099
|
+
* @param {string} appId the application id
|
|
19100
|
+
* @param {string} providerName the provider/server name
|
|
19101
|
+
* @returns {{ oauth?: object }}
|
|
19102
|
+
*/
|
|
19103
|
+
getOAuthState: (win, appId, providerName) => {
|
|
19104
|
+
try {
|
|
19105
|
+
const filename = path.join(
|
|
19106
|
+
app.getPath("userData"),
|
|
19107
|
+
appName,
|
|
19108
|
+
appId,
|
|
19109
|
+
configFilename,
|
|
19110
|
+
);
|
|
19111
|
+
const providers = getFileContents(filename, {});
|
|
19112
|
+
const entry = providers[providerName];
|
|
19113
|
+
if (!entry || !entry.oauth) return {};
|
|
19114
|
+
|
|
19115
|
+
const buffer = Buffer.from(entry.oauth, "base64");
|
|
19116
|
+
const decrypted = safeStorage.decryptString(buffer);
|
|
19117
|
+
return { oauth: JSON.parse(decrypted) };
|
|
19118
|
+
} catch (error) {
|
|
19119
|
+
console.error("[providerController] Error reading OAuth state:", error);
|
|
19120
|
+
return {};
|
|
19121
|
+
}
|
|
19122
|
+
},
|
|
19028
19123
|
};
|
|
19029
19124
|
|
|
19030
19125
|
providerController_1 = providerController;
|
|
@@ -30734,11 +30829,11 @@ var __importStar$4 = (commonjsGlobal && commonjsGlobal.__importStar) || function
|
|
|
30734
30829
|
Object.defineProperty(parse$2, "__esModule", { value: true });
|
|
30735
30830
|
parse$2.safeParseAsync = parse$2.safeParse = parse$2.parseAsync = parse$2.parse = void 0;
|
|
30736
30831
|
const core$5 = __importStar$4(core$8);
|
|
30737
|
-
const errors_js_1$
|
|
30738
|
-
parse$2.parse = core$5._parse(errors_js_1$
|
|
30739
|
-
parse$2.parseAsync = core$5._parseAsync(errors_js_1$
|
|
30740
|
-
parse$2.safeParse = core$5._safeParse(errors_js_1$
|
|
30741
|
-
parse$2.safeParseAsync = core$5._safeParseAsync(errors_js_1$
|
|
30832
|
+
const errors_js_1$1 = errors$3;
|
|
30833
|
+
parse$2.parse = core$5._parse(errors_js_1$1.ZodRealError);
|
|
30834
|
+
parse$2.parseAsync = core$5._parseAsync(errors_js_1$1.ZodRealError);
|
|
30835
|
+
parse$2.safeParse = core$5._safeParse(errors_js_1$1.ZodRealError);
|
|
30836
|
+
parse$2.safeParseAsync = core$5._safeParseAsync(errors_js_1$1.ZodRealError);
|
|
30742
30837
|
|
|
30743
30838
|
var hasRequiredSchemas;
|
|
30744
30839
|
|
|
@@ -34204,1426 +34299,1457 @@ function date$1(params) {
|
|
|
34204
34299
|
|
|
34205
34300
|
} (types$2));
|
|
34206
34301
|
|
|
34207
|
-
var auth$2 = {};
|
|
34208
|
-
|
|
34209
34302
|
var auth$1 = {};
|
|
34210
34303
|
|
|
34211
|
-
|
|
34212
|
-
|
|
34213
|
-
|
|
34214
|
-
|
|
34215
|
-
|
|
34216
|
-
|
|
34304
|
+
var auth = {};
|
|
34305
|
+
|
|
34306
|
+
var hasRequiredAuth$1;
|
|
34307
|
+
|
|
34308
|
+
function requireAuth$1 () {
|
|
34309
|
+
if (hasRequiredAuth$1) return auth;
|
|
34310
|
+
hasRequiredAuth$1 = 1;
|
|
34311
|
+
(function (exports) {
|
|
34312
|
+
var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
34313
|
+
if (k2 === undefined) k2 = k;
|
|
34314
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
34315
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
34316
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
34317
|
+
}
|
|
34318
|
+
Object.defineProperty(o, k2, desc);
|
|
34319
|
+
}) : (function(o, m, k, k2) {
|
|
34320
|
+
if (k2 === undefined) k2 = k;
|
|
34321
|
+
o[k2] = m[k];
|
|
34322
|
+
}));
|
|
34323
|
+
var __setModuleDefault = (commonjsGlobal && commonjsGlobal.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
34324
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
34325
|
+
}) : function(o, v) {
|
|
34326
|
+
o["default"] = v;
|
|
34327
|
+
});
|
|
34328
|
+
var __importStar = (commonjsGlobal && commonjsGlobal.__importStar) || function (mod) {
|
|
34329
|
+
if (mod && mod.__esModule) return mod;
|
|
34330
|
+
var result = {};
|
|
34331
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
34332
|
+
__setModuleDefault(result, mod);
|
|
34333
|
+
return result;
|
|
34334
|
+
};
|
|
34335
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
34336
|
+
exports.OAuthTokenRevocationRequestSchema = exports.OAuthClientRegistrationErrorSchema = exports.OAuthClientInformationFullSchema = exports.OAuthClientInformationSchema = exports.OAuthClientMetadataSchema = exports.OptionalSafeUrlSchema = exports.OAuthErrorResponseSchema = exports.OAuthTokensSchema = exports.OpenIdProviderDiscoveryMetadataSchema = exports.OpenIdProviderMetadataSchema = exports.OAuthMetadataSchema = exports.OAuthProtectedResourceMetadataSchema = exports.SafeUrlSchema = void 0;
|
|
34337
|
+
const z = __importStar(v4);
|
|
34338
|
+
/**
|
|
34339
|
+
* Reusable URL validation that disallows javascript: scheme
|
|
34340
|
+
*/
|
|
34341
|
+
exports.SafeUrlSchema = z
|
|
34342
|
+
.url()
|
|
34343
|
+
.superRefine((val, ctx) => {
|
|
34344
|
+
if (!URL.canParse(val)) {
|
|
34345
|
+
ctx.addIssue({
|
|
34346
|
+
code: z.ZodIssueCode.custom,
|
|
34347
|
+
message: 'URL must be parseable',
|
|
34348
|
+
fatal: true
|
|
34349
|
+
});
|
|
34350
|
+
return z.NEVER;
|
|
34351
|
+
}
|
|
34352
|
+
})
|
|
34353
|
+
.refine(url => {
|
|
34354
|
+
const u = new URL(url);
|
|
34355
|
+
return u.protocol !== 'javascript:' && u.protocol !== 'data:' && u.protocol !== 'vbscript:';
|
|
34356
|
+
}, { message: 'URL cannot use javascript:, data:, or vbscript: scheme' });
|
|
34357
|
+
/**
|
|
34358
|
+
* RFC 9728 OAuth Protected Resource Metadata
|
|
34359
|
+
*/
|
|
34360
|
+
exports.OAuthProtectedResourceMetadataSchema = z.looseObject({
|
|
34361
|
+
resource: z.string().url(),
|
|
34362
|
+
authorization_servers: z.array(exports.SafeUrlSchema).optional(),
|
|
34363
|
+
jwks_uri: z.string().url().optional(),
|
|
34364
|
+
scopes_supported: z.array(z.string()).optional(),
|
|
34365
|
+
bearer_methods_supported: z.array(z.string()).optional(),
|
|
34366
|
+
resource_signing_alg_values_supported: z.array(z.string()).optional(),
|
|
34367
|
+
resource_name: z.string().optional(),
|
|
34368
|
+
resource_documentation: z.string().optional(),
|
|
34369
|
+
resource_policy_uri: z.string().url().optional(),
|
|
34370
|
+
resource_tos_uri: z.string().url().optional(),
|
|
34371
|
+
tls_client_certificate_bound_access_tokens: z.boolean().optional(),
|
|
34372
|
+
authorization_details_types_supported: z.array(z.string()).optional(),
|
|
34373
|
+
dpop_signing_alg_values_supported: z.array(z.string()).optional(),
|
|
34374
|
+
dpop_bound_access_tokens_required: z.boolean().optional()
|
|
34375
|
+
});
|
|
34376
|
+
/**
|
|
34377
|
+
* RFC 8414 OAuth 2.0 Authorization Server Metadata
|
|
34378
|
+
*/
|
|
34379
|
+
exports.OAuthMetadataSchema = z.looseObject({
|
|
34380
|
+
issuer: z.string(),
|
|
34381
|
+
authorization_endpoint: exports.SafeUrlSchema,
|
|
34382
|
+
token_endpoint: exports.SafeUrlSchema,
|
|
34383
|
+
registration_endpoint: exports.SafeUrlSchema.optional(),
|
|
34384
|
+
scopes_supported: z.array(z.string()).optional(),
|
|
34385
|
+
response_types_supported: z.array(z.string()),
|
|
34386
|
+
response_modes_supported: z.array(z.string()).optional(),
|
|
34387
|
+
grant_types_supported: z.array(z.string()).optional(),
|
|
34388
|
+
token_endpoint_auth_methods_supported: z.array(z.string()).optional(),
|
|
34389
|
+
token_endpoint_auth_signing_alg_values_supported: z.array(z.string()).optional(),
|
|
34390
|
+
service_documentation: exports.SafeUrlSchema.optional(),
|
|
34391
|
+
revocation_endpoint: exports.SafeUrlSchema.optional(),
|
|
34392
|
+
revocation_endpoint_auth_methods_supported: z.array(z.string()).optional(),
|
|
34393
|
+
revocation_endpoint_auth_signing_alg_values_supported: z.array(z.string()).optional(),
|
|
34394
|
+
introspection_endpoint: z.string().optional(),
|
|
34395
|
+
introspection_endpoint_auth_methods_supported: z.array(z.string()).optional(),
|
|
34396
|
+
introspection_endpoint_auth_signing_alg_values_supported: z.array(z.string()).optional(),
|
|
34397
|
+
code_challenge_methods_supported: z.array(z.string()).optional(),
|
|
34398
|
+
client_id_metadata_document_supported: z.boolean().optional()
|
|
34399
|
+
});
|
|
34400
|
+
/**
|
|
34401
|
+
* OpenID Connect Discovery 1.0 Provider Metadata
|
|
34402
|
+
* see: https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
|
|
34403
|
+
*/
|
|
34404
|
+
exports.OpenIdProviderMetadataSchema = z.looseObject({
|
|
34405
|
+
issuer: z.string(),
|
|
34406
|
+
authorization_endpoint: exports.SafeUrlSchema,
|
|
34407
|
+
token_endpoint: exports.SafeUrlSchema,
|
|
34408
|
+
userinfo_endpoint: exports.SafeUrlSchema.optional(),
|
|
34409
|
+
jwks_uri: exports.SafeUrlSchema,
|
|
34410
|
+
registration_endpoint: exports.SafeUrlSchema.optional(),
|
|
34411
|
+
scopes_supported: z.array(z.string()).optional(),
|
|
34412
|
+
response_types_supported: z.array(z.string()),
|
|
34413
|
+
response_modes_supported: z.array(z.string()).optional(),
|
|
34414
|
+
grant_types_supported: z.array(z.string()).optional(),
|
|
34415
|
+
acr_values_supported: z.array(z.string()).optional(),
|
|
34416
|
+
subject_types_supported: z.array(z.string()),
|
|
34417
|
+
id_token_signing_alg_values_supported: z.array(z.string()),
|
|
34418
|
+
id_token_encryption_alg_values_supported: z.array(z.string()).optional(),
|
|
34419
|
+
id_token_encryption_enc_values_supported: z.array(z.string()).optional(),
|
|
34420
|
+
userinfo_signing_alg_values_supported: z.array(z.string()).optional(),
|
|
34421
|
+
userinfo_encryption_alg_values_supported: z.array(z.string()).optional(),
|
|
34422
|
+
userinfo_encryption_enc_values_supported: z.array(z.string()).optional(),
|
|
34423
|
+
request_object_signing_alg_values_supported: z.array(z.string()).optional(),
|
|
34424
|
+
request_object_encryption_alg_values_supported: z.array(z.string()).optional(),
|
|
34425
|
+
request_object_encryption_enc_values_supported: z.array(z.string()).optional(),
|
|
34426
|
+
token_endpoint_auth_methods_supported: z.array(z.string()).optional(),
|
|
34427
|
+
token_endpoint_auth_signing_alg_values_supported: z.array(z.string()).optional(),
|
|
34428
|
+
display_values_supported: z.array(z.string()).optional(),
|
|
34429
|
+
claim_types_supported: z.array(z.string()).optional(),
|
|
34430
|
+
claims_supported: z.array(z.string()).optional(),
|
|
34431
|
+
service_documentation: z.string().optional(),
|
|
34432
|
+
claims_locales_supported: z.array(z.string()).optional(),
|
|
34433
|
+
ui_locales_supported: z.array(z.string()).optional(),
|
|
34434
|
+
claims_parameter_supported: z.boolean().optional(),
|
|
34435
|
+
request_parameter_supported: z.boolean().optional(),
|
|
34436
|
+
request_uri_parameter_supported: z.boolean().optional(),
|
|
34437
|
+
require_request_uri_registration: z.boolean().optional(),
|
|
34438
|
+
op_policy_uri: exports.SafeUrlSchema.optional(),
|
|
34439
|
+
op_tos_uri: exports.SafeUrlSchema.optional(),
|
|
34440
|
+
client_id_metadata_document_supported: z.boolean().optional()
|
|
34441
|
+
});
|
|
34442
|
+
/**
|
|
34443
|
+
* OpenID Connect Discovery metadata that may include OAuth 2.0 fields
|
|
34444
|
+
* This schema represents the real-world scenario where OIDC providers
|
|
34445
|
+
* return a mix of OpenID Connect and OAuth 2.0 metadata fields
|
|
34446
|
+
*/
|
|
34447
|
+
exports.OpenIdProviderDiscoveryMetadataSchema = z.object({
|
|
34448
|
+
...exports.OpenIdProviderMetadataSchema.shape,
|
|
34449
|
+
...exports.OAuthMetadataSchema.pick({
|
|
34450
|
+
code_challenge_methods_supported: true
|
|
34451
|
+
}).shape
|
|
34452
|
+
});
|
|
34453
|
+
/**
|
|
34454
|
+
* OAuth 2.1 token response
|
|
34455
|
+
*/
|
|
34456
|
+
exports.OAuthTokensSchema = z
|
|
34457
|
+
.object({
|
|
34458
|
+
access_token: z.string(),
|
|
34459
|
+
id_token: z.string().optional(), // Optional for OAuth 2.1, but necessary in OpenID Connect
|
|
34460
|
+
token_type: z.string(),
|
|
34461
|
+
expires_in: z.coerce.number().optional(),
|
|
34462
|
+
scope: z.string().optional(),
|
|
34463
|
+
refresh_token: z.string().optional()
|
|
34464
|
+
})
|
|
34465
|
+
.strip();
|
|
34466
|
+
/**
|
|
34467
|
+
* OAuth 2.1 error response
|
|
34468
|
+
*/
|
|
34469
|
+
exports.OAuthErrorResponseSchema = z.object({
|
|
34470
|
+
error: z.string(),
|
|
34471
|
+
error_description: z.string().optional(),
|
|
34472
|
+
error_uri: z.string().optional()
|
|
34473
|
+
});
|
|
34474
|
+
/**
|
|
34475
|
+
* Optional version of SafeUrlSchema that allows empty string for retrocompatibility on tos_uri and logo_uri
|
|
34476
|
+
*/
|
|
34477
|
+
exports.OptionalSafeUrlSchema = exports.SafeUrlSchema.optional().or(z.literal('').transform(() => undefined));
|
|
34478
|
+
/**
|
|
34479
|
+
* RFC 7591 OAuth 2.0 Dynamic Client Registration metadata
|
|
34480
|
+
*/
|
|
34481
|
+
exports.OAuthClientMetadataSchema = z
|
|
34482
|
+
.object({
|
|
34483
|
+
redirect_uris: z.array(exports.SafeUrlSchema),
|
|
34484
|
+
token_endpoint_auth_method: z.string().optional(),
|
|
34485
|
+
grant_types: z.array(z.string()).optional(),
|
|
34486
|
+
response_types: z.array(z.string()).optional(),
|
|
34487
|
+
client_name: z.string().optional(),
|
|
34488
|
+
client_uri: exports.SafeUrlSchema.optional(),
|
|
34489
|
+
logo_uri: exports.OptionalSafeUrlSchema,
|
|
34490
|
+
scope: z.string().optional(),
|
|
34491
|
+
contacts: z.array(z.string()).optional(),
|
|
34492
|
+
tos_uri: exports.OptionalSafeUrlSchema,
|
|
34493
|
+
policy_uri: z.string().optional(),
|
|
34494
|
+
jwks_uri: exports.SafeUrlSchema.optional(),
|
|
34495
|
+
jwks: z.any().optional(),
|
|
34496
|
+
software_id: z.string().optional(),
|
|
34497
|
+
software_version: z.string().optional(),
|
|
34498
|
+
software_statement: z.string().optional()
|
|
34499
|
+
})
|
|
34500
|
+
.strip();
|
|
34501
|
+
/**
|
|
34502
|
+
* RFC 7591 OAuth 2.0 Dynamic Client Registration client information
|
|
34503
|
+
*/
|
|
34504
|
+
exports.OAuthClientInformationSchema = z
|
|
34505
|
+
.object({
|
|
34506
|
+
client_id: z.string(),
|
|
34507
|
+
client_secret: z.string().optional(),
|
|
34508
|
+
client_id_issued_at: z.number().optional(),
|
|
34509
|
+
client_secret_expires_at: z.number().optional()
|
|
34510
|
+
})
|
|
34511
|
+
.strip();
|
|
34512
|
+
/**
|
|
34513
|
+
* RFC 7591 OAuth 2.0 Dynamic Client Registration full response (client information plus metadata)
|
|
34514
|
+
*/
|
|
34515
|
+
exports.OAuthClientInformationFullSchema = exports.OAuthClientMetadataSchema.merge(exports.OAuthClientInformationSchema);
|
|
34516
|
+
/**
|
|
34517
|
+
* RFC 7591 OAuth 2.0 Dynamic Client Registration error response
|
|
34518
|
+
*/
|
|
34519
|
+
exports.OAuthClientRegistrationErrorSchema = z
|
|
34520
|
+
.object({
|
|
34521
|
+
error: z.string(),
|
|
34522
|
+
error_description: z.string().optional()
|
|
34523
|
+
})
|
|
34524
|
+
.strip();
|
|
34525
|
+
/**
|
|
34526
|
+
* RFC 7009 OAuth 2.0 Token Revocation request
|
|
34527
|
+
*/
|
|
34528
|
+
exports.OAuthTokenRevocationRequestSchema = z
|
|
34529
|
+
.object({
|
|
34530
|
+
token: z.string(),
|
|
34531
|
+
token_type_hint: z.string().optional()
|
|
34532
|
+
})
|
|
34533
|
+
.strip();
|
|
34534
|
+
|
|
34535
|
+
} (auth));
|
|
34536
|
+
return auth;
|
|
34537
|
+
}
|
|
34538
|
+
|
|
34539
|
+
var authUtils = {};
|
|
34540
|
+
|
|
34541
|
+
var hasRequiredAuthUtils;
|
|
34542
|
+
|
|
34543
|
+
function requireAuthUtils () {
|
|
34544
|
+
if (hasRequiredAuthUtils) return authUtils;
|
|
34545
|
+
hasRequiredAuthUtils = 1;
|
|
34546
|
+
/**
|
|
34547
|
+
* Utilities for handling OAuth resource URIs.
|
|
34548
|
+
*/
|
|
34549
|
+
Object.defineProperty(authUtils, "__esModule", { value: true });
|
|
34550
|
+
authUtils.resourceUrlFromServerUrl = resourceUrlFromServerUrl;
|
|
34551
|
+
authUtils.checkResourceAllowed = checkResourceAllowed;
|
|
34552
|
+
/**
|
|
34553
|
+
* Converts a server URL to a resource URL by removing the fragment.
|
|
34554
|
+
* RFC 8707 section 2 states that resource URIs "MUST NOT include a fragment component".
|
|
34555
|
+
* Keeps everything else unchanged (scheme, domain, port, path, query).
|
|
34556
|
+
*/
|
|
34557
|
+
function resourceUrlFromServerUrl(url) {
|
|
34558
|
+
const resourceURL = typeof url === 'string' ? new URL(url) : new URL(url.href);
|
|
34559
|
+
resourceURL.hash = ''; // Remove fragment
|
|
34560
|
+
return resourceURL;
|
|
34561
|
+
}
|
|
34562
|
+
/**
|
|
34563
|
+
* Checks if a requested resource URL matches a configured resource URL.
|
|
34564
|
+
* A requested resource matches if it has the same scheme, domain, port,
|
|
34565
|
+
* and its path starts with the configured resource's path.
|
|
34566
|
+
*
|
|
34567
|
+
* @param requestedResource The resource URL being requested
|
|
34568
|
+
* @param configuredResource The resource URL that has been configured
|
|
34569
|
+
* @returns true if the requested resource matches the configured resource, false otherwise
|
|
34570
|
+
*/
|
|
34571
|
+
function checkResourceAllowed({ requestedResource, configuredResource }) {
|
|
34572
|
+
const requested = typeof requestedResource === 'string' ? new URL(requestedResource) : new URL(requestedResource.href);
|
|
34573
|
+
const configured = typeof configuredResource === 'string' ? new URL(configuredResource) : new URL(configuredResource.href);
|
|
34574
|
+
// Compare the origin (scheme, domain, and port)
|
|
34575
|
+
if (requested.origin !== configured.origin) {
|
|
34576
|
+
return false;
|
|
34217
34577
|
}
|
|
34218
|
-
|
|
34219
|
-
|
|
34220
|
-
|
|
34221
|
-
|
|
34222
|
-
|
|
34223
|
-
|
|
34224
|
-
|
|
34225
|
-
|
|
34226
|
-
|
|
34227
|
-
|
|
34228
|
-
|
|
34229
|
-
|
|
34230
|
-
|
|
34231
|
-
|
|
34232
|
-
|
|
34233
|
-
|
|
34234
|
-
|
|
34235
|
-
|
|
34236
|
-
|
|
34237
|
-
|
|
34578
|
+
// Handle cases like requested=/foo and configured=/foo/
|
|
34579
|
+
if (requested.pathname.length < configured.pathname.length) {
|
|
34580
|
+
return false;
|
|
34581
|
+
}
|
|
34582
|
+
// Check if the requested path starts with the configured path
|
|
34583
|
+
// Ensure both paths end with / for proper comparison
|
|
34584
|
+
// This ensures that if we have paths like "/api" and "/api/users",
|
|
34585
|
+
// we properly detect that "/api/users" is a subpath of "/api"
|
|
34586
|
+
// By adding a trailing slash if missing, we avoid false positives
|
|
34587
|
+
// where paths like "/api123" would incorrectly match "/api"
|
|
34588
|
+
const requestedPath = requested.pathname.endsWith('/') ? requested.pathname : requested.pathname + '/';
|
|
34589
|
+
const configuredPath = configured.pathname.endsWith('/') ? configured.pathname : configured.pathname + '/';
|
|
34590
|
+
return requestedPath.startsWith(configuredPath);
|
|
34591
|
+
}
|
|
34592
|
+
|
|
34593
|
+
return authUtils;
|
|
34594
|
+
}
|
|
34595
|
+
|
|
34596
|
+
var errors$2 = {};
|
|
34597
|
+
|
|
34598
|
+
var hasRequiredErrors$1;
|
|
34599
|
+
|
|
34600
|
+
function requireErrors$1 () {
|
|
34601
|
+
if (hasRequiredErrors$1) return errors$2;
|
|
34602
|
+
hasRequiredErrors$1 = 1;
|
|
34603
|
+
Object.defineProperty(errors$2, "__esModule", { value: true });
|
|
34604
|
+
errors$2.OAUTH_ERRORS = errors$2.CustomOAuthError = errors$2.InvalidTargetError = errors$2.InsufficientScopeError = errors$2.InvalidClientMetadataError = errors$2.TooManyRequestsError = errors$2.MethodNotAllowedError = errors$2.InvalidTokenError = errors$2.UnsupportedTokenTypeError = errors$2.UnsupportedResponseTypeError = errors$2.TemporarilyUnavailableError = errors$2.ServerError = errors$2.AccessDeniedError = errors$2.InvalidScopeError = errors$2.UnsupportedGrantTypeError = errors$2.UnauthorizedClientError = errors$2.InvalidGrantError = errors$2.InvalidClientError = errors$2.InvalidRequestError = errors$2.OAuthError = void 0;
|
|
34238
34605
|
/**
|
|
34239
|
-
*
|
|
34606
|
+
* Base class for all OAuth errors
|
|
34240
34607
|
*/
|
|
34241
|
-
|
|
34242
|
-
|
|
34243
|
-
|
|
34244
|
-
|
|
34245
|
-
|
|
34246
|
-
code: z.ZodIssueCode.custom,
|
|
34247
|
-
message: 'URL must be parseable',
|
|
34248
|
-
fatal: true
|
|
34249
|
-
});
|
|
34250
|
-
return z.NEVER;
|
|
34608
|
+
class OAuthError extends Error {
|
|
34609
|
+
constructor(message, errorUri) {
|
|
34610
|
+
super(message);
|
|
34611
|
+
this.errorUri = errorUri;
|
|
34612
|
+
this.name = this.constructor.name;
|
|
34251
34613
|
}
|
|
34252
|
-
|
|
34253
|
-
|
|
34254
|
-
|
|
34255
|
-
|
|
34256
|
-
|
|
34614
|
+
/**
|
|
34615
|
+
* Converts the error to a standard OAuth error response object
|
|
34616
|
+
*/
|
|
34617
|
+
toResponseObject() {
|
|
34618
|
+
const response = {
|
|
34619
|
+
error: this.errorCode,
|
|
34620
|
+
error_description: this.message
|
|
34621
|
+
};
|
|
34622
|
+
if (this.errorUri) {
|
|
34623
|
+
response.error_uri = this.errorUri;
|
|
34624
|
+
}
|
|
34625
|
+
return response;
|
|
34626
|
+
}
|
|
34627
|
+
get errorCode() {
|
|
34628
|
+
return this.constructor.errorCode;
|
|
34629
|
+
}
|
|
34630
|
+
}
|
|
34631
|
+
errors$2.OAuthError = OAuthError;
|
|
34257
34632
|
/**
|
|
34258
|
-
*
|
|
34633
|
+
* Invalid request error - The request is missing a required parameter,
|
|
34634
|
+
* includes an invalid parameter value, includes a parameter more than once,
|
|
34635
|
+
* or is otherwise malformed.
|
|
34259
34636
|
*/
|
|
34260
|
-
|
|
34261
|
-
|
|
34262
|
-
|
|
34263
|
-
|
|
34264
|
-
scopes_supported: z.array(z.string()).optional(),
|
|
34265
|
-
bearer_methods_supported: z.array(z.string()).optional(),
|
|
34266
|
-
resource_signing_alg_values_supported: z.array(z.string()).optional(),
|
|
34267
|
-
resource_name: z.string().optional(),
|
|
34268
|
-
resource_documentation: z.string().optional(),
|
|
34269
|
-
resource_policy_uri: z.string().url().optional(),
|
|
34270
|
-
resource_tos_uri: z.string().url().optional(),
|
|
34271
|
-
tls_client_certificate_bound_access_tokens: z.boolean().optional(),
|
|
34272
|
-
authorization_details_types_supported: z.array(z.string()).optional(),
|
|
34273
|
-
dpop_signing_alg_values_supported: z.array(z.string()).optional(),
|
|
34274
|
-
dpop_bound_access_tokens_required: z.boolean().optional()
|
|
34275
|
-
});
|
|
34637
|
+
class InvalidRequestError extends OAuthError {
|
|
34638
|
+
}
|
|
34639
|
+
errors$2.InvalidRequestError = InvalidRequestError;
|
|
34640
|
+
InvalidRequestError.errorCode = 'invalid_request';
|
|
34276
34641
|
/**
|
|
34277
|
-
*
|
|
34642
|
+
* Invalid client error - Client authentication failed (e.g., unknown client, no client
|
|
34643
|
+
* authentication included, or unsupported authentication method).
|
|
34278
34644
|
*/
|
|
34279
|
-
|
|
34280
|
-
|
|
34281
|
-
|
|
34282
|
-
|
|
34283
|
-
registration_endpoint: exports.SafeUrlSchema.optional(),
|
|
34284
|
-
scopes_supported: z.array(z.string()).optional(),
|
|
34285
|
-
response_types_supported: z.array(z.string()),
|
|
34286
|
-
response_modes_supported: z.array(z.string()).optional(),
|
|
34287
|
-
grant_types_supported: z.array(z.string()).optional(),
|
|
34288
|
-
token_endpoint_auth_methods_supported: z.array(z.string()).optional(),
|
|
34289
|
-
token_endpoint_auth_signing_alg_values_supported: z.array(z.string()).optional(),
|
|
34290
|
-
service_documentation: exports.SafeUrlSchema.optional(),
|
|
34291
|
-
revocation_endpoint: exports.SafeUrlSchema.optional(),
|
|
34292
|
-
revocation_endpoint_auth_methods_supported: z.array(z.string()).optional(),
|
|
34293
|
-
revocation_endpoint_auth_signing_alg_values_supported: z.array(z.string()).optional(),
|
|
34294
|
-
introspection_endpoint: z.string().optional(),
|
|
34295
|
-
introspection_endpoint_auth_methods_supported: z.array(z.string()).optional(),
|
|
34296
|
-
introspection_endpoint_auth_signing_alg_values_supported: z.array(z.string()).optional(),
|
|
34297
|
-
code_challenge_methods_supported: z.array(z.string()).optional(),
|
|
34298
|
-
client_id_metadata_document_supported: z.boolean().optional()
|
|
34299
|
-
});
|
|
34645
|
+
class InvalidClientError extends OAuthError {
|
|
34646
|
+
}
|
|
34647
|
+
errors$2.InvalidClientError = InvalidClientError;
|
|
34648
|
+
InvalidClientError.errorCode = 'invalid_client';
|
|
34300
34649
|
/**
|
|
34301
|
-
*
|
|
34302
|
-
*
|
|
34650
|
+
* Invalid grant error - The provided authorization grant or refresh token is
|
|
34651
|
+
* invalid, expired, revoked, does not match the redirection URI used in the
|
|
34652
|
+
* authorization request, or was issued to another client.
|
|
34303
34653
|
*/
|
|
34304
|
-
|
|
34305
|
-
|
|
34306
|
-
|
|
34307
|
-
|
|
34308
|
-
userinfo_endpoint: exports.SafeUrlSchema.optional(),
|
|
34309
|
-
jwks_uri: exports.SafeUrlSchema,
|
|
34310
|
-
registration_endpoint: exports.SafeUrlSchema.optional(),
|
|
34311
|
-
scopes_supported: z.array(z.string()).optional(),
|
|
34312
|
-
response_types_supported: z.array(z.string()),
|
|
34313
|
-
response_modes_supported: z.array(z.string()).optional(),
|
|
34314
|
-
grant_types_supported: z.array(z.string()).optional(),
|
|
34315
|
-
acr_values_supported: z.array(z.string()).optional(),
|
|
34316
|
-
subject_types_supported: z.array(z.string()),
|
|
34317
|
-
id_token_signing_alg_values_supported: z.array(z.string()),
|
|
34318
|
-
id_token_encryption_alg_values_supported: z.array(z.string()).optional(),
|
|
34319
|
-
id_token_encryption_enc_values_supported: z.array(z.string()).optional(),
|
|
34320
|
-
userinfo_signing_alg_values_supported: z.array(z.string()).optional(),
|
|
34321
|
-
userinfo_encryption_alg_values_supported: z.array(z.string()).optional(),
|
|
34322
|
-
userinfo_encryption_enc_values_supported: z.array(z.string()).optional(),
|
|
34323
|
-
request_object_signing_alg_values_supported: z.array(z.string()).optional(),
|
|
34324
|
-
request_object_encryption_alg_values_supported: z.array(z.string()).optional(),
|
|
34325
|
-
request_object_encryption_enc_values_supported: z.array(z.string()).optional(),
|
|
34326
|
-
token_endpoint_auth_methods_supported: z.array(z.string()).optional(),
|
|
34327
|
-
token_endpoint_auth_signing_alg_values_supported: z.array(z.string()).optional(),
|
|
34328
|
-
display_values_supported: z.array(z.string()).optional(),
|
|
34329
|
-
claim_types_supported: z.array(z.string()).optional(),
|
|
34330
|
-
claims_supported: z.array(z.string()).optional(),
|
|
34331
|
-
service_documentation: z.string().optional(),
|
|
34332
|
-
claims_locales_supported: z.array(z.string()).optional(),
|
|
34333
|
-
ui_locales_supported: z.array(z.string()).optional(),
|
|
34334
|
-
claims_parameter_supported: z.boolean().optional(),
|
|
34335
|
-
request_parameter_supported: z.boolean().optional(),
|
|
34336
|
-
request_uri_parameter_supported: z.boolean().optional(),
|
|
34337
|
-
require_request_uri_registration: z.boolean().optional(),
|
|
34338
|
-
op_policy_uri: exports.SafeUrlSchema.optional(),
|
|
34339
|
-
op_tos_uri: exports.SafeUrlSchema.optional(),
|
|
34340
|
-
client_id_metadata_document_supported: z.boolean().optional()
|
|
34341
|
-
});
|
|
34654
|
+
class InvalidGrantError extends OAuthError {
|
|
34655
|
+
}
|
|
34656
|
+
errors$2.InvalidGrantError = InvalidGrantError;
|
|
34657
|
+
InvalidGrantError.errorCode = 'invalid_grant';
|
|
34342
34658
|
/**
|
|
34343
|
-
*
|
|
34344
|
-
*
|
|
34345
|
-
* return a mix of OpenID Connect and OAuth 2.0 metadata fields
|
|
34659
|
+
* Unauthorized client error - The authenticated client is not authorized to use
|
|
34660
|
+
* this authorization grant type.
|
|
34346
34661
|
*/
|
|
34347
|
-
|
|
34348
|
-
|
|
34349
|
-
|
|
34350
|
-
|
|
34351
|
-
}).shape
|
|
34352
|
-
});
|
|
34662
|
+
class UnauthorizedClientError extends OAuthError {
|
|
34663
|
+
}
|
|
34664
|
+
errors$2.UnauthorizedClientError = UnauthorizedClientError;
|
|
34665
|
+
UnauthorizedClientError.errorCode = 'unauthorized_client';
|
|
34353
34666
|
/**
|
|
34354
|
-
*
|
|
34667
|
+
* Unsupported grant type error - The authorization grant type is not supported
|
|
34668
|
+
* by the authorization server.
|
|
34355
34669
|
*/
|
|
34356
|
-
|
|
34357
|
-
|
|
34358
|
-
|
|
34359
|
-
|
|
34360
|
-
token_type: z.string(),
|
|
34361
|
-
expires_in: z.coerce.number().optional(),
|
|
34362
|
-
scope: z.string().optional(),
|
|
34363
|
-
refresh_token: z.string().optional()
|
|
34364
|
-
})
|
|
34365
|
-
.strip();
|
|
34670
|
+
class UnsupportedGrantTypeError extends OAuthError {
|
|
34671
|
+
}
|
|
34672
|
+
errors$2.UnsupportedGrantTypeError = UnsupportedGrantTypeError;
|
|
34673
|
+
UnsupportedGrantTypeError.errorCode = 'unsupported_grant_type';
|
|
34366
34674
|
/**
|
|
34367
|
-
*
|
|
34675
|
+
* Invalid scope error - The requested scope is invalid, unknown, malformed, or
|
|
34676
|
+
* exceeds the scope granted by the resource owner.
|
|
34368
34677
|
*/
|
|
34369
|
-
|
|
34370
|
-
|
|
34371
|
-
|
|
34372
|
-
|
|
34373
|
-
|
|
34678
|
+
class InvalidScopeError extends OAuthError {
|
|
34679
|
+
}
|
|
34680
|
+
errors$2.InvalidScopeError = InvalidScopeError;
|
|
34681
|
+
InvalidScopeError.errorCode = 'invalid_scope';
|
|
34682
|
+
/**
|
|
34683
|
+
* Access denied error - The resource owner or authorization server denied the request.
|
|
34684
|
+
*/
|
|
34685
|
+
class AccessDeniedError extends OAuthError {
|
|
34686
|
+
}
|
|
34687
|
+
errors$2.AccessDeniedError = AccessDeniedError;
|
|
34688
|
+
AccessDeniedError.errorCode = 'access_denied';
|
|
34374
34689
|
/**
|
|
34375
|
-
*
|
|
34690
|
+
* Server error - The authorization server encountered an unexpected condition
|
|
34691
|
+
* that prevented it from fulfilling the request.
|
|
34376
34692
|
*/
|
|
34377
|
-
|
|
34693
|
+
class ServerError extends OAuthError {
|
|
34694
|
+
}
|
|
34695
|
+
errors$2.ServerError = ServerError;
|
|
34696
|
+
ServerError.errorCode = 'server_error';
|
|
34378
34697
|
/**
|
|
34379
|
-
*
|
|
34698
|
+
* Temporarily unavailable error - The authorization server is currently unable to
|
|
34699
|
+
* handle the request due to a temporary overloading or maintenance of the server.
|
|
34380
34700
|
*/
|
|
34381
|
-
|
|
34382
|
-
|
|
34383
|
-
|
|
34384
|
-
|
|
34385
|
-
grant_types: z.array(z.string()).optional(),
|
|
34386
|
-
response_types: z.array(z.string()).optional(),
|
|
34387
|
-
client_name: z.string().optional(),
|
|
34388
|
-
client_uri: exports.SafeUrlSchema.optional(),
|
|
34389
|
-
logo_uri: exports.OptionalSafeUrlSchema,
|
|
34390
|
-
scope: z.string().optional(),
|
|
34391
|
-
contacts: z.array(z.string()).optional(),
|
|
34392
|
-
tos_uri: exports.OptionalSafeUrlSchema,
|
|
34393
|
-
policy_uri: z.string().optional(),
|
|
34394
|
-
jwks_uri: exports.SafeUrlSchema.optional(),
|
|
34395
|
-
jwks: z.any().optional(),
|
|
34396
|
-
software_id: z.string().optional(),
|
|
34397
|
-
software_version: z.string().optional(),
|
|
34398
|
-
software_statement: z.string().optional()
|
|
34399
|
-
})
|
|
34400
|
-
.strip();
|
|
34701
|
+
class TemporarilyUnavailableError extends OAuthError {
|
|
34702
|
+
}
|
|
34703
|
+
errors$2.TemporarilyUnavailableError = TemporarilyUnavailableError;
|
|
34704
|
+
TemporarilyUnavailableError.errorCode = 'temporarily_unavailable';
|
|
34401
34705
|
/**
|
|
34402
|
-
*
|
|
34706
|
+
* Unsupported response type error - The authorization server does not support
|
|
34707
|
+
* obtaining an authorization code using this method.
|
|
34403
34708
|
*/
|
|
34404
|
-
|
|
34405
|
-
|
|
34406
|
-
|
|
34407
|
-
|
|
34408
|
-
client_id_issued_at: z.number().optional(),
|
|
34409
|
-
client_secret_expires_at: z.number().optional()
|
|
34410
|
-
})
|
|
34411
|
-
.strip();
|
|
34709
|
+
class UnsupportedResponseTypeError extends OAuthError {
|
|
34710
|
+
}
|
|
34711
|
+
errors$2.UnsupportedResponseTypeError = UnsupportedResponseTypeError;
|
|
34712
|
+
UnsupportedResponseTypeError.errorCode = 'unsupported_response_type';
|
|
34412
34713
|
/**
|
|
34413
|
-
*
|
|
34714
|
+
* Unsupported token type error - The authorization server does not support
|
|
34715
|
+
* the requested token type.
|
|
34414
34716
|
*/
|
|
34415
|
-
|
|
34717
|
+
class UnsupportedTokenTypeError extends OAuthError {
|
|
34718
|
+
}
|
|
34719
|
+
errors$2.UnsupportedTokenTypeError = UnsupportedTokenTypeError;
|
|
34720
|
+
UnsupportedTokenTypeError.errorCode = 'unsupported_token_type';
|
|
34416
34721
|
/**
|
|
34417
|
-
*
|
|
34722
|
+
* Invalid token error - The access token provided is expired, revoked, malformed,
|
|
34723
|
+
* or invalid for other reasons.
|
|
34418
34724
|
*/
|
|
34419
|
-
|
|
34420
|
-
|
|
34421
|
-
|
|
34422
|
-
|
|
34423
|
-
})
|
|
34424
|
-
.strip();
|
|
34725
|
+
class InvalidTokenError extends OAuthError {
|
|
34726
|
+
}
|
|
34727
|
+
errors$2.InvalidTokenError = InvalidTokenError;
|
|
34728
|
+
InvalidTokenError.errorCode = 'invalid_token';
|
|
34425
34729
|
/**
|
|
34426
|
-
*
|
|
34730
|
+
* Method not allowed error - The HTTP method used is not allowed for this endpoint.
|
|
34731
|
+
* (Custom, non-standard error)
|
|
34427
34732
|
*/
|
|
34428
|
-
|
|
34429
|
-
|
|
34430
|
-
|
|
34431
|
-
|
|
34432
|
-
|
|
34433
|
-
|
|
34733
|
+
class MethodNotAllowedError extends OAuthError {
|
|
34734
|
+
}
|
|
34735
|
+
errors$2.MethodNotAllowedError = MethodNotAllowedError;
|
|
34736
|
+
MethodNotAllowedError.errorCode = 'method_not_allowed';
|
|
34737
|
+
/**
|
|
34738
|
+
* Too many requests error - Rate limit exceeded.
|
|
34739
|
+
* (Custom, non-standard error based on RFC 6585)
|
|
34740
|
+
*/
|
|
34741
|
+
class TooManyRequestsError extends OAuthError {
|
|
34742
|
+
}
|
|
34743
|
+
errors$2.TooManyRequestsError = TooManyRequestsError;
|
|
34744
|
+
TooManyRequestsError.errorCode = 'too_many_requests';
|
|
34745
|
+
/**
|
|
34746
|
+
* Invalid client metadata error - The client metadata is invalid.
|
|
34747
|
+
* (Custom error for dynamic client registration - RFC 7591)
|
|
34748
|
+
*/
|
|
34749
|
+
class InvalidClientMetadataError extends OAuthError {
|
|
34750
|
+
}
|
|
34751
|
+
errors$2.InvalidClientMetadataError = InvalidClientMetadataError;
|
|
34752
|
+
InvalidClientMetadataError.errorCode = 'invalid_client_metadata';
|
|
34753
|
+
/**
|
|
34754
|
+
* Insufficient scope error - The request requires higher privileges than provided by the access token.
|
|
34755
|
+
*/
|
|
34756
|
+
class InsufficientScopeError extends OAuthError {
|
|
34757
|
+
}
|
|
34758
|
+
errors$2.InsufficientScopeError = InsufficientScopeError;
|
|
34759
|
+
InsufficientScopeError.errorCode = 'insufficient_scope';
|
|
34760
|
+
/**
|
|
34761
|
+
* Invalid target error - The requested resource is invalid, missing, unknown, or malformed.
|
|
34762
|
+
* (Custom error for resource indicators - RFC 8707)
|
|
34763
|
+
*/
|
|
34764
|
+
class InvalidTargetError extends OAuthError {
|
|
34765
|
+
}
|
|
34766
|
+
errors$2.InvalidTargetError = InvalidTargetError;
|
|
34767
|
+
InvalidTargetError.errorCode = 'invalid_target';
|
|
34768
|
+
/**
|
|
34769
|
+
* A utility class for defining one-off error codes
|
|
34770
|
+
*/
|
|
34771
|
+
class CustomOAuthError extends OAuthError {
|
|
34772
|
+
constructor(customErrorCode, message, errorUri) {
|
|
34773
|
+
super(message, errorUri);
|
|
34774
|
+
this.customErrorCode = customErrorCode;
|
|
34775
|
+
}
|
|
34776
|
+
get errorCode() {
|
|
34777
|
+
return this.customErrorCode;
|
|
34778
|
+
}
|
|
34779
|
+
}
|
|
34780
|
+
errors$2.CustomOAuthError = CustomOAuthError;
|
|
34781
|
+
/**
|
|
34782
|
+
* A full list of all OAuthErrors, enabling parsing from error responses
|
|
34783
|
+
*/
|
|
34784
|
+
errors$2.OAUTH_ERRORS = {
|
|
34785
|
+
[InvalidRequestError.errorCode]: InvalidRequestError,
|
|
34786
|
+
[InvalidClientError.errorCode]: InvalidClientError,
|
|
34787
|
+
[InvalidGrantError.errorCode]: InvalidGrantError,
|
|
34788
|
+
[UnauthorizedClientError.errorCode]: UnauthorizedClientError,
|
|
34789
|
+
[UnsupportedGrantTypeError.errorCode]: UnsupportedGrantTypeError,
|
|
34790
|
+
[InvalidScopeError.errorCode]: InvalidScopeError,
|
|
34791
|
+
[AccessDeniedError.errorCode]: AccessDeniedError,
|
|
34792
|
+
[ServerError.errorCode]: ServerError,
|
|
34793
|
+
[TemporarilyUnavailableError.errorCode]: TemporarilyUnavailableError,
|
|
34794
|
+
[UnsupportedResponseTypeError.errorCode]: UnsupportedResponseTypeError,
|
|
34795
|
+
[UnsupportedTokenTypeError.errorCode]: UnsupportedTokenTypeError,
|
|
34796
|
+
[InvalidTokenError.errorCode]: InvalidTokenError,
|
|
34797
|
+
[MethodNotAllowedError.errorCode]: MethodNotAllowedError,
|
|
34798
|
+
[TooManyRequestsError.errorCode]: TooManyRequestsError,
|
|
34799
|
+
[InvalidClientMetadataError.errorCode]: InvalidClientMetadataError,
|
|
34800
|
+
[InsufficientScopeError.errorCode]: InsufficientScopeError,
|
|
34801
|
+
[InvalidTargetError.errorCode]: InvalidTargetError
|
|
34802
|
+
};
|
|
34434
34803
|
|
|
34435
|
-
|
|
34436
|
-
|
|
34437
|
-
var authUtils = {};
|
|
34438
|
-
|
|
34439
|
-
/**
|
|
34440
|
-
* Utilities for handling OAuth resource URIs.
|
|
34441
|
-
*/
|
|
34442
|
-
Object.defineProperty(authUtils, "__esModule", { value: true });
|
|
34443
|
-
authUtils.resourceUrlFromServerUrl = resourceUrlFromServerUrl;
|
|
34444
|
-
authUtils.checkResourceAllowed = checkResourceAllowed;
|
|
34445
|
-
/**
|
|
34446
|
-
* Converts a server URL to a resource URL by removing the fragment.
|
|
34447
|
-
* RFC 8707 section 2 states that resource URIs "MUST NOT include a fragment component".
|
|
34448
|
-
* Keeps everything else unchanged (scheme, domain, port, path, query).
|
|
34449
|
-
*/
|
|
34450
|
-
function resourceUrlFromServerUrl(url) {
|
|
34451
|
-
const resourceURL = typeof url === 'string' ? new URL(url) : new URL(url.href);
|
|
34452
|
-
resourceURL.hash = ''; // Remove fragment
|
|
34453
|
-
return resourceURL;
|
|
34804
|
+
return errors$2;
|
|
34454
34805
|
}
|
|
34455
|
-
/**
|
|
34456
|
-
* Checks if a requested resource URL matches a configured resource URL.
|
|
34457
|
-
* A requested resource matches if it has the same scheme, domain, port,
|
|
34458
|
-
* and its path starts with the configured resource's path.
|
|
34459
|
-
*
|
|
34460
|
-
* @param requestedResource The resource URL being requested
|
|
34461
|
-
* @param configuredResource The resource URL that has been configured
|
|
34462
|
-
* @returns true if the requested resource matches the configured resource, false otherwise
|
|
34463
|
-
*/
|
|
34464
|
-
function checkResourceAllowed({ requestedResource, configuredResource }) {
|
|
34465
|
-
const requested = typeof requestedResource === 'string' ? new URL(requestedResource) : new URL(requestedResource.href);
|
|
34466
|
-
const configured = typeof configuredResource === 'string' ? new URL(configuredResource) : new URL(configuredResource.href);
|
|
34467
|
-
// Compare the origin (scheme, domain, and port)
|
|
34468
|
-
if (requested.origin !== configured.origin) {
|
|
34469
|
-
return false;
|
|
34470
|
-
}
|
|
34471
|
-
// Handle cases like requested=/foo and configured=/foo/
|
|
34472
|
-
if (requested.pathname.length < configured.pathname.length) {
|
|
34473
|
-
return false;
|
|
34474
|
-
}
|
|
34475
|
-
// Check if the requested path starts with the configured path
|
|
34476
|
-
// Ensure both paths end with / for proper comparison
|
|
34477
|
-
// This ensures that if we have paths like "/api" and "/api/users",
|
|
34478
|
-
// we properly detect that "/api/users" is a subpath of "/api"
|
|
34479
|
-
// By adding a trailing slash if missing, we avoid false positives
|
|
34480
|
-
// where paths like "/api123" would incorrectly match "/api"
|
|
34481
|
-
const requestedPath = requested.pathname.endsWith('/') ? requested.pathname : requested.pathname + '/';
|
|
34482
|
-
const configuredPath = configured.pathname.endsWith('/') ? configured.pathname : configured.pathname + '/';
|
|
34483
|
-
return requestedPath.startsWith(configuredPath);
|
|
34484
|
-
}
|
|
34485
|
-
|
|
34486
|
-
var errors$2 = {};
|
|
34487
34806
|
|
|
34488
|
-
|
|
34489
|
-
errors$2.OAUTH_ERRORS = errors$2.CustomOAuthError = errors$2.InvalidTargetError = errors$2.InsufficientScopeError = errors$2.InvalidClientMetadataError = errors$2.TooManyRequestsError = errors$2.MethodNotAllowedError = errors$2.InvalidTokenError = errors$2.UnsupportedTokenTypeError = errors$2.UnsupportedResponseTypeError = errors$2.TemporarilyUnavailableError = errors$2.ServerError = errors$2.AccessDeniedError = errors$2.InvalidScopeError = errors$2.UnsupportedGrantTypeError = errors$2.UnauthorizedClientError = errors$2.InvalidGrantError = errors$2.InvalidClientError = errors$2.InvalidRequestError = errors$2.OAuthError = void 0;
|
|
34490
|
-
/**
|
|
34491
|
-
* Base class for all OAuth errors
|
|
34492
|
-
*/
|
|
34493
|
-
class OAuthError extends Error {
|
|
34494
|
-
constructor(message, errorUri) {
|
|
34495
|
-
super(message);
|
|
34496
|
-
this.errorUri = errorUri;
|
|
34497
|
-
this.name = this.constructor.name;
|
|
34498
|
-
}
|
|
34499
|
-
/**
|
|
34500
|
-
* Converts the error to a standard OAuth error response object
|
|
34501
|
-
*/
|
|
34502
|
-
toResponseObject() {
|
|
34503
|
-
const response = {
|
|
34504
|
-
error: this.errorCode,
|
|
34505
|
-
error_description: this.message
|
|
34506
|
-
};
|
|
34507
|
-
if (this.errorUri) {
|
|
34508
|
-
response.error_uri = this.errorUri;
|
|
34509
|
-
}
|
|
34510
|
-
return response;
|
|
34511
|
-
}
|
|
34512
|
-
get errorCode() {
|
|
34513
|
-
return this.constructor.errorCode;
|
|
34514
|
-
}
|
|
34515
|
-
}
|
|
34516
|
-
errors$2.OAuthError = OAuthError;
|
|
34517
|
-
/**
|
|
34518
|
-
* Invalid request error - The request is missing a required parameter,
|
|
34519
|
-
* includes an invalid parameter value, includes a parameter more than once,
|
|
34520
|
-
* or is otherwise malformed.
|
|
34521
|
-
*/
|
|
34522
|
-
class InvalidRequestError extends OAuthError {
|
|
34523
|
-
}
|
|
34524
|
-
errors$2.InvalidRequestError = InvalidRequestError;
|
|
34525
|
-
InvalidRequestError.errorCode = 'invalid_request';
|
|
34526
|
-
/**
|
|
34527
|
-
* Invalid client error - Client authentication failed (e.g., unknown client, no client
|
|
34528
|
-
* authentication included, or unsupported authentication method).
|
|
34529
|
-
*/
|
|
34530
|
-
class InvalidClientError extends OAuthError {
|
|
34531
|
-
}
|
|
34532
|
-
errors$2.InvalidClientError = InvalidClientError;
|
|
34533
|
-
InvalidClientError.errorCode = 'invalid_client';
|
|
34534
|
-
/**
|
|
34535
|
-
* Invalid grant error - The provided authorization grant or refresh token is
|
|
34536
|
-
* invalid, expired, revoked, does not match the redirection URI used in the
|
|
34537
|
-
* authorization request, or was issued to another client.
|
|
34538
|
-
*/
|
|
34539
|
-
class InvalidGrantError extends OAuthError {
|
|
34540
|
-
}
|
|
34541
|
-
errors$2.InvalidGrantError = InvalidGrantError;
|
|
34542
|
-
InvalidGrantError.errorCode = 'invalid_grant';
|
|
34543
|
-
/**
|
|
34544
|
-
* Unauthorized client error - The authenticated client is not authorized to use
|
|
34545
|
-
* this authorization grant type.
|
|
34546
|
-
*/
|
|
34547
|
-
class UnauthorizedClientError extends OAuthError {
|
|
34548
|
-
}
|
|
34549
|
-
errors$2.UnauthorizedClientError = UnauthorizedClientError;
|
|
34550
|
-
UnauthorizedClientError.errorCode = 'unauthorized_client';
|
|
34551
|
-
/**
|
|
34552
|
-
* Unsupported grant type error - The authorization grant type is not supported
|
|
34553
|
-
* by the authorization server.
|
|
34554
|
-
*/
|
|
34555
|
-
class UnsupportedGrantTypeError extends OAuthError {
|
|
34556
|
-
}
|
|
34557
|
-
errors$2.UnsupportedGrantTypeError = UnsupportedGrantTypeError;
|
|
34558
|
-
UnsupportedGrantTypeError.errorCode = 'unsupported_grant_type';
|
|
34559
|
-
/**
|
|
34560
|
-
* Invalid scope error - The requested scope is invalid, unknown, malformed, or
|
|
34561
|
-
* exceeds the scope granted by the resource owner.
|
|
34562
|
-
*/
|
|
34563
|
-
class InvalidScopeError extends OAuthError {
|
|
34564
|
-
}
|
|
34565
|
-
errors$2.InvalidScopeError = InvalidScopeError;
|
|
34566
|
-
InvalidScopeError.errorCode = 'invalid_scope';
|
|
34567
|
-
/**
|
|
34568
|
-
* Access denied error - The resource owner or authorization server denied the request.
|
|
34569
|
-
*/
|
|
34570
|
-
class AccessDeniedError extends OAuthError {
|
|
34571
|
-
}
|
|
34572
|
-
errors$2.AccessDeniedError = AccessDeniedError;
|
|
34573
|
-
AccessDeniedError.errorCode = 'access_denied';
|
|
34574
|
-
/**
|
|
34575
|
-
* Server error - The authorization server encountered an unexpected condition
|
|
34576
|
-
* that prevented it from fulfilling the request.
|
|
34577
|
-
*/
|
|
34578
|
-
class ServerError extends OAuthError {
|
|
34579
|
-
}
|
|
34580
|
-
errors$2.ServerError = ServerError;
|
|
34581
|
-
ServerError.errorCode = 'server_error';
|
|
34582
|
-
/**
|
|
34583
|
-
* Temporarily unavailable error - The authorization server is currently unable to
|
|
34584
|
-
* handle the request due to a temporary overloading or maintenance of the server.
|
|
34585
|
-
*/
|
|
34586
|
-
class TemporarilyUnavailableError extends OAuthError {
|
|
34587
|
-
}
|
|
34588
|
-
errors$2.TemporarilyUnavailableError = TemporarilyUnavailableError;
|
|
34589
|
-
TemporarilyUnavailableError.errorCode = 'temporarily_unavailable';
|
|
34590
|
-
/**
|
|
34591
|
-
* Unsupported response type error - The authorization server does not support
|
|
34592
|
-
* obtaining an authorization code using this method.
|
|
34593
|
-
*/
|
|
34594
|
-
class UnsupportedResponseTypeError extends OAuthError {
|
|
34595
|
-
}
|
|
34596
|
-
errors$2.UnsupportedResponseTypeError = UnsupportedResponseTypeError;
|
|
34597
|
-
UnsupportedResponseTypeError.errorCode = 'unsupported_response_type';
|
|
34598
|
-
/**
|
|
34599
|
-
* Unsupported token type error - The authorization server does not support
|
|
34600
|
-
* the requested token type.
|
|
34601
|
-
*/
|
|
34602
|
-
class UnsupportedTokenTypeError extends OAuthError {
|
|
34603
|
-
}
|
|
34604
|
-
errors$2.UnsupportedTokenTypeError = UnsupportedTokenTypeError;
|
|
34605
|
-
UnsupportedTokenTypeError.errorCode = 'unsupported_token_type';
|
|
34606
|
-
/**
|
|
34607
|
-
* Invalid token error - The access token provided is expired, revoked, malformed,
|
|
34608
|
-
* or invalid for other reasons.
|
|
34609
|
-
*/
|
|
34610
|
-
class InvalidTokenError extends OAuthError {
|
|
34611
|
-
}
|
|
34612
|
-
errors$2.InvalidTokenError = InvalidTokenError;
|
|
34613
|
-
InvalidTokenError.errorCode = 'invalid_token';
|
|
34614
|
-
/**
|
|
34615
|
-
* Method not allowed error - The HTTP method used is not allowed for this endpoint.
|
|
34616
|
-
* (Custom, non-standard error)
|
|
34617
|
-
*/
|
|
34618
|
-
class MethodNotAllowedError extends OAuthError {
|
|
34619
|
-
}
|
|
34620
|
-
errors$2.MethodNotAllowedError = MethodNotAllowedError;
|
|
34621
|
-
MethodNotAllowedError.errorCode = 'method_not_allowed';
|
|
34622
|
-
/**
|
|
34623
|
-
* Too many requests error - Rate limit exceeded.
|
|
34624
|
-
* (Custom, non-standard error based on RFC 6585)
|
|
34625
|
-
*/
|
|
34626
|
-
class TooManyRequestsError extends OAuthError {
|
|
34627
|
-
}
|
|
34628
|
-
errors$2.TooManyRequestsError = TooManyRequestsError;
|
|
34629
|
-
TooManyRequestsError.errorCode = 'too_many_requests';
|
|
34630
|
-
/**
|
|
34631
|
-
* Invalid client metadata error - The client metadata is invalid.
|
|
34632
|
-
* (Custom error for dynamic client registration - RFC 7591)
|
|
34633
|
-
*/
|
|
34634
|
-
class InvalidClientMetadataError extends OAuthError {
|
|
34635
|
-
}
|
|
34636
|
-
errors$2.InvalidClientMetadataError = InvalidClientMetadataError;
|
|
34637
|
-
InvalidClientMetadataError.errorCode = 'invalid_client_metadata';
|
|
34638
|
-
/**
|
|
34639
|
-
* Insufficient scope error - The request requires higher privileges than provided by the access token.
|
|
34640
|
-
*/
|
|
34641
|
-
class InsufficientScopeError extends OAuthError {
|
|
34642
|
-
}
|
|
34643
|
-
errors$2.InsufficientScopeError = InsufficientScopeError;
|
|
34644
|
-
InsufficientScopeError.errorCode = 'insufficient_scope';
|
|
34645
|
-
/**
|
|
34646
|
-
* Invalid target error - The requested resource is invalid, missing, unknown, or malformed.
|
|
34647
|
-
* (Custom error for resource indicators - RFC 8707)
|
|
34648
|
-
*/
|
|
34649
|
-
class InvalidTargetError extends OAuthError {
|
|
34650
|
-
}
|
|
34651
|
-
errors$2.InvalidTargetError = InvalidTargetError;
|
|
34652
|
-
InvalidTargetError.errorCode = 'invalid_target';
|
|
34653
|
-
/**
|
|
34654
|
-
* A utility class for defining one-off error codes
|
|
34655
|
-
*/
|
|
34656
|
-
class CustomOAuthError extends OAuthError {
|
|
34657
|
-
constructor(customErrorCode, message, errorUri) {
|
|
34658
|
-
super(message, errorUri);
|
|
34659
|
-
this.customErrorCode = customErrorCode;
|
|
34660
|
-
}
|
|
34661
|
-
get errorCode() {
|
|
34662
|
-
return this.customErrorCode;
|
|
34663
|
-
}
|
|
34664
|
-
}
|
|
34665
|
-
errors$2.CustomOAuthError = CustomOAuthError;
|
|
34666
|
-
/**
|
|
34667
|
-
* A full list of all OAuthErrors, enabling parsing from error responses
|
|
34668
|
-
*/
|
|
34669
|
-
errors$2.OAUTH_ERRORS = {
|
|
34670
|
-
[InvalidRequestError.errorCode]: InvalidRequestError,
|
|
34671
|
-
[InvalidClientError.errorCode]: InvalidClientError,
|
|
34672
|
-
[InvalidGrantError.errorCode]: InvalidGrantError,
|
|
34673
|
-
[UnauthorizedClientError.errorCode]: UnauthorizedClientError,
|
|
34674
|
-
[UnsupportedGrantTypeError.errorCode]: UnsupportedGrantTypeError,
|
|
34675
|
-
[InvalidScopeError.errorCode]: InvalidScopeError,
|
|
34676
|
-
[AccessDeniedError.errorCode]: AccessDeniedError,
|
|
34677
|
-
[ServerError.errorCode]: ServerError,
|
|
34678
|
-
[TemporarilyUnavailableError.errorCode]: TemporarilyUnavailableError,
|
|
34679
|
-
[UnsupportedResponseTypeError.errorCode]: UnsupportedResponseTypeError,
|
|
34680
|
-
[UnsupportedTokenTypeError.errorCode]: UnsupportedTokenTypeError,
|
|
34681
|
-
[InvalidTokenError.errorCode]: InvalidTokenError,
|
|
34682
|
-
[MethodNotAllowedError.errorCode]: MethodNotAllowedError,
|
|
34683
|
-
[TooManyRequestsError.errorCode]: TooManyRequestsError,
|
|
34684
|
-
[InvalidClientMetadataError.errorCode]: InvalidClientMetadataError,
|
|
34685
|
-
[InsufficientScopeError.errorCode]: InsufficientScopeError,
|
|
34686
|
-
[InvalidTargetError.errorCode]: InvalidTargetError
|
|
34687
|
-
};
|
|
34807
|
+
var hasRequiredAuth;
|
|
34688
34808
|
|
|
34689
|
-
|
|
34690
|
-
|
|
34691
|
-
|
|
34692
|
-
|
|
34693
|
-
|
|
34694
|
-
|
|
34695
|
-
auth$
|
|
34696
|
-
auth$
|
|
34697
|
-
auth$
|
|
34698
|
-
auth$
|
|
34699
|
-
auth$
|
|
34700
|
-
auth$
|
|
34701
|
-
auth$
|
|
34702
|
-
auth$
|
|
34703
|
-
auth$
|
|
34704
|
-
auth$
|
|
34705
|
-
auth$
|
|
34706
|
-
auth$
|
|
34707
|
-
auth$
|
|
34708
|
-
auth$
|
|
34709
|
-
auth$
|
|
34710
|
-
auth$
|
|
34711
|
-
auth$
|
|
34712
|
-
|
|
34713
|
-
|
|
34714
|
-
|
|
34715
|
-
const
|
|
34716
|
-
const
|
|
34717
|
-
const
|
|
34718
|
-
|
|
34719
|
-
|
|
34720
|
-
|
|
34721
|
-
|
|
34722
|
-
|
|
34723
|
-
|
|
34724
|
-
|
|
34725
|
-
|
|
34726
|
-
|
|
34727
|
-
|
|
34728
|
-
|
|
34729
|
-
|
|
34730
|
-
|
|
34731
|
-
|
|
34732
|
-
|
|
34733
|
-
|
|
34734
|
-
|
|
34735
|
-
|
|
34736
|
-
|
|
34737
|
-
|
|
34738
|
-
|
|
34739
|
-
|
|
34740
|
-
|
|
34741
|
-
|
|
34742
|
-
|
|
34743
|
-
|
|
34744
|
-
|
|
34745
|
-
|
|
34746
|
-
|
|
34747
|
-
|
|
34748
|
-
|
|
34749
|
-
|
|
34750
|
-
|
|
34751
|
-
|
|
34752
|
-
|
|
34753
|
-
|
|
34754
|
-
|
|
34755
|
-
|
|
34756
|
-
|
|
34757
|
-
|
|
34758
|
-
|
|
34759
|
-
|
|
34760
|
-
|
|
34761
|
-
|
|
34762
|
-
|
|
34763
|
-
|
|
34764
|
-
|
|
34765
|
-
|
|
34766
|
-
|
|
34767
|
-
|
|
34768
|
-
|
|
34769
|
-
|
|
34770
|
-
}
|
|
34771
|
-
|
|
34772
|
-
|
|
34773
|
-
|
|
34774
|
-
|
|
34775
|
-
|
|
34776
|
-
|
|
34777
|
-
|
|
34778
|
-
|
|
34779
|
-
|
|
34780
|
-
|
|
34781
|
-
|
|
34782
|
-
|
|
34783
|
-
|
|
34784
|
-
|
|
34785
|
-
|
|
34786
|
-
|
|
34787
|
-
|
|
34788
|
-
|
|
34789
|
-
|
|
34790
|
-
|
|
34791
|
-
|
|
34792
|
-
|
|
34793
|
-
|
|
34794
|
-
|
|
34795
|
-
|
|
34796
|
-
|
|
34797
|
-
|
|
34798
|
-
|
|
34799
|
-
|
|
34800
|
-
|
|
34801
|
-
|
|
34802
|
-
|
|
34803
|
-
|
|
34804
|
-
|
|
34805
|
-
|
|
34806
|
-
|
|
34807
|
-
|
|
34808
|
-
|
|
34809
|
-
|
|
34810
|
-
}
|
|
34811
|
-
|
|
34812
|
-
|
|
34813
|
-
|
|
34814
|
-
|
|
34815
|
-
|
|
34816
|
-
|
|
34817
|
-
|
|
34818
|
-
|
|
34819
|
-
|
|
34820
|
-
|
|
34821
|
-
|
|
34822
|
-
|
|
34823
|
-
|
|
34824
|
-
|
|
34825
|
-
|
|
34826
|
-
|
|
34827
|
-
|
|
34828
|
-
|
|
34829
|
-
|
|
34830
|
-
|
|
34831
|
-
|
|
34832
|
-
|
|
34833
|
-
|
|
34834
|
-
|
|
34835
|
-
|
|
34836
|
-
|
|
34837
|
-
|
|
34838
|
-
|
|
34839
|
-
|
|
34840
|
-
|
|
34841
|
-
|
|
34842
|
-
|
|
34843
|
-
|
|
34844
|
-
|
|
34845
|
-
|
|
34846
|
-
|
|
34847
|
-
|
|
34848
|
-
|
|
34849
|
-
|
|
34850
|
-
|
|
34851
|
-
}
|
|
34852
|
-
|
|
34853
|
-
|
|
34854
|
-
|
|
34855
|
-
|
|
34856
|
-
|
|
34857
|
-
|
|
34858
|
-
|
|
34859
|
-
|
|
34860
|
-
|
|
34861
|
-
|
|
34862
|
-
|
|
34863
|
-
|
|
34864
|
-
|
|
34865
|
-
|
|
34866
|
-
|
|
34867
|
-
|
|
34868
|
-
|
|
34869
|
-
|
|
34870
|
-
|
|
34871
|
-
|
|
34872
|
-
|
|
34873
|
-
|
|
34874
|
-
|
|
34875
|
-
|
|
34876
|
-
|
|
34877
|
-
|
|
34878
|
-
|
|
34879
|
-
|
|
34880
|
-
|
|
34881
|
-
|
|
34882
|
-
|
|
34883
|
-
|
|
34884
|
-
|
|
34885
|
-
|
|
34886
|
-
|
|
34887
|
-
|
|
34888
|
-
|
|
34889
|
-
|
|
34890
|
-
|
|
34891
|
-
|
|
34892
|
-
|
|
34893
|
-
|
|
34894
|
-
|
|
34895
|
-
|
|
34896
|
-
|
|
34897
|
-
|
|
34898
|
-
|
|
34899
|
-
|
|
34900
|
-
|
|
34901
|
-
|
|
34902
|
-
|
|
34903
|
-
|
|
34904
|
-
|
|
34905
|
-
|
|
34906
|
-
|
|
34907
|
-
|
|
34908
|
-
|
|
34909
|
-
|
|
34910
|
-
|
|
34911
|
-
|
|
34912
|
-
|
|
34913
|
-
|
|
34914
|
-
|
|
34915
|
-
|
|
34916
|
-
|
|
34917
|
-
|
|
34918
|
-
|
|
34919
|
-
|
|
34920
|
-
|
|
34921
|
-
|
|
34922
|
-
|
|
34923
|
-
|
|
34924
|
-
|
|
34925
|
-
|
|
34926
|
-
|
|
34927
|
-
|
|
34928
|
-
|
|
34929
|
-
|
|
34930
|
-
|
|
34931
|
-
|
|
34932
|
-
|
|
34933
|
-
|
|
34934
|
-
|
|
34935
|
-
|
|
34936
|
-
|
|
34937
|
-
|
|
34938
|
-
|
|
34939
|
-
|
|
34940
|
-
|
|
34941
|
-
|
|
34942
|
-
|
|
34943
|
-
|
|
34944
|
-
|
|
34945
|
-
|
|
34946
|
-
|
|
34947
|
-
|
|
34948
|
-
|
|
34949
|
-
|
|
34950
|
-
|
|
34951
|
-
|
|
34952
|
-
|
|
34953
|
-
|
|
34954
|
-
|
|
34955
|
-
|
|
34956
|
-
|
|
34957
|
-
|
|
34958
|
-
|
|
34959
|
-
|
|
34960
|
-
|
|
34961
|
-
|
|
34962
|
-
|
|
34963
|
-
|
|
34964
|
-
|
|
34965
|
-
|
|
34966
|
-
|
|
34967
|
-
|
|
34968
|
-
|
|
34969
|
-
|
|
34970
|
-
|
|
34971
|
-
|
|
34972
|
-
|
|
34973
|
-
|
|
34974
|
-
|
|
34975
|
-
|
|
34976
|
-
|
|
34977
|
-
|
|
34978
|
-
|
|
34979
|
-
|
|
34980
|
-
|
|
34981
|
-
|
|
34982
|
-
|
|
34983
|
-
|
|
34984
|
-
|
|
34985
|
-
|
|
34986
|
-
|
|
34987
|
-
|
|
34988
|
-
|
|
34989
|
-
|
|
34990
|
-
|
|
34991
|
-
|
|
34992
|
-
|
|
34993
|
-
|
|
34994
|
-
|
|
34995
|
-
|
|
34996
|
-
|
|
34997
|
-
|
|
34998
|
-
|
|
34999
|
-
|
|
35000
|
-
|
|
35001
|
-
|
|
35002
|
-
|
|
35003
|
-
|
|
35004
|
-
|
|
35005
|
-
|
|
35006
|
-
|
|
35007
|
-
|
|
35008
|
-
|
|
35009
|
-
|
|
35010
|
-
|
|
35011
|
-
|
|
35012
|
-
|
|
35013
|
-
|
|
35014
|
-
|
|
35015
|
-
|
|
35016
|
-
|
|
35017
|
-
|
|
35018
|
-
|
|
35019
|
-
|
|
35020
|
-
|
|
35021
|
-
|
|
35022
|
-
|
|
35023
|
-
|
|
35024
|
-
|
|
35025
|
-
|
|
35026
|
-
|
|
35027
|
-
|
|
35028
|
-
|
|
35029
|
-
|
|
35030
|
-
|
|
35031
|
-
|
|
35032
|
-
|
|
35033
|
-
|
|
35034
|
-
|
|
35035
|
-
|
|
35036
|
-
|
|
35037
|
-
|
|
35038
|
-
|
|
35039
|
-
|
|
35040
|
-
|
|
35041
|
-
|
|
35042
|
-
|
|
35043
|
-
|
|
35044
|
-
|
|
35045
|
-
|
|
35046
|
-
|
|
35047
|
-
|
|
35048
|
-
|
|
35049
|
-
|
|
35050
|
-
|
|
35051
|
-
|
|
35052
|
-
|
|
35053
|
-
|
|
35054
|
-
}
|
|
35055
|
-
|
|
35056
|
-
|
|
35057
|
-
|
|
35058
|
-
|
|
35059
|
-
|
|
35060
|
-
|
|
35061
|
-
|
|
35062
|
-
|
|
35063
|
-
|
|
35064
|
-
|
|
35065
|
-
|
|
35066
|
-
|
|
35067
|
-
|
|
35068
|
-
|
|
35069
|
-
|
|
35070
|
-
|
|
35071
|
-
|
|
35072
|
-
|
|
35073
|
-
|
|
35074
|
-
|
|
35075
|
-
|
|
35076
|
-
|
|
35077
|
-
|
|
35078
|
-
|
|
35079
|
-
|
|
35080
|
-
|
|
35081
|
-
|
|
35082
|
-
|
|
35083
|
-
|
|
35084
|
-
|
|
35085
|
-
|
|
35086
|
-
|
|
35087
|
-
|
|
35088
|
-
|
|
35089
|
-
|
|
35090
|
-
|
|
35091
|
-
|
|
35092
|
-
|
|
35093
|
-
|
|
35094
|
-
|
|
35095
|
-
|
|
35096
|
-
|
|
35097
|
-
|
|
35098
|
-
|
|
35099
|
-
|
|
35100
|
-
|
|
35101
|
-
|
|
35102
|
-
|
|
35103
|
-
|
|
35104
|
-
|
|
35105
|
-
|
|
35106
|
-
|
|
35107
|
-
|
|
35108
|
-
|
|
35109
|
-
|
|
35110
|
-
|
|
35111
|
-
|
|
35112
|
-
|
|
35113
|
-
|
|
35114
|
-
|
|
35115
|
-
|
|
35116
|
-
|
|
35117
|
-
|
|
35118
|
-
|
|
35119
|
-
|
|
35120
|
-
|
|
35121
|
-
|
|
35122
|
-
|
|
35123
|
-
|
|
35124
|
-
|
|
35125
|
-
|
|
35126
|
-
|
|
35127
|
-
|
|
35128
|
-
|
|
35129
|
-
|
|
35130
|
-
|
|
35131
|
-
|
|
35132
|
-
|
|
35133
|
-
|
|
35134
|
-
|
|
35135
|
-
|
|
35136
|
-
|
|
35137
|
-
|
|
35138
|
-
|
|
35139
|
-
|
|
35140
|
-
|
|
35141
|
-
|
|
35142
|
-
|
|
35143
|
-
|
|
35144
|
-
|
|
35145
|
-
|
|
35146
|
-
|
|
35147
|
-
|
|
35148
|
-
|
|
35149
|
-
|
|
35150
|
-
}
|
|
35151
|
-
|
|
35152
|
-
|
|
35153
|
-
|
|
35154
|
-
|
|
35155
|
-
|
|
35156
|
-
|
|
35157
|
-
|
|
35158
|
-
|
|
35159
|
-
|
|
35160
|
-
|
|
35161
|
-
|
|
35162
|
-
|
|
35163
|
-
|
|
35164
|
-
|
|
35165
|
-
|
|
35166
|
-
|
|
35167
|
-
|
|
35168
|
-
|
|
35169
|
-
|
|
35170
|
-
|
|
35171
|
-
}
|
|
35172
|
-
|
|
35173
|
-
|
|
35174
|
-
|
|
35175
|
-
|
|
35176
|
-
|
|
35177
|
-
|
|
35178
|
-
|
|
35179
|
-
|
|
35180
|
-
|
|
35181
|
-
|
|
35182
|
-
|
|
35183
|
-
|
|
35184
|
-
|
|
35185
|
-
|
|
35186
|
-
|
|
35187
|
-
|
|
35188
|
-
|
|
35189
|
-
|
|
35190
|
-
|
|
35191
|
-
|
|
35192
|
-
|
|
35193
|
-
|
|
35194
|
-
|
|
35195
|
-
|
|
35196
|
-
|
|
35197
|
-
|
|
35198
|
-
|
|
35199
|
-
|
|
35200
|
-
|
|
35201
|
-
|
|
35202
|
-
|
|
35203
|
-
|
|
35204
|
-
|
|
35205
|
-
|
|
35206
|
-
|
|
35207
|
-
|
|
35208
|
-
|
|
35209
|
-
|
|
35210
|
-
|
|
35211
|
-
|
|
35212
|
-
|
|
35213
|
-
|
|
35214
|
-
|
|
35215
|
-
|
|
35216
|
-
|
|
35217
|
-
|
|
35218
|
-
|
|
35219
|
-
|
|
35220
|
-
|
|
35221
|
-
|
|
35222
|
-
|
|
35223
|
-
|
|
35224
|
-
|
|
35225
|
-
|
|
35226
|
-
|
|
35227
|
-
|
|
35228
|
-
|
|
35229
|
-
|
|
35230
|
-
|
|
35231
|
-
|
|
35232
|
-
|
|
35233
|
-
|
|
35234
|
-
|
|
35235
|
-
|
|
35236
|
-
|
|
35237
|
-
|
|
35238
|
-
|
|
35239
|
-
|
|
35240
|
-
|
|
35241
|
-
|
|
35242
|
-
|
|
35243
|
-
|
|
35244
|
-
|
|
35245
|
-
|
|
35246
|
-
|
|
35247
|
-
|
|
35248
|
-
|
|
35249
|
-
|
|
35250
|
-
|
|
35251
|
-
|
|
35252
|
-
|
|
35253
|
-
}
|
|
35254
|
-
|
|
35255
|
-
|
|
35256
|
-
|
|
35257
|
-
|
|
35258
|
-
|
|
35259
|
-
|
|
35260
|
-
|
|
35261
|
-
|
|
35262
|
-
|
|
35263
|
-
|
|
35264
|
-
|
|
35265
|
-
|
|
35266
|
-
|
|
35267
|
-
|
|
35268
|
-
|
|
35269
|
-
|
|
35270
|
-
|
|
35271
|
-
|
|
35272
|
-
|
|
35273
|
-
|
|
35274
|
-
|
|
35275
|
-
|
|
35276
|
-
|
|
35277
|
-
|
|
35278
|
-
|
|
35279
|
-
|
|
35280
|
-
|
|
35281
|
-
|
|
35282
|
-
|
|
35283
|
-
|
|
35284
|
-
|
|
35285
|
-
|
|
35286
|
-
|
|
35287
|
-
|
|
35288
|
-
|
|
35289
|
-
|
|
35290
|
-
|
|
35291
|
-
|
|
35292
|
-
|
|
35293
|
-
|
|
35294
|
-
|
|
35295
|
-
|
|
35296
|
-
|
|
35297
|
-
|
|
35298
|
-
|
|
35299
|
-
|
|
35300
|
-
|
|
35301
|
-
|
|
35302
|
-
|
|
35303
|
-
|
|
35304
|
-
|
|
35305
|
-
|
|
35306
|
-
|
|
35307
|
-
|
|
35308
|
-
|
|
35309
|
-
|
|
35310
|
-
|
|
35311
|
-
|
|
35312
|
-
|
|
35313
|
-
|
|
35314
|
-
|
|
35315
|
-
|
|
35316
|
-
|
|
35317
|
-
|
|
35318
|
-
|
|
35319
|
-
|
|
35320
|
-
|
|
35321
|
-
|
|
35322
|
-
|
|
35323
|
-
|
|
35324
|
-
|
|
35325
|
-
|
|
35326
|
-
|
|
35327
|
-
|
|
35328
|
-
|
|
35329
|
-
|
|
35330
|
-
|
|
35331
|
-
|
|
35332
|
-
|
|
35333
|
-
|
|
35334
|
-
|
|
35335
|
-
|
|
35336
|
-
|
|
35337
|
-
|
|
35338
|
-
|
|
35339
|
-
|
|
35340
|
-
|
|
35341
|
-
|
|
35342
|
-
|
|
35343
|
-
|
|
35344
|
-
|
|
35345
|
-
|
|
35346
|
-
|
|
35347
|
-
|
|
35348
|
-
|
|
35349
|
-
|
|
35350
|
-
|
|
35351
|
-
}
|
|
35352
|
-
|
|
35353
|
-
|
|
35354
|
-
|
|
35355
|
-
|
|
35356
|
-
|
|
35357
|
-
|
|
35358
|
-
|
|
35359
|
-
|
|
35360
|
-
|
|
35361
|
-
|
|
35362
|
-
|
|
35363
|
-
|
|
35364
|
-
|
|
35365
|
-
|
|
35366
|
-
|
|
35367
|
-
|
|
35368
|
-
|
|
35369
|
-
|
|
35370
|
-
|
|
35371
|
-
|
|
35372
|
-
|
|
35373
|
-
|
|
35374
|
-
|
|
35375
|
-
|
|
35376
|
-
|
|
35377
|
-
|
|
35378
|
-
|
|
35379
|
-
|
|
35380
|
-
|
|
35381
|
-
|
|
35382
|
-
|
|
35383
|
-
|
|
35384
|
-
|
|
35385
|
-
|
|
35386
|
-
|
|
35387
|
-
|
|
35388
|
-
|
|
35389
|
-
|
|
35390
|
-
|
|
35391
|
-
|
|
35392
|
-
|
|
35393
|
-
|
|
35394
|
-
|
|
35395
|
-
|
|
35396
|
-
|
|
35397
|
-
|
|
35398
|
-
|
|
35399
|
-
|
|
35400
|
-
|
|
35401
|
-
|
|
35402
|
-
|
|
35403
|
-
|
|
35404
|
-
|
|
35405
|
-
|
|
35406
|
-
|
|
35407
|
-
|
|
35408
|
-
|
|
35409
|
-
|
|
35410
|
-
|
|
35411
|
-
|
|
35412
|
-
|
|
35413
|
-
|
|
35414
|
-
|
|
35415
|
-
|
|
35416
|
-
|
|
35417
|
-
|
|
35418
|
-
|
|
35419
|
-
|
|
35420
|
-
|
|
35421
|
-
|
|
35422
|
-
|
|
35423
|
-
|
|
35424
|
-
|
|
35425
|
-
|
|
35426
|
-
|
|
35427
|
-
|
|
35428
|
-
|
|
35429
|
-
|
|
35430
|
-
|
|
35431
|
-
|
|
35432
|
-
|
|
35433
|
-
|
|
35434
|
-
|
|
35435
|
-
|
|
35436
|
-
|
|
35437
|
-
|
|
35438
|
-
|
|
35439
|
-
|
|
35440
|
-
|
|
35441
|
-
|
|
35442
|
-
|
|
35443
|
-
|
|
35444
|
-
|
|
35445
|
-
|
|
35446
|
-
|
|
35447
|
-
|
|
35448
|
-
|
|
35449
|
-
|
|
35450
|
-
|
|
35451
|
-
|
|
35452
|
-
|
|
35453
|
-
|
|
35454
|
-
|
|
35455
|
-
|
|
35456
|
-
|
|
35457
|
-
|
|
35458
|
-
|
|
35459
|
-
|
|
35460
|
-
|
|
35461
|
-
|
|
35462
|
-
|
|
35463
|
-
|
|
35464
|
-
|
|
35465
|
-
|
|
35466
|
-
|
|
35467
|
-
|
|
35468
|
-
|
|
35469
|
-
|
|
35470
|
-
|
|
35471
|
-
|
|
35472
|
-
|
|
35473
|
-
|
|
35474
|
-
|
|
35475
|
-
|
|
35476
|
-
|
|
35477
|
-
|
|
35478
|
-
|
|
35479
|
-
|
|
35480
|
-
|
|
35481
|
-
|
|
35482
|
-
|
|
35483
|
-
|
|
35484
|
-
|
|
35485
|
-
|
|
35486
|
-
|
|
35487
|
-
|
|
35488
|
-
|
|
35489
|
-
|
|
35490
|
-
|
|
35491
|
-
|
|
35492
|
-
|
|
35493
|
-
|
|
35494
|
-
|
|
35495
|
-
|
|
35496
|
-
|
|
35497
|
-
|
|
35498
|
-
|
|
35499
|
-
|
|
35500
|
-
|
|
35501
|
-
|
|
35502
|
-
|
|
35503
|
-
|
|
35504
|
-
|
|
35505
|
-
|
|
35506
|
-
|
|
35507
|
-
|
|
35508
|
-
|
|
35509
|
-
|
|
35510
|
-
|
|
35511
|
-
|
|
35512
|
-
|
|
35513
|
-
|
|
35514
|
-
|
|
35515
|
-
|
|
35516
|
-
|
|
35517
|
-
|
|
35518
|
-
|
|
35519
|
-
|
|
35520
|
-
|
|
35521
|
-
|
|
35522
|
-
|
|
35523
|
-
|
|
35524
|
-
|
|
35525
|
-
|
|
35526
|
-
|
|
35527
|
-
|
|
35528
|
-
|
|
35529
|
-
|
|
35530
|
-
|
|
35531
|
-
|
|
35532
|
-
|
|
35533
|
-
|
|
35534
|
-
|
|
35535
|
-
|
|
35536
|
-
|
|
35537
|
-
|
|
35538
|
-
|
|
35539
|
-
|
|
35540
|
-
}
|
|
35541
|
-
|
|
35542
|
-
|
|
35543
|
-
|
|
35544
|
-
|
|
35545
|
-
|
|
35546
|
-
|
|
35547
|
-
|
|
35548
|
-
|
|
35549
|
-
|
|
35550
|
-
|
|
35551
|
-
|
|
35552
|
-
|
|
35553
|
-
|
|
35554
|
-
|
|
35555
|
-
|
|
35556
|
-
|
|
35557
|
-
|
|
35558
|
-
|
|
35559
|
-
|
|
35560
|
-
|
|
35561
|
-
|
|
35562
|
-
|
|
35563
|
-
|
|
35564
|
-
|
|
35565
|
-
|
|
35566
|
-
|
|
35567
|
-
|
|
35568
|
-
|
|
35569
|
-
|
|
35570
|
-
|
|
35571
|
-
|
|
35572
|
-
|
|
35573
|
-
|
|
35574
|
-
|
|
35575
|
-
|
|
35576
|
-
|
|
35577
|
-
|
|
35578
|
-
|
|
35579
|
-
|
|
35580
|
-
|
|
35581
|
-
|
|
35582
|
-
|
|
35583
|
-
|
|
35584
|
-
|
|
35585
|
-
|
|
35586
|
-
|
|
35587
|
-
|
|
35588
|
-
|
|
35589
|
-
|
|
35590
|
-
|
|
35591
|
-
|
|
35592
|
-
|
|
35593
|
-
|
|
35594
|
-
|
|
35595
|
-
|
|
35596
|
-
|
|
35597
|
-
|
|
35598
|
-
|
|
35599
|
-
|
|
35600
|
-
|
|
35601
|
-
|
|
35602
|
-
|
|
35603
|
-
|
|
35604
|
-
|
|
35605
|
-
|
|
35606
|
-
|
|
35607
|
-
|
|
35608
|
-
|
|
35609
|
-
|
|
35610
|
-
|
|
35611
|
-
|
|
35612
|
-
|
|
35613
|
-
|
|
35614
|
-
|
|
35615
|
-
|
|
35616
|
-
|
|
35617
|
-
|
|
35618
|
-
|
|
35619
|
-
|
|
35620
|
-
|
|
35621
|
-
|
|
35622
|
-
|
|
35623
|
-
|
|
35624
|
-
|
|
35625
|
-
|
|
35626
|
-
|
|
34809
|
+
function requireAuth () {
|
|
34810
|
+
if (hasRequiredAuth) return auth$1;
|
|
34811
|
+
hasRequiredAuth = 1;
|
|
34812
|
+
var __importDefault = (commonjsGlobal && commonjsGlobal.__importDefault) || function (mod) {
|
|
34813
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
34814
|
+
};
|
|
34815
|
+
Object.defineProperty(auth$1, "__esModule", { value: true });
|
|
34816
|
+
auth$1.UnauthorizedError = void 0;
|
|
34817
|
+
auth$1.selectClientAuthMethod = selectClientAuthMethod;
|
|
34818
|
+
auth$1.parseErrorResponse = parseErrorResponse;
|
|
34819
|
+
auth$1.auth = auth;
|
|
34820
|
+
auth$1.isHttpsUrl = isHttpsUrl;
|
|
34821
|
+
auth$1.selectResourceURL = selectResourceURL;
|
|
34822
|
+
auth$1.extractWWWAuthenticateParams = extractWWWAuthenticateParams;
|
|
34823
|
+
auth$1.extractResourceMetadataUrl = extractResourceMetadataUrl;
|
|
34824
|
+
auth$1.discoverOAuthProtectedResourceMetadata = discoverOAuthProtectedResourceMetadata;
|
|
34825
|
+
auth$1.discoverOAuthMetadata = discoverOAuthMetadata;
|
|
34826
|
+
auth$1.buildDiscoveryUrls = buildDiscoveryUrls;
|
|
34827
|
+
auth$1.discoverAuthorizationServerMetadata = discoverAuthorizationServerMetadata;
|
|
34828
|
+
auth$1.discoverOAuthServerInfo = discoverOAuthServerInfo;
|
|
34829
|
+
auth$1.startAuthorization = startAuthorization;
|
|
34830
|
+
auth$1.prepareAuthorizationCodeRequest = prepareAuthorizationCodeRequest;
|
|
34831
|
+
auth$1.exchangeAuthorization = exchangeAuthorization;
|
|
34832
|
+
auth$1.refreshAuthorization = refreshAuthorization;
|
|
34833
|
+
auth$1.fetchToken = fetchToken;
|
|
34834
|
+
auth$1.registerClient = registerClient;
|
|
34835
|
+
const pkce_challenge_1 = __importDefault(require$$0$7);
|
|
34836
|
+
const types_js_1 = types$2;
|
|
34837
|
+
const auth_js_1 = requireAuth$1();
|
|
34838
|
+
const auth_js_2 = requireAuth$1();
|
|
34839
|
+
const auth_utils_js_1 = requireAuthUtils();
|
|
34840
|
+
const errors_js_1 = requireErrors$1();
|
|
34841
|
+
class UnauthorizedError extends Error {
|
|
34842
|
+
constructor(message) {
|
|
34843
|
+
super(message ?? 'Unauthorized');
|
|
34844
|
+
}
|
|
34845
|
+
}
|
|
34846
|
+
auth$1.UnauthorizedError = UnauthorizedError;
|
|
34847
|
+
function isClientAuthMethod(method) {
|
|
34848
|
+
return ['client_secret_basic', 'client_secret_post', 'none'].includes(method);
|
|
34849
|
+
}
|
|
34850
|
+
const AUTHORIZATION_CODE_RESPONSE_TYPE = 'code';
|
|
34851
|
+
const AUTHORIZATION_CODE_CHALLENGE_METHOD = 'S256';
|
|
34852
|
+
/**
|
|
34853
|
+
* Determines the best client authentication method to use based on server support and client configuration.
|
|
34854
|
+
*
|
|
34855
|
+
* Priority order (highest to lowest):
|
|
34856
|
+
* 1. client_secret_basic (if client secret is available)
|
|
34857
|
+
* 2. client_secret_post (if client secret is available)
|
|
34858
|
+
* 3. none (for public clients)
|
|
34859
|
+
*
|
|
34860
|
+
* @param clientInformation - OAuth client information containing credentials
|
|
34861
|
+
* @param supportedMethods - Authentication methods supported by the authorization server
|
|
34862
|
+
* @returns The selected authentication method
|
|
34863
|
+
*/
|
|
34864
|
+
function selectClientAuthMethod(clientInformation, supportedMethods) {
|
|
34865
|
+
const hasClientSecret = clientInformation.client_secret !== undefined;
|
|
34866
|
+
// Prefer the method returned by the server during client registration, if valid.
|
|
34867
|
+
// When server metadata is present we also require the method to be listed as supported;
|
|
34868
|
+
// when supportedMethods is empty (metadata omitted the field) the DCR hint stands alone.
|
|
34869
|
+
if ('token_endpoint_auth_method' in clientInformation &&
|
|
34870
|
+
clientInformation.token_endpoint_auth_method &&
|
|
34871
|
+
isClientAuthMethod(clientInformation.token_endpoint_auth_method) &&
|
|
34872
|
+
(supportedMethods.length === 0 || supportedMethods.includes(clientInformation.token_endpoint_auth_method))) {
|
|
34873
|
+
return clientInformation.token_endpoint_auth_method;
|
|
34874
|
+
}
|
|
34875
|
+
// If server metadata omits token_endpoint_auth_methods_supported, RFC 8414 §2 says the
|
|
34876
|
+
// default is client_secret_basic. RFC 6749 §2.3.1 also requires servers to support HTTP
|
|
34877
|
+
// Basic authentication for clients with a secret, making it the safest default.
|
|
34878
|
+
if (supportedMethods.length === 0) {
|
|
34879
|
+
return hasClientSecret ? 'client_secret_basic' : 'none';
|
|
34880
|
+
}
|
|
34881
|
+
// Try methods in priority order (most secure first)
|
|
34882
|
+
if (hasClientSecret && supportedMethods.includes('client_secret_basic')) {
|
|
34883
|
+
return 'client_secret_basic';
|
|
34884
|
+
}
|
|
34885
|
+
if (hasClientSecret && supportedMethods.includes('client_secret_post')) {
|
|
34886
|
+
return 'client_secret_post';
|
|
34887
|
+
}
|
|
34888
|
+
if (supportedMethods.includes('none')) {
|
|
34889
|
+
return 'none';
|
|
34890
|
+
}
|
|
34891
|
+
// Fallback: use what we have
|
|
34892
|
+
return hasClientSecret ? 'client_secret_post' : 'none';
|
|
34893
|
+
}
|
|
34894
|
+
/**
|
|
34895
|
+
* Applies client authentication to the request based on the specified method.
|
|
34896
|
+
*
|
|
34897
|
+
* Implements OAuth 2.1 client authentication methods:
|
|
34898
|
+
* - client_secret_basic: HTTP Basic authentication (RFC 6749 Section 2.3.1)
|
|
34899
|
+
* - client_secret_post: Credentials in request body (RFC 6749 Section 2.3.1)
|
|
34900
|
+
* - none: Public client authentication (RFC 6749 Section 2.1)
|
|
34901
|
+
*
|
|
34902
|
+
* @param method - The authentication method to use
|
|
34903
|
+
* @param clientInformation - OAuth client information containing credentials
|
|
34904
|
+
* @param headers - HTTP headers object to modify
|
|
34905
|
+
* @param params - URL search parameters to modify
|
|
34906
|
+
* @throws {Error} When required credentials are missing
|
|
34907
|
+
*/
|
|
34908
|
+
function applyClientAuthentication(method, clientInformation, headers, params) {
|
|
34909
|
+
const { client_id, client_secret } = clientInformation;
|
|
34910
|
+
switch (method) {
|
|
34911
|
+
case 'client_secret_basic':
|
|
34912
|
+
applyBasicAuth(client_id, client_secret, headers);
|
|
34913
|
+
return;
|
|
34914
|
+
case 'client_secret_post':
|
|
34915
|
+
applyPostAuth(client_id, client_secret, params);
|
|
34916
|
+
return;
|
|
34917
|
+
case 'none':
|
|
34918
|
+
applyPublicAuth(client_id, params);
|
|
34919
|
+
return;
|
|
34920
|
+
default:
|
|
34921
|
+
throw new Error(`Unsupported client authentication method: ${method}`);
|
|
34922
|
+
}
|
|
34923
|
+
}
|
|
34924
|
+
/**
|
|
34925
|
+
* Applies HTTP Basic authentication (RFC 6749 Section 2.3.1)
|
|
34926
|
+
*/
|
|
34927
|
+
function applyBasicAuth(clientId, clientSecret, headers) {
|
|
34928
|
+
if (!clientSecret) {
|
|
34929
|
+
throw new Error('client_secret_basic authentication requires a client_secret');
|
|
34930
|
+
}
|
|
34931
|
+
const credentials = btoa(`${clientId}:${clientSecret}`);
|
|
34932
|
+
headers.set('Authorization', `Basic ${credentials}`);
|
|
34933
|
+
}
|
|
34934
|
+
/**
|
|
34935
|
+
* Applies POST body authentication (RFC 6749 Section 2.3.1)
|
|
34936
|
+
*/
|
|
34937
|
+
function applyPostAuth(clientId, clientSecret, params) {
|
|
34938
|
+
params.set('client_id', clientId);
|
|
34939
|
+
if (clientSecret) {
|
|
34940
|
+
params.set('client_secret', clientSecret);
|
|
34941
|
+
}
|
|
34942
|
+
}
|
|
34943
|
+
/**
|
|
34944
|
+
* Applies public client authentication (RFC 6749 Section 2.1)
|
|
34945
|
+
*/
|
|
34946
|
+
function applyPublicAuth(clientId, params) {
|
|
34947
|
+
params.set('client_id', clientId);
|
|
34948
|
+
}
|
|
34949
|
+
/**
|
|
34950
|
+
* Parses an OAuth error response from a string or Response object.
|
|
34951
|
+
*
|
|
34952
|
+
* If the input is a standard OAuth2.0 error response, it will be parsed according to the spec
|
|
34953
|
+
* and an instance of the appropriate OAuthError subclass will be returned.
|
|
34954
|
+
* If parsing fails, it falls back to a generic ServerError that includes
|
|
34955
|
+
* the response status (if available) and original content.
|
|
34956
|
+
*
|
|
34957
|
+
* @param input - A Response object or string containing the error response
|
|
34958
|
+
* @returns A Promise that resolves to an OAuthError instance
|
|
34959
|
+
*/
|
|
34960
|
+
async function parseErrorResponse(input) {
|
|
34961
|
+
const statusCode = input instanceof Response ? input.status : undefined;
|
|
34962
|
+
const body = input instanceof Response ? await input.text() : input;
|
|
34963
|
+
try {
|
|
34964
|
+
const result = auth_js_1.OAuthErrorResponseSchema.parse(JSON.parse(body));
|
|
34965
|
+
const { error, error_description, error_uri } = result;
|
|
34966
|
+
const errorClass = errors_js_1.OAUTH_ERRORS[error] || errors_js_1.ServerError;
|
|
34967
|
+
return new errorClass(error_description || '', error_uri);
|
|
34968
|
+
}
|
|
34969
|
+
catch (error) {
|
|
34970
|
+
// Not a valid OAuth error response, but try to inform the user of the raw data anyway
|
|
34971
|
+
const errorMessage = `${statusCode ? `HTTP ${statusCode}: ` : ''}Invalid OAuth error response: ${error}. Raw body: ${body}`;
|
|
34972
|
+
return new errors_js_1.ServerError(errorMessage);
|
|
34973
|
+
}
|
|
34974
|
+
}
|
|
34975
|
+
/**
|
|
34976
|
+
* Orchestrates the full auth flow with a server.
|
|
34977
|
+
*
|
|
34978
|
+
* This can be used as a single entry point for all authorization functionality,
|
|
34979
|
+
* instead of linking together the other lower-level functions in this module.
|
|
34980
|
+
*/
|
|
34981
|
+
async function auth(provider, options) {
|
|
34982
|
+
try {
|
|
34983
|
+
return await authInternal(provider, options);
|
|
34984
|
+
}
|
|
34985
|
+
catch (error) {
|
|
34986
|
+
// Handle recoverable error types by invalidating credentials and retrying
|
|
34987
|
+
if (error instanceof errors_js_1.InvalidClientError || error instanceof errors_js_1.UnauthorizedClientError) {
|
|
34988
|
+
await provider.invalidateCredentials?.('all');
|
|
34989
|
+
return await authInternal(provider, options);
|
|
34990
|
+
}
|
|
34991
|
+
else if (error instanceof errors_js_1.InvalidGrantError) {
|
|
34992
|
+
await provider.invalidateCredentials?.('tokens');
|
|
34993
|
+
return await authInternal(provider, options);
|
|
34994
|
+
}
|
|
34995
|
+
// Throw otherwise
|
|
34996
|
+
throw error;
|
|
34997
|
+
}
|
|
34998
|
+
}
|
|
34999
|
+
async function authInternal(provider, { serverUrl, authorizationCode, scope, resourceMetadataUrl, fetchFn }) {
|
|
35000
|
+
// Check if the provider has cached discovery state to skip discovery
|
|
35001
|
+
const cachedState = await provider.discoveryState?.();
|
|
35002
|
+
let resourceMetadata;
|
|
35003
|
+
let authorizationServerUrl;
|
|
35004
|
+
let metadata;
|
|
35005
|
+
// If resourceMetadataUrl is not provided, try to load it from cached state
|
|
35006
|
+
// This handles browser redirects where the URL was saved before navigation
|
|
35007
|
+
let effectiveResourceMetadataUrl = resourceMetadataUrl;
|
|
35008
|
+
if (!effectiveResourceMetadataUrl && cachedState?.resourceMetadataUrl) {
|
|
35009
|
+
effectiveResourceMetadataUrl = new URL(cachedState.resourceMetadataUrl);
|
|
35010
|
+
}
|
|
35011
|
+
if (cachedState?.authorizationServerUrl) {
|
|
35012
|
+
// Restore discovery state from cache
|
|
35013
|
+
authorizationServerUrl = cachedState.authorizationServerUrl;
|
|
35014
|
+
resourceMetadata = cachedState.resourceMetadata;
|
|
35015
|
+
metadata =
|
|
35016
|
+
cachedState.authorizationServerMetadata ?? (await discoverAuthorizationServerMetadata(authorizationServerUrl, { fetchFn }));
|
|
35017
|
+
// If resource metadata wasn't cached, try to fetch it for selectResourceURL
|
|
35018
|
+
if (!resourceMetadata) {
|
|
35019
|
+
try {
|
|
35020
|
+
resourceMetadata = await discoverOAuthProtectedResourceMetadata(serverUrl, { resourceMetadataUrl: effectiveResourceMetadataUrl }, fetchFn);
|
|
35021
|
+
}
|
|
35022
|
+
catch {
|
|
35023
|
+
// RFC 9728 not available — selectResourceURL will handle undefined
|
|
35024
|
+
}
|
|
35025
|
+
}
|
|
35026
|
+
// Re-save if we enriched the cached state with missing metadata
|
|
35027
|
+
if (metadata !== cachedState.authorizationServerMetadata || resourceMetadata !== cachedState.resourceMetadata) {
|
|
35028
|
+
await provider.saveDiscoveryState?.({
|
|
35029
|
+
authorizationServerUrl: String(authorizationServerUrl),
|
|
35030
|
+
resourceMetadataUrl: effectiveResourceMetadataUrl?.toString(),
|
|
35031
|
+
resourceMetadata,
|
|
35032
|
+
authorizationServerMetadata: metadata
|
|
35033
|
+
});
|
|
35034
|
+
}
|
|
35035
|
+
}
|
|
35036
|
+
else {
|
|
35037
|
+
// Full discovery via RFC 9728
|
|
35038
|
+
const serverInfo = await discoverOAuthServerInfo(serverUrl, { resourceMetadataUrl: effectiveResourceMetadataUrl, fetchFn });
|
|
35039
|
+
authorizationServerUrl = serverInfo.authorizationServerUrl;
|
|
35040
|
+
metadata = serverInfo.authorizationServerMetadata;
|
|
35041
|
+
resourceMetadata = serverInfo.resourceMetadata;
|
|
35042
|
+
// Persist discovery state for future use
|
|
35043
|
+
// TODO: resourceMetadataUrl is only populated when explicitly provided via options
|
|
35044
|
+
// or loaded from cached state. The URL derived internally by
|
|
35045
|
+
// discoverOAuthProtectedResourceMetadata() is not captured back here.
|
|
35046
|
+
await provider.saveDiscoveryState?.({
|
|
35047
|
+
authorizationServerUrl: String(authorizationServerUrl),
|
|
35048
|
+
resourceMetadataUrl: effectiveResourceMetadataUrl?.toString(),
|
|
35049
|
+
resourceMetadata,
|
|
35050
|
+
authorizationServerMetadata: metadata
|
|
35051
|
+
});
|
|
35052
|
+
}
|
|
35053
|
+
const resource = await selectResourceURL(serverUrl, provider, resourceMetadata);
|
|
35054
|
+
// Apply scope selection strategy (SEP-835):
|
|
35055
|
+
// 1. WWW-Authenticate scope (passed via `scope` param)
|
|
35056
|
+
// 2. PRM scopes_supported
|
|
35057
|
+
// 3. Client metadata scope (user-configured fallback)
|
|
35058
|
+
// The resolved scope is used consistently for both DCR and the authorization request.
|
|
35059
|
+
const resolvedScope = scope || resourceMetadata?.scopes_supported?.join(' ') || provider.clientMetadata.scope;
|
|
35060
|
+
// Handle client registration if needed
|
|
35061
|
+
let clientInformation = await Promise.resolve(provider.clientInformation());
|
|
35062
|
+
if (!clientInformation) {
|
|
35063
|
+
if (authorizationCode !== undefined) {
|
|
35064
|
+
throw new Error('Existing OAuth client information is required when exchanging an authorization code');
|
|
35065
|
+
}
|
|
35066
|
+
const supportsUrlBasedClientId = metadata?.client_id_metadata_document_supported === true;
|
|
35067
|
+
const clientMetadataUrl = provider.clientMetadataUrl;
|
|
35068
|
+
if (clientMetadataUrl && !isHttpsUrl(clientMetadataUrl)) {
|
|
35069
|
+
throw new errors_js_1.InvalidClientMetadataError(`clientMetadataUrl must be a valid HTTPS URL with a non-root pathname, got: ${clientMetadataUrl}`);
|
|
35070
|
+
}
|
|
35071
|
+
const shouldUseUrlBasedClientId = supportsUrlBasedClientId && clientMetadataUrl;
|
|
35072
|
+
if (shouldUseUrlBasedClientId) {
|
|
35073
|
+
// SEP-991: URL-based Client IDs
|
|
35074
|
+
clientInformation = {
|
|
35075
|
+
client_id: clientMetadataUrl
|
|
35076
|
+
};
|
|
35077
|
+
await provider.saveClientInformation?.(clientInformation);
|
|
35078
|
+
}
|
|
35079
|
+
else {
|
|
35080
|
+
// Fallback to dynamic registration
|
|
35081
|
+
if (!provider.saveClientInformation) {
|
|
35082
|
+
throw new Error('OAuth client information must be saveable for dynamic registration');
|
|
35083
|
+
}
|
|
35084
|
+
const fullInformation = await registerClient(authorizationServerUrl, {
|
|
35085
|
+
metadata,
|
|
35086
|
+
clientMetadata: provider.clientMetadata,
|
|
35087
|
+
scope: resolvedScope,
|
|
35088
|
+
fetchFn
|
|
35089
|
+
});
|
|
35090
|
+
await provider.saveClientInformation(fullInformation);
|
|
35091
|
+
clientInformation = fullInformation;
|
|
35092
|
+
}
|
|
35093
|
+
}
|
|
35094
|
+
// Non-interactive flows (e.g., client_credentials, jwt-bearer) don't need a redirect URL
|
|
35095
|
+
const nonInteractiveFlow = !provider.redirectUrl;
|
|
35096
|
+
// Exchange authorization code for tokens, or fetch tokens directly for non-interactive flows
|
|
35097
|
+
if (authorizationCode !== undefined || nonInteractiveFlow) {
|
|
35098
|
+
const tokens = await fetchToken(provider, authorizationServerUrl, {
|
|
35099
|
+
metadata,
|
|
35100
|
+
resource,
|
|
35101
|
+
authorizationCode,
|
|
35102
|
+
fetchFn
|
|
35103
|
+
});
|
|
35104
|
+
await provider.saveTokens(tokens);
|
|
35105
|
+
return 'AUTHORIZED';
|
|
35106
|
+
}
|
|
35107
|
+
const tokens = await provider.tokens();
|
|
35108
|
+
// Handle token refresh or new authorization
|
|
35109
|
+
if (tokens?.refresh_token) {
|
|
35110
|
+
try {
|
|
35111
|
+
// Attempt to refresh the token
|
|
35112
|
+
const newTokens = await refreshAuthorization(authorizationServerUrl, {
|
|
35113
|
+
metadata,
|
|
35114
|
+
clientInformation,
|
|
35115
|
+
refreshToken: tokens.refresh_token,
|
|
35116
|
+
resource,
|
|
35117
|
+
addClientAuthentication: provider.addClientAuthentication,
|
|
35118
|
+
fetchFn
|
|
35119
|
+
});
|
|
35120
|
+
await provider.saveTokens(newTokens);
|
|
35121
|
+
return 'AUTHORIZED';
|
|
35122
|
+
}
|
|
35123
|
+
catch (error) {
|
|
35124
|
+
// If this is a ServerError, or an unknown type, log it out and try to continue. Otherwise, escalate so we can fix things and retry.
|
|
35125
|
+
if (!(error instanceof errors_js_1.OAuthError) || error instanceof errors_js_1.ServerError) ;
|
|
35126
|
+
else {
|
|
35127
|
+
// Refresh failed for another reason, re-throw
|
|
35128
|
+
throw error;
|
|
35129
|
+
}
|
|
35130
|
+
}
|
|
35131
|
+
}
|
|
35132
|
+
const state = provider.state ? await provider.state() : undefined;
|
|
35133
|
+
// Start new authorization flow
|
|
35134
|
+
const { authorizationUrl, codeVerifier } = await startAuthorization(authorizationServerUrl, {
|
|
35135
|
+
metadata,
|
|
35136
|
+
clientInformation,
|
|
35137
|
+
state,
|
|
35138
|
+
redirectUrl: provider.redirectUrl,
|
|
35139
|
+
scope: resolvedScope,
|
|
35140
|
+
resource
|
|
35141
|
+
});
|
|
35142
|
+
await provider.saveCodeVerifier(codeVerifier);
|
|
35143
|
+
await provider.redirectToAuthorization(authorizationUrl);
|
|
35144
|
+
return 'REDIRECT';
|
|
35145
|
+
}
|
|
35146
|
+
/**
|
|
35147
|
+
* SEP-991: URL-based Client IDs
|
|
35148
|
+
* Validate that the client_id is a valid URL with https scheme
|
|
35149
|
+
*/
|
|
35150
|
+
function isHttpsUrl(value) {
|
|
35151
|
+
if (!value)
|
|
35152
|
+
return false;
|
|
35153
|
+
try {
|
|
35154
|
+
const url = new URL(value);
|
|
35155
|
+
return url.protocol === 'https:' && url.pathname !== '/';
|
|
35156
|
+
}
|
|
35157
|
+
catch {
|
|
35158
|
+
return false;
|
|
35159
|
+
}
|
|
35160
|
+
}
|
|
35161
|
+
async function selectResourceURL(serverUrl, provider, resourceMetadata) {
|
|
35162
|
+
const defaultResource = (0, auth_utils_js_1.resourceUrlFromServerUrl)(serverUrl);
|
|
35163
|
+
// If provider has custom validation, delegate to it
|
|
35164
|
+
if (provider.validateResourceURL) {
|
|
35165
|
+
return await provider.validateResourceURL(defaultResource, resourceMetadata?.resource);
|
|
35166
|
+
}
|
|
35167
|
+
// Only include resource parameter when Protected Resource Metadata is present
|
|
35168
|
+
if (!resourceMetadata) {
|
|
35169
|
+
return undefined;
|
|
35170
|
+
}
|
|
35171
|
+
// Validate that the metadata's resource is compatible with our request
|
|
35172
|
+
if (!(0, auth_utils_js_1.checkResourceAllowed)({ requestedResource: defaultResource, configuredResource: resourceMetadata.resource })) {
|
|
35173
|
+
throw new Error(`Protected resource ${resourceMetadata.resource} does not match expected ${defaultResource} (or origin)`);
|
|
35174
|
+
}
|
|
35175
|
+
// Prefer the resource from metadata since it's what the server is telling us to request
|
|
35176
|
+
return new URL(resourceMetadata.resource);
|
|
35177
|
+
}
|
|
35178
|
+
/**
|
|
35179
|
+
* Extract resource_metadata, scope, and error from WWW-Authenticate header.
|
|
35180
|
+
*/
|
|
35181
|
+
function extractWWWAuthenticateParams(res) {
|
|
35182
|
+
const authenticateHeader = res.headers.get('WWW-Authenticate');
|
|
35183
|
+
if (!authenticateHeader) {
|
|
35184
|
+
return {};
|
|
35185
|
+
}
|
|
35186
|
+
const [type, scheme] = authenticateHeader.split(' ');
|
|
35187
|
+
if (type.toLowerCase() !== 'bearer' || !scheme) {
|
|
35188
|
+
return {};
|
|
35189
|
+
}
|
|
35190
|
+
const resourceMetadataMatch = extractFieldFromWwwAuth(res, 'resource_metadata') || undefined;
|
|
35191
|
+
let resourceMetadataUrl;
|
|
35192
|
+
if (resourceMetadataMatch) {
|
|
35193
|
+
try {
|
|
35194
|
+
resourceMetadataUrl = new URL(resourceMetadataMatch);
|
|
35195
|
+
}
|
|
35196
|
+
catch {
|
|
35197
|
+
// Ignore invalid URL
|
|
35198
|
+
}
|
|
35199
|
+
}
|
|
35200
|
+
const scope = extractFieldFromWwwAuth(res, 'scope') || undefined;
|
|
35201
|
+
const error = extractFieldFromWwwAuth(res, 'error') || undefined;
|
|
35202
|
+
return {
|
|
35203
|
+
resourceMetadataUrl,
|
|
35204
|
+
scope,
|
|
35205
|
+
error
|
|
35206
|
+
};
|
|
35207
|
+
}
|
|
35208
|
+
/**
|
|
35209
|
+
* Extracts a specific field's value from the WWW-Authenticate header string.
|
|
35210
|
+
*
|
|
35211
|
+
* @param response The HTTP response object containing the headers.
|
|
35212
|
+
* @param fieldName The name of the field to extract (e.g., "realm", "nonce").
|
|
35213
|
+
* @returns The field value
|
|
35214
|
+
*/
|
|
35215
|
+
function extractFieldFromWwwAuth(response, fieldName) {
|
|
35216
|
+
const wwwAuthHeader = response.headers.get('WWW-Authenticate');
|
|
35217
|
+
if (!wwwAuthHeader) {
|
|
35218
|
+
return null;
|
|
35219
|
+
}
|
|
35220
|
+
const pattern = new RegExp(`${fieldName}=(?:"([^"]+)"|([^\\s,]+))`);
|
|
35221
|
+
const match = wwwAuthHeader.match(pattern);
|
|
35222
|
+
if (match) {
|
|
35223
|
+
// Pattern matches: field_name="value" or field_name=value (unquoted)
|
|
35224
|
+
return match[1] || match[2];
|
|
35225
|
+
}
|
|
35226
|
+
return null;
|
|
35227
|
+
}
|
|
35228
|
+
/**
|
|
35229
|
+
* Extract resource_metadata from response header.
|
|
35230
|
+
* @deprecated Use `extractWWWAuthenticateParams` instead.
|
|
35231
|
+
*/
|
|
35232
|
+
function extractResourceMetadataUrl(res) {
|
|
35233
|
+
const authenticateHeader = res.headers.get('WWW-Authenticate');
|
|
35234
|
+
if (!authenticateHeader) {
|
|
35235
|
+
return undefined;
|
|
35236
|
+
}
|
|
35237
|
+
const [type, scheme] = authenticateHeader.split(' ');
|
|
35238
|
+
if (type.toLowerCase() !== 'bearer' || !scheme) {
|
|
35239
|
+
return undefined;
|
|
35240
|
+
}
|
|
35241
|
+
const regex = /resource_metadata="([^"]*)"/;
|
|
35242
|
+
const match = regex.exec(authenticateHeader);
|
|
35243
|
+
if (!match) {
|
|
35244
|
+
return undefined;
|
|
35245
|
+
}
|
|
35246
|
+
try {
|
|
35247
|
+
return new URL(match[1]);
|
|
35248
|
+
}
|
|
35249
|
+
catch {
|
|
35250
|
+
return undefined;
|
|
35251
|
+
}
|
|
35252
|
+
}
|
|
35253
|
+
/**
|
|
35254
|
+
* Looks up RFC 9728 OAuth 2.0 Protected Resource Metadata.
|
|
35255
|
+
*
|
|
35256
|
+
* If the server returns a 404 for the well-known endpoint, this function will
|
|
35257
|
+
* return `undefined`. Any other errors will be thrown as exceptions.
|
|
35258
|
+
*/
|
|
35259
|
+
async function discoverOAuthProtectedResourceMetadata(serverUrl, opts, fetchFn = fetch) {
|
|
35260
|
+
const response = await discoverMetadataWithFallback(serverUrl, 'oauth-protected-resource', fetchFn, {
|
|
35261
|
+
protocolVersion: opts?.protocolVersion,
|
|
35262
|
+
metadataUrl: opts?.resourceMetadataUrl
|
|
35263
|
+
});
|
|
35264
|
+
if (!response || response.status === 404) {
|
|
35265
|
+
await response?.body?.cancel();
|
|
35266
|
+
throw new Error(`Resource server does not implement OAuth 2.0 Protected Resource Metadata.`);
|
|
35267
|
+
}
|
|
35268
|
+
if (!response.ok) {
|
|
35269
|
+
await response.body?.cancel();
|
|
35270
|
+
throw new Error(`HTTP ${response.status} trying to load well-known OAuth protected resource metadata.`);
|
|
35271
|
+
}
|
|
35272
|
+
return auth_js_2.OAuthProtectedResourceMetadataSchema.parse(await response.json());
|
|
35273
|
+
}
|
|
35274
|
+
/**
|
|
35275
|
+
* Helper function to handle fetch with CORS retry logic
|
|
35276
|
+
*/
|
|
35277
|
+
async function fetchWithCorsRetry(url, headers, fetchFn = fetch) {
|
|
35278
|
+
try {
|
|
35279
|
+
return await fetchFn(url, { headers });
|
|
35280
|
+
}
|
|
35281
|
+
catch (error) {
|
|
35282
|
+
if (error instanceof TypeError) {
|
|
35283
|
+
if (headers) {
|
|
35284
|
+
// CORS errors come back as TypeError, retry without headers
|
|
35285
|
+
return fetchWithCorsRetry(url, undefined, fetchFn);
|
|
35286
|
+
}
|
|
35287
|
+
else {
|
|
35288
|
+
// We're getting CORS errors on retry too, return undefined
|
|
35289
|
+
return undefined;
|
|
35290
|
+
}
|
|
35291
|
+
}
|
|
35292
|
+
throw error;
|
|
35293
|
+
}
|
|
35294
|
+
}
|
|
35295
|
+
/**
|
|
35296
|
+
* Constructs the well-known path for auth-related metadata discovery
|
|
35297
|
+
*/
|
|
35298
|
+
function buildWellKnownPath(wellKnownPrefix, pathname = '', options = {}) {
|
|
35299
|
+
// Strip trailing slash from pathname to avoid double slashes
|
|
35300
|
+
if (pathname.endsWith('/')) {
|
|
35301
|
+
pathname = pathname.slice(0, -1);
|
|
35302
|
+
}
|
|
35303
|
+
return options.prependPathname ? `${pathname}/.well-known/${wellKnownPrefix}` : `/.well-known/${wellKnownPrefix}${pathname}`;
|
|
35304
|
+
}
|
|
35305
|
+
/**
|
|
35306
|
+
* Tries to discover OAuth metadata at a specific URL
|
|
35307
|
+
*/
|
|
35308
|
+
async function tryMetadataDiscovery(url, protocolVersion, fetchFn = fetch) {
|
|
35309
|
+
const headers = {
|
|
35310
|
+
'MCP-Protocol-Version': protocolVersion
|
|
35311
|
+
};
|
|
35312
|
+
return await fetchWithCorsRetry(url, headers, fetchFn);
|
|
35313
|
+
}
|
|
35314
|
+
/**
|
|
35315
|
+
* Determines if fallback to root discovery should be attempted
|
|
35316
|
+
*/
|
|
35317
|
+
function shouldAttemptFallback(response, pathname) {
|
|
35318
|
+
return !response || (response.status >= 400 && response.status < 500 && pathname !== '/');
|
|
35319
|
+
}
|
|
35320
|
+
/**
|
|
35321
|
+
* Generic function for discovering OAuth metadata with fallback support
|
|
35322
|
+
*/
|
|
35323
|
+
async function discoverMetadataWithFallback(serverUrl, wellKnownType, fetchFn, opts) {
|
|
35324
|
+
const issuer = new URL(serverUrl);
|
|
35325
|
+
const protocolVersion = opts?.protocolVersion ?? types_js_1.LATEST_PROTOCOL_VERSION;
|
|
35326
|
+
let url;
|
|
35327
|
+
if (opts?.metadataUrl) {
|
|
35328
|
+
url = new URL(opts.metadataUrl);
|
|
35329
|
+
}
|
|
35330
|
+
else {
|
|
35331
|
+
// Try path-aware discovery first
|
|
35332
|
+
const wellKnownPath = buildWellKnownPath(wellKnownType, issuer.pathname);
|
|
35333
|
+
url = new URL(wellKnownPath, opts?.metadataServerUrl ?? issuer);
|
|
35334
|
+
url.search = issuer.search;
|
|
35335
|
+
}
|
|
35336
|
+
let response = await tryMetadataDiscovery(url, protocolVersion, fetchFn);
|
|
35337
|
+
// If path-aware discovery fails with 404 and we're not already at root, try fallback to root discovery
|
|
35338
|
+
if (!opts?.metadataUrl && shouldAttemptFallback(response, issuer.pathname)) {
|
|
35339
|
+
const rootUrl = new URL(`/.well-known/${wellKnownType}`, issuer);
|
|
35340
|
+
response = await tryMetadataDiscovery(rootUrl, protocolVersion, fetchFn);
|
|
35341
|
+
}
|
|
35342
|
+
return response;
|
|
35343
|
+
}
|
|
35344
|
+
/**
|
|
35345
|
+
* Looks up RFC 8414 OAuth 2.0 Authorization Server Metadata.
|
|
35346
|
+
*
|
|
35347
|
+
* If the server returns a 404 for the well-known endpoint, this function will
|
|
35348
|
+
* return `undefined`. Any other errors will be thrown as exceptions.
|
|
35349
|
+
*
|
|
35350
|
+
* @deprecated This function is deprecated in favor of `discoverAuthorizationServerMetadata`.
|
|
35351
|
+
*/
|
|
35352
|
+
async function discoverOAuthMetadata(issuer, { authorizationServerUrl, protocolVersion } = {}, fetchFn = fetch) {
|
|
35353
|
+
if (typeof issuer === 'string') {
|
|
35354
|
+
issuer = new URL(issuer);
|
|
35355
|
+
}
|
|
35356
|
+
if (!authorizationServerUrl) {
|
|
35357
|
+
authorizationServerUrl = issuer;
|
|
35358
|
+
}
|
|
35359
|
+
if (typeof authorizationServerUrl === 'string') {
|
|
35360
|
+
authorizationServerUrl = new URL(authorizationServerUrl);
|
|
35361
|
+
}
|
|
35362
|
+
protocolVersion ?? (protocolVersion = types_js_1.LATEST_PROTOCOL_VERSION);
|
|
35363
|
+
const response = await discoverMetadataWithFallback(authorizationServerUrl, 'oauth-authorization-server', fetchFn, {
|
|
35364
|
+
protocolVersion,
|
|
35365
|
+
metadataServerUrl: authorizationServerUrl
|
|
35366
|
+
});
|
|
35367
|
+
if (!response || response.status === 404) {
|
|
35368
|
+
await response?.body?.cancel();
|
|
35369
|
+
return undefined;
|
|
35370
|
+
}
|
|
35371
|
+
if (!response.ok) {
|
|
35372
|
+
await response.body?.cancel();
|
|
35373
|
+
throw new Error(`HTTP ${response.status} trying to load well-known OAuth metadata`);
|
|
35374
|
+
}
|
|
35375
|
+
return auth_js_2.OAuthMetadataSchema.parse(await response.json());
|
|
35376
|
+
}
|
|
35377
|
+
/**
|
|
35378
|
+
* Builds a list of discovery URLs to try for authorization server metadata.
|
|
35379
|
+
* URLs are returned in priority order:
|
|
35380
|
+
* 1. OAuth metadata at the given URL
|
|
35381
|
+
* 2. OIDC metadata endpoints at the given URL
|
|
35382
|
+
*/
|
|
35383
|
+
function buildDiscoveryUrls(authorizationServerUrl) {
|
|
35384
|
+
const url = typeof authorizationServerUrl === 'string' ? new URL(authorizationServerUrl) : authorizationServerUrl;
|
|
35385
|
+
const hasPath = url.pathname !== '/';
|
|
35386
|
+
const urlsToTry = [];
|
|
35387
|
+
if (!hasPath) {
|
|
35388
|
+
// Root path: https://example.com/.well-known/oauth-authorization-server
|
|
35389
|
+
urlsToTry.push({
|
|
35390
|
+
url: new URL('/.well-known/oauth-authorization-server', url.origin),
|
|
35391
|
+
type: 'oauth'
|
|
35392
|
+
});
|
|
35393
|
+
// OIDC: https://example.com/.well-known/openid-configuration
|
|
35394
|
+
urlsToTry.push({
|
|
35395
|
+
url: new URL(`/.well-known/openid-configuration`, url.origin),
|
|
35396
|
+
type: 'oidc'
|
|
35397
|
+
});
|
|
35398
|
+
return urlsToTry;
|
|
35399
|
+
}
|
|
35400
|
+
// Strip trailing slash from pathname to avoid double slashes
|
|
35401
|
+
let pathname = url.pathname;
|
|
35402
|
+
if (pathname.endsWith('/')) {
|
|
35403
|
+
pathname = pathname.slice(0, -1);
|
|
35404
|
+
}
|
|
35405
|
+
// 1. OAuth metadata at the given URL
|
|
35406
|
+
// Insert well-known before the path: https://example.com/.well-known/oauth-authorization-server/tenant1
|
|
35407
|
+
urlsToTry.push({
|
|
35408
|
+
url: new URL(`/.well-known/oauth-authorization-server${pathname}`, url.origin),
|
|
35409
|
+
type: 'oauth'
|
|
35410
|
+
});
|
|
35411
|
+
// 2. OIDC metadata endpoints
|
|
35412
|
+
// RFC 8414 style: Insert /.well-known/openid-configuration before the path
|
|
35413
|
+
urlsToTry.push({
|
|
35414
|
+
url: new URL(`/.well-known/openid-configuration${pathname}`, url.origin),
|
|
35415
|
+
type: 'oidc'
|
|
35416
|
+
});
|
|
35417
|
+
// OIDC Discovery 1.0 style: Append /.well-known/openid-configuration after the path
|
|
35418
|
+
urlsToTry.push({
|
|
35419
|
+
url: new URL(`${pathname}/.well-known/openid-configuration`, url.origin),
|
|
35420
|
+
type: 'oidc'
|
|
35421
|
+
});
|
|
35422
|
+
return urlsToTry;
|
|
35423
|
+
}
|
|
35424
|
+
/**
|
|
35425
|
+
* Discovers authorization server metadata with support for RFC 8414 OAuth 2.0 Authorization Server Metadata
|
|
35426
|
+
* and OpenID Connect Discovery 1.0 specifications.
|
|
35427
|
+
*
|
|
35428
|
+
* This function implements a fallback strategy for authorization server discovery:
|
|
35429
|
+
* 1. Attempts RFC 8414 OAuth metadata discovery first
|
|
35430
|
+
* 2. If OAuth discovery fails, falls back to OpenID Connect Discovery
|
|
35431
|
+
*
|
|
35432
|
+
* @param authorizationServerUrl - The authorization server URL obtained from the MCP Server's
|
|
35433
|
+
* protected resource metadata, or the MCP server's URL if the
|
|
35434
|
+
* metadata was not found.
|
|
35435
|
+
* @param options - Configuration options
|
|
35436
|
+
* @param options.fetchFn - Optional fetch function for making HTTP requests, defaults to global fetch
|
|
35437
|
+
* @param options.protocolVersion - MCP protocol version to use, defaults to LATEST_PROTOCOL_VERSION
|
|
35438
|
+
* @returns Promise resolving to authorization server metadata, or undefined if discovery fails
|
|
35439
|
+
*/
|
|
35440
|
+
async function discoverAuthorizationServerMetadata(authorizationServerUrl, { fetchFn = fetch, protocolVersion = types_js_1.LATEST_PROTOCOL_VERSION } = {}) {
|
|
35441
|
+
const headers = {
|
|
35442
|
+
'MCP-Protocol-Version': protocolVersion,
|
|
35443
|
+
Accept: 'application/json'
|
|
35444
|
+
};
|
|
35445
|
+
// Get the list of URLs to try
|
|
35446
|
+
const urlsToTry = buildDiscoveryUrls(authorizationServerUrl);
|
|
35447
|
+
// Try each URL in order
|
|
35448
|
+
for (const { url: endpointUrl, type } of urlsToTry) {
|
|
35449
|
+
const response = await fetchWithCorsRetry(endpointUrl, headers, fetchFn);
|
|
35450
|
+
if (!response) {
|
|
35451
|
+
/**
|
|
35452
|
+
* CORS error occurred - don't throw as the endpoint may not allow CORS,
|
|
35453
|
+
* continue trying other possible endpoints
|
|
35454
|
+
*/
|
|
35455
|
+
continue;
|
|
35456
|
+
}
|
|
35457
|
+
if (!response.ok) {
|
|
35458
|
+
await response.body?.cancel();
|
|
35459
|
+
// Continue looking for any 4xx response code.
|
|
35460
|
+
if (response.status >= 400 && response.status < 500) {
|
|
35461
|
+
continue; // Try next URL
|
|
35462
|
+
}
|
|
35463
|
+
throw new Error(`HTTP ${response.status} trying to load ${type === 'oauth' ? 'OAuth' : 'OpenID provider'} metadata from ${endpointUrl}`);
|
|
35464
|
+
}
|
|
35465
|
+
// Parse and validate based on type
|
|
35466
|
+
if (type === 'oauth') {
|
|
35467
|
+
return auth_js_2.OAuthMetadataSchema.parse(await response.json());
|
|
35468
|
+
}
|
|
35469
|
+
else {
|
|
35470
|
+
return auth_js_1.OpenIdProviderDiscoveryMetadataSchema.parse(await response.json());
|
|
35471
|
+
}
|
|
35472
|
+
}
|
|
35473
|
+
return undefined;
|
|
35474
|
+
}
|
|
35475
|
+
/**
|
|
35476
|
+
* Discovers the authorization server for an MCP server following
|
|
35477
|
+
* {@link https://datatracker.ietf.org/doc/html/rfc9728 | RFC 9728} (OAuth 2.0 Protected
|
|
35478
|
+
* Resource Metadata), with fallback to treating the server URL as the
|
|
35479
|
+
* authorization server.
|
|
35480
|
+
*
|
|
35481
|
+
* This function combines two discovery steps into one call:
|
|
35482
|
+
* 1. Probes `/.well-known/oauth-protected-resource` on the MCP server to find the
|
|
35483
|
+
* authorization server URL (RFC 9728).
|
|
35484
|
+
* 2. Fetches authorization server metadata from that URL (RFC 8414 / OpenID Connect Discovery).
|
|
35485
|
+
*
|
|
35486
|
+
* Use this when you need the authorization server metadata for operations outside the
|
|
35487
|
+
* {@linkcode auth} orchestrator, such as token refresh or token revocation.
|
|
35488
|
+
*
|
|
35489
|
+
* @param serverUrl - The MCP resource server URL
|
|
35490
|
+
* @param opts - Optional configuration
|
|
35491
|
+
* @param opts.resourceMetadataUrl - Override URL for the protected resource metadata endpoint
|
|
35492
|
+
* @param opts.fetchFn - Custom fetch function for HTTP requests
|
|
35493
|
+
* @returns Authorization server URL, metadata, and resource metadata (if available)
|
|
35494
|
+
*/
|
|
35495
|
+
async function discoverOAuthServerInfo(serverUrl, opts) {
|
|
35496
|
+
let resourceMetadata;
|
|
35497
|
+
let authorizationServerUrl;
|
|
35498
|
+
try {
|
|
35499
|
+
resourceMetadata = await discoverOAuthProtectedResourceMetadata(serverUrl, { resourceMetadataUrl: opts?.resourceMetadataUrl }, opts?.fetchFn);
|
|
35500
|
+
if (resourceMetadata.authorization_servers && resourceMetadata.authorization_servers.length > 0) {
|
|
35501
|
+
authorizationServerUrl = resourceMetadata.authorization_servers[0];
|
|
35502
|
+
}
|
|
35503
|
+
}
|
|
35504
|
+
catch {
|
|
35505
|
+
// RFC 9728 not supported -- fall back to treating the server URL as the authorization server
|
|
35506
|
+
}
|
|
35507
|
+
// If we don't get a valid authorization server from protected resource metadata,
|
|
35508
|
+
// fall back to the legacy MCP spec behavior: MCP server base URL acts as the authorization server
|
|
35509
|
+
if (!authorizationServerUrl) {
|
|
35510
|
+
authorizationServerUrl = String(new URL('/', serverUrl));
|
|
35511
|
+
}
|
|
35512
|
+
const authorizationServerMetadata = await discoverAuthorizationServerMetadata(authorizationServerUrl, { fetchFn: opts?.fetchFn });
|
|
35513
|
+
return {
|
|
35514
|
+
authorizationServerUrl,
|
|
35515
|
+
authorizationServerMetadata,
|
|
35516
|
+
resourceMetadata
|
|
35517
|
+
};
|
|
35518
|
+
}
|
|
35519
|
+
/**
|
|
35520
|
+
* Begins the authorization flow with the given server, by generating a PKCE challenge and constructing the authorization URL.
|
|
35521
|
+
*/
|
|
35522
|
+
async function startAuthorization(authorizationServerUrl, { metadata, clientInformation, redirectUrl, scope, state, resource }) {
|
|
35523
|
+
let authorizationUrl;
|
|
35524
|
+
if (metadata) {
|
|
35525
|
+
authorizationUrl = new URL(metadata.authorization_endpoint);
|
|
35526
|
+
if (!metadata.response_types_supported.includes(AUTHORIZATION_CODE_RESPONSE_TYPE)) {
|
|
35527
|
+
throw new Error(`Incompatible auth server: does not support response type ${AUTHORIZATION_CODE_RESPONSE_TYPE}`);
|
|
35528
|
+
}
|
|
35529
|
+
if (metadata.code_challenge_methods_supported &&
|
|
35530
|
+
!metadata.code_challenge_methods_supported.includes(AUTHORIZATION_CODE_CHALLENGE_METHOD)) {
|
|
35531
|
+
throw new Error(`Incompatible auth server: does not support code challenge method ${AUTHORIZATION_CODE_CHALLENGE_METHOD}`);
|
|
35532
|
+
}
|
|
35533
|
+
}
|
|
35534
|
+
else {
|
|
35535
|
+
authorizationUrl = new URL('/authorize', authorizationServerUrl);
|
|
35536
|
+
}
|
|
35537
|
+
// Generate PKCE challenge
|
|
35538
|
+
const challenge = await (0, pkce_challenge_1.default)();
|
|
35539
|
+
const codeVerifier = challenge.code_verifier;
|
|
35540
|
+
const codeChallenge = challenge.code_challenge;
|
|
35541
|
+
authorizationUrl.searchParams.set('response_type', AUTHORIZATION_CODE_RESPONSE_TYPE);
|
|
35542
|
+
authorizationUrl.searchParams.set('client_id', clientInformation.client_id);
|
|
35543
|
+
authorizationUrl.searchParams.set('code_challenge', codeChallenge);
|
|
35544
|
+
authorizationUrl.searchParams.set('code_challenge_method', AUTHORIZATION_CODE_CHALLENGE_METHOD);
|
|
35545
|
+
authorizationUrl.searchParams.set('redirect_uri', String(redirectUrl));
|
|
35546
|
+
if (state) {
|
|
35547
|
+
authorizationUrl.searchParams.set('state', state);
|
|
35548
|
+
}
|
|
35549
|
+
if (scope) {
|
|
35550
|
+
authorizationUrl.searchParams.set('scope', scope);
|
|
35551
|
+
}
|
|
35552
|
+
if (scope?.includes('offline_access')) {
|
|
35553
|
+
// if the request includes the OIDC-only "offline_access" scope,
|
|
35554
|
+
// we need to set the prompt to "consent" to ensure the user is prompted to grant offline access
|
|
35555
|
+
// https://openid.net/specs/openid-connect-core-1_0.html#OfflineAccess
|
|
35556
|
+
authorizationUrl.searchParams.append('prompt', 'consent');
|
|
35557
|
+
}
|
|
35558
|
+
if (resource) {
|
|
35559
|
+
authorizationUrl.searchParams.set('resource', resource.href);
|
|
35560
|
+
}
|
|
35561
|
+
return { authorizationUrl, codeVerifier };
|
|
35562
|
+
}
|
|
35563
|
+
/**
|
|
35564
|
+
* Prepares token request parameters for an authorization code exchange.
|
|
35565
|
+
*
|
|
35566
|
+
* This is the default implementation used by fetchToken when the provider
|
|
35567
|
+
* doesn't implement prepareTokenRequest.
|
|
35568
|
+
*
|
|
35569
|
+
* @param authorizationCode - The authorization code received from the authorization endpoint
|
|
35570
|
+
* @param codeVerifier - The PKCE code verifier
|
|
35571
|
+
* @param redirectUri - The redirect URI used in the authorization request
|
|
35572
|
+
* @returns URLSearchParams for the authorization_code grant
|
|
35573
|
+
*/
|
|
35574
|
+
function prepareAuthorizationCodeRequest(authorizationCode, codeVerifier, redirectUri) {
|
|
35575
|
+
return new URLSearchParams({
|
|
35576
|
+
grant_type: 'authorization_code',
|
|
35577
|
+
code: authorizationCode,
|
|
35578
|
+
code_verifier: codeVerifier,
|
|
35579
|
+
redirect_uri: String(redirectUri)
|
|
35580
|
+
});
|
|
35581
|
+
}
|
|
35582
|
+
/**
|
|
35583
|
+
* Internal helper to execute a token request with the given parameters.
|
|
35584
|
+
* Used by exchangeAuthorization, refreshAuthorization, and fetchToken.
|
|
35585
|
+
*/
|
|
35586
|
+
async function executeTokenRequest(authorizationServerUrl, { metadata, tokenRequestParams, clientInformation, addClientAuthentication, resource, fetchFn }) {
|
|
35587
|
+
const tokenUrl = metadata?.token_endpoint ? new URL(metadata.token_endpoint) : new URL('/token', authorizationServerUrl);
|
|
35588
|
+
const headers = new Headers({
|
|
35589
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
35590
|
+
Accept: 'application/json'
|
|
35591
|
+
});
|
|
35592
|
+
if (resource) {
|
|
35593
|
+
tokenRequestParams.set('resource', resource.href);
|
|
35594
|
+
}
|
|
35595
|
+
if (addClientAuthentication) {
|
|
35596
|
+
await addClientAuthentication(headers, tokenRequestParams, tokenUrl, metadata);
|
|
35597
|
+
}
|
|
35598
|
+
else if (clientInformation) {
|
|
35599
|
+
const supportedMethods = metadata?.token_endpoint_auth_methods_supported ?? [];
|
|
35600
|
+
const authMethod = selectClientAuthMethod(clientInformation, supportedMethods);
|
|
35601
|
+
applyClientAuthentication(authMethod, clientInformation, headers, tokenRequestParams);
|
|
35602
|
+
}
|
|
35603
|
+
const response = await (fetchFn ?? fetch)(tokenUrl, {
|
|
35604
|
+
method: 'POST',
|
|
35605
|
+
headers,
|
|
35606
|
+
body: tokenRequestParams
|
|
35607
|
+
});
|
|
35608
|
+
if (!response.ok) {
|
|
35609
|
+
throw await parseErrorResponse(response);
|
|
35610
|
+
}
|
|
35611
|
+
return auth_js_2.OAuthTokensSchema.parse(await response.json());
|
|
35612
|
+
}
|
|
35613
|
+
/**
|
|
35614
|
+
* Exchanges an authorization code for an access token with the given server.
|
|
35615
|
+
*
|
|
35616
|
+
* Supports multiple client authentication methods as specified in OAuth 2.1:
|
|
35617
|
+
* - Automatically selects the best authentication method based on server support
|
|
35618
|
+
* - Falls back to appropriate defaults when server metadata is unavailable
|
|
35619
|
+
*
|
|
35620
|
+
* @param authorizationServerUrl - The authorization server's base URL
|
|
35621
|
+
* @param options - Configuration object containing client info, auth code, etc.
|
|
35622
|
+
* @returns Promise resolving to OAuth tokens
|
|
35623
|
+
* @throws {Error} When token exchange fails or authentication is invalid
|
|
35624
|
+
*/
|
|
35625
|
+
async function exchangeAuthorization(authorizationServerUrl, { metadata, clientInformation, authorizationCode, codeVerifier, redirectUri, resource, addClientAuthentication, fetchFn }) {
|
|
35626
|
+
const tokenRequestParams = prepareAuthorizationCodeRequest(authorizationCode, codeVerifier, redirectUri);
|
|
35627
|
+
return executeTokenRequest(authorizationServerUrl, {
|
|
35628
|
+
metadata,
|
|
35629
|
+
tokenRequestParams,
|
|
35630
|
+
clientInformation,
|
|
35631
|
+
addClientAuthentication,
|
|
35632
|
+
resource,
|
|
35633
|
+
fetchFn
|
|
35634
|
+
});
|
|
35635
|
+
}
|
|
35636
|
+
/**
|
|
35637
|
+
* Exchange a refresh token for an updated access token.
|
|
35638
|
+
*
|
|
35639
|
+
* Supports multiple client authentication methods as specified in OAuth 2.1:
|
|
35640
|
+
* - Automatically selects the best authentication method based on server support
|
|
35641
|
+
* - Preserves the original refresh token if a new one is not returned
|
|
35642
|
+
*
|
|
35643
|
+
* @param authorizationServerUrl - The authorization server's base URL
|
|
35644
|
+
* @param options - Configuration object containing client info, refresh token, etc.
|
|
35645
|
+
* @returns Promise resolving to OAuth tokens (preserves original refresh_token if not replaced)
|
|
35646
|
+
* @throws {Error} When token refresh fails or authentication is invalid
|
|
35647
|
+
*/
|
|
35648
|
+
async function refreshAuthorization(authorizationServerUrl, { metadata, clientInformation, refreshToken, resource, addClientAuthentication, fetchFn }) {
|
|
35649
|
+
const tokenRequestParams = new URLSearchParams({
|
|
35650
|
+
grant_type: 'refresh_token',
|
|
35651
|
+
refresh_token: refreshToken
|
|
35652
|
+
});
|
|
35653
|
+
const tokens = await executeTokenRequest(authorizationServerUrl, {
|
|
35654
|
+
metadata,
|
|
35655
|
+
tokenRequestParams,
|
|
35656
|
+
clientInformation,
|
|
35657
|
+
addClientAuthentication,
|
|
35658
|
+
resource,
|
|
35659
|
+
fetchFn
|
|
35660
|
+
});
|
|
35661
|
+
// Preserve original refresh token if server didn't return a new one
|
|
35662
|
+
return { refresh_token: refreshToken, ...tokens };
|
|
35663
|
+
}
|
|
35664
|
+
/**
|
|
35665
|
+
* Unified token fetching that works with any grant type via provider.prepareTokenRequest().
|
|
35666
|
+
*
|
|
35667
|
+
* This function provides a single entry point for obtaining tokens regardless of the
|
|
35668
|
+
* OAuth grant type. The provider's prepareTokenRequest() method determines which grant
|
|
35669
|
+
* to use and supplies the grant-specific parameters.
|
|
35670
|
+
*
|
|
35671
|
+
* @param provider - OAuth client provider that implements prepareTokenRequest()
|
|
35672
|
+
* @param authorizationServerUrl - The authorization server's base URL
|
|
35673
|
+
* @param options - Configuration for the token request
|
|
35674
|
+
* @returns Promise resolving to OAuth tokens
|
|
35675
|
+
* @throws {Error} When provider doesn't implement prepareTokenRequest or token fetch fails
|
|
35676
|
+
*
|
|
35677
|
+
* @example
|
|
35678
|
+
* // Provider for client_credentials:
|
|
35679
|
+
* class MyProvider implements OAuthClientProvider {
|
|
35680
|
+
* prepareTokenRequest(scope) {
|
|
35681
|
+
* const params = new URLSearchParams({ grant_type: 'client_credentials' });
|
|
35682
|
+
* if (scope) params.set('scope', scope);
|
|
35683
|
+
* return params;
|
|
35684
|
+
* }
|
|
35685
|
+
* // ... other methods
|
|
35686
|
+
* }
|
|
35687
|
+
*
|
|
35688
|
+
* const tokens = await fetchToken(provider, authServerUrl, { metadata });
|
|
35689
|
+
*/
|
|
35690
|
+
async function fetchToken(provider, authorizationServerUrl, { metadata, resource, authorizationCode, fetchFn } = {}) {
|
|
35691
|
+
const scope = provider.clientMetadata.scope;
|
|
35692
|
+
// Use provider's prepareTokenRequest if available, otherwise fall back to authorization_code
|
|
35693
|
+
let tokenRequestParams;
|
|
35694
|
+
if (provider.prepareTokenRequest) {
|
|
35695
|
+
tokenRequestParams = await provider.prepareTokenRequest(scope);
|
|
35696
|
+
}
|
|
35697
|
+
// Default to authorization_code grant if no custom prepareTokenRequest
|
|
35698
|
+
if (!tokenRequestParams) {
|
|
35699
|
+
if (!authorizationCode) {
|
|
35700
|
+
throw new Error('Either provider.prepareTokenRequest() or authorizationCode is required');
|
|
35701
|
+
}
|
|
35702
|
+
if (!provider.redirectUrl) {
|
|
35703
|
+
throw new Error('redirectUrl is required for authorization_code flow');
|
|
35704
|
+
}
|
|
35705
|
+
const codeVerifier = await provider.codeVerifier();
|
|
35706
|
+
tokenRequestParams = prepareAuthorizationCodeRequest(authorizationCode, codeVerifier, provider.redirectUrl);
|
|
35707
|
+
}
|
|
35708
|
+
const clientInformation = await provider.clientInformation();
|
|
35709
|
+
return executeTokenRequest(authorizationServerUrl, {
|
|
35710
|
+
metadata,
|
|
35711
|
+
tokenRequestParams,
|
|
35712
|
+
clientInformation: clientInformation ?? undefined,
|
|
35713
|
+
addClientAuthentication: provider.addClientAuthentication,
|
|
35714
|
+
resource,
|
|
35715
|
+
fetchFn
|
|
35716
|
+
});
|
|
35717
|
+
}
|
|
35718
|
+
/**
|
|
35719
|
+
* Performs OAuth 2.0 Dynamic Client Registration according to RFC 7591.
|
|
35720
|
+
*
|
|
35721
|
+
* If `scope` is provided, it overrides `clientMetadata.scope` in the registration
|
|
35722
|
+
* request body. This allows callers to apply the Scope Selection Strategy (SEP-835)
|
|
35723
|
+
* consistently across both DCR and the subsequent authorization request.
|
|
35724
|
+
*/
|
|
35725
|
+
async function registerClient(authorizationServerUrl, { metadata, clientMetadata, scope, fetchFn }) {
|
|
35726
|
+
let registrationUrl;
|
|
35727
|
+
if (metadata) {
|
|
35728
|
+
if (!metadata.registration_endpoint) {
|
|
35729
|
+
throw new Error('Incompatible auth server: does not support dynamic client registration');
|
|
35730
|
+
}
|
|
35731
|
+
registrationUrl = new URL(metadata.registration_endpoint);
|
|
35732
|
+
}
|
|
35733
|
+
else {
|
|
35734
|
+
registrationUrl = new URL('/register', authorizationServerUrl);
|
|
35735
|
+
}
|
|
35736
|
+
const response = await (fetchFn ?? fetch)(registrationUrl, {
|
|
35737
|
+
method: 'POST',
|
|
35738
|
+
headers: {
|
|
35739
|
+
'Content-Type': 'application/json'
|
|
35740
|
+
},
|
|
35741
|
+
body: JSON.stringify({
|
|
35742
|
+
...clientMetadata,
|
|
35743
|
+
...(scope !== undefined ? { scope } : {})
|
|
35744
|
+
})
|
|
35745
|
+
});
|
|
35746
|
+
if (!response.ok) {
|
|
35747
|
+
throw await parseErrorResponse(response);
|
|
35748
|
+
}
|
|
35749
|
+
return auth_js_2.OAuthClientInformationFullSchema.parse(await response.json());
|
|
35750
|
+
}
|
|
35751
|
+
|
|
35752
|
+
return auth$1;
|
|
35627
35753
|
}
|
|
35628
35754
|
|
|
35629
35755
|
var stream = {};
|
|
@@ -35826,7 +35952,7 @@ Object.defineProperty(streamableHttp$1, "__esModule", { value: true });
|
|
|
35826
35952
|
streamableHttp$1.StreamableHTTPClientTransport = streamableHttp$1.StreamableHTTPError = void 0;
|
|
35827
35953
|
const transport_js_1 = transport$1;
|
|
35828
35954
|
const types_js_1$4 = types$2;
|
|
35829
|
-
const auth_js_1 =
|
|
35955
|
+
const auth_js_1 = requireAuth();
|
|
35830
35956
|
const stream_1 = stream;
|
|
35831
35957
|
// Default reconnection options for StreamableHTTP connections
|
|
35832
35958
|
const DEFAULT_STREAMABLE_HTTP_RECONNECTION_OPTIONS = {
|
|
@@ -36950,6 +37076,244 @@ var mcpScopeResolver = {
|
|
|
36950
37076
|
applyPathScopeToCredentials: applyPathScopeToCredentials$1,
|
|
36951
37077
|
};
|
|
36952
37078
|
|
|
37079
|
+
/**
|
|
37080
|
+
* mcpOAuthProvider.js
|
|
37081
|
+
*
|
|
37082
|
+
* Implements the MCP SDK's `OAuthClientProvider` interface for custom
|
|
37083
|
+
* remote (streamable_http) MCP servers that authenticate with standard
|
|
37084
|
+
* OAuth 2.0 (e.g. Granola, Linear). This is the generic, SDK-native
|
|
37085
|
+
* alternative to the catalog-only subprocess auth model (`runAuth`)
|
|
37086
|
+
* used by the bundled Google servers.
|
|
37087
|
+
*
|
|
37088
|
+
* Flow (driven by mcpController.connectStreamableHttpWithOAuth):
|
|
37089
|
+
* 1. A loopback HTTP server is started on 127.0.0.1:<ephemeral> to
|
|
37090
|
+
* catch the OAuth redirect. `redirectUrl` reflects that port.
|
|
37091
|
+
* 2. On first connect with no/expired tokens, the SDK calls
|
|
37092
|
+
* `redirectToAuthorization`, which opens the system browser.
|
|
37093
|
+
* 3. The user consents; the authorization server redirects back to the
|
|
37094
|
+
* loopback `/callback?code=...`, which resolves `_waitForCode()`.
|
|
37095
|
+
* 4. The controller calls `transport.finishAuth(code)` → `saveTokens`.
|
|
37096
|
+
*
|
|
37097
|
+
* Tokens, Dynamic Client Registration info, and the PKCE verifier are
|
|
37098
|
+
* persisted encrypted in the SAME providers.json store as credentials
|
|
37099
|
+
* (via providerController), keyed by (appId, serverName). They are never
|
|
37100
|
+
* returned to the renderer.
|
|
37101
|
+
*/
|
|
37102
|
+
|
|
37103
|
+
var mcpOAuthProvider;
|
|
37104
|
+
var hasRequiredMcpOAuthProvider;
|
|
37105
|
+
|
|
37106
|
+
function requireMcpOAuthProvider () {
|
|
37107
|
+
if (hasRequiredMcpOAuthProvider) return mcpOAuthProvider;
|
|
37108
|
+
hasRequiredMcpOAuthProvider = 1;
|
|
37109
|
+
const { shell } = require$$0$2;
|
|
37110
|
+
const http = require$$1$5;
|
|
37111
|
+
const providerController = requireProviderController();
|
|
37112
|
+
|
|
37113
|
+
/**
|
|
37114
|
+
* Start a loopback HTTP server bound to 127.0.0.1 on an OS-assigned port.
|
|
37115
|
+
* Resolves once listening with `{ server, port, codePromise }` where
|
|
37116
|
+
* `codePromise` resolves with the OAuth `code` (or rejects on `error`).
|
|
37117
|
+
*/
|
|
37118
|
+
function startLoopbackServer() {
|
|
37119
|
+
let resolveCode;
|
|
37120
|
+
let rejectCode;
|
|
37121
|
+
const codePromise = new Promise((resolve, reject) => {
|
|
37122
|
+
resolveCode = resolve;
|
|
37123
|
+
rejectCode = reject;
|
|
37124
|
+
});
|
|
37125
|
+
|
|
37126
|
+
const server = http.createServer((req, res) => {
|
|
37127
|
+
try {
|
|
37128
|
+
const reqUrl = new URL(req.url, "http://127.0.0.1");
|
|
37129
|
+
if (reqUrl.pathname !== "/callback") {
|
|
37130
|
+
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
37131
|
+
res.end("Not found");
|
|
37132
|
+
return;
|
|
37133
|
+
}
|
|
37134
|
+
const error = reqUrl.searchParams.get("error");
|
|
37135
|
+
const code = reqUrl.searchParams.get("code");
|
|
37136
|
+
const heading = error ? "Authorization failed" : "Authorization complete";
|
|
37137
|
+
const body = error
|
|
37138
|
+
? "You can close this window and try again in Dash."
|
|
37139
|
+
: "You can close this window and return to Dash.";
|
|
37140
|
+
const html =
|
|
37141
|
+
"<!doctype html><html><head><meta charset='utf-8'>" +
|
|
37142
|
+
"<title>Dash</title></head>" +
|
|
37143
|
+
"<body style='font-family:system-ui,sans-serif;background:#111;color:#eee;" +
|
|
37144
|
+
"display:flex;align-items:center;justify-content:center;height:100vh;margin:0;'>" +
|
|
37145
|
+
`<div style='text-align:center;'><h2>${heading}</h2><p>${body}</p></div>` +
|
|
37146
|
+
"</body></html>";
|
|
37147
|
+
res.writeHead(error ? 400 : 200, { "Content-Type": "text/html" });
|
|
37148
|
+
res.end(html);
|
|
37149
|
+
|
|
37150
|
+
if (error) {
|
|
37151
|
+
rejectCode(new Error(`OAuth authorization error: ${error}`));
|
|
37152
|
+
} else if (code) {
|
|
37153
|
+
resolveCode(code);
|
|
37154
|
+
} else {
|
|
37155
|
+
rejectCode(new Error("OAuth callback missing authorization code"));
|
|
37156
|
+
}
|
|
37157
|
+
} catch (e) {
|
|
37158
|
+
rejectCode(e);
|
|
37159
|
+
}
|
|
37160
|
+
});
|
|
37161
|
+
|
|
37162
|
+
return new Promise((resolve, reject) => {
|
|
37163
|
+
server.once("error", reject);
|
|
37164
|
+
// Bind to loopback only (never 0.0.0.0) — port 0 = OS-assigned.
|
|
37165
|
+
server.listen(0, "127.0.0.1", () => {
|
|
37166
|
+
const addr = server.address();
|
|
37167
|
+
resolve({ server, port: addr.port, codePromise });
|
|
37168
|
+
});
|
|
37169
|
+
});
|
|
37170
|
+
}
|
|
37171
|
+
|
|
37172
|
+
/**
|
|
37173
|
+
* Create an OAuthClientProvider for one (appId, serverName) pair.
|
|
37174
|
+
*
|
|
37175
|
+
* @param {object} args
|
|
37176
|
+
* @param {BrowserWindow|null} args.win unused today; reserved for future
|
|
37177
|
+
* window-scoped flows.
|
|
37178
|
+
* @param {string} args.appId application id (providers.json namespace)
|
|
37179
|
+
* @param {string} args.serverName provider/server name (storage key)
|
|
37180
|
+
* @param {object} args.mcpConfig the server config; `mcpConfig.oauth` may
|
|
37181
|
+
* carry `{ scopes, clientId?, clientSecret? }`.
|
|
37182
|
+
*/
|
|
37183
|
+
function createMcpOAuthProvider({ win, appId, serverName, mcpConfig }) {
|
|
37184
|
+
const oauth = (mcpConfig && mcpConfig.oauth) || {};
|
|
37185
|
+
|
|
37186
|
+
// Lazy-hydrated cache of persisted { tokens, clientInformation, codeVerifier }.
|
|
37187
|
+
let state = null;
|
|
37188
|
+
const load = () => {
|
|
37189
|
+
if (state) return state;
|
|
37190
|
+
const res = providerController.getOAuthState(win, appId, serverName);
|
|
37191
|
+
state = (res && res.oauth) || {};
|
|
37192
|
+
return state;
|
|
37193
|
+
};
|
|
37194
|
+
const persist = (patch) => {
|
|
37195
|
+
state = { ...load(), ...patch };
|
|
37196
|
+
providerController.saveOAuthState(win, appId, serverName, state);
|
|
37197
|
+
};
|
|
37198
|
+
|
|
37199
|
+
// Loopback server for the current flow (null when idle).
|
|
37200
|
+
let loopback = null;
|
|
37201
|
+
|
|
37202
|
+
return {
|
|
37203
|
+
get redirectUrl() {
|
|
37204
|
+
return loopback
|
|
37205
|
+
? `http://127.0.0.1:${loopback.port}/callback`
|
|
37206
|
+
: undefined;
|
|
37207
|
+
},
|
|
37208
|
+
|
|
37209
|
+
get clientMetadata() {
|
|
37210
|
+
const redirectUrl = this.redirectUrl;
|
|
37211
|
+
return {
|
|
37212
|
+
client_name: `Dash – ${serverName}`,
|
|
37213
|
+
redirect_uris: redirectUrl ? [redirectUrl] : [],
|
|
37214
|
+
grant_types: ["authorization_code", "refresh_token"],
|
|
37215
|
+
response_types: ["code"],
|
|
37216
|
+
token_endpoint_auth_method: oauth.clientSecret
|
|
37217
|
+
? "client_secret_post"
|
|
37218
|
+
: "none",
|
|
37219
|
+
...(oauth.scopes ? { scope: oauth.scopes } : {}),
|
|
37220
|
+
};
|
|
37221
|
+
},
|
|
37222
|
+
|
|
37223
|
+
clientInformation() {
|
|
37224
|
+
// Pre-registered (manual) client wins over Dynamic Client Registration.
|
|
37225
|
+
if (oauth.clientId) {
|
|
37226
|
+
return {
|
|
37227
|
+
client_id: oauth.clientId,
|
|
37228
|
+
...(oauth.clientSecret ? { client_secret: oauth.clientSecret } : {}),
|
|
37229
|
+
};
|
|
37230
|
+
}
|
|
37231
|
+
return load().clientInformation;
|
|
37232
|
+
},
|
|
37233
|
+
|
|
37234
|
+
saveClientInformation(clientInformation) {
|
|
37235
|
+
persist({ clientInformation });
|
|
37236
|
+
},
|
|
37237
|
+
|
|
37238
|
+
tokens() {
|
|
37239
|
+
return load().tokens;
|
|
37240
|
+
},
|
|
37241
|
+
|
|
37242
|
+
// Called by the SDK on initial authorization AND on every refresh.
|
|
37243
|
+
saveTokens(tokens) {
|
|
37244
|
+
persist({ tokens });
|
|
37245
|
+
},
|
|
37246
|
+
|
|
37247
|
+
saveCodeVerifier(codeVerifier) {
|
|
37248
|
+
persist({ codeVerifier });
|
|
37249
|
+
},
|
|
37250
|
+
|
|
37251
|
+
codeVerifier() {
|
|
37252
|
+
const v = load().codeVerifier;
|
|
37253
|
+
if (!v) throw new Error("No OAuth code verifier saved");
|
|
37254
|
+
return v;
|
|
37255
|
+
},
|
|
37256
|
+
|
|
37257
|
+
async redirectToAuthorization(authorizationUrl) {
|
|
37258
|
+
await shell.openExternal(authorizationUrl.toString());
|
|
37259
|
+
},
|
|
37260
|
+
|
|
37261
|
+
// Lets the SDK clear bad credentials so the next attempt re-auths
|
|
37262
|
+
// without manual intervention (e.g. refresh token revoked).
|
|
37263
|
+
invalidateCredentials(scope) {
|
|
37264
|
+
if (scope === "all" || scope === "tokens") persist({ tokens: undefined });
|
|
37265
|
+
if (scope === "all" || scope === "client")
|
|
37266
|
+
persist({ clientInformation: undefined });
|
|
37267
|
+
if (scope === "all" || scope === "verifier")
|
|
37268
|
+
persist({ codeVerifier: undefined });
|
|
37269
|
+
},
|
|
37270
|
+
|
|
37271
|
+
// --- helpers used by the controller (not part of the SDK interface) ---
|
|
37272
|
+
|
|
37273
|
+
async _startLoopback() {
|
|
37274
|
+
if (!loopback) {
|
|
37275
|
+
loopback = await startLoopbackServer();
|
|
37276
|
+
}
|
|
37277
|
+
return loopback;
|
|
37278
|
+
},
|
|
37279
|
+
|
|
37280
|
+
_stopLoopback() {
|
|
37281
|
+
if (loopback) {
|
|
37282
|
+
try {
|
|
37283
|
+
loopback.server.close();
|
|
37284
|
+
} catch (_e) {
|
|
37285
|
+
/* already closing */
|
|
37286
|
+
}
|
|
37287
|
+
loopback = null;
|
|
37288
|
+
}
|
|
37289
|
+
},
|
|
37290
|
+
|
|
37291
|
+
_waitForCode(timeoutMs = 120000) {
|
|
37292
|
+
if (!loopback) {
|
|
37293
|
+
return Promise.reject(new Error("OAuth loopback server not started"));
|
|
37294
|
+
}
|
|
37295
|
+
return Promise.race([
|
|
37296
|
+
loopback.codePromise,
|
|
37297
|
+
new Promise((_resolve, reject) =>
|
|
37298
|
+
setTimeout(
|
|
37299
|
+
() =>
|
|
37300
|
+
reject(
|
|
37301
|
+
new Error(
|
|
37302
|
+
"OAuth authorization timed out. Close the browser tab and try again.",
|
|
37303
|
+
),
|
|
37304
|
+
),
|
|
37305
|
+
timeoutMs,
|
|
37306
|
+
),
|
|
37307
|
+
),
|
|
37308
|
+
]);
|
|
37309
|
+
},
|
|
37310
|
+
};
|
|
37311
|
+
}
|
|
37312
|
+
|
|
37313
|
+
mcpOAuthProvider = { createMcpOAuthProvider, startLoopbackServer };
|
|
37314
|
+
return mcpOAuthProvider;
|
|
37315
|
+
}
|
|
37316
|
+
|
|
36953
37317
|
/**
|
|
36954
37318
|
* mcpController.js
|
|
36955
37319
|
*
|
|
@@ -36966,7 +37330,7 @@ var mcpScopeResolver = {
|
|
|
36966
37330
|
const { Client } = require$$0$8;
|
|
36967
37331
|
const {
|
|
36968
37332
|
StdioClientTransport,
|
|
36969
|
-
} = require$$1$
|
|
37333
|
+
} = require$$1$6;
|
|
36970
37334
|
const {
|
|
36971
37335
|
StreamableHTTPClientTransport,
|
|
36972
37336
|
} = streamableHttp$1;
|
|
@@ -37377,6 +37741,57 @@ async function refreshGoogleOAuthToken(tokenRefresh) {
|
|
|
37377
37741
|
console.log("[mcpController] Google OAuth token refreshed successfully");
|
|
37378
37742
|
}
|
|
37379
37743
|
|
|
37744
|
+
/**
|
|
37745
|
+
* Connect a streamable_http MCP server that authenticates via OAuth 2.0,
|
|
37746
|
+
* using the SDK's native OAuthClientProvider.
|
|
37747
|
+
*
|
|
37748
|
+
* Drives the connect → UnauthorizedError → finishAuth → reconnect dance:
|
|
37749
|
+
* - With valid (or refreshable) tokens, the first connect succeeds and no
|
|
37750
|
+
* browser opens (fast path).
|
|
37751
|
+
* - Otherwise the SDK opens the system browser via
|
|
37752
|
+
* `redirectToAuthorization`, throws UnauthorizedError, and we wait for
|
|
37753
|
+
* the loopback callback, exchange the code, then reconnect.
|
|
37754
|
+
*
|
|
37755
|
+
* The authorized reconnect uses a FRESH transport because the first
|
|
37756
|
+
* transport already called `start()` and cannot be restarted. `finishAuth`
|
|
37757
|
+
* runs on the original transport so it reuses that attempt's discovery state.
|
|
37758
|
+
*
|
|
37759
|
+
* @returns {Promise<{ client, transport }>} a connected client + transport
|
|
37760
|
+
*/
|
|
37761
|
+
async function connectStreamableHttpWithOAuth(urlObj, oauthProvider) {
|
|
37762
|
+
const {
|
|
37763
|
+
UnauthorizedError,
|
|
37764
|
+
} = requireAuth();
|
|
37765
|
+
|
|
37766
|
+
await oauthProvider._startLoopback();
|
|
37767
|
+
try {
|
|
37768
|
+
const client = new Client({ name: "dash", version: "1.0.0" });
|
|
37769
|
+
const transport = new StreamableHTTPClientTransport(urlObj, {
|
|
37770
|
+
authProvider: oauthProvider,
|
|
37771
|
+
});
|
|
37772
|
+
try {
|
|
37773
|
+
await client.connect(transport);
|
|
37774
|
+
return { client, transport };
|
|
37775
|
+
} catch (err) {
|
|
37776
|
+
if (!(err instanceof UnauthorizedError)) throw err;
|
|
37777
|
+
console.log(
|
|
37778
|
+
"[mcpController] OAuth required — waiting for browser authorization...",
|
|
37779
|
+
);
|
|
37780
|
+
const code = await oauthProvider._waitForCode();
|
|
37781
|
+
await transport.finishAuth(code);
|
|
37782
|
+
|
|
37783
|
+
const client2 = new Client({ name: "dash", version: "1.0.0" });
|
|
37784
|
+
const transport2 = new StreamableHTTPClientTransport(urlObj, {
|
|
37785
|
+
authProvider: oauthProvider,
|
|
37786
|
+
});
|
|
37787
|
+
await client2.connect(transport2);
|
|
37788
|
+
return { client: client2, transport: transport2 };
|
|
37789
|
+
}
|
|
37790
|
+
} finally {
|
|
37791
|
+
oauthProvider._stopLoopback();
|
|
37792
|
+
}
|
|
37793
|
+
}
|
|
37794
|
+
|
|
37380
37795
|
const mcpController$3 = {
|
|
37381
37796
|
/**
|
|
37382
37797
|
* startServer
|
|
@@ -37409,6 +37824,7 @@ const mcpController$3 = {
|
|
|
37409
37824
|
credentials,
|
|
37410
37825
|
workspaceId,
|
|
37411
37826
|
pathScope = null,
|
|
37827
|
+
appId = null,
|
|
37412
37828
|
) => {
|
|
37413
37829
|
const key = serverKey(workspaceId, serverName);
|
|
37414
37830
|
// Slice 3b: when the gate is enforced, override credentials with
|
|
@@ -37483,6 +37899,11 @@ const mcpController$3 = {
|
|
|
37483
37899
|
|
|
37484
37900
|
// Create transport based on type
|
|
37485
37901
|
let transport;
|
|
37902
|
+
// OAuth state, populated below for OAuth streamable_http servers.
|
|
37903
|
+
// When set, the connect step runs the interactive OAuth dance
|
|
37904
|
+
// (which builds its own transport) instead of the generic connect.
|
|
37905
|
+
let oauthProvider = null;
|
|
37906
|
+
let oauthUrl = null;
|
|
37486
37907
|
if (mcpConfig.transport === "streamable_http") {
|
|
37487
37908
|
// Remote HTTP transport - connect to a hosted MCP server
|
|
37488
37909
|
const url = interpolate$1(mcpConfig.url, credentials);
|
|
@@ -37490,21 +37911,37 @@ const mcpController$3 = {
|
|
|
37490
37911
|
throw new Error("Streamable HTTP transport requires a URL");
|
|
37491
37912
|
}
|
|
37492
37913
|
|
|
37493
|
-
|
|
37494
|
-
|
|
37495
|
-
|
|
37496
|
-
|
|
37497
|
-
|
|
37498
|
-
|
|
37914
|
+
if (mcpConfig.auth === "oauth" || mcpConfig.oauth) {
|
|
37915
|
+
// OAuth 2.0 server (e.g. Granola, Linear): authenticate via the
|
|
37916
|
+
// SDK's native OAuthClientProvider + browser flow + token
|
|
37917
|
+
// refresh. Transport is created during the connect dance below.
|
|
37918
|
+
const {
|
|
37919
|
+
createMcpOAuthProvider,
|
|
37920
|
+
} = requireMcpOAuthProvider();
|
|
37921
|
+
oauthProvider = createMcpOAuthProvider({
|
|
37922
|
+
win,
|
|
37923
|
+
appId,
|
|
37924
|
+
serverName,
|
|
37925
|
+
mcpConfig,
|
|
37926
|
+
});
|
|
37927
|
+
oauthUrl = new URL(url);
|
|
37928
|
+
} else {
|
|
37929
|
+
// Build request headers from headerTemplate
|
|
37930
|
+
const headers = {};
|
|
37931
|
+
if (mcpConfig.headerTemplate && credentials) {
|
|
37932
|
+
Object.entries(mcpConfig.headerTemplate).forEach(
|
|
37933
|
+
([headerName, template]) => {
|
|
37934
|
+
headers[headerName] = interpolate$1(template, credentials);
|
|
37935
|
+
},
|
|
37936
|
+
);
|
|
37937
|
+
}
|
|
37938
|
+
|
|
37939
|
+
transport = new StreamableHTTPClientTransport(new URL(url), {
|
|
37940
|
+
requestInit: {
|
|
37941
|
+
headers,
|
|
37499
37942
|
},
|
|
37500
|
-
);
|
|
37943
|
+
});
|
|
37501
37944
|
}
|
|
37502
|
-
|
|
37503
|
-
transport = new StreamableHTTPClientTransport(new URL(url), {
|
|
37504
|
-
requestInit: {
|
|
37505
|
-
headers,
|
|
37506
|
-
},
|
|
37507
|
-
});
|
|
37508
37945
|
} else {
|
|
37509
37946
|
// stdio transport (default) - spawn a local child process
|
|
37510
37947
|
const env = cleanEnvForChildProcess();
|
|
@@ -37589,14 +38026,26 @@ const mcpController$3 = {
|
|
|
37589
38026
|
serverName,
|
|
37590
38027
|
});
|
|
37591
38028
|
|
|
37592
|
-
// Create MCP client
|
|
37593
|
-
|
|
37594
|
-
|
|
37595
|
-
|
|
37596
|
-
|
|
37597
|
-
|
|
37598
|
-
|
|
37599
|
-
|
|
38029
|
+
// Create / connect MCP client. OAuth servers run the interactive
|
|
38030
|
+
// connect → authorize → reconnect dance, which yields its own
|
|
38031
|
+
// client + transport (a fresh transport is required for the
|
|
38032
|
+
// authorized reconnect).
|
|
38033
|
+
let client;
|
|
38034
|
+
if (oauthProvider) {
|
|
38035
|
+
const oauthResult = await connectStreamableHttpWithOAuth(
|
|
38036
|
+
oauthUrl,
|
|
38037
|
+
oauthProvider,
|
|
38038
|
+
);
|
|
38039
|
+
client = oauthResult.client;
|
|
38040
|
+
transport = oauthResult.transport;
|
|
38041
|
+
} else {
|
|
38042
|
+
client = new Client({
|
|
38043
|
+
name: "dash",
|
|
38044
|
+
version: "1.0.0",
|
|
38045
|
+
});
|
|
38046
|
+
// Connect to the server
|
|
38047
|
+
await client.connect(transport);
|
|
38048
|
+
}
|
|
37600
38049
|
|
|
37601
38050
|
// List available tools
|
|
37602
38051
|
let tools = [];
|
|
@@ -37682,6 +38131,83 @@ const mcpController$3 = {
|
|
|
37682
38131
|
return startPromise;
|
|
37683
38132
|
},
|
|
37684
38133
|
|
|
38134
|
+
/**
|
|
38135
|
+
* authorizeServer
|
|
38136
|
+
* Run the interactive OAuth 2.0 authorization flow on demand for a
|
|
38137
|
+
* custom streamable_http MCP server (the Settings "Authorize" button
|
|
38138
|
+
* and the re-auth banner). Opens the system browser, completes the
|
|
38139
|
+
* flow, and persists tokens encrypted. A subsequent startServer hits
|
|
38140
|
+
* the valid-token fast path with no browser.
|
|
38141
|
+
*
|
|
38142
|
+
* @param {BrowserWindow} win the main window
|
|
38143
|
+
* @param {string} serverName the provider/server name
|
|
38144
|
+
* @param {object} mcpConfig must be streamable_http with auth: "oauth"
|
|
38145
|
+
* @param {object} credentials decrypted credentials (for URL interpolation)
|
|
38146
|
+
* @param {string} appId application id (token storage namespace)
|
|
38147
|
+
* @returns {Promise<{ success, serverName, tools } | { error, message }>}
|
|
38148
|
+
*/
|
|
38149
|
+
authorizeServer: async (win, serverName, mcpConfig, credentials, appId) => {
|
|
38150
|
+
try {
|
|
38151
|
+
if (
|
|
38152
|
+
!mcpConfig ||
|
|
38153
|
+
mcpConfig.transport !== "streamable_http" ||
|
|
38154
|
+
!(mcpConfig.auth === "oauth" || mcpConfig.oauth)
|
|
38155
|
+
) {
|
|
38156
|
+
return {
|
|
38157
|
+
error: true,
|
|
38158
|
+
message: "Server is not configured for OAuth authorization",
|
|
38159
|
+
};
|
|
38160
|
+
}
|
|
38161
|
+
|
|
38162
|
+
const url = interpolate$1(mcpConfig.url, credentials);
|
|
38163
|
+
if (!url) {
|
|
38164
|
+
return {
|
|
38165
|
+
error: true,
|
|
38166
|
+
message: "Streamable HTTP transport requires a URL",
|
|
38167
|
+
};
|
|
38168
|
+
}
|
|
38169
|
+
|
|
38170
|
+
const { createMcpOAuthProvider } = requireMcpOAuthProvider();
|
|
38171
|
+
const oauthProvider = createMcpOAuthProvider({
|
|
38172
|
+
win,
|
|
38173
|
+
appId,
|
|
38174
|
+
serverName,
|
|
38175
|
+
mcpConfig,
|
|
38176
|
+
});
|
|
38177
|
+
|
|
38178
|
+
const { client } = await connectStreamableHttpWithOAuth(
|
|
38179
|
+
new URL(url),
|
|
38180
|
+
oauthProvider,
|
|
38181
|
+
);
|
|
38182
|
+
|
|
38183
|
+
// Verify the connection by listing tools, then close — startServer
|
|
38184
|
+
// will reconnect later using the freshly stored tokens.
|
|
38185
|
+
let tools = [];
|
|
38186
|
+
try {
|
|
38187
|
+
const toolsResult = await client.listTools();
|
|
38188
|
+
tools = toolsResult.tools || [];
|
|
38189
|
+
} catch (_e) {
|
|
38190
|
+
// Tools optional for the auth check
|
|
38191
|
+
}
|
|
38192
|
+
try {
|
|
38193
|
+
await client.close();
|
|
38194
|
+
} catch (_e) {
|
|
38195
|
+
/* ignore close errors */
|
|
38196
|
+
}
|
|
38197
|
+
|
|
38198
|
+
console.log(
|
|
38199
|
+
`[mcpController] OAuth authorization succeeded for ${serverName} (${tools.length} tools)`,
|
|
38200
|
+
);
|
|
38201
|
+
return { success: true, serverName, tools };
|
|
38202
|
+
} catch (error) {
|
|
38203
|
+
console.error(
|
|
38204
|
+
`[mcpController] OAuth authorization failed for ${serverName}:`,
|
|
38205
|
+
error,
|
|
38206
|
+
);
|
|
38207
|
+
return { error: true, message: error.message };
|
|
38208
|
+
}
|
|
38209
|
+
},
|
|
38210
|
+
|
|
37685
38211
|
/**
|
|
37686
38212
|
* stopServer
|
|
37687
38213
|
* Stop a running MCP server
|
|
@@ -56494,13 +57020,13 @@ __export(src_exports, {
|
|
|
56494
57020
|
var dist = __toCommonJS(src_exports);
|
|
56495
57021
|
|
|
56496
57022
|
// src/server.ts
|
|
56497
|
-
var import_node_http = require$$
|
|
57023
|
+
var import_node_http = require$$1$5;
|
|
56498
57024
|
|
|
56499
57025
|
// src/listener.ts
|
|
56500
|
-
var import_node_http22 = require$$1$
|
|
57026
|
+
var import_node_http22 = require$$1$7;
|
|
56501
57027
|
|
|
56502
57028
|
// src/request.ts
|
|
56503
|
-
var import_node_http2 = require$$1$
|
|
57029
|
+
var import_node_http2 = require$$1$7;
|
|
56504
57030
|
var import_node_stream = require$$5$1;
|
|
56505
57031
|
var RequestError = class extends Error {
|
|
56506
57032
|
constructor(message, options) {
|
|
@@ -60154,10 +60680,10 @@ var themeFromUrlErrors$1 = {
|
|
|
60154
60680
|
* computed styles, and favicon/logo images (via node-vibrant).
|
|
60155
60681
|
*/
|
|
60156
60682
|
|
|
60157
|
-
const css = require$$0$
|
|
60158
|
-
const { Vibrant } = require$$1$
|
|
60683
|
+
const css = require$$0$a;
|
|
60684
|
+
const { Vibrant } = require$$1$8;
|
|
60159
60685
|
const https = require$$11;
|
|
60160
|
-
const http = require$$
|
|
60686
|
+
const http = require$$1$5;
|
|
60161
60687
|
const { URL: URL$1 } = require$$4;
|
|
60162
60688
|
const {
|
|
60163
60689
|
UrlUnreachableError,
|
|
@@ -65005,7 +65531,7 @@ var toolHandlers$1 = {
|
|
|
65005
65531
|
* per-request, receiving the full messages array each time.
|
|
65006
65532
|
*/
|
|
65007
65533
|
|
|
65008
|
-
const Anthropic = require$$0$
|
|
65534
|
+
const Anthropic = require$$0$b;
|
|
65009
65535
|
const mcpController$2 = mcpControllerExports;
|
|
65010
65536
|
const cliController$1 = cliControllerExports;
|
|
65011
65537
|
const toolDefinitions = toolDefinitions$1;
|
|
@@ -74947,6 +75473,7 @@ const {
|
|
|
74947
75473
|
MCP_INSTALL_KNOWN_EXTERNAL_CONFIRM: MCP_INSTALL_KNOWN_EXTERNAL_CONFIRM$1,
|
|
74948
75474
|
MCP_INSTALL_KNOWN_EXTERNAL_RESULT: MCP_INSTALL_KNOWN_EXTERNAL_RESULT$1,
|
|
74949
75475
|
MCP_RUN_AUTH,
|
|
75476
|
+
MCP_AUTHORIZE,
|
|
74950
75477
|
} = events$8;
|
|
74951
75478
|
|
|
74952
75479
|
const mcpApi$2 = {
|
|
@@ -74971,6 +75498,7 @@ const mcpApi$2 = {
|
|
|
74971
75498
|
credentials,
|
|
74972
75499
|
workspaceId = null,
|
|
74973
75500
|
pathScope = null,
|
|
75501
|
+
appId = null,
|
|
74974
75502
|
) =>
|
|
74975
75503
|
ipcRenderer$j.invoke(MCP_START_SERVER, {
|
|
74976
75504
|
serverName,
|
|
@@ -74978,6 +75506,7 @@ const mcpApi$2 = {
|
|
|
74978
75506
|
credentials,
|
|
74979
75507
|
workspaceId,
|
|
74980
75508
|
pathScope,
|
|
75509
|
+
appId,
|
|
74981
75510
|
}),
|
|
74982
75511
|
|
|
74983
75512
|
/**
|
|
@@ -75131,6 +75660,27 @@ const mcpApi$2 = {
|
|
|
75131
75660
|
*/
|
|
75132
75661
|
runAuth: (mcpConfig, credentials, authCommand) =>
|
|
75133
75662
|
ipcRenderer$j.invoke(MCP_RUN_AUTH, { mcpConfig, credentials, authCommand }),
|
|
75663
|
+
|
|
75664
|
+
/**
|
|
75665
|
+
* authorize
|
|
75666
|
+
* Run the interactive OAuth 2.0 authorization flow for a custom
|
|
75667
|
+
* streamable_http MCP server (opens the system browser). Tokens are
|
|
75668
|
+
* persisted encrypted in the main process; a later startServer reuses
|
|
75669
|
+
* them with no browser.
|
|
75670
|
+
*
|
|
75671
|
+
* @param {string} serverName the provider/server name (token storage key)
|
|
75672
|
+
* @param {object} mcpConfig { transport: "streamable_http", auth: "oauth", url, oauth }
|
|
75673
|
+
* @param {object} credentials decrypted credentials (URL interpolation)
|
|
75674
|
+
* @param {string} appId application id (token storage namespace)
|
|
75675
|
+
* @returns {Promise<{ success, serverName, tools } | { error, message }>}
|
|
75676
|
+
*/
|
|
75677
|
+
authorize: (serverName, mcpConfig, credentials, appId = null) =>
|
|
75678
|
+
ipcRenderer$j.invoke(MCP_AUTHORIZE, {
|
|
75679
|
+
serverName,
|
|
75680
|
+
mcpConfig,
|
|
75681
|
+
credentials,
|
|
75682
|
+
appId,
|
|
75683
|
+
}),
|
|
75134
75684
|
};
|
|
75135
75685
|
|
|
75136
75686
|
var mcpApi_1 = mcpApi$2;
|