diff --git a/.gitignore b/.gitignore index b7f2d2b3..7f3ad858 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,7 @@ venv.bak/ .idea/ /imports/ /servers/ +/app/frontend/static/assets/images/auth/custom/ /backups/ /temp/ /docker/servers/ diff --git a/app/classes/controllers/management_controller.py b/app/classes/controllers/management_controller.py index 547a8ebd..47860fe1 100644 --- a/app/classes/controllers/management_controller.py +++ b/app/classes/controllers/management_controller.py @@ -94,6 +94,14 @@ class ManagementController: def delete_scheduled_task(schedule_id): return HelpersManagement.delete_scheduled_task(schedule_id) + @staticmethod + def set_login_image(path): + HelpersManagement.set_login_image(path) + + @staticmethod + def get_login_image(): + return HelpersManagement.get_login_image() + @staticmethod def update_scheduled_task(schedule_id, updates): return HelpersManagement.update_scheduled_task(schedule_id, updates) diff --git a/app/classes/models/management.py b/app/classes/models/management.py index c961f002..55c86bb7 100644 --- a/app/classes/models/management.py +++ b/app/classes/models/management.py @@ -43,6 +43,7 @@ class AuditLog(BaseModel): # ********************************************************************************** class CraftySettings(BaseModel): secret_api_key = CharField(default="") + login_photo = CharField(default="login_1.jpg") class Meta: table_name = "crafty_settings" @@ -254,6 +255,19 @@ class HelpersManagement: ) return settings[0].secret_api_key + @staticmethod + def get_login_image(): + settings = CraftySettings.select(CraftySettings.login_photo).where( + CraftySettings.id == 1 + ) + return settings[0].login_photo + + @staticmethod + def set_login_image(photo): + CraftySettings.update({CraftySettings.login_photo: photo}).where( + CraftySettings.id == 1 + ).execute() + # ********************************************************************************** # Schedules Methods # ********************************************************************************** diff --git a/app/classes/shared/main_controller.py b/app/classes/shared/main_controller.py index eb8c3219..b6af8ed0 100644 --- a/app/classes/shared/main_controller.py +++ b/app/classes/shared/main_controller.py @@ -73,6 +73,7 @@ class Controller: timezone=str(tz) ) self.first_login = False + self.cached_login = self.management.get_login_image() self.support_scheduler.start() @staticmethod diff --git a/app/classes/web/ajax_handler.py b/app/classes/web/ajax_handler.py index a90b4141..f4ed1dac 100644 --- a/app/classes/web/ajax_handler.py +++ b/app/classes/web/ajax_handler.py @@ -352,6 +352,38 @@ class AjaxHandler(BaseHandler): self.controller.clear_unexecuted_commands() return + elif page == "select_photo": + if exec_user["superuser"]: + photo = self.get_argument("photo", None) + if photo == "login_1.jpg": + self.controller.management.set_login_image("login_1.jpg") + self.controller.cached_login = f"{photo}" + else: + self.controller.management.set_login_image(f"custom/{photo}") + self.controller.cached_login = f"custom/{photo}" + return + + elif page == "delete_photo": + if exec_user["superuser"]: + photo = self.get_argument("photo", None) + if photo and photo != "login_1.jpg": + os.remove( + os.path.join( + self.controller.project_root, + f"app/frontend/static/assets/images/auth/custom/{photo}", + ) + ) + current = self.controller.cached_login + split = current.split("/") + if split == 1: + current_photo = current + else: + current_photo = split[1] + if current_photo == photo: + self.controller.management.set_login_image("login_1.jpg") + self.controller.cached_login = "login_1.jpg" + return + elif page == "kill": if not permissions["Commands"] in user_perms: if not superuser: diff --git a/app/classes/web/panel_handler.py b/app/classes/web/panel_handler.py index 9111d358..85e3d083 100644 --- a/app/classes/web/panel_handler.py +++ b/app/classes/web/panel_handler.py @@ -849,6 +849,25 @@ class PanelHandler(BaseHandler): page_data["roles"] = self.controller.roles.get_all_roles() page_data["auth-servers"][user.user_id] = super_auth_servers page_data["managed_users"] = [] + page_data["backgrounds"] = [] + cached_split = self.controller.cached_login.split("/") + + if len(cached_split) == 1: + page_data["backgrounds"].append( + self.controller.cached_login + ) + else: + page_data["backgrounds"].append(cached_split[1]) + if "login_1.jpg" not in page_data["backgrounds"]: + page_data["backgrounds"].append("login_1.jpg") + for item in os.listdir( + os.path.join( + self.controller.project_root, + "app/frontend/static/assets/images/auth/custom", + ) + ): + if item not in page_data["backgrounds"]: + page_data["backgrounds"].append(item) else: page_data["managed_users"] = self.controller.users.get_managed_users( exec_user["user_id"] diff --git a/app/classes/web/public_handler.py b/app/classes/web/public_handler.py index cf50d535..bb31248f 100644 --- a/app/classes/web/public_handler.py +++ b/app/classes/web/public_handler.py @@ -48,6 +48,7 @@ class PublicHandler(BaseHandler): template = "public/404.html" if page == "login": + page_data["background"] = self.controller.cached_login template = "public/login.html" elif page == 404: diff --git a/app/classes/web/upload_handler.py b/app/classes/web/upload_handler.py index 077128e4..2de4fe1f 100644 --- a/app/classes/web/upload_handler.py +++ b/app/classes/web/upload_handler.py @@ -152,65 +152,46 @@ class UploadHandler(BaseHandler): return self.do_upload = True - if superuser: - exec_user_server_permissions = ( - self.controller.server_perms.list_defined_permissions() + if not superuser: + self.helper.websocket_helper.broadcast_user( + user_id, + "send_start_error", + { + "error": self.helper.translation.translate( + "error", + "superError", + self.controller.users.get_user_lang_by_id(user_id), + ), + }, ) - elif api_key is not None: - exec_user_server_permissions = ( - self.controller.server_perms.get_api_key_permissions_list( - api_key, server_id - ) + return + if not self.request.headers.get("X-Content-Type", None).startswith( + "image/" + ): + self.helper.websocket_helper.broadcast_user( + user_id, + "send_start_error", + { + "error": self.helper.translation.translate( + "error", + "fileError", + self.controller.users.get_user_lang_by_id(user_id), + ), + }, ) - else: - exec_user_server_permissions = ( - self.controller.server_perms.get_user_id_permissions_list( - exec_user["user_id"], server_id - ) - ) - - server_id = self.request.headers.get("X-ServerId", None) - if server_id is None: - logger.warning("Server ID not found in upload handler call") - Console.warning("Server ID not found in upload handler call") - self.do_upload = False - + return if user_id is None: logger.warning("User ID not found in upload handler call") Console.warning("User ID not found in upload handler call") self.do_upload = False - if EnumPermissionsServer.FILES not in exec_user_server_permissions: - logger.warning( - f"User {user_id} tried to upload a file to " - f"{server_id} without permissions!" - ) - Console.warning( - f"User {user_id} tried to upload a file to " - f"{server_id} without permissions!" - ) - self.do_upload = False - - path = self.request.headers.get("X-Path", None) + path = os.path.join( + self.controller.project_root, + "app/frontend/static/assets/images/auth/custom", + ) filename = self.request.headers.get("X-FileName", None) full_path = os.path.join(path, filename) - if not Helpers.in_path( - Helpers.get_os_understandable_path( - self.controller.servers.get_server_data_by_id(server_id)["path"] - ), - full_path, - ): - logger.warning( - f"User {user_id} tried to upload a file to {server_id} " - f"but the path is not inside of the server!" - ) - Console.warning( - f"User {user_id} tried to upload a file to {server_id} " - f"but the path is not inside of the server!" - ) - self.do_upload = False - if self.do_upload: try: self.f = open(full_path, "wb") diff --git a/app/frontend/static/assets/css/dark/style.css b/app/frontend/static/assets/css/dark/style.css index d4b32181..dbd6ea8b 100755 --- a/app/frontend/static/assets/css/dark/style.css +++ b/app/frontend/static/assets/css/dark/style.css @@ -28362,11 +28362,6 @@ div.tagsinput span.tag a { min-height: 100vh; } -.auth.auth-bg-1 { - background: url("../../images/auth/login_1.jpg"); - background-size: cover; -} - .auth.register-bg-1 { background: url("../../images/auth/register.jpg") center center no-repeat; background-size: cover; diff --git a/app/frontend/static/assets/css/shared/style.css b/app/frontend/static/assets/css/shared/style.css index 5b223d6d..7352d637 100755 --- a/app/frontend/static/assets/css/shared/style.css +++ b/app/frontend/static/assets/css/shared/style.css @@ -26992,11 +26992,6 @@ div.tagsinput span.tag a { min-height: 100vh; } -.auth.auth-bg-1 { - background: url("../../images/auth/login_1.jpg"); - background-size: cover; -} - .auth.register-bg-1 { background: url("../../images/auth/register.jpg") center center no-repeat; background-size: cover; diff --git a/app/frontend/templates/panel/panel_config.html b/app/frontend/templates/panel/panel_config.html index b344f1c9..26f34a12 100644 --- a/app/frontend/templates/panel/panel_config.html +++ b/app/frontend/templates/panel/panel_config.html @@ -229,6 +229,59 @@ +
+
+
+
+ +

