feat(admin): add geolocation information to user sessions and implement geo IP fetching

This commit is contained in:
Jose Selesan
2026-06-10 10:01:36 -03:00
parent 93b3a82638
commit 00f0cf511f
5 changed files with 104 additions and 39 deletions

View File

@@ -0,0 +1,57 @@
type IpGeoInfo = {
ip: string;
city: string;
country: string;
countryCode: string;
};
const cache = new Map<string, { data: IpGeoInfo; expiresAt: number }>();
const CACHE_TTL_MS = 60 * 60 * 1000;
function getCached(ip: string): IpGeoInfo | undefined {
const entry = cache.get(ip);
if (!entry) return undefined;
if (Date.now() > entry.expiresAt) {
cache.delete(ip);
return undefined;
}
return entry.data;
}
function setCache(ip: string, info: IpGeoInfo): void {
cache.set(ip, { data: info, expiresAt: Date.now() + CACHE_TTL_MS });
}
async function fetchGeoInfo(ip: string): Promise<IpGeoInfo | null> {
if (ip === '127.0.0.1' || ip === '::1' || ip.startsWith('192.168.') || ip.startsWith('10.')) {
return { ip, city: 'Red local', country: 'Red local', countryCode: 'LOCAL' };
}
const cached = getCached(ip);
if (cached) return cached;
try {
const response = await fetch(
`http://ip-api.com/json/${ip}?fields=status,country,countryCode,city,query`
);
if (!response.ok) return null;
const data = await response.json();
if (data.status !== 'success') return null;
const info: IpGeoInfo = {
ip: data.query,
city: data.city || 'Desconocida',
country: data.country || 'Desconocido',
countryCode: data.countryCode || '',
};
setCache(ip, info);
return info;
} catch {
return null;
}
}
export type { IpGeoInfo };
export { fetchGeoInfo };