- Suppression de /app/api/pdf-proxy/route.ts (endpoint inutilisé avec CORS *) - Suppression de /app/api/pdf-clean/route.ts (endpoint inutilisé avec CORS *) - Mise à jour du rapport d'audit de sécurité - Les PDFs sont désormais affichés via URLs présignées S3 directes
78 lines
2.6 KiB
TypeScript
78 lines
2.6 KiB
TypeScript
// app/api/csp-report/route.ts
|
|
import { NextRequest, NextResponse } from 'next/server';
|
|
import { createSbServiceRole } from '@/lib/supabaseServer';
|
|
|
|
export const dynamic = 'force-dynamic';
|
|
|
|
interface CSPReport {
|
|
'csp-report': {
|
|
'document-uri': string;
|
|
'violated-directive': string;
|
|
'effective-directive'?: string;
|
|
'blocked-uri'?: string;
|
|
'source-file'?: string;
|
|
'line-number'?: number;
|
|
'column-number'?: number;
|
|
'status-code'?: number;
|
|
referrer?: string;
|
|
'original-policy'?: string;
|
|
};
|
|
}
|
|
|
|
export async function POST(req: NextRequest) {
|
|
try {
|
|
const report: CSPReport = await req.json();
|
|
const cspReport = report['csp-report'];
|
|
|
|
// Validation basique
|
|
if (!cspReport || !cspReport['document-uri'] || !cspReport['violated-directive']) {
|
|
console.error('❌ CSP Report invalide:', report);
|
|
return NextResponse.json({ error: 'Invalid CSP report format' }, { status: 400 });
|
|
}
|
|
|
|
// Log console pour debug immédiat
|
|
console.log('🔒 CSP Violation détectée:', {
|
|
timestamp: new Date().toISOString(),
|
|
page: cspReport['document-uri'],
|
|
directive: cspReport['violated-directive'],
|
|
blocked: cspReport['blocked-uri'] || 'inline',
|
|
source: cspReport['source-file'],
|
|
line: cspReport['line-number']
|
|
});
|
|
|
|
// Enregistrer en base de données
|
|
const supabase = createSbServiceRole();
|
|
|
|
const { error: insertError } = await supabase
|
|
.from('csp_reports')
|
|
.insert({
|
|
document_uri: cspReport['document-uri'],
|
|
violated_directive: cspReport['violated-directive'],
|
|
effective_directive: cspReport['effective-directive'],
|
|
blocked_uri: cspReport['blocked-uri'],
|
|
source_file: cspReport['source-file'],
|
|
line_number: cspReport['line-number'],
|
|
column_number: cspReport['column-number'],
|
|
status_code: cspReport['status-code'],
|
|
user_agent: req.headers.get('user-agent'),
|
|
referrer: cspReport.referrer,
|
|
original_policy: cspReport['original-policy']
|
|
});
|
|
|
|
if (insertError) {
|
|
console.error('❌ Erreur insertion CSP report:', insertError);
|
|
// Ne pas échouer la requête même si l'insertion échoue
|
|
}
|
|
|
|
return NextResponse.json({ received: true }, { status: 200 });
|
|
} catch (error) {
|
|
console.error('❌ Erreur traitement CSP report:', error);
|
|
// Retourner 200 quand même pour ne pas polluer les logs navigateur
|
|
return NextResponse.json({ received: false }, { status: 200 });
|
|
}
|
|
}
|
|
|
|
// Gérer les requêtes OPTIONS (CORS preflight)
|
|
export async function OPTIONS() {
|
|
return NextResponse.json({}, { status: 200 });
|
|
}
|