import type { FastifyRequest } from "fastify"; import geoip from "geoip-lite"; // Requer `trustProxy: true` no Fastify (ver server.ts) — aí `req.ip` já // reflete o primeiro IP de X-Forwarded-For, que o nginx interno preenche // (ver nginx/nginx.conf) a partir do que o reverse proxy externo do usuário // mandar. Sem isso, todo mundo apareceria com o IP do container "web". export function resolveIp(req: FastifyRequest): string { return req.ip; } // A porta de origem do cliente normalmente NÃO sobrevive a um reverse // proxy (o socket que a API enxerga é o do nginx, não o do navegador do // visitante) — só é possível saber a porta real se algum proxy na cadeia // mandar um cabeçalho explícito (X-Forwarded-Port não costuma carregar a // porta do cliente, mas deixamos o suporte pronto caso o proxy externo do // usuário seja configurado para isso). Na ausência dele, usamos a porta do // socket TCP direto (a porta efêmera de quem conectou nesse hop). export function resolvePort(req: FastifyRequest): number | null { const header = req.headers["x-forwarded-port"]; const value = Array.isArray(header) ? header[0] : header; if (value) { const port = Number(value.split(",")[0]); if (Number.isFinite(port)) return port; } return req.socket?.remotePort ?? null; } export function resolveGeo(ip: string): { country: string | null; city: string | null } { const geo = geoip.lookup(ip); return { country: geo?.country ?? null, city: geo?.city ?? null }; }