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

@@ -1,5 +1,6 @@
import { createHash, randomInt } from 'node:crypto';
import { auth } from '@/lib/auth';
import { type IpGeoInfo, fetchGeoInfo } from '@/lib/geoip';
import { sendMail } from '@/lib/mailer';
import { db } from '@/lib/prisma';
import type {
@@ -82,13 +83,6 @@ type UserAgentInfo = {
device: string;
};
type IpGeoInfo = {
ip: string;
city: string;
country: string;
countryCode: string;
};
function parseUserAgent(ua: string | undefined): UserAgentInfo {
if (!ua) {
return { browser: 'Desconocido', os: 'Desconocido', device: 'Desconocido' };
@@ -118,31 +112,6 @@ function parseUserAgent(ua: string | undefined): UserAgentInfo {
return { browser, os, device };
}
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' };
}
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;
return {
ip: data.query,
city: data.city || 'Desconocida',
country: data.country || 'Desconocido',
countryCode: data.countryCode || '',
};
} catch {
return null;
}
}
async function sendResetOtpEmail(email: string, otpCode: string) {
await sendMail({
to: email,