Добавляем все файлы

This commit is contained in:
2025-11-06 19:41:55 +02:00
parent 235d6a3a18
commit 2e5aaec307
218 changed files with 79015 additions and 0 deletions

88
main_plugin/auth/auth.css Executable file
View File

@@ -0,0 +1,88 @@
#authorizationButton {
width: 26px;
height: 26px;
position: relative;
cursor: pointer;
user-select: none;
float: right;
margin-left: 5px;
}
#authorizationButton:hover {
background-image: url(../../img/pict/g_iconslyb.svg);
}
#loginButton {
margin: 0px 3px;
}
#authorizationDiv {
font-size: 0.85em;
display: inline-block;
position: fixed;
user-select: none;
background-color: rgba(255, 255, 255, 0.92);
width: 370px;
border-radius: 5px;
height: 230px;
box-shadow: 0px 0px 5px #777;
color: #000000;
text-shadow: none;
z-index: 100;
min-height: fit-content;
}
#authorizationDiv input, #authorizationDiv textarea, #authorizationDiv select, #authorizationDiv button {
font-size: 0.85em;
}
.authorizationDivTop {
text-align: center;
border: none;
border-bottom: inherit;
padding: 5px;
background-color: rgba(255, 255, 255, 0.6);
}
.authorizationDivCloseFun {
background-image: url(../../img/pict/b_iconslyb.svg);
float: right;
width: 22px;
height: 22px;
background-position: -159px -120px;
cursor: pointer;
}
.authorizationDivMainDiv {
display: flex;
align-items: center;
height: 200px;
justify-content: center;
flex-direction: column;
padding: 10px 0px;
}
.formRow {
display: flex;
justify-content: center;
width: -webkit-fill-available;
margin: 5px 45px;
}
.formRow label {
margin-right: 10px;
white-space: nowrap;
}
.formRow input {
flex: 1;
min-width: 0;
}
#BackArrow {
background-position: -77px -37px;
background-image: url(../../img/pict/b_iconslyb.svg);
width: 26px;
height: 26px;
position: absolute;
left: 0px;
top: 33px;
}
#BackArrow:hover {
background-image: url(../../img/pict/g_iconslyb.svg);
cursor: pointer;
}

161
main_plugin/auth/auth.js Executable file
View File

