From 4da104211bdec80f83849cff8eb5144575510ae4 Mon Sep 17 00:00:00 2001 From: maver Date: Sun, 23 Apr 2023 18:09:23 +0200 Subject: [PATCH 1/4] Add basic authentication middleware --- src/middleware/basicAuthMiddleware.js | 39 +++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/middleware/basicAuthMiddleware.js diff --git a/src/middleware/basicAuthMiddleware.js b/src/middleware/basicAuthMiddleware.js new file mode 100644 index 000000000..2f368214c --- /dev/null +++ b/src/middleware/basicAuthMiddleware.js @@ -0,0 +1,39 @@ +/** + * When applied, this middleware will ensure the request contains the required header for basic authentication and only + * allow access to the endpoint after successful authentication. + */ + +const {dirname} = require('path'); +const appDir = dirname(require.main.filename); +const config = require(appDir + '/config.conf'); + +const unauthorizedResponse = (res) => { + res.set('WWW-Authenticate', 'Basic realm="SillyTavern", charset="UTF-8"'); + return res.status(401).send('Authentication required'); +}; + +const basicAuthMiddleware = function (request, response, callback) { + const authHeader = request.headers.authorization; + + if (!authHeader) { + return unauthorizedResponse(response); + } + + const [scheme, credentials] = authHeader.split(' '); + + if (scheme !== 'Basic' || !credentials) { + return unauthorizedResponse(response); + } + + const [username, password] = Buffer.from(credentials, 'base64') + .toString('utf8') + .split(':'); + + if (username === config.basicAuthUser.username && password === config.basicAuthUser.password) { + return callback(); + } else { + return unauthorizedResponse(response); + } +} + +module.exports = basicAuthMiddleware; \ No newline at end of file From c821b1fba43b7c78f3c4289811e6b3edaba7063b Mon Sep 17 00:00:00 2001 From: maver Date: Sun, 23 Apr 2023 18:10:44 +0200 Subject: [PATCH 2/4] Add option to start server with basic authentication enabled --- config.conf | 6 ++++-- server.js | 3 +++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/config.conf b/config.conf index 8cb18a2b2..f155916ad 100644 --- a/config.conf +++ b/config.conf @@ -1,11 +1,13 @@ const port = 8000; const whitelist = ['127.0.0.1']; //Example for add several IP in whitelist: ['127.0.0.1', '192.168.0.10'] -const whitelistMode = true; //Disabling enabling the ip whitelist mode. true/false +const whitelistMode = false; //Disabling enabling the ip whitelist mode. true/false +const basicAuthMode = false; //Toggle basic authentication for endpoints. +const basicAuthUser = {username: "user", password: "password"}; //Login credentials when basicAuthMode is true. const autorun = true; //Autorun in the browser. true/false const enableExtensions = true; //Enables support for TavernAI-extras project const listen = true; // If true, Can be access from other device or PC. otherwise can be access only from hosting machine. module.exports = { - port, whitelist, whitelistMode, autorun, enableExtensions, listen + port, whitelist, whitelistMode, basicAuthMode, basicAuthUser, autorun, enableExtensions, listen }; diff --git a/server.js b/server.js index c7fd4a199..afb5a89cf 100644 --- a/server.js +++ b/server.js @@ -35,6 +35,7 @@ const rimraf = require("rimraf"); const multer = require("multer"); const http = require("http"); const https = require('https'); +const basicAuthMiddleware = require('./src/middleware/basicAuthMiddleware'); //const PNG = require('pngjs').PNG; const extract = require('png-chunks-extract'); const encode = require('png-chunks-encode'); @@ -194,6 +195,8 @@ const CORS = cors({ app.use(CORS); +if (listen && config.basicAuthMode) app.use(basicAuthMiddleware); + app.use(function (req, res, next) { //Security let clientIp = req.connection.remoteAddress; let ip = ipaddr.parse(clientIp); From 8be863b50be9793b308d1af49075a57f2f74d041 Mon Sep 17 00:00:00 2001 From: maver Date: Sun, 23 Apr 2023 18:11:28 +0200 Subject: [PATCH 3/4] Warn user when no whitelist or auth method is chosen And the server is publicly available --- server.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/server.js b/server.js index afb5a89cf..4ccadf8a9 100644 --- a/server.js +++ b/server.js @@ -2398,6 +2398,10 @@ const setupTasks = async function () { if (autorun) open(autorunUrl.toString()); console.log('SillyTavern is listening on: ' + tavernUrl); + if (listen && + !config.whitelistMode && + !config.basicAuthMode) + console.log('Your SillyTavern is currently open to the public. To increase security, consider enabling whitelisting or basic authentication.') if (fs.existsSync('public/characters/update.txt') && !is_colab) { convertStage1(); From 566675256817eafbaf1370cd752410b467320d97 Mon Sep 17 00:00:00 2001 From: maver Date: Sun, 23 Apr 2023 18:31:47 +0200 Subject: [PATCH 4/4] Set whitelistMode to true by default --- config.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.conf b/config.conf index f155916ad..77c6b85ad 100644 --- a/config.conf +++ b/config.conf @@ -1,7 +1,7 @@ const port = 8000; const whitelist = ['127.0.0.1']; //Example for add several IP in whitelist: ['127.0.0.1', '192.168.0.10'] -const whitelistMode = false; //Disabling enabling the ip whitelist mode. true/false +const whitelistMode = true; //Disabling enabling the ip whitelist mode. true/false const basicAuthMode = false; //Toggle basic authentication for endpoints. const basicAuthUser = {username: "user", password: "password"}; //Login credentials when basicAuthMode is true. const autorun = true; //Autorun in the browser. true/false