Allow file paths with symbols for background

This commit is contained in:
Andrew 2023-01-18 14:35:35 -05:00
parent 71c5d46296
commit 0d85b55c06
7 changed files with 114 additions and 85 deletions

View File

@ -355,7 +355,7 @@ class AjaxHandler(BaseHandler):
elif page == "select_photo": elif page == "select_photo":
if exec_user["superuser"]: if exec_user["superuser"]:
photo = self.get_argument("photo", None) photo = urllib.parse.unquote(self.get_argument("photo", ""))
opacity = self.get_argument("opacity", 100) opacity = self.get_argument("opacity", 100)
self.controller.management.set_login_opacity(int(opacity)) self.controller.management.set_login_opacity(int(opacity))
if photo == "login_1.jpg": if photo == "login_1.jpg":

View File

@ -1,69 +1,82 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Crafty Controller</title>
<!-- plugins:css -->
<link rel="stylesheet" href="/static/assets/vendors/mdi/css/materialdesignicons.min.css">
<link rel="stylesheet" href="/static/assets/vendors/flag-icon-css/css/flag-icon.min.css">
<link rel="stylesheet" href="/static/assets/vendors/ti-icons/css/themify-icons.css">
<link rel="stylesheet" href="/static/assets/vendors/typicons/typicons.css">
<link rel="stylesheet" href="/static/assets/vendors/css/vendor.bundle.base.css">
<!-- endinject -->
<!-- Plugin css for this page -->
<!-- End Plugin css for this page -->
<!-- Layout styles -->
<link rel="stylesheet" href="/static/assets/css/dark/style.css">
<!-- End Layout styles -->
<link rel="shortcut icon" type="image/svg+xml" href="/static/assets/images/logo_small.svg">
<link rel="alternate icon" href="/static/assets/images/favicon.png" />
</head>
<body class="dark-theme">
<div class="container-scroller">
<div class="container-fluid page-body-wrapper full-page-wrapper">
<div class="content-wrapper d-flex align-items-center auth auth-bg-1 theme-one">
<div class="row w-100">
<div class="col-lg-4 mx-auto">
<div class="auto-form-wrapper"> <head>
<div class="text-center"> <!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Crafty Controller</title>
<!-- plugins:css -->
<link rel="stylesheet" href="/static/assets/vendors/mdi/css/materialdesignicons.min.css">
<link rel="stylesheet" href="/static/assets/vendors/flag-icon-css/css/flag-icon.min.css">
<link rel="stylesheet" href="/static/assets/vendors/ti-icons/css/themify-icons.css">
<link rel="stylesheet" href="/static/assets/vendors/typicons/typicons.css">
<link rel="stylesheet" href="/static/assets/vendors/css/vendor.bundle.base.css">
<!-- endinject -->
<!-- Plugin css for this page -->
<!-- End Plugin css for this page -->
<!-- Layout styles -->
<link rel="stylesheet" href="/static/assets/css/dark/style.css">
<!-- End Layout styles -->
<link rel="shortcut icon" type="image/svg+xml" href="/static/assets/images/logo_small.svg">
<link rel="alternate icon" href="/static/assets/images/favicon.png" />
</head>
<style>
.auth.auth-bg-1 {
background: url("../../static/assets/images/auth/{% raw data['background'] %}"),
url("../../static/assets/images/auth/login-1.jpg");
background-size: cover;
}
</style>
<body class="dark-theme">
<div class="container-scroller">
<div class="container-fluid page-body-wrapper full-page-wrapper">
<div class="content-wrapper d-flex align-items-center auth auth-bg-1 theme-one">
<div class="row w-100">
<div class="col-lg-4 mx-auto">
<div class="auto-form-wrapper">
<div class="text-center">
<img src="/static/assets/images/logo_long.svg"><br /><br /> <img src="/static/assets/images/logo_long.svg"><br /><br />
<div class="col-sm-12 grid-margin stretch-card"> <div class="col-sm-12 grid-margin stretch-card">
<div class="card card-statistics social-card google-card card-colored"> <div class="card card-statistics social-card google-card card-colored">
<div class="card-body"> <div class="card-body">
<h4 class="platform-name mb-3 mt-4 font-weight-semibold user-name">{{ translate('accessDenied', 'accessDenied', data['lang']) }}</h4> <h4 class="platform-name mb-3 mt-4 font-weight-semibold user-name">{{ translate('accessDenied',
<h5 class="headline font-weight-medium">{{ translate('accessDenied', 'noAccess', data['lang']) }}</h5> 'accessDenied', data['lang']) }}</h4>
<p class="mb-2 comment font-weight-light"> <h5 class="headline font-weight-medium">{{ translate('accessDenied', 'noAccess', data['lang']) }}
{{ translate('accessDenied', 'contactAdmin', data['lang']) }}<br /><br /> </h5>
<a class="d-inline font-weight-medium" href="https://discord.gg/9VJPhCE"> {{ translate('accessDenied', 'contact', data['lang']) }}</a> <p class="mb-2 comment font-weight-light">
</p> {{ translate('accessDenied', 'contactAdmin', data['lang']) }}<br /><br />
<a class="d-inline font-weight-medium" href="https://discord.gg/9VJPhCE"> {{
translate('accessDenied', 'contact', data['lang']) }}</a>
</p>
</div>
</div> </div>
</div> </div>
</div> </div>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
<!-- content-wrapper ends -->
</div> </div>
<!-- page-body-wrapper ends --> <!-- content-wrapper ends -->
</div> </div>
<!-- container-scroller --> <!-- page-body-wrapper ends -->
<!-- plugins:js --> </div>
<script src="/static/assets/vendors/js/vendor.bundle.base.js"></script> <!-- container-scroller -->
<!-- endinject --> <!-- plugins:js -->
<!-- inject:js --> <script src="/static/assets/vendors/js/vendor.bundle.base.js"></script>
<script src="/static/assets/js/shared/off-canvas.js"></script> <!-- endinject -->
<script src="/static/assets/js/shared/hoverable-collapse.js"></script> <!-- inject:js -->
<script src="/static/assets/js/shared/misc.js"></script> <script src="/static/assets/js/shared/off-canvas.js"></script>
<script src="/static/assets/js/shared/settings.js"></script> <script src="/static/assets/js/shared/hoverable-collapse.js"></script>
<script src="/static/assets/js/shared/todolist.js"></script> <script src="/static/assets/js/shared/misc.js"></script>
<!-- endinject --> <script src="/static/assets/js/shared/settings.js"></script>
</body> <script src="/static/assets/js/shared/todolist.js"></script>
<!-- endinject -->
</body>
</html> </html>

