39 lines
1.0 KiB
TypeScript
39 lines
1.0 KiB
TypeScript
import { timingSafeEqual } from 'crypto'
|
|
import { NextRequest, NextResponse } from 'next/server'
|
|
|
|
/**
|
|
* Validate the shared upload secret before accepting mutation routes.
|
|
*/
|
|
export function validateUploadSecret(req: NextRequest): NextResponse | null {
|
|
const secret = req.headers.get('x-upload-secret')
|
|
const expectedSecret = process.env.UPLOAD_SECRET_KEY
|
|
|
|
if (!expectedSecret) {
|
|
return NextResponse.json(
|
|
{ success: false, error: 'Configuration serveur incomplete (UPLOAD_SECRET_KEY manquant)' },
|
|
{ status: 500 },
|
|
)
|
|
}
|
|
|
|
if (!secret) {
|
|
return NextResponse.json(
|
|
{ success: false, error: "Cle d'authentification manquante" },
|
|
{ status: 401 },
|
|
)
|
|
}
|
|
|
|
// Timing-safe comparison to prevent timing attacks
|
|
const a = Buffer.from(secret)
|
|
const b = Buffer.from(expectedSecret)
|
|
const isValid = a.length === b.length && timingSafeEqual(a, b)
|
|
|
|
if (!isValid) {
|
|
return NextResponse.json(
|
|
{ success: false, error: "Cle d'authentification invalide" },
|
|
{ status: 401 },
|
|
)
|
|
}
|
|
|
|
return null
|
|
}
|