diff --git a/.gitignore b/.gitignore index f2a0ff389c..8203e413df 100644 --- a/.gitignore +++ b/.gitignore @@ -85,3 +85,6 @@ blob-report/ cloud/ omnirouteCloud/ omnirouteSite/ + +# Security Analysis (standalone project with own git) +security-analysis/ diff --git a/src/app/api/cli-tools/claude-settings/route.ts b/src/app/api/cli-tools/claude-settings/route.ts index c0d8ba8240..87f898bcc5 100644 --- a/src/app/api/cli-tools/claude-settings/route.ts +++ b/src/app/api/cli-tools/claude-settings/route.ts @@ -19,7 +19,7 @@ const readSettings = async () => { const settingsPath = getClaudeSettingsPath(); const content = await fs.readFile(settingsPath, "utf-8"); return JSON.parse(content); - } catch (error) { + } catch (error: any) { if (error.code === "ENOENT") { return null; } @@ -69,7 +69,7 @@ export async function GET() { } // POST - Backup old fields and write new settings -export async function POST(request) { +export async function POST(request: Request) { try { const writeGuard = ensureCliConfigWriteAllowed(); if (writeGuard) { @@ -92,11 +92,11 @@ export async function POST(request) { await createBackup("claude", settingsPath); // Read current settings - let currentSettings = {}; + let currentSettings: Record = {}; try { const content = await fs.readFile(settingsPath, "utf-8"); currentSettings = JSON.parse(content); - } catch (error) { + } catch (error: any) { if (error.code !== "ENOENT") { throw error; } @@ -152,11 +152,11 @@ export async function DELETE() { const settingsPath = getClaudeSettingsPath(); // Read current settings - let currentSettings = {}; + let currentSettings: Record = {}; try { const content = await fs.readFile(settingsPath, "utf-8"); currentSettings = JSON.parse(content); - } catch (error) { + } catch (error: any) { if (error.code === "ENOENT") { return NextResponse.json({ success: true, diff --git a/src/app/api/cli-tools/cline-settings/route.ts b/src/app/api/cli-tools/cline-settings/route.ts index 650737ea0d..03e397c1af 100644 --- a/src/app/api/cli-tools/cline-settings/route.ts +++ b/src/app/api/cli-tools/cline-settings/route.ts @@ -16,7 +16,7 @@ const readGlobalState = async () => { try { const content = await fs.readFile(GLOBAL_STATE_PATH, "utf-8"); return JSON.parse(content); - } catch (error) { + } catch (error: any) { if (error.code === "ENOENT") return null; throw error; } @@ -27,14 +27,14 @@ const readSecrets = async () => { try { const content = await fs.readFile(SECRETS_PATH, "utf-8"); return JSON.parse(content); - } catch (error) { + } catch (error: any) { if (error.code === "ENOENT") return {}; throw error; } }; // Check if OmniRoute is configured as OpenAI-compatible provider -const hasOmniRouteConfig = (globalState) => { +const hasOmniRouteConfig = (globalState: any) => { if (!globalState) return false; const isOpenAi = globalState.actModeApiProvider === "openai" || globalState.planModeApiProvider === "openai"; @@ -96,7 +96,7 @@ export async function GET() { } // POST - Configure Cline to use OmniRoute as OpenAI-compatible provider -export async function POST(request) { +export async function POST(request: Request) { try { const writeGuard = ensureCliConfigWriteAllowed(); if (writeGuard) { @@ -117,7 +117,7 @@ export async function POST(request) { await createBackup("cline", SECRETS_PATH); // Read existing globalState or create new - let globalState = {}; + let globalState: Record = {}; try { const existing = await fs.readFile(GLOBAL_STATE_PATH, "utf-8"); globalState = JSON.parse(existing); @@ -139,7 +139,7 @@ export async function POST(request) { await fs.writeFile(GLOBAL_STATE_PATH, JSON.stringify(globalState, null, 2)); // Write API key to secrets - let secrets = {}; + let secrets: Record = {}; try { const existing = await fs.readFile(SECRETS_PATH, "utf-8"); secrets = JSON.parse(existing); @@ -175,11 +175,11 @@ export async function DELETE() { await createBackup("cline", SECRETS_PATH); // Read existing state - let globalState = {}; + let globalState: Record = {}; try { const existing = await fs.readFile(GLOBAL_STATE_PATH, "utf-8"); globalState = JSON.parse(existing); - } catch (error) { + } catch (error: any) { if (error.code === "ENOENT") { return NextResponse.json({ success: true, message: "No settings file to reset" }); } @@ -199,7 +199,7 @@ export async function DELETE() { await fs.writeFile(GLOBAL_STATE_PATH, JSON.stringify(globalState, null, 2)); // Remove API key from secrets - let secrets = {}; + let secrets: Record = {}; try { const existing = await fs.readFile(SECRETS_PATH, "utf-8"); secrets = JSON.parse(existing); diff --git a/src/app/api/cli-tools/codex-settings/route.ts b/src/app/api/cli-tools/codex-settings/route.ts index 7421d289e1..dd799d992f 100644 --- a/src/app/api/cli-tools/codex-settings/route.ts +++ b/src/app/api/cli-tools/codex-settings/route.ts @@ -15,8 +15,8 @@ const getCodexAuthPath = () => getCliConfigPaths("codex").auth; const getCodexDir = () => path.dirname(getCodexConfigPath()); // Parse TOML config to object (simple parser for codex config) -const parseToml = (content) => { - const result = { _root: {}, _sections: {} }; +const parseToml = (content: string) => { + const result: Record = { _root: {}, _sections: {} }; let currentSection = "_root"; content.split("\n").forEach((line) => { @@ -55,8 +55,8 @@ const parseToml = (content) => { }; // Convert parsed object back to TOML string -const toToml = (parsed) => { - let lines = []; +const toToml = (parsed: Record) => { + let lines: string[] = []; // Root level keys Object.entries(parsed._root).forEach(([key, value]) => { @@ -81,14 +81,14 @@ const readConfig = async () => { const configPath = getCodexConfigPath(); const content = await fs.readFile(configPath, "utf-8"); return content; - } catch (error) { + } catch (error: any) { if (error.code === "ENOENT") return null; throw error; } }; // Check if config has OmniRoute settings -const hasOmniRouteConfig = (config) => { +const hasOmniRouteConfig = (config: string | null) => { if (!config) return false; return ( config.includes('model_provider = "omniroute"') || @@ -137,7 +137,7 @@ export async function GET() { } // POST - Update OmniRoute settings (merge with existing config) -export async function POST(request) { +export async function POST(request: Request) { try { const writeGuard = ensureCliConfigWriteAllowed(); if (writeGuard) { @@ -164,7 +164,7 @@ export async function POST(request) { await createMultiBackup("codex", [configPath, authPath]); // Read and parse existing config - let parsed = { _root: {}, _sections: {} }; + let parsed: Record = { _root: {}, _sections: {} }; try { const existingConfig = await fs.readFile(configPath, "utf-8"); parsed = parseToml(existingConfig); @@ -190,7 +190,7 @@ export async function POST(request) { await fs.writeFile(configPath, configContent); // Update auth.json with OPENAI_API_KEY (Codex reads this first) - let authData = {}; + let authData: Record = {}; try { const existingAuth = await fs.readFile(authPath, "utf-8"); authData = JSON.parse(existingAuth); @@ -226,11 +226,11 @@ export async function DELETE() { await createMultiBackup("codex", [configPath, getCodexAuthPath()]); // Read and parse existing config - let parsed = { _root: {}, _sections: {} }; + let parsed: Record = { _root: {}, _sections: {} }; try { const existingConfig = await fs.readFile(configPath, "utf-8"); parsed = parseToml(existingConfig); - } catch (error) { + } catch (error: any) { if (error.code === "ENOENT") { return NextResponse.json({ success: true, diff --git a/src/app/api/cli-tools/droid-settings/route.ts b/src/app/api/cli-tools/droid-settings/route.ts index f7c220b8d1..e95f95f4c9 100644 --- a/src/app/api/cli-tools/droid-settings/route.ts +++ b/src/app/api/cli-tools/droid-settings/route.ts @@ -19,14 +19,14 @@ const readSettings = async () => { const settingsPath = getDroidSettingsPath(); const content = await fs.readFile(settingsPath, "utf-8"); return JSON.parse(content); - } catch (error) { + } catch (error: any) { if (error.code === "ENOENT") return null; throw error; } }; // Check if settings has OmniRoute customModels -const hasOmniRouteConfig = (settings) => { +const hasOmniRouteConfig = (settings: any) => { if (!settings || !settings.customModels) return false; return settings.customModels.some((m) => m.id === "custom:OmniRoute-0"); }; @@ -72,7 +72,7 @@ export async function GET() { } // POST - Update OmniRoute customModels (merge with existing settings) -export async function POST(request) { +export async function POST(request: Request) { try { const writeGuard = ensureCliConfigWriteAllowed(); if (writeGuard) { @@ -95,7 +95,7 @@ export async function POST(request) { await createBackup("droid", settingsPath); // Read existing settings or create new - let settings = {}; + let settings: Record = {}; try { const existingSettings = await fs.readFile(settingsPath, "utf-8"); settings = JSON.parse(existingSettings); @@ -157,11 +157,11 @@ export async function DELETE() { await createBackup("droid", settingsPath); // Read existing settings - let settings = {}; + let settings: Record = {}; try { const existingSettings = await fs.readFile(settingsPath, "utf-8"); settings = JSON.parse(existingSettings); - } catch (error) { + } catch (error: any) { if (error.code === "ENOENT") { return NextResponse.json({ success: true, diff --git a/src/app/api/cli-tools/openclaw-settings/route.ts b/src/app/api/cli-tools/openclaw-settings/route.ts index 2b91502575..1b9004c22d 100644 --- a/src/app/api/cli-tools/openclaw-settings/route.ts +++ b/src/app/api/cli-tools/openclaw-settings/route.ts @@ -19,14 +19,14 @@ const readSettings = async () => { const settingsPath = getOpenClawSettingsPath(); const content = await fs.readFile(settingsPath, "utf-8"); return JSON.parse(content); - } catch (error) { + } catch (error: any) { if (error.code === "ENOENT") return null; throw error; } }; // Check if settings has OmniRoute config -const hasOmniRouteConfig = (settings) => { +const hasOmniRouteConfig = (settings: any) => { if (!settings || !settings.models || !settings.models.providers) return false; return !!settings.models.providers["omniroute"]; }; @@ -72,7 +72,7 @@ export async function GET() { } // POST - Update OmniRoute settings (merge with existing settings) -export async function POST(request) { +export async function POST(request: Request) { try { const writeGuard = ensureCliConfigWriteAllowed(); if (writeGuard) { @@ -95,7 +95,7 @@ export async function POST(request) { await createBackup("openclaw", settingsPath); // Read existing settings or create new - let settings = {}; + let settings: Record = {}; try { const existingSettings = await fs.readFile(settingsPath, "utf-8"); settings = JSON.parse(existingSettings); @@ -157,11 +157,11 @@ export async function DELETE() { await createBackup("openclaw", settingsPath); // Read existing settings - let settings = {}; + let settings: Record = {}; try { const existingSettings = await fs.readFile(settingsPath, "utf-8"); settings = JSON.parse(existingSettings); - } catch (error) { + } catch (error: any) { if (error.code === "ENOENT") { return NextResponse.json({ success: true, diff --git a/src/app/api/oauth/[provider]/[action]/route.ts b/src/app/api/oauth/[provider]/[action]/route.ts index 68b939e9ab..33899779b6 100644 --- a/src/app/api/oauth/[provider]/[action]/route.ts +++ b/src/app/api/oauth/[provider]/[action]/route.ts @@ -23,7 +23,7 @@ if (!globalThis.__codexCallbackState) { // GET /api/oauth/[provider]/authorize - Generate auth URL // GET /api/oauth/[provider]/device-code - Request device code (for device_code flow) -export async function GET(request, { params }) { +export async function GET(request: Request, { params }: { params: Promise<{ provider: string; action: string }> }) { try { const { provider, action } = await params; const { searchParams } = new URL(request.url); @@ -68,7 +68,7 @@ export async function GET(request, { params }) { return NextResponse.json({ error: "Unknown action" }, { status: 400 }); } catch (error) { console.log("OAuth GET error:", error); - return NextResponse.json({ error: error.message }, { status: 500 }); + return NextResponse.json({ error: (error as any).message }, { status: 500 }); } } @@ -76,7 +76,7 @@ export async function GET(request, { params }) { * Start Codex callback server on port 1455 * Returns the auth URL and stores codeVerifier for later exchange */ -async function handleStartCallbackServer(provider, searchParams) { +async function handleStartCallbackServer(provider: string, searchParams: URLSearchParams) { if (provider !== "codex") { return NextResponse.json( { error: "Callback server only supported for codex" }, @@ -135,13 +135,13 @@ async function handleStartCallbackServer(provider, searchParams) { serverPort: port, }); } catch (error) { - return NextResponse.json({ error: error.message }, { status: 500 }); + return NextResponse.json({ error: (error as any).message }, { status: 500 }); } } // POST /api/oauth/[provider]/exchange - Exchange code for tokens and save // POST /api/oauth/[provider]/poll - Poll for token (device_code flow) -export async function POST(request, { params }) { +export async function POST(request: Request, { params }: { params: Promise<{ provider: string; action: string }> }) { try { const { provider, action } = await params; const body = await request.json(); @@ -320,7 +320,7 @@ export async function POST(request, { params }) { displayName: connection.displayName, }, }); - } catch (exchangeErr) { + } catch (exchangeErr: any) { return NextResponse.json({ success: false, error: exchangeErr.message }, { status: 500 }); } } @@ -328,7 +328,7 @@ export async function POST(request, { params }) { return NextResponse.json({ error: "Unknown action" }, { status: 400 }); } catch (error) { console.log("OAuth POST error:", error); - return NextResponse.json({ error: error.message }, { status: 500 }); + return NextResponse.json({ error: (error as any).message }, { status: 500 }); } } diff --git a/src/app/api/providers/[id]/route.ts b/src/app/api/providers/[id]/route.ts index 96300ace68..376c823521 100644 --- a/src/app/api/providers/[id]/route.ts +++ b/src/app/api/providers/[id]/route.ts @@ -9,7 +9,7 @@ import { getConsistentMachineId } from "@/shared/utils/machineId"; import { syncToCloud } from "@/lib/cloudSync"; // GET /api/providers/[id] - Get single connection -export async function GET(request, { params }) { +export async function GET(request: Request, { params }: { params: Promise<{ id: string }> }) { try { const { id } = await params; const connection = await getProviderConnectionById(id); @@ -19,7 +19,7 @@ export async function GET(request, { params }) { } // Hide sensitive fields - const result = { ...connection }; + const result: Record = { ...connection }; delete result.apiKey; delete result.accessToken; delete result.refreshToken; @@ -33,7 +33,7 @@ export async function GET(request, { params }) { } // PUT /api/providers/[id] - Update connection -export async function PUT(request, { params }) { +export async function PUT(request: Request, { params }: { params: Promise<{ id: string }> }) { try { const { id } = await params; const body = await request.json(); @@ -60,7 +60,7 @@ export async function PUT(request, { params }) { return NextResponse.json({ error: "Connection not found" }, { status: 404 }); } - const updateData = {}; + const updateData: Record = {}; if (name !== undefined) updateData.name = name; if (priority !== undefined) updateData.priority = priority; if (globalPriority !== undefined) updateData.globalPriority = globalPriority; @@ -80,7 +80,7 @@ export async function PUT(request, { params }) { const updated = await updateProviderConnection(id, updateData); // Hide sensitive fields - const result = { ...updated }; + const result: Record = { ...updated }; delete result.apiKey; delete result.accessToken; delete result.refreshToken; @@ -97,7 +97,7 @@ export async function PUT(request, { params }) { } // DELETE /api/providers/[id] - Delete connection -export async function DELETE(request, { params }) { +export async function DELETE(request: Request, { params }: { params: Promise<{ id: string }> }) { try { const { id } = await params;