@agent-native/core 0.18.1 → 0.19.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.
Files changed (109) hide show
  1. package/README.md +1 -11
  2. package/dist/a2a/client.d.ts +7 -0
  3. package/dist/a2a/client.d.ts.map +1 -1
  4. package/dist/a2a/client.js +3 -0
  5. package/dist/a2a/client.js.map +1 -1
  6. package/dist/cli/connect.d.ts +94 -0
  7. package/dist/cli/connect.d.ts.map +1 -0
  8. package/dist/cli/connect.js +443 -0
  9. package/dist/cli/connect.js.map +1 -0
  10. package/dist/cli/index.js +16 -0
  11. package/dist/cli/index.js.map +1 -1
  12. package/dist/cli/mcp-config-writers.d.ts +71 -0
  13. package/dist/cli/mcp-config-writers.d.ts.map +1 -0
  14. package/dist/cli/mcp-config-writers.js +210 -0
  15. package/dist/cli/mcp-config-writers.js.map +1 -0
  16. package/dist/client/AssistantChat.d.ts.map +1 -1
  17. package/dist/client/AssistantChat.js +11 -63
  18. package/dist/client/AssistantChat.js.map +1 -1
  19. package/dist/client/composer/PromptComposer.d.ts +6 -1
  20. package/dist/client/composer/PromptComposer.d.ts.map +1 -1
  21. package/dist/client/composer/PromptComposer.js +5 -4
  22. package/dist/client/composer/PromptComposer.js.map +1 -1
  23. package/dist/client/composer/TiptapComposer.d.ts +6 -1
  24. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  25. package/dist/client/composer/TiptapComposer.js +20 -10
  26. package/dist/client/composer/TiptapComposer.js.map +1 -1
  27. package/dist/client/conversation/AgentConversation.d.ts +18 -0
  28. package/dist/client/conversation/AgentConversation.d.ts.map +1 -0
  29. package/dist/client/conversation/AgentConversation.js +94 -0
  30. package/dist/client/conversation/AgentConversation.js.map +1 -0
  31. package/dist/client/conversation/AgentConversation.spec.d.ts +2 -0
  32. package/dist/client/conversation/AgentConversation.spec.d.ts.map +1 -0
  33. package/dist/client/conversation/AgentConversation.spec.js +69 -0
  34. package/dist/client/conversation/AgentConversation.spec.js.map +1 -0
  35. package/dist/client/conversation/index.d.ts +4 -0
  36. package/dist/client/conversation/index.d.ts.map +1 -0
  37. package/dist/client/conversation/index.js +3 -0
  38. package/dist/client/conversation/index.js.map +1 -0
  39. package/dist/client/conversation/types.d.ts +54 -0
  40. package/dist/client/conversation/types.d.ts.map +1 -0
  41. package/dist/client/conversation/types.js +2 -0
  42. package/dist/client/conversation/types.js.map +1 -0
  43. package/dist/client/conversation/use-near-bottom-autoscroll.d.ts +15 -0
  44. package/dist/client/conversation/use-near-bottom-autoscroll.d.ts.map +1 -0
  45. package/dist/client/conversation/use-near-bottom-autoscroll.js +66 -0
  46. package/dist/client/conversation/use-near-bottom-autoscroll.js.map +1 -0
  47. package/dist/client/index.d.ts +1 -0
  48. package/dist/client/index.d.ts.map +1 -1
  49. package/dist/client/index.js +1 -0
  50. package/dist/client/index.js.map +1 -1
  51. package/dist/client/resources/ResourceTree.d.ts.map +1 -1
  52. package/dist/client/resources/ResourceTree.js +2 -2
  53. package/dist/client/resources/ResourceTree.js.map +1 -1
  54. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  55. package/dist/client/resources/ResourcesPanel.js +4 -28
  56. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  57. package/dist/code-agents/index.d.ts +1 -0
  58. package/dist/code-agents/index.d.ts.map +1 -1
  59. package/dist/code-agents/index.js +1 -0
  60. package/dist/code-agents/index.js.map +1 -1
  61. package/dist/code-agents/transcript-normalizer.d.ts +50 -0
  62. package/dist/code-agents/transcript-normalizer.d.ts.map +1 -0
  63. package/dist/code-agents/transcript-normalizer.js +356 -0
  64. package/dist/code-agents/transcript-normalizer.js.map +1 -0
  65. package/dist/extensions/schema.d.ts +1 -1
  66. package/dist/mcp/build-server.d.ts.map +1 -1
  67. package/dist/mcp/build-server.js +30 -0
  68. package/dist/mcp/build-server.js.map +1 -1
  69. package/dist/mcp/connect-route.d.ts +43 -0
  70. package/dist/mcp/connect-route.d.ts.map +1 -0
  71. package/dist/mcp/connect-route.js +638 -0
  72. package/dist/mcp/connect-route.js.map +1 -0
  73. package/dist/mcp/connect-store.d.ts +132 -0
  74. package/dist/mcp/connect-store.d.ts.map +1 -0
  75. package/dist/mcp/connect-store.js +434 -0
  76. package/dist/mcp/connect-store.js.map +1 -0
  77. package/dist/server/auth.d.ts +17 -0
  78. package/dist/server/auth.d.ts.map +1 -1
  79. package/dist/server/auth.js +149 -33
  80. package/dist/server/auth.js.map +1 -1
  81. package/dist/server/better-auth-instance.d.ts +43 -0
  82. package/dist/server/better-auth-instance.d.ts.map +1 -1
  83. package/dist/server/better-auth-instance.js +25 -0
  84. package/dist/server/better-auth-instance.js.map +1 -1
  85. package/dist/server/core-routes-plugin.d.ts +12 -0
  86. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  87. package/dist/server/core-routes-plugin.js +42 -0
  88. package/dist/server/core-routes-plugin.js.map +1 -1
  89. package/dist/server/identity-sso-store.d.ts +86 -0
  90. package/dist/server/identity-sso-store.d.ts.map +1 -0
  91. package/dist/server/identity-sso-store.js +243 -0
  92. package/dist/server/identity-sso-store.js.map +1 -0
  93. package/dist/server/identity-sso.d.ts +78 -0
  94. package/dist/server/identity-sso.d.ts.map +1 -0
  95. package/dist/server/identity-sso.js +425 -0
  96. package/dist/server/identity-sso.js.map +1 -0
  97. package/dist/server/index.d.ts +1 -0
  98. package/dist/server/index.d.ts.map +1 -1
  99. package/dist/server/index.js +1 -0
  100. package/dist/server/index.js.map +1 -1
  101. package/dist/server/onboarding-html.d.ts.map +1 -1
  102. package/dist/server/onboarding-html.js +2 -1
  103. package/dist/server/onboarding-html.js.map +1 -1
  104. package/dist/sharing/schema.d.ts +1 -1
  105. package/docs/content/code-agents-ui.md +14 -3
  106. package/docs/content/cross-app-sso.md +118 -0
  107. package/docs/content/external-agents.md +130 -51
  108. package/docs/content/migration-workbench.md +1 -1
  109. package/package.json +2 -1
