2026-01-05 09:58:59 +07:00
|
|
|
import { NextResponse } from "next/server";
|
|
|
|
|
import { getProviderConnections } from "@/lib/localDb";
|
2026-04-24 11:36:16 +07:00
|
|
|
import { backfillCodexEmails } from "@/lib/oauth/providers";
|
2026-01-05 09:58:59 +07:00
|
|
|
|
2026-05-16 10:54:41 +07:00
|
|
|
// Whitelist: only safe metadata fields exposed to UI
|
|
|
|
|
const SAFE_FIELDS = [
|
|
|
|
|
"id", "provider", "authType", "name", "email", "displayName",
|
|
|
|
|
"priority", "globalPriority", "isActive", "defaultModel",
|
|
|
|
|
"testStatus", "lastError", "lastErrorAt", "errorCode",
|
|
|
|
|
"expiresAt", "lastUsedAt", "consecutiveUseCount",
|
|
|
|
|
"createdAt", "updatedAt",
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
// providerSpecificData fields safe to expose (non-secret config only)
|
|
|
|
|
const SAFE_PSD_FIELDS = [
|
|
|
|
|
"baseUrl", "azureEndpoint", "deployment", "apiVersion", "accountId",
|
|
|
|
|
"region", "projectId", "resourceUrl", "proxyPoolId",
|
|
|
|
|
"connectionProxyEnabled", "connectionProxyUrl", "connectionNoProxy",
|
|
|
|
|
"githubLogin", "githubName", "githubEmail", "githubUserId",
|
|
|
|
|
"username", "firstName", "lastName", "authMethod", "authKind",
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
function maskName(name) {
|
|
|
|
|
if (typeof name !== "string" || name.length <= 16) return name;
|
|
|
|
|
// Names like "hahask-uDUOg90..." may embed API keys — mask if looks like key
|
|
|
|
|
if (/[a-zA-Z0-9_-]{32,}/.test(name)) return `${name.slice(0, 8)}***`;
|
|
|
|
|
return name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function sanitize(c) {
|
|
|
|
|
const safe = {};
|
|
|
|
|
for (const f of SAFE_FIELDS) if (c[f] !== undefined) safe[f] = c[f];
|
|
|
|
|
if (safe.name) safe.name = maskName(safe.name);
|
|
|
|
|
if (c.providerSpecificData) {
|
|
|
|
|
const psd = {};
|
|
|
|
|
for (const f of SAFE_PSD_FIELDS) {
|
|
|
|
|
if (c.providerSpecificData[f] !== undefined) psd[f] = c.providerSpecificData[f];
|
|
|
|
|
}
|
|
|
|
|
safe.providerSpecificData = psd;
|
|
|
|
|
}
|
|
|
|
|
return safe;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GET /api/providers/client - List connections for dashboard UI (whitelist only)
|
2026-01-05 09:58:59 +07:00
|
|
|
export async function GET() {
|
|
|
|
|
try {
|
2026-04-24 11:36:16 +07:00
|
|
|
await backfillCodexEmails();
|
2026-01-05 09:58:59 +07:00
|
|
|
const connections = await getProviderConnections();
|
2026-05-16 10:54:41 +07:00
|
|
|
return NextResponse.json({ connections: connections.map(sanitize) });
|
2026-01-05 09:58:59 +07:00
|
|
|
} catch (error) {
|
|
|
|
|
console.log("Error fetching providers for client:", error);
|
|
|
|
|
return NextResponse.json({ error: "Failed to fetch providers" }, { status: 500 });
|
|
|
|
|
}
|
|
|
|
|
}
|