Add api key and sorting on scoreboard

This commit is contained in:
Joey Yakimowich-Payne 2026-01-15 14:49:10 -07:00
commit 4688a73559
No known key found for this signature in database
GPG key ID: 6BFE655FA5ABD1E1
14 changed files with 791 additions and 227 deletions

View file

@ -90,6 +90,24 @@ const runMigrations = () => {
db.exec("ALTER TABLE users ADD COLUMN openrouter_model TEXT");
console.log("Migration: Added openrouter_model to users");
}
const hasOpenAIKey = userTableInfo2.some(col => col.name === "openai_api_key");
if (!hasOpenAIKey) {
db.exec("ALTER TABLE users ADD COLUMN openai_api_key TEXT");
console.log("Migration: Added openai_api_key to users");
}
const hasOpenAIModel = userTableInfo2.some(col => col.name === "openai_model");
if (!hasOpenAIModel) {
db.exec("ALTER TABLE users ADD COLUMN openai_model TEXT");
console.log("Migration: Added openai_model to users");
}
const hasGeminiModel = userTableInfo2.some(col => col.name === "gemini_model");
if (!hasGeminiModel) {
db.exec("ALTER TABLE users ADD COLUMN gemini_model TEXT");
console.log("Migration: Added gemini_model to users");
}
};
runMigrations();

View file

@ -106,16 +106,20 @@ router.get('/me/preferences', (req: AuthenticatedRequest, res: Response) => {
const user = db.prepare(`
SELECT color_scheme as colorScheme, gemini_api_key as geminiApiKey,
ai_provider as aiProvider, openrouter_api_key as openRouterApiKey,
openrouter_model as openRouterModel
gemini_model as geminiModel, ai_provider as aiProvider,
openrouter_api_key as openRouterApiKey, openrouter_model as openRouterModel,
openai_api_key as openAIApiKey, openai_model as openAIModel
FROM users
WHERE id = ?
`).get(userSub) as {
colorScheme: string | null;
geminiApiKey: string | null;
geminiModel: string | null;
aiProvider: string | null;
openRouterApiKey: string | null;
openRouterModel: string | null;
openAIApiKey: string | null;
openAIModel: string | null;
} | undefined;
const groups = req.user!.groups || [];
@ -125,30 +129,37 @@ router.get('/me/preferences', (req: AuthenticatedRequest, res: Response) => {
colorScheme: user?.colorScheme || 'blue',
aiProvider: user?.aiProvider || 'gemini',
geminiApiKey: decryptForUser(user?.geminiApiKey || null, userSub),
geminiModel: user?.geminiModel || null,
openRouterApiKey: decryptForUser(user?.openRouterApiKey || null, userSub),
openRouterModel: user?.openRouterModel || null,
openAIApiKey: decryptForUser(user?.openAIApiKey || null, userSub),
openAIModel: user?.openAIModel || null,
hasAIAccess,
});
});
router.put('/me/preferences', (req: AuthenticatedRequest, res: Response) => {
const userSub = req.user!.sub;
const { colorScheme, geminiApiKey, aiProvider, openRouterApiKey, openRouterModel } = req.body;
const { colorScheme, geminiApiKey, geminiModel, aiProvider, openRouterApiKey, openRouterModel, openAIApiKey, openAIModel } = req.body;
const encryptedGeminiKey = encryptForUser(geminiApiKey || null, userSub);
const encryptedOpenRouterKey = encryptForUser(openRouterApiKey || null, userSub);
const encryptedOpenAIKey = encryptForUser(openAIApiKey || null, userSub);
const encryptedEmail = encryptForUser(req.user!.email || null, userSub);
const encryptedDisplayName = encryptForUser(req.user!.name || null, userSub);
const upsertUser = db.prepare(`
INSERT INTO users (id, username, email, display_name, color_scheme, gemini_api_key, ai_provider, openrouter_api_key, openrouter_model, last_login)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)
INSERT INTO users (id, username, email, display_name, color_scheme, gemini_api_key, gemini_model, ai_provider, openrouter_api_key, openrouter_model, openai_api_key, openai_model, last_login)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)
ON CONFLICT(id) DO UPDATE SET
color_scheme = ?,
gemini_api_key = ?,
gemini_model = ?,
ai_provider = ?,
openrouter_api_key = ?,
openrouter_model = ?,
openai_api_key = ?,
openai_model = ?,
last_login = CURRENT_TIMESTAMP
`);
@ -159,14 +170,20 @@ router.put('/me/preferences', (req: AuthenticatedRequest, res: Response) => {
encryptedDisplayName,
colorScheme || 'blue',
encryptedGeminiKey,
geminiModel || null,
aiProvider || 'gemini',
encryptedOpenRouterKey,
openRouterModel || null,
encryptedOpenAIKey,
openAIModel || null,
colorScheme || 'blue',
encryptedGeminiKey,
geminiModel || null,
aiProvider || 'gemini',
encryptedOpenRouterKey,
openRouterModel || null
openRouterModel || null,
encryptedOpenAIKey,
openAIModel || null
);
res.json({ success: true });