@@ -0,0 +1,434 @@
1
+ /**
2
+ * Framework-table store for the "connect external agents" feature.
3
+ *
4
+ * Two additive, dialect-agnostic tables back the browser **Connect** page and
5
+ * the OAuth-style **device-code flow** a CLI drives:
6
+ *
7
+ * - `mcp_connect_tokens` — one row per minted MCP token. We never store the
8
+ * token value (it's a signed JWT); only its `jti` so revocation is a
9
+ * SQL lookup. Revoking sets `revoked_at`; the row is never deleted.
10
+ * - `mcp_device_codes` — short-lived (10 min) device/user code pairs for
11
+ * the OAuth 2.0 device-authorization-style CLI flow. Single-use
12
+ * (`consumed_at`), rate-limited at creation.
13
+ *
14
+ * Mirrors `application-state/store.ts`: lazy `ensureTable()`, `getDbExec()`,
15
+ * `isPostgres()` dialect branching for upserts, `isConnectionError()` swallow
16
+ * so a transient Neon WS drop never 500s. `CREATE TABLE IF NOT EXISTS` only —
17
+ * strictly additive, never DROP / ALTER (shared prod DB rule).
18
+ */
19
+ import { getDbExec, isConnectionError, intType, } from "../db/client.js";
20
+ import { randomBytes, randomUUID } from "node:crypto";
21
+ let _initPromise;
22
+ /**
23
+ * Scope claim that marks a connect-minted token (vs. an ordinary A2A
24
+ * delegation JWT). Only tokens carrying this scope go through the revoke
25
+ * lookup in `verifyAuth` — defined here so both `connect-route.ts` and
26
+ * `build-server.ts` import it from the leaf store without a cycle.
27
+ */
28
+ export const MCP_CONNECT_SCOPE = "mcp-connect";
29
+ /** Device codes are valid for 10 minutes. */
30
+ export const DEVICE_CODE_TTL_MS = 10 * 60_000;
31
+ /** Default minted-token lifetime. Configurable per-request 1–365 days. */
32
+ export const DEFAULT_TOKEN_TTL_DAYS = 90;
33
+ export const MIN_TOKEN_TTL_DAYS = 1;
34
+ export const MAX_TOKEN_TTL_DAYS = 365;
35
+ /**
36
+ * Rate limit for `device/start`: at most this many device codes may be created
37
+ * within `DEVICE_START_WINDOW_MS`. Unauthenticated endpoint — keep it tight so
38
+ * a hostile client can't flood the table or brute-force user codes.
39
+ */
40
+ export const DEVICE_START_MAX = 20;
41
+ export const DEVICE_START_WINDOW_MS = 60_000;
42
+ async function ensureTable() {
43
+ if (!_initPromise) {
44
+ _initPromise = (async () => {
45
+ const client = getDbExec();
46
+ // Additive only. Never DROP / ALTER — this DB is shared across every
47
+ // deploy context (preview/branch/prod) for hosted templates.
48
+ await client.execute(`
49
+ CREATE TABLE IF NOT EXISTS mcp_connect_tokens (
50
+ id TEXT PRIMARY KEY,
51
+ jti TEXT UNIQUE NOT NULL,
52
+ owner_email TEXT NOT NULL,
53
+ org_id TEXT,
54
+ label TEXT,
55
+ created_at ${intType()},
56
+ last_used_at ${intType()},
57
+ revoked_at ${intType()}
58
+ )
59
+ `);
60
+ await client.execute(`
61
+ CREATE TABLE IF NOT EXISTS mcp_device_codes (
62
+ device_code TEXT PRIMARY KEY,
63
+ user_code TEXT NOT NULL,
64
+ owner_email TEXT,
65
+ org_id TEXT,
66
+ status TEXT NOT NULL DEFAULT 'pending',
67
+ token_jti TEXT,
68
+ created_at ${intType()},
69
+ expires_at ${intType()},
70
+ consumed_at ${intType()}
71
+ )
72
+ `);
73
+ })().catch((err) => {
74
+ // Don't cache a rejected init. A transient DB blip should let the next
75
+ // connect/mint/revoke call retry rather than wedging the process.
76
+ _initPromise = undefined;
77
+ throw err;
78
+ });
79
+ }
80
+ return _initPromise;
81
+ }
82
+ /**
83
+ * Persist a record of a minted token. The token value itself (a signed JWT)
84
+ * is NEVER stored — only its `jti`, so revocation is a cheap SQL lookup.
85
+ */
86
+ export async function recordMintedToken(params) {
87
+ await ensureTable();
88
+ const client = getDbExec();
89
+ const id = randomUUID();
90
+ await client.execute({
91
+ sql: `INSERT INTO mcp_connect_tokens (id, jti, owner_email, org_id, label, created_at, last_used_at, revoked_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
92
+ args: [
93
+ id,
94
+ params.jti,
95
+ params.ownerEmail,
96
+ params.orgId ?? null,
97
+ params.label ?? null,
98
+ Date.now(),
99
+ null,
100
+ null,
101
+ ],
102
+ });
103
+ return id;
104
+ }
105
+ /**
106
+ * Returns true when the given `jti` corresponds to a token that has been
107
+ * revoked. Fails OPEN on a store/DB error: a transient Neon WS drop must not
108
+ * lock every connected agent out. Signature verification is unaffected — this
109
+ * is only the post-verify revoke check (see `verifyAuth` in build-server.ts).
110
+ */
111
+ export async function isJtiRevoked(jti) {
112
+ try {
113
+ await ensureTable();
114
+ const client = getDbExec();
115
+ const { rows } = await client.execute({
116
+ sql: `SELECT revoked_at FROM mcp_connect_tokens WHERE jti = ?`,
117
+ args: [jti],
118
+ });
119
+ if (rows.length === 0)
120
+ return false;
121
+ const revokedAt = rows[0].revoked_at ?? rows[0].revokedAt;
122
+ return revokedAt != null;
123
+ }
124
+ catch (err) {
125
+ // Fail open: a DB blip must not turn every minted token into a 401.
126
+ // (Signature checks already passed; this only gates explicit revokes.)
127
+ if (isConnectionError(err))
128
+ return false;
129
+ return false;
130
+ }
131
+ }
132
+ export async function listTokens(ownerEmail) {
133
+ try {
134
+ await ensureTable();
135
+ const client = getDbExec();
136
+ const { rows } = await client.execute({
137
+ sql: `SELECT id, jti, owner_email, org_id, label, created_at, last_used_at, revoked_at FROM mcp_connect_tokens WHERE owner_email = ? ORDER BY created_at DESC`,
138
+ args: [ownerEmail],
139
+ });
140
+ return rows.map((r) => ({
141
+ id: r.id,
142
+ jti: r.jti,
143
+ ownerEmail: (r.owner_email ?? r.ownerEmail),
144
+ orgId: (r.org_id ?? r.orgId ?? null),
145
+ label: (r.label ?? null),
146
+ createdAt: numOrNull(r.created_at ?? r.createdAt),
147
+ lastUsedAt: numOrNull(r.last_used_at ?? r.lastUsedAt),
148
+ revokedAt: numOrNull(r.revoked_at ?? r.revokedAt),
149
+ }));
150
+ }
151
+ catch (err) {
152
+ if (isConnectionError(err))
153
+ return [];
154
+ throw err;
155
+ }
156
+ }
157
+ /**
158
+ * Revoke a token, but ONLY if it is owned by `ownerEmail` (the caller). The
159
+ * `owner_email = ?` predicate is the access scope — a caller can never revoke
160
+ * another user's token. Idempotent: re-revoking keeps the first timestamp.
161
+ * Returns true when a row was actually transitioned to revoked.
162
+ */
163
+ export async function revokeToken(ownerEmail, id) {
164
+ await ensureTable();
165
+ const client = getDbExec();
166
+ const result = await client.execute({
167
+ sql: `UPDATE mcp_connect_tokens SET revoked_at = ? WHERE id = ? AND owner_email = ? AND revoked_at IS NULL`,
168
+ args: [Date.now(), id, ownerEmail],
169
+ });
170
+ return result.rowsAffected > 0;
171
+ }
172
+ /**
173
+ * Best-effort: stamp `last_used_at` for a token. Swallows all errors — this is
174
+ * pure telemetry and must never affect the auth path.
175
+ */
176
+ export async function touchTokenUsed(jti) {
177
+ try {
178
+ await ensureTable();
179
+ const client = getDbExec();
180
+ await client.execute({
181
+ sql: `UPDATE mcp_connect_tokens SET last_used_at = ? WHERE jti = ?`,
182
+ args: [Date.now(), jti],
183
+ });
184
+ }
185
+ catch {
186
+ // last_used_at is informational only — never throw from the hot path.
187
+ }
188
+ }
189
+ const USER_CODE_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; // Crockford-ish base32, no 0/1/O/I
190
+ /** Crypto-random short human-typable code, formatted `XXXX-XXXX`. */
191
+ function generateUserCode() {
192
+ const bytes = randomBytes(8);
193
+ let out = "";
194
+ for (let i = 0; i < 8; i++) {
195
+ out += USER_CODE_ALPHABET[bytes[i] % USER_CODE_ALPHABET.length];
196
+ if (i === 3)
197
+ out += "-";
198
+ }
199
+ return out;
200
+ }
201
+ function generateDeviceCode() {
202
+ return randomBytes(32).toString("base64url");
203
+ }
204
+ /**
205
+ * Create a new device+user code pair. Rate-limited: at most
206
+ * `DEVICE_START_MAX` codes within `DEVICE_START_WINDOW_MS`. The window count
207
+ * is a coarse global cap (this endpoint is unauthenticated) — enough to stop
208
+ * table flooding / user-code brute force without per-IP plumbing.
209
+ *
210
+ * Throws `RATE_LIMITED` when the cap is exceeded so the route can map it to a
211
+ * 429.
212
+ */
213
+ export async function createDeviceCode() {
214
+ await ensureTable();
215
+ const client = getDbExec();
216
+ const now = Date.now();
217
+ try {
218
+ const { rows } = await client.execute({
219
+ sql: `SELECT COUNT(*) AS n FROM mcp_device_codes WHERE created_at > ?`,
220
+ args: [now - DEVICE_START_WINDOW_MS],
221
+ });
222
+ const n = Number(rows[0]?.n ?? rows[0]?.["COUNT(*)"] ?? 0);
223
+ if (Number.isFinite(n) && n >= DEVICE_START_MAX) {
224
+ throw new Error("RATE_LIMITED");
225
+ }
226
+ }
227
+ catch (err) {
228
+ if (err?.message === "RATE_LIMITED")
229
+ throw err;
230
+ // A read failure here should not block legitimate device starts — the
231
+ // single-use + short-TTL design is the primary protection. Continue.
232
+ }
233
+ const deviceCode = generateDeviceCode();
234
+ const userCode = generateUserCode();
235
+ const expiresAt = now + DEVICE_CODE_TTL_MS;
236
+ await client.execute({
237
+ sql: `INSERT INTO mcp_device_codes (device_code, user_code, owner_email, org_id, status, token_jti, created_at, expires_at, consumed_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
238
+ args: [
239
+ deviceCode,
240
+ userCode,
241
+ null,
242
+ null,
243
+ "pending",
244
+ null,
245
+ now,
246
+ expiresAt,
247
+ null,
248
+ ],
249
+ });
250
+ return {
251
+ deviceCode,
252
+ userCode,
253
+ ownerEmail: null,
254
+ orgId: null,
255
+ status: "pending",
256
+ tokenJti: null,
257
+ createdAt: now,
258
+ expiresAt,
259
+ consumedAt: null,
260
+ };
261
+ }
262
+ function mapDeviceRow(r) {
263
+ return {
264
+ deviceCode: (r.device_code ?? r.deviceCode),
265
+ userCode: (r.user_code ?? r.userCode),
266
+ ownerEmail: (r.owner_email ?? r.ownerEmail ?? null),
267
+ orgId: (r.org_id ?? r.orgId ?? null),
268
+ status: (r.status ?? "pending"),
269
+ tokenJti: (r.token_jti ?? r.tokenJti ?? null),
270
+ createdAt: numOrNull(r.created_at ?? r.createdAt),
271
+ expiresAt: numOrNull(r.expires_at ?? r.expiresAt),
272
+ consumedAt: numOrNull(r.consumed_at ?? r.consumedAt),
273
+ };
274
+ }
275
+ export async function getDeviceCode(deviceCode) {
276
+ try {
277
+ await ensureTable();
278
+ const client = getDbExec();
279
+ const { rows } = await client.execute({
280
+ sql: `SELECT * FROM mcp_device_codes WHERE device_code = ?`,
281
+ args: [deviceCode],
282
+ });
283
+ if (rows.length === 0)
284
+ return null;
285
+ return mapDeviceRow(rows[0]);
286
+ }
287
+ catch (err) {
288
+ if (isConnectionError(err))
289
+ return null;
290
+ throw err;
291
+ }
292
+ }
293
+ export async function getDeviceCodeByUserCode(userCode) {
294
+ try {
295
+ await ensureTable();
296
+ const client = getDbExec();
297
+ const { rows } = await client.execute({
298
+ sql: `SELECT * FROM mcp_device_codes WHERE user_code = ?`,
299
+ args: [userCode],
300
+ });
301
+ if (rows.length === 0)
302
+ return null;
303
+ return mapDeviceRow(rows[0]);
304
+ }
305
+ catch (err) {
306
+ if (isConnectionError(err))
307
+ return null;
308
+ throw err;
309
+ }
310
+ }
311
+ /**
312
+ * Bind the logged-in user (email + org) to a pending device code, identified
313
+ * by its human-typable `user_code`. Only transitions a non-expired, still
314
+ * `pending` row. Returns the bound row, or a string error code:
315
+ * - `not_found` — no such user_code
316
+ * - `expired` — past its TTL
317
+ * - `already` — already approved/consumed (not re-bindable)
318
+ */
319
+ export async function approveDeviceCode(userCode, ownerEmail, orgId) {
320
+ await ensureTable();
321
+ const client = getDbExec();
322
+ const row = await getDeviceCodeByUserCode(userCode);
323
+ if (!row)
324
+ return "not_found";
325
+ if ((row.expiresAt ?? 0) < Date.now())
326
+ return "expired";
327
+ if (row.status !== "pending")
328
+ return "already";
329
+ const result = await client.execute({
330
+ sql: `UPDATE mcp_device_codes SET status = 'approved', owner_email = ?, org_id = ? WHERE user_code = ? AND status = 'pending'`,
331
+ args: [ownerEmail, orgId, userCode],
332
+ });
333
+ if (result.rowsAffected === 0) {
334
+ // Lost a race with another approve — re-read to report the real state.
335
+ const fresh = await getDeviceCodeByUserCode(userCode);
336
+ return fresh && fresh.status !== "pending" ? "already" : "not_found";
337
+ }
338
+ return {
339
+ ...row,
340
+ status: "approved",
341
+ ownerEmail,
342
+ orgId,
343
+ };
344
+ }
345
+ /**
346
+ * Atomically transition an approved device code to consumed and stamp the
347
+ * minted token's jti. Single-use: only succeeds when the row is currently
348
+ * `approved` (not already consumed). Returns the pre-consume row on success,
349
+ * or null when it could not be consumed (already consumed / not approved /
350
+ * gone). The caller mints the token only after this returns a row.
351
+ */
352
+ export async function consumeDeviceCode(deviceCode, tokenJti) {
353
+ await ensureTable();
354
+ const client = getDbExec();
355
+ const row = await getDeviceCode(deviceCode);
356
+ if (!row)
357
+ return null;
358
+ if (row.status !== "approved")
359
+ return null;
360
+ const result = await client.execute({
361
+ sql: `UPDATE mcp_device_codes SET status = 'consumed', token_jti = ?, consumed_at = ? WHERE device_code = ? AND status = 'approved'`,
362
+ args: [tokenJti, Date.now(), deviceCode],
363
+ });
364
+ if (result.rowsAffected === 0)
365
+ return null; // lost the single-use race
366
+ return row;
367
+ }
368
+ /**
369
+ * Claim an approved device code for token minting without making it terminal.
370
+ * If signing or token recording fails, callers release this back to approved
371
+ * so the CLI can retry the poll instead of being stuck at "consumed".
372
+ */
373
+ export async function claimDeviceCodeForMint(deviceCode, tokenJti) {
374
+ await ensureTable();
375
+ const client = getDbExec();
376
+ const row = await getDeviceCode(deviceCode);
377
+ if (!row || row.status !== "approved")
378
+ return null;
379
+ const result = await client.execute({
380
+ sql: `UPDATE mcp_device_codes SET status = 'minting', token_jti = ?, consumed_at = ? WHERE device_code = ? AND status = 'approved'`,
381
+ args: [tokenJti, Date.now(), deviceCode],
382
+ });
383
+ if (result.rowsAffected === 0)
384
+ return null;
385
+ return row;
386
+ }
387
+ export async function finishDeviceCodeMint(deviceCode, tokenJti) {
388
+ await ensureTable();
389
+ const client = getDbExec();
390
+ const result = await client.execute({
391
+ sql: `UPDATE mcp_device_codes SET status = 'consumed' WHERE device_code = ? AND status = 'minting' AND token_jti = ?`,
392
+ args: [deviceCode, tokenJti],
393
+ });
394
+ return result.rowsAffected > 0;
395
+ }
396
+ export async function releaseDeviceCodeMint(deviceCode, tokenJti) {
397
+ try {
398
+ await ensureTable();
399
+ const client = getDbExec();
400
+ await client.execute({
401
+ sql: `UPDATE mcp_device_codes SET status = 'approved', token_jti = NULL, consumed_at = NULL WHERE device_code = ? AND status = 'minting' AND token_jti = ?`,
402
+ args: [deviceCode, tokenJti],
403
+ });
404
+ }
405
+ catch {
406
+ // The next poll will keep returning pending for a minting row until a
407
+ // later cleanup/retry path can observe or repair it. Do not throw here.
408
+ }
409
+ }
410
+ /**
411
+ * Best-effort: flip an expired, still-pending/approved row to `expired` so
412
+ * the poll endpoint can report a clean terminal state. Swallows errors.
413
+ */
414
+ export async function expireDeviceCode(deviceCode) {
415
+ try {
416
+ await ensureTable();
417
+ const client = getDbExec();
418
+ await client.execute({
419
+ sql: `UPDATE mcp_device_codes SET status = 'expired' WHERE device_code = ? AND status IN ('pending','approved')`,
420
+ args: [deviceCode],
421
+ });
422
+ }
423
+ catch {
424
+ // The poll handler already treats past-TTL rows as expired regardless of
425
+ // whether this housekeeping write lands.
426
+ }
427
+ }
428
+ function numOrNull(v) {
429
+ if (v == null)
430
+ return null;
431
+ const n = Number(v);
432
+ return Number.isFinite(n) ? n : null;
433
+ }
434
+ //# sourceMappingURL=connect-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect-store.js","sourceRoot":"","sources":["../../src/mcp/connect-store.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Framework-table store for the \"connect external agents\" feature.\n *\n * Two additive, dialect-agnostic tables back the browser **Connect** page and\n * the OAuth-style **device-code flow** a CLI drives:\n *\n * - `mcp_connect_tokens` — one row per minted MCP token. We never store the\n * token value (it's a signed JWT); only its `jti` so revocation is a\n * SQL lookup. Revoking sets `revoked_at`; the row is never deleted.\n * - `mcp_device_codes` — short-lived (10 min) device/user code pairs for\n * the OAuth 2.0 device-authorization-style CLI flow. Single-use\n * (`consumed_at`), rate-limited at creation.\n *\n * Mirrors `application-state/store.ts`: lazy `ensureTable()`, `getDbExec()`,\n * `isPostgres()` dialect branching for upserts, `isConnectionError()` swallow\n * so a transient Neon WS drop never 500s. `CREATE TABLE IF NOT EXISTS` only —\n * strictly additive, never DROP / ALTER (shared prod DB rule).\n */\n\nimport {\n getDbExec,\n isConnectionError,\n isPostgres,\n intType,\n} from \"../db/client.js\";\nimport { randomBytes, randomUUID } from \"node:crypto\";\n\nlet _initPromise: Promise<void> | undefined;\n\n/**\n * Scope claim that marks a connect-minted token (vs. an ordinary A2A\n * delegation JWT). Only tokens carrying this scope go through the revoke\n * lookup in `verifyAuth` — defined here so both `connect-route.ts` and\n * `build-server.ts` import it from the leaf store without a cycle.\n */\nexport const MCP_CONNECT_SCOPE = \"mcp-connect\";\n\n/** Device codes are valid for 10 minutes. */\nexport const DEVICE_CODE_TTL_MS = 10 * 60_000;\n\n/** Default minted-token lifetime. Configurable per-request 1–365 days. */\nexport const DEFAULT_TOKEN_TTL_DAYS = 90;\nexport const MIN_TOKEN_TTL_DAYS = 1;\nexport const MAX_TOKEN_TTL_DAYS = 365;\n\n/**\n * Rate limit for `device/start`: at most this many device codes may be created\n * within `DEVICE_START_WINDOW_MS`. Unauthenticated endpoint — keep it tight so\n * a hostile client can't flood the table or brute-force user codes.\n */\nexport const DEVICE_START_MAX = 20;\nexport const DEVICE_START_WINDOW_MS = 60_000;\n\nasync function ensureTable(): Promise<void> {\n if (!_initPromise) {\n _initPromise = (async () => {\n const client = getDbExec();\n // Additive only. Never DROP / ALTER — this DB is shared across every\n // deploy context (preview/branch/prod) for hosted templates.\n await client.execute(`\n CREATE TABLE IF NOT EXISTS mcp_connect_tokens (\n id TEXT PRIMARY KEY,\n jti TEXT UNIQUE NOT NULL,\n owner_email TEXT NOT NULL,\n org_id TEXT,\n label TEXT,\n created_at ${intType()},\n last_used_at ${intType()},\n revoked_at ${intType()}\n )\n `);\n await client.execute(`\n CREATE TABLE IF NOT EXISTS mcp_device_codes (\n device_code TEXT PRIMARY KEY,\n user_code TEXT NOT NULL,\n owner_email TEXT,\n org_id TEXT,\n status TEXT NOT NULL DEFAULT 'pending',\n token_jti TEXT,\n created_at ${intType()},\n expires_at ${intType()},\n consumed_at ${intType()}\n )\n `);\n })().catch((err) => {\n // Don't cache a rejected init. A transient DB blip should let the next\n // connect/mint/revoke call retry rather than wedging the process.\n _initPromise = undefined;\n throw err;\n });\n }\n return _initPromise;\n}\n\n// ---------------------------------------------------------------------------\n// Minted-token records\n// ---------------------------------------------------------------------------\n\nexport interface MintedTokenRow {\n id: string;\n jti: string;\n ownerEmail: string;\n orgId: string | null;\n label: string | null;\n createdAt: number | null;\n lastUsedAt: number | null;\n revokedAt: number | null;\n}\n\n/**\n * Persist a record of a minted token. The token value itself (a signed JWT)\n * is NEVER stored — only its `jti`, so revocation is a cheap SQL lookup.\n */\nexport async function recordMintedToken(params: {\n jti: string;\n ownerEmail: string;\n orgId?: string | null;\n label?: string | null;\n}): Promise<string> {\n await ensureTable();\n const client = getDbExec();\n const id = randomUUID();\n await client.execute({\n sql: `INSERT INTO mcp_connect_tokens (id, jti, owner_email, org_id, label, created_at, last_used_at, revoked_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,\n args: [\n id,\n params.jti,\n params.ownerEmail,\n params.orgId ?? null,\n params.label ?? null,\n Date.now(),\n null,\n null,\n ],\n });\n return id;\n}\n\n/**\n * Returns true when the given `jti` corresponds to a token that has been\n * revoked. Fails OPEN on a store/DB error: a transient Neon WS drop must not\n * lock every connected agent out. Signature verification is unaffected — this\n * is only the post-verify revoke check (see `verifyAuth` in build-server.ts).\n */\nexport async function isJtiRevoked(jti: string): Promise<boolean> {\n try {\n await ensureTable();\n const client = getDbExec();\n const { rows } = await client.execute({\n sql: `SELECT revoked_at FROM mcp_connect_tokens WHERE jti = ?`,\n args: [jti],\n });\n if (rows.length === 0) return false;\n const revokedAt = rows[0].revoked_at ?? rows[0].revokedAt;\n return revokedAt != null;\n } catch (err) {\n // Fail open: a DB blip must not turn every minted token into a 401.\n // (Signature checks already passed; this only gates explicit revokes.)\n if (isConnectionError(err)) return false;\n return false;\n }\n}\n\nexport async function listTokens(\n ownerEmail: string,\n): Promise<MintedTokenRow[]> {\n try {\n await ensureTable();\n const client = getDbExec();\n const { rows } = await client.execute({\n sql: `SELECT id, jti, owner_email, org_id, label, created_at, last_used_at, revoked_at FROM mcp_connect_tokens WHERE owner_email = ? ORDER BY created_at DESC`,\n args: [ownerEmail],\n });\n return rows.map((r: any) => ({\n id: r.id as string,\n jti: r.jti as string,\n ownerEmail: (r.owner_email ?? r.ownerEmail) as string,\n orgId: (r.org_id ?? r.orgId ?? null) as string | null,\n label: (r.label ?? null) as string | null,\n createdAt: numOrNull(r.created_at ?? r.createdAt),\n lastUsedAt: numOrNull(r.last_used_at ?? r.lastUsedAt),\n revokedAt: numOrNull(r.revoked_at ?? r.revokedAt),\n }));\n } catch (err) {\n if (isConnectionError(err)) return [];\n throw err;\n }\n}\n\n/**\n * Revoke a token, but ONLY if it is owned by `ownerEmail` (the caller). The\n * `owner_email = ?` predicate is the access scope — a caller can never revoke\n * another user's token. Idempotent: re-revoking keeps the first timestamp.\n * Returns true when a row was actually transitioned to revoked.\n */\nexport async function revokeToken(\n ownerEmail: string,\n id: string,\n): Promise<boolean> {\n await ensureTable();\n const client = getDbExec();\n const result = await client.execute({\n sql: `UPDATE mcp_connect_tokens SET revoked_at = ? WHERE id = ? AND owner_email = ? AND revoked_at IS NULL`,\n args: [Date.now(), id, ownerEmail],\n });\n return result.rowsAffected > 0;\n}\n\n/**\n * Best-effort: stamp `last_used_at` for a token. Swallows all errors — this is\n * pure telemetry and must never affect the auth path.\n */\nexport async function touchTokenUsed(jti: string): Promise<void> {\n try {\n await ensureTable();\n const client = getDbExec();\n await client.execute({\n sql: `UPDATE mcp_connect_tokens SET last_used_at = ? WHERE jti = ?`,\n args: [Date.now(), jti],\n });\n } catch {\n // last_used_at is informational only — never throw from the hot path.\n }\n}\n\n// ---------------------------------------------------------------------------\n// Device-code flow (OAuth 2.0 device-authorization style)\n// ---------------------------------------------------------------------------\n\nexport interface DeviceCodeRow {\n deviceCode: string;\n userCode: string;\n ownerEmail: string | null;\n orgId: string | null;\n status: \"pending\" | \"approved\" | \"minting\" | \"consumed\" | \"expired\";\n tokenJti: string | null;\n createdAt: number | null;\n expiresAt: number | null;\n consumedAt: number | null;\n}\n\nconst USER_CODE_ALPHABET = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567\"; // Crockford-ish base32, no 0/1/O/I\n\n/** Crypto-random short human-typable code, formatted `XXXX-XXXX`. */\nfunction generateUserCode(): string {\n const bytes = randomBytes(8);\n let out = \"\";\n for (let i = 0; i < 8; i++) {\n out += USER_CODE_ALPHABET[bytes[i] % USER_CODE_ALPHABET.length];\n if (i === 3) out += \"-\";\n }\n return out;\n}\n\nfunction generateDeviceCode(): string {\n return randomBytes(32).toString(\"base64url\");\n}\n\n/**\n * Create a new device+user code pair. Rate-limited: at most\n * `DEVICE_START_MAX` codes within `DEVICE_START_WINDOW_MS`. The window count\n * is a coarse global cap (this endpoint is unauthenticated) — enough to stop\n * table flooding / user-code brute force without per-IP plumbing.\n *\n * Throws `RATE_LIMITED` when the cap is exceeded so the route can map it to a\n * 429.\n */\nexport async function createDeviceCode(): Promise<DeviceCodeRow> {\n await ensureTable();\n const client = getDbExec();\n\n const now = Date.now();\n try {\n const { rows } = await client.execute({\n sql: `SELECT COUNT(*) AS n FROM mcp_device_codes WHERE created_at > ?`,\n args: [now - DEVICE_START_WINDOW_MS],\n });\n const n = Number(rows[0]?.n ?? rows[0]?.[\"COUNT(*)\"] ?? 0);\n if (Number.isFinite(n) && n >= DEVICE_START_MAX) {\n throw new Error(\"RATE_LIMITED\");\n }\n } catch (err: any) {\n if (err?.message === \"RATE_LIMITED\") throw err;\n // A read failure here should not block legitimate device starts — the\n // single-use + short-TTL design is the primary protection. Continue.\n }\n\n const deviceCode = generateDeviceCode();\n const userCode = generateUserCode();\n const expiresAt = now + DEVICE_CODE_TTL_MS;\n await client.execute({\n sql: `INSERT INTO mcp_device_codes (device_code, user_code, owner_email, org_id, status, token_jti, created_at, expires_at, consumed_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n args: [\n deviceCode,\n userCode,\n null,\n null,\n \"pending\",\n null,\n now,\n expiresAt,\n null,\n ],\n });\n return {\n deviceCode,\n userCode,\n ownerEmail: null,\n orgId: null,\n status: \"pending\",\n tokenJti: null,\n createdAt: now,\n expiresAt,\n consumedAt: null,\n };\n}\n\nfunction mapDeviceRow(r: any): DeviceCodeRow {\n return {\n deviceCode: (r.device_code ?? r.deviceCode) as string,\n userCode: (r.user_code ?? r.userCode) as string,\n ownerEmail: (r.owner_email ?? r.ownerEmail ?? null) as string | null,\n orgId: (r.org_id ?? r.orgId ?? null) as string | null,\n status: (r.status ?? \"pending\") as DeviceCodeRow[\"status\"],\n tokenJti: (r.token_jti ?? r.tokenJti ?? null) as string | null,\n createdAt: numOrNull(r.created_at ?? r.createdAt),\n expiresAt: numOrNull(r.expires_at ?? r.expiresAt),\n consumedAt: numOrNull(r.consumed_at ?? r.consumedAt),\n };\n}\n\nexport async function getDeviceCode(\n deviceCode: string,\n): Promise<DeviceCodeRow | null> {\n try {\n await ensureTable();\n const client = getDbExec();\n const { rows } = await client.execute({\n sql: `SELECT * FROM mcp_device_codes WHERE device_code = ?`,\n args: [deviceCode],\n });\n if (rows.length === 0) return null;\n return mapDeviceRow(rows[0]);\n } catch (err) {\n if (isConnectionError(err)) return null;\n throw err;\n }\n}\n\nexport async function getDeviceCodeByUserCode(\n userCode: string,\n): Promise<DeviceCodeRow | null> {\n try {\n await ensureTable();\n const client = getDbExec();\n const { rows } = await client.execute({\n sql: `SELECT * FROM mcp_device_codes WHERE user_code = ?`,\n args: [userCode],\n });\n if (rows.length === 0) return null;\n return mapDeviceRow(rows[0]);\n } catch (err) {\n if (isConnectionError(err)) return null;\n throw err;\n }\n}\n\n/**\n * Bind the logged-in user (email + org) to a pending device code, identified\n * by its human-typable `user_code`. Only transitions a non-expired, still\n * `pending` row. Returns the bound row, or a string error code:\n * - `not_found` — no such user_code\n * - `expired` — past its TTL\n * - `already` — already approved/consumed (not re-bindable)\n */\nexport async function approveDeviceCode(\n userCode: string,\n ownerEmail: string,\n orgId: string | null,\n): Promise<DeviceCodeRow | \"not_found\" | \"expired\" | \"already\"> {\n await ensureTable();\n const client = getDbExec();\n const row = await getDeviceCodeByUserCode(userCode);\n if (!row) return \"not_found\";\n if ((row.expiresAt ?? 0) < Date.now()) return \"expired\";\n if (row.status !== \"pending\") return \"already\";\n\n const result = await client.execute({\n sql: `UPDATE mcp_device_codes SET status = 'approved', owner_email = ?, org_id = ? WHERE user_code = ? AND status = 'pending'`,\n args: [ownerEmail, orgId, userCode],\n });\n if (result.rowsAffected === 0) {\n // Lost a race with another approve — re-read to report the real state.\n const fresh = await getDeviceCodeByUserCode(userCode);\n return fresh && fresh.status !== \"pending\" ? \"already\" : \"not_found\";\n }\n return {\n ...row,\n status: \"approved\",\n ownerEmail,\n orgId,\n };\n}\n\n/**\n * Atomically transition an approved device code to consumed and stamp the\n * minted token's jti. Single-use: only succeeds when the row is currently\n * `approved` (not already consumed). Returns the pre-consume row on success,\n * or null when it could not be consumed (already consumed / not approved /\n * gone). The caller mints the token only after this returns a row.\n */\nexport async function consumeDeviceCode(\n deviceCode: string,\n tokenJti: string,\n): Promise<DeviceCodeRow | null> {\n await ensureTable();\n const client = getDbExec();\n const row = await getDeviceCode(deviceCode);\n if (!row) return null;\n if (row.status !== \"approved\") return null;\n const result = await client.execute({\n sql: `UPDATE mcp_device_codes SET status = 'consumed', token_jti = ?, consumed_at = ? WHERE device_code = ? AND status = 'approved'`,\n args: [tokenJti, Date.now(), deviceCode],\n });\n if (result.rowsAffected === 0) return null; // lost the single-use race\n return row;\n}\n\n/**\n * Claim an approved device code for token minting without making it terminal.\n * If signing or token recording fails, callers release this back to approved\n * so the CLI can retry the poll instead of being stuck at \"consumed\".\n */\nexport async function claimDeviceCodeForMint(\n deviceCode: string,\n tokenJti: string,\n): Promise<DeviceCodeRow | null> {\n await ensureTable();\n const client = getDbExec();\n const row = await getDeviceCode(deviceCode);\n if (!row || row.status !== \"approved\") return null;\n const result = await client.execute({\n sql: `UPDATE mcp_device_codes SET status = 'minting', token_jti = ?, consumed_at = ? WHERE device_code = ? AND status = 'approved'`,\n args: [tokenJti, Date.now(), deviceCode],\n });\n if (result.rowsAffected === 0) return null;\n return row;\n}\n\nexport async function finishDeviceCodeMint(\n deviceCode: string,\n tokenJti: string,\n): Promise<boolean> {\n await ensureTable();\n const client = getDbExec();\n const result = await client.execute({\n sql: `UPDATE mcp_device_codes SET status = 'consumed' WHERE device_code = ? AND status = 'minting' AND token_jti = ?`,\n args: [deviceCode, tokenJti],\n });\n return result.rowsAffected > 0;\n}\n\nexport async function releaseDeviceCodeMint(\n deviceCode: string,\n tokenJti: string,\n): Promise<void> {\n try {\n await ensureTable();\n const client = getDbExec();\n await client.execute({\n sql: `UPDATE mcp_device_codes SET status = 'approved', token_jti = NULL, consumed_at = NULL WHERE device_code = ? AND status = 'minting' AND token_jti = ?`,\n args: [deviceCode, tokenJti],\n });\n } catch {\n // The next poll will keep returning pending for a minting row until a\n // later cleanup/retry path can observe or repair it. Do not throw here.\n }\n}\n\n/**\n * Best-effort: flip an expired, still-pending/approved row to `expired` so\n * the poll endpoint can report a clean terminal state. Swallows errors.\n */\nexport async function expireDeviceCode(deviceCode: string): Promise<void> {\n try {\n await ensureTable();\n const client = getDbExec();\n await client.execute({\n sql: `UPDATE mcp_device_codes SET status = 'expired' WHERE device_code = ? AND status IN ('pending','approved')`,\n args: [deviceCode],\n });\n } catch {\n // The poll handler already treats past-TTL rows as expired regardless of\n // whether this housekeeping write lands.\n }\n}\n\nfunction numOrNull(v: unknown): number | null {\n if (v == null) return null;\n const n = Number(v);\n return Number.isFinite(n) ? n : null;\n}\n"]}
@@ -178,6 +178,23 @@ export declare function safeReturnPath(raw: string | null | undefined): string;
178
178
  * proceeds. Mirrors the rawPath/getLoginHtml resolution in the auth guard.
179
179
  */
180
180
  export declare function getConfiguredLoginHtml(event: H3Event): string | null;
181
+ /**
182
+ * True only when the request originates from the local machine — the raw
183
+ * socket peer is `127.0.0.0/8`, `::1`, or the IPv4-mapped `::ffff:127.0.0.1`
184
+ * (an optional IPv6 zone id like `fe80::1%en0` is stripped first).
185
+ *
186
+ * `getRequestIP(event)` is called WITHOUT `{ xForwardedFor: true }`, so it
187
+ * returns the real connection peer and never an attacker-controlled
188
+ * `X-Forwarded-For` value — a remote client cannot spoof its way past this.
189
+ * Used to scope local-only conveniences (the desktop SSO broker and the dev
190
+ * auto-account) so a directly network-reachable dev server never exposes
191
+ * them to a remote visitor. NOTE: a reverse proxy / tunnel that connects to
192
+ * the dev server over localhost still appears as loopback, so this is a
193
+ * necessary but not sufficient gate — callers pair it with NODE_ENV and,
194
+ * for the dev account, a throwaway per-DB password.
195
+ */
196
+ export declare function isLoopbackAddress(ip: string | undefined): boolean;
197
+ export declare function isExpectedAuthFailure(error: unknown): boolean;
181
198
  /**
182
199
  * Create a new session in the legacy sessions table.
183
200
  * Used by google-oauth.ts for mobile deep linking.
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/server/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/server/auth.ts"],"names":[],"mappings":"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"}