Skip to content
Merged

sync #28

Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 19 additions & 6 deletions routes/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import rateLimit from 'express-rate-limit';
import argon2 from 'argon2';
import jwt from 'jsonwebtoken';
import { createHash, randomBytes } from 'crypto';
import { isIP } from 'net';

import { query } from '../config/db.js';
import { generateToken, authenticateToken } from '../middleware/auth.js';
Expand Down Expand Up @@ -99,16 +100,28 @@ function isPrivateIp(ip) {
return false;
}

async function isVpnOrProxy(ip) {
if (isPrivateIp(ip)) {
console.log('[VPN] Skipping private IP:', ip);
function normalizeClientIp(ip) {
if (typeof ip !== 'string') return null;
const trimmed = ip.trim();
if (!trimmed) return null;
const withoutV4Mapped = trimmed.replace(/^::ffff:/, '');
return isIP(withoutV4Mapped) ? withoutV4Mapped : null;
}

export async function isVpnOrProxy(ip) {
const cleanIp = normalizeClientIp(ip);
if (!cleanIp) {
console.log('[VPN] Skipping invalid IP:', ip);
return false;
}

const cleanIp = ip.replace(/^::ffff:/, '');
if (isPrivateIp(cleanIp)) {
console.log('[VPN] Skipping private IP:', cleanIp);
return false;
}

try {
const res = await fetchWithTimeout(`http://ip-api.com/json/${cleanIp}?fields=proxy,hosting,isp,org,query`);
const res = await fetchWithTimeout(`http://ip-api.com/json/${encodeURIComponent(cleanIp)}?fields=proxy,hosting,isp,org,query`);
const data = await res.json();
console.log('[VPN] ip-api response for', cleanIp, ':', JSON.stringify(data));
return data.proxy === true || data.hosting === true;
Expand All @@ -117,7 +130,7 @@ async function isVpnOrProxy(ip) {
}

try {
const res = await fetchWithTimeout(`https://ipinfo.io/${cleanIp}/json`);
const res = await fetchWithTimeout(`https://ipinfo.io/${encodeURIComponent(cleanIp)}/json`);
const data = await res.json();
console.log('[VPN] ipinfo response for', cleanIp, ':', JSON.stringify({ org: data.org }));
const orgLower = (data.org || '').toLowerCase();
Expand Down
Loading