View File

@ -34,8 +34,8 @@
}}</h4> }}</h4>
{% if data['user_data']['hints'] %} {% if data['user_data']['hints'] %}
<span class="too_small" title="{{ translate('dashboard', 'cannotSee', data['lang']) }}" , <span class="too_small" title="{{ translate('dashboard', 'cannotSee', data['lang']) }}" ,
data-content="{{ translate('dashboard', 'cannotSeeOnMobile2', data['lang']) }}" , data-content="{{ translate('dashboard', 'cannotSeeOnMobile2', data['lang']) }}" ,
data-placement="top"></span> data-placement="top"></span>
{% end %} {% end %}
<!-- TODO: Translate the following --> <!-- TODO: Translate the following -->
<div><a class="nav-link" href="/panel/add_user"><i class="fas fa-plus-circle"></i> &nbsp; {{ <div><a class="nav-link" href="/panel/add_user"><i class="fas fa-plus-circle"></i> &nbsp; {{
@ -134,8 +134,8 @@
data['lang']) }}</h4> data['lang']) }}</h4>
{% if data['user_data']['hints'] %} {% if data['user_data']['hints'] %}
<span class="too_small2" title="{{ translate('dashboard', 'cannotSee', data['lang']) }}" , <span class="too_small2" title="{{ translate('dashboard', 'cannotSee', data['lang']) }}" ,
data-content="{{ translate('dashboard', 'cannotSeeOnMobile2', data['lang']) }}" , data-content="{{ translate('dashboard', 'cannotSeeOnMobile2', data['lang']) }}" ,
data-placement="top"></span> data-placement="top"></span>
{% end %} {% end %}
<div><a class="nav-link" href="/panel/add_role"><i class="fas fa-plus-circle"></i> &nbsp; {{ <div><a class="nav-link" href="/panel/add_role"><i class="fas fa-plus-circle"></i> &nbsp; {{
translate('panelConfig', 'newRole', data['lang']) }}</a></div> translate('panelConfig', 'newRole', data['lang']) }}</a></div>
@ -244,18 +244,20 @@
{% raw xsrf_form_html() %} {% raw xsrf_form_html() %}
<input type="hidden" value="import_zip" name="create_type"> <input type="hidden" value="import_zip" name="create_type">
<div class="col form-group"> <div class="col form-group">
<span id="upload_input"><input type="file" class="form-control-file" id="file" name="file" multiple="false" required></span> <span id="upload_input"><input type="file" class="form-control-file" id="file" name="file"
multiple="false" required></span>
</div> </div>
<div class="col form-group"> <div class="col form-group">
<button type="button" class="btn btn-info" id="upload-button" onclick="sendFile()" disabled>UPLOAD</button> <button type="button" class="btn btn-info" id="upload-button" onclick="sendFile()"
disabled>UPLOAD</button>
</div> </div>
</form> </form>
<hr> <hr>
<hr /> <hr />
<h4>{{ translate('panelConfig', 'loginBackground', data['lang']) }}</h4> <h4>{{ translate('panelConfig', 'loginBackground', data['lang']) }}</h4>
<form id="try_photo_form"> <form id="try_photo_form">
<select class="form-select form-control form-control-lg select-css" id="try_photo" name="try_photo" <select class="form-select form-control form-control-lg select-css" id="try_photo"
form="try_photo" onchange="updateBackgroundSelect()"> name="try_photo" form="try_photo" onchange="updateBackgroundSelect()">
{% for image in data["backgrounds"] %} {% for image in data["backgrounds"] %}
<option value="{{image}}">{{image}}</option> <option value="{{image}}">{{image}}</option>
{% end %} {% end %}
@ -271,8 +273,8 @@
<div class="form-group row"> <div class="form-group row">
<label for="photo" class="col-sm-6 col-form-label">Selected Background Image</label> <label for="photo" class="col-sm-6 col-form-label">Selected Background Image</label>
<div class="col-sm-6"> <div class="col-sm-6">
<select class="form-select form-control form-control-lg select-css form-control-plaintext" id="photo" name="photo" <select class="form-select form-control form-control-lg select-css form-control-plaintext"
form="photo_form" onchange="updateBackgroundPreview()"> id="photo" name="photo" form="photo_form" onchange="updateBackgroundPreview()">
{% for image in data["backgrounds"] %} {% for image in data["backgrounds"] %}
<option value="{{image}}">{{image}}</option> <option value="{{image}}">{{image}}</option>
{% end %} {% end %}
@ -281,18 +283,23 @@
</div> </div>
<div id="photo_loading" class="form-group" hidden> <div id="photo_loading" class="form-group" hidden>
<div class="progress"> <div class="progress">
<div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" style="width: 100%">&nbsp;<i class="fa-solid fa-spinner"></i></div> <div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar"
aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" style="width: 100%">&nbsp;<i
class="fa-solid fa-spinner"></i></div>
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-3" for="formControlRange">{{ translate('panelConfig', 'loginOpacity', data['lang']) }}</label> <label class="col-sm-3" for="formControlRange">{{ translate('panelConfig', 'loginOpacity',
data['lang']) }}</label>
<label class="col-sm-1" id="opacityValue">{{ data['login_opacity'] }}%</label> <label class="col-sm-1" id="opacityValue">{{ data['login_opacity'] }}%</label>
<div class="range col-sm-8"> <div class="range col-sm-8">
<input type="range" class="form-control-range" id="modal_opacity" name="modal_opacity" onchange="previewOpacity()" min="0" max="100" value="{{ data['login_opacity'] }}"> <input type="range" class="form-control-range" id="modal_opacity" name="modal_opacity"
onchange="previewOpacity()" min="0" max="100" value="{{ data['login_opacity'] }}">
</div> </div>
</div> </div>
<div id="login_preview" style="position: relative;"> <div id="login_preview" style="position: relative;">
<img id="bg-preview" src="../../static/assets/images/auth/{{ data['background'] }}" class="img-fluid" alt="Responsive image"> <img id="bg-preview" src="../../static/assets/images/auth/{{ data['background'] }}"
class="img-fluid" alt="Responsive image">
<div id="login-form-preview"> <div id="login-form-preview">
<div id="login-form-background" class="auto-form-wrapper login-modal"> <div id="login-form-background" class="auto-form-wrapper login-modal">
<div class="text-center auto-form-logo"> <div class="text-center auto-form-logo">
@ -356,21 +363,25 @@
</style> </style>
<div id="login_form_data"> <div id="login_form_data">
<input type="hidden" name="_xsrf" value="2|1d603267|809fb6bd82f677d440e484dde7c3a310|1671726040" disabled> <input type="hidden" name="_xsrf"
value="2|1d603267|809fb6bd82f677d440e484dde7c3a310|1671726040" disabled>
<div class="form-group"> <div class="form-group">
<label class="label">Username</label> <label class="label">Username</label>
<div class="input-group"> <div class="input-group">
<input type="text" class="form-control login-text-input login-input" placeholder="Username" name="username" id="username" required="true" disabled> <input type="text" class="form-control login-text-input login-input"
placeholder="Username" name="username" id="username" required="true" disabled>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="label">Password</label> <label class="label">Password</label>
<div class="input-group"> <div class="input-group">
<input type="password" class="form-control login-text-input login-input" placeholder="Password" name="password" id="password" required="true" disabled> <input type="password" class="form-control login-text-input login-input"
placeholder="Password" name="password" id="password" required="true" disabled>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<button class="login-input btn btn-primary submit-btn btn-block" disabled>Log In</button> <button class="login-input btn btn-primary submit-btn btn-block" disabled>Log
In</button>
</div> </div>
<fieldset style="color: red; text-align: center;"> <fieldset style="color: red; text-align: center;">
@ -384,7 +395,8 @@
<a href="#" class="text-small forgot-password" disabled>Forgot Password</a> <a href="#" class="text-small forgot-password" disabled>Forgot Password</a>
</div> </div>
<div class="text-block text-center my-3"> <div class="text-block text-center my-3">
<span class="text-small font-weight-semibold"><a href="https://craftycontrol.com/">Crafty Control <span class="text-small font-weight-semibold"><a
href="https://craftycontrol.com/">Crafty Control
4.0.20</a> </span> 4.0.20</a> </span>
</div> </div>
</div> </div>
@ -392,9 +404,11 @@
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<button class="btn btn-outline-success select-photo" type="button">{{ translate('panelConfig', <button class="btn btn-outline-success select-photo" type="button">{{
translate('panelConfig',
'apply', data['lang']) }}</button> 'apply', data['lang']) }}</button>
<button class="btn btn-outline-danger delete-photo" type="button">{{ translate('panelConfig', <button class="btn btn-outline-danger delete-photo" type="button">{{
translate('panelConfig',
'cancel', data['lang']) }}</button> 'cancel', data['lang']) }}</button>
</div> </div>
</form> </form>
@ -508,10 +522,12 @@
var token = getCookie("_xsrf") var token = getCookie("_xsrf")
let photo = $('#photo').find(":selected").val(); let photo = $('#photo').find(":selected").val();
let opacity = $('#modal_opacity').val(); let opacity = $('#modal_opacity').val();
let enc_photo = encodeURIComponent(photo);
$.ajax({ $.ajax({
type: "POST", type: "POST",
headers: { 'X-XSRFToken': token }, headers: { 'X-XSRFToken': token },
url: '/ajax/select_photo?photo=' + photo + '&opacity=' + opacity, url: '/ajax/select_photo?photo=' + enc_photo + '&opacity=' + opacity,
success: function (data) { success: function (data) {
window.location.reload(); window.location.reload();
}, },

View File

@ -23,7 +23,7 @@
</head> </head>
<style> <style>
.auth.auth-bg-1 { .auth.auth-bg-1 {
background: url("../../static/assets/images/auth/{{data['background']}}"), background: url("../../static/assets/images/auth/{% raw data['background'] %}"),
url("../../static/assets/images/auth/login-1.jpg"); url("../../static/assets/images/auth/login-1.jpg");
background-size: cover; background-size: cover;
} }

View File

@ -23,7 +23,7 @@
</head> </head>
<style> <style>
.auth.auth-bg-1 { .auth.auth-bg-1 {
background: url("../../static/assets/images/auth/{{data['background']}}"), background: url("../../static/assets/images/auth/{% raw data['background'] %}"),
url("../../static/assets/images/auth/login-1.jpg"); url("../../static/assets/images/auth/login-1.jpg");
background-size: cover; background-size: cover;
} }

View File

@ -23,7 +23,7 @@
</head> </head>
<style> <style>
.auth.auth-bg-1 { .auth.auth-bg-1 {
background: url("../../static/assets/images/auth/{{data['background']}}"), background: url("../../static/assets/images/auth/{% raw data['background'] %}"),
url("../../static/assets/images/auth/login-1.jpg"); url("../../static/assets/images/auth/login-1.jpg");
background-size: cover; background-size: cover;
} }
@ -79,16 +79,16 @@
<label class="label">{{ translate('login', 'username', data['lang']) }}</label> <label class="label">{{ translate('login', 'username', data['lang']) }}</label>
<div class="input-group"> <div class="input-group">
<input type="text" class="form-control login-text-input login-input" <input type="text" class="form-control login-text-input login-input"
placeholder="{{ translate('login', 'username', data['lang']) }}" name="username" id="username" placeholder="{{ translate('login', 'username', data['lang']) }}" name="username" id="username"
required="true"> required="true">
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="label">{{ translate('login', 'password', data['lang']) }}</label> <label class="label">{{ translate('login', 'password', data['lang']) }}</label>
<div class="input-group"> <div class="input-group">
<input type="password" class="form-control login-text-input login-input" <input type="password" class="form-control login-text-input login-input"
placeholder="{{ translate('login', 'password', data['lang']) }}" name="password" id="password" placeholder="{{ translate('login', 'password', data['lang']) }}" name="password" id="password"
required="true"> required="true">
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">

View File

@ -9,7 +9,7 @@
<!-- View for Large screen --> <!-- View for Large screen -->
<style> <style>
.auth.auth-bg-1 { .auth.auth-bg-1 {
background: url("../../static/assets/images/auth/{{data['background']}}"), background: url("../../static/assets/images/auth/{% raw data['background'] %}"),
url("../../static/assets/images/auth/login-1.jpg"); url("../../static/assets/images/auth/login-1.jpg");
background-size: cover; background-size: cover;
} }