| @@ -31,6 +31,8 @@ enableForwardedWhitelist: true | ||
| 31 | 31 | whitelist: |
| 32 | 32 | - ::1 |
| 33 | 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 | 36 | # Toggle basic authentication for endpoints |
| 35 | 37 | basicAuthMode: false |
| 36 | 38 | # Basic authentication credentials |
| @@ -1,6 +1,7 @@ | ||
| 1 | 1 | import path from 'node:path'; |
| 2 | 2 | import fs from 'node:fs'; |
| 3 | 3 | import process from 'node:process'; |
| 4 | +import Handlebars from 'handlebars'; | |
| 4 | 5 | import ipMatching from 'ip-matching'; |
| 5 | 6 | |
| 6 | 7 | import { getIpFromRequest } from '../express-common.js'; |
| @@ -11,6 +12,9 @@ const enableForwardedWhitelist = getConfigValue('enableForwardedWhitelist', fals | ||
| 11 | 12 | let whitelist = getConfigValue('whitelist', []); |
| 12 | 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 | 18 | if (fs.existsSync(whitelistPath)) { |
| 15 | 19 | try { |
| 16 | 20 | let whitelistTxt = fs.readFileSync(whitelistPath, 'utf-8'); |
| @@ -55,9 +59,9 @@ export default function whitelistMiddleware(whitelistMode, listen) { | ||
| 55 | 59 | return function (req, res, next) { |
| 56 | 60 | const clientIp = getIpFromRequest(req); |
| 57 | 61 | const forwardedIp = getForwardedIp(req); |
| 62 | + const userAgent = req.headers['user-agent']; | |
| 58 | 63 | |
| 59 | 64 | if (listen && !knownIPs.has(clientIp)) { |
| 60 | - const userAgent = req.headers['user-agent']; | |
| 61 | 65 | console.log(color.yellow(`New connection from ${clientIp}; User Agent: ${userAgent}\n`)); |
| 62 | 66 | knownIPs.add(clientIp); |
| 63 | 67 | |
| @@ -76,9 +80,21 @@ export default function whitelistMiddleware(whitelistMode, listen) { | ||
| 76 | 80 | || forwardedIp && whitelistMode === true && !whitelist.some(x => ipMatching.matches(forwardedIp, ipMatching.getMatch(x))) |
| 77 | 81 | ) { |
| 78 | 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 | 99 | next(); |
| 84 | 100 | }; |