78 lines
2.4 KiB
TypeScript
78 lines
2.4 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server';
|
|
import { auth } from '@/auth';
|
|
import { prisma } from '@/lib/prisma';
|
|
import { encryptApiKey, hashApiKey } from '@/lib/crypto';
|
|
import { VALID_PROVIDERS } from '@/lib/ai/router';
|
|
|
|
type RouteContext = { params: Promise<{ provider: string }> };
|
|
|
|
export async function PATCH(req: NextRequest, context: RouteContext) {
|
|
const session = await auth();
|
|
if (!session?.user?.id) {
|
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
|
}
|
|
|
|
const { provider } = await context.params;
|
|
if (!VALID_PROVIDERS.has(provider)) {
|
|
return NextResponse.json({ error: 'Unknown provider' }, { status: 400 });
|
|
}
|
|
|
|
const body = (await req.json().catch(() => ({}))) as {
|
|
isActive?: boolean;
|
|
model?: string;
|
|
alias?: string;
|
|
baseUrl?: string;
|
|
apiKey?: string; // optional — only when rotating the key
|
|
};
|
|
|
|
const data: Record<string, unknown> = {};
|
|
|
|
if (typeof body.isActive === 'boolean') data.isActive = body.isActive;
|
|
if (body.model !== undefined) data.model = body.model || null;
|
|
if (body.alias !== undefined) data.alias = body.alias || '';
|
|
if (body.baseUrl !== undefined) data.baseUrl = body.baseUrl || null;
|
|
|
|
// Key rotation: only when new key explicitly provided
|
|
if (body.apiKey && body.apiKey.length >= 8) {
|
|
data.encryptedKey = await encryptApiKey(body.apiKey);
|
|
data.keyHash = hashApiKey(body.apiKey);
|
|
}
|
|
|
|
if (Object.keys(data).length === 0) {
|
|
return NextResponse.json({ error: 'No fields to update' }, { status: 400 });
|
|
}
|
|
|
|
const updated = await prisma.userAPIKey.updateMany({
|
|
where: { userId: session.user.id, provider },
|
|
data,
|
|
});
|
|
|
|
if (updated.count === 0) {
|
|
return NextResponse.json({ error: 'Not found' }, { status: 404 });
|
|
}
|
|
|
|
return NextResponse.json({ ok: true });
|
|
}
|
|
|
|
export async function DELETE(_req: NextRequest, context: RouteContext) {
|
|
const session = await auth();
|
|
if (!session?.user?.id) {
|
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
|
}
|
|
|
|
const { provider } = await context.params;
|
|
if (!VALID_PROVIDERS.has(provider)) {
|
|
return NextResponse.json({ error: 'Unknown provider' }, { status: 400 });
|
|
}
|
|
|
|
const deleted = await prisma.userAPIKey.deleteMany({
|
|
where: { userId: session.user.id, provider },
|
|
});
|
|
|
|
if (deleted.count === 0) {
|
|
return NextResponse.json({ error: 'Not found' }, { status: 404 });
|
|
}
|
|
|
|
return NextResponse.json({ ok: true });
|
|
}
|