From bc8ba91429b8acbb3813fe68e09bb80ae085751d Mon Sep 17 00:00:00 2001 From: somebody Date: Fri, 21 Jul 2023 21:44:10 -0500 Subject: [PATCH] Private Mode improvements - cleaned up ui a bit - disallow setting empty password (user could press the hotkey by mistake and be confused), giving the user a notification if they try to. - gives the login attempter a message if the password is incorrect, as well as screaming in the logs - obscures story name in page title --- aiserver.py | 11 ++++++-- static/koboldai.css | 25 +++++++++++++++++ static/koboldai.js | 64 ++++++++++++++++++++++++++++++++++--------- templates/popups.html | 4 +-- 4 files changed, 87 insertions(+), 17 deletions(-) diff --git a/aiserver.py b/aiserver.py index dc565c97..8f04cd07 100644 --- a/aiserver.py +++ b/aiserver.py @@ -7784,9 +7784,16 @@ def UI_2_update_tokens(data): def UI_2_privacy_mode(data): if data['enabled']: koboldai_vars.privacy_mode = True + return + + if data['password'] == koboldai_vars.privacy_password: + koboldai_vars.privacy_mode = False else: - if data['password'] == koboldai_vars.privacy_password: - koboldai_vars.privacy_mode = False + logger.warning("Watch out! Someone tried to unlock your instance with an incorrect password! Stay on your toes...") + show_error_notification( + title="Invalid password", + text="The password you provided was incorrect. Please try again." + ) #==================================================================# # Genres diff --git a/static/koboldai.css b/static/koboldai.css index c35b0c80..145f217e 100644 --- a/static/koboldai.css +++ b/static/koboldai.css @@ -1457,6 +1457,30 @@ td.server_vars { line-height: 2; } +/* Privacy Mode (Lock Screen) */ +#privacy_mode { + height: unset; + width: unset; + position: relative; + top: unset; + left: unset; +} + +#privacy_mode .popup_list_area { + display: flex; + align-items: center; + flex-direction: column; + padding-top: 10px; + padding-bottom: 10px; + padding-left: 15px; + padding-right: 15px; +} + +#privacy_mode input { + margin-top: 15px; + width: 85%; +} + /* ---------------------------- OVERALL PAGE CONFIG ------------------------------*/ body { background-color: var(--background); @@ -1962,6 +1986,7 @@ body { color: var(--popup_title_bar_color_text); text-align: center; font-size: calc(1.3em + var(--font_size_adjustment)); + user-select: none; } .popup .action_button { diff --git a/static/koboldai.js b/static/koboldai.js index 0fde7169..7e647813 100644 --- a/static/koboldai.js +++ b/static/koboldai.js @@ -83,6 +83,7 @@ let story_id = -1; var dirty_chunks = []; var initial_socketio_connection_occured = false; var selected_model_data; +var privacy_mode_enabled = false; // Each entry into this array should be an object that looks like: // {class: "class", key: "key", func: callback} @@ -161,7 +162,7 @@ const shortcuts = [ {mod: "ctrl", key: "m", desc: "Focuses Memory", func: () => focusEl("#memory")}, {mod: "ctrl", key: "u", desc: "Focuses Author's Note", func: () => focusEl("#authors_notes")}, // CTRL-N is reserved :^( {mod: "ctrl", key: "g", desc: "Focuses game text", func: () => focusEl("#input_text")}, - {mod: "ctrl", key: "l", desc: '"Lock" screen (Not secure)', func: () => socket.emit("privacy_mode", {'enabled': true})}, + {mod: "ctrl", key: "l", desc: '"Lock" screen (Not secure)', func: maybe_enable_privacy_mode}, {mod: "ctrl", key: "k", desc: "Finder", func: open_finder}, {mod: "ctrl", key: "/", desc: "Help screen", func: () => openPopup("shortcuts-popup")}, ] @@ -3402,16 +3403,36 @@ function update_story_picture(chunk_id) { image.setAttribute("chunk", chunk_id); } +function maybe_enable_privacy_mode() { + const password = document.getElementById("user_privacy_password").value; + + if (!password) { + showNotification( + "Lock Failed", + "Please set a password before locking KoboldAI.", + "error" + ) + return; + } + + socket.emit("privacy_mode", {'enabled': true}) +} + function privacy_mode(enabled) { + privacy_mode_enabled = enabled; + updateTitle(); + + const sideMenu = document.getElementById("SideMenu"); + const mainGrid = document.getElementById("main-grid"); + const rightSideMenu = document.getElementById("rightSideMenu"); + + for (const menu of [sideMenu, mainGrid, rightSideMenu]) { + menu.classList.toggle("superblur", enabled); + } + if (enabled) { - document.getElementById('SideMenu').classList.add("superblur"); - document.getElementById('main-grid').classList.add("superblur"); - document.getElementById('rightSideMenu').classList.add("superblur"); openPopup("privacy_mode"); } else { - document.getElementById('SideMenu').classList.remove("superblur"); - document.getElementById('main-grid').classList.remove("superblur"); - document.getElementById('rightSideMenu').classList.remove("superblur"); if (!$el("#privacy_mode").classList.contains("hidden")) closePopups(); document.getElementById('privacy_password').value = ""; } @@ -4708,7 +4729,7 @@ function close_menus() { document.getElementById("main-grid").classList.remove("story_menu-open"); //close popup menus - closePopups(); + closePopups(true); //unselect sampler items for (temp of document.getElementsByClassName("sample_order")) { @@ -5809,8 +5830,15 @@ function position_context_menu(contextMenu, x, y) { function updateTitle() { const titleInput = $el(".var_sync_story_story_name"); - if (!titleInput.innerText) return; - document.title = `${titleInput.innerText} - KoboldAI Client`; + let titleText = "Story"; + + if (!privacy_mode_enabled && titleInput.innerText) { + titleText = titleInput.innerText; + } else { + titleText = "[🔒]" + } + + document.title = `${titleText} - KoboldAI Client`; } function openClubImport() { @@ -5845,17 +5873,27 @@ function openPopup(id) { } } -function closePopups() { +function closePopups(userAction=false) { + // userAction specifies if a user tried to close the popup by normal means + // (ESC, clicking outside the menu, etc). const container = $el("#popup-container"); - container.classList.add("hidden"); + let allHidden = true; for (const popupWindow of container.children) { + // Do not let the user close windows they shouldn't be! Sneaky devils! + if (userAction && popupWindow.getAttribute("allow-close") === "false") { + allHidden = false; + continue; + } + popupWindow.classList.add("hidden"); } + + if (allHidden) container.classList.add("hidden"); } $el("#popup-container").addEventListener("click", function(event) { - if (event.target === this) closePopups(); + if (event.target === this) closePopups(true); }); /* -- Colab Cookie Handling -- */ diff --git a/templates/popups.html b/templates/popups.html index 9c6b4a9e..32966267 100644 --- a/templates/popups.html +++ b/templates/popups.html @@ -70,12 +70,12 @@ -