@mcp-z/client 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +159 -0
- package/LICENSE +21 -0
- package/README.md +90 -0
- package/dist/cjs/auth/capability-discovery.d.cts +25 -0
- package/dist/cjs/auth/capability-discovery.d.ts +25 -0
- package/dist/cjs/auth/capability-discovery.js +280 -0
- package/dist/cjs/auth/capability-discovery.js.map +1 -0
- package/dist/cjs/auth/index.d.cts +9 -0
- package/dist/cjs/auth/index.d.ts +9 -0
- package/dist/cjs/auth/index.js +28 -0
- package/dist/cjs/auth/index.js.map +1 -0
- package/dist/cjs/auth/interactive-oauth-flow.d.cts +58 -0
- package/dist/cjs/auth/interactive-oauth-flow.d.ts +58 -0
- package/dist/cjs/auth/interactive-oauth-flow.js +537 -0
- package/dist/cjs/auth/interactive-oauth-flow.js.map +1 -0
- package/dist/cjs/auth/oauth-callback-listener.d.cts +56 -0
- package/dist/cjs/auth/oauth-callback-listener.d.ts +56 -0
- package/dist/cjs/auth/oauth-callback-listener.js +333 -0
- package/dist/cjs/auth/oauth-callback-listener.js.map +1 -0
- package/dist/cjs/auth/pkce.d.cts +17 -0
- package/dist/cjs/auth/pkce.d.ts +17 -0
- package/dist/cjs/auth/pkce.js +192 -0
- package/dist/cjs/auth/pkce.js.map +1 -0
- package/dist/cjs/auth/rfc9728-discovery.d.cts +34 -0
- package/dist/cjs/auth/rfc9728-discovery.d.ts +34 -0
- package/dist/cjs/auth/rfc9728-discovery.js +436 -0
- package/dist/cjs/auth/rfc9728-discovery.js.map +1 -0
- package/dist/cjs/auth/types.d.cts +137 -0
- package/dist/cjs/auth/types.d.ts +137 -0
- package/dist/cjs/auth/types.js +9 -0
- package/dist/cjs/auth/types.js.map +1 -0
- package/dist/cjs/client-helpers.d.cts +55 -0
- package/dist/cjs/client-helpers.d.ts +55 -0
- package/dist/cjs/client-helpers.js +128 -0
- package/dist/cjs/client-helpers.js.map +1 -0
- package/dist/cjs/config/server-loader.d.cts +27 -0
- package/dist/cjs/config/server-loader.d.ts +27 -0
- package/dist/cjs/config/server-loader.js +111 -0
- package/dist/cjs/config/server-loader.js.map +1 -0
- package/dist/cjs/config/validate-config.d.cts +15 -0
- package/dist/cjs/config/validate-config.d.ts +15 -0
- package/dist/cjs/config/validate-config.js +128 -0
- package/dist/cjs/config/validate-config.js.map +1 -0
- package/dist/cjs/connection/connect-client.d.cts +59 -0
- package/dist/cjs/connection/connect-client.d.ts +59 -0
- package/dist/cjs/connection/connect-client.js +536 -0
- package/dist/cjs/connection/connect-client.js.map +1 -0
- package/dist/cjs/connection/existing-process-transport.d.cts +40 -0
- package/dist/cjs/connection/existing-process-transport.d.ts +40 -0
- package/dist/cjs/connection/existing-process-transport.js +274 -0
- package/dist/cjs/connection/existing-process-transport.js.map +1 -0
- package/dist/cjs/connection/types.d.cts +61 -0
- package/dist/cjs/connection/types.d.ts +61 -0
- package/dist/cjs/connection/types.js +53 -0
- package/dist/cjs/connection/types.js.map +1 -0
- package/dist/cjs/connection/wait-for-http-ready.d.cts +15 -0
- package/dist/cjs/connection/wait-for-http-ready.d.ts +15 -0
- package/dist/cjs/connection/wait-for-http-ready.js +232 -0
- package/dist/cjs/connection/wait-for-http-ready.js.map +1 -0
- package/dist/cjs/dcr/dcr-authenticator.d.cts +73 -0
- package/dist/cjs/dcr/dcr-authenticator.d.ts +73 -0
- package/dist/cjs/dcr/dcr-authenticator.js +655 -0
- package/dist/cjs/dcr/dcr-authenticator.js.map +1 -0
- package/dist/cjs/dcr/dynamic-client-registrar.d.cts +28 -0
- package/dist/cjs/dcr/dynamic-client-registrar.d.ts +28 -0
- package/dist/cjs/dcr/dynamic-client-registrar.js +245 -0
- package/dist/cjs/dcr/dynamic-client-registrar.js.map +1 -0
- package/dist/cjs/dcr/index.d.cts +8 -0
- package/dist/cjs/dcr/index.d.ts +8 -0
- package/dist/cjs/dcr/index.js +24 -0
- package/dist/cjs/dcr/index.js.map +1 -0
- package/dist/cjs/index.d.cts +21 -0
- package/dist/cjs/index.d.ts +21 -0
- package/dist/cjs/index.js +94 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/monkey-patches.d.cts +6 -0
- package/dist/cjs/monkey-patches.d.ts +6 -0
- package/dist/cjs/monkey-patches.js +236 -0
- package/dist/cjs/monkey-patches.js.map +1 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/response-wrappers.d.cts +41 -0
- package/dist/cjs/response-wrappers.d.ts +41 -0
- package/dist/cjs/response-wrappers.js +443 -0
- package/dist/cjs/response-wrappers.js.map +1 -0
- package/dist/cjs/search/index.d.cts +6 -0
- package/dist/cjs/search/index.d.ts +6 -0
- package/dist/cjs/search/index.js +25 -0
- package/dist/cjs/search/index.js.map +1 -0
- package/dist/cjs/search/search.d.cts +22 -0
- package/dist/cjs/search/search.d.ts +22 -0
- package/dist/cjs/search/search.js +630 -0
- package/dist/cjs/search/search.js.map +1 -0
- package/dist/cjs/search/types.d.cts +122 -0
- package/dist/cjs/search/types.d.ts +122 -0
- package/dist/cjs/search/types.js +10 -0
- package/dist/cjs/search/types.js.map +1 -0
- package/dist/cjs/spawn/spawn-server.d.cts +83 -0
- package/dist/cjs/spawn/spawn-server.d.ts +83 -0
- package/dist/cjs/spawn/spawn-server.js +410 -0
- package/dist/cjs/spawn/spawn-server.js.map +1 -0
- package/dist/cjs/spawn/spawn-servers.d.cts +151 -0
- package/dist/cjs/spawn/spawn-servers.d.ts +151 -0
- package/dist/cjs/spawn/spawn-servers.js +911 -0
- package/dist/cjs/spawn/spawn-servers.js.map +1 -0
- package/dist/cjs/types.d.cts +11 -0
- package/dist/cjs/types.d.ts +11 -0
- package/dist/cjs/types.js +10 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/cjs/utils/logger.d.cts +24 -0
- package/dist/cjs/utils/logger.d.ts +24 -0
- package/dist/cjs/utils/logger.js +80 -0
- package/dist/cjs/utils/logger.js.map +1 -0
- package/dist/cjs/utils/path-utils.d.cts +45 -0
- package/dist/cjs/utils/path-utils.d.ts +45 -0
- package/dist/cjs/utils/path-utils.js +158 -0
- package/dist/cjs/utils/path-utils.js.map +1 -0
- package/dist/cjs/utils/sanitizer.d.cts +30 -0
- package/dist/cjs/utils/sanitizer.d.ts +30 -0
- package/dist/cjs/utils/sanitizer.js +124 -0
- package/dist/cjs/utils/sanitizer.js.map +1 -0
- package/dist/esm/auth/capability-discovery.d.ts +25 -0
- package/dist/esm/auth/capability-discovery.js +110 -0
- package/dist/esm/auth/capability-discovery.js.map +1 -0
- package/dist/esm/auth/index.d.ts +9 -0
- package/dist/esm/auth/index.js +6 -0
- package/dist/esm/auth/index.js.map +1 -0
- package/dist/esm/auth/interactive-oauth-flow.d.ts +58 -0
- package/dist/esm/auth/interactive-oauth-flow.js +217 -0
- package/dist/esm/auth/interactive-oauth-flow.js.map +1 -0
- package/dist/esm/auth/oauth-callback-listener.d.ts +56 -0
- package/dist/esm/auth/oauth-callback-listener.js +166 -0
- package/dist/esm/auth/oauth-callback-listener.js.map +1 -0
- package/dist/esm/auth/pkce.d.ts +17 -0
- package/dist/esm/auth/pkce.js +41 -0
- package/dist/esm/auth/pkce.js.map +1 -0
- package/dist/esm/auth/rfc9728-discovery.d.ts +34 -0
- package/dist/esm/auth/rfc9728-discovery.js +157 -0
- package/dist/esm/auth/rfc9728-discovery.js.map +1 -0
- package/dist/esm/auth/types.d.ts +137 -0
- package/dist/esm/auth/types.js +7 -0
- package/dist/esm/auth/types.js.map +1 -0
- package/dist/esm/client-helpers.d.ts +55 -0
- package/dist/esm/client-helpers.js +81 -0
- package/dist/esm/client-helpers.js.map +1 -0
- package/dist/esm/config/server-loader.d.ts +27 -0
- package/dist/esm/config/server-loader.js +49 -0
- package/dist/esm/config/server-loader.js.map +1 -0
- package/dist/esm/config/validate-config.d.ts +15 -0
- package/dist/esm/config/validate-config.js +76 -0
- package/dist/esm/config/validate-config.js.map +1 -0
- package/dist/esm/connection/connect-client.d.ts +59 -0
- package/dist/esm/connection/connect-client.js +272 -0
- package/dist/esm/connection/connect-client.js.map +1 -0
- package/dist/esm/connection/existing-process-transport.d.ts +40 -0
- package/dist/esm/connection/existing-process-transport.js +103 -0
- package/dist/esm/connection/existing-process-transport.js.map +1 -0
- package/dist/esm/connection/types.d.ts +61 -0
- package/dist/esm/connection/types.js +34 -0
- package/dist/esm/connection/types.js.map +1 -0
- package/dist/esm/connection/wait-for-http-ready.d.ts +15 -0
- package/dist/esm/connection/wait-for-http-ready.js +43 -0
- package/dist/esm/connection/wait-for-http-ready.js.map +1 -0
- package/dist/esm/dcr/dcr-authenticator.d.ts +73 -0
- package/dist/esm/dcr/dcr-authenticator.js +235 -0
- package/dist/esm/dcr/dcr-authenticator.js.map +1 -0
- package/dist/esm/dcr/dynamic-client-registrar.d.ts +28 -0
- package/dist/esm/dcr/dynamic-client-registrar.js +66 -0
- package/dist/esm/dcr/dynamic-client-registrar.js.map +1 -0
- package/dist/esm/dcr/index.d.ts +8 -0
- package/dist/esm/dcr/index.js +5 -0
- package/dist/esm/dcr/index.js.map +1 -0
- package/dist/esm/index.d.ts +21 -0
- package/dist/esm/index.js +22 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/monkey-patches.d.ts +6 -0
- package/dist/esm/monkey-patches.js +32 -0
- package/dist/esm/monkey-patches.js.map +1 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/response-wrappers.d.ts +41 -0
- package/dist/esm/response-wrappers.js +201 -0
- package/dist/esm/response-wrappers.js.map +1 -0
- package/dist/esm/search/index.d.ts +6 -0
- package/dist/esm/search/index.js +3 -0
- package/dist/esm/search/index.js.map +1 -0
- package/dist/esm/search/search.d.ts +22 -0
- package/dist/esm/search/search.js +236 -0
- package/dist/esm/search/search.js.map +1 -0
- package/dist/esm/search/types.d.ts +122 -0
- package/dist/esm/search/types.js +8 -0
- package/dist/esm/search/types.js.map +1 -0
- package/dist/esm/spawn/spawn-server.d.ts +83 -0
- package/dist/esm/spawn/spawn-server.js +145 -0
- package/dist/esm/spawn/spawn-server.js.map +1 -0
- package/dist/esm/spawn/spawn-servers.d.ts +151 -0
- package/dist/esm/spawn/spawn-servers.js +406 -0
- package/dist/esm/spawn/spawn-servers.js.map +1 -0
- package/dist/esm/types.d.ts +11 -0
- package/dist/esm/types.js +9 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/esm/utils/logger.d.ts +24 -0
- package/dist/esm/utils/logger.js +59 -0
- package/dist/esm/utils/logger.js.map +1 -0
- package/dist/esm/utils/path-utils.d.ts +45 -0
- package/dist/esm/utils/path-utils.js +89 -0
- package/dist/esm/utils/path-utils.js.map +1 -0
- package/dist/esm/utils/sanitizer.d.ts +30 -0
- package/dist/esm/utils/sanitizer.js +43 -0
- package/dist/esm/utils/sanitizer.js.map +1 -0
- package/package.json +92 -0
- package/schemas/servers.d.ts +90 -0
- package/schemas/servers.schema.json +104 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth Authorization Flow Handler
|
|
3
|
+
* Manages browser-based OAuth flows and token exchange with PKCE support
|
|
4
|
+
*/
|
|
5
|
+
import type { OAuthFlowOptions, TokenSet } from './types.js';
|
|
6
|
+
/**
|
|
7
|
+
* InteractiveOAuthFlow manages the complete OAuth authorization code flow
|
|
8
|
+
*/
|
|
9
|
+
export declare class InteractiveOAuthFlow {
|
|
10
|
+
/**
|
|
11
|
+
* Perform OAuth authorization code flow
|
|
12
|
+
*
|
|
13
|
+
* @param authorizationEndpoint - OAuth authorization endpoint URL
|
|
14
|
+
* @param tokenEndpoint - OAuth token endpoint URL
|
|
15
|
+
* @param clientId - OAuth client ID
|
|
16
|
+
* @param clientSecret - OAuth client secret
|
|
17
|
+
* @param options - Flow options (port is required - use get-port to find available port)
|
|
18
|
+
* @returns Token set with access and refresh tokens
|
|
19
|
+
*
|
|
20
|
+
* @throws Error if flow fails or times out
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* import getPort from 'get-port';
|
|
24
|
+
*
|
|
25
|
+
* const flow = new InteractiveOAuthFlow();
|
|
26
|
+
* const port = await getPort();
|
|
27
|
+
* const tokens = await flow.performAuthFlow(
|
|
28
|
+
* 'https://example.com/oauth/authorize',
|
|
29
|
+
* 'https://example.com/oauth/token',
|
|
30
|
+
* 'client-id',
|
|
31
|
+
* 'client-secret',
|
|
32
|
+
* { port, scopes: ['read', 'write'] }
|
|
33
|
+
* );
|
|
34
|
+
*/
|
|
35
|
+
performAuthFlow(authorizationEndpoint: string, tokenEndpoint: string, clientId: string, clientSecret: string, options: OAuthFlowOptions): Promise<TokenSet>;
|
|
36
|
+
/**
|
|
37
|
+
* Exchange authorization code for access and refresh tokens
|
|
38
|
+
* @param codeVerifier - Optional PKCE code verifier (RFC 7636)
|
|
39
|
+
*/
|
|
40
|
+
private exchangeCodeForTokens;
|
|
41
|
+
/**
|
|
42
|
+
* Refresh access token using refresh token
|
|
43
|
+
*
|
|
44
|
+
* @param tokenEndpoint - OAuth token endpoint URL
|
|
45
|
+
* @param refreshToken - Refresh token from previous token set
|
|
46
|
+
* @param clientId - OAuth client ID
|
|
47
|
+
* @param clientSecret - OAuth client secret
|
|
48
|
+
* @returns New token set with refreshed access token
|
|
49
|
+
*
|
|
50
|
+
* @throws Error if refresh fails
|
|
51
|
+
*/
|
|
52
|
+
refreshTokens(tokenEndpoint: string, refreshToken: string, clientId: string, clientSecret: string): Promise<TokenSet>;
|
|
53
|
+
/**
|
|
54
|
+
* Open browser to authorization URL
|
|
55
|
+
* Uses platform-specific command to open default browser
|
|
56
|
+
*/
|
|
57
|
+
private openBrowser;
|
|
58
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth Authorization Flow Handler
|
|
3
|
+
* Manages browser-based OAuth flows and token exchange with PKCE support
|
|
4
|
+
*/
|
|
5
|
+
import type { OAuthFlowOptions, TokenSet } from './types.js';
|
|
6
|
+
/**
|
|
7
|
+
* InteractiveOAuthFlow manages the complete OAuth authorization code flow
|
|
8
|
+
*/
|
|
9
|
+
export declare class InteractiveOAuthFlow {
|
|
10
|
+
/**
|
|
11
|
+
* Perform OAuth authorization code flow
|
|
12
|
+
*
|
|
13
|
+
* @param authorizationEndpoint - OAuth authorization endpoint URL
|
|
14
|
+
* @param tokenEndpoint - OAuth token endpoint URL
|
|
15
|
+
* @param clientId - OAuth client ID
|
|
16
|
+
* @param clientSecret - OAuth client secret
|
|
17
|
+
* @param options - Flow options (port is required - use get-port to find available port)
|
|
18
|
+
* @returns Token set with access and refresh tokens
|
|
19
|
+
*
|
|
20
|
+
* @throws Error if flow fails or times out
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* import getPort from 'get-port';
|
|
24
|
+
*
|
|
25
|
+
* const flow = new InteractiveOAuthFlow();
|
|
26
|
+
* const port = await getPort();
|
|
27
|
+
* const tokens = await flow.performAuthFlow(
|
|
28
|
+
* 'https://example.com/oauth/authorize',
|
|
29
|
+
* 'https://example.com/oauth/token',
|
|
30
|
+
* 'client-id',
|
|
31
|
+
* 'client-secret',
|
|
32
|
+
* { port, scopes: ['read', 'write'] }
|
|
33
|
+
* );
|
|
34
|
+
*/
|
|
35
|
+
performAuthFlow(authorizationEndpoint: string, tokenEndpoint: string, clientId: string, clientSecret: string, options: OAuthFlowOptions): Promise<TokenSet>;
|
|
36
|
+
/**
|
|
37
|
+
* Exchange authorization code for access and refresh tokens
|
|
38
|
+
* @param codeVerifier - Optional PKCE code verifier (RFC 7636)
|
|
39
|
+
*/
|
|
40
|
+
private exchangeCodeForTokens;
|
|
41
|
+
/**
|
|
42
|
+
* Refresh access token using refresh token
|
|
43
|
+
*
|
|
44
|
+
* @param tokenEndpoint - OAuth token endpoint URL
|
|
45
|
+
* @param refreshToken - Refresh token from previous token set
|
|
46
|
+
* @param clientId - OAuth client ID
|
|
47
|
+
* @param clientSecret - OAuth client secret
|
|
48
|
+
* @returns New token set with refreshed access token
|
|
49
|
+
*
|
|
50
|
+
* @throws Error if refresh fails
|
|
51
|
+
*/
|
|
52
|
+
refreshTokens(tokenEndpoint: string, refreshToken: string, clientId: string, clientSecret: string): Promise<TokenSet>;
|
|
53
|
+
/**
|
|
54
|
+
* Open browser to authorization URL
|
|
55
|
+
* Uses platform-specific command to open default browser
|
|
56
|
+
*/
|
|
57
|
+
private openBrowser;
|
|
58
|
+
}
|
|
@@ -0,0 +1,537 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth Authorization Flow Handler
|
|
3
|
+
* Manages browser-based OAuth flows and token exchange with PKCE support
|
|
4
|
+
*/ "use strict";
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
Object.defineProperty(exports, "InteractiveOAuthFlow", {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
get: function() {
|
|
11
|
+
return InteractiveOAuthFlow;
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
var _nodechild_process = /*#__PURE__*/ _interop_require_wildcard(require("node:child_process"));
|
|
15
|
+
var _loggerts = require("../utils/logger.js");
|
|
16
|
+
var _oauthcallbacklistenerts = require("./oauth-callback-listener.js");
|
|
17
|
+
var _pkcets = require("./pkce.js");
|
|
18
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
19
|
+
try {
|
|
20
|
+
var info = gen[key](arg);
|
|
21
|
+
var value = info.value;
|
|
22
|
+
} catch (error) {
|
|
23
|
+
reject(error);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (info.done) {
|
|
27
|
+
resolve(value);
|
|
28
|
+
} else {
|
|
29
|
+
Promise.resolve(value).then(_next, _throw);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function _async_to_generator(fn) {
|
|
33
|
+
return function() {
|
|
34
|
+
var self = this, args = arguments;
|
|
35
|
+
return new Promise(function(resolve, reject) {
|
|
36
|
+
var gen = fn.apply(self, args);
|
|
37
|
+
function _next(value) {
|
|
38
|
+
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
|
|
39
|
+
}
|
|
40
|
+
function _throw(err) {
|
|
41
|
+
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
|
|
42
|
+
}
|
|
43
|
+
_next(undefined);
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function _class_call_check(instance, Constructor) {
|
|
48
|
+
if (!(instance instanceof Constructor)) {
|
|
49
|
+
throw new TypeError("Cannot call a class as a function");
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function _instanceof(left, right) {
|
|
53
|
+
if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
|
|
54
|
+
return !!right[Symbol.hasInstance](left);
|
|
55
|
+
} else {
|
|
56
|
+
return left instanceof right;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function _getRequireWildcardCache(nodeInterop) {
|
|
60
|
+
if (typeof WeakMap !== "function") return null;
|
|
61
|
+
var cacheBabelInterop = new WeakMap();
|
|
62
|
+
var cacheNodeInterop = new WeakMap();
|
|
63
|
+
return (_getRequireWildcardCache = function(nodeInterop) {
|
|
64
|
+
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
|
|
65
|
+
})(nodeInterop);
|
|
66
|
+
}
|
|
67
|
+
function _interop_require_wildcard(obj, nodeInterop) {
|
|
68
|
+
if (!nodeInterop && obj && obj.__esModule) {
|
|
69
|
+
return obj;
|
|
70
|
+
}
|
|
71
|
+
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
|
|
72
|
+
return {
|
|
73
|
+
default: obj
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
var cache = _getRequireWildcardCache(nodeInterop);
|
|
77
|
+
if (cache && cache.has(obj)) {
|
|
78
|
+
return cache.get(obj);
|
|
79
|
+
}
|
|
80
|
+
var newObj = {
|
|
81
|
+
__proto__: null
|
|
82
|
+
};
|
|
83
|
+
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
|
|
84
|
+
for(var key in obj){
|
|
85
|
+
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
86
|
+
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
|
|
87
|
+
if (desc && (desc.get || desc.set)) {
|
|
88
|
+
Object.defineProperty(newObj, key, desc);
|
|
89
|
+
} else {
|
|
90
|
+
newObj[key] = obj[key];
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
newObj.default = obj;
|
|
95
|
+
if (cache) {
|
|
96
|
+
cache.set(obj, newObj);
|
|
97
|
+
}
|
|
98
|
+
return newObj;
|
|
99
|
+
}
|
|
100
|
+
function _ts_generator(thisArg, body) {
|
|
101
|
+
var f, y, t, _ = {
|
|
102
|
+
label: 0,
|
|
103
|
+
sent: function() {
|
|
104
|
+
if (t[0] & 1) throw t[1];
|
|
105
|
+
return t[1];
|
|
106
|
+
},
|
|
107
|
+
trys: [],
|
|
108
|
+
ops: []
|
|
109
|
+
}, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
|
|
110
|
+
return d(g, "next", {
|
|
111
|
+
value: verb(0)
|
|
112
|
+
}), d(g, "throw", {
|
|
113
|
+
value: verb(1)
|
|
114
|
+
}), d(g, "return", {
|
|
115
|
+
value: verb(2)
|
|
116
|
+
}), typeof Symbol === "function" && d(g, Symbol.iterator, {
|
|
117
|
+
value: function() {
|
|
118
|
+
return this;
|
|
119
|
+
}
|
|
120
|
+
}), g;
|
|
121
|
+
function verb(n) {
|
|
122
|
+
return function(v) {
|
|
123
|
+
return step([
|
|
124
|
+
n,
|
|
125
|
+
v
|
|
126
|
+
]);
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
function step(op) {
|
|
130
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
131
|
+
while(g && (g = 0, op[0] && (_ = 0)), _)try {
|
|
132
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
133
|
+
if (y = 0, t) op = [
|
|
134
|
+
op[0] & 2,
|
|
135
|
+
t.value
|
|
136
|
+
];
|
|
137
|
+
switch(op[0]){
|
|
138
|
+
case 0:
|
|
139
|
+
case 1:
|
|
140
|
+
t = op;
|
|
141
|
+
break;
|
|
142
|
+
case 4:
|
|
143
|
+
_.label++;
|
|
144
|
+
return {
|
|
145
|
+
value: op[1],
|
|
146
|
+
done: false
|
|
147
|
+
};
|
|
148
|
+
case 5:
|
|
149
|
+
_.label++;
|
|
150
|
+
y = op[1];
|
|
151
|
+
op = [
|
|
152
|
+
0
|
|
153
|
+
];
|
|
154
|
+
continue;
|
|
155
|
+
case 7:
|
|
156
|
+
op = _.ops.pop();
|
|
157
|
+
_.trys.pop();
|
|
158
|
+
continue;
|
|
159
|
+
default:
|
|
160
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
|
|
161
|
+
_ = 0;
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
|
|
165
|
+
_.label = op[1];
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
if (op[0] === 6 && _.label < t[1]) {
|
|
169
|
+
_.label = t[1];
|
|
170
|
+
t = op;
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
if (t && _.label < t[2]) {
|
|
174
|
+
_.label = t[2];
|
|
175
|
+
_.ops.push(op);
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
if (t[2]) _.ops.pop();
|
|
179
|
+
_.trys.pop();
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
op = body.call(thisArg, _);
|
|
183
|
+
} catch (e) {
|
|
184
|
+
op = [
|
|
185
|
+
6,
|
|
186
|
+
e
|
|
187
|
+
];
|
|
188
|
+
y = 0;
|
|
189
|
+
} finally{
|
|
190
|
+
f = t = 0;
|
|
191
|
+
}
|
|
192
|
+
if (op[0] & 5) throw op[1];
|
|
193
|
+
return {
|
|
194
|
+
value: op[0] ? op[1] : void 0,
|
|
195
|
+
done: true
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
var InteractiveOAuthFlow = /*#__PURE__*/ function() {
|
|
200
|
+
"use strict";
|
|
201
|
+
function InteractiveOAuthFlow() {
|
|
202
|
+
_class_call_check(this, InteractiveOAuthFlow);
|
|
203
|
+
}
|
|
204
|
+
var _proto = InteractiveOAuthFlow.prototype;
|
|
205
|
+
/**
|
|
206
|
+
* Perform OAuth authorization code flow
|
|
207
|
+
*
|
|
208
|
+
* @param authorizationEndpoint - OAuth authorization endpoint URL
|
|
209
|
+
* @param tokenEndpoint - OAuth token endpoint URL
|
|
210
|
+
* @param clientId - OAuth client ID
|
|
211
|
+
* @param clientSecret - OAuth client secret
|
|
212
|
+
* @param options - Flow options (port is required - use get-port to find available port)
|
|
213
|
+
* @returns Token set with access and refresh tokens
|
|
214
|
+
*
|
|
215
|
+
* @throws Error if flow fails or times out
|
|
216
|
+
*
|
|
217
|
+
* @example
|
|
218
|
+
* import getPort from 'get-port';
|
|
219
|
+
*
|
|
220
|
+
* const flow = new InteractiveOAuthFlow();
|
|
221
|
+
* const port = await getPort();
|
|
222
|
+
* const tokens = await flow.performAuthFlow(
|
|
223
|
+
* 'https://example.com/oauth/authorize',
|
|
224
|
+
* 'https://example.com/oauth/token',
|
|
225
|
+
* 'client-id',
|
|
226
|
+
* 'client-secret',
|
|
227
|
+
* { port, scopes: ['read', 'write'] }
|
|
228
|
+
* );
|
|
229
|
+
*/ _proto.performAuthFlow = function performAuthFlow(authorizationEndpoint, tokenEndpoint, clientId, clientSecret, options) {
|
|
230
|
+
return _async_to_generator(function() {
|
|
231
|
+
var _options_logger, logger, callbackListener, pkce, redirectUri, authUrl, timeout, result, tokens, error;
|
|
232
|
+
return _ts_generator(this, function(_state) {
|
|
233
|
+
switch(_state.label){
|
|
234
|
+
case 0:
|
|
235
|
+
logger = (_options_logger = options.logger) !== null && _options_logger !== void 0 ? _options_logger : _loggerts.logger;
|
|
236
|
+
callbackListener = new _oauthcallbacklistenerts.OAuthCallbackListener({
|
|
237
|
+
port: options.port,
|
|
238
|
+
logger: logger
|
|
239
|
+
});
|
|
240
|
+
if (!options.pkce) return [
|
|
241
|
+
3,
|
|
242
|
+
2
|
|
243
|
+
];
|
|
244
|
+
logger.debug('🔐 Generating PKCE parameters...');
|
|
245
|
+
return [
|
|
246
|
+
4,
|
|
247
|
+
(0, _pkcets.generatePkce)()
|
|
248
|
+
];
|
|
249
|
+
case 1:
|
|
250
|
+
pkce = _state.sent();
|
|
251
|
+
_state.label = 2;
|
|
252
|
+
case 2:
|
|
253
|
+
_state.trys.push([
|
|
254
|
+
2,
|
|
255
|
+
9,
|
|
256
|
+
10,
|
|
257
|
+
12
|
|
258
|
+
]);
|
|
259
|
+
// Start callback server
|
|
260
|
+
return [
|
|
261
|
+
4,
|
|
262
|
+
callbackListener.start()
|
|
263
|
+
];
|
|
264
|
+
case 3:
|
|
265
|
+
_state.sent();
|
|
266
|
+
// Build redirect URI
|
|
267
|
+
redirectUri = options.redirectUri || "http://localhost:".concat(options.port, "/callback");
|
|
268
|
+
// Build authorization URL
|
|
269
|
+
authUrl = new URL(authorizationEndpoint);
|
|
270
|
+
authUrl.searchParams.set('client_id', clientId);
|
|
271
|
+
authUrl.searchParams.set('redirect_uri', redirectUri);
|
|
272
|
+
authUrl.searchParams.set('response_type', 'code');
|
|
273
|
+
if (options.scopes && options.scopes.length > 0) {
|
|
274
|
+
authUrl.searchParams.set('scope', options.scopes.join(' '));
|
|
275
|
+
}
|
|
276
|
+
// Add resource parameter if specified (RFC 8707)
|
|
277
|
+
if (options.resource) {
|
|
278
|
+
authUrl.searchParams.set('resource', options.resource);
|
|
279
|
+
}
|
|
280
|
+
// Add PKCE parameters if generated (RFC 7636)
|
|
281
|
+
if (pkce) {
|
|
282
|
+
authUrl.searchParams.set('code_challenge', pkce.codeChallenge);
|
|
283
|
+
authUrl.searchParams.set('code_challenge_method', pkce.codeChallengeMethod);
|
|
284
|
+
}
|
|
285
|
+
if (!options.headless) return [
|
|
286
|
+
3,
|
|
287
|
+
4
|
|
288
|
+
];
|
|
289
|
+
logger.info('🔗 Please visit this URL to authorize:');
|
|
290
|
+
logger.info(authUrl.toString());
|
|
291
|
+
logger.info('Waiting for callback...');
|
|
292
|
+
return [
|
|
293
|
+
3,
|
|
294
|
+
6
|
|
295
|
+
];
|
|
296
|
+
case 4:
|
|
297
|
+
logger.debug('🌐 Opening browser for OAuth authorization...');
|
|
298
|
+
// Try to open browser (requires 'open' package or native command)
|
|
299
|
+
return [
|
|
300
|
+
4,
|
|
301
|
+
this.openBrowser(authUrl.toString())
|
|
302
|
+
];
|
|
303
|
+
case 5:
|
|
304
|
+
_state.sent();
|
|
305
|
+
_state.label = 6;
|
|
306
|
+
case 6:
|
|
307
|
+
// Wait for callback with timeout
|
|
308
|
+
timeout = options.timeout || (options.headless ? 60000 : 300000);
|
|
309
|
+
return [
|
|
310
|
+
4,
|
|
311
|
+
callbackListener.waitForCallback(timeout)
|
|
312
|
+
];
|
|
313
|
+
case 7:
|
|
314
|
+
result = _state.sent();
|
|
315
|
+
return [
|
|
316
|
+
4,
|
|
317
|
+
this.exchangeCodeForTokens(tokenEndpoint, result.code, clientId, clientSecret, redirectUri, pkce === null || pkce === void 0 ? void 0 : pkce.codeVerifier)
|
|
318
|
+
];
|
|
319
|
+
case 8:
|
|
320
|
+
tokens = _state.sent();
|
|
321
|
+
return [
|
|
322
|
+
2,
|
|
323
|
+
tokens
|
|
324
|
+
];
|
|
325
|
+
case 9:
|
|
326
|
+
error = _state.sent();
|
|
327
|
+
logger.error('❌ OAuth flow failed:', _instanceof(error, Error) ? error.message : String(error));
|
|
328
|
+
throw error;
|
|
329
|
+
case 10:
|
|
330
|
+
// Always close callback server
|
|
331
|
+
return [
|
|
332
|
+
4,
|
|
333
|
+
callbackListener.stop()
|
|
334
|
+
];
|
|
335
|
+
case 11:
|
|
336
|
+
_state.sent();
|
|
337
|
+
return [
|
|
338
|
+
7
|
|
339
|
+
];
|
|
340
|
+
case 12:
|
|
341
|
+
return [
|
|
342
|
+
2
|
|
343
|
+
];
|
|
344
|
+
}
|
|
345
|
+
});
|
|
346
|
+
}).call(this);
|
|
347
|
+
};
|
|
348
|
+
/**
|
|
349
|
+
* Exchange authorization code for access and refresh tokens
|
|
350
|
+
* @param codeVerifier - Optional PKCE code verifier (RFC 7636)
|
|
351
|
+
*/ _proto.exchangeCodeForTokens = function exchangeCodeForTokens(tokenEndpoint, code, clientId, clientSecret, redirectUri, codeVerifier) {
|
|
352
|
+
return _async_to_generator(function() {
|
|
353
|
+
var params, response, errorText, data, tokenSet;
|
|
354
|
+
return _ts_generator(this, function(_state) {
|
|
355
|
+
switch(_state.label){
|
|
356
|
+
case 0:
|
|
357
|
+
params = new URLSearchParams({
|
|
358
|
+
grant_type: 'authorization_code',
|
|
359
|
+
code: code,
|
|
360
|
+
redirect_uri: redirectUri,
|
|
361
|
+
client_id: clientId,
|
|
362
|
+
client_secret: clientSecret
|
|
363
|
+
});
|
|
364
|
+
// Add PKCE code verifier if provided (RFC 7636)
|
|
365
|
+
if (codeVerifier) {
|
|
366
|
+
params.set('code_verifier', codeVerifier);
|
|
367
|
+
}
|
|
368
|
+
return [
|
|
369
|
+
4,
|
|
370
|
+
fetch(tokenEndpoint, {
|
|
371
|
+
method: 'POST',
|
|
372
|
+
headers: {
|
|
373
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
374
|
+
Accept: 'application/json',
|
|
375
|
+
Connection: 'close'
|
|
376
|
+
},
|
|
377
|
+
body: params
|
|
378
|
+
})
|
|
379
|
+
];
|
|
380
|
+
case 1:
|
|
381
|
+
response = _state.sent();
|
|
382
|
+
if (!!response.ok) return [
|
|
383
|
+
3,
|
|
384
|
+
3
|
|
385
|
+
];
|
|
386
|
+
return [
|
|
387
|
+
4,
|
|
388
|
+
response.text()
|
|
389
|
+
];
|
|
390
|
+
case 2:
|
|
391
|
+
errorText = _state.sent();
|
|
392
|
+
throw new Error("Token exchange failed (".concat(response.status, "): ").concat(errorText));
|
|
393
|
+
case 3:
|
|
394
|
+
return [
|
|
395
|
+
4,
|
|
396
|
+
response.json()
|
|
397
|
+
];
|
|
398
|
+
case 4:
|
|
399
|
+
data = _state.sent();
|
|
400
|
+
if (!data.access_token) {
|
|
401
|
+
throw new Error('Token response missing access_token');
|
|
402
|
+
}
|
|
403
|
+
tokenSet = {
|
|
404
|
+
accessToken: data.access_token,
|
|
405
|
+
refreshToken: data.refresh_token || '',
|
|
406
|
+
expiresAt: Date.now() + data.expires_in * 1000,
|
|
407
|
+
clientId: clientId,
|
|
408
|
+
clientSecret: clientSecret
|
|
409
|
+
};
|
|
410
|
+
if (data.scope) {
|
|
411
|
+
tokenSet.scopes = data.scope.split(' ');
|
|
412
|
+
}
|
|
413
|
+
return [
|
|
414
|
+
2,
|
|
415
|
+
tokenSet
|
|
416
|
+
];
|
|
417
|
+
}
|
|
418
|
+
});
|
|
419
|
+
})();
|
|
420
|
+
};
|
|
421
|
+
/**
|
|
422
|
+
* Refresh access token using refresh token
|
|
423
|
+
*
|
|
424
|
+
* @param tokenEndpoint - OAuth token endpoint URL
|
|
425
|
+
* @param refreshToken - Refresh token from previous token set
|
|
426
|
+
* @param clientId - OAuth client ID
|
|
427
|
+
* @param clientSecret - OAuth client secret
|
|
428
|
+
* @returns New token set with refreshed access token
|
|
429
|
+
*
|
|
430
|
+
* @throws Error if refresh fails
|
|
431
|
+
*/ _proto.refreshTokens = function refreshTokens(tokenEndpoint, refreshToken, clientId, clientSecret) {
|
|
432
|
+
return _async_to_generator(function() {
|
|
433
|
+
var response, errorText, data, tokenSet;
|
|
434
|
+
return _ts_generator(this, function(_state) {
|
|
435
|
+
switch(_state.label){
|
|
436
|
+
case 0:
|
|
437
|
+
return [
|
|
438
|
+
4,
|
|
439
|
+
fetch(tokenEndpoint, {
|
|
440
|
+
method: 'POST',
|
|
441
|
+
headers: {
|
|
442
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
443
|
+
Accept: 'application/json',
|
|
444
|
+
Connection: 'close'
|
|
445
|
+
},
|
|
446
|
+
body: new URLSearchParams({
|
|
447
|
+
grant_type: 'refresh_token',
|
|
448
|
+
refresh_token: refreshToken,
|
|
449
|
+
client_id: clientId,
|
|
450
|
+
client_secret: clientSecret
|
|
451
|
+
})
|
|
452
|
+
})
|
|
453
|
+
];
|
|
454
|
+
case 1:
|
|
455
|
+
response = _state.sent();
|
|
456
|
+
if (!!response.ok) return [
|
|
457
|
+
3,
|
|
458
|
+
3
|
|
459
|
+
];
|
|
460
|
+
return [
|
|
461
|
+
4,
|
|
462
|
+
response.text()
|
|
463
|
+
];
|
|
464
|
+
case 2:
|
|
465
|
+
errorText = _state.sent();
|
|
466
|
+
throw new Error("Token refresh failed (".concat(response.status, "): ").concat(errorText));
|
|
467
|
+
case 3:
|
|
468
|
+
return [
|
|
469
|
+
4,
|
|
470
|
+
response.json()
|
|
471
|
+
];
|
|
472
|
+
case 4:
|
|
473
|
+
data = _state.sent();
|
|
474
|
+
if (!data.access_token) {
|
|
475
|
+
throw new Error('Token refresh response missing access_token');
|
|
476
|
+
}
|
|
477
|
+
tokenSet = {
|
|
478
|
+
accessToken: data.access_token,
|
|
479
|
+
refreshToken: data.refresh_token || refreshToken,
|
|
480
|
+
expiresAt: Date.now() + data.expires_in * 1000,
|
|
481
|
+
clientId: clientId,
|
|
482
|
+
clientSecret: clientSecret
|
|
483
|
+
};
|
|
484
|
+
if (data.scope) {
|
|
485
|
+
tokenSet.scopes = data.scope.split(' ');
|
|
486
|
+
}
|
|
487
|
+
return [
|
|
488
|
+
2,
|
|
489
|
+
tokenSet
|
|
490
|
+
];
|
|
491
|
+
}
|
|
492
|
+
});
|
|
493
|
+
})();
|
|
494
|
+
};
|
|
495
|
+
/**
|
|
496
|
+
* Open browser to authorization URL
|
|
497
|
+
* Uses platform-specific command to open default browser
|
|
498
|
+
*/ _proto.openBrowser = function openBrowser(url) {
|
|
499
|
+
return _async_to_generator(function() {
|
|
500
|
+
var platform, command, args, child;
|
|
501
|
+
return _ts_generator(this, function(_state) {
|
|
502
|
+
// Determine platform-specific command
|
|
503
|
+
platform = process.platform;
|
|
504
|
+
if (platform === 'darwin') {
|
|
505
|
+
command = 'open';
|
|
506
|
+
args = [
|
|
507
|
+
url
|
|
508
|
+
];
|
|
509
|
+
} else if (platform === 'win32') {
|
|
510
|
+
command = 'cmd';
|
|
511
|
+
args = [
|
|
512
|
+
'/c',
|
|
513
|
+
'start',
|
|
514
|
+
url
|
|
515
|
+
];
|
|
516
|
+
} else {
|
|
517
|
+
// Linux and others
|
|
518
|
+
command = 'xdg-open';
|
|
519
|
+
args = [
|
|
520
|
+
url
|
|
521
|
+
];
|
|
522
|
+
}
|
|
523
|
+
// Spawn browser process
|
|
524
|
+
child = _nodechild_process.spawn(command, args, {
|
|
525
|
+
detached: true,
|
|
526
|
+
stdio: 'ignore'
|
|
527
|
+
});
|
|
528
|
+
child.unref();
|
|
529
|
+
return [
|
|
530
|
+
2
|
|
531
|
+
];
|
|
532
|
+
});
|
|
533
|
+
})();
|
|
534
|
+
};
|
|
535
|
+
return InteractiveOAuthFlow;
|
|
536
|
+
}();
|
|
537
|
+
/* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/libs/client/src/auth/interactive-oauth-flow.ts"],"sourcesContent":["/**\n * OAuth Authorization Flow Handler\n * Manages browser-based OAuth flows and token exchange with PKCE support\n */\n\nimport * as child_process from 'node:child_process';\nimport { logger as defaultLogger } from '../utils/logger.ts';\nimport { OAuthCallbackListener } from './oauth-callback-listener.ts';\nimport { generatePkce } from './pkce.ts';\nimport type { OAuthFlowOptions, PkceParams, TokenSet } from './types.ts';\n\n/**\n * OAuth token response from token endpoint\n */\ninterface TokenResponse {\n access_token: string;\n refresh_token?: string;\n expires_in: number;\n scope?: string;\n token_type?: string;\n}\n\n/**\n * InteractiveOAuthFlow manages the complete OAuth authorization code flow\n */\nexport class InteractiveOAuthFlow {\n /**\n * Perform OAuth authorization code flow\n *\n * @param authorizationEndpoint - OAuth authorization endpoint URL\n * @param tokenEndpoint - OAuth token endpoint URL\n * @param clientId - OAuth client ID\n * @param clientSecret - OAuth client secret\n * @param options - Flow options (port is required - use get-port to find available port)\n * @returns Token set with access and refresh tokens\n *\n * @throws Error if flow fails or times out\n *\n * @example\n * import getPort from 'get-port';\n *\n * const flow = new InteractiveOAuthFlow();\n * const port = await getPort();\n * const tokens = await flow.performAuthFlow(\n * 'https://example.com/oauth/authorize',\n * 'https://example.com/oauth/token',\n * 'client-id',\n * 'client-secret',\n * { port, scopes: ['read', 'write'] }\n * );\n */\n async performAuthFlow(authorizationEndpoint: string, tokenEndpoint: string, clientId: string, clientSecret: string, options: OAuthFlowOptions): Promise<TokenSet> {\n const logger = options.logger ?? defaultLogger;\n const callbackListener = new OAuthCallbackListener({ port: options.port, logger });\n\n // Generate PKCE parameters if requested (RFC 7636)\n let pkce: PkceParams | undefined;\n if (options.pkce) {\n logger.debug('🔐 Generating PKCE parameters...');\n pkce = await generatePkce();\n }\n\n try {\n // Start callback server\n await callbackListener.start();\n\n // Build redirect URI\n const redirectUri = options.redirectUri || `http://localhost:${options.port}/callback`;\n\n // Build authorization URL\n const authUrl = new URL(authorizationEndpoint);\n authUrl.searchParams.set('client_id', clientId);\n authUrl.searchParams.set('redirect_uri', redirectUri);\n authUrl.searchParams.set('response_type', 'code');\n\n if (options.scopes && options.scopes.length > 0) {\n authUrl.searchParams.set('scope', options.scopes.join(' '));\n }\n\n // Add resource parameter if specified (RFC 8707)\n if (options.resource) {\n authUrl.searchParams.set('resource', options.resource);\n }\n\n // Add PKCE parameters if generated (RFC 7636)\n if (pkce) {\n authUrl.searchParams.set('code_challenge', pkce.codeChallenge);\n authUrl.searchParams.set('code_challenge_method', pkce.codeChallengeMethod);\n }\n\n // Open browser or print URL for headless mode\n if (options.headless) {\n logger.info('🔗 Please visit this URL to authorize:');\n logger.info(authUrl.toString());\n logger.info('Waiting for callback...');\n } else {\n logger.debug('🌐 Opening browser for OAuth authorization...');\n // Try to open browser (requires 'open' package or native command)\n await this.openBrowser(authUrl.toString());\n }\n\n // Wait for callback with timeout\n const timeout = options.timeout || (options.headless ? 60000 : 300000);\n const result = await callbackListener.waitForCallback(timeout);\n\n // Exchange authorization code for tokens (with PKCE verifier if used)\n const tokens = await this.exchangeCodeForTokens(tokenEndpoint, result.code, clientId, clientSecret, redirectUri, pkce?.codeVerifier);\n\n return tokens;\n } catch (error) {\n logger.error('❌ OAuth flow failed:', error instanceof Error ? error.message : String(error));\n throw error;\n } finally {\n // Always close callback server\n await callbackListener.stop();\n }\n }\n\n /**\n * Exchange authorization code for access and refresh tokens\n * @param codeVerifier - Optional PKCE code verifier (RFC 7636)\n */\n private async exchangeCodeForTokens(tokenEndpoint: string, code: string, clientId: string, clientSecret: string, redirectUri: string, codeVerifier?: string): Promise<TokenSet> {\n const params = new URLSearchParams({\n grant_type: 'authorization_code',\n code,\n redirect_uri: redirectUri,\n client_id: clientId,\n client_secret: clientSecret,\n });\n\n // Add PKCE code verifier if provided (RFC 7636)\n if (codeVerifier) {\n params.set('code_verifier', codeVerifier);\n }\n\n const response = await fetch(tokenEndpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n Accept: 'application/json',\n Connection: 'close',\n },\n body: params,\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Token exchange failed (${response.status}): ${errorText}`);\n }\n\n const data = (await response.json()) as TokenResponse;\n\n if (!data.access_token) {\n throw new Error('Token response missing access_token');\n }\n\n const tokenSet: TokenSet = {\n accessToken: data.access_token,\n refreshToken: data.refresh_token || '',\n expiresAt: Date.now() + data.expires_in * 1000,\n clientId,\n clientSecret,\n };\n\n if (data.scope) {\n tokenSet.scopes = data.scope.split(' ');\n }\n\n return tokenSet;\n }\n\n /**\n * Refresh access token using refresh token\n *\n * @param tokenEndpoint - OAuth token endpoint URL\n * @param refreshToken - Refresh token from previous token set\n * @param clientId - OAuth client ID\n * @param clientSecret - OAuth client secret\n * @returns New token set with refreshed access token\n *\n * @throws Error if refresh fails\n */\n async refreshTokens(tokenEndpoint: string, refreshToken: string, clientId: string, clientSecret: string): Promise<TokenSet> {\n const response = await fetch(tokenEndpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n Accept: 'application/json',\n Connection: 'close',\n },\n body: new URLSearchParams({\n grant_type: 'refresh_token',\n refresh_token: refreshToken,\n client_id: clientId,\n client_secret: clientSecret,\n }),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Token refresh failed (${response.status}): ${errorText}`);\n }\n\n const data = (await response.json()) as TokenResponse;\n\n if (!data.access_token) {\n throw new Error('Token refresh response missing access_token');\n }\n\n const tokenSet: TokenSet = {\n accessToken: data.access_token,\n refreshToken: data.refresh_token || refreshToken, // Reuse old refresh token if not provided\n expiresAt: Date.now() + data.expires_in * 1000,\n clientId,\n clientSecret,\n };\n\n if (data.scope) {\n tokenSet.scopes = data.scope.split(' ');\n }\n\n return tokenSet;\n }\n\n /**\n * Open browser to authorization URL\n * Uses platform-specific command to open default browser\n */\n private async openBrowser(url: string): Promise<void> {\n // Determine platform-specific command\n const platform = process.platform;\n let command: string;\n let args: string[];\n\n if (platform === 'darwin') {\n command = 'open';\n args = [url];\n } else if (platform === 'win32') {\n command = 'cmd';\n args = ['/c', 'start', url];\n } else {\n // Linux and others\n command = 'xdg-open';\n args = [url];\n }\n\n // Spawn browser process\n const child = child_process.spawn(command, args, {\n detached: true,\n stdio: 'ignore',\n });\n\n child.unref();\n }\n}\n"],"names":["InteractiveOAuthFlow","performAuthFlow","authorizationEndpoint","tokenEndpoint","clientId","clientSecret","options","logger","callbackListener","pkce","redirectUri","authUrl","timeout","result","tokens","error","defaultLogger","OAuthCallbackListener","port","debug","generatePkce","start","URL","searchParams","set","scopes","length","join","resource","codeChallenge","codeChallengeMethod","headless","info","toString","openBrowser","waitForCallback","exchangeCodeForTokens","code","codeVerifier","Error","message","String","stop","params","response","errorText","data","tokenSet","URLSearchParams","grant_type","redirect_uri","client_id","client_secret","fetch","method","headers","Accept","Connection","body","ok","text","status","json","access_token","accessToken","refreshToken","refresh_token","expiresAt","Date","now","expires_in","scope","split","refreshTokens","url","platform","command","args","child","process","child_process","spawn","detached","stdio","unref"],"mappings":"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"}
|