mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-03 13:52:09 +03:00
fix(#549): resolve real API key from keyId in codex/droid/kilo settings
CLI settings routes (codex-settings, droid-settings, kilo-settings) were writing the masked API key string directly to config files when the dashboard sent a keyId. Now resolves the real key from the database via getApiKeyById() before writing, matching the pattern already implemented in claude-settings, openclaw-settings, and cline-settings. Closes #549
This commit is contained in:
@@ -12,6 +12,7 @@ import { createMultiBackup } from "@/shared/services/backupService";
|
||||
import { saveCliToolLastConfigured, deleteCliToolLastConfigured } from "@/lib/db/cliToolState";
|
||||
import { cliModelConfigSchema } from "@/shared/validation/schemas";
|
||||
import { isValidationFailure, validateBody } from "@/shared/validation/helpers";
|
||||
import { getApiKeyById } from "@/lib/localDb";
|
||||
|
||||
const getCodexConfigPath = () => getCliConfigPaths("codex").config;
|
||||
const getCodexAuthPath = () => getCliConfigPaths("codex").auth;
|
||||
@@ -166,7 +167,8 @@ export async function POST(request: Request) {
|
||||
if (isValidationFailure(validation)) {
|
||||
return NextResponse.json({ error: validation.error }, { status: 400 });
|
||||
}
|
||||
const { baseUrl, apiKey, model } = validation.data;
|
||||
const { baseUrl, model } = validation.data;
|
||||
let { apiKey } = validation.data;
|
||||
if (!apiKey) {
|
||||
return NextResponse.json(
|
||||
{ error: "baseUrl, apiKey and model are required" },
|
||||
@@ -174,6 +176,21 @@ export async function POST(request: Request) {
|
||||
);
|
||||
}
|
||||
|
||||
// (#549) Resolve real key from DB if keyId was provided.
|
||||
// The dashboard sends masked key strings — resolving by ID guarantees
|
||||
// we always write the full key value to the config file.
|
||||
const keyId = typeof rawBody?.keyId === "string" ? rawBody.keyId.trim() : null;
|
||||
if (keyId) {
|
||||
try {
|
||||
const keyRecord = await getApiKeyById(keyId);
|
||||
if (keyRecord?.key) {
|
||||
apiKey = keyRecord.key as string;
|
||||
}
|
||||
} catch {
|
||||
// Non-critical: fall back to whatever value was in apiKey
|
||||
}
|
||||
}
|
||||
|
||||
const codexDir = getCodexDir();
|
||||
const configPath = getCodexConfigPath();
|
||||
const authPath = getCodexAuthPath();
|
||||
|
||||
@@ -12,6 +12,7 @@ import { createBackup } from "@/shared/services/backupService";
|
||||
import { saveCliToolLastConfigured, deleteCliToolLastConfigured } from "@/lib/db/cliToolState";
|
||||
import { cliModelConfigSchema } from "@/shared/validation/schemas";
|
||||
import { isValidationFailure, validateBody } from "@/shared/validation/helpers";
|
||||
import { getApiKeyById } from "@/lib/localDb";
|
||||
|
||||
const getDroidSettingsPath = () => getCliPrimaryConfigPath("droid");
|
||||
const getDroidDir = () => path.dirname(getDroidSettingsPath());
|
||||
@@ -101,7 +102,21 @@ export async function POST(request: Request) {
|
||||
if (isValidationFailure(validation)) {
|
||||
return NextResponse.json({ error: validation.error }, { status: 400 });
|
||||
}
|
||||
const { baseUrl, apiKey, model } = validation.data;
|
||||
const { baseUrl, model } = validation.data;
|
||||
let { apiKey } = validation.data;
|
||||
|
||||
// (#549) Resolve real key from DB if keyId was provided.
|
||||
const keyId = typeof rawBody?.keyId === "string" ? rawBody.keyId.trim() : null;
|
||||
if (keyId) {
|
||||
try {
|
||||
const keyRecord = await getApiKeyById(keyId);
|
||||
if (keyRecord?.key) {
|
||||
apiKey = keyRecord.key as string;
|
||||
}
|
||||
} catch {
|
||||
// Non-critical: fall back to whatever value was in apiKey
|
||||
}
|
||||
}
|
||||
|
||||
const droidDir = getDroidDir();
|
||||
const settingsPath = getDroidSettingsPath();
|
||||
|
||||
@@ -9,6 +9,7 @@ import { createBackup } from "@/shared/services/backupService";
|
||||
import { saveCliToolLastConfigured, deleteCliToolLastConfigured } from "@/lib/db/cliToolState";
|
||||
import { cliModelConfigSchema } from "@/shared/validation/schemas";
|
||||
import { isValidationFailure, validateBody } from "@/shared/validation/helpers";
|
||||
import { getApiKeyById } from "@/lib/localDb";
|
||||
|
||||
const KILO_DATA_DIR = path.join(os.homedir(), ".local", "share", "kilo");
|
||||
const AUTH_PATH = path.join(KILO_DATA_DIR, "auth.json");
|
||||
@@ -133,7 +134,21 @@ export async function POST(request) {
|
||||
if (isValidationFailure(validation)) {
|
||||
return NextResponse.json({ error: validation.error }, { status: 400 });
|
||||
}
|
||||
const { baseUrl, apiKey, model } = validation.data;
|
||||
const { baseUrl, model } = validation.data;
|
||||
let { apiKey } = validation.data;
|
||||
|
||||
// (#549) Resolve real key from DB if keyId was provided.
|
||||
const keyId = typeof rawBody?.keyId === "string" ? rawBody.keyId.trim() : null;
|
||||
if (keyId) {
|
||||
try {
|
||||
const keyRecord = await getApiKeyById(keyId);
|
||||
if (keyRecord?.key) {
|
||||
apiKey = keyRecord.key as string;
|
||||
}
|
||||
} catch {
|
||||
// Non-critical: fall back to whatever value was in apiKey
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure directories exist
|
||||
await fs.mkdir(KILO_DATA_DIR, { recursive: true });
|
||||
|
||||
Reference in New Issue
Block a user