diff --git a/.gitlab/lint.yml b/.gitlab/lint.yml
index 101e26b2..bc797808 100644
--- a/.gitlab/lint.yml
+++ b/.gitlab/lint.yml
@@ -44,13 +44,17 @@ black:
# Code Climate/Quality Checking [https://pylint.pycqa.org/en/latest/]
pylint:
stage: lint
- image: registry.gitlab.com/pipeline-components/pylint:0.21.1
+ image: registry.gitlab.com/pipeline-components/pylint:latest
tags:
- docker
rules:
- if: "$CODE_QUALITY_DISABLED"
when: never
- if: "$CI_COMMIT_TAG || $CI_COMMIT_BRANCH"
+ before_script:
+ - apk update
+ - apk add gcc python3-dev linux-headers build-base
+ - pip3 install --no-cache-dir -r requirements.txt
script:
- pylint --exit-zero --load-plugins=pylint_gitlab --output-format=gitlab-codeclimate:codeclimate.json $(find -type f -name "*.py" ! -path "**/.venv/**" ! -path "**/app/migrations/**")
artifacts:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4d05ab6f..d02386a9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,7 @@
### Refactor
- Refactor subpage perm checks ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/695))
### Bug fixes
+- [`CVE-2024-1064`] Security-related fix to resolve an issue with the HTTP listener ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/704))
- Fix bukkit and downstream fork MOTD crash ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/686))
- Fix bug where invalid server Id leads to stack ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/690))
- Fix indent on public status check box ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/691))
@@ -16,6 +17,11 @@
### Tweaks
- Refactor Forge server initialisation flow for newer versions ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/687))
- Remove scroll bars from player management ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/693))
+- Add warning to wizard for unsupported mc ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/701))
+- Improve display for `th-TH` characters ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/703))
+- Improve display of white text on **wssErrors** ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/703))
+- Improve display of white text on **Buttons** ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/703))
+- Fix dashboard motd issue #322 ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/705))
### Lang
- Update `zh_CN, pl_PL, nl_BE, lv_LV, he_IL, fr_FR, de_DE, lol_EN` translations for `4.2.3` ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/696))
- New `uk_UA, tr_TR, th_TH` translations for `4.2.3` ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/696))
diff --git a/app/classes/web/base_handler.py b/app/classes/web/base_handler.py
index ad490c2f..ced6cb97 100644
--- a/app/classes/web/base_handler.py
+++ b/app/classes/web/base_handler.py
@@ -106,7 +106,7 @@ class BaseHandler(tornado.web.RequestHandler):
if type(text) in self.nobleach:
logger.debug("Auto-bleaching - bypass type")
return text
- return nh3.clean(text)
+ return nh3.clean(text) # pylint: disable=no-member
def get_argument(
self,
diff --git a/app/classes/web/http_handler.py b/app/classes/web/http_handler.py
index ca340c66..32676d59 100644
--- a/app/classes/web/http_handler.py
+++ b/app/classes/web/http_handler.py
@@ -17,7 +17,7 @@ class HTTPHandler(BaseHandler):
url = "https://" + url
db_port = self.helper.get_setting("https_port")
try:
- resp = requests.get(url + ":" + str(port))
+ resp = requests.head(url + ":" + str(port), timeout=(0.5, 5))
resp.raise_for_status()
except Exception:
port = db_port
@@ -35,7 +35,7 @@ class HTTPHandlerPage(BaseHandler):
url = "https://" + url
db_port = self.helper.get_setting("https_port")
try:
- resp = requests.get(url + ":" + str(port))
+ resp = requests.head(url + ":" + str(port), timeout=(0.5, 5))
resp.raise_for_status()
except Exception:
port = db_port
diff --git a/app/classes/web/http_handler_page.py b/app/classes/web/http_handler_page.py
index 30a8aaa1..77161577 100644
--- a/app/classes/web/http_handler_page.py
+++ b/app/classes/web/http_handler_page.py
@@ -25,7 +25,7 @@ class HTTPHandlerPage(BaseHandler):
backup_url = url + str(self.helper.get_setting("https_port"))
try:
- resp = requests.get(primary_url)
+ resp = requests.head(primary_url, timeout=(0.5, 5))
resp.raise_for_status()
url = primary_url
except Exception:
diff --git a/app/classes/web/panel_handler.py b/app/classes/web/panel_handler.py
index 0dc1df31..a7e54974 100644
--- a/app/classes/web/panel_handler.py
+++ b/app/classes/web/panel_handler.py
@@ -80,6 +80,7 @@ class PanelHandler(BaseHandler):
) in self.controller.crafty_perms.list_defined_crafty_permissions():
argument = int(
float(
+ # pylint: disable=no-member
nh3.clean(self.get_argument(f"permission_{permission.name}", "0"))
)
)
@@ -89,7 +90,10 @@ class PanelHandler(BaseHandler):
)
q_argument = int(
- float(nh3.clean(self.get_argument(f"quantity_{permission.name}", "0")))
+ float(
+ # pylint: disable=no-member
+ nh3.clean(self.get_argument(f"quantity_{permission.name}", "0"))
+ )
)
if q_argument:
server_quantity[permission.name] = q_argument
@@ -503,7 +507,9 @@ class PanelHandler(BaseHandler):
template = "panel/dashboard.html"
elif page == "server_detail":
+ # pylint: disable=no-member
subpage = nh3.clean(self.get_argument("subpage", ""))
+ # pylint: enable=no-member
server_id = self.check_server_id()
# load page the user was on last
@@ -1362,7 +1368,9 @@ class PanelHandler(BaseHandler):
template = "panel/panel_edit_user_apikeys.html"
elif page == "remove_user":
+ # pylint: disable=no-member
user_id = nh3.clean(self.get_argument("id", None))
+ # pylint: enable=no-member
if (
not superuser
diff --git a/app/classes/web/public_handler.py b/app/classes/web/public_handler.py
index 7df88f68..762d3fb1 100644
--- a/app/classes/web/public_handler.py
+++ b/app/classes/web/public_handler.py
@@ -29,8 +29,10 @@ class PublicHandler(BaseHandler):
# self.clear_cookie("user_data")
def get(self, page=None):
+ # pylint: disable=no-member
error = nh3.clean(self.get_argument("error", "Invalid Login!"))
error_msg = nh3.clean(self.get_argument("error_msg", ""))
+ # pylint: enable=no-member
page_data = {
"version": self.helper.get_version_string(),
@@ -87,8 +89,10 @@ class PublicHandler(BaseHandler):
)
def post(self, page=None):
+ # pylint: disable=no-member
error = nh3.clean(self.get_argument("error", "Invalid Login!"))
error_msg = nh3.clean(self.get_argument("error_msg", ""))
+ # pylint: enable=no-member
page_data = {
"version": self.helper.get_version_string(),
@@ -108,10 +112,11 @@ class PublicHandler(BaseHandler):
if self.request.query:
next_page = "/login?" + self.request.query
+ # pylint: disable=no-member
entered_username = nh3.clean(self.get_argument("username"))
entered_password = self.get_argument("password")
+ # pylint: enable=no-member
- # pylint: disable=no-member
try:
user_id = HelperUsers.get_user_id_by_name(entered_username.lower())
user_data = HelperUsers.get_user_model(user_id)
diff --git a/app/classes/web/tornado_handler.py b/app/classes/web/tornado_handler.py
index f5501d31..fbcf970f 100644
--- a/app/classes/web/tornado_handler.py
+++ b/app/classes/web/tornado_handler.py
@@ -112,7 +112,7 @@ class Webserver:
cookie_secret = self.helper.random_string_generator(32)
HelpersManagement.set_cookie_secret(cookie_secret)
- if not http_port:
+ if not http_port and http_port != 0:
http_port = 8000
if not https_port:
@@ -191,8 +191,11 @@ class Webserver:
serve_traceback=debug_errors,
)
- self.http_server = tornado.httpserver.HTTPServer(http_app)
- self.http_server.listen(http_port)
+ if http_port != 0:
+ self.http_server = tornado.httpserver.HTTPServer(http_app)
+ self.http_server.listen(http_port)
+ else:
+ logger.info("http port disabled by config")
self.https_server = tornado.httpserver.HTTPServer(app, ssl_options=cert_objects)
self.https_server.listen(https_port)
diff --git a/app/frontend/static/assets/css/crafty.css b/app/frontend/static/assets/css/crafty.css
index cc1a8b82..43dd2e6a 100644
--- a/app/frontend/static/assets/css/crafty.css
+++ b/app/frontend/static/assets/css/crafty.css
@@ -37,16 +37,16 @@ nav.sidebar {
width: 10px;
height: 10px;
border-radius: 100%;
- border: 2px solid #fff;
+ border: 2px solid var(--white);
display: block;
}
.toggle-handle {
- background-color: white !important;
+ background-color: var(--white) !important;
}
.toggle-on {
- color: black !important;
+ color: var(--dark) !important;
}
.toggle {
@@ -61,7 +61,7 @@ nav.sidebar {
width: 10px;
height: 10px;
border-radius: 100%;
- border: 2px solid #fff;
+ border: 2px solid var(--white);
display: block;
}
@@ -95,7 +95,7 @@ nav.sidebar {
}
.scrollable-element {
- scrollbar-color: red yellow;
+ scrollbar-color: var(--red) var(--yellow);
}
.term-nav-item {
@@ -212,6 +212,14 @@ div>.input-group>.form-control {
top: calc(-0.125rem + 1px);
}
+a.btn-primary {
+ color: var(--white);
+}
+
+button.btn-primary {
+ color: var(--white);
+}
+
/**************************************************************/
/**************************************************************/
@@ -233,4 +241,30 @@ td.action .btn {
margin-bottom: 0.2rem;
}
+/**************************************************************/
+
+/**************************************************************/
+/* CSS for warnings Displays */
+/**************************************************************/
+div.warnings div.wssError {
+ color: var(--white);
+}
+
+div.warnings div.wssError a {
+ color: var(--outline);
+}
+
+div.warnings div.wssError a:hover {
+ color: var(--white-smoke);
+}
+
+/**************************************************************/
+
+/**************************************************************/
+/* CSS for Fonts Displays */
+/**************************************************************/
+*:lang(th-TH) :not(.fa, .fas, .fab, .fa-solid) {
+ font-family: 'Sarabun', 'roboto', sans-serif;
+}
+
/**************************************************************/
\ No newline at end of file
diff --git a/app/frontend/static/assets/js/motd.js b/app/frontend/static/assets/js/motd.js
index 3d07c8fb..8f63e763 100644
--- a/app/frontend/static/assets/js/motd.js
+++ b/app/frontend/static/assets/js/motd.js
@@ -96,7 +96,7 @@ function initParser(input, output) {
var input = document.getElementById(input),
output = document.getElementById(output);
if (input != null && output != null) {
- var parsed = parseStyle(input.innerHTML);
+ var parsed = parseStyle(input.innerText);
output.innerHTML = '';
output.appendChild(parsed);
}
diff --git a/app/frontend/templates/base.html b/app/frontend/templates/base.html
index 8d72ece6..a1fe0f9c 100755
--- a/app/frontend/templates/base.html
+++ b/app/frontend/templates/base.html
@@ -14,6 +14,7 @@
+
@@ -53,7 +54,6 @@
-
@@ -395,7 +395,7 @@
}
},
callback: function (result) {
- if (result){
+ if (result) {
location.href = "/panel/download_support_package";
} else {
bootbox.close();
@@ -489,8 +489,8 @@
if (link) {
let linkEl = document.createElement('a')
linkEl.href = link;
- linkEl.innerHTML = link_msg;
- linkEl.style.color = 'white';
+ linkEl.innerHTML = "See our documentation for details.";
+ //linkEl.style.color = 'white';
linkEl.style.textDecoration = 'underline';
linkEl.target = "_blank";
@@ -586,7 +586,7 @@
'⚠️You are in a recovery account. Access is limited!',
link='/logout',
link_msg="Click here to log out after you change your password. ⚠️",
- className='anti-lockout',
+ className='anti-lockout',
bg_color='#6887dc'
)
}
diff --git a/app/frontend/templates/panel/dashboard.html b/app/frontend/templates/panel/dashboard.html
index eb4a51a9..0d4fc0ac 100644
--- a/app/frontend/templates/panel/dashboard.html
+++ b/app/frontend/templates/panel/dashboard.html
@@ -287,8 +287,7 @@
data['lang']) }}
{% if server['stats']['desc'] != 'False' %}
-