diff --git a/css/main.css b/css/main.css index 3a4e29f..1d1c84c 100644 --- a/css/main.css +++ b/css/main.css @@ -361,7 +361,7 @@ body.dark-mode td { border-color: #444; } body.dark-mode th { - background: #121212; + background: #2a2a2a; } body.dark-mode code, diff --git a/lua/luarails.py b/lua/luarails.py index e7e6e3f..7abac98 100644 --- a/lua/luarails.py +++ b/lua/luarails.py @@ -1,106 +1,14 @@ -guardrails_code = """ --- Guardrails and safe patterns for plugin development +import os --- Safe string operations -function safe_concat(...) - local result = {} - for i, v in ipairs({...}) do - if v ~= nil then - table.insert(result, tostring(v)) - end - end - return table.concat(result) -end +def get_file_contents(filename : str) -> str | None: + """ Gets the Contents of a File and returns it in str format """ + script_dir = os.path.dirname(os.path.abspath(__file__)) + path = os.path.join(script_dir, filename) --- Safe table operations -function table_contains(tbl, value) - for _, v in ipairs(tbl) do - if v == value then return true end - end - return false -end + if not os.path.isfile(path): + print(f"File '{filename}' not found in {script_dir}") + return None -function table_keys(tbl) - local keys = {} - for k, _ in pairs(tbl) do - table.insert(keys, k) - end - return keys -end + with open(path, 'r', encoding='utf-8') as file: + return file.read() -function table_values(tbl) - local values = {} - for _, v in pairs(tbl) do - table.insert(values, v) - end - return values -end - --- Safe string escaping -function escape_html(str) - if str == nil then return "" end - local s = tostring(str) - s = string.gsub(s, "&", "&") - s = string.gsub(s, "<", "<") - s = string.gsub(s, ">", ">") - s = string.gsub(s, '"', """) - s = string.gsub(s, "'", "'") - return s -end - --- Pattern validation -function is_valid_filename(name) - if name == nil or name == "" then return false end - -- Block directory traversal - if string.match(name, "%.%.") then return false end - if string.match(name, "/") or string.match(name, "\\\\") then return false end - return true -end - --- Safe error handling wrapper -function try_catch(fn, catch_fn) - local status, err = pcall(fn) - if not status and catch_fn then - catch_fn(err) - end - return status -end - --- Request validation -function validate_request(req, required_fields) - if type(req) ~= "table" then return false, "Request must be a table" end - for _, field in ipairs(required_fields) do - if req[field] == nil then - return false, "Missing required field: " .. field - end - end - return true, nil -end - --- Rate limiting helper (simple in-memory) -_rate_limits = _rate_limits or {} -function check_rate_limit(key, max_calls, window_seconds) - local now = os.time() - if _rate_limits[key] == nil then - _rate_limits[key] = {count = 1, window_start = now} - return true - end - - local rl = _rate_limits[key] - if now - rl.window_start > window_seconds then - -- Reset window - rl.count = 1 - rl.window_start = now - return true - end - - if rl.count >= max_calls then - return false - end - - rl.count = rl.count + 1 - return true -end - -log("Lua guardrails initialized") -""" \ No newline at end of file diff --git a/lua/plugin_manager.py b/lua/plugin_manager.py index 7e32357..c44e3b6 100644 --- a/lua/plugin_manager.py +++ b/lua/plugin_manager.py @@ -8,7 +8,7 @@ from watchdog.events import FileSystemEventHandler from log.Logger import Logger from .PluginFSHandler import PluginFSHandler import json -from .luarails import guardrails_code +from .luarails import get_file_contents PLUGINS_DIR = Path(__file__).parent / "plugins" HTML_DIR = Path(__file__).parent / "../html" @@ -112,7 +112,7 @@ class PluginManager: def _setup_lua_guardrails(self): try: - self.lua.execute(guardrails_code) + self.lua.execute(get_file_contents("luarails.lua")) except LuaError as e: Logger.log_lua_error(f"Failed to initialize Lua guardrails: {e}") diff --git a/webserver.py b/webserver.py index 5a2381b..43fd960 100644 --- a/webserver.py +++ b/webserver.py @@ -31,7 +31,7 @@ def get_html_files(directory=HTML_DIR): return html_files -def build_index_page(): +def build_index_page() -> str: with open(BASE_FILE, "r", encoding="utf-8") as f: base_html = f.read() @@ -80,7 +80,7 @@ H2_CANDIDATES = [h for h in hash_list if h != H1] H2 = random.choice(H2_CANDIDATES) if H2_CANDIDATES else H1 # cahcing was a bad, idea, servertime got stuck. it is now a variable ;) -def index_footer(): +def index_footer() -> str: tor_link = "http://7uhuxits7qfmiagkmpazxvh3rtk6aijs6pbawge3fl77y4xqjixlhkqd.onion/" return f"""