| @@ -31,6 +31,8 @@ enableForwardedWhitelist: true | |||
| 31 | whitelist: | 31 | whitelist: |
| 32 | - ::1 | 32 | - ::1 |
| 33 | - 127.0.0.1 | 33 | - 127.0.0.1 |
| 34 | # HTML displayed when a connection is blocked. Use "{{ipDetails}}" to print the client's IP. | ||
| 35 | whitelistErrorMessage: "<h1>Forbidden</h1><p>If you are the system administrator, add your IP address to the whitelist or disable whitelist mode by editing <code>config.yaml</code> in the root directory of your installation.</p><hr /><p><em>Connection from {{ipDetails}} has been blocked. This attempt has been logged.</em></p>" | ||
| 34 | # Toggle basic authentication for endpoints | 36 | # Toggle basic authentication for endpoints |
| 35 | basicAuthMode: false | 37 | basicAuthMode: false |
| 36 | # Basic authentication credentials | 38 | # Basic authentication credentials |
| @@ -1,6 +1,7 @@ | |||
| 1 | import path from 'node:path'; | 1 | import path from 'node:path'; |
| 2 | import fs from 'node:fs'; | 2 | import fs from 'node:fs'; |
| 3 | import process from 'node:process'; | 3 | import process from 'node:process'; |
| 4 | import Handlebars from 'handlebars'; | ||
| 4 | import ipMatching from 'ip-matching'; | 5 | import ipMatching from 'ip-matching'; |
| 5 | 6 | ||
| 6 | import { getIpFromRequest } from '../express-common.js'; | 7 | import { getIpFromRequest } from '../express-common.js'; |
| @@ -11,6 +12,9 @@ const enableForwardedWhitelist = getConfigValue('enableForwardedWhitelist', fals | |||
| 11 | let whitelist = getConfigValue('whitelist', []); | 12 | let whitelist = getConfigValue('whitelist', []); |
| 12 | let knownIPs = new Set(); | 13 | let knownIPs = new Set(); |
| 13 | 14 | ||
| 15 | const DEFAULT_WHITELIST_ERROR_MESSAGE = | ||
| 16 | '<h1>Forbidden</h1><p>If you are the system administrator, add your IP address to the whitelist or disable whitelist mode by editing <code>config.yaml</code> in the root directory of your installation.</p><hr /><p><em>Connection from {{ipDetails}} has been blocked. This attempt has been logged.</em></p>'; | ||
| 17 | |||
| 14 | if (fs.existsSync(whitelistPath)) { | 18 | if (fs.existsSync(whitelistPath)) { |
| 15 | try { | 19 | try { |
| 16 | let whitelistTxt = fs.readFileSync(whitelistPath, 'utf-8'); | 20 | let whitelistTxt = fs.readFileSync(whitelistPath, 'utf-8'); |
| @@ -55,9 +59,9 @@ export default function whitelistMiddleware(whitelistMode, listen) { | |||
| 55 | return function (req, res, next) { | 59 | return function (req, res, next) { |
| 56 | const clientIp = getIpFromRequest(req); | 60 | const clientIp = getIpFromRequest(req); |
| 57 | const forwardedIp = getForwardedIp(req); | 61 | const forwardedIp = getForwardedIp(req); |
| 62 | const userAgent = req.headers['user-agent']; | ||
| 58 | 63 | ||
| 59 | if (listen && !knownIPs.has(clientIp)) { | 64 | if (listen && !knownIPs.has(clientIp)) { |
| 60 | const userAgent = req.headers['user-agent']; | ||
| 61 | console.log(color.yellow(`New connection from ${clientIp}; User Agent: ${userAgent}\n`)); | 65 | console.log(color.yellow(`New connection from ${clientIp}; User Agent: ${userAgent}\n`)); |
| 62 | knownIPs.add(clientIp); | 66 | knownIPs.add(clientIp); |
| 63 | 67 | ||
| @@ -76,9 +80,21 @@ export default function whitelistMiddleware(whitelistMode, listen) { | |||
| 76 | || forwardedIp && whitelistMode === true && !whitelist.some(x => ipMatching.matches(forwardedIp, ipMatching.getMatch(x))) | 80 | || forwardedIp && whitelistMode === true && !whitelist.some(x => ipMatching.matches(forwardedIp, ipMatching.getMatch(x))) |
| 77 | ) { | 81 | ) { |
| 78 | // Log the connection attempt with real IP address | 82 | // Log the connection attempt with real IP address |
| 79 | const ipDetails = forwardedIp ? `${clientIp} (forwarded from ${forwardedIp})` : clientIp; | 83 | const ipDetails = forwardedIp |
| 80 | console.log(color.red('Forbidden: Connection attempt from ' + ipDetails + '. If you are attempting to connect, please add your IP address in whitelist or disable whitelist mode in config.yaml in root of SillyTavern folder.\n')); | 84 | ? `${clientIp} (forwarded from ${forwardedIp})` |
| 81 | return res.status(403).send('<b>Forbidden</b>: Connection attempt from <b>' + ipDetails + '</b>. If you are attempting to connect, please add your IP address in whitelist or disable whitelist mode in config.yaml in root of SillyTavern folder.'); | 85 | : clientIp; |
| 86 | const errorMessage = Handlebars.compile( | ||
| 87 | getConfigValue( | ||
| 88 | 'whitelistErrorMessage', | ||
| 89 | DEFAULT_WHITELIST_ERROR_MESSAGE, | ||
| 90 | ), | ||
| 91 | ); | ||
| 92 | console.log( | ||
| 93 | color.red( | ||
| 94 | `Blocked connection from ${clientIp}; User Agent: ${userAgent}\n\tTo allow this connection, add its IP address to the whitelist or disable whitelist mode by editing config.yaml in the root directory of your SillyTavern installation.\n`, | ||
| 95 | ), | ||
| 96 | ); | ||
| 97 | return res.status(403).send(errorMessage({ ipDetails })); | ||
| 82 | } | 98 | } |
| 83 | next(); | 99 | next(); |
| 84 | }; | 100 | }; |