import path from "path" import fs from "fs/promises" import z from "zod" import { Global } from "../global" export namespace McpAuth { export const Tokens = z.object({ accessToken: z.string(), refreshToken: z.string().optional(), expiresAt: z.number().optional(), scope: z.string().optional(), }) export type Tokens = z.infer export const ClientInfo = z.object({ clientId: z.string(), clientSecret: z.string().optional(), clientIdIssuedAt: z.number().optional(), clientSecretExpiresAt: z.number().optional(), }) export type ClientInfo = z.infer export const Entry = z.object({ tokens: Tokens.optional(), clientInfo: ClientInfo.optional(), codeVerifier: z.string().optional(), }) export type Entry = z.infer const filepath = path.join(Global.Path.data, "mcp-auth.json") export async function get(mcpName: string): Promise { const data = await all() return data[mcpName] } export async function all(): Promise> { const file = Bun.file(filepath) return file.json().catch(() => ({})) } export async function set(mcpName: string, entry: Entry): Promise { const file = Bun.file(filepath) const data = await all() await Bun.write(file, JSON.stringify({ ...data, [mcpName]: entry }, null, 2)) await fs.chmod(file.name!, 0o600) } export async function remove(mcpName: string): Promise { const file = Bun.file(filepath) const data = await all() delete data[mcpName] await Bun.write(file, JSON.stringify(data, null, 2)) await fs.chmod(file.name!, 0o600) } export async function updateTokens(mcpName: string, tokens: Tokens): Promise { const entry = (await get(mcpName)) ?? {} entry.tokens = tokens await set(mcpName, entry) } export async function updateClientInfo(mcpName: string, clientInfo: ClientInfo): Promise { const entry = (await get(mcpName)) ?? {} entry.clientInfo = clientInfo await set(mcpName, entry) } export async function updateCodeVerifier(mcpName: string, codeVerifier: string): Promise { const entry = (await get(mcpName)) ?? {} entry.codeVerifier = codeVerifier await set(mcpName, entry) } export async function clearCodeVerifier(mcpName: string): Promise { const entry = await get(mcpName) if (entry) { delete entry.codeVerifier await set(mcpName, entry) } } }