fix(security): resolve CodeQL random/password-hash alerts and sync docs & tests

This commit is contained in:
diegosouzapw
2026-05-20 01:59:36 -03:00
parent 78c344b3a2
commit 5735b4d4db
7 changed files with 20 additions and 15 deletions

View File

@@ -17,7 +17,7 @@ It provides a single OpenAI-compatible endpoint (`/v1/*`) and routes traffic acr
Core capabilities:
- OpenAI-compatible API surface for CLI/tools (177 providers, 31 executors)
- OpenAI-compatible API surface for CLI/tools (177 providers, 38 executors)
- Request/response translation across provider formats
- Model combo fallback (multi-model sequence)
- Structured combo steps (`provider + model + connection`) with runtime ordering by `compositeTiers`

View File

@@ -411,7 +411,7 @@ open-sse/
├── types.d.ts
├── config/ Provider registries, header profiles, identity, …
├── handlers/ Request handlers (chat, embeddings, audio, image, …)
├── executors/ 31 provider-specific HTTP executors
├── executors/ 38 provider-specific HTTP executors
├── translator/ Format conversion (OpenAI ↔ Claude ↔ Gemini ↔ Cursor ↔ Kiro)
├── transformer/ Responses API ↔ Chat Completions stream transformer
├── services/ 80+ service modules (combos, fallback, quotas, identity, …)
@@ -441,7 +441,7 @@ open-sse/
### 4.2 `open-sse/executors/`
31 provider executors, each extending `BaseExecutor` (`base.ts`):
38 provider executors, each extending `BaseExecutor` (`base.ts`):
`antigravity`, `azure-openai`, `blackbox-web`, `chatgpt-web`, `cliproxyapi`,
`cloudflare-ai`, `codex`, `commandCode`, `cursor`, `default`, `devin-cli`,

View File

@@ -1,6 +1,7 @@
import { NextRequest, NextResponse } from "next/server";
import { CORS_HEADERS, handleCorsOptions } from "@/shared/utils/cors";
import { type LeaderboardScope, getTopN } from "@/lib/gamification/leaderboard";
import crypto from "crypto";
export async function OPTIONS() {
return handleCorsOptions();
@@ -22,8 +23,9 @@ export async function GET(request: NextRequest) {
}
const token = authHeader.slice(7);
const crypto = await import("crypto");
const tokenHash = crypto.createHash("sha256").update(token).digest("hex");
const tokenHash = crypto
.pbkdf2Sync(token, "omniroute-federation-salt", 1000, 32, "sha256")
.toString("hex");
const { getDbInstance } = await import("@/lib/db/core");
const db = getDbInstance();
const server = db

View File

@@ -2,6 +2,7 @@ import { NextRequest, NextResponse } from "next/server";
import { CORS_HEADERS, handleCorsOptions } from "@/shared/utils/cors";
import { updateScore } from "@/lib/gamification/leaderboard";
import { z } from "zod";
import crypto from "crypto";
export async function OPTIONS() {
return handleCorsOptions();
@@ -19,10 +20,10 @@ export async function POST(request: NextRequest) {
);
}
// Validate token against connected community servers
const token = authHeader.slice(7);
const crypto = await import("crypto");
const tokenHash = crypto.createHash("sha256").update(token).digest("hex");
const tokenHash = crypto
.pbkdf2Sync(token, "omniroute-federation-salt", 1000, 32, "sha256")
.toString("hex");
const { getDbInstance } = await import("@/lib/db/core");
const db = getDbInstance();
const server = db

View File

@@ -12,9 +12,8 @@ import crypto from "crypto";
function generateInviteCode(): string {
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
let code = "";
const bytes = crypto.randomBytes(8);
for (let i = 0; i < 8; i++) {
code += chars[bytes[i] % chars.length];
code += chars[crypto.randomInt(0, chars.length)];
}
return code;
}

View File

@@ -24,7 +24,9 @@ export async function connectServer(
apiKey: string
): Promise<ServerConnection> {
const id = crypto.randomUUID();
const apiKeyHash = crypto.createHash("sha256").update(apiKey).digest("hex");
const apiKeyHash = crypto
.pbkdf2Sync(apiKey, "omniroute-federation-salt", 1000, 32, "sha256")
.toString("hex");
const { connectServer: dbConnect } = await import("../db/gamification");
dbConnect(id, name, url, apiKeyHash);

View File

@@ -136,14 +136,15 @@ test("intelligent combo selection defaults only inside the intelligent filter",
test("sidebar visibility excludes the removed auto-combo item", async () => {
const sidebarVisibility = await import("../../src/shared/constants/sidebarVisibility.ts");
const primarySection = sidebarVisibility.SIDEBAR_SECTIONS.find(
(section) => section.id === "primary"
const omniProxySection = sidebarVisibility.SIDEBAR_SECTIONS.find(
(section) => section.id === "omni-proxy"
);
assert.equal(sidebarVisibility.HIDEABLE_SIDEBAR_ITEM_IDS.includes("auto-combo"), false);
assert.ok(primarySection);
assert.ok(omniProxySection);
const items = sidebarVisibility.getSectionItems(omniProxySection);
assert.equal(
primarySection.items.some((item) => item.id === "auto-combo"),
items.some((item) => item.id === "auto-combo"),
false
);
assert.deepEqual(sidebarVisibility.normalizeHiddenSidebarItems(["auto-combo", "home"]), ["home"]);