feat: intégration Sentry + migration middleware.js → proxy.js (Next.js 16)
Sentry (tracking erreurs frontend + API routes) : - sentry.client.config.js : erreurs navigateur + Session Replay sur erreurs - sentry.server.config.js : erreurs API routes (register, jwt callback) - sentry.edge.config.js : runtime edge (middleware proxy) - instrumentation.js : point d'entrée Next.js 15+ (register + captureRequestError) - next.config.mjs : wrappé avec withSentryConfig (source maps désactivés sans SENTRY_AUTH_TOKEN) - .env.sample : ajout de NEXT_PUBLIC_SENTRY_DSN (placeholder) Migration middleware → proxy (bug pré-existant surfacé par le build Sentry) : - proxy.js : fusion du rate limiting + auth NextAuth en un seul proxy Next.js 16 - middleware.js : supprimé (Next.js 16 n'accepte plus les deux fichiers simultanément) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1 +1,55 @@
|
||||
export {auth as proxy} from './auth.js'
|
||||
import {NextResponse} from 'next/server'
|
||||
import {auth} from './auth.js'
|
||||
import {createRateLimiter} from '@/lib/rate-limit.js'
|
||||
|
||||
// 5 inscriptions max par IP toutes les 15 minutes
|
||||
const checkRegister = createRateLimiter({windowMs: 15 * 60 * 1000, max: 5})
|
||||
|
||||
// 10 tentatives de connexion max par IP toutes les 5 minutes
|
||||
const checkSignin = createRateLimiter({windowMs: 5 * 60 * 1000, max: 10})
|
||||
|
||||
const limiters = {
|
||||
'/api/auth/register': checkRegister,
|
||||
'/api/auth/callback/credentials': checkSignin,
|
||||
}
|
||||
|
||||
/**
|
||||
* Extrait l'IP cliente depuis les headers HTTP.
|
||||
* Priorité à X-Real-IP (Nginx), puis X-Forwarded-For.
|
||||
*/
|
||||
function getClientIp(request) {
|
||||
const realIp = request.headers.get('x-real-ip')
|
||||
if (realIp) {
|
||||
return realIp.trim()
|
||||
}
|
||||
|
||||
const forwarded = request.headers.get('x-forwarded-for')
|
||||
if (forwarded) {
|
||||
return forwarded.split(',')[0].trim()
|
||||
}
|
||||
|
||||
return 'unknown'
|
||||
}
|
||||
|
||||
export async function proxy(request) {
|
||||
const {pathname} = request.nextUrl
|
||||
const check = limiters[pathname]
|
||||
|
||||
// Rate limiting sur les routes d'authentification critiques
|
||||
if (check) {
|
||||
const ip = getClientIp(request)
|
||||
const result = check(`${ip}:${pathname}`)
|
||||
|
||||
if (!result.success) {
|
||||
return NextResponse.json(
|
||||
{message: 'Trop de tentatives. Veuillez réessayer dans quelques minutes.'},
|
||||
{
|
||||
status: 429,
|
||||
headers: {'Retry-After': String(result.retryAfter)},
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return auth(request)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user