feat: add OpenAI model support and harden OSS security defaults

This commit is contained in:
willchen96 2026-05-09 14:55:51 +08:00
parent adc2cf2370
commit bef75b082d
24 changed files with 1301 additions and 364 deletions

View file

@ -17,6 +17,10 @@ import { checkProjectAccess } from "../lib/access";
export const chatRouter = Router();
type Db = ReturnType<typeof createServerSupabase>;
const isDev = process.env.NODE_ENV !== "production";
const devLog = (...args: Parameters<typeof console.log>) => {
if (isDev) console.log(...args);
};
type AccessibleChat = {
id: string;
@ -436,7 +440,7 @@ chatRouter.post("/", requireAuth, async (req, res) => {
const project_id = parsedProjectId.projectId;
const model = parsedModel.model;
console.log("[chat/stream] incoming request", {
devLog("[chat/stream] incoming request", {
userId,
chat_id,
project_id,
@ -497,7 +501,7 @@ chatRouter.post("/", requireAuth, async (req, res) => {
chatTitle = newChat.title;
}
console.log("[chat/stream] resolved chatId", chatId);
devLog("[chat/stream] resolved chatId", chatId);
const lastUser = [...messages].reverse().find((m) => m.role === "user");
if (lastUser) {
@ -530,7 +534,7 @@ chatRouter.post("/", requireAuth, async (req, res) => {
const workflowStore = await buildWorkflowStore(userId, userEmail, db);
console.log("[chat/stream] starting LLM stream", {
devLog("[chat/stream] starting LLM stream", {
apiMessageCount: apiMessages.length,
docCount: Object.keys(docIndex).length,
workflowCount: Object.keys(workflowStore).length,
@ -562,7 +566,7 @@ chatRouter.post("/", requireAuth, async (req, res) => {
projectId: resolvedProjectId,
});
console.log("[chat/stream] LLM stream finished", {
devLog("[chat/stream] LLM stream finished", {
fullTextLen: fullText?.length ?? 0,
eventCount: events?.length ?? 0,
});

View file

@ -3,7 +3,9 @@ import { requireAuth } from "../middleware/auth";
import { createServerSupabase } from "../lib/supabase";
import { DEFAULT_TABULAR_MODEL, resolveModel } from "../lib/llm";
import {
type ApiKeyStatus,
getUserApiKeyStatus,
hasEnvApiKey,
normalizeApiKeyProvider,
saveUserApiKey,
} from "../lib/userApiKeys";
@ -23,7 +25,7 @@ type UserProfileRow = {
function serializeProfile(
row: UserProfileRow,
apiKeyStatus?: { claude: boolean; gemini: boolean },
apiKeyStatus?: ApiKeyStatus,
) {
const creditsUsed = row.message_credits_used ?? 0;
return {
@ -233,6 +235,12 @@ userRouter.put("/api-keys/:provider", requireAuth, async (req, res) => {
typeof req.body?.api_key === "string" ? req.body.api_key : null;
const db = createServerSupabase();
try {
if (hasEnvApiKey(provider)) {
return void res.status(409).json({
detail:
"This provider is configured by the server environment and cannot be changed from the browser.",
});
}
await saveUserApiKey(userId, provider, apiKey, db);
const status = await getUserApiKeyStatus(userId, db);
res.json(status);