Merge branch 'staging' into replace-ajax

ace3e942999b7a37b1c5c7b8283fb1a322793699

Cohee <18619528+Cohee1207@users.noreply.github.com>

7 files changed, +623 -19Ignore whitespace
.github/readme.md+40 -0
@@ -276,6 +276,46 @@ In order to enable viewing your keys by clicking a button in the API block:
2762761. Set the value of `allowKeysExposure` to `true` in `config.yaml` file.
2772772. Restart the SillyTavern server.
278278
279+## Command-line arguments
280+
281+You can pass command-line arguments to SillyTavern server startup to override some settings in `config.yaml`.
282+
283+### Examples
284+
285+```shell
286+node server.js --port 8000 --listen false
287+# or
288+npm run start -- --port 8000 --listen false
289+# or (Windows only)
290+Start.bat --port 8000 --listen false
291+```
292+
293+### Supported arguments
294+
295+| Option | Description | Type | Default |
296+|-------------------------|------------------------------------------------------------------------------------------------------|----------|------------------------------|
297+| `--version` | Show version number | boolean | |
298+| `--enableIPv6` | Enables IPv6. | boolean | false |
299+| `--enableIPv4` | Enables IPv4. | boolean | true |
300+| `--port` | Sets the port under which SillyTavern will run. If not provided falls back to yaml config 'port'. | number | 8000 |
301+| `--dnsPreferIPv6` | Prefers IPv6 for dns. If not provided falls back to yaml config 'preferIPv6'. | boolean | false |
302+| `--autorun` | Automatically launch SillyTavern in the browser. If not provided falls back to yaml config 'autorun'.| boolean | false |
303+| `--autorunHostname` | The autorun hostname, probably best left on 'auto'. | string | null |
304+| `--autorunPortOverride` | Overrides the port for autorun. | string | null |
305+| `--listen` | SillyTavern is listening on all network interfaces. If not provided falls back to yaml config 'listen'.| boolean | false |
306+| `--corsProxy` | Enables CORS proxy. If not provided falls back to yaml config 'enableCorsProxy'. | boolean | false |
307+| `--disableCsrf` | Disables CSRF protection | boolean | null |
308+| `--ssl` | Enables SSL | boolean | false |
309+| `--certPath` | Path to your certificate file. | string | "certs/cert.pem" |
310+| `--keyPath` | Path to your private key file. | string | "certs/privkey.pem" |
311+| `--whitelist` | Enables whitelist mode | boolean | null |
312+| `--dataRoot` | Root directory for data storage | string | null |
313+| `--avoidLocalhost` | Avoids using 'localhost' for autorun in auto mode. | boolean | null |
314+| `--basicAuthMode` | Enables basic authentication | boolean | null |
315+| `--requestProxyEnabled` | Enables a use of proxy for outgoing requests | boolean | null |
316+| `--requestProxyUrl` | Request proxy URL (HTTP or SOCKS protocols) | string | null |
317+| `--requestProxyBypass` | Request proxy bypass list (space separated list of hosts) | array | null |
318+
279319## Remote connections
280320
281321Most often this is for people who want to use SillyTavern on their mobile phones while their PC runs the ST server on the same wifi network.
default/config.yaml+10 -0
@@ -37,6 +37,16 @@ basicAuthUser:
3737 password: "password"
3838# Enables CORS proxy middleware
3939enableCorsProxy: false
40+# -- REQUEST PROXY CONFIGURATION --
41+requestProxy:
42+ # If a proxy is enabled, all outgoing HTTP/HTTPS requests will be routed through it.
43+ enabled: false
44+ # Proxy URL. Possible protocols: http, https, socks, socks5, socks4, pac
45+ url: "socks5://username:password@example.com:1080"
46+ # Proxy bypass list. Requests to these hosts won't be routed through the proxy.
47+ bypass:
48+ - localhost
49+ - 127.0.0.1
4050# Enable multi-user mode
4151enableUserAccounts: false
4252# Enable discreet login mode: hides user list on the login screen
package-lock.json+482 -2
@@ -40,6 +40,7 @@
4040 "png-chunk-text": "^1.0.0",
4141 "png-chunks-encode": "^1.0.0",
4242 "png-chunks-extract": "^1.0.0",
43+ "proxy-agent": "^6.4.0",
4344 "rate-limiter-flexible": "^5.0.0",
4445 "response-time": "^2.3.2",
4546 "sanitize-filename": "^1.6.3",
@@ -941,6 +942,12 @@
941942 "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==",
942943 "license": "MIT"
943944 },
945+ "node_modules/@tootallnate/quickjs-emscripten": {
946+ "version": "0.23.0",
947+ "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz",
948+ "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==",
949+ "license": "MIT"
950+ },
944951 "node_modules/@types/cacheable-request": {
945952 "version": "6.0.3",
946953 "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz",
@@ -1080,6 +1087,41 @@
10801087 "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
10811088 }
10821089 },
1090+ "node_modules/agent-base": {
1091+ "version": "7.1.1",
1092+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz",
1093+ "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==",
1094+ "license": "MIT",
1095+ "dependencies": {
1096+ "debug": "^4.3.4"
1097+ },
1098+ "engines": {
1099+ "node": ">= 14"
1100+ }
1101+ },
1102+ "node_modules/agent-base/node_modules/debug": {
1103+ "version": "4.3.7",
1104+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
1105+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
1106+ "license": "MIT",
1107+ "dependencies": {
1108+ "ms": "^2.1.3"
1109+ },
1110+ "engines": {
1111+ "node": ">=6.0"
1112+ },
1113+ "peerDependenciesMeta": {
1114+ "supports-color": {
1115+ "optional": true
1116+ }
1117+ }
1118+ },
1119+ "node_modules/agent-base/node_modules/ms": {
1120+ "version": "2.1.3",
1121+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
1122+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
1123+ "license": "MIT"
1124+ },
10831125 "node_modules/agentkeepalive": {
10841126 "version": "4.5.0",
10851127 "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz",
@@ -1382,6 +1424,18 @@
13821424 "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
13831425 "license": "MIT"
13841426 },
1427+ "node_modules/ast-types": {
1428+ "version": "0.13.4",
1429+ "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz",
1430+ "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==",
1431+ "license": "MIT",
1432+ "dependencies": {
1433+ "tslib": "^2.0.1"
1434+ },
1435+ "engines": {
1436+ "node": ">=4"
1437+ }
1438+ },
13851439 "node_modules/async": {
13861440 "version": "3.2.5",
13871441 "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz",
@@ -1445,6 +1499,15 @@
14451499 ],
14461500 "license": "MIT"
14471501 },
1502+ "node_modules/basic-ftp": {
1503+ "version": "5.0.5",
1504+ "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz",
1505+ "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==",
1506+ "license": "MIT",
1507+ "engines": {
1508+ "node": ">=10.0.0"
1509+ }
1510+ },
14481511 "node_modules/bing-translate-api": {
14491512 "version": "2.9.1",
14501513 "resolved": "https://registry.npmjs.org/bing-translate-api/-/bing-translate-api-2.9.1.tgz",
@@ -2250,6 +2313,15 @@
22502313 "url": "https://github.com/sponsors/fb55"
22512314 }
22522315 },
2316+ "node_modules/data-uri-to-buffer": {
2317+ "version": "6.0.2",
2318+ "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz",
2319+ "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==",
2320+ "license": "MIT",
2321+ "engines": {
2322+ "node": ">= 14"
2323+ }
2324+ },
22532325 "node_modules/debug": {
22542326 "version": "2.6.9",
22552327 "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -2316,6 +2388,20 @@
23162388 "node": ">=8"
23172389 }
23182390 },
2391+ "node_modules/degenerator": {
2392+ "version": "5.0.1",
2393+ "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz",
2394+ "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==",
2395+ "license": "MIT",
2396+ "dependencies": {
2397+ "ast-types": "^0.13.4",
2398+ "escodegen": "^2.1.0",
2399+ "esprima": "^4.0.1"
2400+ },
2401+ "engines": {
2402+ "node": ">= 14"
2403+ }
2404+ },
23192405 "node_modules/delayed-stream": {
23202406 "version": "1.0.0",
23212407 "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
@@ -2528,6 +2614,27 @@
25282614 "node": ">=0.8.0"
25292615 }
25302616 },
2617+ "node_modules/escodegen": {
2618+ "version": "2.1.0",
2619+ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz",
2620+ "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==",
2621+ "license": "BSD-2-Clause",
2622+ "dependencies": {
2623+ "esprima": "^4.0.1",
2624+ "estraverse": "^5.2.0",
2625+ "esutils": "^2.0.2"
2626+ },
2627+ "bin": {
2628+ "escodegen": "bin/escodegen.js",
2629+ "esgenerate": "bin/esgenerate.js"
2630+ },
2631+ "engines": {
2632+ "node": ">=6.0"
2633+ },
2634+ "optionalDependencies": {
2635+ "source-map": "~0.6.1"
2636+ }
2637+ },
25312638 "node_modules/eslint": {
25322639 "version": "8.57.0",
25332640 "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz",
@@ -2683,6 +2790,19 @@
26832790 "url": "https://opencollective.com/eslint"
26842791 }
26852792 },
2793+ "node_modules/esprima": {
2794+ "version": "4.0.1",
2795+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
2796+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
2797+ "license": "BSD-2-Clause",
2798+ "bin": {
2799+ "esparse": "bin/esparse.js",
2800+ "esvalidate": "bin/esvalidate.js"
2801+ },
2802+ "engines": {
2803+ "node": ">=4"
2804+ }
2805+ },
26862806 "node_modules/esquery": {
26872807 "version": "1.5.0",
26882808 "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
@@ -2713,7 +2833,6 @@
27132833 "version": "5.3.0",
27142834 "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
27152835 "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
2716- "dev": true,
27172836 "license": "BSD-2-Clause",
27182837 "engines": {
27192838 "node": ">=4.0"
@@ -2723,7 +2842,6 @@
27232842 "version": "2.0.3",
27242843 "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
27252844 "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
2726- "dev": true,
27272845 "license": "BSD-2-Clause",
27282846 "engines": {
27292847 "node": ">=0.10.0"
@@ -3071,6 +3189,20 @@
30713189 "node": ">= 0.6"
30723190 }
30733191 },
3192+ "node_modules/fs-extra": {
3193+ "version": "11.2.0",
3194+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz",
3195+ "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==",
3196+ "license": "MIT",
3197+ "dependencies": {
3198+ "graceful-fs": "^4.2.0",
3199+ "jsonfile": "^6.0.1",
3200+ "universalify": "^2.0.0"
3201+ },
3202+ "engines": {
3203+ "node": ">=14.14"
3204+ }
3205+ },
30743206 "node_modules/fs.realpath": {
30753207 "version": "1.0.0",
30763208 "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@@ -3130,6 +3262,44 @@
31303262 "url": "https://github.com/sponsors/sindresorhus"
31313263 }
31323264 },
3265+ "node_modules/get-uri": {
3266+ "version": "6.0.3",
3267+ "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz",
3268+ "integrity": "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==",
3269+ "license": "MIT",
3270+ "dependencies": {
3271+ "basic-ftp": "^5.0.2",
3272+ "data-uri-to-buffer": "^6.0.2",
3273+ "debug": "^4.3.4",
3274+ "fs-extra": "^11.2.0"
3275+ },
3276+ "engines": {
3277+ "node": ">= 14"
3278+ }
3279+ },
3280+ "node_modules/get-uri/node_modules/debug": {
3281+ "version": "4.3.7",
3282+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
3283+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
3284+ "license": "MIT",
3285+ "dependencies": {
3286+ "ms": "^2.1.3"
3287+ },
3288+ "engines": {
3289+ "node": ">=6.0"
3290+ },
3291+ "peerDependenciesMeta": {
3292+ "supports-color": {
3293+ "optional": true
3294+ }
3295+ }
3296+ },
3297+ "node_modules/get-uri/node_modules/ms": {
3298+ "version": "2.1.3",
3299+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
3300+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
3301+ "license": "MIT"
3302+ },
31333303 "node_modules/gifwrap": {
31343304 "version": "0.10.1",
31353305 "resolved": "https://registry.npmjs.org/gifwrap/-/gifwrap-0.10.1.tgz",
@@ -3369,6 +3539,42 @@
33693539 "node": ">= 0.8"
33703540 }
33713541 },
3542+ "node_modules/http-proxy-agent": {
3543+ "version": "7.0.2",
3544+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
3545+ "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
3546+ "license": "MIT",
3547+ "dependencies": {
3548+ "agent-base": "^7.1.0",
3549+ "debug": "^4.3.4"
3550+ },
3551+ "engines": {
3552+ "node": ">= 14"
3553+ }
3554+ },
3555+ "node_modules/http-proxy-agent/node_modules/debug": {
3556+ "version": "4.3.7",
3557+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
3558+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
3559+ "license": "MIT",
3560+ "dependencies": {
3561+ "ms": "^2.1.3"
3562+ },
3563+ "engines": {
3564+ "node": ">=6.0"
3565+ },
3566+ "peerDependenciesMeta": {
3567+ "supports-color": {
3568+ "optional": true
3569+ }
3570+ }
3571+ },
3572+ "node_modules/http-proxy-agent/node_modules/ms": {
3573+ "version": "2.1.3",
3574+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
3575+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
3576+ "license": "MIT"
3577+ },
33723578 "node_modules/http2-wrapper": {
33733579 "version": "1.0.3",
33743580 "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz",
@@ -3382,6 +3588,42 @@
33823588 "node": ">=10.19.0"
33833589 }
33843590 },
3591+ "node_modules/https-proxy-agent": {
3592+ "version": "7.0.5",
3593+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz",
3594+ "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==",
3595+ "license": "MIT",
3596+ "dependencies": {
3597+ "agent-base": "^7.0.2",
3598+ "debug": "4"
3599+ },
3600+ "engines": {
3601+ "node": ">= 14"
3602+ }
3603+ },
3604+ "node_modules/https-proxy-agent/node_modules/debug": {
3605+ "version": "4.3.7",
3606+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
3607+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
3608+ "license": "MIT",
3609+ "dependencies": {
3610+ "ms": "^2.1.3"
3611+ },
3612+ "engines": {
3613+ "node": ">=6.0"
3614+ },
3615+ "peerDependenciesMeta": {
3616+ "supports-color": {
3617+ "optional": true
3618+ }
3619+ }
3620+ },
3621+ "node_modules/https-proxy-agent/node_modules/ms": {
3622+ "version": "2.1.3",
3623+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
3624+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
3625+ "license": "MIT"
3626+ },
33853627 "node_modules/humanize-ms": {
33863628 "version": "1.2.1",
33873629 "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
@@ -3485,6 +3727,19 @@
34853727 "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
34863728 "license": "ISC"
34873729 },
3730+ "node_modules/ip-address": {
3731+ "version": "9.0.5",
3732+ "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz",
3733+ "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==",
3734+ "license": "MIT",
3735+ "dependencies": {
3736+ "jsbn": "1.1.0",
3737+ "sprintf-js": "^1.1.3"
3738+ },
3739+ "engines": {
3740+ "node": ">= 12"
3741+ }
3742+ },
34883743 "node_modules/ip-matching": {
34893744 "version": "2.1.2",
34903745 "resolved": "https://registry.npmjs.org/ip-matching/-/ip-matching-2.1.2.tgz",
@@ -3669,6 +3924,12 @@
36693924 "js-yaml": "bin/js-yaml.js"
36703925 }
36713926 },
3927+ "node_modules/jsbn": {
3928+ "version": "1.1.0",
3929+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz",
3930+ "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==",
3931+ "license": "MIT"
3932+ },
36723933 "node_modules/json-buffer": {
36733934 "version": "3.0.1",
36743935 "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
@@ -3761,6 +4022,18 @@
37614022 "dev": true,
37624023 "license": "MIT"
37634024 },
4025+ "node_modules/jsonfile": {
4026+ "version": "6.1.0",
4027+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
4028+ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
4029+ "license": "MIT",
4030+ "dependencies": {
4031+ "universalify": "^2.0.0"
4032+ },
4033+ "optionalDependencies": {
4034+ "graceful-fs": "^4.1.6"
4035+ }
4036+ },
37644037 "node_modules/keygrip": {
37654038 "version": "1.1.0",
37664039 "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz",
@@ -4053,6 +4326,15 @@
40534326 "node": ">= 0.6"
40544327 }
40554328 },
4329+ "node_modules/netmask": {
4330+ "version": "2.0.2",
4331+ "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz",
4332+ "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==",
4333+ "license": "MIT",
4334+ "engines": {
4335+ "node": ">= 0.4.0"
4336+ }
4337+ },
40564338 "node_modules/node-domexception": {
40574339 "version": "1.0.0",
40584340 "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
@@ -4323,6 +4605,61 @@
43234605 "url": "https://github.com/sponsors/sindresorhus"
43244606 }
43254607 },
4608+ "node_modules/pac-proxy-agent": {
4609+ "version": "7.0.2",
4610+ "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.2.tgz",
4611+ "integrity": "sha512-BFi3vZnO9X5Qt6NRz7ZOaPja3ic0PhlsmCRYLOpN11+mWBCR6XJDqW5RF3j8jm4WGGQZtBA+bTfxYzeKW73eHg==",
4612+ "license": "MIT",
4613+ "dependencies": {
4614+ "@tootallnate/quickjs-emscripten": "^0.23.0",
4615+ "agent-base": "^7.0.2",
4616+ "debug": "^4.3.4",
4617+ "get-uri": "^6.0.1",
4618+ "http-proxy-agent": "^7.0.0",
4619+ "https-proxy-agent": "^7.0.5",
4620+ "pac-resolver": "^7.0.1",
4621+ "socks-proxy-agent": "^8.0.4"
4622+ },
4623+ "engines": {
4624+ "node": ">= 14"
4625+ }
4626+ },
4627+ "node_modules/pac-proxy-agent/node_modules/debug": {
4628+ "version": "4.3.7",
4629+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
4630+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
4631+ "license": "MIT",
4632+ "dependencies": {
4633+ "ms": "^2.1.3"
4634+ },
4635+ "engines": {
4636+ "node": ">=6.0"
4637+ },
4638+ "peerDependenciesMeta": {
4639+ "supports-color": {
4640+ "optional": true
4641+ }
4642+ }
4643+ },
4644+ "node_modules/pac-proxy-agent/node_modules/ms": {
4645+ "version": "2.1.3",
4646+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
4647+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
4648+ "license": "MIT"
4649+ },
4650+ "node_modules/pac-resolver": {
4651+ "version": "7.0.1",
4652+ "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz",
4653+ "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==",
4654+ "license": "MIT",
4655+ "dependencies": {
4656+ "degenerator": "^5.0.0",
4657+ "netmask": "^2.0.2"
4658+ },
4659+ "engines": {
4660+ "node": ">= 14"
4661+ }
4662+ },
43264663 "node_modules/pako": {
43274664 "version": "1.0.11",
43284665 "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
@@ -4618,6 +4955,57 @@
46184955 "node": ">= 0.10"
46194956 }
46204957 },
4958+ "node_modules/proxy-agent": {
4959+ "version": "6.4.0",
4960+ "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.4.0.tgz",
4961+ "integrity": "sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==",
4962+ "license": "MIT",
4963+ "dependencies": {
4964+ "agent-base": "^7.0.2",
4965+ "debug": "^4.3.4",
4966+ "http-proxy-agent": "^7.0.1",
4967+ "https-proxy-agent": "^7.0.3",
4968+ "lru-cache": "^7.14.1",
4969+ "pac-proxy-agent": "^7.0.1",
4970+ "proxy-from-env": "^1.1.0",
4971+ "socks-proxy-agent": "^8.0.2"
4972+ },
4973+ "engines": {
4974+ "node": ">= 14"
4975+ }
4976+ },
4977+ "node_modules/proxy-agent/node_modules/debug": {
4978+ "version": "4.3.7",
4979+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
4980+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
4981+ "license": "MIT",
4982+ "dependencies": {
4983+ "ms": "^2.1.3"
4984+ },
4985+ "engines": {
4986+ "node": ">=6.0"
4987+ },
4988+ "peerDependenciesMeta": {
4989+ "supports-color": {
4990+ "optional": true
4991+ }
4992+ }
4993+ },
4994+ "node_modules/proxy-agent/node_modules/lru-cache": {
4995+ "version": "7.18.3",
4996+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
4997+ "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
4998+ "license": "ISC",
4999+ "engines": {
5000+ "node": ">=12"
5001+ }
5002+ },
5003+ "node_modules/proxy-agent/node_modules/ms": {
5004+ "version": "2.1.3",
5005+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
5006+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
5007+ "license": "MIT"
5008+ },
46215009 "node_modules/proxy-from-env": {
46225010 "version": "1.1.0",
46235011 "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
@@ -5135,6 +5523,83 @@
51355523 "integrity": "sha512-VZBmZP8WU3sMOZm1bdgTadsQbcscK0UM8oKxKVBs4XAhUo2Xxzm/OFMGBkPusxw9xL3Uy8LrzEqGqJhclsr0yA==",
51365524 "license": "MIT"
51375525 },
5526+ "node_modules/smart-buffer": {
5527+ "version": "4.2.0",
5528+ "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
5529+ "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
5530+ "license": "MIT",
5531+ "engines": {
5532+ "node": ">= 6.0.0",
5533+ "npm": ">= 3.0.0"
5534+ }
5535+ },
5536+ "node_modules/socks": {
5537+ "version": "2.8.3",
5538+ "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz",
5539+ "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==",
5540+ "license": "MIT",
5541+ "dependencies": {
5542+ "ip-address": "^9.0.5",
5543+ "smart-buffer": "^4.2.0"
5544+ },
5545+ "engines": {
5546+ "node": ">= 10.0.0",
5547+ "npm": ">= 3.0.0"
5548+ }
5549+ },
5550+ "node_modules/socks-proxy-agent": {
5551+ "version": "8.0.4",
5552+ "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.4.tgz",
5553+ "integrity": "sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==",
5554+ "license": "MIT",
5555+ "dependencies": {
5556+ "agent-base": "^7.1.1",
5557+ "debug": "^4.3.4",
5558+ "socks": "^2.8.3"
5559+ },
5560+ "engines": {
5561+ "node": ">= 14"
5562+ }
5563+ },
5564+ "node_modules/socks-proxy-agent/node_modules/debug": {
5565+ "version": "4.3.7",
5566+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
5567+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
5568+ "license": "MIT",
5569+ "dependencies": {
5570+ "ms": "^2.1.3"
5571+ },
5572+ "engines": {
5573+ "node": ">=6.0"
5574+ },
5575+ "peerDependenciesMeta": {
5576+ "supports-color": {
5577+ "optional": true
5578+ }
5579+ }
5580+ },
5581+ "node_modules/socks-proxy-agent/node_modules/ms": {
5582+ "version": "2.1.3",
5583+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
5584+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
5585+ "license": "MIT"
5586+ },
5587+ "node_modules/source-map": {
5588+ "version": "0.6.1",
5589+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
5590+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
5591+ "license": "BSD-3-Clause",
5592+ "optional": true,
5593+ "engines": {
5594+ "node": ">=0.10.0"
5595+ }
5596+ },
5597+ "node_modules/sprintf-js": {
5598+ "version": "1.1.3",
5599+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz",
5600+ "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==",
5601+ "license": "BSD-3-Clause"
5602+ },
51385603 "node_modules/statuses": {
51395604 "version": "2.0.1",
51405605 "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
@@ -5348,6 +5813,12 @@
53485813 "utf8-byte-length": "^1.0.1"
53495814 }
53505815 },
5816+ "node_modules/tslib": {
5817+ "version": "2.7.0",
5818+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
5819+ "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==",
5820+ "license": "0BSD"
5821+ },
53515822 "node_modules/tsscmp": {
53525823 "version": "1.0.6",
53535824 "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz",
@@ -5407,6 +5878,15 @@
54075878 "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
54085879 "license": "MIT"
54095880 },
5881+ "node_modules/universalify": {
5882+ "version": "2.0.1",
5883+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
5884+ "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
5885+ "license": "MIT",
5886+ "engines": {
5887+ "node": ">= 10.0.0"
5888+ }
5889+ },
54105890 "node_modules/unpipe": {
54115891 "version": "1.0.0",
54125892 "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
package.json+1 -0
@@ -30,6 +30,7 @@
3030 "png-chunk-text": "^1.0.0",
3131 "png-chunks-encode": "^1.0.0",
3232 "png-chunks-extract": "^1.0.0",
33+ "proxy-agent": "^6.4.0",
3334 "rate-limiter-flexible": "^5.0.0",
3435 "response-time": "^2.3.2",
3536 "sanitize-filename": "^1.6.3",
public/scripts/slash-commands.js+10 -17
@@ -440,7 +440,7 @@ export function initDefaultSlashCommands() {
440440 ],
441441 unnamedArgumentList: [
442442 new SlashCommandArgument(
443443 'prompt', [ARGUMENT_TYPE.STRING], truefalse, false,
444444 ),
445445 ],
446446 helpString: 'Asks a specified character card a prompt. Character name must be provided in a named argument.',
@@ -2469,31 +2469,21 @@ async function askCharacter(args, text) {
24692469 // Not supported in group chats
24702470 // TODO: Maybe support group chats?
24712471 if (selected_group) {
24722472 toastr.error('Cannot run this/ask command in a group chat!');
2473- return '';
2474- }
2475-
2476- if (!text) {
2477- console.warn('WARN: No text provided for /ask command');
2478- toastr.warning('No text provided for /ask command');
24792473 return '';
24802474 }
24812475
24822476 let name = '';
2483- let mesText = '';
24842477
24852478 if (args?.name) {
24862479 name = args.name.trim();
2487- mesText = text.trim();
24882480
24892481 if (!name && !mesText) {
24902482 toastr.warning('You must specify a name andof textthe character to ask.');
24912483 return '';
24922484 }
24932485 }
24942486
2495- mesText = getRegexedString(mesText, regex_placement.SLASH_COMMAND);
2496-
24972487 const prevChId = this_chid;
24982488
24992489 // Find the character
@@ -2503,9 +2493,12 @@ async function askCharacter(args, text) {
25032493 return '';
25042494 }
25052495
2506- // Sending a message implicitly saves the chat, so this needs to be done before changing the character
2496+ if (text) {
2507- // Otherwise, a corruption will occur
2497+ const mesText = getRegexedString(text.trim(), regex_placement.SLASH_COMMAND);
2508- await sendMessageAsUser(mesText, '');
2498+ // Sending a message implicitly saves the chat, so this needs to be done before changing the character
2499+ // Otherwise, a corruption will occur
2500+ await sendMessageAsUser(mesText, '');
2501+ }
25092502
25102503 // Override character and send a user message
25112504 setCharacterId(String(chId));
server.js+24 -0
@@ -37,6 +37,7 @@ util.inspect.defaultOptions.depth = 4;
3737const userModule = require('./src/users');
3838const basicAuthMiddleware = require('./src/middleware/basicAuth');
3939const whitelistMiddleware = require('./src/middleware/whitelist');
40+const initRequestProxy = require('./src/request-proxy');
4041const contentManager = require('./src/endpoints/content-manager');
4142const {
4243 getVersion,
@@ -75,6 +76,10 @@ const DEFAULT_AVOID_LOCALHOST = false;
7576const DEFAULT_AUTORUN_HOSTNAME = 'auto';
7677const DEFAULT_AUTORUN_PORT = -1;
7778
79+const DEFAULT_PROXY_ENABLED = false;
80+const DEFAULT_PROXY_URL = '';
81+const DEFAULT_PROXY_BYPASS = [];
82+
7883const cliArguments = yargs(hideBin(process.argv))
7984 .usage('Usage: <your-start-script> <command> [options]')
8085 .option('enableIPv6', {
@@ -145,6 +150,18 @@ const cliArguments = yargs(hideBin(process.argv))
145150 type: 'boolean',
146151 default: null,
147152 describe: 'Enables basic authentication',
153+ }).option('requestProxyEnabled', {
154+ type: 'boolean',
155+ default: null,
156+ describe: 'Enables a use of proxy for outgoing requests',
157+ }).option('requestProxyUrl', {
158+ type: 'string',
159+ default: null,
160+ describe: 'Request proxy URL (HTTP or SOCKS protocols)',
161+ }).option('requestProxyBypass', {
162+ type: 'array',
163+ default: null,
164+ describe: 'Request proxy bypass list (space separated list of hosts)',
148165 }).parseSync();
149166
150167// change all relative paths
@@ -181,6 +198,10 @@ const dnsPreferIPv6 = cliArguments.dnsPreferIPv6 ?? getConfigValue('dnsPreferIPv
181198
182199const avoidLocalhost = cliArguments.avoidLocalhost ?? getConfigValue('avoidLocalhost', DEFAULT_AVOID_LOCALHOST);
183200
201+const proxyEnabled = cliArguments.requestProxyEnabled ?? getConfigValue('requestProxy.enabled', DEFAULT_PROXY_ENABLED);
202+const proxyUrl = cliArguments.requestProxyUrl ?? getConfigValue('requestProxy.url', DEFAULT_PROXY_URL);
203+const proxyBypass = cliArguments.requestProxyBypass ?? getConfigValue('requestProxy.bypass', DEFAULT_PROXY_BYPASS);
204+
184205if (dnsPreferIPv6) {
185206 // Set default DNS resolution order to IPv6 first
186207 dns.setDefaultResultOrder('ipv6first');
@@ -662,6 +683,9 @@ const preSetupTasks = async function () {
662683 console.error('Uncaught exception:', err);
663684 exitProcess();
664685 });
686+
687+ // Add request proxy.
688+ initRequestProxy({ enabled: proxyEnabled, url: proxyUrl, bypass: proxyBypass });
665689};
666690
667691/**
src/request-proxy.js+56 -0
@@ -0,0 +1,56 @@
1+const http = require('node:http');
2+const https = require('node:https');
3+
4+const { isValidUrl, color } = require('./util.js');
5+
6+const LOG_HEADER = '[Request Proxy]';
7+
8+/**
9+ * Initialize request proxy.
10+ * @param {ProxySettings} settings Proxy settings.
11+ * @typedef {object} ProxySettings
12+ * @property {boolean} enabled Whether proxy is enabled.
13+ * @property {string} url Proxy URL.
14+ * @property {string[]} bypass List of URLs to bypass proxy.
15+ */
16+function initRequestProxy({ enabled, url, bypass }) {
17+ try {
18+ const { ProxyAgent } = require('proxy-agent');
19+
20+ // No proxy is enabled, so return
21+ if (!enabled) {
22+ return;
23+ }
24+
25+ if (!url) {
26+ console.error(color.red(LOG_HEADER), 'No proxy URL provided');
27+ return;
28+ }
29+
30+ if (!isValidUrl(url)) {
31+ console.error(color.red(LOG_HEADER), 'Invalid proxy URL provided');
32+ return;
33+ }
34+
35+ // ProxyAgent uses proxy-from-env under the hood
36+ // Reference: https://github.com/Rob--W/proxy-from-env
37+ process.env.all_proxy = url;
38+
39+
40+ if (Array.isArray(bypass) && bypass.length > 0) {
41+ process.env.no_proxy = bypass.join(',');
42+ }
43+
44+ const proxyAgent = new ProxyAgent();
45+ http.globalAgent = proxyAgent;
46+ https.globalAgent = proxyAgent;
47+
48+ console.log();
49+ console.log(color.green(LOG_HEADER), 'Proxy URL is used:', color.blue(url));
50+ console.log();
51+ } catch (error) {
52+ console.error(color.red(LOG_HEADER), 'Failed to initialize request proxy:', error);
53+ }
54+}
55+
56+module.exports = initRequestProxy;