@n24q02m/mcp-core 1.0.0-beta.3 → 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/build/auth/credential-form.d.ts +45 -0
- package/build/auth/credential-form.d.ts.map +1 -0
- package/build/auth/credential-form.js +668 -0
- package/build/auth/credential-form.js.map +1 -0
- package/build/auth/delegated-oauth-app.d.ts +53 -0
- package/build/auth/delegated-oauth-app.d.ts.map +1 -0
- package/build/auth/delegated-oauth-app.js +531 -0
- package/build/auth/delegated-oauth-app.js.map +1 -0
- package/build/auth/index.d.ts +10 -0
- package/build/auth/index.d.ts.map +1 -0
- package/build/auth/index.js +10 -0
- package/build/auth/index.js.map +1 -0
- package/build/auth/local-oauth-app.d.ts +83 -0
- package/build/auth/local-oauth-app.d.ts.map +1 -0
- package/build/auth/local-oauth-app.js +355 -0
- package/build/auth/local-oauth-app.js.map +1 -0
- package/build/auth/router.d.ts +18 -0
- package/build/auth/router.d.ts.map +1 -0
- package/build/auth/router.js +62 -0
- package/build/auth/router.js.map +1 -0
- package/build/auth/well-known.d.ts +4 -0
- package/build/auth/well-known.d.ts.map +1 -0
- package/build/auth/well-known.js +20 -0
- package/build/auth/well-known.js.map +1 -0
- package/build/index.d.ts +3 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +5 -1
- package/build/index.js.map +1 -1
- package/build/relay/browser.d.ts.map +1 -1
- package/build/relay/browser.js +10 -0
- package/build/relay/browser.js.map +1 -1
- package/build/storage/config-file.d.ts +10 -0
- package/build/storage/config-file.d.ts.map +1 -1
- package/build/storage/config-file.js +20 -7
- package/build/storage/config-file.js.map +1 -1
- package/build/transport/local-server.d.ts +67 -0
- package/build/transport/local-server.d.ts.map +1 -0
- package/build/transport/local-server.js +131 -0
- package/build/transport/local-server.js.map +1 -0
- package/package.json +5 -1
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local OAuth 2.1 Authorization Server as an HTTP request handler.
|
|
3
|
+
*
|
|
4
|
+
* Provides a self-hosted Authorization Server for single-user MCP servers.
|
|
5
|
+
* Implements the OAuth 2.1 PKCE flow with credential collection via a
|
|
6
|
+
* browser-rendered form.
|
|
7
|
+
*
|
|
8
|
+
* Routes:
|
|
9
|
+
* - GET /authorize -- Render credential form
|
|
10
|
+
* - POST /authorize -- Save credentials, return auth code
|
|
11
|
+
* - POST /otp -- Submit multi-step credential (OTP / 2FA password)
|
|
12
|
+
* - POST /token -- Exchange auth code + PKCE verifier for JWT
|
|
13
|
+
* - GET /setup-status -- Poll background setup completion
|
|
14
|
+
* - GET /.well-known/oauth-authorization-server -- RFC 8414 metadata
|
|
15
|
+
* - GET /.well-known/oauth-protected-resource -- RFC 9728 metadata
|
|
16
|
+
*
|
|
17
|
+
* The /mcp endpoint is NOT included -- it is mounted by the transport layer.
|
|
18
|
+
*
|
|
19
|
+
* This is a TypeScript port of core-py's ``local_oauth_app.py``. Behavior,
|
|
20
|
+
* protocol, and TTL constants are kept identical for cross-language parity.
|
|
21
|
+
*/
|
|
22
|
+
import { JWTIssuer } from '../oauth/jwt-issuer.js';
|
|
23
|
+
import { type RelayConfigSchema } from './credential-form.js';
|
|
24
|
+
import { type RequestHandler } from './router.js';
|
|
25
|
+
/** Next-step hint returned by credential / step callbacks. */
|
|
26
|
+
export type NextStep = Record<string, unknown>;
|
|
27
|
+
/**
|
|
28
|
+
* Callback invoked when the user submits credentials via POST /authorize.
|
|
29
|
+
*
|
|
30
|
+
* Return ``null`` to finish the flow or a ``next_step`` dict to trigger a
|
|
31
|
+
* follow-up (OAuth device code, OTP, 2FA password, etc). May be sync or async.
|
|
32
|
+
*/
|
|
33
|
+
export type CredentialsCallback = (creds: Record<string, string>) => NextStep | null | Promise<NextStep | null>;
|
|
34
|
+
/**
|
|
35
|
+
* Callback invoked when the user submits step input via POST /otp.
|
|
36
|
+
*
|
|
37
|
+
* Return ``null`` to complete the flow, a ``{type: "otp_required" |
|
|
38
|
+
* "password_required", ...}`` dict to chain to another step, or
|
|
39
|
+
* ``{type: "error", text: "..."}`` to reject the current input and allow
|
|
40
|
+
* retry. Callbacks comparing secrets MUST use a timing-safe comparison.
|
|
41
|
+
* May be sync or async.
|
|
42
|
+
*/
|
|
43
|
+
export type StepCallback = (data: Record<string, string>) => NextStep | null | Promise<NextStep | null>;
|
|
44
|
+
export interface LocalOAuthAppOptions {
|
|
45
|
+
/** Identifier for the MCP server (used for JWT iss / aud). */
|
|
46
|
+
serverName: string;
|
|
47
|
+
/** RelayConfigSchema describing the credential form. */
|
|
48
|
+
relaySchema: RelayConfigSchema;
|
|
49
|
+
/** Optional callback invoked with credentials after POST /authorize. */
|
|
50
|
+
onCredentialsSaved?: CredentialsCallback;
|
|
51
|
+
/** Optional callback invoked with step data after POST /otp. */
|
|
52
|
+
onStepSubmitted?: StepCallback;
|
|
53
|
+
/** Optional pre-created JWT issuer. If omitted, one is created automatically. */
|
|
54
|
+
jwtIssuer?: JWTIssuer;
|
|
55
|
+
/**
|
|
56
|
+
* Optional renderer used in place of the default credential form on GET
|
|
57
|
+
* /authorize. Receives the relay schema and an options object with
|
|
58
|
+
* ``submitUrl`` (which embeds the PKCE nonce) and returns the full HTML
|
|
59
|
+
* page. Consumers (email, telegram) use this to inject rich UX while
|
|
60
|
+
* reusing core OAuth plumbing.
|
|
61
|
+
*/
|
|
62
|
+
customCredentialFormHtml?: (schema: RelayConfigSchema, options: {
|
|
63
|
+
submitUrl: string;
|
|
64
|
+
}) => string;
|
|
65
|
+
}
|
|
66
|
+
export interface LocalOAuthAppResult {
|
|
67
|
+
/** HTTP request handler to mount on a Node ``http.Server``. */
|
|
68
|
+
handler: RequestHandler;
|
|
69
|
+
/** JWT issuer, needed by the transport layer to verify Bearer tokens. */
|
|
70
|
+
jwtIssuer: JWTIssuer;
|
|
71
|
+
/** Mark a background setup step as complete (polled by GET /setup-status). */
|
|
72
|
+
markSetupComplete: (key?: string) => void;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Create OAuth 2.1 Authorization Server HTTP handler.
|
|
76
|
+
*
|
|
77
|
+
* Returns a handler compatible with ``http.createServer`` along with the
|
|
78
|
+
* ``JWTIssuer`` (for the transport layer to verify Bearer tokens) and a
|
|
79
|
+
* ``markSetupComplete`` function for background setup callbacks (e.g. GDrive
|
|
80
|
+
* device code flow).
|
|
81
|
+
*/
|
|
82
|
+
export declare function createLocalOAuthApp(options: LocalOAuthAppOptions): Promise<LocalOAuthAppResult>;
|
|
83
|
+
//# sourceMappingURL=local-oauth-app.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-oauth-app.d.ts","sourceRoot":"","sources":["../../src/auth/local-oauth-app.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAIH,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAClD,OAAO,EAAE,KAAK,iBAAiB,EAAwB,MAAM,sBAAsB,CAAA;AACnF,OAAO,EAML,KAAK,cAAc,EACpB,MAAM,aAAa,CAAA;AAGpB,8DAA8D;AAC9D,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAE9C;;;;;GAKG;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,QAAQ,GAAG,IAAI,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAA;AAE/G;;;;;;;;GAQG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,QAAQ,GAAG,IAAI,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAA;AAEvG,MAAM,WAAW,oBAAoB;IACnC,8DAA8D;IAC9D,UAAU,EAAE,MAAM,CAAA;IAClB,wDAAwD;IACxD,WAAW,EAAE,iBAAiB,CAAA;IAC9B,wEAAwE;IACxE,kBAAkB,CAAC,EAAE,mBAAmB,CAAA;IACxC,gEAAgE;IAChE,eAAe,CAAC,EAAE,YAAY,CAAA;IAC9B,iFAAiF;IACjF,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB;;;;;;OAMG;IACH,wBAAwB,CAAC,EAAE,CAAC,MAAM,EAAE,iBAAiB,EAAE,OAAO,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,KAAK,MAAM,CAAA;CACjG;AAED,MAAM,WAAW,mBAAmB;IAClC,+DAA+D;IAC/D,OAAO,EAAE,cAAc,CAAA;IACvB,yEAAyE;IACzE,SAAS,EAAE,SAAS,CAAA;IACpB,8EAA8E;IAC9E,iBAAiB,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;CAC1C;AAmED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA2TrG"}
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local OAuth 2.1 Authorization Server as an HTTP request handler.
|
|
3
|
+
*
|
|
4
|
+
* Provides a self-hosted Authorization Server for single-user MCP servers.
|
|
5
|
+
* Implements the OAuth 2.1 PKCE flow with credential collection via a
|
|
6
|
+
* browser-rendered form.
|
|
7
|
+
*
|
|
8
|
+
* Routes:
|
|
9
|
+
* - GET /authorize -- Render credential form
|
|
10
|
+
* - POST /authorize -- Save credentials, return auth code
|
|
11
|
+
* - POST /otp -- Submit multi-step credential (OTP / 2FA password)
|
|
12
|
+
* - POST /token -- Exchange auth code + PKCE verifier for JWT
|
|
13
|
+
* - GET /setup-status -- Poll background setup completion
|
|
14
|
+
* - GET /.well-known/oauth-authorization-server -- RFC 8414 metadata
|
|
15
|
+
* - GET /.well-known/oauth-protected-resource -- RFC 9728 metadata
|
|
16
|
+
*
|
|
17
|
+
* The /mcp endpoint is NOT included -- it is mounted by the transport layer.
|
|
18
|
+
*
|
|
19
|
+
* This is a TypeScript port of core-py's ``local_oauth_app.py``. Behavior,
|
|
20
|
+
* protocol, and TTL constants are kept identical for cross-language parity.
|
|
21
|
+
*/
|
|
22
|
+
import { createHash, randomBytes, timingSafeEqual } from 'node:crypto';
|
|
23
|
+
import { JWTIssuer } from '../oauth/jwt-issuer.js';
|
|
24
|
+
import { renderCredentialForm } from './credential-form.js';
|
|
25
|
+
import { createRouter, htmlResponse, jsonResponse, parseFormBody, parseJsonBody } from './router.js';
|
|
26
|
+
import { authorizationServerMetadata, protectedResourceMetadata } from './well-known.js';
|
|
27
|
+
// Auth codes and PKCE sessions expire after 10 minutes.
|
|
28
|
+
const AUTH_CODE_TTL_S = 600;
|
|
29
|
+
const SESSION_TTL_S = 600;
|
|
30
|
+
// Multi-step auth (OTP / 2FA password) constraints.
|
|
31
|
+
const OTP_TIMEOUT_S = 300;
|
|
32
|
+
const OTP_MAX_ATTEMPTS = 5;
|
|
33
|
+
/**
|
|
34
|
+
* Verify PKCE S256: ``base64url(sha256(code_verifier)) == code_challenge``,
|
|
35
|
+
* using a timing-safe comparison to prevent timing attacks.
|
|
36
|
+
*/
|
|
37
|
+
function s256Verify(codeVerifier, codeChallenge) {
|
|
38
|
+
const computed = createHash('sha256').update(codeVerifier, 'ascii').digest('base64url');
|
|
39
|
+
if (computed.length !== codeChallenge.length)
|
|
40
|
+
return false;
|
|
41
|
+
try {
|
|
42
|
+
return timingSafeEqual(Buffer.from(computed, 'ascii'), Buffer.from(codeChallenge, 'ascii'));
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/** Prune entries older than ``ttlMs`` milliseconds from an in-memory store. */
|
|
49
|
+
function pruneExpired(store, ttlMs) {
|
|
50
|
+
const now = Date.now();
|
|
51
|
+
for (const [key, value] of store) {
|
|
52
|
+
if (now - value.createdAt > ttlMs)
|
|
53
|
+
store.delete(key);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/** Derive the public base URL of this request (protocol + host, no trailing slash). */
|
|
57
|
+
function getBaseUrl(req) {
|
|
58
|
+
const host = req.headers.host ?? 'localhost';
|
|
59
|
+
const encrypted = req.socket.encrypted === true;
|
|
60
|
+
const forwardedProto = req.headers['x-forwarded-proto'];
|
|
61
|
+
const protocol = typeof forwardedProto === 'string' && forwardedProto.length > 0
|
|
62
|
+
? forwardedProto.split(',')[0].trim()
|
|
63
|
+
: encrypted
|
|
64
|
+
? 'https'
|
|
65
|
+
: 'http';
|
|
66
|
+
return `${protocol}://${host}`;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Create OAuth 2.1 Authorization Server HTTP handler.
|
|
70
|
+
*
|
|
71
|
+
* Returns a handler compatible with ``http.createServer`` along with the
|
|
72
|
+
* ``JWTIssuer`` (for the transport layer to verify Bearer tokens) and a
|
|
73
|
+
* ``markSetupComplete`` function for background setup callbacks (e.g. GDrive
|
|
74
|
+
* device code flow).
|
|
75
|
+
*/
|
|
76
|
+
export async function createLocalOAuthApp(options) {
|
|
77
|
+
const jwtIssuer = options.jwtIssuer ?? new JWTIssuer(options.serverName);
|
|
78
|
+
await jwtIssuer.init();
|
|
79
|
+
// In-memory stores keyed by nonce / auth_code. Each entry has a ``createdAt``
|
|
80
|
+
// for TTL expiry.
|
|
81
|
+
const pendingSessions = new Map();
|
|
82
|
+
const authCodes = new Map();
|
|
83
|
+
// Single-user local mode: one pending multi-step session at a time.
|
|
84
|
+
let pendingStep = null;
|
|
85
|
+
const setupStatus = { gdrive: 'idle' };
|
|
86
|
+
function markPendingStep() {
|
|
87
|
+
pendingStep = { active: true, createdAt: Date.now(), attempts: 0 };
|
|
88
|
+
}
|
|
89
|
+
function clearPendingStep() {
|
|
90
|
+
pendingStep = null;
|
|
91
|
+
}
|
|
92
|
+
// ------------------------------------------------------------------
|
|
93
|
+
// Route handlers
|
|
94
|
+
// ------------------------------------------------------------------
|
|
95
|
+
async function authorizeGet(req, res) {
|
|
96
|
+
const url = new URL(req.url ?? '/', `http://${req.headers.host ?? 'localhost'}`);
|
|
97
|
+
const params = url.searchParams;
|
|
98
|
+
const clientId = params.get('client_id');
|
|
99
|
+
const redirectUri = params.get('redirect_uri');
|
|
100
|
+
const state = params.get('state');
|
|
101
|
+
const codeChallenge = params.get('code_challenge');
|
|
102
|
+
const codeChallengeMethod = params.get('code_challenge_method') ?? 'S256';
|
|
103
|
+
if (!clientId || !redirectUri || !state || !codeChallenge) {
|
|
104
|
+
jsonResponse(res, 400, {
|
|
105
|
+
error: 'invalid_request',
|
|
106
|
+
error_description: 'Missing required parameters'
|
|
107
|
+
});
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const nonce = randomBytes(32).toString('base64url');
|
|
111
|
+
pendingSessions.set(nonce, {
|
|
112
|
+
clientId,
|
|
113
|
+
redirectUri,
|
|
114
|
+
state,
|
|
115
|
+
codeChallenge,
|
|
116
|
+
codeChallengeMethod,
|
|
117
|
+
createdAt: Date.now()
|
|
118
|
+
});
|
|
119
|
+
pruneExpired(pendingSessions, SESSION_TTL_S * 1000);
|
|
120
|
+
const base = getBaseUrl(req);
|
|
121
|
+
const submitUrl = `${base}/authorize?nonce=${nonce}`;
|
|
122
|
+
const html = options.customCredentialFormHtml !== undefined
|
|
123
|
+
? options.customCredentialFormHtml(options.relaySchema, { submitUrl })
|
|
124
|
+
: renderCredentialForm(options.relaySchema, { submitUrl });
|
|
125
|
+
htmlResponse(res, 200, html);
|
|
126
|
+
}
|
|
127
|
+
async function authorizePost(req, res) {
|
|
128
|
+
const url = new URL(req.url ?? '/', `http://${req.headers.host ?? 'localhost'}`);
|
|
129
|
+
const nonce = url.searchParams.get('nonce');
|
|
130
|
+
if (!nonce || !pendingSessions.has(nonce)) {
|
|
131
|
+
jsonResponse(res, 400, {
|
|
132
|
+
error: 'invalid_request',
|
|
133
|
+
error_description: 'Invalid or expired nonce'
|
|
134
|
+
});
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const session = pendingSessions.get(nonce);
|
|
138
|
+
pendingSessions.delete(nonce);
|
|
139
|
+
if (Date.now() - session.createdAt > SESSION_TTL_S * 1000) {
|
|
140
|
+
jsonResponse(res, 400, {
|
|
141
|
+
error: 'invalid_request',
|
|
142
|
+
error_description: 'Session expired'
|
|
143
|
+
});
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
let credentials;
|
|
147
|
+
try {
|
|
148
|
+
credentials = await parseJsonBody(req);
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
jsonResponse(res, 400, {
|
|
152
|
+
error: 'invalid_request',
|
|
153
|
+
error_description: 'Invalid JSON body'
|
|
154
|
+
});
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
// Save credentials via callback. Callback may return a dict with
|
|
158
|
+
// next_step info (e.g. GDrive OAuth device code to show in the form).
|
|
159
|
+
let nextStep = null;
|
|
160
|
+
if (options.onCredentialsSaved !== undefined) {
|
|
161
|
+
try {
|
|
162
|
+
const result = await options.onCredentialsSaved(credentials);
|
|
163
|
+
if (result !== null && result !== undefined && typeof result === 'object') {
|
|
164
|
+
nextStep = result;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
jsonResponse(res, 500, {
|
|
169
|
+
error: 'server_error',
|
|
170
|
+
error_description: 'Failed to save credentials'
|
|
171
|
+
});
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
// Generate auth code.
|
|
176
|
+
const authCode = randomBytes(32).toString('base64url');
|
|
177
|
+
authCodes.set(authCode, {
|
|
178
|
+
codeChallenge: session.codeChallenge,
|
|
179
|
+
codeChallengeMethod: session.codeChallengeMethod,
|
|
180
|
+
createdAt: Date.now()
|
|
181
|
+
});
|
|
182
|
+
pruneExpired(authCodes, AUTH_CODE_TTL_S * 1000);
|
|
183
|
+
const separator = session.redirectUri.includes('?') ? '&' : '?';
|
|
184
|
+
const redirectUrl = `${session.redirectUri}${separator}code=${authCode}&state=${session.state}`;
|
|
185
|
+
const body = { ok: true, redirect_url: redirectUrl };
|
|
186
|
+
if (nextStep !== null) {
|
|
187
|
+
body.next_step = nextStep;
|
|
188
|
+
// If next_step requires additional input (OTP or 2FA password),
|
|
189
|
+
// activate pending step session so /otp endpoint accepts input.
|
|
190
|
+
const stepType = nextStep.type;
|
|
191
|
+
if (stepType === 'otp_required' || stepType === 'password_required') {
|
|
192
|
+
markPendingStep();
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
jsonResponse(res, 200, body);
|
|
196
|
+
}
|
|
197
|
+
async function authorize(req, res) {
|
|
198
|
+
if (req.method === 'GET') {
|
|
199
|
+
await authorizeGet(req, res);
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
await authorizePost(req, res);
|
|
203
|
+
}
|
|
204
|
+
async function token(req, res) {
|
|
205
|
+
let form;
|
|
206
|
+
try {
|
|
207
|
+
form = await parseFormBody(req);
|
|
208
|
+
}
|
|
209
|
+
catch {
|
|
210
|
+
jsonResponse(res, 400, { error: 'invalid_request' });
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
const grantType = form.grant_type;
|
|
214
|
+
if (grantType !== 'authorization_code') {
|
|
215
|
+
jsonResponse(res, 400, { error: 'unsupported_grant_type' });
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
const code = form.code;
|
|
219
|
+
const codeVerifier = form.code_verifier;
|
|
220
|
+
if (!code || !codeVerifier) {
|
|
221
|
+
jsonResponse(res, 400, {
|
|
222
|
+
error: 'invalid_request',
|
|
223
|
+
error_description: 'Missing code or code_verifier'
|
|
224
|
+
});
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
const entry = authCodes.get(code);
|
|
228
|
+
if (entry === undefined) {
|
|
229
|
+
jsonResponse(res, 400, { error: 'invalid_grant' });
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
authCodes.delete(code);
|
|
233
|
+
if (Date.now() - entry.createdAt > AUTH_CODE_TTL_S * 1000) {
|
|
234
|
+
jsonResponse(res, 400, { error: 'invalid_grant' });
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
if (entry.codeChallengeMethod !== 'S256') {
|
|
238
|
+
jsonResponse(res, 400, {
|
|
239
|
+
error: 'invalid_request',
|
|
240
|
+
error_description: 'Only S256 is supported'
|
|
241
|
+
});
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
if (!s256Verify(codeVerifier, entry.codeChallenge)) {
|
|
245
|
+
jsonResponse(res, 400, { error: 'invalid_grant' });
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
const accessToken = await jwtIssuer.issueAccessToken('local-user');
|
|
249
|
+
jsonResponse(res, 200, {
|
|
250
|
+
access_token: accessToken,
|
|
251
|
+
token_type: 'Bearer',
|
|
252
|
+
expires_in: 3600
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
async function otpHandler(req, res) {
|
|
256
|
+
// 1. Active session check.
|
|
257
|
+
if (pendingStep === null || !pendingStep.active) {
|
|
258
|
+
jsonResponse(res, 400, {
|
|
259
|
+
error: 'invalid_request',
|
|
260
|
+
error_description: 'No active step session'
|
|
261
|
+
});
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
// 2. Timeout check.
|
|
265
|
+
if (Date.now() - pendingStep.createdAt > OTP_TIMEOUT_S * 1000) {
|
|
266
|
+
clearPendingStep();
|
|
267
|
+
jsonResponse(res, 400, {
|
|
268
|
+
error: 'invalid_request',
|
|
269
|
+
error_description: 'Step session expired'
|
|
270
|
+
});
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
// 3. Parse JSON body BEFORE incrementing attempts. Malformed input
|
|
274
|
+
// must not consume the user's retry quota nor clear the session.
|
|
275
|
+
let stepData;
|
|
276
|
+
try {
|
|
277
|
+
stepData = await parseJsonBody(req);
|
|
278
|
+
}
|
|
279
|
+
catch {
|
|
280
|
+
jsonResponse(res, 400, {
|
|
281
|
+
error: 'invalid_request',
|
|
282
|
+
error_description: 'Invalid JSON body'
|
|
283
|
+
});
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
// 4. Increment attempts counter (count every valid-JSON submit).
|
|
287
|
+
pendingStep.attempts += 1;
|
|
288
|
+
// 5. Attempt limit check.
|
|
289
|
+
if (pendingStep.attempts > OTP_MAX_ATTEMPTS) {
|
|
290
|
+
clearPendingStep();
|
|
291
|
+
jsonResponse(res, 400, {
|
|
292
|
+
error: 'invalid_request',
|
|
293
|
+
error_description: 'Too many attempts'
|
|
294
|
+
});
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
// 6. Dispatch to step callback.
|
|
298
|
+
let nextStep = null;
|
|
299
|
+
if (options.onStepSubmitted !== undefined) {
|
|
300
|
+
try {
|
|
301
|
+
const result = await options.onStepSubmitted(stepData);
|
|
302
|
+
if (result !== null && result !== undefined && typeof result === 'object') {
|
|
303
|
+
nextStep = result;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
catch {
|
|
307
|
+
jsonResponse(res, 500, {
|
|
308
|
+
error: 'server_error',
|
|
309
|
+
error_description: 'Failed to process step input'
|
|
310
|
+
});
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
// Error from callback: keep pending session, allow retry.
|
|
315
|
+
if (nextStep !== null && nextStep.type === 'error') {
|
|
316
|
+
const errText = typeof nextStep.text === 'string' ? nextStep.text : 'Invalid input';
|
|
317
|
+
jsonResponse(res, 200, { ok: false, error: errText });
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
// Chain to next step: reset counters so the new step gets its own quota.
|
|
321
|
+
if (nextStep !== null && (nextStep.type === 'otp_required' || nextStep.type === 'password_required')) {
|
|
322
|
+
markPendingStep();
|
|
323
|
+
jsonResponse(res, 200, { ok: true, next_step: nextStep });
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
// Completion (callback returned null / undefined or unknown dict type).
|
|
327
|
+
clearPendingStep();
|
|
328
|
+
jsonResponse(res, 200, { ok: true });
|
|
329
|
+
}
|
|
330
|
+
async function setupStatusHandler(_req, res) {
|
|
331
|
+
jsonResponse(res, 200, setupStatus);
|
|
332
|
+
}
|
|
333
|
+
async function wellKnownAs(req, res) {
|
|
334
|
+
const base = getBaseUrl(req);
|
|
335
|
+
jsonResponse(res, 200, authorizationServerMetadata(base));
|
|
336
|
+
}
|
|
337
|
+
async function wellKnownPr(req, res) {
|
|
338
|
+
const base = getBaseUrl(req);
|
|
339
|
+
jsonResponse(res, 200, protectedResourceMetadata(base, [base]));
|
|
340
|
+
}
|
|
341
|
+
function markSetupComplete(key = 'gdrive') {
|
|
342
|
+
setupStatus[key] = 'complete';
|
|
343
|
+
}
|
|
344
|
+
const handler = createRouter([
|
|
345
|
+
{ method: 'GET', path: '/authorize', handler: authorize },
|
|
346
|
+
{ method: 'POST', path: '/authorize', handler: authorize },
|
|
347
|
+
{ method: 'POST', path: '/token', handler: token },
|
|
348
|
+
{ method: 'POST', path: '/otp', handler: otpHandler },
|
|
349
|
+
{ method: 'GET', path: '/setup-status', handler: setupStatusHandler },
|
|
350
|
+
{ method: 'GET', path: '/.well-known/oauth-authorization-server', handler: wellKnownAs },
|
|
351
|
+
{ method: 'GET', path: '/.well-known/oauth-protected-resource', handler: wellKnownPr }
|
|
352
|
+
]);
|
|
353
|
+
return { handler, jwtIssuer, markSetupComplete };
|
|
354
|
+
}
|
|
355
|
+
//# sourceMappingURL=local-oauth-app.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-oauth-app.js","sourceRoot":"","sources":["../../src/auth/local-oauth-app.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAEtE,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAClD,OAAO,EAA0B,oBAAoB,EAAE,MAAM,sBAAsB,CAAA;AACnF,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,aAAa,EAEd,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,2BAA2B,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAA;AAsDxF,wDAAwD;AACxD,MAAM,eAAe,GAAG,GAAG,CAAA;AAC3B,MAAM,aAAa,GAAG,GAAG,CAAA;AAEzB,oDAAoD;AACpD,MAAM,aAAa,GAAG,GAAG,CAAA;AACzB,MAAM,gBAAgB,GAAG,CAAC,CAAA;AAuB1B;;;GAGG;AACH,SAAS,UAAU,CAAC,YAAoB,EAAE,aAAqB;IAC7D,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;IACvF,IAAI,QAAQ,CAAC,MAAM,KAAK,aAAa,CAAC,MAAM;QAAE,OAAO,KAAK,CAAA;IAC1D,IAAI,CAAC;QACH,OAAO,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC,CAAA;IAC7F,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AAED,+EAA+E;AAC/E,SAAS,YAAY,CAAkC,KAAqB,EAAE,KAAa;IACzF,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IACtB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,KAAK,EAAE,CAAC;QACjC,IAAI,GAAG,GAAG,KAAK,CAAC,SAAS,GAAG,KAAK;YAAE,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IACtD,CAAC;AACH,CAAC;AAED,uFAAuF;AACvF,SAAS,UAAU,CAAC,GAAoB;IACtC,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,WAAW,CAAA;IAC5C,MAAM,SAAS,GAAI,GAAG,CAAC,MAAkC,CAAC,SAAS,KAAK,IAAI,CAAA;IAC5E,MAAM,cAAc,GAAG,GAAG,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAA;IACvD,MAAM,QAAQ,GACZ,OAAO,cAAc,KAAK,QAAQ,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC;QAC7D,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;QACrC,CAAC,CAAC,SAAS;YACT,CAAC,CAAC,OAAO;YACT,CAAC,CAAC,MAAM,CAAA;IACd,OAAO,GAAG,QAAQ,MAAM,IAAI,EAAE,CAAA;AAChC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,OAA6B;IACrE,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,IAAI,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;IACxE,MAAM,SAAS,CAAC,IAAI,EAAE,CAAA;IAEtB,8EAA8E;IAC9E,kBAAkB;IAClB,MAAM,eAAe,GAAG,IAAI,GAAG,EAA0B,CAAA;IACzD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAyB,CAAA;IAElD,oEAAoE;IACpE,IAAI,WAAW,GAAuB,IAAI,CAAA;IAC1C,MAAM,WAAW,GAA2B,EAAE,MAAM,EAAE,MAAM,EAAE,CAAA;IAE9D,SAAS,eAAe;QACtB,WAAW,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAA;IACpE,CAAC;IAED,SAAS,gBAAgB;QACvB,WAAW,GAAG,IAAI,CAAA;IACpB,CAAC;IAED,qEAAqE;IACrE,iBAAiB;IACjB,qEAAqE;IAErE,KAAK,UAAU,YAAY,CAAC,GAAoB,EAAE,GAAmB;QACnE,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,UAAU,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,WAAW,EAAE,CAAC,CAAA;QAChF,MAAM,MAAM,GAAG,GAAG,CAAC,YAAY,CAAA;QAC/B,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;QACxC,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;QAC9C,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QACjC,MAAM,aAAa,GAAG,MAAM,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAA;QAClD,MAAM,mBAAmB,GAAG,MAAM,CAAC,GAAG,CAAC,uBAAuB,CAAC,IAAI,MAAM,CAAA;QAEzE,IAAI,CAAC,QAAQ,IAAI,CAAC,WAAW,IAAI,CAAC,KAAK,IAAI,CAAC,aAAa,EAAE,CAAC;YAC1D,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE;gBACrB,KAAK,EAAE,iBAAiB;gBACxB,iBAAiB,EAAE,6BAA6B;aACjD,CAAC,CAAA;YACF,OAAM;QACR,CAAC;QAED,MAAM,KAAK,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;QACnD,eAAe,CAAC,GAAG,CAAC,KAAK,EAAE;YACzB,QAAQ;YACR,WAAW;YACX,KAAK;YACL,aAAa;YACb,mBAAmB;YACnB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB,CAAC,CAAA;QACF,YAAY,CAAC,eAAe,EAAE,aAAa,GAAG,IAAI,CAAC,CAAA;QAEnD,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,CAAA;QAC5B,MAAM,SAAS,GAAG,GAAG,IAAI,oBAAoB,KAAK,EAAE,CAAA;QACpD,MAAM,IAAI,GACR,OAAO,CAAC,wBAAwB,KAAK,SAAS;YAC5C,CAAC,CAAC,OAAO,CAAC,wBAAwB,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,CAAC;YACtE,CAAC,CAAC,oBAAoB,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,CAAC,CAAA;QAC9D,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IAC9B,CAAC;IAED,KAAK,UAAU,aAAa,CAAC,GAAoB,EAAE,GAAmB;QACpE,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,UAAU,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,WAAW,EAAE,CAAC,CAAA;QAChF,MAAM,KAAK,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QAC3C,IAAI,CAAC,KAAK,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1C,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE;gBACrB,KAAK,EAAE,iBAAiB;gBACxB,iBAAiB,EAAE,0BAA0B;aAC9C,CAAC,CAAA;YACF,OAAM;QACR,CAAC;QAED,MAAM,OAAO,GAAG,eAAe,CAAC,GAAG,CAAC,KAAK,CAAmB,CAAA;QAC5D,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAE7B,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,SAAS,GAAG,aAAa,GAAG,IAAI,EAAE,CAAC;YAC1D,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE;gBACrB,KAAK,EAAE,iBAAiB;gBACxB,iBAAiB,EAAE,iBAAiB;aACrC,CAAC,CAAA;YACF,OAAM;QACR,CAAC;QAED,IAAI,WAAmC,CAAA;QACvC,IAAI,CAAC;YACH,WAAW,GAAG,MAAM,aAAa,CAAyB,GAAG,CAAC,CAAA;QAChE,CAAC;QAAC,MAAM,CAAC;YACP,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE;gBACrB,KAAK,EAAE,iBAAiB;gBACxB,iBAAiB,EAAE,mBAAmB;aACvC,CAAC,CAAA;YACF,OAAM;QACR,CAAC;QAED,iEAAiE;QACjE,sEAAsE;QACtE,IAAI,QAAQ,GAAoB,IAAI,CAAA;QACpC,IAAI,OAAO,CAAC,kBAAkB,KAAK,SAAS,EAAE,CAAC;YAC7C,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAA;gBAC5D,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,SAAS,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;oBAC1E,QAAQ,GAAG,MAAM,CAAA;gBACnB,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE;oBACrB,KAAK,EAAE,cAAc;oBACrB,iBAAiB,EAAE,4BAA4B;iBAChD,CAAC,CAAA;gBACF,OAAM;YACR,CAAC;QACH,CAAC;QAED,sBAAsB;QACtB,MAAM,QAAQ,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;QACtD,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE;YACtB,aAAa,EAAE,OAAO,CAAC,aAAa;YACpC,mBAAmB,EAAE,OAAO,CAAC,mBAAmB;YAChD,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB,CAAC,CAAA;QACF,YAAY,CAAC,SAAS,EAAE,eAAe,GAAG,IAAI,CAAC,CAAA;QAE/C,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAA;QAC/D,MAAM,WAAW,GAAG,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,QAAQ,QAAQ,UAAU,OAAO,CAAC,KAAK,EAAE,CAAA;QAE/F,MAAM,IAAI,GAA4B,EAAE,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,WAAW,EAAE,CAAA;QAC7E,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACtB,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAA;YACzB,gEAAgE;YAChE,gEAAgE;YAChE,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAA;YAC9B,IAAI,QAAQ,KAAK,cAAc,IAAI,QAAQ,KAAK,mBAAmB,EAAE,CAAC;gBACpE,eAAe,EAAE,CAAA;YACnB,CAAC;QACH,CAAC;QACD,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IAC9B,CAAC;IAED,KAAK,UAAU,SAAS,CAAC,GAAoB,EAAE,GAAmB;QAChE,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;YACzB,MAAM,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;YAC5B,OAAM;QACR,CAAC;QACD,MAAM,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;IAC/B,CAAC;IAED,KAAK,UAAU,KAAK,CAAC,GAAoB,EAAE,GAAmB;QAC5D,IAAI,IAA4B,CAAA;QAChC,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,aAAa,CAAC,GAAG,CAAC,CAAA;QACjC,CAAC;QAAC,MAAM,CAAC;YACP,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC,CAAA;YACpD,OAAM;QACR,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAA;QACjC,IAAI,SAAS,KAAK,oBAAoB,EAAE,CAAC;YACvC,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC,CAAA;YAC3D,OAAM;QACR,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;QACtB,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,CAAA;QACvC,IAAI,CAAC,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YAC3B,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE;gBACrB,KAAK,EAAE,iBAAiB;gBACxB,iBAAiB,EAAE,+BAA+B;aACnD,CAAC,CAAA;YACF,OAAM;QACR,CAAC;QAED,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QACjC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAA;YAClD,OAAM;QACR,CAAC;QACD,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QAEtB,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,GAAG,eAAe,GAAG,IAAI,EAAE,CAAC;YAC1D,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAA;YAClD,OAAM;QACR,CAAC;QAED,IAAI,KAAK,CAAC,mBAAmB,KAAK,MAAM,EAAE,CAAC;YACzC,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE;gBACrB,KAAK,EAAE,iBAAiB;gBACxB,iBAAiB,EAAE,wBAAwB;aAC5C,CAAC,CAAA;YACF,OAAM;QACR,CAAC;QAED,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC;YACnD,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAA;YAClD,OAAM;QACR,CAAC;QAED,MAAM,WAAW,GAAG,MAAM,SAAS,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAA;QAClE,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE;YACrB,YAAY,EAAE,WAAW;YACzB,UAAU,EAAE,QAAQ;YACpB,UAAU,EAAE,IAAI;SACjB,CAAC,CAAA;IACJ,CAAC;IAED,KAAK,UAAU,UAAU,CAAC,GAAoB,EAAE,GAAmB;QACjE,2BAA2B;QAC3B,IAAI,WAAW,KAAK,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;YAChD,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE;gBACrB,KAAK,EAAE,iBAAiB;gBACxB,iBAAiB,EAAE,wBAAwB;aAC5C,CAAC,CAAA;YACF,OAAM;QACR,CAAC;QAED,oBAAoB;QACpB,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,WAAW,CAAC,SAAS,GAAG,aAAa,GAAG,IAAI,EAAE,CAAC;YAC9D,gBAAgB,EAAE,CAAA;YAClB,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE;gBACrB,KAAK,EAAE,iBAAiB;gBACxB,iBAAiB,EAAE,sBAAsB;aAC1C,CAAC,CAAA;YACF,OAAM;QACR,CAAC;QAED,mEAAmE;QACnE,iEAAiE;QACjE,IAAI,QAAgC,CAAA;QACpC,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,aAAa,CAAyB,GAAG,CAAC,CAAA;QAC7D,CAAC;QAAC,MAAM,CAAC;YACP,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE;gBACrB,KAAK,EAAE,iBAAiB;gBACxB,iBAAiB,EAAE,mBAAmB;aACvC,CAAC,CAAA;YACF,OAAM;QACR,CAAC;QAED,iEAAiE;QACjE,WAAW,CAAC,QAAQ,IAAI,CAAC,CAAA;QAEzB,0BAA0B;QAC1B,IAAI,WAAW,CAAC,QAAQ,GAAG,gBAAgB,EAAE,CAAC;YAC5C,gBAAgB,EAAE,CAAA;YAClB,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE;gBACrB,KAAK,EAAE,iBAAiB;gBACxB,iBAAiB,EAAE,mBAAmB;aACvC,CAAC,CAAA;YACF,OAAM;QACR,CAAC;QAED,gCAAgC;QAChC,IAAI,QAAQ,GAAoB,IAAI,CAAA;QACpC,IAAI,OAAO,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;YAC1C,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAA;gBACtD,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,SAAS,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;oBAC1E,QAAQ,GAAG,MAAM,CAAA;gBACnB,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE;oBACrB,KAAK,EAAE,cAAc;oBACrB,iBAAiB,EAAE,8BAA8B;iBAClD,CAAC,CAAA;gBACF,OAAM;YACR,CAAC;QACH,CAAC;QAED,0DAA0D;QAC1D,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YACnD,MAAM,OAAO,GAAG,OAAO,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,eAAe,CAAA;YACnF,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAA;YACrD,OAAM;QACR,CAAC;QAED,yEAAyE;QACzE,IAAI,QAAQ,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,cAAc,IAAI,QAAQ,CAAC,IAAI,KAAK,mBAAmB,CAAC,EAAE,CAAC;YACrG,eAAe,EAAE,CAAA;YACjB,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAA;YACzD,OAAM;QACR,CAAC;QAED,wEAAwE;QACxE,gBAAgB,EAAE,CAAA;QAClB,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;IACtC,CAAC;IAED,KAAK,UAAU,kBAAkB,CAAC,IAAqB,EAAE,GAAmB;QAC1E,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,WAAW,CAAC,CAAA;IACrC,CAAC;IAED,KAAK,UAAU,WAAW,CAAC,GAAoB,EAAE,GAAmB;QAClE,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,CAAA;QAC5B,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,2BAA2B,CAAC,IAAI,CAAC,CAAC,CAAA;IAC3D,CAAC;IAED,KAAK,UAAU,WAAW,CAAC,GAAoB,EAAE,GAAmB;QAClE,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,CAAA;QAC5B,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,yBAAyB,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjE,CAAC;IAED,SAAS,iBAAiB,CAAC,GAAG,GAAG,QAAQ;QACvC,WAAW,CAAC,GAAG,CAAC,GAAG,UAAU,CAAA;IAC/B,CAAC;IAED,MAAM,OAAO,GAAG,YAAY,CAAC;QAC3B,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE;QACzD,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE;QAC1D,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE;QAClD,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE;QACrD,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,kBAAkB,EAAE;QACrE,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,yCAAyC,EAAE,OAAO,EAAE,WAAW,EAAE;QACxF,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,uCAAuC,EAAE,OAAO,EAAE,WAAW,EAAE;KACvF,CAAC,CAAA;IAEF,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,CAAA;AAClD,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal minimal HTTP router. Not exported from the package.
|
|
3
|
+
* Matches requests by method + pathname, calls first matching handler.
|
|
4
|
+
*/
|
|
5
|
+
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
6
|
+
export type RequestHandler = (req: IncomingMessage, res: ServerResponse) => void | Promise<void>;
|
|
7
|
+
interface Route {
|
|
8
|
+
method: string;
|
|
9
|
+
path: string;
|
|
10
|
+
handler: RequestHandler;
|
|
11
|
+
}
|
|
12
|
+
export declare function createRouter(routes: Route[]): RequestHandler;
|
|
13
|
+
export declare function parseJsonBody<T = Record<string, unknown>>(req: IncomingMessage): Promise<T>;
|
|
14
|
+
export declare function parseFormBody(req: IncomingMessage): Promise<Record<string, string>>;
|
|
15
|
+
export declare function jsonResponse(res: ServerResponse, status: number, body: unknown): void;
|
|
16
|
+
export declare function htmlResponse(res: ServerResponse, status: number, html: string): void;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/auth/router.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAEhE,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;AAEhG,UAAU,KAAK;IACb,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,cAAc,CAAA;CACxB;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,cAAc,CAuB5D;AAED,wBAAsB,aAAa,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,CAAC,CAAC,CAajG;AAED,wBAAsB,aAAa,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAczF;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAGrF;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAGpF"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export function createRouter(routes) {
|
|
2
|
+
return async (req, res) => {
|
|
3
|
+
const method = req.method?.toUpperCase() ?? 'GET';
|
|
4
|
+
const url = new URL(req.url ?? '/', `http://${req.headers.host ?? 'localhost'}`);
|
|
5
|
+
const pathname = url.pathname;
|
|
6
|
+
for (const route of routes) {
|
|
7
|
+
if (route.method === method && route.path === pathname) {
|
|
8
|
+
try {
|
|
9
|
+
await route.handler(req, res);
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
if (!res.headersSent) {
|
|
13
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
14
|
+
res.end(JSON.stringify({ error: 'internal_error' }));
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
21
|
+
res.end(JSON.stringify({ error: 'not_found' }));
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export async function parseJsonBody(req) {
|
|
25
|
+
return new Promise((resolve, reject) => {
|
|
26
|
+
const chunks = [];
|
|
27
|
+
req.on('data', (chunk) => chunks.push(chunk));
|
|
28
|
+
req.on('end', () => {
|
|
29
|
+
try {
|
|
30
|
+
resolve(JSON.parse(Buffer.concat(chunks).toString('utf-8')));
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
reject(new Error('Invalid JSON'));
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
req.on('error', reject);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
export async function parseFormBody(req) {
|
|
40
|
+
return new Promise((resolve, reject) => {
|
|
41
|
+
const chunks = [];
|
|
42
|
+
req.on('data', (chunk) => chunks.push(chunk));
|
|
43
|
+
req.on('end', () => {
|
|
44
|
+
const params = new URLSearchParams(Buffer.concat(chunks).toString('utf-8'));
|
|
45
|
+
const result = {};
|
|
46
|
+
for (const [key, value] of params) {
|
|
47
|
+
result[key] = value;
|
|
48
|
+
}
|
|
49
|
+
resolve(result);
|
|
50
|
+
});
|
|
51
|
+
req.on('error', reject);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
export function jsonResponse(res, status, body) {
|
|
55
|
+
res.writeHead(status, { 'Content-Type': 'application/json' });
|
|
56
|
+
res.end(JSON.stringify(body));
|
|
57
|
+
}
|
|
58
|
+
export function htmlResponse(res, status, html) {
|
|
59
|
+
res.writeHead(status, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
60
|
+
res.end(html);
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/auth/router.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** OAuth 2.1 well-known metadata generators (RFC 8414 + RFC 9728). */
|
|
2
|
+
export declare function authorizationServerMetadata(issuerUrl: string): Record<string, unknown>;
|
|
3
|
+
export declare function protectedResourceMetadata(resource: string, authorizationServers: string[]): Record<string, unknown>;
|
|
4
|
+
//# sourceMappingURL=well-known.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"well-known.d.ts","sourceRoot":"","sources":["../../src/auth/well-known.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAUtF;AAED,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAMnH"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/** OAuth 2.1 well-known metadata generators (RFC 8414 + RFC 9728). */
|
|
2
|
+
export function authorizationServerMetadata(issuerUrl) {
|
|
3
|
+
return {
|
|
4
|
+
issuer: issuerUrl,
|
|
5
|
+
authorization_endpoint: `${issuerUrl}/authorize`,
|
|
6
|
+
token_endpoint: `${issuerUrl}/token`,
|
|
7
|
+
response_types_supported: ['code'],
|
|
8
|
+
grant_types_supported: ['authorization_code'],
|
|
9
|
+
code_challenge_methods_supported: ['S256'],
|
|
10
|
+
token_endpoint_auth_methods_supported: ['none']
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export function protectedResourceMetadata(resource, authorizationServers) {
|
|
14
|
+
return {
|
|
15
|
+
resource,
|
|
16
|
+
authorization_servers: authorizationServers,
|
|
17
|
+
bearer_methods_supported: ['header']
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=well-known.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"well-known.js","sourceRoot":"","sources":["../../src/auth/well-known.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,MAAM,UAAU,2BAA2B,CAAC,SAAiB;IAC3D,OAAO;QACL,MAAM,EAAE,SAAS;QACjB,sBAAsB,EAAE,GAAG,SAAS,YAAY;QAChD,cAAc,EAAE,GAAG,SAAS,QAAQ;QACpC,wBAAwB,EAAE,CAAC,MAAM,CAAC;QAClC,qBAAqB,EAAE,CAAC,oBAAoB,CAAC;QAC7C,gCAAgC,EAAE,CAAC,MAAM,CAAC;QAC1C,qCAAqC,EAAE,CAAC,MAAM,CAAC;KAChD,CAAA;AACH,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,QAAgB,EAAE,oBAA8B;IACxF,OAAO;QACL,QAAQ;QACR,qBAAqB,EAAE,oBAAoB;QAC3C,wBAAwB,EAAE,CAAC,QAAQ,CAAC;KACrC,CAAA;AACH,CAAC"}
|
package/build/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export { authorizationServerMetadata, type CapabilityInfo, type ConfigField, type CredentialsCallback, createLocalOAuthApp, type LocalOAuthAppOptions, type LocalOAuthAppResult, type NextStep, protectedResourceMetadata, type RelayConfigSchema, type RenderOptions, renderCredentialForm, type StepCallback } from './auth/index.js';
|
|
1
2
|
export * from './crypto/index.js';
|
|
2
3
|
export { JWTIssuer } from './oauth/jwt-issuer.js';
|
|
3
4
|
export { InMemoryAuthCache, type IOAuthSessionCache, OAuthProvider, type OAuthProviderOptions, type PreAuthSession } from './oauth/provider.js';
|
|
@@ -5,8 +6,9 @@ export { type IUserCredentialStore, SqliteUserStore } from './oauth/user-store.j
|
|
|
5
6
|
export { tryOpenBrowser } from './relay/browser.js';
|
|
6
7
|
export { createSession, generatePassphrase, pollForResponses, pollForResult, type RelaySession, sendMessage } from './relay/client.js';
|
|
7
8
|
export type * from './schema/types.js';
|
|
8
|
-
export { deleteConfig, exportConfig, importConfig, listConfigs, readConfig, writeConfig } from './storage/config-file.js';
|
|
9
|
+
export { deleteConfig, exportConfig, importConfig, listConfigs, readConfig, scheduleReloadExit, writeConfig } from './storage/config-file.js';
|
|
9
10
|
export { clearMode, getMode, type ServerMode, setLocalMode } from './storage/mode.js';
|
|
10
11
|
export * from './storage/resolver.js';
|
|
11
12
|
export { acquireSessionLock, releaseSessionLock, type SessionInfo, writeSessionLock } from './storage/session-lock.js';
|
|
13
|
+
export { type LocalServerHandle, type RunLocalServerOptions, runLocalServer } from './transport/local-server.js';
|
|
12
14
|
//# sourceMappingURL=index.d.ts.map
|
package/build/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,2BAA2B,EAC3B,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,mBAAmB,EACxB,mBAAmB,EACnB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,QAAQ,EACb,yBAAyB,EACzB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,oBAAoB,EACpB,KAAK,YAAY,EAClB,MAAM,iBAAiB,CAAA;AACxB,cAAc,mBAAmB,CAAA;AAEjC,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AACjD,OAAO,EACL,iBAAiB,EACjB,KAAK,kBAAkB,EACvB,aAAa,EACb,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACpB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,KAAK,oBAAoB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAClF,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACnD,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,aAAa,EACb,KAAK,YAAY,EACjB,WAAW,EACZ,MAAM,mBAAmB,CAAA;AAC1B,mBAAmB,mBAAmB,CAAA;AACtC,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,UAAU,EACV,kBAAkB,EAClB,WAAW,EACZ,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,UAAU,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACrF,cAAc,uBAAuB,CAAA;AACrC,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,KAAK,WAAW,EAChB,gBAAgB,EACjB,MAAM,2BAA2B,CAAA;AAElC,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,cAAc,EACf,MAAM,6BAA6B,CAAA"}
|
package/build/index.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
// Local OAuth 2.1 Authorization Server (single-user, 127.0.0.1)
|
|
2
|
+
export { authorizationServerMetadata, createLocalOAuthApp, protectedResourceMetadata, renderCredentialForm } from './auth/index.js';
|
|
1
3
|
export * from './crypto/index.js';
|
|
2
4
|
// OAuth 2.1 multi-user infrastructure (HTTP mode)
|
|
3
5
|
export { JWTIssuer } from './oauth/jwt-issuer.js';
|
|
@@ -5,8 +7,10 @@ export { InMemoryAuthCache, OAuthProvider } from './oauth/provider.js';
|
|
|
5
7
|
export { SqliteUserStore } from './oauth/user-store.js';
|
|
6
8
|
export { tryOpenBrowser } from './relay/browser.js';
|
|
7
9
|
export { createSession, generatePassphrase, pollForResponses, pollForResult, sendMessage } from './relay/client.js';
|
|
8
|
-
export { deleteConfig, exportConfig, importConfig, listConfigs, readConfig, writeConfig } from './storage/config-file.js';
|
|
10
|
+
export { deleteConfig, exportConfig, importConfig, listConfigs, readConfig, scheduleReloadExit, writeConfig } from './storage/config-file.js';
|
|
9
11
|
export { clearMode, getMode, setLocalMode } from './storage/mode.js';
|
|
10
12
|
export * from './storage/resolver.js';
|
|
11
13
|
export { acquireSessionLock, releaseSessionLock, writeSessionLock } from './storage/session-lock.js';
|
|
14
|
+
// Local MCP server entry point (OAuth AS + /mcp transport on 127.0.0.1)
|
|
15
|
+
export { runLocalServer } from './transport/local-server.js';
|
|
12
16
|
//# sourceMappingURL=index.js.map
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAA;AACjC,kDAAkD;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AACjD,OAAO,EACL,iBAAiB,EAEjB,aAAa,EAGd,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAA6B,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAClF,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACnD,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,aAAa,EAEb,WAAW,EACZ,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,UAAU,EACV,WAAW,EACZ,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAmB,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACrF,cAAc,uBAAuB,CAAA;AACrC,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAElB,gBAAgB,EACjB,MAAM,2BAA2B,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,OAAO,EACL,2BAA2B,EAI3B,mBAAmB,EAInB,yBAAyB,EAGzB,oBAAoB,EAErB,MAAM,iBAAiB,CAAA;AACxB,cAAc,mBAAmB,CAAA;AACjC,kDAAkD;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AACjD,OAAO,EACL,iBAAiB,EAEjB,aAAa,EAGd,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAA6B,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAClF,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACnD,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,aAAa,EAEb,WAAW,EACZ,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,UAAU,EACV,kBAAkB,EAClB,WAAW,EACZ,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAmB,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACrF,cAAc,uBAAuB,CAAA;AACrC,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAElB,gBAAgB,EACjB,MAAM,2BAA2B,CAAA;AAClC,wEAAwE;AACxE,OAAO,EAGL,cAAc,EACf,MAAM,6BAA6B,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/relay/browser.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/relay/browser.ts"],"names":[],"mappings":"AAAA;;GAEG;AA4CH;;;;;;;;;GASG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAqClE"}
|