mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-12 14:16:12 +00:00
fix(ai): block aiBaseUrl from leaking across providers
The user row stores a single `aiBaseUrl` column that is meaningful only for the LOCAL provider, but `buildUserProvider` and `resolveProviderForTest` were forwarding that value to OpenAI and Anthropic clients too. A user who had configured LOCAL pointing at e.g. `http://192.168.x.x/v1` and later switched to OPENAI would have their OpenAI API key sent to that LAN host on the next request. Defence in three layers: - PATCH /api/user/ai-provider — when the provider switches to anything other than LOCAL and the body does not include an explicit `aiBaseUrl` write, set the column back to NULL. - `buildUserProvider` — for OPENAI hardcode `https://api.openai.com/v1`, for ANTHROPIC do not forward a base URL at all (the SDK default is correct and the UI never exposed an Anthropic base-URL input). - `resolveProviderForTest` — same belt-and-braces: ignore the merged base URL for OPENAI/ANTHROPIC so a stored LOCAL value cannot bleed into a connection-test request. Adds two regression tests covering the LOCAL → OPENAI and LOCAL → ANTHROPIC paths with a stale `aiBaseUrl`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
a75fbc6aaf
commit
eba898f4c1
3 files changed
+71
-5
No files matched your search
@@ -117,6 +117,20 @@ export const PATCH = apiHandler(async (request: NextRequest) => {
|
||||
throw new HttpError(422, "No valid fields");
|
||||
}
|
||||
|
||||
// When the provider switches away from LOCAL, drop any stored
|
||||
// `aiBaseUrl`. The column is shared across providers, so without
|
||||
// this a user who once configured LOCAL → http://192.168.x.x and
|
||||
// then switched to OPENAI/ANTHROPIC would have their cloud key
|
||||
// sent to that URL on the next request. Only LOCAL legitimately
|
||||
// uses a custom base URL.
|
||||
if (
|
||||
typeof updates.aiProvider === "string" &&
|
||||
updates.aiProvider !== "LOCAL" &&
|
||||
!("aiBaseUrl" in updates)
|
||||
) {
|
||||
updates.aiBaseUrl = null;
|
||||
}
|
||||
|
||||
await prisma.user.update({ where: { id: user.id }, data: updates });
|
||||
|
||||
return apiSuccess({ updated: true });
|
||||
|
||||
Reference in new issue
Block a user