2023-12-14 17:36:41 -05:00
const path = require ( 'path' ) ;
const fs = require ( 'fs' ) ;
const ipaddr = require ( 'ipaddr.js' ) ;
const ipMatching = require ( 'ip-matching' ) ;
const { color , getConfigValue } = require ( '../util' ) ;
const whitelistPath = path . join ( process . cwd ( ) , './whitelist.txt' ) ;
let whitelist = getConfigValue ( 'whitelist' , [ ] ) ;
2023-12-15 18:43:00 +02:00
let knownIPs = new Set ( ) ;
const whitelistMode = getConfigValue ( 'whitelistMode' , true ) ;
2023-12-14 17:36:41 -05:00
if ( fs . existsSync ( whitelistPath ) ) {
try {
let whitelistTxt = fs . readFileSync ( whitelistPath , 'utf-8' ) ;
whitelist = whitelistTxt . split ( '\n' ) . filter ( ip => ip ) . map ( ip => ip . trim ( ) ) ;
} catch ( e ) {
// Ignore errors that may occur when reading the whitelist (e.g. permissions)
}
}
function getIpFromRequest ( req ) {
let clientIp = req . connection . remoteAddress ;
let ip = ipaddr . parse ( clientIp ) ;
// Check if the IP address is IPv4-mapped IPv6 address
if ( ip . kind ( ) === 'ipv6' && ip instanceof ipaddr . IPv6 && ip . isIPv4MappedAddress ( ) ) {
const ipv4 = ip . toIPv4Address ( ) . toString ( ) ;
clientIp = ipv4 ;
} else {
clientIp = ip ;
clientIp = clientIp . toString ( ) ;
}
return clientIp ;
}
2024-03-30 22:42:51 +02:00
/ * *
* Returns a middleware function that checks if the client IP is in the whitelist .
* @ param { boolean } listen If listen mode is enabled via config or command line
* @ returns { import ( 'express' ) . RequestHandler } The middleware function
* /
function whitelistMiddleware ( listen ) {
return function ( req , res , next ) {
const clientIp = getIpFromRequest ( req ) ;
2023-12-14 17:36:41 -05:00
2024-03-30 22:42:51 +02:00
if ( listen && ! knownIPs . has ( clientIp ) ) {
const userAgent = req . headers [ 'user-agent' ] ;
console . log ( color . yellow ( ` New connection from ${ clientIp } ; User Agent: ${ userAgent } \n ` ) ) ;
knownIPs . add ( clientIp ) ;
// Write access log
const timestamp = new Date ( ) . toISOString ( ) ;
const log = ` ${ timestamp } ${ clientIp } ${ userAgent } \n ` ;
fs . appendFile ( 'access.log' , log , ( err ) => {
if ( err ) {
console . error ( 'Failed to write access log:' , err ) ;
}
} ) ;
}
//clientIp = req.connection.remoteAddress.split(':').pop();
if ( whitelistMode === true && ! whitelist . some ( x => ipMatching . matches ( clientIp , ipMatching . getMatch ( x ) ) ) ) {
console . log ( color . red ( 'Forbidden: Connection attempt from ' + clientIp + '. 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' ) ) ;
return res . status ( 403 ) . send ( '<b>Forbidden</b>: Connection attempt from <b>' + clientIp + '</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.' ) ;
}
next ( ) ;
} ;
}
2023-12-14 17:36:41 -05:00
module . exports = whitelistMiddleware ;