Customisable header for IP and country code, and improve how country names are handled

merge-requests/208/head
Thomas Lynch 4 years ago
parent fb5299faad
commit 8935ca5c28
  1. 6
      configs/main.js.example
  2. 4
      helpers/checks/dnsbl.js
  3. 10
      helpers/countries.js
  4. 4
      helpers/dnsbl.js
  5. 4
      helpers/processip.js
  6. 14
      models/forms/makepost.js
  7. 5
      models/pages/manage/settings.js
  8. 13
      package-lock.json
  9. 1
      package.json
  10. 262
      views/includes/2charisocountries.pug

@ -27,6 +27,12 @@ module.exports = {
//list of allowed host for checking referrer
allowedHosts: ['domain.com', 'www.domain.com'],
//These 2 are usually not necessary to change. Only if you use a proxy/cdn like cloudflare, and then it probably requires change to nginx config.
//header for country codes, for cloudflare, use 'Cf-Ipcountry'
countryCodeHeader: 'x-country-code',
//header for visitor IP, for cloudflare use 'CF-Connecting-IP'
ipHeader: 'X-Real-IP',
//data used in opengraph meta tags. used to generate link previews in e.g. discord, twitter, etc
meta: {
siteName: 'imageboard',

@ -3,14 +3,14 @@
const cache = require(__dirname+'/../../redis.js')
, dynamicResponse = require(__dirname+'/../dynamic.js')
, deleteTempFiles = require(__dirname+'/../files/deletetempfiles.js')
, { dnsbl, blockBypass } = require(__dirname+'/../../configs/main.js')
, { ipHeader, dnsbl, blockBypass } = require(__dirname+'/../../configs/main.js')
, { batch } = require('dnsbl');
module.exports = async (req, res, next) => {
if (dnsbl.enabled && dnsbl.blacklists.length > 0 //if dnsbl enabled and has more than 0 blacklists
&& (!res.locals.blockBypass || !blockBypass.bypassDnsbl)) { //and there is no valid block bypass, or they do not bypass dnsbl
const ip = req.headers['x-real-ip'] || req.connection.remoteAddress;
const ip = req.headers[ipHeader] || req.connection.remoteAddress;
let isBlacklisted = await cache.get(`blacklisted:${ip}`);
if (isBlacklisted === null) { //not cached
const dnsblResp = await batch(ip, dnsbl.blacklists);

@ -0,0 +1,10 @@
'use strict';
const countries = require('i18n-iso-countries')
, countryNamesMap = countries.getNames('en')
, countryCodes = Object.keys(countryNamesMap);
module.exports = {
countryNamesMap,
countryCodes,
}

@ -2,13 +2,13 @@
const cache = require(__dirname+'/../redis.js')
, dynamicResponse = require(__dirname+'/dynamic.js')
, { dnsbl } = require(__dirname+'/../configs/main.js')
, { ipHeader, dnsbl } = require(__dirname+'/../configs/main.js')
, { batch } = require('dnsbl');
module.exports = async (req, res, next) => {
if (dnsbl.enabled) {
const ip = req.headers['x-real-ip'] || req.connection.remoteAddress;
const ip = req.headers[ipHeader] || req.connection.remoteAddress;
let isBlacklisted = await cache.get(`blacklisted:${ip}`);
if (isBlacklisted === null) { //not cached
const dnsblResp = await batch(ip, dnsbl.blacklists);

@ -1,11 +1,11 @@
'use strict';
const { ipHashPermLevel } = require(__dirname+'/../configs/main.js')
const { ipHeader, ipHashPermLevel } = require(__dirname+'/../configs/main.js')
, { isIP } = require('net')
, hashIp = require(__dirname+'/haship.js');
module.exports = (req, res, next) => {
const ip = req.headers['x-real-ip'] || req.connection.remoteAddress; //need to consider forwarded-for, etc here and in nginx
const ip = req.headers[ipHeader] || req.connection.remoteAddress;
const ipVersion = isIP(ip);
if (ipVersion) {
const delimiter = ipVersion === 4 ? '.' : ':';

@ -1,6 +1,7 @@
'use strict';
const path = require('path')
, { countryNamesMap } = require('../../helpers/countries.js')
, { createHash, randomBytes } = require('crypto')
, { remove, pathExists } = require('fs-extra')
, uploadDirectory = require(__dirname+'/../../helpers/files/uploadDirectory.js')
@ -22,7 +23,7 @@ const path = require('path')
, timeUtils = require(__dirname+'/../../helpers/timeutils.js')
, deletePosts = require(__dirname+'/deletepost.js')
, spamCheck = require(__dirname+'/../../helpers/checks/spamcheck.js')
, { thumbSize, thumbExtension, postPasswordSecret, strictFiltering } = require(__dirname+'/../../configs/main.js')
, { countryCodeHeader, thumbSize, thumbExtension, postPasswordSecret, strictFiltering } = require(__dirname+'/../../configs/main.js')
, buildQueue = require(__dirname+'/../../queue.js')
, dynamicResponse = require(__dirname+'/../../helpers/dynamic.js')
, { buildThread } = require(__dirname+'/../../helpers/tasks.js');
@ -50,11 +51,11 @@ module.exports = async (req, res, next) => {
captchaMode, lockMode, allowedFileTypes, flags } = res.locals.board.settings;
if (flags === true
&& res.locals.permLevel >= 4
&& req.headers['x-country-code']
&& blockedCountries.includes(req.headers['x-country-code'])) {
&& req.headers[countryCodeHeader]
&& blockedCountries.includes(req.headers[countryCodeHeader])) {
return dynamicResponse(req, res, 403, 'message', {
'title': 'Forbidden',
'message': `Your country code ${req.headers['x-country-code']} is not allowed to post on this board`,
'message': `Your country code ${req.headers[countryCodeHeader]} is not allowed to post on this board`,
'redirect': redirect
});
}
@ -312,9 +313,10 @@ module.exports = async (req, res, next) => {
}
let country = null;
if (flags === true) {
const code = req.headers[countryCodeHeader];
country = {
'code': req.headers['x-country-code'],
'name': req.headers['x-country-name']
code,
'name': countryNamesMap[code]
}
}
let password = null;

@ -1,6 +1,7 @@
'use strict';
const { themes, codeThemes } = require(__dirname+'/../../../helpers/themes.js');
const { themes, codeThemes } = require(__dirname+'/../../../helpers/themes.js')
, { countryNamesMap, countryCodes } = require(__dirname+'/../../../helpers/countries.js')
module.exports = async (req, res, next) => {
@ -8,6 +9,8 @@ module.exports = async (req, res, next) => {
.set('Cache-Control', 'private, max-age=5')
.render('managesettings', {
csrf: req.csrfToken(),
countryNamesMap,
countryCodes,
themes,
codeThemes,
});

13
package-lock.json generated

@ -2006,6 +2006,11 @@
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
"integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups="
},
"diacritics": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/diacritics/-/diacritics-1.3.0.tgz",
"integrity": "sha1-PvqHMj67hj5mls67AILUj/PW96E="
},
"dicer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/dicer/-/dicer-0.3.0.tgz",
@ -3879,6 +3884,14 @@
}
}
},
"i18n-iso-countries": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/i18n-iso-countries/-/i18n-iso-countries-6.0.0.tgz",
"integrity": "sha512-2YOLRUNrnOq/sVchB6PfOgZ4E0rRMfxxy+QMhjv+2fiJHMidmmmb24UPHwXmzxyybB8mFPU+/uE46ebLOJIrpQ==",
"requires": {
"diacritics": "1.3.0"
}
},
"iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",

@ -28,6 +28,7 @@
"gulp-pug": "^4.0.1",
"gulp-uglify-es": "^2.0.0",
"highlight.js": "^10.1.2",
"i18n-iso-countries": "^6.0.0",
"ioredis": "^4.14.1",
"mongodb": "^3.6.0",
"node-fetch": "^2.6.0",

@ -1,264 +1,8 @@
-
const codeKeys = ['??', 'AD','AE','AF','AG','AI','AL','AM','AO','AQ','AR','AS','AT','AU','AW','AX','AZ','BA','BB','BD','BE','BF','BG','BH','BI','BJ','BL','BM','BN','BO','BQ','BR','BS','BT','BV','BW','BY','BZ','CA','CC','CD','CF','CG','CH','CI','CK','CL','CM','CN','CO','CR','CU','CV','CW','CX','CY','CZ','DE','DJ','DK','DM','DO','DZ','EC','EE','EG','EH','ER','ES','ET','FI','FJ','FK','FM','FO','FR','GA','GB','GD','GE','GF','GG','GH','GI','GL','GM','GN','GP','GQ','GR','GS','GT','GU','GW','GY','HK','HM','HN','HR','HT','HU','ID','IE','IL','IM','IN','IO','IQ','IR','IS','IT','JE','JM','JO','JP','KE','KG','KH','KI','KM','KN','KP','KR','KW','KY','KZ','LA','LB','LC','LI','LK','LR','LS','LT','LU','LV','LY','MA','MC','MD','ME','MF','MG','MH','MK','ML','MM','MN','MO','MP','MQ','MR','MS','MT','MU','MV','MW','MX','MY','MZ','NA','NC','NE','NF','NG','NI','NL','NO','NP','NR','NU','NZ','OM','PA','PE','PF','PG','PH','PK','PL','PM','PN','PR','PS','PT','PW','PY','QA','RE','RO','RS','RU','RW','SA','SB','SC','SD','SE','SG','SH','SI','SJ','SK','SL','SM','SN','SO','SR','SS','ST','SV','SX','SY','SZ','TC','TD','TF','TG','TH','TJ','TK','TL','TM','TN','TO','TR','TT','TV','TW','TZ','UA','UG','UM','US','UY','UZ','VA','VC','VE','VG','VI','VN','VU','WF','WS','XK','YE','YT','ZA','ZM','ZW'];
const codeMap = {
'??': 'TOR (not implemented yet)',
'AD': 'Andorra',
'AE': 'United Arab Emirates',
'AF': 'Afghanistan',
'AG': 'Antigua and Barbuda',
'AI': 'Anguilla',
'AL': 'Albania',
'AM': 'Armenia',
'AO': 'Angola',
'AQ': 'Antarctica',
'AR': 'Argentina',
'AS': 'American Samoa',
'AT': 'Austria',
'AU': 'Australia',
'AW': 'Aruba',
'AX': 'Aland Islands',
'AZ': 'Azerbaijan',
'BA': 'Bosnia and Herzegovina',
'BB': 'Barbados',
'BD': 'Bangladesh',
'BE': 'Belgium',
'BF': 'Burkina Faso',
'BG': 'Bulgaria',
'BH': 'Bahrain',
'BI': 'Burundi',
'BJ': 'Benin',
'BL': 'Saint Barthelemy',
'BM': 'Bermuda',
'BN': 'Brunei',
'BO': 'Bolivia',
'BQ': 'Bonaire, Saint Eustatius and Saba ',
'BR': 'Brazil',
'BS': 'Bahamas',
'BT': 'Bhutan',
'BV': 'Bouvet Island',
'BW': 'Botswana',
'BY': 'Belarus',
'BZ': 'Belize',
'CA': 'Canada',
'CC': 'Cocos Islands',
'CD': 'Democratic Republic of the Congo',
'CF': 'Central African Republic',
'CG': 'Republic of the Congo',
'CH': 'Switzerland',
'CI': 'Ivory Coast',
'CK': 'Cook Islands',
'CL': 'Chile',
'CM': 'Cameroon',
'CN': 'China',
'CO': 'Colombia',
'CR': 'Costa Rica',
'CU': 'Cuba',
'CV': 'Cape Verde',
'CW': 'Curacao',
'CX': 'Christmas Island',
'CY': 'Cyprus',
'CZ': 'Czech Republic',
'DE': 'Germany',
'DJ': 'Djibouti',
'DK': 'Denmark',
'DM': 'Dominica',
'DO': 'Dominican Republic',
'DZ': 'Algeria',
'EC': 'Ecuador',
'EE': 'Estonia',
'EG': 'Egypt',
'EH': 'Western Sahara',
'ER': 'Eritrea',
'ES': 'Spain',
'ET': 'Ethiopia',
'FI': 'Finland',
'FJ': 'Fiji',
'FK': 'Falkland Islands',
'FM': 'Micronesia',
'FO': 'Faroe Islands',
'FR': 'France',
'GA': 'Gabon',
'GB': 'United Kingdom',
'GD': 'Grenada',
'GE': 'Georgia',
'GF': 'French Guiana',
'GG': 'Guernsey',
'GH': 'Ghana',
'GI': 'Gibraltar',
'GL': 'Greenland',
'GM': 'Gambia',
'GN': 'Guinea',
'GP': 'Guadeloupe',
'GQ': 'Equatorial Guinea',
'GR': 'Greece',
'GS': 'South Georgia and the South Sandwich Islands',
'GT': 'Guatemala',
'GU': 'Guam',
'GW': 'Guinea-Bissau',
'GY': 'Guyana',
'HK': 'Hong Kong',
'HM': 'Heard Island and McDonald Islands',
'HN': 'Honduras',
'HR': 'Croatia',
'HT': 'Haiti',
'HU': 'Hungary',
'ID': 'Indonesia',
'IE': 'Ireland',
'IL': 'Israel',
'IM': 'Isle of Man',
'IN': 'India',
'IO': 'British Indian Ocean Territory',
'IQ': 'Iraq',
'IR': 'Iran',
'IS': 'Iceland',
'IT': 'Italy',
'JE': 'Jersey',
'JM': 'Jamaica',
'JO': 'Jordan',
'JP': 'Japan',
'KE': 'Kenya',
'KG': 'Kyrgyzstan',
'KH': 'Cambodia',
'KI': 'Kiribati',
'KM': 'Comoros',
'KN': 'Saint Kitts and Nevis',
'KP': 'North Korea',
'KR': 'South Korea',
'KW': 'Kuwait',
'KY': 'Cayman Islands',
'KZ': 'Kazakhstan',
'LA': 'Laos',
'LB': 'Lebanon',
'LC': 'Saint Lucia',
'LI': 'Liechtenstein',
'LK': 'Sri Lanka',
'LR': 'Liberia',
'LS': 'Lesotho',
'LT': 'Lithuania',
'LU': 'Luxembourg',
'LV': 'Latvia',
'LY': 'Libya',
'MA': 'Morocco',
'MC': 'Monaco',
'MD': 'Moldova',
'ME': 'Montenegro',
'MF': 'Saint Martin',
'MG': 'Madagascar',
'MH': 'Marshall Islands',
'MK': 'Macedonia',
'ML': 'Mali',
'MM': 'Myanmar',
'MN': 'Mongolia',
'MO': 'Macao',
'MP': 'Northern Mariana Islands',
'MQ': 'Martinique',
'MR': 'Mauritania',
'MS': 'Montserrat',
'MT': 'Malta',
'MU': 'Mauritius',
'MV': 'Maldives',
'MW': 'Malawi',
'MX': 'Mexico',
'MY': 'Malaysia',
'MZ': 'Mozambique',
'NA': 'Namibia',
'NC': 'New Caledonia',
'NE': 'Niger',
'NF': 'Norfolk Island',
'NG': 'Nigeria',
'NI': 'Nicaragua',
'NL': 'Netherlands',
'NO': 'Norway',
'NP': 'Nepal',
'NR': 'Nauru',
'NU': 'Niue',
'NZ': 'New Zealand',
'OM': 'Oman',
'PA': 'Panama',
'PE': 'Peru',
'PF': 'French Polynesia',
'PG': 'Papua New Guinea',
'PH': 'Philippines',
'PK': 'Pakistan',
'PL': 'Poland',
'PM': 'Saint Pierre and Miquelon',
'PN': 'Pitcairn',
'PR': 'Puerto Rico',
'PS': 'Palestinian Territory',
'PT': 'Portugal',
'PW': 'Palau',
'PY': 'Paraguay',
'QA': 'Qatar',
'RE': 'Reunion',
'RO': 'Romania',
'RS': 'Serbia',
'RU': 'Russia',
'RW': 'Rwanda',
'SA': 'Saudi Arabia',
'SB': 'Solomon Islands',
'SC': 'Seychelles',
'SD': 'Sudan',
'SE': 'Sweden',
'SG': 'Singapore',
'SH': 'Saint Helena',
'SI': 'Slovenia',
'SJ': 'Svalbard and Jan Mayen',
'SK': 'Slovakia',
'SL': 'Sierra Leone',
'SM': 'San Marino',
'SN': 'Senegal',
'SO': 'Somalia',
'SR': 'Suriname',
'SS': 'South Sudan',
'ST': 'Sao Tome and Principe',
'SV': 'El Salvador',
'SX': 'Sint Maarten',
'SY': 'Syria',
'SZ': 'Swaziland',
'TC': 'Turks and Caicos Islands',
'TD': 'Chad',
'TF': 'French Southern Territories',
'TG': 'Togo',
'TH': 'Thailand',
'TJ': 'Tajikistan',
'TK': 'Tokelau',
'TL': 'East Timor',
'TM': 'Turkmenistan',
'TN': 'Tunisia',
'TO': 'Tonga',
'TR': 'Turkey',
'TT': 'Trinidad and Tobago',
'TV': 'Tuvalu',
'TW': 'Taiwan',
'TZ': 'Tanzania',
'UA': 'Ukraine',
'UG': 'Uganda',
'UM': 'United States Minor Outlying Islands',
'US': 'United States',
'UY': 'Uruguay',
'UZ': 'Uzbekistan',
'VA': 'Vatican',
'VC': 'Saint Vincent and the Grenadines',
'VE': 'Venezuela',
'VG': 'British Virgin Islands',
'VI': 'U.S. Virgin Islands',
'VN': 'Vietnam',
'VU': 'Vanuatu',
'WF': 'Wallis and Futuna',
'WS': 'Samoa',
'XK': 'Kosovo',
'YE': 'Yemen',
'YT': 'Mayotte',
'ZA': 'South Africa',
'ZM': 'Zambia',
'ZW': 'Zimbabwe'
}
- const blockedCountries = new Set(board.settings.blockedCountries);
select(name='countries' size='10' multiple)
optgroup(label='Currently blocked')
each code in board.settings.blockedCountries
option(value=code selected=true) #{codeMap[code]}
option(value=code selected=true) #{countryNamesMap[code]}
optgroup(label='Not blocked')
each code in codeKeys.filter(c => !blockedCountries.has(c))
option(value=code) #{codeMap[code]}
each code in countryCodes.filter(c => !blockedCountries.has(c))
option(value=code) #{countryNamesMap[code]}

Loading…
Cancel
Save