diff --git a/README.md b/README.md index f861f5c6..b2b7c887 100644 --- a/README.md +++ b/README.md @@ -69,8 +69,9 @@ Configuration takes place in the environment variables that are defined in ecosy | Variable | Description | Example | |----------------|:-------------------------|------------------------:| -| PORT | Port | 80 | -| REDIS_URL | URL:PORT of redis server | "redis://localhost:6379" | +| PORT | Own Port | 80 | +| HOST | Own Host | "localhost" | +| REDIS_URL | URL:PORT of redis server | "redis://localhost:6379"| | MYSQL_HOST | MySql Host | "localhost" | | MYSQL_USER | MySql User | "user" | | MYSQL_PW | MySql Password | "password" | @@ -90,7 +91,7 @@ Configuration takes place in the environment variables that are defined in ecosy | CAPTCHA_TIME | time in minutes between captchas | 30 | | SESSION_SECRET | random sting for express sessions | "ayylmao" | | LOG_MYSQL | if sql queries should get logged | 0 | -| USE_XREALIP | see cloudflare section | 1 | +| USE_XREALIP | see ngins / CDN section | 1 | | BACKUP_URL | url of backup server (see Backup) | "http://localhost" | | BACKUP_DIR | mounted directory of backup server | "/mnt/backup/" | | GMAIL_USER | gmail username if used for mails | "ppfun@gmail.com" | @@ -108,7 +109,7 @@ Notes: | Variable | Description | |-----------------------|:-------------------------| -| DISCORD_INVITE | Invite to discord server | +| GUILDED_INVITE | Invite to guilded server | | DISCORD_CLIENT_ID | All | | DISCORD_CLIENT_SECRET | those | | GOOGLE_CLIENT_ID | values | diff --git a/deployment/example-ecosystem.yml b/deployment/example-ecosystem.yml index 38239253..1a0fbbb3 100644 --- a/deployment/example-ecosystem.yml +++ b/deployment/example-ecosystem.yml @@ -3,9 +3,9 @@ apps: name : 'web' node_args: --nouse-idle-notification --expose-gc env: - HOSTURL: "http://localhost" - ASSET_SERVER: "http://localhost" PORT: 80 + HOST: "localhost" + ASSET_SERVER: "http://localhost" REDIS_URL: 'redis://localhost:6379' MYSQL_HOST: "localhost" MYSQL_USER: "pixelplanet" diff --git a/package-lock.json b/package-lock.json index ec5e6825..98bbaa0b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7011,6 +7011,14 @@ "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", "dev": true }, + "opentype.js": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/opentype.js/-/opentype.js-0.7.3.tgz", + "integrity": "sha1-QPuM4Yv9YOdESO/f5EKDQJg5eqs=", + "requires": { + "tiny-inflate": "^1.0.2" + } + }, "optionator": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", @@ -7526,6 +7534,14 @@ "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==", "dev": true }, + "ppfun-captcha": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/ppfun-captcha/-/ppfun-captcha-1.6.2.tgz", + "integrity": "sha512-pe15Inrr791duH9mMAyc9PCiYdMY5kLbaLCuoWVLWJ+kydHvMnwnYPKQUfEXzohrGWidKkNKQJk3E9o1U3GdAg==", + "requires": { + "opentype.js": "^0.7.3" + } + }, "prebuild-install": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.0.0.tgz", @@ -9365,6 +9381,11 @@ "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", "dev": true }, + "tiny-inflate": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", + "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==" + }, "tiny-invariant": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz", diff --git a/package.json b/package.json index bdc3d254..4dbea75e 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,7 @@ "passport-json": "^1.2.0", "passport-reddit": "^0.2.4", "passport-vkontakte": "^0.5.0", + "ppfun-captcha": "^1.6.2", "react": "^17.0.1", "react-dom": "^17.0.1", "react-icons": "^4.1.0", diff --git a/src/captchaserver.js b/src/captchaserver.js index 22660022..3fb970e5 100644 --- a/src/captchaserver.js +++ b/src/captchaserver.js @@ -16,7 +16,8 @@ const PORT = 7000; const server = http.createServer((req, res) => { const captcha = ppfunCaptcha.create(); - console.log(`Serving ${captcha.text} to ${req.headers['x-real-ip']}`); + const ip = req.headers['x-real-ip'] || req.connection.remoteAddress; + console.log(`Serving ${captcha.text} to ${ip}`); res.writeHead(200, { 'Content-Type': 'text/html', 'Cache-Control': 'no-cache', @@ -25,6 +26,6 @@ const server = http.createServer((req, res) => { res.end(); }); -server.listen(port, () => { - console.log(`Captcha Server listening on port ${port}`); +server.listen(PORT, () => { + console.log(`Captcha Server listening on port ${PORT}`); }); diff --git a/src/core/config.js b/src/core/config.js index fb6eb6ce..1160bf3f 100644 --- a/src/core/config.js +++ b/src/core/config.js @@ -35,8 +35,6 @@ export const MYSQL_USER = process.env.MYSQL_USER || 'pixelplanet'; export const MYSQL_PW = process.env.MYSQL_PW || 'password'; // Social -export const DISCORD_INVITE = process.env.DISCORD_INVITE - || 'https://discordapp.com/'; export const GUILDED_INVITE = process.env.GUILDED_INVITE || 'https://www.guilded.gg/'; diff --git a/src/utils/cloudflareip.js b/src/utils/cloudflareip.js deleted file mode 100644 index da95b2e9..00000000 --- a/src/utils/cloudflareip.js +++ /dev/null @@ -1,60 +0,0 @@ -/* - * check if IP is from cloudflare - * @flow - */ - -import { Address4, Address6 } from 'ip-address'; - -import logger from '../core/logger'; - -// returns null | Address4 | Address6 -function intoAddress(str) { - if (typeof str === 'string') str = str.trim(); - try { - const isV6 = (str.indexOf(':') !== -1); - let ip = null; - if (isV6) { - ip = new Address6(str); - } else { - ip = new Address4(str); - } - return ip; - } catch { - logger.error(`CF-check: Got invalid ip ${str}`); - return null; - } -} - -const cloudflareIps = [ - '103.21.244.0/22', - '103.22.200.0/22', - '103.31.4.0/22', - '104.16.0.0/12', - '108.162.192.0/18', - '131.0.72.0/22', - '141.101.64.0/18', - '162.158.0.0/15', - '172.64.0.0/13', - '173.245.48.0/20', - '188.114.96.0/20', - '190.93.240.0/20', - '197.234.240.0/22', - '198.41.128.0/17', - '2400:cb00::/32', - '2405:8100::/32', - '2405:b500::/32', - '2606:4700::/32', - '2803:f800::/32', - '2c0f:f248::/32', - '2a06:98c0::/29', -].map(intoAddress); - -// returns bool -function isCloudflareIp(testIpString: string): boolean { - if (!testIpString) return false; - const testIp = intoAddress(testIpString); - if (!testIp) return false; - return cloudflareIps.some((cf) => testIp.isInSubnet(cf)); -} - -export default isCloudflareIp; diff --git a/src/utils/ip.js b/src/utils/ip.js index 2037d162..236bb296 100644 --- a/src/utils/ip.js +++ b/src/utils/ip.js @@ -3,20 +3,11 @@ * @flow */ -import isCloudflareIp from './cloudflareip'; - import logger from '../core/logger'; import { USE_XREALIP } from '../core/config'; -function isTrustedProxy(ip: string): boolean { - if (ip === '::ffff:127.0.0.1' || ip === '127.0.0.1' || isCloudflareIp(ip)) { - return true; - } - return false; -} - export function getHostFromRequest(req): ?string { const { headers } = req; const host = headers['x-forwarded-host'] || headers.host; @@ -26,30 +17,25 @@ export function getHostFromRequest(req): ?string { } export function getIPFromRequest(req): ?string { - const { socket, connection, headers } = req; + + if (USE_XREALIP) { + const ip = req.headers['x-real-ip']; + if (ip) { + return ip; + } + } + + const { socket, connection } = req; let conip = (connection ? connection.remoteAddress : socket.remoteAddress); conip = conip || '0.0.0.1'; - if (USE_XREALIP) { - const ip = headers['x-real-ip']; - return ip || conip; - } + // eslint-disable-next-line max-len + logger.warn( + `Connection not going through nginx and cloudflare! IP: ${conip}`, headers + ); - if (!headers['x-forwarded-for'] || !isTrustedProxy(conip)) { - // eslint-disable-next-line max-len - logger.warn(`Connection not going through nginx and cloudflare! IP: ${conip}`, headers); - return conip; - } - - const forwardedFor = headers['x-forwarded-for']; - const ipList = forwardedFor.split(',').map((str) => str.trim()); - - let ip = ipList.pop(); - while (isTrustedProxy(ip) && ipList.length) { - ip = ipList.pop(); - } - return ip || conip; + return conip; } export function getIPv6Subnet(ip: string): string { diff --git a/src/web.js b/src/web.js index 60f96fc4..055c246d 100644 --- a/src/web.js +++ b/src/web.js @@ -31,7 +31,7 @@ import generateGlobePage from './ssr-components/Globe'; import generateMainPage from './ssr-components/Main'; import { SECOND, MONTH } from './core/constants'; -import { PORT, DISCORD_INVITE, GUILDED_INVITE } from './core/config'; +import { PORT, HOST, GUILDED_INVITE } from './core/config'; import { ccToCoords } from './utils/location'; import { startAllCanvasLoops } from './core/tileserver'; @@ -111,11 +111,8 @@ app.use(express.static(path.join(__dirname, 'public'), { // -// Redirecct to discord and guilded +// Redirecct to guilded // ----------------------------------------------------------------------------- -app.use('/discord', (req, res) => { - res.redirect(DISCORD_INVITE); -}); app.use('/guilded', (req, res) => { res.redirect(GUILDED_INVITE); }); @@ -203,10 +200,13 @@ const promise = models.sync({ alter: { drop: false } }) // const promise = models.sync() .catch((err) => logger.error(err.stack)); promise.then(() => { - server.listen(PORT, () => { + server.listen(PORT, HOST, () => { rankings.updateRanking(); chatProvider.initialize(); const address = server.address(); - logger.log('info', `web is running at http://localhost:${address.port}/`); + logger.log( + 'info', + `web is running at http://${address.host}:${address.port}/`, + ); }); });