diff --git a/approval.js b/approval.js index 49f2ab2..3658e7a 100644 --- a/approval.js +++ b/approval.js @@ -1,4 +1,6 @@ import {countryForIP} from "./maxmind.js"; +import {clientIP} from "./misc.js"; +import {sql} from "./db.js"; const bannedCountries = [ @@ -15,6 +17,16 @@ const bannedCountries = [ ] +export async function approveTOS(socket, time, version, callback) { + const ipAddress = clientIP(socket) + const query = `insert into tosacceptance (ipaddr, time, version) values ('${ipAddress}', '${time}', '${version}')`; + console.log('query:', query) + await sql(query) + console.log('approved TOS') + callback(true) +} + + export function approveWallet(walletAddress) { // todo OFAC lookup return true @@ -22,25 +34,23 @@ export function approveWallet(walletAddress) { function approveIP(ipAddress) { + let country try { - const country = countryForIP(ipAddress) - if (!country) return false - const approved = !bannedCountries.includes(country) - if (!approved) - // todo log ban & report - console.warn(`IP ${ipAddress} from ${country} is banned`) - console.debug(`IP ${ipAddress} from ${country} is ${approved ? 'approved' : 'rejected'}`) - return approved + country = countryForIP(ipAddress) } catch (e) { console.warn(`IP lookup failed for ${ipAddress}: ${e.message}`) return false } + if (!country) return false + const approved = !bannedCountries.includes(country) + console.debug(`IP ${ipAddress} from ${country} is ${approved ? 'approved' : 'rejected'}`) + return approved } export function approveRegion(socket, bypass) { - const ipAddress = socket.handshake.address + const ipAddress = clientIP(socket) const debug = bypass === process.env.DEXORDER_REGION_APPROVAL; const approved = debug || approveIP(ipAddress) socket.emit('approvedRegion', approved) diff --git a/misc.js b/misc.js index f3f4cae..208f056 100644 --- a/misc.js +++ b/misc.js @@ -2,3 +2,8 @@ import util from "util"; import fs from "fs"; export const readFile = (fileName) => util.promisify(fs.readFile)(fileName, 'utf8'); + +export function clientIP(socket) { + // X-Forwarded-For + return socket.handshake.headers['x-forwarded-for']?.split(',')[0] || socket.handshake.address; +} diff --git a/route.js b/route.js index f4dabe9..a625f30 100644 --- a/route.js +++ b/route.js @@ -3,7 +3,7 @@ import {lookupToken} from "./token.js"; import {requestVault, loginAddress} from "./vault.js"; import {subOHLCs, subPools, unsubOHLCs, unsubPools} from "./pool.js"; import {gib} from "./faucet.js"; -import {approveRegion} from "./approval.js"; +import {approveRegion, approveTOS} from "./approval.js"; // Server route handling @@ -19,6 +19,7 @@ export function initIO() { socket.on('unsubOHLCs', (chainId, poolPeriods) => unsubOHLCs(socket, chainId, poolPeriods)) socket.on('ensureVault', (chainId, owner, num) => requestVault(socket, chainId, owner, num)) socket.on('gib', async (chainId, owner, vault, tokenAmounts) => await gib(chainId, owner, vault, tokenAmounts)) + socket.on('approveTOS', (time, version, callback) => approveTOS(socket, time, version, callback)) socket.on('approveRegion', (bypass) => approveRegion(socket, bypass)) socket.join('public') }); diff --git a/vault.js b/vault.js index 2369b76..be5e26c 100644 --- a/vault.js +++ b/vault.js @@ -6,6 +6,7 @@ import {sendVaultOrders} from "./order.js"; import {newContract} from "./contract.js"; import {approveWallet} from "./approval.js"; import {sql} from "./db.js"; +import {clientIP} from "./misc.js"; export function vaultAddress(chainId, owner, num=0) { @@ -136,7 +137,7 @@ async function createVault(chainId, owner, num) { export async function requestVault(socket, chainId, owner, num) { - const ipAddress = socket.handshake.address + const ipAddress = clientIP(socket) const time = new Date().toISOString(); const query = `insert into vaultcreationrequest (chain, owner, num, time, ipaddr) values (${chainId}, '${owner}', ${num}, '${time}', '${ipAddress}') ON CONFLICT DO NOTHING`; console.log('query:', query)