From 4caec7c8579087060d143ddc64bd0f4875841e76 Mon Sep 17 00:00:00 2001 From: Grzegorz Gidel Date: Sat, 22 Apr 2023 18:12:22 +0200 Subject: [PATCH 01/11] Avoid usage of 'var' in Generate() to make reasoning about the code easier --- public/script.js | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/public/script.js b/public/script.js index 277453e37..175e08b59 100644 --- a/public/script.js +++ b/public/script.js @@ -1351,15 +1351,16 @@ async function Generate(type, automatic_trigger, force_name2) { } if (online_status != 'no_connection' && this_chid != undefined && this_chid !== 'invalid-safety-id') { + let textareaText; if (type !== 'regenerate' && type !== "swipe" && !isImpersonate) { is_send_press = true; - var textareaText = $("#send_textarea").val(); + textareaText = $("#send_textarea").val(); //console.log('Not a Regenerate call, so posting normall with input of: ' +textareaText); $("#send_textarea").val('').trigger('input'); } else { //console.log('Regenerate call detected') - var textareaText = ""; + textareaText = ""; if (chat.length && chat[chat.length - 1]['is_user']) {//If last message from You } @@ -1392,14 +1393,13 @@ async function Generate(type, automatic_trigger, force_name2) { promptBias = messageBias ?? promptBias ?? ''; - var storyString = ""; - var userSendString = ""; - var finalPromt = ""; - var postAnchorChar = "Elaborate speaker"; - var postAnchorStyle = "Writing style: very long messages";//"[Genre: roleplay chat][Tone: very long messages with descriptions]"; - var anchorTop = ''; - var anchorBottom = ''; - var topAnchorDepth = 8; + let storyString = ""; + let finalPromt = ""; + let postAnchorChar = "Elaborate speaker"; + let postAnchorStyle = "Writing style: very long messages";//"[Genre: roleplay chat][Tone: very long messages with descriptions]"; + let anchorTop = ''; + let anchorBottom = ''; + const topAnchorDepth = 8; if (character_anchor && !is_pygmalion) { console.log('saw not pyg'); @@ -1506,12 +1506,12 @@ async function Generate(type, automatic_trigger, force_name2) { ////////////////////////////////// - var count_exm_add = 0; + let count_exm_add = 0; console.log('emptying chat2'); - var chat2 = []; - var j = 0; + let chat2 = []; + let j = 0; console.log('pre-replace chat.length = ' + chat.length); - for (var i = chat.length - 1; i >= 0; i--) { + for (let i = chat.length - 1; i >= 0; i--) { let charName = selected_group ? chat[j].name : name2; if (j == 0) { chat[j]['mes'] = chat[j]['mes'].replace(/{{user}}/gi, name1); @@ -1543,7 +1543,7 @@ async function Generate(type, automatic_trigger, force_name2) { } console.log('post replace chat.length = ' + chat.length); //chat2 = chat2.reverse(); - var this_max_context = 1487; + let this_max_context = 1487; if (main_api == 'kobold' || main_api == 'textgenerationwebui') { this_max_context = (max_context - amount_gen); } @@ -1594,14 +1594,14 @@ async function Generate(type, automatic_trigger, force_name2) { let { worldInfoString, worldInfoBefore, worldInfoAfter } = getWorldInfoPrompt(chat2); console.log('post swipe shift:' + chat2.length); - var i = 0; + let i = 0; // hack for regeneration of the first message if (chat2.length == 0) { chat2.push(''); } - for (var item of chat2) { + for (let item of chat2) { chatString = item + chatString; const encodeString = JSON.stringify( worldInfoString + storyString + chatString + @@ -1666,7 +1666,7 @@ async function Generate(type, automatic_trigger, force_name2) { console.log('generating prompt'); chatString = ""; arrMes = arrMes.reverse(); - var is_add_personality = false; + let is_add_personality = false; arrMes.forEach(function (item, i, arr) {//For added anchors and others if (i >= arrMes.length - 1 && $.trim(item).substr(0, (name1 + ":").length) != name1 + ":") { @@ -1859,9 +1859,9 @@ async function Generate(type, automatic_trigger, force_name2) { this_amount_gen = Math.min(this_amount_gen, hordeAmountGen); } - var generate_data; + let generate_data; if (main_api == 'kobold') { - var generate_data = { + generate_data = { prompt: finalPromt, gui_settings: true, max_length: amount_gen, @@ -1929,7 +1929,7 @@ async function Generate(type, automatic_trigger, force_name2) { }; } - var generate_url = ''; + let generate_url = ''; if (main_api == 'kobold') { generate_url = '/generate'; } else if (main_api == 'textgenerationwebui') { From 2dfb41d46113732f078485a708e1ff9bc2df0f06 Mon Sep 17 00:00:00 2001 From: Grzegorz Gidel Date: Sat, 22 Apr 2023 16:08:24 +0200 Subject: [PATCH 02/11] Simplify anchor selection code --- public/script.js | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/public/script.js b/public/script.js index 175e08b59..ee79b058c 100644 --- a/public/script.js +++ b/public/script.js @@ -1395,26 +1395,26 @@ async function Generate(type, automatic_trigger, force_name2) { let storyString = ""; let finalPromt = ""; - let postAnchorChar = "Elaborate speaker"; - let postAnchorStyle = "Writing style: very long messages";//"[Genre: roleplay chat][Tone: very long messages with descriptions]"; let anchorTop = ''; let anchorBottom = ''; const topAnchorDepth = 8; - if (character_anchor && !is_pygmalion) { + // Compute anchors + if (!is_pygmalion) { console.log('saw not pyg'); + + let postAnchorChar = character_anchor ? name2 + " Elaborate speaker" : ""; + let postAnchorStyle = style_anchor ? "Writing style: very long messages" : ""; if (anchor_order === 0) { - anchorTop = name2 + " " + postAnchorChar; - } else { - console.log('saw pyg, adding anchors') - anchorBottom = "[" + name2 + " " + postAnchorChar + "]"; - } - } - if (style_anchor && !is_pygmalion) { - if (anchor_order === 1) { + anchorTop = postAnchorChar; + anchorBottom = postAnchorStyle; + } else { // anchor_order === 1 anchorTop = postAnchorStyle; - } else { - anchorBottom = "[" + postAnchorStyle + "]"; + anchorBottom = postAnchorChar; + } + + if (anchorBottom) { + anchorBottom = "[" + anchorBottom + "]"; } } From c7fa0c594a4424bccb88ac6059c0dc9cffecb950 Mon Sep 17 00:00:00 2001 From: Grzegorz Gidel Date: Sat, 22 Apr 2023 16:59:52 +0200 Subject: [PATCH 03/11] Improve locality of declarations and visual separation of code --- public/script.js | 39 +++++++++++++++++---------------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/public/script.js b/public/script.js index ee79b058c..d38550c20 100644 --- a/public/script.js +++ b/public/script.js @@ -1321,11 +1321,11 @@ async function Generate(type, automatic_trigger, force_name2) { //console.log('Generate entered'); setGenerationProgress(0); tokens_already_generated = 0; + const isImpersonate = type == "impersonate"; message_already_generated = isImpersonate ? `${name1}: ` : `${name2}: `; const slashCommand = getSlashCommand($("#send_textarea").val(), type); - if (slashCommand == system_message_types.HELP) { sendSystemMessage(system_message_types.HELP); $("#send_textarea").val('').trigger('input'); @@ -1340,8 +1340,7 @@ async function Generate(type, automatic_trigger, force_name2) { if (isStreamingEnabled()) { streamingProcessor = new StreamingProcessor(type, force_name2); hideSwipeButtons(); - } - else { + } else { streamingProcessor = false; } @@ -1390,16 +1389,12 @@ async function Generate(type, automatic_trigger, force_name2) { } // bias from the latest message is top priority// - promptBias = messageBias ?? promptBias ?? ''; - let storyString = ""; - let finalPromt = ""; + // Compute anchors + const topAnchorDepth = 8; let anchorTop = ''; let anchorBottom = ''; - const topAnchorDepth = 8; - - // Compute anchors if (!is_pygmalion) { console.log('saw not pyg'); @@ -1438,22 +1433,18 @@ async function Generate(type, automatic_trigger, force_name2) { addOneMessage(chat[chat.length - 1]); } //////////////////////////////////// - let chatString = ''; - let arrMes = []; - let mesSend = []; let charDescription = baseChatReplace($.trim(characters[this_chid].description), name1, name2); let charPersonality = baseChatReplace($.trim(characters[this_chid].personality), name1, name2); let Scenario = baseChatReplace($.trim(characters[this_chid].scenario), name1, name2); let mesExamples = baseChatReplace($.trim(characters[this_chid].mes_example), name1, name2); + // Parse example messages if (!mesExamples.startsWith('')) { mesExamples = '\n' + mesExamples.trim(); } - if (mesExamples.replace(//gi, '').trim().length === 0) { mesExamples = ''; } - let mesExamplesArray = mesExamples.split(//gi).slice(1).map(block => `\n${block.trim()}\n`); if (main_api === 'openai') { @@ -1467,6 +1458,8 @@ async function Generate(type, automatic_trigger, force_name2) { setOpenAIMessageExamples(mesExamplesArray); } + let storyString = ""; + if (is_pygmalion) { storyString += appendToStoryString(charDescription, power_user.disable_description_formatting ? '' : name2 + "'s Persona: "); storyString += appendToStoryString(charPersonality, power_user.disable_personality_formatting ? '' : 'Personality: '); @@ -1506,12 +1499,10 @@ async function Generate(type, automatic_trigger, force_name2) { ////////////////////////////////// - let count_exm_add = 0; console.log('emptying chat2'); let chat2 = []; - let j = 0; console.log('pre-replace chat.length = ' + chat.length); - for (let i = chat.length - 1; i >= 0; i--) { + for (let i = chat.length - 1, j = 0; i >= 0; i--, j++) { let charName = selected_group ? chat[j].name : name2; if (j == 0) { chat[j]['mes'] = chat[j]['mes'].replace(/{{user}}/gi, name1); @@ -1539,10 +1530,11 @@ async function Generate(type, automatic_trigger, force_name2) { //chat2[i] = (chat2[i] ?? '').replace(/{.*}/g, ''); chat2[i] = (chat2[i] ?? '').replace(/{{(\*?.+?\*?)}}/g, ''); //console.log('replacing chat2 {}s'); - j++; } console.log('post replace chat.length = ' + chat.length); //chat2 = chat2.reverse(); + + // Determine token limit let this_max_context = 1487; if (main_api == 'kobold' || main_api == 'textgenerationwebui') { this_max_context = (max_context - amount_gen); @@ -1560,11 +1552,11 @@ async function Generate(type, automatic_trigger, force_name2) { if (main_api == 'openai') { this_max_context = oai_settings.openai_max_context; } - if (main_api == 'poe') { this_max_context = Number(max_context); } + // Adjust token limit for Horde let hordeAmountGen = null; if (main_api == 'kobold' && horde_settings.use_horde && horde_settings.auto_adjust) { let adjustedParams; @@ -1594,13 +1586,17 @@ async function Generate(type, automatic_trigger, force_name2) { let { worldInfoString, worldInfoBefore, worldInfoAfter } = getWorldInfoPrompt(chat2); console.log('post swipe shift:' + chat2.length); - let i = 0; // hack for regeneration of the first message if (chat2.length == 0) { chat2.push(''); } + let chatString = ''; + let arrMes = []; + let mesSend = []; + let count_exm_add = 0; + let i = 0; for (let item of chat2) { chatString = item + chatString; const encodeString = JSON.stringify( @@ -1675,7 +1671,6 @@ async function Generate(type, automatic_trigger, force_name2) { } } if (i === arrMes.length - topAnchorDepth && count_view_mes >= topAnchorDepth && !is_add_personality) { - is_add_personality = true; //chatString = chatString.substr(0,chatString.length-1); //anchorAndPersonality = "[Genre: roleplay chat][Tone: very long messages with descriptions]"; @@ -1800,7 +1795,7 @@ async function Generate(type, automatic_trigger, force_name2) { mesSendString = '\n' + mesSendString; //mesSendString = mesSendString; //This edit simply removes the first "" that is prepended to all context prompts } - finalPromt = worldInfoBefore + storyString + worldInfoAfter + afterScenarioAnchor + mesExmString + mesSendString + generatedPromtCache + promptBias; + let finalPromt = worldInfoBefore + storyString + worldInfoAfter + afterScenarioAnchor + mesExmString + mesSendString + generatedPromtCache + promptBias; if (zeroDepthAnchor && zeroDepthAnchor.length) { if (!isMultigenEnabled() || tokens_already_generated == 0) { From 248f8b57a26dad06e476eb2e224761a8bead8538 Mon Sep 17 00:00:00 2001 From: Grzegorz Gidel Date: Sat, 22 Apr 2023 20:23:19 +0200 Subject: [PATCH 04/11] Simplify the message gathering loop --- public/script.js | 71 ++++++++++++++++++++++-------------------------- 1 file changed, 32 insertions(+), 39 deletions(-) diff --git a/public/script.js b/public/script.js index d38550c20..d55885047 100644 --- a/public/script.js +++ b/public/script.js @@ -1592,11 +1592,9 @@ async function Generate(type, automatic_trigger, force_name2) { chat2.push(''); } + // Collect enough messages to fill the context let chatString = ''; let arrMes = []; - let mesSend = []; - let count_exm_add = 0; - let i = 0; for (let item of chat2) { chatString = item + chatString; const encodeString = JSON.stringify( @@ -1609,47 +1607,42 @@ async function Generate(type, automatic_trigger, force_name2) { //if (is_pygmalion && i == chat2.length-1) item='\n'+item; arrMes[arrMes.length] = item; } else { - console.log('reducing chat.length by 1'); - i = chat2.length - 1; + break; } await delay(1); //For disable slow down (encode gpt-2 need fix) - // console.log(i+' '+chat.length); - - count_exm_add = 0; - - if (i === chat2.length - 1) { - if (!power_user.pin_examples) { - let mesExmString = ''; - for (let iii = 0; iii < mesExamplesArray.length; iii++) { - mesExmString += mesExamplesArray[iii]; - const prompt = JSON.stringify(worldInfoString + storyString + mesExmString + chatString + anchorTop + anchorBottom + charPersonality + promptBias + allAnchors); - const tokenCount = getTokenCount(prompt, padding_tokens); - if (tokenCount < this_max_context) { - if (power_user.disable_examples_formatting) { - mesExamplesArray[iii] = mesExamplesArray[iii].replace(//i, ''); - } - - if (!is_pygmalion) { - mesExamplesArray[iii] = mesExamplesArray[iii].replace(//i, `This is how ${name2} should talk`); - } - count_exm_add++; - await delay(1); - } else { - iii = mesExamplesArray.length; - } - } - } - if (!is_pygmalion && Scenario && Scenario.length > 0) { - storyString += !power_user.disable_scenario_formatting ? `Circumstances and context of the dialogue: ${Scenario}\n` : `${Scenario}\n`; - } - console.log('calling runGenerate'); - await runGenerate(); - return; - } - i++; } + // Prepare unpinned example messages + let count_exm_add = 0; + if (!power_user.pin_examples) { + let mesExmString = ''; + for (let i = 0; i < mesExamplesArray.length; i++) { + mesExmString += mesExamplesArray[i]; + const prompt = JSON.stringify(worldInfoString + storyString + mesExmString + chatString + anchorTop + anchorBottom + charPersonality + promptBias + allAnchors); + const tokenCount = getTokenCount(prompt, padding_tokens); + if (tokenCount < this_max_context) { + if (power_user.disable_examples_formatting) { + mesExamplesArray[i] = mesExamplesArray[i].replace(//i, ''); + } else if (!is_pygmalion) { + mesExamplesArray[i] = mesExamplesArray[i].replace(//i, `This is how ${name2} should talk`); + } + count_exm_add++; + await delay(1); + } else { + break; + } + } + } + + if (!is_pygmalion && Scenario && Scenario.length > 0) { + storyString += !power_user.disable_scenario_formatting ? `Circumstances and context of the dialogue: ${Scenario}\n` : `${Scenario}\n`; + } + + let mesSend = []; + console.log('calling runGenerate'); + await runGenerate(); + async function runGenerate(cycleGenerationPromt = '') { is_send_press = true; From d71dcc72faa2882681fcd90b98de1db181070c8d Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Sun, 23 Apr 2023 16:22:15 +0300 Subject: [PATCH 05/11] Colab fix --- colab/GPU.ipynb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/colab/GPU.ipynb b/colab/GPU.ipynb index e82f9891b..d5a99fbab 100644 --- a/colab/GPU.ipynb +++ b/colab/GPU.ipynb @@ -307,6 +307,7 @@ " %cd /SillyTavern\n", " !npm install\n", " !npm install -g localtunnel\n", + " !npm install -g forever\n", "ii.addTask(\"Install Tavern Dependencies\", installTavernDependencies)\n", "ii.run()\n", "\n", @@ -315,7 +316,10 @@ "print(\"KoboldAI LINK:\", url, '###Extensions API LINK###', globals.extras_url, \"###SillyTavern LINK###\", sep=\"\\n\")\n", "p = subprocess.Popen([\"lt\", \"--port\", \"5001\"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n", "print(p.stdout.readline().decode().strip())\n", - "!node server.js" + "!sed -i 's/listen = true/listen = false/g' config.conf\n", + "!touch stdout.log stderr.log\n", + "!forever start -o stdout.log -e stderr.log server.js\n", + "!tail -f stdout.log stderr.log" ] } ], From c6ce7ac7e885717ef9148335cfface3c6d308b52 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Sun, 23 Apr 2023 17:15:18 +0300 Subject: [PATCH 06/11] Replace localtunnel with cloudflare --- colab/GPU.ipynb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/colab/GPU.ipynb b/colab/GPU.ipynb index d5a99fbab..5c0b3012b 100644 --- a/colab/GPU.ipynb +++ b/colab/GPU.ipynb @@ -308,17 +308,18 @@ " !npm install\n", " !npm install -g localtunnel\n", " !npm install -g forever\n", + " !pip install flask-cloudflared\n", "ii.addTask(\"Install Tavern Dependencies\", installTavernDependencies)\n", "ii.run()\n", "\n", "%env colaburl=$url\n", "%env SILLY_TAVERN_PORT=5001\n", - "print(\"KoboldAI LINK:\", url, '###Extensions API LINK###', globals.extras_url, \"###SillyTavern LINK###\", sep=\"\\n\")\n", - "p = subprocess.Popen([\"lt\", \"--port\", \"5001\"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n", - "print(p.stdout.readline().decode().strip())\n", + "from flask_cloudflared import start_cloudflared\n", "!sed -i 's/listen = true/listen = false/g' config.conf\n", "!touch stdout.log stderr.log\n", "!forever start -o stdout.log -e stderr.log server.js\n", + "print(\"KoboldAI LINK:\", url, '###Extensions API LINK###', globals.extras_url, \"###SillyTavern LINK###\", sep=\"\\n\")\n", + "start_cloudflared(5001, 7000)\n", "!tail -f stdout.log stderr.log" ] } From 0897685f02a26f072584bccfb9ea8ac6e4e610bb Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Sun, 23 Apr 2023 17:36:11 +0300 Subject: [PATCH 07/11] Fix cloudflare sharing --- colab/GPU.ipynb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/colab/GPU.ipynb b/colab/GPU.ipynb index 5c0b3012b..44ec0e8cd 100644 --- a/colab/GPU.ipynb +++ b/colab/GPU.ipynb @@ -319,7 +319,15 @@ "!touch stdout.log stderr.log\n", "!forever start -o stdout.log -e stderr.log server.js\n", "print(\"KoboldAI LINK:\", url, '###Extensions API LINK###', globals.extras_url, \"###SillyTavern LINK###\", sep=\"\\n\")\n", - "start_cloudflared(5001, 7000)\n", + "import inspect\n", + "import random\n", + "sig = inspect.signature(start_cloudflared)\n", + "sum = sum(1 for param in sig.parameters.values() if param.kind == param.POSITIONAL_OR_KEYWORD)\n", + "if sum > 1:\n", + " metrics_port = random.randint(8100, 9000)\n", + " start_cloudflared(5001, metrics_port)\n", + "else:\n", + " start_cloudflared(5001)\n", "!tail -f stdout.log stderr.log" ] } From 4da104211bdec80f83849cff8eb5144575510ae4 Mon Sep 17 00:00:00 2001 From: maver Date: Sun, 23 Apr 2023 18:09:23 +0200 Subject: [PATCH 08/11] 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 09/11] 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 10/11] 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 11/11] 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