diff --git a/CHANGELOG.md b/CHANGELOG.md
index dfd883a7..ccd95863 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,21 +1,28 @@
# Changelog
## --- [4.2.2] - 2023/TBD
### New features
-TBD
+- Loading Screen for Crafty during startup ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/668))
### Refactor
- Remove deprecated API V1 ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/670))
+- Tidy up main.py to be more comprehensive ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/668))
### Bug fixes
- Remove webhook `custom` option from webook provider list as it's not currently an option ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/664))
+- Bump cryptography for CVE-2023-49083 ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/680))
+- Fix bug where su cannot edit general user password ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/676))
+- Fix bug where no file error on import root dir ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/677))
+- Fix Unban button failing to pardon users ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/671))
+- Fix stack in API error handling ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/674))
+- Fix bug where you cannot select "do not monitor mounts" from `config.json` ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/678))
+- Fix support log 'x' button still downloading logs ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/679))
### Tweaks
- Homogenize Panel logos/branding ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/666))
- Retain previous tab when revisiting server details page (#272)([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/667))
- Add server name tag in panel header (#272)([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/667))
- Setup logging for panel authentication attempts ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/669))
- Update minimum password length from 6 to 8, and unrestrict maximum password length ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/669))
-- Fix Unban button failing to pardon users ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/671))
-- Fix stack in API error handling ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/674))
+- Give better feedback when backup delete fails ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/681))
### Lang
-TBD
+- pl_PL Minor fixes ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/675))
## --- [4.2.1] - 2023/11/01
diff --git a/app/classes/controllers/servers_controller.py b/app/classes/controllers/servers_controller.py
index 99151a32..88923194 100644
--- a/app/classes/controllers/servers_controller.py
+++ b/app/classes/controllers/servers_controller.py
@@ -22,6 +22,7 @@ from app.classes.models.server_permissions import (
PermissionsServers,
EnumPermissionsServer,
)
+from app.classes.shared.websocket_manager import WebSocketManager
logger = logging.getLogger(__name__)
@@ -36,6 +37,7 @@ class ServersController(metaclass=Singleton):
self.management_helper = management_helper
self.servers_list = []
self.stats = Stats(self.helper, self)
+ self.web_sock = WebSocketManager()
self.server_subpage = {}
# **********************************************************************************
@@ -170,8 +172,15 @@ class ServersController(metaclass=Singleton):
def init_all_servers(self):
servers = self.get_all_defined_servers()
self.failed_servers = []
-
for server in servers:
+ self.web_sock.broadcast_to_admins(
+ "update",
+ {"section": "server", "server": server["server_name"]},
+ )
+ self.web_sock.broadcast_to_non_admins(
+ "update",
+ {"section": "init"},
+ )
server_id = server.get("server_id")
# if we have already initialized this server, let's skip it.
diff --git a/app/classes/shared/helpers.py b/app/classes/shared/helpers.py
index 62ce8819..7524cf90 100644
--- a/app/classes/shared/helpers.py
+++ b/app/classes/shared/helpers.py
@@ -80,6 +80,7 @@ class Helpers:
self.translation = Translation(self)
self.update_available = False
self.ignored_names = ["crafty_managed.txt", "db_stats"]
+ self.crafty_starting = False
@staticmethod
def auto_installer_fix(ex):
diff --git a/app/classes/shared/main_controller.py b/app/classes/shared/main_controller.py
index de2e6b80..ae58d988 100644
--- a/app/classes/shared/main_controller.py
+++ b/app/classes/shared/main_controller.py
@@ -85,7 +85,7 @@ class Controller:
encoding="utf-8",
) as f:
self.auth_tracker = json.load(f)
- except:
+ except (FileNotFoundError, json.JSONDecodeError):
self.auth_tracker = {}
def log_attempt(self, remote_ip, username):
diff --git a/app/classes/shared/websocket_manager.py b/app/classes/shared/websocket_manager.py
index f48adef8..7cda296d 100644
--- a/app/classes/shared/websocket_manager.py
+++ b/app/classes/shared/websocket_manager.py
@@ -37,7 +37,15 @@ class WebSocketManager(metaclass=Singleton):
def broadcast_to_admins(self, event_type: str, data):
def filter_fn(client):
- if client.get_user_id in HelperUsers.get_super_user_list():
+ if str(client.get_user_id()) in str(HelperUsers.get_super_user_list()):
+ return True
+ return False
+
+ self.broadcast_with_fn(filter_fn, event_type, data)
+
+ def broadcast_to_non_admins(self, event_type: str, data):
+ def filter_fn(client):
+ if str(client.get_user_id()) not in str(HelperUsers.get_super_user_list()):
return True
return False
diff --git a/app/classes/web/panel_handler.py b/app/classes/web/panel_handler.py
index e8643aa7..8ac827c3 100644
--- a/app/classes/web/panel_handler.py
+++ b/app/classes/web/panel_handler.py
@@ -210,6 +210,8 @@ class PanelHandler(BaseHandler):
error = self.get_argument("error", "WTF Error!")
template = "panel/denied.html"
+ if self.helper.crafty_starting:
+ page = "loading"
now = time.time()
formatted_time = str(
@@ -243,9 +245,13 @@ class PanelHandler(BaseHandler):
for r in exec_user["roles"]:
role = self.controller.roles.get_role(r)
exec_user_role.add(role["role_name"])
- defined_servers = self.controller.servers.get_authorized_servers(
- exec_user["user_id"]
- )
+ # get_auth_servers will throw an exception if run while Crafty is starting
+ if not self.helper.crafty_starting:
+ defined_servers = self.controller.servers.get_authorized_servers(
+ exec_user["user_id"]
+ )
+ else:
+ defined_servers = []
user_order = self.controller.users.get_user_by_id(exec_user["user_id"])
user_order = user_order["server_order"].split(",")
@@ -1615,7 +1621,8 @@ class PanelHandler(BaseHandler):
logs_thread.start()
self.redirect("/panel/dashboard")
return
-
+ if self.helper.crafty_starting:
+ template = "panel/loading.html"
self.render(
template,
data=page_data,
diff --git a/app/classes/web/routes/api/crafty/imports/index.py b/app/classes/web/routes/api/crafty/imports/index.py
index e6c8c548..2aca2fa9 100644
--- a/app/classes/web/routes/api/crafty/imports/index.py
+++ b/app/classes/web/routes/api/crafty/imports/index.py
@@ -7,6 +7,7 @@ from jsonschema.exceptions import ValidationError
from app.classes.models.crafty_permissions import EnumPermissionsCrafty
from app.classes.shared.helpers import Helpers
from app.classes.web.base_api_handler import BaseApiHandler
+from app.classes.web.websocket_handler import WebSocketManager
logger = logging.getLogger(__name__)
files_get_schema = {
@@ -73,7 +74,7 @@ class ApiImportFilesIndexHandler(BaseApiHandler):
else:
if user_id:
user_lang = self.controller.users.get_user_lang_by_id(user_id)
- self.helper.websocket_helper.broadcast_user(
+ WebSocketManager().broadcast_user(
user_id,
"send_start_error",
{
@@ -85,7 +86,7 @@ class ApiImportFilesIndexHandler(BaseApiHandler):
else:
if not self.helper.check_path_exists(folder) and user_id:
user_lang = self.controller.users.get_user_lang_by_id(user_id)
- self.helper.websocket_helper.broadcast_user(
+ WebSocketManager().broadcast_user(
user_id,
"send_start_error",
{
diff --git a/app/classes/web/routes/api/servers/server/backups/backup/index.py b/app/classes/web/routes/api/servers/server/backups/backup/index.py
index b92e1e9f..9a4ecc30 100644
--- a/app/classes/web/routes/api/servers/server/backups/backup/index.py
+++ b/app/classes/web/routes/api/servers/server/backups/backup/index.py
@@ -72,9 +72,9 @@ class ApiServersServerBackupsBackupIndexHandler(BaseApiHandler):
FileHelpers.del_file(
os.path.join(backup_conf["backup_path"], data["filename"])
)
- except Exception:
+ except Exception as e:
return self.finish_json(
- 400, {"status": "error", "error": "NO BACKUP FOUND"}
+ 400, {"status": "error", "error": f"DELETE FAILED with error {e}"}
)
self.controller.management.add_to_audit_log(
auth_data[4]["user_id"],
diff --git a/app/classes/web/routes/api/users/user/index.py b/app/classes/web/routes/api/users/user/index.py
index d416e800..1b7f6f91 100644
--- a/app/classes/web/routes/api/users/user/index.py
+++ b/app/classes/web/routes/api/users/user/index.py
@@ -215,7 +215,7 @@ class ApiUsersUserIndexHandler(BaseApiHandler):
user_obj = HelperUsers.get_user_model(user_id)
if "password" in data and str(user["user_id"]) != str(user_id):
- if str(user["user_id"]) != str(user_obj.manager):
+ if str(user["user_id"]) != str(user_obj.manager) and not user["superuser"]:
# TODO: edit your own password
return self.finish_json(
400, {"status": "error", "error": "INVALID_PASSWORD_MODIFY"}
diff --git a/app/frontend/templates/base.html b/app/frontend/templates/base.html
index cca5ef3b..48c6ee95 100755
--- a/app/frontend/templates/base.html
+++ b/app/frontend/templates/base.html
@@ -384,18 +384,21 @@
if (x) {
x.remove()
}
- bootbox.alert({
+ bootbox.confirm({
title: "{{ translate('notify', 'downloadLogs', data['lang']) }}",
message: "{{ translate('notify', 'finishedPreparing', data['lang']) }}",
buttons: {
- ok: {
+ confirm: {
label: 'Download',
className: 'btn-info'
}
},
- callback: function () {
- console.log("in callback")
- location.href = "/panel/download_support_package";
+ callback: function (result) {
+ if (result){
+ location.href = "/panel/download_support_package";
+ } else {
+ bootbox.close();
+ }
}
});
});
@@ -605,4 +608,4 @@