@@ -0,0 +1,161 @@
/**
* @file auth.js
* @brief Скрипт авторизации, содержит функции и переменные для входа, регистрации и управления блоком авторизации
*/
addEventListener("load", function() {
movementMenu("authorizationDiv");
let authorizationButtonId = document.getElementById("authorizationButton");
const authorizationDivId = document.getElementById("authorizationDiv");
if (getCookie('Login') == "true") {
authorizationButtonId.style.background = "url(../../img/pict/mc_iconslyb.svg) -1038px 1px";
document.documentElement.style.setProperty('--autButBackX', '-1038');
document.documentElement.style.setProperty('--autButBackY', '1');
authorizationButtonId.onclick = function() {
jsonrpcRequest("logoutUser", { logoff: "Выйти" })
.then(response => {
location.reload();
})
};
} else if (getCookie('Login') == "false") {
authorizationButtonId.style.background = "url(../../img/pict/mc_iconslyb.svg) -756px 1px";
document.documentElement.style.setProperty('--autButBackX', '-756');
document.documentElement.style.setProperty('--autButBackY', '1');
authorizationButtonId.onclick = function() {
const el = authorizationDivId;
if (el.style.visibility === "visible") {
el.style.visibility = "hidden";
} else {
el.style.visibility = "visible";
el.style.top = "20%";
el.style.left = "50%";
el.style.transform = "translate(-50%, -20%)";
}
};
}
});
/**
* @brief Закрывает блок авторизации
*/
function authorizationDivCloseFun() {
document.getElementById("authorizationDiv").style.visibility = "hidden";
}
/**
* @brief Создаёт форму кнопки входа
*/
function loginButtonFunCreate() {
document.querySelector(".authorizationDivMainDiv").innerHTML = `
<div id="BackArrow" onClick="mainButtonFunCreate()"></div>
<div class="formRow">
<label>{{login_label}}:</label>
<input type="text" id="loginInput" name="login">
</div>
<div class="formRow">
<label>{{password_label}}:</label>
<input type="password" id="passInput" name="pass" autocomplete="">
</div>
<div class="formRow">
<button type="button" id="loginButton" onClick="loginButtonFun()">{{login}}</button>
</div>
`;
const inputLogin = document.getElementById('loginInput');
const inputPass = document.getElementById('passInput');
const loginBtn = document.getElementById('loginButton');
[inputLogin, inputPass].forEach(input => {
input.addEventListener('keydown', function(e) {
if (e.key === 'Enter') {
if (loginBtn.getAttribute('onClick') === 'loginButtonFun()') {
loginBtn.click();
}
}
});
});
}
/**
* @brief Обрабатывает нажатие кнопки входа
*/
function loginButtonFun() {
var login = document.getElementById("loginInput").value;
var pass = document.getElementById("passInput").value;
jsonrpcRequest("loginUser", { login: login, pass: pass, log: "Войти" })
.then(response => {
if (response == "true") {
location.reload();
} else {
messageFunction("{{incorrect_login_password}}");
}
});
}
/**
* @brief Создаёт форму кнопки регистрации
*/
function registrationButtonFunCreate() {
document.querySelector(".authorizationDivMainDiv").innerHTML = `
<div id="BackArrow" onClick="mainButtonFunCreate()"></div>
<div class="formRow">
<label>{{login_label}}:</label>
<input type="text" id="loginInput" name="login">
</div>
<div class="formRow">
<label>{{password_label}}:</label>
<input type="text" id="passInput" name="pass">
</div>
<div class="formRow">
<label>{{repeat_password_label}}:</label>
<input type="text" id="passСheckInput" name="pass">
</div>
<div class="formRow">
<label>{{email_label}}:</label>
<input id="emailInput">
</div>
<div class="formRow">
<button type="button" id="loginButton" onClick="registrationButtonFun()">{{register}}</button>
</div>
`;
}
/**
* @brief Обрабатывает нажатие кнопки регистрации
*/
function registrationButtonFun() {
var login = document.getElementById("loginInput").value;
var pass = document.getElementById("passInput").value;
var passСheck = document.getElementById("passСheckInput").value;
var email = document.getElementById("emailInput").value;
if (login.trim() == "" || pass.trim() == "" || passСheck.trim() == "" || email.trim() == "" ) {
messageFunction("{{fill_all_fields}}");
return;
}
if (pass != passСheck) {
messageFunction("{{passwords_do_not_match}}");
return;
}
jsonrpcRequest("registerUser", { login: login, pass: pass, email: email }).then(response => {
if (response == "true") {
messageFunction("{{account_creation_request_sent}}");
} else if (response == "name_exists") {
messageFunction("{{user_exists}}");
} else {
messageFunction("{{account_creation_request_error}}");
}
});
}
/**
* @brief Создаёт главную форму выбора между входом и регистрацией
*/
function mainButtonFunCreate() {
document.querySelector(".authorizationDivMainDiv").innerHTML = `
<div class="formRow">{{account_authorization}}</div>
<div class="formRow">
<button type="button" id="loginButton" onClick="loginButtonFunCreate()">{{login}}</button>
<button type="button" id="loginButton" onClick="registrationButtonFunCreate()">{{register}}</button>
</div>
`;
}

43
main_plugin/auth/auth.php Executable file
View File

@@ -0,0 +1,43 @@
<?php
/**
* @file auth.php
* @brief Содержит интерфейс авторизации пользователя
*/
?>
<?php /** @brief Кнопка вызова окна авторизации */ $authorizationButton; ?>
<span id="authorizationButton"></span>
<?php /** @brief Основной контейнер окна авторизации */ $authorizationDiv; ?>
<div id="authorizationDiv" class="borderStyle" style="visibility: hidden; top: 20%; left: 50%; transform: translate(-50%, -20%);">
<div class="authorizationDivTop" class="borderStyle">
<span class="authorizationDivTopTitle">{{authorization}}</span>
<span class="authorizationDivCloseFun" onClick="authorizationDivCloseFun()" class="editib"></span>
</div>
<div class="authorizationDivMainDiv">
<div class="formRow">{{account_authorization}}</div>
<div class="formRow">
<button type="button" id="loginButton" onClick="loginButtonFunCreate()">{{login}}</button>
<button type="button" id="loginButton" onClick="registrationButtonFunCreate()">{{register}}</button>
</div>
</div>
</div>
<script>
window.addEventListener("load", function() {
try {
var buttonHTML = document.getElementById("authorizationButton").outerHTML;
var divHTML = document.getElementById("authorizationDiv").outerHTML;
document.getElementById("authorizationButton").remove();
document.getElementById("authorizationDiv").remove();
var container = document.getElementById("hbody");
if (!container) throw new Error("#hbody не найден для authorization");
container.insertAdjacentHTML("beforeend", buttonHTML);
container.insertAdjacentHTML("beforeend", divHTML);
} catch (e) {
console.error("Ошибка в блоке authorization:", e);
}
});
</script>

