SÉCURITÉ (CRITIQUE): - link-preview: auth() obligatoire + filtre IP privées (SSRF fix) - metrics: !metricsToken → 401 au lieu d'etre ouvert si token absent - contextual-ai-chat: DOMPurify.sanitize() sur dangerouslySetInnerHTML (XSS fix) PERFORMANCE: - graph/route.ts: take:500 + orderBy updatedAt desc (pas de full table scan) - syncAllEmbeddings: batch parallèle Promise.allSettled × 5 (pas séquentiel) - 80 console.log supprimés du code production BASE DE DONNÉES: - Note: index contentUpdatedAt + isPublic ajoutés au schema - DocumentChunk: commentaire index vectoriel HNSW (à exécuter manuellement)
61 lines
1.5 KiB
TypeScript
61 lines
1.5 KiB
TypeScript
import { NextRequest } from 'next/server'
|
|
import { prisma } from '@/lib/prisma'
|
|
|
|
export async function GET(req: NextRequest) {
|
|
try {
|
|
const canvasId = req.nextUrl.searchParams.get('id')
|
|
|
|
if (!canvasId) {
|
|
return new Response(JSON.stringify({ error: 'Missing id' }), {
|
|
status: 400,
|
|
headers: { 'Content-Type': 'application/json' },
|
|
})
|
|
}
|
|
|
|
const canvas = await prisma.canvas.findUnique({
|
|
where: { id: canvasId },
|
|
})
|
|
|
|
if (!canvas) {
|
|
return new Response(JSON.stringify({ error: 'Not found' }), {
|
|
status: 404,
|
|
headers: { 'Content-Type': 'application/json' },
|
|
})
|
|
}
|
|
|
|
|
|
let parsed: any
|
|
try {
|
|
parsed = JSON.parse(canvas.data)
|
|
} catch (parseErr) {
|
|
return new Response(JSON.stringify({ error: 'Invalid data' }), {
|
|
status: 500,
|
|
headers: { 'Content-Type': 'application/json' },
|
|
})
|
|
}
|
|
|
|
|
|
if (parsed.type !== 'slides' || !parsed.html) {
|
|
return new Response(JSON.stringify({ error: 'Not a slides canvas' }), {
|
|
status: 400,
|
|
headers: { 'Content-Type': 'application/json' },
|
|
})
|
|
}
|
|
|
|
|
|
return new Response(parsed.html, {
|
|
status: 200,
|
|
headers: {
|
|
'Content-Type': 'text/html; charset=utf-8',
|
|
'Cache-Control': 'no-cache',
|
|
},
|
|
})
|
|
} catch (error) {
|
|
console.error('[Slides API] FATAL:', error)
|
|
return new Response(JSON.stringify({ error: 'Internal Server Error' }), {
|
|
status: 500,
|
|
headers: { 'Content-Type': 'application/json' },
|
|
})
|
|
}
|
|
}
|