nestjs-cluster-throttle
Version:
Enterprise-grade rate limiting module for NestJS with Redis support, multiple strategies, and cluster mode
76 lines • 2.94 kB
JavaScript
;
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.IpApiGeoProvider = void 0;
const common_1 = require("@nestjs/common");
let IpApiGeoProvider = class IpApiGeoProvider {
constructor() {
this.baseUrl = 'http://ip-api.com/json';
this.cache = new Map();
this.cacheTTL = 3600000;
}
async lookup(ip) {
if (this.isPrivateIP(ip)) {
return {
countryCode: 'XX',
country: 'Private/Local',
};
}
const cached = this.cache.get(ip);
if (cached && Date.now() - cached.timestamp < this.cacheTTL) {
return cached.result;
}
try {
const response = await fetch(`${this.baseUrl}/${ip}?fields=status,country,countryCode,region,city,lat,lon,timezone`);
if (!response.ok) {
console.error(`IP-API returned status: ${response.status}`);
return null;
}
const data = await response.json();
if (data.status === 'fail') {
console.error('IP-API lookup failed:', data.message);
return null;
}
const result = {
country: data.country,
countryCode: data.countryCode,
region: data.region,
city: data.city,
lat: data.lat,
lon: data.lon,
timezone: data.timezone,
};
this.cache.set(ip, { result, timestamp: Date.now() });
return result;
}
catch (error) {
console.error('Error fetching geo data from IP-API:', error);
return null;
}
}
isPrivateIP(ip) {
const parts = ip.split('.').map(Number);
if (parts[0] === 10)
return true;
if (parts[0] === 172 && parts[1] >= 16 && parts[1] <= 31)
return true;
if (parts[0] === 192 && parts[1] === 168)
return true;
if (parts[0] === 127)
return true;
return false;
}
clearCache() {
this.cache.clear();
}
};
exports.IpApiGeoProvider = IpApiGeoProvider;
exports.IpApiGeoProvider = IpApiGeoProvider = __decorate([
(0, common_1.Injectable)()
], IpApiGeoProvider);
//# sourceMappingURL=ip-api-geo.provider.js.map