82
main_plugin/auth/func.auth.php Executable file
View File

@@ -0,0 +1,82 @@
<?php
/**
* @file func.auth.php
* @brief Функции для регистрации пользователей и отправки уведомлений по email
*/
/**
* @brief Регистрирует нового пользователя
* @param array $params Массив с ключами 'login', 'pass', 'email'
* @return string "name_exists" если пользователь уже есть, "true" если регистрация прошла успешно
* @throws Exception Если произошла ошибка при создании запроса на регистрацию
*/
function registerUser($params) {
global $path, $config;
$exists = false;
$requestFile = simplexml_load_file($path . $config['usersRequest']);
foreach ($requestFile->users->user as $child) {
if ((string)$child['name'] === $params['login']) {
$exists = true;
break;
}
}
$usersFile = simplexml_load_file($path . $config['users']);
foreach ($usersFile->users->user as $child) {
if ((string)$child['name'] === $params['login']) {
$exists = true;
break;
}
}
if ($exists) {
return "name_exists";
} else {
$requestFile = simplexml_load_file($path . $config['usersRequest']);
$requestFilePath = $path . $config['usersRequest'];
$newUser = $requestFile->users->addChild('user');
$newUser->addAttribute('name', $params['login']);
$newUser->addAttribute('pass', $params['pass']);
$newUser->addAttribute('access', '');
$newUser->addAttribute('email', $params['email']);
$newUser->addAttribute('link', md5($params['login'].$params['pass']));
$dom = new DOMDocument('1.0', 'UTF-8');
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadXML($requestFile->asXML());
if ($dom->save($requestFilePath)) {
return sendRegistrationEmail($params);
} else {
throw new Exception("Error while creating user request", -32003);
}
}
}
/**
* @brief Отправляет уведомление о регистрации пользователю и администратору
* @param array $paramsEmail Массив с ключами 'login', 'pass', 'email'
* @return string "true" при успешной отправке
* @throws Exception Если произошла ошибка при отправке email
*/
function sendRegistrationEmail($paramsEmail) {
global $config;
$to = $config['emailAdmin'];
$subject = '=?UTF-8?B?'.base64_encode('Запрос на создание аккаунта на сайте ').'?=' . $_SERVER['HTTP_HOST'];
$message = 'Логин: ' . $paramsEmail['login'] . "\r\n";
$message .= 'Пароль: ' . $paramsEmail['pass'] . "\r\n";
$message .= 'Почта: ' . $paramsEmail['email'] . "\r\n";
$message .= 'Сайт: ' . $config['server'] . "\r\n";
$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type: text/html; charset=UTF-8" . "\r\n";
$headers .= "From: info@oblat.lv";
if (!mail($to, $subject, $message, $headers)) {
throw new Exception("Error sending email", -32002);
}
return "true";
}
?>

23
main_plugin/auth/lang.js.php Executable file
View File

@@ -0,0 +1,23 @@
<?php
/**
* @file lang.js.php
* @brief Генерирует JavaScript-файл с языковыми строками для плагина авторизации
*/
global $path, $_SESSION;
/** @brief Загружает языковой массив для плагина авторизации */
$lang = include $path . 'lang.php';
/** @brief Определяет текущий язык пользователя, берется из GET-параметра или сессии, по умолчанию 'en' */
$lng = $_GET['lng'] ?? ($_SESSION['lng'] ?? 'en');
/** @brief Массив для подстановки языковых строк в шаблон JS */
$placeholders = [];
foreach ($lang[$lng] as $key => $value) {
$placeholders['{{' . $key . '}}'] = $value;
}
echo strtr(file_get_contents($path . 'auth.js'), $placeholders);
?>

