From b0cb9829784a141e24c220437154ec847c3106ee Mon Sep 17 00:00:00 2001 From: BPplays Date: Wed, 25 Dec 2024 16:42:58 -0800 Subject: [PATCH 01/48] added automatic ipv6 ipv4 detection --- default/config.yaml | 6 ++- server.js | 89 ++++++++++++++++++++++++++++++++++----------- 2 files changed, 71 insertions(+), 24 deletions(-) diff --git a/default/config.yaml b/default/config.yaml index a3de53021..fcff9c76f 100644 --- a/default/config.yaml +++ b/default/config.yaml @@ -7,9 +7,11 @@ cardsCacheCapacity: 100 # Listen for incoming connections listen: false # Enables IPv6 and/or IPv4 protocols. Need to have at least one enabled! +# - Use option "auto" to automatically detect support +# - Use "enabled" or "disabled" to enable or disabled each protocol protocol: - ipv4: true - ipv6: false + ipv4: auto + ipv6: auto # Prefers IPv6 for DNS. Enable this on ISPs that don't have issues with IPv6 dnsPreferIPv6: false # The hostname that autorun opens. diff --git a/server.js b/server.js index db7ba9306..9c62f68f2 100644 --- a/server.js +++ b/server.js @@ -4,6 +4,7 @@ import fs from 'node:fs'; import http from 'node:http'; import https from 'node:https'; +import os from 'os'; import path from 'node:path'; import util from 'node:util'; import net from 'node:net'; @@ -133,8 +134,8 @@ const DEFAULT_CSRF_DISABLED = false; const DEFAULT_BASIC_AUTH = false; const DEFAULT_PER_USER_BASIC_AUTH = false; -const DEFAULT_ENABLE_IPV6 = false; -const DEFAULT_ENABLE_IPV4 = true; +const DEFAULT_ENABLE_IPV6 = "auto"; +const DEFAULT_ENABLE_IPV4 = "auto"; const DEFAULT_PREFER_IPV6 = false; @@ -149,11 +150,11 @@ const DEFAULT_PROXY_BYPASS = []; const cliArguments = yargs(hideBin(process.argv)) .usage('Usage: [options]') - .option('enableIPv6', { + .option('string', { type: 'boolean', default: null, describe: `Enables IPv6.\n[config default: ${DEFAULT_ENABLE_IPV6}]`, - }).option('enableIPv4', { + }).option('string', { type: 'boolean', default: null, describe: `Enables IPv4.\n[config default: ${DEFAULT_ENABLE_IPV4}]`, @@ -280,7 +281,7 @@ if (dnsPreferIPv6) { console.log('Preferring IPv4 for DNS resolution'); } -if (!enableIPv6 && !enableIPv4) { +if (enableIPv6 == "disabled" && enableIPv4 == "disabled") { console.error('error: You can\'t disable all internet protocols: at least IPv6 or IPv4 must be enabled.'); process.exit(1); } @@ -365,6 +366,28 @@ function getSessionCookieAge() { return undefined; } +async function getHasIP() { + let hasIPv6 = false; + let hasIPv4 = false; + const interfaces = os.networkInterfaces(); + + for (const iface of Object.values(interfaces)) { + if (iface === undefined) { + continue + } + for (const info of iface) { + if (info.family === 'IPv6') { + hasIPv6 = true; + } + + if (info.family === 'IPv4') { + hasIPv4 = true; + } + } + } + return [hasIPv6, hasIPv4]; +} + app.use(cookieSession({ name: getCookieSessionName(), sameSite: 'strict', @@ -685,18 +708,18 @@ const preSetupTasks = async function () { * Gets the hostname to use for autorun in the browser. * @returns {string} The hostname to use for autorun */ -function getAutorunHostname() { +function getAutorunHostname(useIPv6, useIPv4) { if (autorunHostname === 'auto') { - if (enableIPv6 && enableIPv4) { + if (useIPv6 && useIPv4) { if (avoidLocalhost) return '[::1]'; return 'localhost'; } - if (enableIPv6) { + if (useIPv6) { return '[::1]'; } - if (enableIPv4) { + if (useIPv4) { return '127.0.0.1'; } } @@ -709,10 +732,10 @@ function getAutorunHostname() { * @param {boolean} v6Failed If the server failed to start on IPv6 * @param {boolean} v4Failed If the server failed to start on IPv4 */ -const postSetupTasks = async function (v6Failed, v4Failed) { +const postSetupTasks = async function (v6Failed, v4Failed, useIPv6, useIPv4) { const autorunUrl = new URL( (cliArguments.ssl ? 'https://' : 'http://') + - (getAutorunHostname()) + + (getAutorunHostname(useIPv6, useIPv4)) + (':') + ((autorunPortOverride >= 0) ? autorunPortOverride : server_port), ); @@ -725,11 +748,11 @@ const postSetupTasks = async function (v6Failed, v4Failed) { let logListen = 'SillyTavern is listening on'; - if (enableIPv6 && !v6Failed) { + if (useIPv6 && !v6Failed) { logListen += color.green(' IPv6: ' + tavernUrlV6.host); } - if (enableIPv4 && !v4Failed) { + if (useIPv4 && !v4Failed) { logListen += color.green(' IPv4: ' + tavernUrl.host); } @@ -805,13 +828,13 @@ function logSecurityAlert(message) { * @param {boolean} v6Failed If the server failed to start on IPv6 * @param {boolean} v4Failed If the server failed to start on IPv4 */ -function handleServerListenFail(v6Failed, v4Failed) { - if (v6Failed && !enableIPv4) { +function handleServerListenFail(v6Failed, v4Failed, useIPv6, useIPv4) { + if (v6Failed && !useIPv4) { console.error(color.red('fatal error: Failed to start server on IPv6 and IPv4 disabled')); process.exit(1); } - if (v4Failed && !enableIPv6) { + if (v4Failed && !useIPv6) { console.error(color.red('fatal error: Failed to start server on IPv4 and IPv6 disabled')); process.exit(1); } @@ -856,13 +879,13 @@ function createHttpServer(url) { }); } -async function startHTTPorHTTPS() { +async function startHTTPorHTTPS(useIPv6, useIPv4) { let v6Failed = false; let v4Failed = false; const createFunc = cliArguments.ssl ? createHttpsServer : createHttpServer; - if (enableIPv6) { + if (useIPv6) { try { await createFunc(tavernUrlV6); } catch (error) { @@ -873,7 +896,7 @@ async function startHTTPorHTTPS() { } } - if (enableIPv4) { + if (useIPv4) { try { await createFunc(tavernUrl); } catch (error) { @@ -888,10 +911,32 @@ async function startHTTPorHTTPS() { } async function startServer() { - const [v6Failed, v4Failed] = await startHTTPorHTTPS(); + let useIPv6 = (enableIPv6 == "enabled") + let useIPv4 = (enableIPv4 == "enabled") - handleServerListenFail(v6Failed, v4Failed); - postSetupTasks(v6Failed, v4Failed); + const [hasIPv6, hasIPv4] = await getHasIP() + if (enableIPv6 == "auto") { + useIPv6 = hasIPv6; + if (useIPv6) { + console.log("IPv6 support detected") + } + } + + if (enableIPv4 == "auto") { + useIPv4 = hasIPv4; + if (useIPv4) { + console.log("IPv4 support detected") + } + } + + if (!useIPv6 && !useIPv4) { + console.log("No IPv6 and no IPv4 enabled") + } + + const [v6Failed, v4Failed] = await startHTTPorHTTPS(useIPv6, useIPv4); + + handleServerListenFail(v6Failed, v4Failed, useIPv6, useIPv4); + postSetupTasks(v6Failed, v4Failed, useIPv6, useIPv4); } async function verifySecuritySettings() { From dc3b18de94974e6ef93e94f4ad8df0a98b94b906 Mon Sep 17 00:00:00 2001 From: BPplays Date: Wed, 25 Dec 2024 16:47:08 -0800 Subject: [PATCH 02/48] fixed typo --- default/config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/default/config.yaml b/default/config.yaml index fcff9c76f..6611e3732 100644 --- a/default/config.yaml +++ b/default/config.yaml @@ -8,7 +8,7 @@ cardsCacheCapacity: 100 listen: false # Enables IPv6 and/or IPv4 protocols. Need to have at least one enabled! # - Use option "auto" to automatically detect support -# - Use "enabled" or "disabled" to enable or disabled each protocol +# - Use "enabled" or "disabled" to enable or disable each protocol protocol: ipv4: auto ipv6: auto From 8d0261bab3df573dbf0f3532b69c543040156574 Mon Sep 17 00:00:00 2001 From: BPplays Date: Wed, 25 Dec 2024 16:52:13 -0800 Subject: [PATCH 03/48] fixed dumb mistake --- server.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server.js b/server.js index 9c62f68f2..78c612e69 100644 --- a/server.js +++ b/server.js @@ -150,12 +150,12 @@ const DEFAULT_PROXY_BYPASS = []; const cliArguments = yargs(hideBin(process.argv)) .usage('Usage: [options]') - .option('string', { - type: 'boolean', + .option('enableIPv6', { + type: 'string', default: null, describe: `Enables IPv6.\n[config default: ${DEFAULT_ENABLE_IPV6}]`, - }).option('string', { - type: 'boolean', + }).option('enableIPv4', { + type: 'string', default: null, describe: `Enables IPv4.\n[config default: ${DEFAULT_ENABLE_IPV4}]`, }).option('port', { From 418a2564b23b40257be7ba7b8a2b77994011793b Mon Sep 17 00:00:00 2001 From: BPplays Date: Wed, 25 Dec 2024 16:59:47 -0800 Subject: [PATCH 04/48] added better error handling --- server.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/server.js b/server.js index 78c612e69..e9262cfce 100644 --- a/server.js +++ b/server.js @@ -281,6 +281,17 @@ if (dnsPreferIPv6) { console.log('Preferring IPv4 for DNS resolution'); } +const ipOptions = ["enabled", "auto", "disabled"]; + +if (!ipOptions.includes(enableIPv6)) { + console.error("`protocol: ipv6` option invalid"); + process.exit(1) +} +if (!ipOptions.includes(enableIPv4)) { + console.error("`protocol: ipv4` option invalid"); + process.exit(1) +} + if (enableIPv6 == "disabled" && enableIPv4 == "disabled") { console.error('error: You can\'t disable all internet protocols: at least IPv6 or IPv4 must be enabled.'); process.exit(1); From 38b1c26396c67bd8a5283e0f8fd06b08c3d9caa9 Mon Sep 17 00:00:00 2001 From: BPplays Date: Wed, 25 Dec 2024 17:01:12 -0800 Subject: [PATCH 05/48] made loop better --- server.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server.js b/server.js index e9262cfce..390febe65 100644 --- a/server.js +++ b/server.js @@ -394,7 +394,9 @@ async function getHasIP() { if (info.family === 'IPv4') { hasIPv4 = true; } + if (hasIPv6 && hasIPv4) break; } + if (hasIPv6 && hasIPv4) break; } return [hasIPv6, hasIPv4]; } From b5139e3ff9d0ef9749acf844df52763306627fcd Mon Sep 17 00:00:00 2001 From: BPplays Date: Wed, 25 Dec 2024 17:06:05 -0800 Subject: [PATCH 06/48] fixed linting issues --- server.js | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/server.js b/server.js index 390febe65..8ece98d51 100644 --- a/server.js +++ b/server.js @@ -134,8 +134,8 @@ const DEFAULT_CSRF_DISABLED = false; const DEFAULT_BASIC_AUTH = false; const DEFAULT_PER_USER_BASIC_AUTH = false; -const DEFAULT_ENABLE_IPV6 = "auto"; -const DEFAULT_ENABLE_IPV4 = "auto"; +const DEFAULT_ENABLE_IPV6 = 'auto'; +const DEFAULT_ENABLE_IPV4 = 'auto'; const DEFAULT_PREFER_IPV6 = false; @@ -281,18 +281,18 @@ if (dnsPreferIPv6) { console.log('Preferring IPv4 for DNS resolution'); } -const ipOptions = ["enabled", "auto", "disabled"]; +const ipOptions = ['enabled', 'auto', 'disabled']; if (!ipOptions.includes(enableIPv6)) { - console.error("`protocol: ipv6` option invalid"); - process.exit(1) + console.error('`protocol: ipv6` option invalid'); + process.exit(1); } if (!ipOptions.includes(enableIPv4)) { - console.error("`protocol: ipv4` option invalid"); - process.exit(1) + console.error('`protocol: ipv4` option invalid'); + process.exit(1); } -if (enableIPv6 == "disabled" && enableIPv4 == "disabled") { +if (enableIPv6 == 'disabled' && enableIPv4 == 'disabled') { console.error('error: You can\'t disable all internet protocols: at least IPv6 or IPv4 must be enabled.'); process.exit(1); } @@ -384,7 +384,7 @@ async function getHasIP() { for (const iface of Object.values(interfaces)) { if (iface === undefined) { - continue + continue; } for (const info of iface) { if (info.family === 'IPv6') { @@ -924,26 +924,26 @@ async function startHTTPorHTTPS(useIPv6, useIPv4) { } async function startServer() { - let useIPv6 = (enableIPv6 == "enabled") - let useIPv4 = (enableIPv4 == "enabled") + let useIPv6 = (enableIPv6 == 'enabled'); + let useIPv4 = (enableIPv4 == 'enabled'); - const [hasIPv6, hasIPv4] = await getHasIP() - if (enableIPv6 == "auto") { + const [hasIPv6, hasIPv4] = await getHasIP(); + if (enableIPv6 == 'auto') { useIPv6 = hasIPv6; if (useIPv6) { - console.log("IPv6 support detected") + console.log('IPv6 support detected'); } } - if (enableIPv4 == "auto") { + if (enableIPv4 == 'auto') { useIPv4 = hasIPv4; if (useIPv4) { - console.log("IPv4 support detected") + console.log('IPv4 support detected'); } } if (!useIPv6 && !useIPv4) { - console.log("No IPv6 and no IPv4 enabled") + console.log('No IPv6 and no IPv4 enabled'); } const [v6Failed, v4Failed] = await startHTTPorHTTPS(useIPv6, useIPv4); From 324eb695f590bce6e22aaa53a795189b07dad46e Mon Sep 17 00:00:00 2001 From: BPplays Date: Wed, 25 Dec 2024 17:16:12 -0800 Subject: [PATCH 07/48] added better error reporting --- server.js | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/server.js b/server.js index 8ece98d51..21a233b30 100644 --- a/server.js +++ b/server.js @@ -924,26 +924,34 @@ async function startHTTPorHTTPS(useIPv6, useIPv4) { } async function startServer() { - let useIPv6 = (enableIPv6 == 'enabled'); - let useIPv4 = (enableIPv4 == 'enabled'); + let useIPv6 = (enableIPv6 === 'enabled'); + let useIPv4 = (enableIPv4 === 'enabled'); const [hasIPv6, hasIPv4] = await getHasIP(); - if (enableIPv6 == 'auto') { + if (enableIPv6 === 'auto') { useIPv6 = hasIPv6; if (useIPv6) { console.log('IPv6 support detected'); } } - if (enableIPv4 == 'auto') { + if (enableIPv4 === 'auto') { useIPv4 = hasIPv4; if (useIPv4) { console.log('IPv4 support detected'); } } - if (!useIPv6 && !useIPv4) { - console.log('No IPv6 and no IPv4 enabled'); + if (enableIPv6 === 'auto' && enableIPv4 === 'auto') { + if (!hasIPv6 && !hasIPv4) { + console.error('Both IPv6 and IPv4 are not detected'); + process.exit(1) + } + } + + if (!useIPv6 && !useIPv6) { + console.error('Both IPv6 and IPv4 are disabled,\nP.S. you should never see this error, at least at one point it was checked for before this'); + process.exit(1) } const [v6Failed, v4Failed] = await startHTTPorHTTPS(useIPv6, useIPv4); From 26c0b620f86e37a220f2cd92fec7b7c306302a6b Mon Sep 17 00:00:00 2001 From: BPplays Date: Wed, 25 Dec 2024 17:16:40 -0800 Subject: [PATCH 08/48] added better error reporting --- server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.js b/server.js index 21a233b30..6681cc2d3 100644 --- a/server.js +++ b/server.js @@ -950,7 +950,7 @@ async function startServer() { } if (!useIPv6 && !useIPv6) { - console.error('Both IPv6 and IPv4 are disabled,\nP.S. you should never see this error, at least at one point it was checked for before this'); + console.error('Both IPv6 and IPv4 are disabled,\nP.S. you should never see this error, at least at one point it was checked for before this, with the rest of the config options'); process.exit(1) } From e861b18992b38ceb03910394f18525c19d958b0b Mon Sep 17 00:00:00 2001 From: BPplays Date: Wed, 25 Dec 2024 17:22:18 -0800 Subject: [PATCH 09/48] added better error reporting --- server.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server.js b/server.js index 6681cc2d3..25d68d0c3 100644 --- a/server.js +++ b/server.js @@ -284,11 +284,11 @@ if (dnsPreferIPv6) { const ipOptions = ['enabled', 'auto', 'disabled']; if (!ipOptions.includes(enableIPv6)) { - console.error('`protocol: ipv6` option invalid'); + console.error('`protocol: ipv6` option invalid\n use:', ipOptions); process.exit(1); } if (!ipOptions.includes(enableIPv4)) { - console.error('`protocol: ipv4` option invalid'); + console.error('`protocol: ipv4` option invalid\n use:', ipOptions); process.exit(1); } From 0bc056993236c49da4746457905aa5532baa8bd8 Mon Sep 17 00:00:00 2001 From: BPplays Date: Wed, 25 Dec 2024 17:25:02 -0800 Subject: [PATCH 10/48] changed to always report supported ip ver even when disabled, green means it's enabled --- server.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/server.js b/server.js index 25d68d0c3..89a201259 100644 --- a/server.js +++ b/server.js @@ -931,15 +931,19 @@ async function startServer() { if (enableIPv6 === 'auto') { useIPv6 = hasIPv6; if (useIPv6) { - console.log('IPv6 support detected'); + console.log(color.green('IPv6 support detected')); } + } else if (hasIPv6) { + console.log('IPv6 support detected'); } if (enableIPv4 === 'auto') { useIPv4 = hasIPv4; if (useIPv4) { - console.log('IPv4 support detected'); + console.log(color.green('IPv4 support detected')); } + } else if (hasIPv4) { + console.log('IPv4 support detected'); } if (enableIPv6 === 'auto' && enableIPv4 === 'auto') { From 9e049f44e296e531d67107f598a1ac34593b0412 Mon Sep 17 00:00:00 2001 From: BPplays Date: Wed, 25 Dec 2024 17:28:44 -0800 Subject: [PATCH 11/48] fixed logic bug --- server.js | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/server.js b/server.js index 89a201259..23ed11f27 100644 --- a/server.js +++ b/server.js @@ -930,32 +930,41 @@ async function startServer() { const [hasIPv6, hasIPv4] = await getHasIP(); if (enableIPv6 === 'auto') { useIPv6 = hasIPv6; + } + if (hasIPv6) { if (useIPv6) { console.log(color.green('IPv6 support detected')); + } else { + console.log('IPv6 support detected'); } - } else if (hasIPv6) { - console.log('IPv6 support detected'); } + if (enableIPv4 === 'auto') { useIPv4 = hasIPv4; if (useIPv4) { console.log(color.green('IPv4 support detected')); } - } else if (hasIPv4) { - console.log('IPv4 support detected'); } + if (hasIPv4) { + if (useIPv4) { + console.log(color.green('IPv4 support detected')); + } else { + console.log('IPv4 support detected'); + } + } + if (enableIPv6 === 'auto' && enableIPv4 === 'auto') { if (!hasIPv6 && !hasIPv4) { console.error('Both IPv6 and IPv4 are not detected'); - process.exit(1) + process.exit(1); } } if (!useIPv6 && !useIPv6) { console.error('Both IPv6 and IPv4 are disabled,\nP.S. you should never see this error, at least at one point it was checked for before this, with the rest of the config options'); - process.exit(1) + process.exit(1); } const [v6Failed, v4Failed] = await startHTTPorHTTPS(useIPv6, useIPv4); From ca283c0da63f7f000baf099447f6bd03d68da78c Mon Sep 17 00:00:00 2001 From: BPplays Date: Thu, 26 Dec 2024 10:28:48 -0800 Subject: [PATCH 12/48] fixed backward compat, and check if auto before getting addrs --- default/config.yaml | 2 +- server.js | 58 +++++++++++++++++++++++---------------------- 2 files changed, 31 insertions(+), 29 deletions(-) diff --git a/default/config.yaml b/default/config.yaml index 6611e3732..189d1c48e 100644 --- a/default/config.yaml +++ b/default/config.yaml @@ -8,7 +8,7 @@ cardsCacheCapacity: 100 listen: false # Enables IPv6 and/or IPv4 protocols. Need to have at least one enabled! # - Use option "auto" to automatically detect support -# - Use "enabled" or "disabled" to enable or disable each protocol +# - Use true or false (no qoutes) to enable or disable each protocol protocol: ipv4: auto ipv6: auto diff --git a/server.js b/server.js index 23ed11f27..59c1b893c 100644 --- a/server.js +++ b/server.js @@ -257,8 +257,8 @@ const enableAccounts = getConfigValue('enableUserAccounts', DEFAULT_ACCOUNTS); const uploadsPath = path.join(dataRoot, UPLOADS_DIRECTORY); -const enableIPv6 = cliArguments.enableIPv6 ?? getConfigValue('protocol.ipv6', DEFAULT_ENABLE_IPV6); -const enableIPv4 = cliArguments.enableIPv4 ?? getConfigValue('protocol.ipv4', DEFAULT_ENABLE_IPV4); +let enableIPv6 = cliArguments.enableIPv6 ?? getConfigValue('protocol.ipv6', DEFAULT_ENABLE_IPV6); +let enableIPv4 = cliArguments.enableIPv4 ?? getConfigValue('protocol.ipv4', DEFAULT_ENABLE_IPV4); const autorunHostname = cliArguments.autorunHostname ?? getConfigValue('autorunHostname', DEFAULT_AUTORUN_HOSTNAME); const autorunPortOverride = cliArguments.autorunPortOverride ?? getConfigValue('autorunPortOverride', DEFAULT_AUTORUN_PORT); @@ -281,7 +281,8 @@ if (dnsPreferIPv6) { console.log('Preferring IPv4 for DNS resolution'); } -const ipOptions = ['enabled', 'auto', 'disabled']; + +const ipOptions = [true, 'auto', false]; if (!ipOptions.includes(enableIPv6)) { console.error('`protocol: ipv6` option invalid\n use:', ipOptions); @@ -292,7 +293,7 @@ if (!ipOptions.includes(enableIPv4)) { process.exit(1); } -if (enableIPv6 == 'disabled' && enableIPv4 == 'disabled') { +if (enableIPv6 === false && enableIPv4 === false) { console.error('error: You can\'t disable all internet protocols: at least IPv6 or IPv4 must be enabled.'); process.exit(1); } @@ -924,33 +925,34 @@ async function startHTTPorHTTPS(useIPv6, useIPv4) { } async function startServer() { - let useIPv6 = (enableIPv6 === 'enabled'); - let useIPv4 = (enableIPv4 === 'enabled'); + let useIPv6 = (enableIPv6 === true); + let useIPv4 = (enableIPv4 === true); + let hasIPv6, hasIPv4; - const [hasIPv6, hasIPv4] = await getHasIP(); - if (enableIPv6 === 'auto') { - useIPv6 = hasIPv6; - } - if (hasIPv6) { - if (useIPv6) { - console.log(color.green('IPv6 support detected')); - } else { - console.log('IPv6 support detected'); + + if (enableIPv6 === 'auto' || enableIPv4 === 'auto') { + [hasIPv6, hasIPv4] = await getHasIP(); + if (enableIPv6 === 'auto') { + useIPv6 = hasIPv6; } - } - - - if (enableIPv4 === 'auto') { - useIPv4 = hasIPv4; - if (useIPv4) { - console.log(color.green('IPv4 support detected')); + if (hasIPv6) { + if (useIPv6) { + console.log(color.green('IPv6 support detected')); + } else { + console.log('IPv6 support detected'); + } } - } - if (hasIPv4) { - if (useIPv4) { - console.log(color.green('IPv4 support detected')); - } else { - console.log('IPv4 support detected'); + + + if (enableIPv4 === 'auto') { + useIPv4 = hasIPv4; + } + if (hasIPv4) { + if (useIPv4) { + console.log(color.green('IPv4 support detected')); + } else { + console.log('IPv4 support detected'); + } } } From 1689baa2a4be97419b3887c3b2cc878fa3e9dc3b Mon Sep 17 00:00:00 2001 From: BPplays Date: Thu, 26 Dec 2024 10:30:51 -0800 Subject: [PATCH 13/48] changed back const --- server.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server.js b/server.js index 59c1b893c..e497e87d5 100644 --- a/server.js +++ b/server.js @@ -257,8 +257,8 @@ const enableAccounts = getConfigValue('enableUserAccounts', DEFAULT_ACCOUNTS); const uploadsPath = path.join(dataRoot, UPLOADS_DIRECTORY); -let enableIPv6 = cliArguments.enableIPv6 ?? getConfigValue('protocol.ipv6', DEFAULT_ENABLE_IPV6); -let enableIPv4 = cliArguments.enableIPv4 ?? getConfigValue('protocol.ipv4', DEFAULT_ENABLE_IPV4); +const enableIPv6 = cliArguments.enableIPv6 ?? getConfigValue('protocol.ipv6', DEFAULT_ENABLE_IPV6); +const enableIPv4 = cliArguments.enableIPv4 ?? getConfigValue('protocol.ipv4', DEFAULT_ENABLE_IPV4); const autorunHostname = cliArguments.autorunHostname ?? getConfigValue('autorunHostname', DEFAULT_AUTORUN_HOSTNAME); const autorunPortOverride = cliArguments.autorunPortOverride ?? getConfigValue('autorunPortOverride', DEFAULT_AUTORUN_PORT); From 4a8b47a6ffe35e6c85d9f03b4d80d069b43362ec Mon Sep 17 00:00:00 2001 From: BPplays Date: Thu, 26 Dec 2024 10:44:48 -0800 Subject: [PATCH 14/48] fixed cli args and logic bug --- server.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/server.js b/server.js index e497e87d5..e05ddc81f 100644 --- a/server.js +++ b/server.js @@ -244,6 +244,12 @@ app.use(helmet({ app.use(compression()); app.use(responseTime()); +function stringToBool(str) { + if (str === 'true') return true; + if (str === 'false') return false; + return str; // or throw an error +} + const server_port = cliArguments.port ?? process.env.SILLY_TAVERN_PORT ?? getConfigValue('port', DEFAULT_PORT); const autorun = (cliArguments.autorun ?? getConfigValue('autorun', DEFAULT_AUTORUN)) && !cliArguments.ssl; const listen = cliArguments.listen ?? getConfigValue('listen', DEFAULT_LISTEN); @@ -257,8 +263,9 @@ const enableAccounts = getConfigValue('enableUserAccounts', DEFAULT_ACCOUNTS); const uploadsPath = path.join(dataRoot, UPLOADS_DIRECTORY); -const enableIPv6 = cliArguments.enableIPv6 ?? getConfigValue('protocol.ipv6', DEFAULT_ENABLE_IPV6); -const enableIPv4 = cliArguments.enableIPv4 ?? getConfigValue('protocol.ipv4', DEFAULT_ENABLE_IPV4); + +const enableIPv6 = stringToBool(cliArguments.enableIPv6) ?? getConfigValue('protocol.ipv6', DEFAULT_ENABLE_IPV6); +const enableIPv4 = stringToBool(cliArguments.enableIPv4) ?? getConfigValue('protocol.ipv4', DEFAULT_ENABLE_IPV4); const autorunHostname = cliArguments.autorunHostname ?? getConfigValue('autorunHostname', DEFAULT_AUTORUN_HOSTNAME); const autorunPortOverride = cliArguments.autorunPortOverride ?? getConfigValue('autorunPortOverride', DEFAULT_AUTORUN_PORT); @@ -957,6 +964,7 @@ async function startServer() { } + if (enableIPv6 === 'auto' && enableIPv4 === 'auto') { if (!hasIPv6 && !hasIPv4) { console.error('Both IPv6 and IPv4 are not detected'); @@ -964,7 +972,7 @@ async function startServer() { } } - if (!useIPv6 && !useIPv6) { + if (!useIPv6 && !useIPv4) { console.error('Both IPv6 and IPv4 are disabled,\nP.S. you should never see this error, at least at one point it was checked for before this, with the rest of the config options'); process.exit(1); } From 591a61a61c177394be984a5b89032d1e3b303dd9 Mon Sep 17 00:00:00 2001 From: BPplays Date: Thu, 26 Dec 2024 10:51:45 -0800 Subject: [PATCH 15/48] misc formatting --- server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.js b/server.js index e05ddc81f..3efc6ff72 100644 --- a/server.js +++ b/server.js @@ -247,7 +247,7 @@ app.use(responseTime()); function stringToBool(str) { if (str === 'true') return true; if (str === 'false') return false; - return str; // or throw an error + return str; } const server_port = cliArguments.port ?? process.env.SILLY_TAVERN_PORT ?? getConfigValue('port', DEFAULT_PORT); From 647b89f8adb7a2be7ac9a055f41ca4ae48ee3958 Mon Sep 17 00:00:00 2001 From: BPplays Date: Thu, 26 Dec 2024 11:40:22 -0800 Subject: [PATCH 16/48] changed settings value error to just set to auto --- server.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/server.js b/server.js index 3efc6ff72..089b4700a 100644 --- a/server.js +++ b/server.js @@ -264,8 +264,8 @@ const enableAccounts = getConfigValue('enableUserAccounts', DEFAULT_ACCOUNTS); const uploadsPath = path.join(dataRoot, UPLOADS_DIRECTORY); -const enableIPv6 = stringToBool(cliArguments.enableIPv6) ?? getConfigValue('protocol.ipv6', DEFAULT_ENABLE_IPV6); -const enableIPv4 = stringToBool(cliArguments.enableIPv4) ?? getConfigValue('protocol.ipv4', DEFAULT_ENABLE_IPV4); +let enableIPv6 = stringToBool(cliArguments.enableIPv6) ?? getConfigValue('protocol.ipv6', DEFAULT_ENABLE_IPV6); +let enableIPv4 = stringToBool(cliArguments.enableIPv4) ?? getConfigValue('protocol.ipv4', DEFAULT_ENABLE_IPV4); const autorunHostname = cliArguments.autorunHostname ?? getConfigValue('autorunHostname', DEFAULT_AUTORUN_HOSTNAME); const autorunPortOverride = cliArguments.autorunPortOverride ?? getConfigValue('autorunPortOverride', DEFAULT_AUTORUN_PORT); @@ -292,12 +292,12 @@ if (dnsPreferIPv6) { const ipOptions = [true, 'auto', false]; if (!ipOptions.includes(enableIPv6)) { - console.error('`protocol: ipv6` option invalid\n use:', ipOptions); - process.exit(1); + console.warn('`protocol: ipv6` option invalid\n use:', ipOptions, "\n setting to: auto"); + enableIPv6 = 'auto'; } if (!ipOptions.includes(enableIPv4)) { - console.error('`protocol: ipv4` option invalid\n use:', ipOptions); - process.exit(1); + console.warn('`protocol: ipv4` option invalid\n use:', ipOptions, "\n setting to: auto"); + enableIPv4 = 'auto'; } if (enableIPv6 === false && enableIPv4 === false) { From 9c0993908ad4827aba523d5cee371dafbf41532b Mon Sep 17 00:00:00 2001 From: BPplays Date: Thu, 26 Dec 2024 11:42:32 -0800 Subject: [PATCH 17/48] moved stringtobool --- server.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/server.js b/server.js index 089b4700a..98f8a8b4f 100644 --- a/server.js +++ b/server.js @@ -68,6 +68,7 @@ import { forwardFetchResponse, removeColorFormatting, getSeparator, + stringToBool, } from './src/util.js'; import { UPLOADS_DIRECTORY } from './src/constants.js'; import { ensureThumbnailCache } from './src/endpoints/thumbnails.js'; @@ -244,11 +245,6 @@ app.use(helmet({ app.use(compression()); app.use(responseTime()); -function stringToBool(str) { - if (str === 'true') return true; - if (str === 'false') return false; - return str; -} const server_port = cliArguments.port ?? process.env.SILLY_TAVERN_PORT ?? getConfigValue('port', DEFAULT_PORT); const autorun = (cliArguments.autorun ?? getConfigValue('autorun', DEFAULT_AUTORUN)) && !cliArguments.ssl; From ae79616c73314c56048480c363ce9de1cc9cbeeb Mon Sep 17 00:00:00 2001 From: BPplays Date: Thu, 26 Dec 2024 11:44:30 -0800 Subject: [PATCH 18/48] changed color of ip warning --- server.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server.js b/server.js index 98f8a8b4f..eb824a360 100644 --- a/server.js +++ b/server.js @@ -288,11 +288,11 @@ if (dnsPreferIPv6) { const ipOptions = [true, 'auto', false]; if (!ipOptions.includes(enableIPv6)) { - console.warn('`protocol: ipv6` option invalid\n use:', ipOptions, "\n setting to: auto"); + console.warn(color.red('`protocol: ipv6` option invalid'), "\n use:", ipOptions, "\n setting to: auto"); enableIPv6 = 'auto'; } if (!ipOptions.includes(enableIPv4)) { - console.warn('`protocol: ipv4` option invalid\n use:', ipOptions, "\n setting to: auto"); + console.warn(color.red('`protocol: ipv4` option invalid'), "\n use:", ipOptions, "\n setting to: auto"); enableIPv4 = 'auto'; } From 1a1ab1d18a5f0a586616326fff29f1de091d1317 Mon Sep 17 00:00:00 2001 From: BPplays Date: Sat, 28 Dec 2024 13:31:50 -0800 Subject: [PATCH 19/48] check for localhost ip and ignore link-local v6, i think you need to specify an interface --- server.js | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/server.js b/server.js index eb824a360..ac97fe402 100644 --- a/server.js +++ b/server.js @@ -28,6 +28,7 @@ import multer from 'multer'; import responseTime from 'response-time'; import helmet from 'helmet'; import bodyParser from 'body-parser'; +import { getMatch, IPMatch, IPSubnetwork, IPRange, matches } from 'ip-matching'; // net related library imports import fetch from 'node-fetch'; @@ -383,26 +384,35 @@ function getSessionCookieAge() { async function getHasIP() { let hasIPv6 = false; + let hasIPv6Local = false; let hasIPv4 = false; + let hasIPv4Local = false; const interfaces = os.networkInterfaces(); + const linkLocalV6 = getMatch('fe80::/10'); for (const iface of Object.values(interfaces)) { if (iface === undefined) { continue; } for (const info of iface) { - if (info.family === 'IPv6') { + if (info.family === 'IPv6' && !linkLocalV6.matches(info.address)) { hasIPv6 = true; + if (info.internal === true) { + hasIPv6Local = true; + } } if (info.family === 'IPv4') { hasIPv4 = true; + if (info.internal === true) { + hasIPv4Local = true; + } } - if (hasIPv6 && hasIPv4) break; + if (hasIPv6 && hasIPv4 && hasIPv6Local && hasIPv4Local) break; } - if (hasIPv6 && hasIPv4) break; + if (hasIPv6 && hasIPv4 && hasIPv6Local && hasIPv4Local) break; } - return [hasIPv6, hasIPv4]; + return [hasIPv6, hasIPv4, hasIPv6Local, hasIPv4Local]; } app.use(cookieSession({ @@ -930,11 +940,13 @@ async function startHTTPorHTTPS(useIPv6, useIPv4) { async function startServer() { let useIPv6 = (enableIPv6 === true); let useIPv4 = (enableIPv4 === true); - let hasIPv6, hasIPv4; + let hasIPv6, hasIPv4, hasIPv6Local, hasIPv4Local, hasIPv6NonLocal, hasIPv4NonLocal; if (enableIPv6 === 'auto' || enableIPv4 === 'auto') { - [hasIPv6, hasIPv4] = await getHasIP(); + [hasIPv6NonLocal, hasIPv4NonLocal, hasIPv6Local, hasIPv4Local] = await getHasIP(); + + hasIPv6 = listen ? hasIPv6NonLocal : hasIPv6Local; if (enableIPv6 === 'auto') { useIPv6 = hasIPv6; } @@ -947,6 +959,7 @@ async function startServer() { } + hasIPv4 = listen ? hasIPv4NonLocal : hasIPv4Local; if (enableIPv4 === 'auto') { useIPv4 = hasIPv4; } From 19eae8cb49177fedf4ce245d9334ef6c4d64f5f8 Mon Sep 17 00:00:00 2001 From: BPplays Date: Sat, 28 Dec 2024 17:14:30 -0800 Subject: [PATCH 20/48] fixed broken ipv6 on linux, and weird implementation in general --- server.js | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/server.js b/server.js index ac97fe402..252f8470b 100644 --- a/server.js +++ b/server.js @@ -28,7 +28,6 @@ import multer from 'multer'; import responseTime from 'response-time'; import helmet from 'helmet'; import bodyParser from 'body-parser'; -import { getMatch, IPMatch, IPSubnetwork, IPRange, matches } from 'ip-matching'; // net related library imports import fetch from 'node-fetch'; @@ -70,6 +69,7 @@ import { removeColorFormatting, getSeparator, stringToBool, + urlHostnameToIPv6, } from './src/util.js'; import { UPLOADS_DIRECTORY } from './src/constants.js'; import { ensureThumbnailCache } from './src/endpoints/thumbnails.js'; @@ -388,14 +388,14 @@ async function getHasIP() { let hasIPv4 = false; let hasIPv4Local = false; const interfaces = os.networkInterfaces(); - const linkLocalV6 = getMatch('fe80::/10'); for (const iface of Object.values(interfaces)) { if (iface === undefined) { continue; } for (const info of iface) { - if (info.family === 'IPv6' && !linkLocalV6.matches(info.address)) { + //! change this if you ever add configurable addresses to bind to + if (info.family === 'IPv6') { hasIPv6 = true; if (info.internal === true) { hasIPv6Local = true; @@ -878,7 +878,7 @@ function handleServerListenFail(v6Failed, v4Failed, useIPv6, useIPv4) { * @returns {Promise} A promise that resolves when the server is listening * @throws {Error} If the server fails to start */ -function createHttpsServer(url) { +function createHttpsServer(url, ipVersion) { return new Promise((resolve, reject) => { const server = https.createServer( { @@ -887,7 +887,15 @@ function createHttpsServer(url) { }, app); server.on('error', reject); server.on('listening', resolve); - server.listen(Number(url.port || 443), url.hostname); + + let host = url.hostname + if (ipVersion === 6) host = urlHostnameToIPv6(url.hostname); + server.listen({ + host: host, + port: Number(url.port || 443), + // see https://nodejs.org/api/net.html#serverlisten for why ipv6Only is used + ipv6Only: true, + }); }); } @@ -897,12 +905,20 @@ function createHttpsServer(url) { * @returns {Promise} A promise that resolves when the server is listening * @throws {Error} If the server fails to start */ -function createHttpServer(url) { +function createHttpServer(url, ipVersion) { return new Promise((resolve, reject) => { const server = http.createServer(app); server.on('error', reject); server.on('listening', resolve); - server.listen(Number(url.port || 80), url.hostname); + + let host = url.hostname + if (ipVersion === 6) host = urlHostnameToIPv6(url.hostname); + server.listen({ + host: host, + port: Number(url.port || 80), + // see https://nodejs.org/api/net.html#serverlisten for why ipv6Only is used + ipv6Only: true, + }); }); } @@ -914,7 +930,7 @@ async function startHTTPorHTTPS(useIPv6, useIPv4) { if (useIPv6) { try { - await createFunc(tavernUrlV6); + await createFunc(tavernUrlV6, 6); } catch (error) { console.error('non-fatal error: failed to start server on IPv6'); console.error(error); @@ -925,7 +941,7 @@ async function startHTTPorHTTPS(useIPv6, useIPv4) { if (useIPv4) { try { - await createFunc(tavernUrl); + await createFunc(tavernUrl, 4); } catch (error) { console.error('non-fatal error: failed to start server on IPv4'); console.error(error); From 0382afc488bcf5fffbf1aa52c454f284c4881154 Mon Sep 17 00:00:00 2001 From: BPplays Date: Sat, 28 Dec 2024 17:15:44 -0800 Subject: [PATCH 21/48] changed foramtting --- server.js | 1 - 1 file changed, 1 deletion(-) diff --git a/server.js b/server.js index 252f8470b..c8fc2e2b3 100644 --- a/server.js +++ b/server.js @@ -394,7 +394,6 @@ async function getHasIP() { continue; } for (const info of iface) { - //! change this if you ever add configurable addresses to bind to if (info.family === 'IPv6') { hasIPv6 = true; if (info.internal === true) { From dd6dcf1c5b819a53b606897121353235a8187f57 Mon Sep 17 00:00:00 2001 From: BPplays Date: Sat, 28 Dec 2024 17:27:49 -0800 Subject: [PATCH 22/48] changed to check 127.0.0.1 because that's what it binds to --- server.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server.js b/server.js index c8fc2e2b3..bd29f58d8 100644 --- a/server.js +++ b/server.js @@ -396,14 +396,14 @@ async function getHasIP() { for (const info of iface) { if (info.family === 'IPv6') { hasIPv6 = true; - if (info.internal === true) { + if (info.address === '::1') { hasIPv6Local = true; } } if (info.family === 'IPv4') { hasIPv4 = true; - if (info.internal === true) { + if (info.address === '127.0.0.1') { hasIPv4Local = true; } } From 07cff878e5dba997d04ffcd03a7fa06b058b232f Mon Sep 17 00:00:00 2001 From: BPplays Date: Sun, 29 Dec 2024 04:20:39 -0800 Subject: [PATCH 23/48] commited util --- src/util.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/util.js b/src/util.js index 13176f46e..1bd870ea1 100644 --- a/src/util.js +++ b/src/util.js @@ -692,6 +692,23 @@ export function isValidUrl(url) { } } +export function urlHostnameToIPv6(hostname) { + if (hostname.charAt(0) === '[') { + hostname = hostname.slice(1); + } + if (hostname.charAt(hostname.length - 1) === ']') { + hostname = hostname.slice(0, -1); + } + // console.log(hostname) + return hostname +} + +export function stringToBool(str) { + if (str === 'true') return true; + if (str === 'false') return false; + return str; +} + /** * MemoryLimitedMap class that limits the memory usage of string values. */ From 7744be33194ec5d8e5dd659bd69db6f72ef2f1f7 Mon Sep 17 00:00:00 2001 From: BPplays Date: Sun, 29 Dec 2024 04:20:59 -0800 Subject: [PATCH 24/48] commited util --- src/util.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/util.js b/src/util.js index 1bd870ea1..8e4d725ec 100644 --- a/src/util.js +++ b/src/util.js @@ -699,7 +699,6 @@ export function urlHostnameToIPv6(hostname) { if (hostname.charAt(hostname.length - 1) === ']') { hostname = hostname.slice(0, -1); } - // console.log(hostname) return hostname } From f67abf9e037b7dc3ccee90299f7fba2a94854135 Mon Sep 17 00:00:00 2001 From: BPplays Date: Mon, 30 Dec 2024 02:59:41 -0800 Subject: [PATCH 25/48] improved urlHostnameToIPv6 --- src/util.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/util.js b/src/util.js index 8e4d725ec..bf182a251 100644 --- a/src/util.js +++ b/src/util.js @@ -693,10 +693,10 @@ export function isValidUrl(url) { } export function urlHostnameToIPv6(hostname) { - if (hostname.charAt(0) === '[') { + if (hostname.startsWith("[")) { hostname = hostname.slice(1); } - if (hostname.charAt(hostname.length - 1) === ']') { + if (hostname.endsWith("]")) { hostname = hostname.slice(0, -1); } return hostname From f27b3361e5dab7fc8f8d706ac603bad09309051f Mon Sep 17 00:00:00 2001 From: BPplays Date: Mon, 30 Dec 2024 03:01:04 -0800 Subject: [PATCH 26/48] lint --- server.js | 8 ++++---- src/util.js | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/server.js b/server.js index bd29f58d8..41d8f747e 100644 --- a/server.js +++ b/server.js @@ -289,11 +289,11 @@ if (dnsPreferIPv6) { const ipOptions = [true, 'auto', false]; if (!ipOptions.includes(enableIPv6)) { - console.warn(color.red('`protocol: ipv6` option invalid'), "\n use:", ipOptions, "\n setting to: auto"); + console.warn(color.red('`protocol: ipv6` option invalid'), '\n use:', ipOptions, '\n setting to: auto'); enableIPv6 = 'auto'; } if (!ipOptions.includes(enableIPv4)) { - console.warn(color.red('`protocol: ipv4` option invalid'), "\n use:", ipOptions, "\n setting to: auto"); + console.warn(color.red('`protocol: ipv4` option invalid'), '\n use:', ipOptions, '\n setting to: auto'); enableIPv4 = 'auto'; } @@ -887,7 +887,7 @@ function createHttpsServer(url, ipVersion) { server.on('error', reject); server.on('listening', resolve); - let host = url.hostname + let host = url.hostname; if (ipVersion === 6) host = urlHostnameToIPv6(url.hostname); server.listen({ host: host, @@ -910,7 +910,7 @@ function createHttpServer(url, ipVersion) { server.on('error', reject); server.on('listening', resolve); - let host = url.hostname + let host = url.hostname; if (ipVersion === 6) host = urlHostnameToIPv6(url.hostname); server.listen({ host: host, diff --git a/src/util.js b/src/util.js index bf182a251..85be19718 100644 --- a/src/util.js +++ b/src/util.js @@ -693,13 +693,13 @@ export function isValidUrl(url) { } export function urlHostnameToIPv6(hostname) { - if (hostname.startsWith("[")) { + if (hostname.startsWith('[')) { hostname = hostname.slice(1); } - if (hostname.endsWith("]")) { + if (hostname.endsWith(']')) { hostname = hostname.slice(0, -1); } - return hostname + return hostname; } export function stringToBool(str) { From 93e0efa241da3a7c4d6d679563f7383162966fca Mon Sep 17 00:00:00 2001 From: BPplays Date: Tue, 31 Dec 2024 03:29:15 -0800 Subject: [PATCH 27/48] made var names better --- server.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server.js b/server.js index 41d8f747e..e304d19e0 100644 --- a/server.js +++ b/server.js @@ -955,13 +955,13 @@ async function startHTTPorHTTPS(useIPv6, useIPv4) { async function startServer() { let useIPv6 = (enableIPv6 === true); let useIPv4 = (enableIPv4 === true); - let hasIPv6, hasIPv4, hasIPv6Local, hasIPv4Local, hasIPv6NonLocal, hasIPv4NonLocal; + let hasIPv6, hasIPv4, hasIPv6Local, hasIPv4Local, hasIPv6Any, hasIPv4Any; if (enableIPv6 === 'auto' || enableIPv4 === 'auto') { - [hasIPv6NonLocal, hasIPv4NonLocal, hasIPv6Local, hasIPv4Local] = await getHasIP(); + [hasIPv6Any, hasIPv4Any, hasIPv6Local, hasIPv4Local] = await getHasIP(); - hasIPv6 = listen ? hasIPv6NonLocal : hasIPv6Local; + hasIPv6 = listen ? hasIPv6Any : hasIPv6Local; if (enableIPv6 === 'auto') { useIPv6 = hasIPv6; } @@ -974,7 +974,7 @@ async function startServer() { } - hasIPv4 = listen ? hasIPv4NonLocal : hasIPv4Local; + hasIPv4 = listen ? hasIPv4Any : hasIPv4Local; if (enableIPv4 === 'auto') { useIPv4 = hasIPv4; } From d956e0ebdc99bba5da188b8e695a50a0cd84a9b3 Mon Sep 17 00:00:00 2001 From: BPplays Date: Tue, 31 Dec 2024 14:46:41 -0800 Subject: [PATCH 28/48] changed formatting --- server.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server.js b/server.js index e304d19e0..bd653fdb0 100644 --- a/server.js +++ b/server.js @@ -385,8 +385,10 @@ function getSessionCookieAge() { async function getHasIP() { let hasIPv6 = false; let hasIPv6Local = false; + let hasIPv4 = false; let hasIPv4Local = false; + const interfaces = os.networkInterfaces(); for (const iface of Object.values(interfaces)) { From 092d11bbe62ea646893fe98974dea89aac9deebf Mon Sep 17 00:00:00 2001 From: BPplays Date: Tue, 31 Dec 2024 22:34:41 -0800 Subject: [PATCH 29/48] added better logging --- server.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server.js b/server.js index bd653fdb0..08d1d926c 100644 --- a/server.js +++ b/server.js @@ -987,6 +987,8 @@ async function startServer() { console.log('IPv4 support detected'); } } + } else { + console.log("Neither protocol: ipv6, nor ipv4 are set to auto, skipping detection") } From 8a321a74500d437233494b3148986d0e89e35c26 Mon Sep 17 00:00:00 2001 From: BPplays Date: Tue, 31 Dec 2024 22:41:13 -0800 Subject: [PATCH 30/48] added better logging --- server.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server.js b/server.js index 08d1d926c..1e91759d4 100644 --- a/server.js +++ b/server.js @@ -971,7 +971,7 @@ async function startServer() { if (useIPv6) { console.log(color.green('IPv6 support detected')); } else { - console.log('IPv6 support detected'); + console.log('IPv6 support detected (but disabled)'); } } @@ -984,7 +984,7 @@ async function startServer() { if (useIPv4) { console.log(color.green('IPv4 support detected')); } else { - console.log('IPv4 support detected'); + console.log('IPv4 support detected (but disabled)'); } } } else { From 48be0ceb1640b5e5f2c5131007c13eb0021f98a0 Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Sat, 4 Jan 2025 16:10:45 +0200 Subject: [PATCH 31/48] Use named constants --- server.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server.js b/server.js index 1e91759d4..80833809b 100644 --- a/server.js +++ b/server.js @@ -289,12 +289,12 @@ if (dnsPreferIPv6) { const ipOptions = [true, 'auto', false]; if (!ipOptions.includes(enableIPv6)) { - console.warn(color.red('`protocol: ipv6` option invalid'), '\n use:', ipOptions, '\n setting to: auto'); - enableIPv6 = 'auto'; + console.warn(color.red('`protocol: ipv6` option invalid'), '\n use:', ipOptions, '\n setting to:', DEFAULT_ENABLE_IPV6); + enableIPv6 = DEFAULT_ENABLE_IPV6; } if (!ipOptions.includes(enableIPv4)) { - console.warn(color.red('`protocol: ipv4` option invalid'), '\n use:', ipOptions, '\n setting to: auto'); - enableIPv4 = 'auto'; + console.warn(color.red('`protocol: ipv4` option invalid'), '\n use:', ipOptions, '\n setting to:', DEFAULT_ENABLE_IPV4); + enableIPv4 = DEFAULT_ENABLE_IPV4; } if (enableIPv6 === false && enableIPv4 === false) { From e75d03fea94d6f690184c58a72bd2d4a3473dcd2 Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Sat, 4 Jan 2025 16:23:09 +0200 Subject: [PATCH 32/48] Fix lint --- server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.js b/server.js index 80833809b..3bd77eb65 100644 --- a/server.js +++ b/server.js @@ -988,7 +988,7 @@ async function startServer() { } } } else { - console.log("Neither protocol: ipv6, nor ipv4 are set to auto, skipping detection") + console.log('Neither protocol: ipv6, nor ipv4 are set to auto, skipping detection'); } From 188a043967f6d821d1bb43203add3b0553b3bbfb Mon Sep 17 00:00:00 2001 From: BPplays Date: Thu, 9 Jan 2025 04:10:19 -0800 Subject: [PATCH 33/48] started adding dns checking --- server.js | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/server.js b/server.js index 3bd77eb65..93919794a 100644 --- a/server.js +++ b/server.js @@ -382,6 +382,46 @@ function getSessionCookieAge() { return undefined; } + +function canResolve(name, useIPv6 = true, useIPv4 = true) { + return new Promise((resolve, reject) => { + let v6Resolve + let v4Resolve + + if (useIPv6) { + dns.resolve6(name, (err) => { + if (err) { + v6Resolve = false + } else { + v6Resolve = true + } + }); + + } else { + v6Resolve = false + } + + if (useIPv4) { + dns.resolve(name, (err) => { + if (err) { + v4Resolve = false + } else { + v4Resolve = true + } + }); + + } else { + v4Resolve = false + } + + if (v6Resolve || v4Resolve) { + resolve + } else { + reject + } + }); +} + async function getHasIP() { let hasIPv6 = false; let hasIPv6Local = false; From bab4f2105615e9976a1fa309bf746eda39da1395 Mon Sep 17 00:00:00 2001 From: BPplays Date: Thu, 9 Jan 2025 07:29:37 -0800 Subject: [PATCH 34/48] added dns checking --- server.js | 66 +++++++++++++++++++++++++++---------------------------- 1 file changed, 32 insertions(+), 34 deletions(-) diff --git a/server.js b/server.js index 93919794a..eeb0ba41c 100644 --- a/server.js +++ b/server.js @@ -9,6 +9,7 @@ import path from 'node:path'; import util from 'node:util'; import net from 'node:net'; import dns from 'node:dns'; +import { promises as dnsPromise } from 'node:dns' import process from 'node:process'; import { fileURLToPath } from 'node:url'; @@ -383,43 +384,36 @@ function getSessionCookieAge() { } -function canResolve(name, useIPv6 = true, useIPv4 = true) { - return new Promise((resolve, reject) => { - let v6Resolve - let v4Resolve +async function canResolve(name, useIPv6 = true, useIPv4 = true) { + try { + let v6Resolved = false; + let v4Resolved = false; if (useIPv6) { - dns.resolve6(name, (err) => { - if (err) { - v6Resolve = false - } else { - v6Resolve = true - } - }); - - } else { - v6Resolve = false + try { + await dnsPromise.resolve6(name); + v6Resolved = true; + } catch (error) { + v6Resolved = false; + } } + // If we need to check IPv4 resolution if (useIPv4) { - dns.resolve(name, (err) => { - if (err) { - v4Resolve = false - } else { - v4Resolve = true - } - }); - - } else { - v4Resolve = false + try { + await dnsPromise.resolve(name); + v4Resolved = true; + } catch (error) { + v4Resolved = false; + } } - if (v6Resolve || v4Resolve) { - resolve - } else { - reject - } - }); + console.log(v6Resolved, v4Resolved) + return v6Resolved || v4Resolved; + + } catch (error) { + return false; + } } async function getHasIP() { @@ -774,12 +768,14 @@ const preSetupTasks = async function () { /** * Gets the hostname to use for autorun in the browser. - * @returns {string} The hostname to use for autorun + * @returns promise({string} The hostname to use for autorun */ -function getAutorunHostname(useIPv6, useIPv4) { +async function getAutorunHostname(useIPv6, useIPv4) { if (autorunHostname === 'auto') { + let localhostResolve = await canResolve('localhost', useIPv6, useIPv4) + if (useIPv6 && useIPv4) { - if (avoidLocalhost) return '[::1]'; + if (avoidLocalhost || !localhostResolve) return '[::1]'; return 'localhost'; } @@ -792,6 +788,7 @@ function getAutorunHostname(useIPv6, useIPv4) { } } + return autorunHostname; } @@ -803,7 +800,7 @@ function getAutorunHostname(useIPv6, useIPv4) { const postSetupTasks = async function (v6Failed, v4Failed, useIPv6, useIPv4) { const autorunUrl = new URL( (cliArguments.ssl ? 'https://' : 'http://') + - (getAutorunHostname(useIPv6, useIPv4)) + + (await getAutorunHostname(useIPv6, useIPv4)) + (':') + ((autorunPortOverride >= 0) ? autorunPortOverride : server_port), ); @@ -1045,6 +1042,7 @@ async function startServer() { process.exit(1); } + const [v6Failed, v4Failed] = await startHTTPorHTTPS(useIPv6, useIPv4); handleServerListenFail(v6Failed, v4Failed, useIPv6, useIPv4); From d177314676b9500e6a81117c67f71c78435b1848 Mon Sep 17 00:00:00 2001 From: BPplays Date: Thu, 9 Jan 2025 07:30:22 -0800 Subject: [PATCH 35/48] formatting --- server.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/server.js b/server.js index eeb0ba41c..dee3c5b23 100644 --- a/server.js +++ b/server.js @@ -398,7 +398,6 @@ async function canResolve(name, useIPv6 = true, useIPv4 = true) { } } - // If we need to check IPv4 resolution if (useIPv4) { try { await dnsPromise.resolve(name); @@ -768,7 +767,7 @@ const preSetupTasks = async function () { /** * Gets the hostname to use for autorun in the browser. - * @returns promise({string} The hostname to use for autorun + * @returns Promise The hostname to use for autorun */ async function getAutorunHostname(useIPv6, useIPv4) { if (autorunHostname === 'auto') { From 874127a4f9ec37307696c9de27dc7450af749ae1 Mon Sep 17 00:00:00 2001 From: BPplays Date: Thu, 9 Jan 2025 07:30:50 -0800 Subject: [PATCH 36/48] lint --- server.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server.js b/server.js index dee3c5b23..40b345201 100644 --- a/server.js +++ b/server.js @@ -9,7 +9,7 @@ import path from 'node:path'; import util from 'node:util'; import net from 'node:net'; import dns from 'node:dns'; -import { promises as dnsPromise } from 'node:dns' +import { promises as dnsPromise } from 'node:dns'; import process from 'node:process'; import { fileURLToPath } from 'node:url'; @@ -407,7 +407,7 @@ async function canResolve(name, useIPv6 = true, useIPv4 = true) { } } - console.log(v6Resolved, v4Resolved) + console.log(v6Resolved, v4Resolved); return v6Resolved || v4Resolved; } catch (error) { @@ -771,7 +771,7 @@ const preSetupTasks = async function () { */ async function getAutorunHostname(useIPv6, useIPv4) { if (autorunHostname === 'auto') { - let localhostResolve = await canResolve('localhost', useIPv6, useIPv4) + let localhostResolve = await canResolve('localhost', useIPv6, useIPv4); if (useIPv6 && useIPv4) { if (avoidLocalhost || !localhostResolve) return '[::1]'; From 45e7edc9b80378a47243e07a4af556077078b29f Mon Sep 17 00:00:00 2001 From: BPplays Date: Thu, 9 Jan 2025 07:35:17 -0800 Subject: [PATCH 37/48] formatting --- server.js | 1 - 1 file changed, 1 deletion(-) diff --git a/server.js b/server.js index 40b345201..47d961c3b 100644 --- a/server.js +++ b/server.js @@ -407,7 +407,6 @@ async function canResolve(name, useIPv6 = true, useIPv4 = true) { } } - console.log(v6Resolved, v4Resolved); return v6Resolved || v4Resolved; } catch (error) { From adc5940d1523f4deba561b76a27d29950f2a6f18 Mon Sep 17 00:00:00 2001 From: BPplays Date: Thu, 9 Jan 2025 18:17:02 -0800 Subject: [PATCH 38/48] formatting changes --- server.js | 35 +++-------------------------------- src/util.js | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 32 deletions(-) diff --git a/server.js b/server.js index 47d961c3b..4cda91ae8 100644 --- a/server.js +++ b/server.js @@ -9,7 +9,6 @@ import path from 'node:path'; import util from 'node:util'; import net from 'node:net'; import dns from 'node:dns'; -import { promises as dnsPromise } from 'node:dns'; import process from 'node:process'; import { fileURLToPath } from 'node:url'; @@ -71,6 +70,7 @@ import { getSeparator, stringToBool, urlHostnameToIPv6, + canResolve, } from './src/util.js'; import { UPLOADS_DIRECTORY } from './src/constants.js'; import { ensureThumbnailCache } from './src/endpoints/thumbnails.js'; @@ -383,37 +383,6 @@ function getSessionCookieAge() { return undefined; } - -async function canResolve(name, useIPv6 = true, useIPv4 = true) { - try { - let v6Resolved = false; - let v4Resolved = false; - - if (useIPv6) { - try { - await dnsPromise.resolve6(name); - v6Resolved = true; - } catch (error) { - v6Resolved = false; - } - } - - if (useIPv4) { - try { - await dnsPromise.resolve(name); - v4Resolved = true; - } catch (error) { - v4Resolved = false; - } - } - - return v6Resolved || v4Resolved; - - } catch (error) { - return false; - } -} - async function getHasIP() { let hasIPv6 = false; let hasIPv6Local = false; @@ -794,6 +763,8 @@ async function getAutorunHostname(useIPv6, useIPv4) { * Tasks that need to be run after the server starts listening. * @param {boolean} v6Failed If the server failed to start on IPv6 * @param {boolean} v4Failed If the server failed to start on IPv4 + * @param {boolean} useIPv6 If the server is using IPv6 + * @param {boolean} useIPv4 If the server is using IPv4 */ const postSetupTasks = async function (v6Failed, v4Failed, useIPv6, useIPv4) { const autorunUrl = new URL( diff --git a/src/util.js b/src/util.js index b5034d248..c11de84e8 100644 --- a/src/util.js +++ b/src/util.js @@ -5,6 +5,7 @@ import process from 'node:process'; import { Readable } from 'node:stream'; import { createRequire } from 'node:module'; import { Buffer } from 'node:buffer'; +import { promises as dnsPromise } from 'node:dns'; import yaml from 'yaml'; import { sync as commandExistsSync } from 'command-exists'; @@ -692,6 +693,10 @@ export function isValidUrl(url) { } } +/** + * removes starting `[` or ending `]` from hostname. + * @param {string} hostname hostname to use + */ export function urlHostnameToIPv6(hostname) { if (hostname.startsWith('[')) { hostname = hostname.slice(1); @@ -702,6 +707,47 @@ export function urlHostnameToIPv6(hostname) { return hostname; } +/** + * Test if can resolve a dns name. + * @param {string} name Domain name to use + * @param {boolean} useIPv6 If use IPv6 + * @param {boolean} useIPv4 If use IPv4 + */ +export async function canResolve(name, useIPv6 = true, useIPv4 = true) { + try { + let v6Resolved = false; + let v4Resolved = false; + + if (useIPv6) { + try { + await dnsPromise.resolve6(name); + v6Resolved = true; + } catch (error) { + v6Resolved = false; + } + } + + if (useIPv4) { + try { + await dnsPromise.resolve(name); + v4Resolved = true; + } catch (error) { + v4Resolved = false; + } + } + + return v6Resolved || v4Resolved; + + } catch (error) { + return false; + } +} + + +/** + * converts string to boolean accepts 'true' or 'false' else it returns the string put in + * @param {string} str Input string + */ export function stringToBool(str) { if (str === 'true') return true; if (str === 'false') return false; From b43ac187ec606bce4f489a066e0960522e7d313d Mon Sep 17 00:00:00 2001 From: BPplays Date: Thu, 9 Jan 2025 18:27:21 -0800 Subject: [PATCH 39/48] formatting changes --- server.js | 12 ++++++++++++ src/util.js | 3 +++ 2 files changed, 15 insertions(+) diff --git a/server.js b/server.js index 4cda91ae8..05b9cec7a 100644 --- a/server.js +++ b/server.js @@ -735,6 +735,8 @@ const preSetupTasks = async function () { /** * Gets the hostname to use for autorun in the browser. + * @param {boolean} useIPv6 If use IPv6 + * @param {boolean} useIPv4 If use IPv4 * @returns Promise The hostname to use for autorun */ async function getAutorunHostname(useIPv6, useIPv4) { @@ -861,6 +863,8 @@ function logSecurityAlert(message) { * Handles the case where the server failed to start on one or both protocols. * @param {boolean} v6Failed If the server failed to start on IPv6 * @param {boolean} v4Failed If the server failed to start on IPv4 + * @param {boolean} useIPv6 If use IPv6 + * @param {boolean} useIPv4 If use IPv4 */ function handleServerListenFail(v6Failed, v4Failed, useIPv6, useIPv4) { if (v6Failed && !useIPv4) { @@ -882,6 +886,7 @@ function handleServerListenFail(v6Failed, v4Failed, useIPv6, useIPv4) { /** * Creates an HTTPS server. * @param {URL} url The URL to listen on + * @param {number} ipVersion the ip version to use * @returns {Promise} A promise that resolves when the server is listening * @throws {Error} If the server fails to start */ @@ -909,6 +914,7 @@ function createHttpsServer(url, ipVersion) { /** * Creates an HTTP server. * @param {URL} url The URL to listen on + * @param {number} ipVersion the ip version to use * @returns {Promise} A promise that resolves when the server is listening * @throws {Error} If the server fails to start */ @@ -929,6 +935,12 @@ function createHttpServer(url, ipVersion) { }); } + +/** + * Starts the server using http or https depending on config + * @param {boolean} useIPv6 If use IPv6 + * @param {boolean} useIPv4 If use IPv4 + */ async function startHTTPorHTTPS(useIPv6, useIPv4) { let v6Failed = false; let v4Failed = false; diff --git a/src/util.js b/src/util.js index c11de84e8..07422a7ef 100644 --- a/src/util.js +++ b/src/util.js @@ -696,6 +696,7 @@ export function isValidUrl(url) { /** * removes starting `[` or ending `]` from hostname. * @param {string} hostname hostname to use + * @returns {string} hostname plus the modifications */ export function urlHostnameToIPv6(hostname) { if (hostname.startsWith('[')) { @@ -712,6 +713,7 @@ export function urlHostnameToIPv6(hostname) { * @param {string} name Domain name to use * @param {boolean} useIPv6 If use IPv6 * @param {boolean} useIPv4 If use IPv4 + * @returns Promise If the URL is valid */ export async function canResolve(name, useIPv6 = true, useIPv4 = true) { try { @@ -747,6 +749,7 @@ export async function canResolve(name, useIPv6 = true, useIPv4 = true) { /** * converts string to boolean accepts 'true' or 'false' else it returns the string put in * @param {string} str Input string + * @returns {boolean|string} boolean else original input string */ export function stringToBool(str) { if (str === 'true') return true; From 5b5b9a91aa83db22c9365fd7d3299e07b677ece6 Mon Sep 17 00:00:00 2001 From: BPplays Date: Thu, 9 Jan 2025 18:44:48 -0800 Subject: [PATCH 40/48] more jsdoc stuff --- server.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/server.js b/server.js index 05b9cec7a..8a3fe833c 100644 --- a/server.js +++ b/server.js @@ -383,6 +383,16 @@ function getSessionCookieAge() { return undefined; } + +/** + * Checks the network interfaces to determine the presence of IPv6 and IPv4 addresses. + * + * @returns {Promise<[boolean, boolean, boolean, boolean]>} A promise that resolves to an array containing: + * - [0]: `hasIPv6` (boolean) - Whether the computer has any IPv6 address, including (`::1`). + * - [1]: `hasIPv4` (boolean) - Whether the computer has any IPv4 address, including (`127.0.0.1`). + * - [2]: `hasIPv6Local` (boolean) - Whether the computer has local IPv6 address (`::1`). + * - [3]: `hasIPv4Local` (boolean) - Whether the computer has local IPv4 address (`127.0.0.1`). + */ async function getHasIP() { let hasIPv6 = false; let hasIPv6Local = false; From f372e1a69d274448878d4255388e1bbfe8ee1a17 Mon Sep 17 00:00:00 2001 From: BPplays Date: Thu, 9 Jan 2025 19:09:55 -0800 Subject: [PATCH 41/48] more jsdoc stuff --- server.js | 13 +++++++++++++ src/util.js | 4 ++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/server.js b/server.js index 8a3fe833c..f95226f7d 100644 --- a/server.js +++ b/server.js @@ -248,28 +248,41 @@ app.use(compression()); app.use(responseTime()); +/** @type {number} */ const server_port = cliArguments.port ?? process.env.SILLY_TAVERN_PORT ?? getConfigValue('port', DEFAULT_PORT); +/** @type {boolean} */ const autorun = (cliArguments.autorun ?? getConfigValue('autorun', DEFAULT_AUTORUN)) && !cliArguments.ssl; +/** @type {boolean} */ const listen = cliArguments.listen ?? getConfigValue('listen', DEFAULT_LISTEN); +/** @type {boolean} */ const enableCorsProxy = cliArguments.corsProxy ?? getConfigValue('enableCorsProxy', DEFAULT_CORS_PROXY); const enableWhitelist = cliArguments.whitelist ?? getConfigValue('whitelistMode', DEFAULT_WHITELIST); +/** @type {string} */ const dataRoot = cliArguments.dataRoot ?? getConfigValue('dataRoot', './data'); +/** @type {boolean} */ const disableCsrf = cliArguments.disableCsrf ?? getConfigValue('disableCsrfProtection', DEFAULT_CSRF_DISABLED); const basicAuthMode = cliArguments.basicAuthMode ?? getConfigValue('basicAuthMode', DEFAULT_BASIC_AUTH); const perUserBasicAuth = getConfigValue('perUserBasicAuth', DEFAULT_PER_USER_BASIC_AUTH); +/** @type {boolean} */ const enableAccounts = getConfigValue('enableUserAccounts', DEFAULT_ACCOUNTS); const uploadsPath = path.join(dataRoot, UPLOADS_DIRECTORY); +/** @type {boolean|'auto'} */ let enableIPv6 = stringToBool(cliArguments.enableIPv6) ?? getConfigValue('protocol.ipv6', DEFAULT_ENABLE_IPV6); +/** @type {boolean|'auto'} */ let enableIPv4 = stringToBool(cliArguments.enableIPv4) ?? getConfigValue('protocol.ipv4', DEFAULT_ENABLE_IPV4); +/** @type {string} */ const autorunHostname = cliArguments.autorunHostname ?? getConfigValue('autorunHostname', DEFAULT_AUTORUN_HOSTNAME); +/** @type {number} */ const autorunPortOverride = cliArguments.autorunPortOverride ?? getConfigValue('autorunPortOverride', DEFAULT_AUTORUN_PORT); +/** @type {boolean} */ const dnsPreferIPv6 = cliArguments.dnsPreferIPv6 ?? getConfigValue('dnsPreferIPv6', DEFAULT_PREFER_IPV6); +/** @type {boolean} */ const avoidLocalhost = cliArguments.avoidLocalhost ?? getConfigValue('avoidLocalhost', DEFAULT_AVOID_LOCALHOST); const proxyEnabled = cliArguments.requestProxyEnabled ?? getConfigValue('requestProxy.enabled', DEFAULT_PROXY_ENABLED); diff --git a/src/util.js b/src/util.js index 07422a7ef..72c1ae704 100644 --- a/src/util.js +++ b/src/util.js @@ -748,8 +748,8 @@ export async function canResolve(name, useIPv6 = true, useIPv4 = true) { /** * converts string to boolean accepts 'true' or 'false' else it returns the string put in - * @param {string} str Input string - * @returns {boolean|string} boolean else original input string + * @param {string|null} str Input string or null + * @returns {boolean|string|null} boolean else original input string or null if input is */ export function stringToBool(str) { if (str === 'true') return true; From 9f98bee3625c7e004533e6ab3c476ed3664c4097 Mon Sep 17 00:00:00 2001 From: BPplays Date: Thu, 9 Jan 2025 19:42:27 -0800 Subject: [PATCH 42/48] foramtting --- server.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server.js b/server.js index f95226f7d..468b1cb4c 100644 --- a/server.js +++ b/server.js @@ -269,9 +269,9 @@ const enableAccounts = getConfigValue('enableUserAccounts', DEFAULT_ACCOUNTS); const uploadsPath = path.join(dataRoot, UPLOADS_DIRECTORY); -/** @type {boolean|'auto'} */ +/** @type {boolean | "auto"} */ let enableIPv6 = stringToBool(cliArguments.enableIPv6) ?? getConfigValue('protocol.ipv6', DEFAULT_ENABLE_IPV6); -/** @type {boolean|'auto'} */ +/** @type {boolean | "auto"} */ let enableIPv4 = stringToBool(cliArguments.enableIPv4) ?? getConfigValue('protocol.ipv4', DEFAULT_ENABLE_IPV4); /** @type {string} */ From aa10dd98c9e2fc8f605962dab3280de1654e2c89 Mon Sep 17 00:00:00 2001 From: BPplays Date: Fri, 10 Jan 2025 02:56:00 -0800 Subject: [PATCH 43/48] more jsdoc stuff --- server.js | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/server.js b/server.js index 468b1cb4c..d5052e583 100644 --- a/server.js +++ b/server.js @@ -998,7 +998,13 @@ async function startHTTPorHTTPS(useIPv6, useIPv4) { async function startServer() { let useIPv6 = (enableIPv6 === true); let useIPv4 = (enableIPv4 === true); - let hasIPv6, hasIPv4, hasIPv6Local, hasIPv4Local, hasIPv6Any, hasIPv4Any; + + let /** @type {boolean} */ hasIPv6, + /** @type {boolean} */ hasIPv4, + /** @type {boolean} */ hasIPv6Local, + /** @type {boolean} */ hasIPv4Local, + /** @type {boolean} */ hasIPv6Any, + /** @type {boolean} */ hasIPv4Any; if (enableIPv6 === 'auto' || enableIPv4 === 'auto') { @@ -1028,18 +1034,21 @@ async function startServer() { console.log('IPv4 support detected (but disabled)'); } } + + + if (enableIPv6 === 'auto' && enableIPv4 === 'auto') { + if (!hasIPv6 && !hasIPv4) { + console.error('Both IPv6 and IPv4 are not detected'); + process.exit(1); + } + } + } else { console.log('Neither protocol: ipv6, nor ipv4 are set to auto, skipping detection'); } - if (enableIPv6 === 'auto' && enableIPv4 === 'auto') { - if (!hasIPv6 && !hasIPv4) { - console.error('Both IPv6 and IPv4 are not detected'); - process.exit(1); - } - } if (!useIPv6 && !useIPv4) { console.error('Both IPv6 and IPv4 are disabled,\nP.S. you should never see this error, at least at one point it was checked for before this, with the rest of the config options'); From faaa4ba6bc812235b4ecd2736c59c80272dae890 Mon Sep 17 00:00:00 2001 From: BPplays Date: Fri, 10 Jan 2025 03:58:15 -0800 Subject: [PATCH 44/48] changed formatting --- server.js | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/server.js b/server.js index d5052e583..fe2cf4d1a 100644 --- a/server.js +++ b/server.js @@ -419,6 +419,7 @@ async function getHasIP() { if (iface === undefined) { continue; } + for (const info of iface) { if (info.family === 'IPv6') { hasIPv6 = true; @@ -437,7 +438,12 @@ async function getHasIP() { } if (hasIPv6 && hasIPv4 && hasIPv6Local && hasIPv4Local) break; } - return [hasIPv6, hasIPv4, hasIPv6Local, hasIPv4Local]; + return [ + hasIPv6, + hasIPv4, + hasIPv6Local, + hasIPv4Local, + ]; } app.use(cookieSession({ @@ -808,11 +814,15 @@ const postSetupTasks = async function (v6Failed, v4Failed, useIPv6, useIPv4) { let logListen = 'SillyTavern is listening on'; if (useIPv6 && !v6Failed) { - logListen += color.green(' IPv6: ' + tavernUrlV6.host); + logListen += color.green( + ' IPv6: ' + tavernUrlV6.host + ); } if (useIPv4 && !v4Failed) { - logListen += color.green(' IPv4: ' + tavernUrl.host); + logListen += color.green( + ' IPv4: ' + tavernUrl.host + ); } const goToLog = 'Go to: ' + color.blue(autorunUrl) + ' to open SillyTavern'; @@ -824,16 +834,22 @@ const postSetupTasks = async function (v6Failed, v4Failed, useIPv6, useIPv4) { console.log('\n' + getSeparator(plainGoToLog.length) + '\n'); if (listen) { - console.log('[::] or 0.0.0.0 means SillyTavern is listening on all network interfaces (Wi-Fi, LAN, localhost). If you want to limit it only to internal localhost ([::1] or 127.0.0.1), change the setting in config.yaml to "listen: false". Check "access.log" file in the SillyTavern directory if you want to inspect incoming connections.\n'); + console.log( + '[::] or 0.0.0.0 means SillyTavern is listening on all network interfaces (Wi-Fi, LAN, localhost). If you want to limit it only to internal localhost ([::1] or 127.0.0.1), change the setting in config.yaml to "listen: false". Check "access.log" file in the SillyTavern directory if you want to inspect incoming connections.\n' + ); } if (basicAuthMode) { if (perUserBasicAuth && !enableAccounts) { - console.error(color.red('Per-user basic authentication is enabled, but user accounts are disabled. This configuration may be insecure.')); + console.error(color.red( + 'Per-user basic authentication is enabled, but user accounts are disabled. This configuration may be insecure.' + )); } else if (!perUserBasicAuth) { const basicAuthUser = getConfigValue('basicAuthUser', {}); if (!basicAuthUser?.username || !basicAuthUser?.password) { - console.warn(color.yellow('Basic Authentication is enabled, but username or password is not set or empty!')); + console.warn(color.yellow( + 'Basic Authentication is enabled, but username or password is not set or empty!' + )); } } } @@ -1010,6 +1026,7 @@ async function startServer() { if (enableIPv6 === 'auto' || enableIPv4 === 'auto') { [hasIPv6Any, hasIPv4Any, hasIPv6Local, hasIPv4Local] = await getHasIP(); + hasIPv6 = listen ? hasIPv6Any : hasIPv6Local; if (enableIPv6 === 'auto') { useIPv6 = hasIPv6; @@ -1059,6 +1076,7 @@ async function startServer() { const [v6Failed, v4Failed] = await startHTTPorHTTPS(useIPv6, useIPv4); handleServerListenFail(v6Failed, v4Failed, useIPv6, useIPv4); + postSetupTasks(v6Failed, v4Failed, useIPv6, useIPv4); } From d769798ba3d15f197430e3fb00e13a4a08288a5a Mon Sep 17 00:00:00 2001 From: BPplays Date: Sun, 12 Jan 2025 22:39:42 -0800 Subject: [PATCH 45/48] replaced some jsdoc with assigning false by default --- server.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/server.js b/server.js index fe2cf4d1a..e8c3cf347 100644 --- a/server.js +++ b/server.js @@ -1015,12 +1015,12 @@ async function startServer() { let useIPv6 = (enableIPv6 === true); let useIPv4 = (enableIPv4 === true); - let /** @type {boolean} */ hasIPv6, - /** @type {boolean} */ hasIPv4, - /** @type {boolean} */ hasIPv6Local, - /** @type {boolean} */ hasIPv4Local, - /** @type {boolean} */ hasIPv6Any, - /** @type {boolean} */ hasIPv4Any; + let hasIPv6 = false, + hasIPv4 = false, + hasIPv6Local = false, + hasIPv4Local = false, + hasIPv6Any = false, + hasIPv4Any = false; if (enableIPv6 === 'auto' || enableIPv4 === 'auto') { From d9bb5e6b1ff17bccd8e3145a91f6c0e10a0267a7 Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Tue, 4 Feb 2025 22:46:24 +0200 Subject: [PATCH 46/48] Revert old default values --- default/config.yaml | 4 ++-- server.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/default/config.yaml b/default/config.yaml index 0945cfa2f..94673ca11 100644 --- a/default/config.yaml +++ b/default/config.yaml @@ -10,8 +10,8 @@ listen: false # - Use option "auto" to automatically detect support # - Use true or false (no qoutes) to enable or disable each protocol protocol: - ipv4: auto - ipv6: auto + ipv4: true + ipv6: false # Prefers IPv6 for DNS. Enable this on ISPs that don't have issues with IPv6 dnsPreferIPv6: false # The hostname that autorun opens. diff --git a/server.js b/server.js index ae8a6bb66..1aa367915 100644 --- a/server.js +++ b/server.js @@ -137,8 +137,8 @@ const DEFAULT_CSRF_DISABLED = false; const DEFAULT_BASIC_AUTH = false; const DEFAULT_PER_USER_BASIC_AUTH = false; -const DEFAULT_ENABLE_IPV6 = 'auto'; -const DEFAULT_ENABLE_IPV4 = 'auto'; +const DEFAULT_ENABLE_IPV6 = false; +const DEFAULT_ENABLE_IPV4 = true; const DEFAULT_PREFER_IPV6 = false; From dfb062af41ba9510b37ff98a6fa385d522bc5c6f Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Tue, 4 Feb 2025 22:52:07 +0200 Subject: [PATCH 47/48] Clean-uo blank lines --- server.js | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/server.js b/server.js index 1aa367915..51f97e0ad 100644 --- a/server.js +++ b/server.js @@ -396,7 +396,6 @@ function getSessionCookieAge() { return undefined; } - /** * Checks the network interfaces to determine the presence of IPv6 and IPv4 addresses. * @@ -796,7 +795,6 @@ async function getAutorunHostname(useIPv6, useIPv4) { } } - return autorunHostname; } @@ -1034,11 +1032,9 @@ async function startServer() { hasIPv6Any = false, hasIPv4Any = false; - if (enableIPv6 === 'auto' || enableIPv4 === 'auto') { [hasIPv6Any, hasIPv4Any, hasIPv6Local, hasIPv4Local] = await getHasIP(); - hasIPv6 = listen ? hasIPv6Any : hasIPv6Local; if (enableIPv6 === 'auto') { useIPv6 = hasIPv6; @@ -1051,7 +1047,6 @@ async function startServer() { } } - hasIPv4 = listen ? hasIPv4Any : hasIPv4Local; if (enableIPv4 === 'auto') { useIPv4 = hasIPv4; @@ -1064,7 +1059,6 @@ async function startServer() { } } - if (enableIPv6 === 'auto' && enableIPv4 === 'auto') { if (!hasIPv6 && !hasIPv4) { console.error('Both IPv6 and IPv4 are not detected'); @@ -1076,19 +1070,13 @@ async function startServer() { console.log('Neither protocol: ipv6, nor ipv4 are set to auto, skipping detection'); } - - - if (!useIPv6 && !useIPv4) { console.error('Both IPv6 and IPv4 are disabled,\nP.S. you should never see this error, at least at one point it was checked for before this, with the rest of the config options'); process.exit(1); } - const [v6Failed, v4Failed] = await startHTTPorHTTPS(useIPv6, useIPv4); - handleServerListenFail(v6Failed, v4Failed, useIPv6, useIPv4); - postSetupTasks(v6Failed, v4Failed, useIPv6, useIPv4); } From 5f564343ec323d2111836dce98e983da5cc44a7a Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Tue, 4 Feb 2025 23:14:01 +0200 Subject: [PATCH 48/48] Remove console log --- server.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/server.js b/server.js index 51f97e0ad..e62562e56 100644 --- a/server.js +++ b/server.js @@ -984,7 +984,6 @@ function createHttpServer(url, ipVersion) { }); } - /** * Starts the server using http or https depending on config * @param {boolean} useIPv6 If use IPv6 @@ -1065,9 +1064,6 @@ async function startServer() { process.exit(1); } } - - } else { - console.log('Neither protocol: ipv6, nor ipv4 are set to auto, skipping detection'); } if (!useIPv6 && !useIPv4) {