mirror of
https://gitlab.com/crafty-controller/crafty-4.git
synced 2024-08-30 18:23:09 +00:00
Merge branch 'dev' into refactor/server_ids
This commit is contained in:
commit
e0bb2eaaa0
15
.gitlab/scripts/linux_perms_fix.sh
Normal file
15
.gitlab/scripts/linux_perms_fix.sh
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Prompt the user for the directory path
|
||||||
|
read -p "Enter the directory path to set permissions (/var/opt/minecraft/crafty): " directory_path
|
||||||
|
|
||||||
|
# Check if the script is running within a Docker container
|
||||||
|
if [ -f "/.dockerenv" ]; then
|
||||||
|
echo "Script is running within a Docker container. Exiting with error."
|
||||||
|
exit 1 # Exit with an error code if running in Docker
|
||||||
|
else
|
||||||
|
echo "Script is not running within a Docker container. Executing permissions changes..."
|
||||||
|
# Run the commands to set permissions
|
||||||
|
sudo chmod 700 $(find "$directory_path" -type d)
|
||||||
|
sudo chmod 644 $(find "$directory_path" -type f)
|
||||||
|
fi
|
@ -9,10 +9,15 @@ TBD
|
|||||||
- Make sure default.json is read from correct location ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/714))
|
- Make sure default.json is read from correct location ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/714))
|
||||||
- Do not allow users at server limit to clone servers ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/718))
|
- Do not allow users at server limit to clone servers ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/718))
|
||||||
- Fix bug where you cannot get to config with unloaded server ([Commit](https://gitlab.com/crafty-controller/crafty-4/-/commit/9de08973b6bb2ddf91283c5c6b0e189ff34f7e24))
|
- Fix bug where you cannot get to config with unloaded server ([Commit](https://gitlab.com/crafty-controller/crafty-4/-/commit/9de08973b6bb2ddf91283c5c6b0e189ff34f7e24))
|
||||||
|
- Fix forge install v1.20, 1.20.1 and 1.20.2 ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/710))
|
||||||
|
- Fix Sanitisation on Passwords ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/715))
|
||||||
|
- Fix `Upload Imports` on unix systems, that have a space in the root dir name ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/722))
|
||||||
|
- Fix Bedrock downloads, add `www` to download URL ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/723))
|
||||||
### Tweaks
|
### Tweaks
|
||||||
- Bump pyOpenSSL & cryptography for CVE-2024-0727, CVE-2023-50782 ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/716))
|
- Bump pyOpenSSL & cryptography for CVE-2024-0727, CVE-2023-50782 ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/716))
|
||||||
|
- Bump cryptography for CVE-2024-26130 ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/724))
|
||||||
### Lang
|
### Lang
|
||||||
TBD
|
- Update `de_DE, en_EN, es_ES, fr_FR, he_IL, lol_EN, lv_LV, nl_BE pl_PL, th_TH, tr_TR, uk_UA, zh_CN` translations for `4.3.0` ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/715))
|
||||||
<br><br>
|
<br><br>
|
||||||
|
|
||||||
## --- [4.2.3] - 2023/02/02
|
## --- [4.2.3] - 2023/02/02
|
||||||
|
@ -52,7 +52,7 @@ class UsersController:
|
|||||||
},
|
},
|
||||||
"password": {
|
"password": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"minLength": 8,
|
"minLength": self.helper.minimum_password_length,
|
||||||
"examples": ["crafty"],
|
"examples": ["crafty"],
|
||||||
"title": "Password",
|
"title": "Password",
|
||||||
},
|
},
|
||||||
|
@ -82,11 +82,11 @@ class MainPrompt(cmd.Cmd):
|
|||||||
# get new password from user
|
# get new password from user
|
||||||
new_pass = getpass.getpass(prompt=f"NEW password for: {username} > ")
|
new_pass = getpass.getpass(prompt=f"NEW password for: {username} > ")
|
||||||
# check to make sure it fits our requirements.
|
# check to make sure it fits our requirements.
|
||||||
if len(new_pass) > 512:
|
if len(new_pass) < self.helper.minimum_password_length:
|
||||||
Console.warning("Passwords must be greater than 6char long and under 512")
|
Console.warning(
|
||||||
return False
|
"Passwords must be greater than"
|
||||||
if len(new_pass) < 6:
|
f" {self.helper.minimum_password_length} char long"
|
||||||
Console.warning("Passwords must be greater than 6char long and under 512")
|
)
|
||||||
return False
|
return False
|
||||||
# grab repeated password input
|
# grab repeated password input
|
||||||
new_pass_conf = getpass.getpass(prompt="Re-enter your password: > ")
|
new_pass_conf = getpass.getpass(prompt="Re-enter your password: > ")
|
||||||
|
@ -81,6 +81,7 @@ class Helpers:
|
|||||||
self.update_available = False
|
self.update_available = False
|
||||||
self.ignored_names = ["crafty_managed.txt", "db_stats"]
|
self.ignored_names = ["crafty_managed.txt", "db_stats"]
|
||||||
self.crafty_starting = False
|
self.crafty_starting = False
|
||||||
|
self.minimum_password_length = 8
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def auto_installer_fix(ex):
|
def auto_installer_fix(ex):
|
||||||
@ -117,7 +118,7 @@ class Helpers:
|
|||||||
Get latest bedrock executable url \n\n
|
Get latest bedrock executable url \n\n
|
||||||
returns url if successful, False if not
|
returns url if successful, False if not
|
||||||
"""
|
"""
|
||||||
url = "https://minecraft.net/en-us/download/server/bedrock/"
|
url = "https://www.minecraft.net/en-us/download/server/bedrock/"
|
||||||
headers = {
|
headers = {
|
||||||
"Accept-Encoding": "identity",
|
"Accept-Encoding": "identity",
|
||||||
"Accept-Language": "en",
|
"Accept-Language": "en",
|
||||||
|
@ -18,12 +18,19 @@ class DatabaseBuilder:
|
|||||||
logger.info("Fresh Install Detected - Creating Default Settings")
|
logger.info("Fresh Install Detected - Creating Default Settings")
|
||||||
Console.info("Fresh Install Detected - Creating Default Settings")
|
Console.info("Fresh Install Detected - Creating Default Settings")
|
||||||
default_data = self.helper.find_default_password()
|
default_data = self.helper.find_default_password()
|
||||||
if password not in default_data:
|
if "password" not in default_data:
|
||||||
Console.help(
|
Console.help(
|
||||||
"No default password found. Using password created "
|
"No default password found. Using password created "
|
||||||
"by Crafty. Find it in app/config/default-creds.txt"
|
"by Crafty. Find it in app/config/default-creds.txt"
|
||||||
)
|
)
|
||||||
username = default_data.get("username", "admin")
|
username = default_data.get("username", "admin")
|
||||||
|
if self.helper.minimum_password_length > default_data.get("password", password):
|
||||||
|
Console.critical(
|
||||||
|
"Default password too short"
|
||||||
|
" using Crafty's created default."
|
||||||
|
" Find it in app/config/default-creds.txt"
|
||||||
|
)
|
||||||
|
else:
|
||||||
password = default_data.get("password", password)
|
password = default_data.get("password", password)
|
||||||
|
|
||||||
self.users_helper.add_user(
|
self.users_helper.add_user(
|
||||||
|
@ -696,6 +696,10 @@ class ServerInstance:
|
|||||||
version_param = version[0][0].split(".")
|
version_param = version[0][0].split(".")
|
||||||
version_major = int(version_param[0])
|
version_major = int(version_param[0])
|
||||||
version_minor = int(version_param[1])
|
version_minor = int(version_param[1])
|
||||||
|
if len(version_param) > 2:
|
||||||
|
version_sub = int(version_param[2])
|
||||||
|
else:
|
||||||
|
version_sub = 0
|
||||||
|
|
||||||
# Checking which version we are with
|
# Checking which version we are with
|
||||||
if version_major <= 1 and version_minor < 17:
|
if version_major <= 1 and version_minor < 17:
|
||||||
@ -729,8 +733,8 @@ class ServerInstance:
|
|||||||
server_obj.execution_command = execution_command
|
server_obj.execution_command = execution_command
|
||||||
Console.debug(SUCCESSMSG)
|
Console.debug(SUCCESSMSG)
|
||||||
|
|
||||||
elif version_major <= 1 and version_minor < 20:
|
elif version_major <= 1 and version_minor <= 20 and version_sub < 3:
|
||||||
# NEW VERSION >= 1.17 and <= 1.20
|
# NEW VERSION >= 1.17 and <= 1.20.2
|
||||||
# (no jar file in server dir, only run.bat and run.sh)
|
# (no jar file in server dir, only run.bat and run.sh)
|
||||||
|
|
||||||
run_file_path = ""
|
run_file_path = ""
|
||||||
@ -777,7 +781,7 @@ class ServerInstance:
|
|||||||
server_obj.execution_command = execution_command
|
server_obj.execution_command = execution_command
|
||||||
Console.debug(SUCCESSMSG)
|
Console.debug(SUCCESSMSG)
|
||||||
else:
|
else:
|
||||||
# NEW VERSION >= 1.20
|
# NEW VERSION >= 1.20.3
|
||||||
# (executable jar is back in server dir)
|
# (executable jar is back in server dir)
|
||||||
|
|
||||||
# Retrieving the executable jar filename
|
# Retrieving the executable jar filename
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
import logging
|
import logging
|
||||||
|
import json
|
||||||
import nh3
|
import nh3
|
||||||
|
from jsonschema import validate
|
||||||
|
from jsonschema.exceptions import ValidationError
|
||||||
|
|
||||||
from app.classes.shared.helpers import Helpers
|
from app.classes.shared.helpers import Helpers
|
||||||
from app.classes.models.users import HelperUsers
|
from app.classes.models.users import HelperUsers
|
||||||
@ -45,7 +48,7 @@ class PublicHandler(BaseHandler):
|
|||||||
}
|
}
|
||||||
|
|
||||||
if self.request.query:
|
if self.request.query:
|
||||||
page_data["query"] = self.request.query
|
page_data["query"] = self.request.query_arguments.get("next")[0].decode()
|
||||||
|
|
||||||
# sensible defaults
|
# sensible defaults
|
||||||
template = "public/404.html"
|
template = "public/404.html"
|
||||||
@ -75,11 +78,7 @@ class PublicHandler(BaseHandler):
|
|||||||
|
|
||||||
# if we have no page, let's go to login
|
# if we have no page, let's go to login
|
||||||
else:
|
else:
|
||||||
if self.request.query:
|
return self.redirect("/login")
|
||||||
self.redirect("/login?" + self.request.query)
|
|
||||||
else:
|
|
||||||
self.redirect("/login")
|
|
||||||
return
|
|
||||||
|
|
||||||
self.render(
|
self.render(
|
||||||
template,
|
template,
|
||||||
@ -89,33 +88,61 @@ class PublicHandler(BaseHandler):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def post(self, page=None):
|
def post(self, page=None):
|
||||||
# pylint: disable=no-member
|
login_schema = {
|
||||||
error = nh3.clean(self.get_argument("error", "Invalid Login!"))
|
"type": "object",
|
||||||
error_msg = nh3.clean(self.get_argument("error_msg", ""))
|
"properties": {
|
||||||
# pylint: enable=no-member
|
"username": {
|
||||||
|
"type": "string",
|
||||||
|
},
|
||||||
|
"password": {"type": "string"},
|
||||||
|
},
|
||||||
|
"required": ["username", "password"],
|
||||||
|
"additionalProperties": False,
|
||||||
|
}
|
||||||
|
try:
|
||||||
|
data = json.loads(self.request.body)
|
||||||
|
except json.decoder.JSONDecodeError as e:
|
||||||
|
logger.error(
|
||||||
|
"Invalid JSON schema for API"
|
||||||
|
f" login attempt from {self.get_remote_ip()}"
|
||||||
|
)
|
||||||
|
return self.finish_json(
|
||||||
|
400, {"status": "error", "error": "INVALID_JSON", "error_data": str(e)}
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
validate(data, login_schema)
|
||||||
|
except ValidationError as e:
|
||||||
|
logger.error(
|
||||||
|
"Invalid JSON schema for API"
|
||||||
|
f" login attempt from {self.get_remote_ip()}"
|
||||||
|
)
|
||||||
|
return self.finish_json(
|
||||||
|
400,
|
||||||
|
{
|
||||||
|
"status": "error",
|
||||||
|
"error": "VWggb2ghIFN0aW5reS 🪠",
|
||||||
|
"error_data": str(e),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
page_data = {
|
page_data = {
|
||||||
"version": self.helper.get_version_string(),
|
"version": self.helper.get_version_string(),
|
||||||
"error": error,
|
|
||||||
"lang": self.helper.get_setting("language"),
|
"lang": self.helper.get_setting("language"),
|
||||||
"lang_page": self.helper.get_lang_page(self.helper.get_setting("language")),
|
"lang_page": self.helper.get_lang_page(self.helper.get_setting("language")),
|
||||||
"query": "",
|
"query": "",
|
||||||
}
|
}
|
||||||
if self.request.query:
|
if self.request.query:
|
||||||
page_data["query"] = self.request.query
|
page_data["query"] = self.request.query_arguments.get("next")[0].decode()
|
||||||
|
|
||||||
if page == "login":
|
if page == "login":
|
||||||
|
data = json.loads(self.request.body)
|
||||||
|
|
||||||
auth_log.info(
|
auth_log.info(
|
||||||
f"User attempting to authenticate from {self.get_remote_ip()}"
|
f"User attempting to authenticate from {self.get_remote_ip()}"
|
||||||
)
|
)
|
||||||
next_page = "/login"
|
entered_username = nh3.clean(data["username"]) # pylint: disable=no-member
|
||||||
if self.request.query:
|
entered_password = data["password"]
|
||||||
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
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
user_id = HelperUsers.get_user_id_by_name(entered_username.lower())
|
user_id = HelperUsers.get_user_id_by_name(entered_username.lower())
|
||||||
@ -127,16 +154,18 @@ class PublicHandler(BaseHandler):
|
|||||||
f" Authentication failed from remote IP {self.get_remote_ip()}"
|
f" Authentication failed from remote IP {self.get_remote_ip()}"
|
||||||
" Users does not exist."
|
" Users does not exist."
|
||||||
)
|
)
|
||||||
error_msg = "Incorrect username or password. Please try again."
|
self.finish_json(
|
||||||
|
403,
|
||||||
|
{
|
||||||
|
"status": "error",
|
||||||
|
"error": self.helper.translation.translate(
|
||||||
|
"login", "incorrect", self.helper.get_setting("language")
|
||||||
|
),
|
||||||
|
},
|
||||||
|
)
|
||||||
# self.clear_cookie("user")
|
# self.clear_cookie("user")
|
||||||
# self.clear_cookie("user_data")
|
# self.clear_cookie("user_data")
|
||||||
self.clear_cookie("token")
|
return self.clear_cookie("token")
|
||||||
if self.request.query:
|
|
||||||
self.redirect(f"/login?error_msg={error_msg}&{self.request.query}")
|
|
||||||
else:
|
|
||||||
self.redirect(f"/login?error_msg={error_msg}")
|
|
||||||
return
|
|
||||||
|
|
||||||
# if we don't have a user
|
# if we don't have a user
|
||||||
if not user_data:
|
if not user_data:
|
||||||
auth_log.error(
|
auth_log.error(
|
||||||
@ -145,15 +174,18 @@ class PublicHandler(BaseHandler):
|
|||||||
" User does not exist."
|
" User does not exist."
|
||||||
)
|
)
|
||||||
self.controller.log_attempt(self.get_remote_ip(), entered_username)
|
self.controller.log_attempt(self.get_remote_ip(), entered_username)
|
||||||
error_msg = "Incorrect username or password. Please try again."
|
self.finish_json(
|
||||||
|
403,
|
||||||
|
{
|
||||||
|
"status": "error",
|
||||||
|
"error": self.helper.translation.translate(
|
||||||
|
"login", "incorrect", self.helper.get_setting("language")
|
||||||
|
),
|
||||||
|
},
|
||||||
|
)
|
||||||
# self.clear_cookie("user")
|
# self.clear_cookie("user")
|
||||||
# self.clear_cookie("user_data")
|
# self.clear_cookie("user_data")
|
||||||
self.clear_cookie("token")
|
return self.clear_cookie("token")
|
||||||
if self.request.query:
|
|
||||||
self.redirect(f"/login?error_msg={error_msg}&{self.request.query}")
|
|
||||||
else:
|
|
||||||
self.redirect(f"/login?error_msg={error_msg}")
|
|
||||||
return
|
|
||||||
|
|
||||||
# if they are disabled
|
# if they are disabled
|
||||||
if not user_data.enabled:
|
if not user_data.enabled:
|
||||||
@ -163,19 +195,18 @@ class PublicHandler(BaseHandler):
|
|||||||
" User account disabled"
|
" User account disabled"
|
||||||
)
|
)
|
||||||
self.controller.log_attempt(self.get_remote_ip(), entered_username)
|
self.controller.log_attempt(self.get_remote_ip(), entered_username)
|
||||||
error_msg = (
|
self.finish_json(
|
||||||
"User account disabled. Please contact "
|
403,
|
||||||
"your system administrator for more info."
|
{
|
||||||
|
"status": "error",
|
||||||
|
"error": self.helper.translation.translate(
|
||||||
|
"login", "disabled", self.helper.get_setting("language")
|
||||||
|
),
|
||||||
|
},
|
||||||
)
|
)
|
||||||
# self.clear_cookie("user")
|
# self.clear_cookie("user")
|
||||||
# self.clear_cookie("user_data")
|
# self.clear_cookie("user_data")
|
||||||
self.clear_cookie("token")
|
return self.clear_cookie("token")
|
||||||
if self.request.query:
|
|
||||||
self.redirect(f"/login?error_msg={error_msg}&{self.request.query}")
|
|
||||||
else:
|
|
||||||
self.redirect(f"/login?error_msg={error_msg}")
|
|
||||||
return
|
|
||||||
|
|
||||||
login_result = self.helper.verify_pass(entered_password, user_data.password)
|
login_result = self.helper.verify_pass(entered_password, user_data.password)
|
||||||
|
|
||||||
# Valid Login
|
# Valid Login
|
||||||
@ -200,13 +231,11 @@ class PublicHandler(BaseHandler):
|
|||||||
user_data.user_id, "Logged in", 0, self.get_remote_ip()
|
user_data.user_id, "Logged in", 0, self.get_remote_ip()
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.request.query_arguments.get("next"):
|
return self.finish_json(
|
||||||
next_page = self.request.query_arguments.get("next")[0].decode()
|
200, {"status": "ok", "data": {"message": "login successful!"}}
|
||||||
else:
|
)
|
||||||
next_page = "/panel/dashboard"
|
|
||||||
|
|
||||||
self.redirect(next_page)
|
# We'll continue on and handle unsuccessful logins
|
||||||
else:
|
|
||||||
auth_log.error(
|
auth_log.error(
|
||||||
f"User attempted to log into {entered_username}."
|
f"User attempted to log into {entered_username}."
|
||||||
f" Authentication failed from remote IP {self.get_remote_ip()}"
|
f" Authentication failed from remote IP {self.get_remote_ip()}"
|
||||||
@ -215,17 +244,21 @@ class PublicHandler(BaseHandler):
|
|||||||
# self.clear_cookie("user")
|
# self.clear_cookie("user")
|
||||||
# self.clear_cookie("user_data")
|
# self.clear_cookie("user_data")
|
||||||
self.clear_cookie("token")
|
self.clear_cookie("token")
|
||||||
error_msg = "Incorrect username or password. Please try again."
|
error_msg = self.helper.translation.translate(
|
||||||
|
"login", "incorrect", self.helper.get_setting("language")
|
||||||
|
)
|
||||||
|
if entered_password == "app/config/default-creds.txt":
|
||||||
|
error_msg += ". "
|
||||||
|
error_msg += self.helper.translation.translate(
|
||||||
|
"login", "defaultPath", self.helper.get_setting("language")
|
||||||
|
)
|
||||||
# log this failed login attempt
|
# log this failed login attempt
|
||||||
self.controller.management.add_to_audit_log(
|
self.controller.management.add_to_audit_log(
|
||||||
user_data.user_id, "Tried to log in", 0, self.get_remote_ip()
|
user_data.user_id, "Tried to log in", 0, self.get_remote_ip()
|
||||||
)
|
)
|
||||||
if self.request.query:
|
return self.finish_json(
|
||||||
self.redirect(f"/login?error_msg={error_msg}&{self.request.query}")
|
403,
|
||||||
|
{"status": "error", "error": error_msg},
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
self.redirect(f"/login?error_msg={error_msg}")
|
self.redirect("/login?")
|
||||||
else:
|
|
||||||
if self.request.query:
|
|
||||||
self.redirect("/login?" + self.request.query)
|
|
||||||
else:
|
|
||||||
self.redirect("/login")
|
|
||||||
|
@ -17,7 +17,7 @@ login_schema = {
|
|||||||
"minLength": 4,
|
"minLength": 4,
|
||||||
"pattern": "^[a-z0-9_]+$",
|
"pattern": "^[a-z0-9_]+$",
|
||||||
},
|
},
|
||||||
"password": {"type": "string", "maxLength": 20, "minLength": 4},
|
"password": {"type": "string", "minLength": 4},
|
||||||
},
|
},
|
||||||
"required": ["username", "password"],
|
"required": ["username", "password"],
|
||||||
"additionalProperties": False,
|
"additionalProperties": False,
|
||||||
|
@ -77,11 +77,7 @@
|
|||||||
box-shadow: 0 12px 16px 0 hsla(0, 0%, 0%, 0.4);
|
box-shadow: 0 12px 16px 0 hsla(0, 0%, 0%, 0.4);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
{% if data['query'] %}
|
<form id="login-form" data-query="{{ data.get('query', None) }}">
|
||||||
<form action="/login?{{ data['query'] }}" method="post">
|
|
||||||
{% else %}
|
|
||||||
<form action="/login" method="post">
|
|
||||||
{% end %}
|
|
||||||
{% raw xsrf_form_html() %}
|
{% raw xsrf_form_html() %}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="label">{{ translate('login', 'username', data['lang']) }}</label>
|
<label class="label">{{ translate('login', 'username', data['lang']) }}</label>
|
||||||
@ -103,16 +99,14 @@
|
|||||||
<button class="login-input btn btn-primary submit-btn btn-block">{{ translate('login', 'login',
|
<button class="login-input btn btn-primary submit-btn btn-block">{{ translate('login', 'login',
|
||||||
data['lang']) }}</button>
|
data['lang']) }}</button>
|
||||||
</div>
|
</div>
|
||||||
{% if error_msg is not None %}
|
<fieldset id="error-field" style="color: red; text-align: center;">
|
||||||
<fieldset style="color: red; text-align: center;">
|
|
||||||
<span>{{error_msg}}</span>
|
|
||||||
</fieldset>
|
</fieldset>
|
||||||
{% end %}
|
|
||||||
<div class="form-group d-flex justify-content-between">
|
<div class="form-group d-flex justify-content-between">
|
||||||
<div class="form-check form-check-flat mt-0">
|
<div class="form-check form-check-flat mt-0">
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<button onclick="resetPass()" id="#resetPass" form="" class="btn btn-outline-primary btn-sm forgot-password ">{{ translate('login', 'forgotPassword',
|
<button onclick="resetPass()" id="#resetPass" form=""
|
||||||
|
class="btn btn-outline-primary btn-sm forgot-password ">{{ translate('login', 'forgotPassword',
|
||||||
data['lang']) }}</button>
|
data['lang']) }}</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -170,7 +164,38 @@
|
|||||||
bootbox.alert(responseData.data)
|
bootbox.alert(responseData.data)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
$("#login-form").on("submit", async function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
let loginForm = document.getElementById("login-form");
|
||||||
|
|
||||||
|
let formData = new FormData(loginForm);
|
||||||
|
|
||||||
|
//Create an object from the form data entries
|
||||||
|
let formDataObject = Object.fromEntries(formData.entries());
|
||||||
|
console.log(formDataObject)
|
||||||
|
let res = await fetch(`/login`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'X-XSRFToken': formDataObject._xsrf,
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
"username": formDataObject.username,
|
||||||
|
"password": formDataObject.password
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
let responseData = await res.json();
|
||||||
|
if (responseData.status === "ok") {
|
||||||
|
console.log("OK")
|
||||||
|
if ($("#login-form").data("query")) {
|
||||||
|
location.href = `${$("#login-form").data("query")}`;
|
||||||
|
} else {
|
||||||
|
location.href = `/panel/dashboard`
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$("#error-field").html(responseData.error);
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
.modal-content {
|
.modal-content {
|
||||||
|
@ -556,7 +556,7 @@
|
|||||||
xmlHttpRequest.addEventListener('load', (event) => {
|
xmlHttpRequest.addEventListener('load', (event) => {
|
||||||
if (event.target.responseText == 'success') {
|
if (event.target.responseText == 'success') {
|
||||||
console.log('Upload for file', file.name, 'was successful!')
|
console.log('Upload for file', file.name, 'was successful!')
|
||||||
document.getElementById("upload_input").innerHTML = `<div class="card-header header-sm d-flex justify-content-between align-items-center" style="width: 100%;"><input value=${fileName} type="text" id="file-uploaded" disabled></input> 🔒</div>`;
|
$("#upload_input").html(`<div class="card-header header-sm d-flex justify-content-between align-items-center" style="width: 100%;"><input value="${decodeURIComponent(fileName)}" type="text" id="file-uploaded" disabled></input> 🔒</div>`);
|
||||||
document.getElementById("lower_half").style.visibility = "visible";
|
document.getElementById("lower_half").style.visibility = "visible";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -881,7 +881,7 @@
|
|||||||
xmlHttpRequest.addEventListener('load', (event) => {
|
xmlHttpRequest.addEventListener('load', (event) => {
|
||||||
if (event.target.responseText == 'success') {
|
if (event.target.responseText == 'success') {
|
||||||
console.log('Upload for file', file.name, 'was successful!')
|
console.log('Upload for file', file.name, 'was successful!')
|
||||||
document.getElementById("upload_input").innerHTML = `<div class="card-header header-sm d-flex justify-content-between align-items-center" style="width: 100%;"><input value=${fileName} type="text" id="file-uploaded" disabled></input> 🔒</div>`;
|
$("#upload_input").html(`<div class="card-header header-sm d-flex justify-content-between align-items-center" style="width: 100%;"><input value="${fileName}" type="text" id="file-uploaded" disabled></input> 🔒</div>`);
|
||||||
document.getElementById("lower_half").style.visibility = "visible";
|
document.getElementById("lower_half").style.visibility = "visible";
|
||||||
document.getElementById("lower_half").hidden = false;
|
document.getElementById("lower_half").hidden = false;
|
||||||
}
|
}
|
||||||
|
@ -215,7 +215,10 @@
|
|||||||
"version": "Version"
|
"version": "Version"
|
||||||
},
|
},
|
||||||
"login": {
|
"login": {
|
||||||
|
"defaultPath": "Der eingegebene Text ist der Pfad zum Passwort, nicht das Passwort selbst. Das Standartpasswort kann unter diesen Pfad eingesehen werden.",
|
||||||
|
"disabled": "Account gesperrt. Für weitere Informationen den Serveradministrator kontaktieren",
|
||||||
"forgotPassword": "Passwort vergessen",
|
"forgotPassword": "Passwort vergessen",
|
||||||
|
"incorrect": "Benutzername oder Passwort falsch",
|
||||||
"login": "Einloggen",
|
"login": "Einloggen",
|
||||||
"password": "Passwort",
|
"password": "Passwort",
|
||||||
"username": "Nutzername",
|
"username": "Nutzername",
|
||||||
|
@ -215,7 +215,10 @@
|
|||||||
"version": "Version"
|
"version": "Version"
|
||||||
},
|
},
|
||||||
"login": {
|
"login": {
|
||||||
|
"defaultPath": "The password you entered is the default credential path, not the password. Please find the default password in that location.",
|
||||||
|
"disabled": "User account disabled. Please contact your system administrator for more info.",
|
||||||
"forgotPassword": "Forgot Password",
|
"forgotPassword": "Forgot Password",
|
||||||
|
"incorrect": "Incorrect username or password",
|
||||||
"login": "Log In",
|
"login": "Log In",
|
||||||
"password": "Password",
|
"password": "Password",
|
||||||
"username": "Username",
|
"username": "Username",
|
||||||
|
@ -111,6 +111,7 @@
|
|||||||
"starting": "Inicio-retrasado",
|
"starting": "Inicio-retrasado",
|
||||||
"status": "Estado",
|
"status": "Estado",
|
||||||
"stop": "Detener",
|
"stop": "Detener",
|
||||||
|
"storage": "Almacenamiento",
|
||||||
"version": "Versión",
|
"version": "Versión",
|
||||||
"welcome": "Bienvenido a Crafty Controller"
|
"welcome": "Bienvenido a Crafty Controller"
|
||||||
},
|
},
|
||||||
@ -214,7 +215,10 @@
|
|||||||
"version": "Versión"
|
"version": "Versión"
|
||||||
},
|
},
|
||||||
"login": {
|
"login": {
|
||||||
|
"defaultPath": "La contraseña introducida es la ruta default de las credenciales, no la contraseña. Busca la contraseña accediendo a la carpeta de la ruta",
|
||||||
|
"disabled": "Cuenta del usuario desactivada. Porfavor contacta al administrador para mas informacion.",
|
||||||
"forgotPassword": "Olvidé mi contraseña",
|
"forgotPassword": "Olvidé mi contraseña",
|
||||||
|
"incorrect": "El nombre de usuario o contraseña es incorrecto",
|
||||||
"login": "Iniciar Sesión",
|
"login": "Iniciar Sesión",
|
||||||
"password": "Contraseña",
|
"password": "Contraseña",
|
||||||
"username": "Usuario",
|
"username": "Usuario",
|
||||||
@ -326,6 +330,7 @@
|
|||||||
"bePatientDeleteFiles": "Tenga paciencia mientras eliminamos su servidor del panel de Crafty y eliminamos todos los archivos. Esta pantalla se cerrará en unos momentos.",
|
"bePatientDeleteFiles": "Tenga paciencia mientras eliminamos su servidor del panel de Crafty y eliminamos todos los archivos. Esta pantalla se cerrará en unos momentos.",
|
||||||
"bePatientUpdate": "Tenga paciencia mientras actualizamos el servidor. El tiempo de descarga puede variar según la velocidad del Internet...<br /> Esta pantalla se actualizará en unos momentos.",
|
"bePatientUpdate": "Tenga paciencia mientras actualizamos el servidor. El tiempo de descarga puede variar según la velocidad del Internet...<br /> Esta pantalla se actualizará en unos momentos.",
|
||||||
"cancel": "Cancelar",
|
"cancel": "Cancelar",
|
||||||
|
"countPlayers": "Incluir el servidor en la cuenta total de jugadores",
|
||||||
"crashTime": "Tiempo de espera por crasheo",
|
"crashTime": "Tiempo de espera por crasheo",
|
||||||
"crashTimeDesc": "¿Cuanto tiempo esperar para considerar el servidor como crasheado?",
|
"crashTimeDesc": "¿Cuanto tiempo esperar para considerar el servidor como crasheado?",
|
||||||
"deleteFilesQuestion": "¿Eliminar archivos del servidor del host?",
|
"deleteFilesQuestion": "¿Eliminar archivos del servidor del host?",
|
||||||
@ -510,6 +515,7 @@
|
|||||||
"cpuUsage": "Uso de CPU",
|
"cpuUsage": "Uso de CPU",
|
||||||
"description": "Descripción",
|
"description": "Descripción",
|
||||||
"errorCalculatingUptime": "Error calculando tiempo de actividad",
|
"errorCalculatingUptime": "Error calculando tiempo de actividad",
|
||||||
|
"loadingMotd": "Cargando MOTD",
|
||||||
"memUsage": "Uso de memoria",
|
"memUsage": "Uso de memoria",
|
||||||
"offline": "Desconectado",
|
"offline": "Desconectado",
|
||||||
"online": "En línea",
|
"online": "En línea",
|
||||||
@ -577,6 +583,7 @@
|
|||||||
"serverUpload": "Subir servidor comprimido",
|
"serverUpload": "Subir servidor comprimido",
|
||||||
"serverVersion": "Versión del servidor",
|
"serverVersion": "Versión del servidor",
|
||||||
"sizeInGB": "Tamaño en GB",
|
"sizeInGB": "Tamaño en GB",
|
||||||
|
"unsupported": "Versiones de Minecraft inferiores a la 1.8 no estan soportadas por Crafty. Es posible instalarlas. Resultados pueden variar.",
|
||||||
"uploadButton": "Subir",
|
"uploadButton": "Subir",
|
||||||
"uploadZip": "Subir archivo Zip para importar servidor",
|
"uploadZip": "Subir archivo Zip para importar servidor",
|
||||||
"zipPath": "Ruta del servidor"
|
"zipPath": "Ruta del servidor"
|
||||||
@ -591,6 +598,15 @@
|
|||||||
"newServer": "Crear nuevo Servidor",
|
"newServer": "Crear nuevo Servidor",
|
||||||
"servers": "Servidores"
|
"servers": "Servidores"
|
||||||
},
|
},
|
||||||
|
"startup": {
|
||||||
|
"almost": "Terminando. Espera un momento...",
|
||||||
|
"internals": "Configurando e inicializando los componentes internos de Crafty",
|
||||||
|
"internet": "Verificando conexion a internet",
|
||||||
|
"server": "Inicializando ",
|
||||||
|
"serverInit": "Inicializando Servidores",
|
||||||
|
"starting": "Crafty esta iniciando...",
|
||||||
|
"tasks": "Iniciando el programador de tareas"
|
||||||
|
},
|
||||||
"userConfig": {
|
"userConfig": {
|
||||||
"apiKey": "Claves API",
|
"apiKey": "Claves API",
|
||||||
"auth": "¿Autorizado? ",
|
"auth": "¿Autorizado? ",
|
@ -215,7 +215,10 @@
|
|||||||
"version": "Version"
|
"version": "Version"
|
||||||
},
|
},
|
||||||
"login": {
|
"login": {
|
||||||
|
"defaultPath": "Ce que tu as renseigné n'est pas le mot de passe, mais le chemin du fichier où le trouver.",
|
||||||
|
"disabled": "Ce compte est désactivé. Merci de contacter l'administrateur de ton serveur pour plus d'informations.",
|
||||||
"forgotPassword": "Mot de Passe Oublié",
|
"forgotPassword": "Mot de Passe Oublié",
|
||||||
|
"incorrect": "Identifiant et/ou mot de passe incorrect.",
|
||||||
"login": "Connexion",
|
"login": "Connexion",
|
||||||
"password": "Mot de Passe",
|
"password": "Mot de Passe",
|
||||||
"username": "Nom d'Utilisateur",
|
"username": "Nom d'Utilisateur",
|
||||||
|
@ -215,7 +215,10 @@
|
|||||||
"version": "גרסה"
|
"version": "גרסה"
|
||||||
},
|
},
|
||||||
"login": {
|
"login": {
|
||||||
|
"defaultPath": "הסיסמה שהזנת היא נתיב האישורים המוגדר כברירת מחדל, ולא הסיסמה עצמה. אנא מצא את הסיסמה המוגדרת כברירת מחדל במיקום זה.",
|
||||||
|
"disabled": "חשבון המשתמש מושבת. אנא פנה למנהל המערכת שלך לקבלת מידע נוסף.",
|
||||||
"forgotPassword": "שכחתי סיסמה",
|
"forgotPassword": "שכחתי סיסמה",
|
||||||
|
"incorrect": "שם משתמש או סיסמה שגויים",
|
||||||
"login": "התחברות",
|
"login": "התחברות",
|
||||||
"password": "סיסמה",
|
"password": "סיסמה",
|
||||||
"username": "שם משתמש",
|
"username": "שם משתמש",
|
||||||
|
@ -215,7 +215,10 @@
|
|||||||
"version": "VERSHUN"
|
"version": "VERSHUN"
|
||||||
},
|
},
|
||||||
"login": {
|
"login": {
|
||||||
|
"defaultPath": "Silleh hooman, dat iz da dafault secret path, not da passwurd. Plz find da default passwurd in dat spot.",
|
||||||
|
"disabled": "User account no play. Plz boop ur system hooman for moar infoz.",
|
||||||
"forgotPassword": "FORGWOTS YOUR SEEKRET",
|
"forgotPassword": "FORGWOTS YOUR SEEKRET",
|
||||||
|
"incorrect": "U gotz wrong name or passwurd",
|
||||||
"login": "WOG INZ",
|
"login": "WOG INZ",
|
||||||
"password": "SEEKRET",
|
"password": "SEEKRET",
|
||||||
"username": "USERNAEM",
|
"username": "USERNAEM",
|
||||||
|
@ -216,7 +216,10 @@
|
|||||||
"version": "Versija"
|
"version": "Versija"
|
||||||
},
|
},
|
||||||
"login": {
|
"login": {
|
||||||
|
"defaultPath": "Parole ko ievadijāt ir celš uz noklusētās paroles vietu, nevis noklusētā parole. Lūdzu apskatiet noklusēto paroli šajā vietā.",
|
||||||
|
"disabled": "Lietotāja konts atspējots. Lūdzu sazinieties ar savu sistēmas administratoru priekš papildus informācijas.",
|
||||||
"forgotPassword": "Aizmirsu Paroli",
|
"forgotPassword": "Aizmirsu Paroli",
|
||||||
|
"incorrect": "Nepareizs lietotājvārds vai parole",
|
||||||
"login": "Ieiet",
|
"login": "Ieiet",
|
||||||
"password": "Parole",
|
"password": "Parole",
|
||||||
"username": "Lietotājvārds",
|
"username": "Lietotājvārds",
|
||||||
|
@ -215,7 +215,10 @@
|
|||||||
"version": "Versie"
|
"version": "Versie"
|
||||||
},
|
},
|
||||||
"login": {
|
"login": {
|
||||||
|
"defaultPath": "Het ingevoerde wachtwoord is het pad naar de standaardreferentie, niet het wachtwoord zelf. Raadpleeg de standaardwachtwoord op de aangegeven locatie.",
|
||||||
|
"disabled": "Gebruikersaccount uitgeschakeld. Neem voor meer informatie contact op met uw systeembeheerder.",
|
||||||
"forgotPassword": "Wachtwoord vergeten",
|
"forgotPassword": "Wachtwoord vergeten",
|
||||||
|
"incorrect": "Verkeerde gebruikersnaam of wachtwoord",
|
||||||
"login": "Log In",
|
"login": "Log In",
|
||||||
"password": "Wachtwoord",
|
"password": "Wachtwoord",
|
||||||
"username": "gebruikersnaam",
|
"username": "gebruikersnaam",
|
||||||
|
@ -215,7 +215,10 @@
|
|||||||
"version": "Wersja"
|
"version": "Wersja"
|
||||||
},
|
},
|
||||||
"login": {
|
"login": {
|
||||||
|
"defaultPath": "Hasło które wprowadziłeś jest podstawową ścieżką w której przechowywane są dane logowania. Znajdź podstawowe hasło w tej lokalizacji.",
|
||||||
|
"disabled": "Konto tego użytkownika jest wyłączone. Skontaktuj się z administratorem by uzyskać więcej informacji.",
|
||||||
"forgotPassword": "Zapomniałem hasła",
|
"forgotPassword": "Zapomniałem hasła",
|
||||||
|
"incorrect": "Niepoprawny login lub hasło/Niepoprawna nazwa użytkownika lub hasło",
|
||||||
"login": "Zaloguj się",
|
"login": "Zaloguj się",
|
||||||
"password": "Hasło",
|
"password": "Hasło",
|
||||||
"username": "Nazwa użytkownika",
|
"username": "Nazwa użytkownika",
|
||||||
|
@ -215,7 +215,10 @@
|
|||||||
"version": "เวอร์ชั่น"
|
"version": "เวอร์ชั่น"
|
||||||
},
|
},
|
||||||
"login": {
|
"login": {
|
||||||
|
"defaultPath": "รหัสผ่านที่คุณกรอกคือเส้นทางข้อมูลเริ่มต้น ไม่ใช่รหัสผ่าน กรุณาค้นหารหัสผ่านเริ่มต้นในตำแหน่งนั้น",
|
||||||
|
"disabled": "บัญชีผู้ใช้ถูกปิดใช้งาน กรุณาติดต่อผู้ดูแลระบบของคุณสำหรับข้อมูลเพิ่มเติม",
|
||||||
"forgotPassword": "ลืมรหัสผ่าน",
|
"forgotPassword": "ลืมรหัสผ่าน",
|
||||||
|
"incorrect": "ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง",
|
||||||
"login": "เข้าสู่ระบบ",
|
"login": "เข้าสู่ระบบ",
|
||||||
"password": "รหัสผ่าน",
|
"password": "รหัสผ่าน",
|
||||||
"username": "ชื่อผู้ใช้",
|
"username": "ชื่อผู้ใช้",
|
||||||
|
@ -215,7 +215,10 @@
|
|||||||
"version": "Sürüm"
|
"version": "Sürüm"
|
||||||
},
|
},
|
||||||
"login": {
|
"login": {
|
||||||
|
"defaultPath": "Girdiğiniz şifre varsayılan şifrenin konumudur, varsayılan şifre değil. Lütfen o konumda bulunan varsayılan şifreyi bulunuz.",
|
||||||
|
"disabled": "Bu kullanıcı hesabı engellenmiştir. Daha fazla bilgi için lütfen sunucu yöneticiniz ile konuşunuz.",
|
||||||
"forgotPassword": "Şifremi Unuttum",
|
"forgotPassword": "Şifremi Unuttum",
|
||||||
|
"incorrect": "Kullanıcı adınız veya şifreniz yanlış.",
|
||||||
"login": "Oturum Aç",
|
"login": "Oturum Aç",
|
||||||
"password": "Şifre",
|
"password": "Şifre",
|
||||||
"username": "Kullanıcı Adı",
|
"username": "Kullanıcı Adı",
|
||||||
|
@ -85,7 +85,7 @@
|
|||||||
"cpuCurFreq": "Швидкість CPU",
|
"cpuCurFreq": "Швидкість CPU",
|
||||||
"cpuMaxFreq": "Максимальна швидкість CPU",
|
"cpuMaxFreq": "Максимальна швидкість CPU",
|
||||||
"cpuUsage": "Використання CPU",
|
"cpuUsage": "Використання CPU",
|
||||||
"crashed": "Аварійне завершення",
|
"crashed": "Краш",
|
||||||
"dashboard": "Панель",
|
"dashboard": "Панель",
|
||||||
"delay-explained": "Служба/агент нещодавно запущено та затримує запуск серверів minecraft",
|
"delay-explained": "Служба/агент нещодавно запущено та затримує запуск серверів minecraft",
|
||||||
"host": "Хост",
|
"host": "Хост",
|
||||||
@ -215,7 +215,10 @@
|
|||||||
"version": "Версія"
|
"version": "Версія"
|
||||||
},
|
},
|
||||||
"login": {
|
"login": {
|
||||||
|
"defaultPath": "Пароль, який ви ввели, є шляхом до облікових даних за умовчанням, а не паролем. Будь ласка, знайдіть стандартний пароль у цьому місці.",
|
||||||
|
"disabled": "Користувача вимкнено. Зверніться до вашого системного адміністратора за допомогою.",
|
||||||
"forgotPassword": "Забули пароль",
|
"forgotPassword": "Забули пароль",
|
||||||
|
"incorrect": "Неправильний логін або пароль",
|
||||||
"login": "Вхід",
|
"login": "Вхід",
|
||||||
"password": "Пароль",
|
"password": "Пароль",
|
||||||
"username": "Логін",
|
"username": "Логін",
|
||||||
@ -351,7 +354,7 @@
|
|||||||
"sendingRequest": "Надсилання вашого запиту...",
|
"sendingRequest": "Надсилання вашого запиту...",
|
||||||
"serverAutoStart": "Сервер Авто-старт",
|
"serverAutoStart": "Сервер Авто-старт",
|
||||||
"serverAutostartDelay": "Сервер Авто-старт затримка",
|
"serverAutostartDelay": "Сервер Авто-старт затримка",
|
||||||
"serverAutostartDelayDesc": "Затримка Авто-старту сервера (Якщо увімкнуто раніше)",
|
"serverAutostartDelayDesc": "Затримка Авто-старту сервера (Після запуску Crafty))",
|
||||||
"serverCrashDetection": "Детектор крашу сервера",
|
"serverCrashDetection": "Детектор крашу сервера",
|
||||||
"serverExecutable": "Виконуваний файл Серверу",
|
"serverExecutable": "Виконуваний файл Серверу",
|
||||||
"serverExecutableDesc": "Це виконуваний файл для запуску сервера",
|
"serverExecutableDesc": "Це виконуваний файл для запуску сервера",
|
||||||
@ -369,7 +372,7 @@
|
|||||||
"serverPortDesc": "Цей порт призначений для статистики Crafty",
|
"serverPortDesc": "Цей порт призначений для статистики Crafty",
|
||||||
"serverStopCommand": "Команда зупинки сервера",
|
"serverStopCommand": "Команда зупинки сервера",
|
||||||
"serverStopCommandDesc": "Команда яка буде надсилатись, щоб зупинити сервер",
|
"serverStopCommandDesc": "Команда яка буде надсилатись, щоб зупинити сервер",
|
||||||
"showStatus": "Показувати на публічній сторінці статус",
|
"showStatus": "Показувати статус на публічній сторінці",
|
||||||
"shutdownTimeout": "Час відклику зупинки",
|
"shutdownTimeout": "Час відклику зупинки",
|
||||||
"statsHint1": "Цей порт на якому працює сервер. Це потрібно лиш для того щоб Crafty міг виводити статистику для цього сервера.",
|
"statsHint1": "Цей порт на якому працює сервер. Це потрібно лиш для того щоб Crafty міг виводити статистику для цього сервера.",
|
||||||
"statsHint2": "Це не змінює порт вашого сервера. Ви мусите власноруч змінити налаштування в server.properties або іншому конфігураційному файлі.",
|
"statsHint2": "Це не змінює порт вашого сервера. Ви мусите власноруч змінити налаштування в server.properties або іншому конфігураційному файлі.",
|
||||||
@ -406,7 +409,7 @@
|
|||||||
"logs": "Логи",
|
"logs": "Логи",
|
||||||
"metrics": "Графік",
|
"metrics": "Графік",
|
||||||
"playerControls": "Керування Гравцями",
|
"playerControls": "Керування Гравцями",
|
||||||
"reset": "Повернутись нагору",
|
"reset": "Вниз",
|
||||||
"schedule": "Розклад",
|
"schedule": "Розклад",
|
||||||
"serverDetails": "Деталі сервера",
|
"serverDetails": "Деталі сервера",
|
||||||
"terminal": "Термінал"
|
"terminal": "Термінал"
|
||||||
|
@ -215,7 +215,10 @@
|
|||||||
"version": "版本"
|
"version": "版本"
|
||||||
},
|
},
|
||||||
"login": {
|
"login": {
|
||||||
|
"defaultPath": "您输入的密码是默认凭据的路径,不是其中的密码。请在此路径中找到默认密码。",
|
||||||
|
"disabled": "用户账号已禁用。请联系您的系统管理员以了解更多信息。",
|
||||||
"forgotPassword": "忘记密码",
|
"forgotPassword": "忘记密码",
|
||||||
|
"incorrect": "用户名或密码错误",
|
||||||
"login": "登录",
|
"login": "登录",
|
||||||
"password": "密码",
|
"password": "密码",
|
||||||
"username": "用户名",
|
"username": "用户名",
|
||||||
|
@ -4,7 +4,7 @@ argon2-cffi==23.1.0
|
|||||||
cached_property==1.5.2
|
cached_property==1.5.2
|
||||||
colorama==0.4.6
|
colorama==0.4.6
|
||||||
croniter==1.4.1
|
croniter==1.4.1
|
||||||
cryptography==42.0.2
|
cryptography==42.0.4
|
||||||
libgravatar==1.0.4
|
libgravatar==1.0.4
|
||||||
nh3==0.2.14
|
nh3==0.2.14
|
||||||
packaging==23.2
|
packaging==23.2
|
||||||
|
Loading…
Reference in New Issue
Block a user