import { NextRequest, NextResponse } from 'next/server'; import { auth } from '@/auth'; import { getEffectiveTier } from '@/lib/entitlements'; import { getActiveByokKey, isByokProviderAllowed } from '@/lib/byok'; import { decryptApiKey } from '@/lib/crypto'; import { fetchLiveModelsForProvider, type FetchModelsResult } from '@/lib/ai/models-list'; import { VALID_PROVIDERS, type AiGatewayProvider } from '@/lib/ai/router'; /** * GET /api/user/api-keys/live-models?provider=[&key=][&baseUrl=] * * Liste les modèles chez le fournisseur. Sans clé (saisie ou déjà enregistrée) : liste vide. * Pas de liste de secours figée. */ export async function GET(request: NextRequest) { const session = await auth(); if (!session?.user?.id) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } const tier = await getEffectiveTier(session.user.id); if (tier === 'BASIC') { return NextResponse.json({ error: 'Forbidden' }, { status: 403 }); } const { searchParams } = request.nextUrl; const provider = searchParams.get('provider') as AiGatewayProvider; let apiKey = searchParams.get('key') ?? ''; let baseUrl = searchParams.get('baseUrl') ?? undefined; if (!provider) { return NextResponse.json({ error: 'Missing provider' }, { status: 400 }); } if (!VALID_PROVIDERS.has(provider)) { return NextResponse.json({ error: 'Invalid provider' }, { status: 400 }); } if (!isByokProviderAllowed(tier, provider)) { return NextResponse.json({ error: 'Tier restricted' }, { status: 403 }); } if (!apiKey || apiKey.length < 4) { const saved = await getActiveByokKey(session.user.id, provider, tier); if (saved) { try { apiKey = await decryptApiKey(saved.encryptedKey); if (!baseUrl && saved.baseUrl) baseUrl = saved.baseUrl; } catch { apiKey = ''; } } } if (!apiKey || apiKey.length < 4) { return NextResponse.json({ success: true, models: [], fromApi: false }); } const result: FetchModelsResult = await fetchLiveModelsForProvider(provider, apiKey, baseUrl); return NextResponse.json({ success: true, models: result.models, fromApi: result.fromApi }); }