33 lines
1.5 KiB
TypeScript
33 lines
1.5 KiB
TypeScript
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 };
|
|
}
|