From f4d3f40ce5e3b6942260f91667dc2dc813d064b1 Mon Sep 17 00:00:00 2001 From: shirosaki-hana Date: Thu, 20 Mar 2025 15:40:11 +0900 Subject: [PATCH 1/7] Add HTTPS support for RisuAI Node.js hosting version The Node.js hosting version of RisuAI previously used simple app.listen for server execution, which didn't support native HTTPS. This caused several functionality issues due to browser security restrictions when accessing RisuAI externally, such as realm loading failures and inability to insert prompt presets. The updated code now checks for certificate files named server.key and server.crt in the /server/node/ssl/certificate directory. If found, the server will start using HTTPS. The /ssl directory includes a script to generate a self-signed SSL certificate using OpenSSL. To use it, add the server's public IP to the [ alt_names ] section in server.conf before generating the certificate. The CA certificate should be installed on the operating system or browser of devices remotely accessing RisuAI. For production use with a domain, it's recommended to use a certificate from an official Certificate Authority. --- .gitignore | 3 +- server/node/server.cjs | 59 ++++++++++++++++++++++-- server/node/ssl/Generate Certificate.bat | 5 ++ server/node/ssl/Generate Certificate.sh | 8 ++++ server/node/ssl/ca.conf | 19 ++++++++ server/node/ssl/server.conf | 23 +++++++++ 6 files changed, 113 insertions(+), 4 deletions(-) create mode 100644 server/node/ssl/Generate Certificate.bat create mode 100644 server/node/ssl/Generate Certificate.sh create mode 100644 server/node/ssl/ca.conf create mode 100644 server/node/ssl/server.conf diff --git a/.gitignore b/.gitignore index e10fde5c..e2bc7106 100644 --- a/.gitignore +++ b/.gitignore @@ -42,4 +42,5 @@ __pycache__/ .tauri/ dist.zip /scripts/ -.env \ No newline at end of file +.env +/server/node/ssl/certificate \ No newline at end of file diff --git a/server/node/server.cjs b/server/node/server.cjs index abf88d98..3a46102f 100644 --- a/server/node/server.cjs +++ b/server/node/server.cjs @@ -9,6 +9,8 @@ app.use(express.static(path.join(process.cwd(), 'dist'), {index: false})); app.use(express.json({ limit: '50mb' })); app.use(express.raw({ type: 'application/octet-stream', limit: '50mb' })); const {pipeline} = require('stream/promises') +const https = require('https'); +const sslPath = path.join(process.cwd(), 'server/node/ssl/certificate'); let password = '' @@ -294,6 +296,57 @@ app.post('/api/write', async (req, res, next) => { } }); -app.listen(6001, () => { - console.log("Server is listening on http://localhost:6001/"); -}); \ No newline at end of file +async function getHttpsOptions() { + + const keyPath = path.join(sslPath, 'server.key'); + const certPath = path.join(sslPath, 'server.crt'); + + console.log(keyPath) + console.log(certPath) + + try { + + await fs.access(keyPath); + await fs.access(certPath); + + const [key, cert] = await Promise.all([ + fs.readFile(keyPath), + fs.readFile(certPath) + ]); + + return { key, cert }; + + } catch (error) { + console.error('SSL setup errors:', error.message); + console.log('Start the server with HTTP instead of HTTPS...'); + return null; + } +} + +async function startServer() { + const port = process.env.PORT || 6001; + const httpsOptions = await getHttpsOptions(); + + if (httpsOptions) { + // HTTPS + https.createServer(httpsOptions, app).listen(port, () => { + console.log("HTTPS server is running."); + console.log("https://localhost:6001/"); + }); + + } else { + // HTTP + app.listen(port, () => { + console.log("HTTP server is running."); + console.log("http://localhost:6001/"); + }); + } +} + +(async () => { + try { + await startServer(); + } catch (error) { + console.error('Fail to start server :', error); + } +})(); \ No newline at end of file diff --git a/server/node/ssl/Generate Certificate.bat b/server/node/ssl/Generate Certificate.bat new file mode 100644 index 00000000..b5a5b41b --- /dev/null +++ b/server/node/ssl/Generate Certificate.bat @@ -0,0 +1,5 @@ +@echo off +mkdir certificate 2>nul +openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout certificate\ca.key -out certificate\ca.crt -config ca.conf +openssl req -new -nodes -newkey rsa:2048 -keyout certificate\server.key -out certificate\server.csr -config server.conf +openssl x509 -req -in certificate\server.csr -CA certificate\ca.crt -CAkey certificate\ca.key -CAcreateserial -out certificate\server.crt -days 3650 -extensions req_ext -extfile server.conf \ No newline at end of file diff --git a/server/node/ssl/Generate Certificate.sh b/server/node/ssl/Generate Certificate.sh new file mode 100644 index 00000000..85850c6d --- /dev/null +++ b/server/node/ssl/Generate Certificate.sh @@ -0,0 +1,8 @@ +#!/bin/bash +mkdir -p certificate +openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout certificate/ca.key -out certificate/ca.crt -config ca.conf +openssl req -new -nodes -newkey rsa:2048 -keyout certificate/server.key -out certificate/server.csr -config server.conf +openssl x509 -req -in certificate/server.csr -CA certificate/ca.crt -CAkey certificate/ca.key -CAcreateserial -out certificate/server.crt -days 3650 -extensions req_ext -extfile server.conf + +chmod 600 certificate/ca.key certificate/server.key +chmod 644 certificate/ca.crt certificate/server.crt certificate/server.csr \ No newline at end of file diff --git a/server/node/ssl/ca.conf b/server/node/ssl/ca.conf new file mode 100644 index 00000000..abd1df36 --- /dev/null +++ b/server/node/ssl/ca.conf @@ -0,0 +1,19 @@ +[ req ] +default_bits = 2048 +prompt = no +default_md = sha256 +distinguished_name = dn +x509_extensions = ca_ext + +[ dn ] +C = KR +ST = Kivotos +L = Millennium Science School +O = Game Development Department +OU = Certificate Authority +CN = Aris CA + +[ ca_ext ] +basicConstraints = critical,CA:TRUE +keyUsage = critical,keyCertSign,cRLSign +subjectKeyIdentifier = hash diff --git a/server/node/ssl/server.conf b/server/node/ssl/server.conf new file mode 100644 index 00000000..c7090687 --- /dev/null +++ b/server/node/ssl/server.conf @@ -0,0 +1,23 @@ +[ req ] +default_bits = 2048 +prompt = no +default_md = sha256 +distinguished_name = dn +req_extensions = req_ext + +[ dn ] +C = KR +ST = Kivotos +L = Millennium Science School +O = Game Development Department +OU = Tendou Aris +CN = localhost + +[ req_ext ] +subjectAltName = @alt_names +basicConstraints = CA:FALSE +keyUsage = digitalSignature, keyEncipherment + +[ alt_names ] +DNS.1 = localhost +IP.1 = 127.0.0.1 From 1a2e44f9ae1b516cffff06cccaba62b9b4435c66 Mon Sep 17 00:00:00 2001 From: shirosaki-hana Date: Thu, 20 Mar 2025 16:38:53 +0900 Subject: [PATCH 2/7] Update Generate Certificate.sh --- server/node/ssl/Generate Certificate.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/node/ssl/Generate Certificate.sh b/server/node/ssl/Generate Certificate.sh index 85850c6d..2cba2b56 100644 --- a/server/node/ssl/Generate Certificate.sh +++ b/server/node/ssl/Generate Certificate.sh @@ -4,5 +4,5 @@ openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout certificate/ca.key openssl req -new -nodes -newkey rsa:2048 -keyout certificate/server.key -out certificate/server.csr -config server.conf openssl x509 -req -in certificate/server.csr -CA certificate/ca.crt -CAkey certificate/ca.key -CAcreateserial -out certificate/server.crt -days 3650 -extensions req_ext -extfile server.conf -chmod 600 certificate/ca.key certificate/server.key -chmod 644 certificate/ca.crt certificate/server.crt certificate/server.csr \ No newline at end of file +chmod 644 certificate/ca.key certificate/server.key +chmod 644 certificate/ca.crt certificate/server.crt certificate/server.csr From 88fd4ffaebb34046d3c920598c974349be105771 Mon Sep 17 00:00:00 2001 From: bangonicdd <157843588+bangonicdd2@users.noreply.github.com> Date: Tue, 1 Apr 2025 13:10:04 +0900 Subject: [PATCH 3/7] fix: 'previous_chat_log' cbs --- src/ts/parser.svelte.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ts/parser.svelte.ts b/src/ts/parser.svelte.ts index 006133cd..d831d517 100644 --- a/src/ts/parser.svelte.ts +++ b/src/ts/parser.svelte.ts @@ -1379,7 +1379,7 @@ function basicMatcher (p1:string,matcherArg:matcherArg,vars:{[key:string]:string case 'previous_chat_log':{ const selchar = db.characters[get(selectedCharID)] const chat = selchar?.chats?.[selchar.chatPage] - return chat?.message[chatID - 1]?.data ?? 'Out of range' + return chat?.message[Number(arra[1])]?.data ?? 'Out of range' } case 'tonumber':{ From 72e47afb49f648ade9aab924e78379a06242c369 Mon Sep 17 00:00:00 2001 From: bangonicdd <157843588+bangonicdd2@users.noreply.github.com> Date: Wed, 2 Apr 2025 02:45:51 +0900 Subject: [PATCH 4/7] fix: add null check on module integration for legacy preset --- src/lib/Setting/Pages/Module/ModuleSettings.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/Setting/Pages/Module/ModuleSettings.svelte b/src/lib/Setting/Pages/Module/ModuleSettings.svelte index ab48f355..d95426c9 100644 --- a/src/lib/Setting/Pages/Module/ModuleSettings.svelte +++ b/src/lib/Setting/Pages/Module/ModuleSettings.svelte @@ -56,7 +56,7 @@ ` } @@ -2235,6 +2235,10 @@ export function getGlobalChatVar(key:string){ return DBState.db.globalChatVariables[key] ?? 'null' } +export function setGlobalChatVar(key:string, value:bool){ // TODO: check globalChatVariables possible type + DBState.db.globalChatVariables[key] = value +} + export function setChatVar(key:string, value:string){ const selectedChar = get(selectedCharID) if(!DBState.db.characters[selectedChar].chats[DBState.db.characters[selectedChar].chatPage].scriptstate){ diff --git a/src/ts/process/lua.ts b/src/ts/process/lua.ts index e44fa188..bfe71cda 100644 --- a/src/ts/process/lua.ts +++ b/src/ts/process/lua.ts @@ -1,4 +1,4 @@ -import { getChatVar, hasher, setChatVar, type simpleCharacterArgument } from "../parser.svelte"; +import { getChatVar, hasher, setChatVar, getGlobalChatVar, type simpleCharacterArgument } from "../parser.svelte"; import { LuaEngine, LuaFactory } from "wasmoon"; import { getCurrentCharacter, getCurrentChat, getDatabase, setCurrentChat, setDatabase, type Chat, type character, type groupChat } from "../storage/database.svelte"; import { get } from "svelte/store"; @@ -25,7 +25,8 @@ interface LuaEngineState { mutex: Mutex; chat: Chat; setVar: (key:string, value:string) => void, - getVar: (key:string) => string + getVar: (key:string) => string, + getGlobalVar: (key:string) => any, } let LuaEngines = new Map() @@ -35,6 +36,7 @@ export async function runLua(code:string, arg:{ chat?:Chat setVar?: (key:string, value:string) => void, getVar?: (key:string) => string, + getGlobalVar?: (key:string) => any, lowLevelAccess?: boolean, mode?: string, data?: any @@ -42,6 +44,7 @@ export async function runLua(code:string, arg:{ const char = arg.char ?? getCurrentCharacter() const setVar = arg.setVar ?? setChatVar const getVar = arg.getVar ?? getChatVar + const getGlobalVar = arg.getGlobalVar ?? getGlobalChatVar const mode = arg.mode ?? 'manual' const data = arg.data ?? {} let chat = arg.chat ?? getCurrentChat() @@ -60,7 +63,8 @@ export async function runLua(code:string, arg:{ mutex: new Mutex(), chat, setVar, - getVar + getVar, + getGlobalVar } LuaEngines.set(mode, luaEngineState) wasEmpty = true @@ -68,6 +72,7 @@ export async function runLua(code:string, arg:{ luaEngineState.chat = chat luaEngineState.setVar = setVar luaEngineState.getVar = getVar + luaEngineState.getGlobalVar = getGlobalVar } return await luaEngineState.mutex.runExclusive(async () => { if (wasEmpty || code !== luaEngineState.code) { @@ -87,6 +92,12 @@ export async function runLua(code:string, arg:{ } return luaEngineState.getVar(key) }) + luaEngine.global.set('getGlobalVar', (id:string, key:string) => { + if(!LuaSafeIds.has(id) && !LuaEditDisplayIds.has(id)){ + return + } + return luaEngineState.getGlobalVar(key) + }) luaEngine.global.set('stopChat', (id:string) => { if(!LuaSafeIds.has(id)){ return From c21dd9e7559dd582f0b765b55cf9c473a2096f6a Mon Sep 17 00:00:00 2001 From: Inha Hwang <73149145+HyperBlaze456@users.noreply.github.com> Date: Tue, 8 Apr 2025 06:02:07 +0900 Subject: [PATCH 7/7] fix: wrong type --- src/ts/parser.svelte.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ts/parser.svelte.ts b/src/ts/parser.svelte.ts index 0c5b5c4e..50aa74bd 100644 --- a/src/ts/parser.svelte.ts +++ b/src/ts/parser.svelte.ts @@ -2235,8 +2235,8 @@ export function getGlobalChatVar(key:string){ return DBState.db.globalChatVariables[key] ?? 'null' } -export function setGlobalChatVar(key:string, value:bool){ // TODO: check globalChatVariables possible type - DBState.db.globalChatVariables[key] = value +export function setGlobalChatVar(key:string, value:string){ + DBState.db.globalChatVariables[key] = value // String to String Map(dictionary) } export function setChatVar(key:string, value:string){