61
main_plugin/auth/lang.php Executable file
View File

@@ -0,0 +1,61 @@
<?php
$lang = [
'ru' => [
'authorization' => 'Авторизация',
'login_label' => 'Логин',
'password_label' => 'Пароль',
'incorrect_login_password' => 'Неверный логин или пароль!',
'repeat_password_label' => 'Повторите пароль',
'email_label' => 'Почта',
'fill_all_fields' => 'Вы должны заполнить все поля!',
'passwords_do_not_match' => 'Пароли не совпадают!',
'account_creation_request_sent' => 'Запрос на создание аккаунта отправлен!',
'user_exists' => 'Пользователь с таким логином уже существует!',
'account_creation_error' => 'Ошибка при создании аккаунта!',
'incorrect_email' => 'Вы ввели неправильную почту!',
'account_creation_request_error' => 'Ошибка при отправке запроса на создание аккаунта!',
'account_authorization' => 'Авторизация аккаунта',
'login' => 'Войти',
'register' => 'Зарегистрироваться',
'logoff' => 'Выйти',
],
'en' => [
'authorization' => 'Authorization',
'login_label' => 'Login',
'password_label' => 'Password',
'incorrect_login_password' => 'Incorrect login or password!',
'repeat_password_label' => 'Repeat password',
'email_label' => 'Email',
'fill_all_fields' => 'You must fill out all fields!',
'passwords_do_not_match' => 'Passwords do not match!',
'account_creation_request_sent' => 'Account creation request sent!',
'user_exists' => 'User with this login already exists!',
'account_creation_error' => 'Error while creating the account!',
'incorrect_email' => 'Incorrect email!',
'account_creation_request_error' => 'Error sending account creation request!',
'account_authorization' => 'Account authorization',
'login' => 'Login',
'register' => 'Register',
'logoff' => 'Log out',
],
'lv' => [
'authorization' => 'Autentifikācija',
'login_label' => 'Lietotājvārds',
'password_label' => 'Parole',
'incorrect_login_password' => 'Nepareizs lietotājvārds vai parole!',
'repeat_password_label' => 'Atkārtot paroli',
'email_label' => 'E-pasts',
'fill_all_fields' => 'Jums jāaizpilda visi lauki!',
'passwords_do_not_match' => 'Paroles nesakrīt!',
'account_creation_request_sent' => 'Pieprasījums par konta izveidi nosūtīts!',
'user_exists' => 'Lietotājs ar šo lietotājvārdu jau pastāv!',
'account_creation_error' => 'Kļūda, izveidojot kontu!',
'incorrect_email' => 'Nepareizs e-pasts!',
'account_creation_request_error' => 'Kļūda, nosūtot pieprasījumu par konta izveidi!',
'account_authorization' => 'Konta autentifikācija',
'login' => 'Ieiet',
'register' => 'Reģistrēties',
'logoff' => 'Iziet',
],
];
return $lang;

27
main_plugin/auth/plug.php Executable file
View File

@@ -0,0 +1,27 @@
<?php
/**
* @file plug.php
* @brief Подключает плагин авторизации, подставляет языковые строки и выводит HTML-код формы авторизации
*/
global $path, $_SESSION;
/** @brief Загружает языковой массив для плагина авторизации */
$lang = include $path . 'main_plugin/auth/lang.php';
/** @brief Определяет текущий язык пользователя, по умолчанию 'en' */
$lng = $_SESSION['lng'] ?? 'en';
include_once $path . 'main_plugin/auth/func.auth.php';
/** @brief Загружает HTML-шаблон формы авторизации */
$Html = file_get_contents($path . 'main_plugin/auth/auth.php');
foreach ($lang[$lng] as $key => $value) {
$Html = str_replace('{{' . $key . '}}', $value, $Html);
}
echo $Html;
echo '<link rel="stylesheet" type="text/css" href="/main_plugin/auth/auth.css">';
echo '<script type="text/javascript" src="/main_plugin/auth/lang.js.php?lng=' . $lng . '"></script>';
?>