{{ translate('panelConfig', 'loginImage', data['lang']) }}

+
+

+ +

+ {% raw xsrf_form_html() %} + + +
+
+ +
+
+
+ + + + +
+
+
+
+
+ +

+
+
+
+
+
+

Login Background Image



+
+ +
+
+ + +
+
+
+
+
{% end %} @@ -307,6 +360,67 @@ }, }); }) + + $('.delete-photo').click(function () { + var token = getCookie("_xsrf") + let photo = $('#photo').find(":selected").val(); + $.ajax({ + type: "POST", + headers: { 'X-XSRFToken': token }, + url: '/ajax/delete_photo?photo=' + photo, + success: function (data) { + location.reload(); + }, + }); + }) + + $('.select-photo').click(function () { + var token = getCookie("_xsrf") + let photo = $('#photo').find(":selected").val(); + $.ajax({ + type: "POST", + headers: { 'X-XSRFToken': token }, + url: '/ajax/select_photo?photo=' + photo, + success: function (data) { + }, + }); + }) + + var file; + function sendFile() { + file = $("#file")[0].files[0] + document.getElementById("upload_input").innerHTML = '
 
' + let xmlHttpRequest = new XMLHttpRequest(); + let token = getCookie("_xsrf") + let fileName = file.name + let target = '/upload' + let mimeType = file.type + let size = file.size + let type = 'background' + + xmlHttpRequest.open('POST', target, true); + xmlHttpRequest.setRequestHeader('X-Content-Type', mimeType); + xmlHttpRequest.setRequestHeader('X-XSRFToken', token); + xmlHttpRequest.setRequestHeader('X-Content-Length', size); + xmlHttpRequest.setRequestHeader('X-Content-Disposition', 'attachment; filename="' + fileName + '"'); + xmlHttpRequest.setRequestHeader('X-Content-Upload-Type', type); + xmlHttpRequest.setRequestHeader('X-FileName', fileName); + xmlHttpRequest.addEventListener('load', (event) => { + if (event.target.responseText == 'success') { + console.log('Upload for file', file.name, 'was successful!') + document.getElementById("upload_input").innerHTML = '
' + fileName + ' 🔒
'; + document.getElementById("lower_half").style.visibility = "visible"; + } + else { + alert('Upload failed with response: ' + event.target.responseText); + doUpload = false; + } + }, false); + xmlHttpRequest.addEventListener('error', (e) => { + console.error('Error while uploading file', file.name + '.', 'Event:', e) + }, false); + xmlHttpRequest.send(file); + } {% end %} \ No newline at end of file diff --git a/app/frontend/templates/panel/panel_edit_user.html b/app/frontend/templates/panel/panel_edit_user.html index de60388e..a40d2903 100644 --- a/app/frontend/templates/panel/panel_edit_user.html +++ b/app/frontend/templates/panel/panel_edit_user.html @@ -124,7 +124,7 @@ data['lang']) }}{% end %}
-