diff --git a/package-lock.json b/package-lock.json index 6d46c12..4c68613 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,17 +1,18 @@ { - "name": "eterna", + "name": "@eterna-hybrid-exchange/cli", "version": "0.3.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "eterna", + "name": "@eterna-hybrid-exchange/cli", "version": "0.3.0", "license": "MIT", "dependencies": { "commander": "^13.0.0", "open": "^10.0.0", - "ora": "^8.0.0" + "ora": "^8.0.0", + "zod": "^4.3.6" }, "bin": { "eterna": "dist/cli.js" @@ -3846,6 +3847,15 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zod": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", + "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } } } diff --git a/package.json b/package.json index 39b6387..1d0b5e3 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,8 @@ "dependencies": { "commander": "^13.0.0", "open": "^10.0.0", - "ora": "^8.0.0" + "ora": "^8.0.0", + "zod": "^4.3.6" }, "devDependencies": { "@eslint/js": "^9.39.4", diff --git a/src/auth/link-legacy-key.ts b/src/auth/link-legacy-key.ts index 8fed5c1..2f7a056 100644 --- a/src/auth/link-legacy-key.ts +++ b/src/auth/link-legacy-key.ts @@ -1,10 +1,7 @@ import { getMcpEndpoint } from "./config.js"; +import { LinkResultSchema } from "./validation.js"; -interface LinkResult { - linked: boolean; - agentName: string; - bybitSubMemberId: string | null; -} +const LINK_TIMEOUT_MS = 10_000; /** * Links a legacy mcp-gateway API key to the caller's OAuth identity. @@ -28,6 +25,7 @@ export async function linkLegacyKey( "Content-Type": "application/json", }, body: JSON.stringify({ legacyApiKey }), + signal: AbortSignal.timeout(LINK_TIMEOUT_MS), }); } catch { console.warn( @@ -37,8 +35,14 @@ export async function linkLegacyKey( } if (res.ok) { - const data = (await res.json()) as LinkResult; - if (data.linked) { + const result = LinkResultSchema.safeParse(await res.json()); + if (!result.success) { + console.warn( + "Warning: Unexpected response from mcp-gateway link endpoint", + ); + return; + } + if (result.data.linked) { console.log( `✓ Legacy account linked — existing Bybit subaccount preserved`, ); diff --git a/src/auth/validation.ts b/src/auth/validation.ts new file mode 100644 index 0000000..2111441 --- /dev/null +++ b/src/auth/validation.ts @@ -0,0 +1,9 @@ +import { z } from "zod"; + +export const LinkResultSchema = z.object({ + linked: z.boolean(), + agentName: z.string(), + bybitSubMemberId: z.string().nullable(), +}); + +export type LinkResult = z.infer;