Files
traxxx-web/src/web/restrictions.js
T

130 lines
2.5 KiB
JavaScript

import path from 'node:path';
import { Reader } from '@maxmind/geoip2-node';
import config from 'config';
import runtimeId from '../../utils/runtime-id.js';
import initLogger from '../logger.js';
const logger = initLogger();
const regions = config.restrictions.regions;
export default async function initRestrictionHandler() {
const reader = await Reader.open('assets/GeoLite2-City.mmdb');
function getRestriction(req) {
if (req.session.geo
&& Object.hasOwn(req.session.geo, 'country')
&& req.session.geo.ip === req.userIp
&& req.session.geo.runtimeId === runtimeId) {
const { country, subdivision } = req.session.geo;
if (!config.restrictions.enabled) {
return {
restriction: 0,
country,
subdivision,
};
}
if (Object.hasOwn(req.session.geo, 'restriction')) {
return {
restriction: req.session.geo.restriction,
country,
subdivision,
};
}
}
const location = reader.city(req.userIp);
const country = location.country.isoCode;
const subdivision = location.subdivisions?.[0]?.isoCode;
if (!config.restrictions.enabled) {
return {
restriction: 0,
country,
subdivision,
};
}
if (regions[country]?.[subdivision]) {
// state or province restriction
return {
restriction: config.restrictions.modes[regions[country][subdivision]],
country,
subdivision,
};
}
if (regions[country]) {
// country restriction
return {
restriction: config.restrictions.modes[regions[country]],
country,
subdivision,
};
}
return {
restriction: null,
country,
subdivision,
};
}
function restrictionHandler(req, res, next) {
try {
const {
restriction,
country,
subdivision,
} = getRestriction(req);
if (restriction === 'block' || req.path === '/sfw/') {
res.render(path.join(import.meta.dirname, '../../assets/sfw.ejs'), {
noVpn: config.restrictions.noVpn.includes(country),
});
return;
}
if (req.session.geo?.restriction !== restriction) {
req.session.geo = {
ip: req.userIp,
runtimeId,
restriction,
country,
subdivision,
};
}
req.geo = {
restriction,
country,
subdivision,
};
}
catch (error) {
logger.error(`Failed Maxmind IP lookup for ${req.ip}: ${error.message}`);
req.session.geo = {
ip: req.userIp,
runtimeId,
restriction: 0,
country: null,
subdivision: null,
};
req.geo = {
restriction: 0,
country: null,
subdivision: null,
};
}
next();
}
return restrictionHandler;
}