From f46116394ccb847610bb369587f454e4da5d40e5 Mon Sep 17 00:00:00 2001 From: Hyko Date: Fri, 24 Apr 2026 21:34:35 -0400 Subject: [PATCH] feat(auth): add proxy support and pass ip/user-agent to login - add ZEN_TRUST_PROXY env variable in .env.example for reverse proxy config - replace getClientIp() with getIpFromHeaders() using next/headers for ip resolution - forward ipAddress and userAgent to login action for session tracking --- .env.example | 3 +++ src/features/auth/actions.js | 7 ++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.env.example b/.env.example index bf254c3..9487c48 100644 --- a/.env.example +++ b/.env.example @@ -10,6 +10,9 @@ ZEN_CURRENCY=CAD ZEN_CURRENCY_SYMBOL=$ ZEN_SUPPORT_EMAIL=support@exemple.com +# PROXY (activer si derrière un reverse proxy) +ZEN_TRUST_PROXY=false + # DATABASE ZEN_DATABASE_URL=postgres://USER:PASSWORD@HOST:PORT/postgres ZEN_DATABASE_URL_DEV=postgres://USER:PASSWORD@HOST:PORT/postgres_dev diff --git a/src/features/auth/actions.js b/src/features/auth/actions.js index 80b57e7..ed81e8c 100644 --- a/src/features/auth/actions.js +++ b/src/features/auth/actions.js @@ -121,7 +121,8 @@ export async function loginAction(formData) { const botCheck = validateAntiBotFields(formData); if (!botCheck.valid) return { success: false, error: botCheck.error }; - const ip = await getClientIp(); + const h = await headers(); + const ip = getIpFromHeaders(h); const rl = enforceRateLimit(ip, 'login'); if (rl && !rl.allowed) { return { success: false, error: `Trop de tentatives. Réessayez dans ${formatRetryAfter(rl.retryAfterMs)}.` }; @@ -129,8 +130,8 @@ export async function loginAction(formData) { const email = formData.get('email'); const password = formData.get('password'); - - const result = await login({ email, password }); + const userAgent = h.get('user-agent') || null; + const result = await login({ email, password }, { ipAddress: ip !== 'unknown' ? ip : null, userAgent }); // An HttpOnly cookie is the only safe transport for session tokens; setting it // here keeps the token out of any JavaScript-readable response payload.