From 5279a9a6a6ba6a11191a20379741b31a6bac7f22 Mon Sep 17 00:00:00 2001 From: TolaMironcenko Date: Wed, 26 Jun 2024 15:59:10 +0700 Subject: [PATCH] added telnet and reboot control, openrouterinit script --- .vscode/settings.json | 79 ++++++++++++++++++ CMakeLists.txt | 4 +- openrouterinit | 35 ++++++++ src/openrouter.cpp | 10 ++- src/reboot/reboot.cpp | 35 ++++++++ src/reboot/reboot.hpp | 8 ++ src/routes.hpp | 6 ++ src/settings/telnet/telnet.cpp | 99 ++++++++++++++++++++++ src/settings/telnet/telnet.hpp | 9 ++ src/types.hpp | 10 +++ src/web/css/button.css | 19 +++++ src/web/css/form.css | 18 ++++ src/web/css/header.css | 20 +++++ src/web/css/index.css | 15 +++- src/web/css/loader.css | 64 +++++++++++++++ src/web/css/notification.css | 43 ++++++++++ src/web/css/settings.css | 146 +++++++++++++++++++++++++++++++++ src/web/index.html | 78 +++++++++++++++++- src/web/js/login.js | 45 ++++++---- src/web/js/notification.js | 23 ++++++ src/web/js/reboot.js | 42 ++++++++++ src/web/js/routes.js | 10 ++- src/web/js/settings/telnet.js | 47 +++++++++++ 23 files changed, 839 insertions(+), 26 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 openrouterinit create mode 100644 src/reboot/reboot.cpp create mode 100644 src/reboot/reboot.hpp create mode 100644 src/routes.hpp create mode 100644 src/settings/telnet/telnet.cpp create mode 100644 src/settings/telnet/telnet.hpp create mode 100644 src/types.hpp create mode 100644 src/web/css/button.css create mode 100644 src/web/css/header.css create mode 100644 src/web/css/loader.css create mode 100644 src/web/css/notification.css create mode 100644 src/web/css/settings.css create mode 100644 src/web/js/notification.js create mode 100644 src/web/js/reboot.js create mode 100644 src/web/js/settings/telnet.js diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..5c23b9e --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,79 @@ +{ + "files.associations": { + "any": "cpp", + "array": "cpp", + "atomic": "cpp", + "bit": "cpp", + "*.tcc": "cpp", + "bitset": "cpp", + "cctype": "cpp", + "charconv": "cpp", + "chrono": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "codecvt": "cpp", + "compare": "cpp", + "concepts": "cpp", + "condition_variable": "cpp", + "csignal": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "forward_list": "cpp", + "list": "cpp", + "map": "cpp", + "set": "cpp", + "string": "cpp", + "unordered_map": "cpp", + "unordered_set": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "optional": "cpp", + "random": "cpp", + "ratio": "cpp", + "regex": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "format": "cpp", + "fstream": "cpp", + "initializer_list": "cpp", + "iomanip": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "limits": "cpp", + "mutex": "cpp", + "new": "cpp", + "numbers": "cpp", + "ostream": "cpp", + "ranges": "cpp", + "semaphore": "cpp", + "span": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "stop_token": "cpp", + "streambuf": "cpp", + "text_encoding": "cpp", + "thread": "cpp", + "cinttypes": "cpp", + "typeinfo": "cpp", + "valarray": "cpp", + "variant": "cpp" + } +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 8cf3aca..99e41fa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required (VERSION 2.6) project(openrouter) -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) include_directories(./src/libs/) @@ -8,4 +8,6 @@ add_executable( openrouter src/openrouter.cpp src/security/cors.cpp + src/settings/telnet/telnet.cpp + src/reboot/reboot.cpp ) diff --git a/openrouterinit b/openrouterinit new file mode 100644 index 0000000..7119359 --- /dev/null +++ b/openrouterinit @@ -0,0 +1,35 @@ +#!/bin/sh +Green='\033[0;32m' +Color_Off='\033[0m' +Red='\033[0;31m' + +case "$1" in + start) + printf "Starting openrouter software " + cd /srv/ftpd/auth_service_router/bin && ./auth_service &> /dev/null & + cd /srv/ftpd/openrouter_adminpanel/bin && ./openrouter &> /dev/null & + if [[ "$?" == "0" ]]; then + printf "[$Green OK $Color_Off]\n" + else + printf "[$Red ERR $Cpolor_Off]\n" + fi + ;; + stop) + printf "Stopping openrouter software " + killall openrouter + killall auth_service + if [[ "$?" == "0" ]]; then + printf "[$Green OK $Color_Off]\n" + else + printf "[$Red ERR $Color_Off]\n" + fi + ;; + restart|reload) + "$0" stop + "$0" start + ;; + *) + echo "httpd init script usage: $0 {start|stop|restart}" + return 1 +esac +return $? \ No newline at end of file diff --git a/src/openrouter.cpp b/src/openrouter.cpp index d89b2f1..cd5b58f 100644 --- a/src/openrouter.cpp +++ b/src/openrouter.cpp @@ -1,6 +1,8 @@ #include #include #include +#include "settings/telnet/telnet.hpp" +#include "reboot/reboot.hpp" #define CORS_ENABLE #include "security/cors.hpp" @@ -8,6 +10,10 @@ int main() { httplib::Server srv; + srv.Post("/api/settings/telnet/get", get_telnet); + srv.Post("/api/settings/telnet/set", set_telnet); + srv.Post("/api/reboot", reboot); + srv.Options("/(.*)", set_cors_headers); srv.set_mount_point("/" , "../src/web"); @@ -15,8 +21,8 @@ int main() { srv.set_mount_point("/css", "../src/web/css"); std::cout << GREEN << "Starting" << RESET << " server on [ " << YELLOW - << "localhost" << RESET << ":" << CYAN << "43243" << RESET << " ]" << std::endl; + << "0.0.0.0" << RESET << ":" << CYAN << "43244" << RESET << " ]" << std::endl; - srv.listen("localhost", 43244); + srv.listen("0.0.0.0", 43244); return 0; } diff --git a/src/reboot/reboot.cpp b/src/reboot/reboot.cpp new file mode 100644 index 0000000..437384d --- /dev/null +++ b/src/reboot/reboot.cpp @@ -0,0 +1,35 @@ +#include "reboot.hpp" +#include +#include "../routes.hpp" +#include +#include "../types.hpp" + +void reboot(const httplib::Request &request, httplib::Response &response) { + std::cout << GREEN << request.path << RESET << " " << request.method << std::endl; + response.set_header("Access-Control-Allow-Origin", "*"); + if (request.body.empty()) { + response.set_content(ACCESS_REQUIRED_STRING, JSON_TYPE); + return; + } + + nlohmann::json json_body = nlohmann::json::parse(request.body); + if (json_body["token"] == nullptr) { + response.set_content(ACCESS_REQUIRED_STRING, JSON_TYPE); + return; + } + + httplib::Client cli(AUTH_SERVICE); + + std::stringstream body; + body << R"({"token":)" << json_body["token"] << R"(})"; + + httplib::Result res = cli.Post("/api/access", body.str().c_str(), JSON_TYPE); + if (res->status == httplib::OK_200) { + nlohmann::json resjson = nlohmann::json::parse(res->body); + if (resjson["access"] == "reject") { + response.set_content(resjson.dump().c_str(), JSON_TYPE); + return; + } + system("reboot"); + } +} diff --git a/src/reboot/reboot.hpp b/src/reboot/reboot.hpp new file mode 100644 index 0000000..4ad585b --- /dev/null +++ b/src/reboot/reboot.hpp @@ -0,0 +1,8 @@ +#ifndef REBOOT_HPP +#define REBOOT_HPP + +#include + +void reboot(const httplib::Request &request, httplib::Response &response); + +#endif // REBOOT_HPP diff --git a/src/routes.hpp b/src/routes.hpp new file mode 100644 index 0000000..eb1b4c5 --- /dev/null +++ b/src/routes.hpp @@ -0,0 +1,6 @@ +#ifndef ROUTES_HPP +#define ROUTES_HPP + +#define AUTH_SERVICE "http://localhost:43243" + +#endif // ROUTES_HPP \ No newline at end of file diff --git a/src/settings/telnet/telnet.cpp b/src/settings/telnet/telnet.cpp new file mode 100644 index 0000000..8442499 --- /dev/null +++ b/src/settings/telnet/telnet.cpp @@ -0,0 +1,99 @@ +#include "telnet.hpp" +#include +#include "../../types.hpp" +#include "../../routes.hpp" +#include +#include +#include +#include +#include + +#define TELNET_REQUIRED_STRING R"({"required":"[token,enabled]"})" + +void get_telnet(const httplib::Request &request, httplib::Response &response) { + std::cout << GREEN << request.path << RESET << " " << request.method << std::endl; + response.set_header("Access-Control-Allow-Origin", "*"); + if (request.body.empty()) { + response.set_content(ACCESS_REQUIRED_STRING, JSON_TYPE); + return; + } + + nlohmann::json json_body = nlohmann::json::parse(request.body); + if (json_body["token"] == nullptr) { + response.set_content(ACCESS_REQUIRED_STRING, JSON_TYPE); + return; + } + + httplib::Client cli(AUTH_SERVICE); + + std::stringstream body; + body << R"({"token":)" << json_body["token"] << R"(})"; + + httplib::Result res = cli.Post("/api/access", body.str().c_str(), JSON_TYPE); + if (res->status == httplib::OK_200) { + nlohmann::json resjson = nlohmann::json::parse(res->body); + if (resjson["access"] == "reject") { + response.set_content(resjson.dump().c_str(), JSON_TYPE); + return; + } + std::ifstream telnetfile("/etc/openrouter/telnet"); + int telnet_enabled; + telnetfile >> telnet_enabled; + telnetfile.close(); + std::stringstream responsedata; + responsedata << R"({"enabled":")" << telnet_enabled << R"("})"; + response.set_content(responsedata.str(), JSON_TYPE); + } +} + +void set_telnet(const httplib::Request &request, httplib::Response &response) { + std::cout << GREEN << request.path << RESET << " " << request.method << std::endl; + response.set_header("Access-Control-Allow-Origin", "*"); + if (request.body.empty()) { + response.set_content(ACCESS_REQUIRED_STRING, JSON_TYPE); + return; + } + + nlohmann::json json_body = nlohmann::json::parse(request.body); + if (json_body["token"] == nullptr) { + response.set_content(ACCESS_REQUIRED_STRING, JSON_TYPE); + return; + } + + if (json_body["enabled"] == nullptr) { + response.set_content(TELNET_REQUIRED_STRING, JSON_TYPE); + return; + } + + httplib::Client cli(AUTH_SERVICE); + + std::stringstream body; + body << R"({"token":)" << json_body["token"] << R"(})"; + + httplib::Result res = cli.Post("/api/access", body.str().c_str(), JSON_TYPE); + if (res->status == httplib::OK_200) { + nlohmann::json resjson = nlohmann::json::parse(res->body); + if (resjson["access"] == "reject") { + response.set_content(resjson.dump().c_str(), JSON_TYPE); + return; + } + std::ofstream telnetfileout("/etc/openrouter/telnet"); + std::string new_telnet_enabled = json_body["enabled"]; + if (new_telnet_enabled == "0") { + system("/etc/init.d/telnet stop"); + system("rm /etc/rc.d/70telnet"); + } else { + system("/etc/init.d/telnet start"); + system("ln -sv /etc/init.d/telnet /etc/rc.d/70telnet"); + } + telnetfileout << stoi(new_telnet_enabled); + telnetfileout.close(); + std::ifstream telnetfile("/etc/openrouter/telnet"); + int telnet_enabled; + telnetfile >> telnet_enabled; + telnetfile.close(); + std::stringstream responsedata; + responsedata << R"({"enabled":")" << telnet_enabled << R"("})"; + response.set_content(responsedata.str(), JSON_TYPE); + } +} diff --git a/src/settings/telnet/telnet.hpp b/src/settings/telnet/telnet.hpp new file mode 100644 index 0000000..254ffab --- /dev/null +++ b/src/settings/telnet/telnet.hpp @@ -0,0 +1,9 @@ +#ifndef SETTINGS_TELNET_HPP +#define SETTINGS_TELNET_HPP + +#include + +void get_telnet(const httplib::Request &request, httplib::Response &response); +void set_telnet(const httplib::Request &request, httplib::Response &response); + +#endif // SETTINGS_TELNET_HPP diff --git a/src/types.hpp b/src/types.hpp new file mode 100644 index 0000000..2d638f6 --- /dev/null +++ b/src/types.hpp @@ -0,0 +1,10 @@ +#ifndef TYPES_H +#define TYPES_H + +#define ACCESS_REQUIRED_STRING R"({"required":"[token]"})" + +#define JWT_SECRET_KEY "secret" +#define STRING403 R"({"status":"403"})" +#define JSON_TYPE "application/json" + +#endif // TYPES_H \ No newline at end of file diff --git a/src/web/css/button.css b/src/web/css/button.css new file mode 100644 index 0000000..9a190cc --- /dev/null +++ b/src/web/css/button.css @@ -0,0 +1,19 @@ +button { + padding: 10px; + border-radius: 10px; + border: none; + transition: 0.3s; + cursor: pointer; +} + +button:hover { + opacity: 0.6; +} + +.linkbutton { + background: transparent; +} + +.linkbutton:hover { + text-decoration: underline; +} diff --git a/src/web/css/form.css b/src/web/css/form.css index 234b74d..077962a 100644 --- a/src/web/css/form.css +++ b/src/web/css/form.css @@ -1,4 +1,7 @@ .form { + position: absolute; + top: 0; + left: 0; width: 100vw; height: 100vh; display: flex; @@ -19,6 +22,10 @@ transform: scale(1); } +.form.active>.formbody { + transform: scale(1); +} + .formbody { width: 50%; height: 50%; @@ -44,6 +51,17 @@ flex-direction: column; } +.forminputbody.confirmform { + display: flex; + flex-direction: row; + align-items: center; + gap: 10px; +} + +.forminputbody.confirmform>button { + width: 100%; +} + .forminputlabel { text-align: center; font-style: normal; diff --git a/src/web/css/header.css b/src/web/css/header.css new file mode 100644 index 0000000..078bf54 --- /dev/null +++ b/src/web/css/header.css @@ -0,0 +1,20 @@ +header { + width: 100vw; + height: 50px; + padding: 10px; + display: flex; + align-items: center; + justify-content: space-between; +} + +.links { + display: flex; + align-items: center; + gap: 10px; +} + +.userbuttons { + display: flex; + align-items: center; + gap: 10px; +} diff --git a/src/web/css/index.css b/src/web/css/index.css index 9c6638d..20e6f51 100644 --- a/src/web/css/index.css +++ b/src/web/css/index.css @@ -1,6 +1,5 @@ :root { color-scheme: light dark; - /* --font-color: light-dark(black, white); */ } * { @@ -12,5 +11,17 @@ body { width: 100vw; height: 100vh; - /* background-color: light-dark(white, black); */ +} + +.adminpanel { + width: 100%; + height: 100%; + transform: scale(0.5); + opacity: 0; + transition: 0.3s; +} + +.adminpanel.active { + transform: scale(1); + opacity: 1; } diff --git a/src/web/css/loader.css b/src/web/css/loader.css new file mode 100644 index 0000000..3d7a644 --- /dev/null +++ b/src/web/css/loader.css @@ -0,0 +1,64 @@ +.loader { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 0; + pointer-events: none; + display: grid; + z-index: 12; + backdrop-filter: blur(5px); + transition: 0.3s; +} + +.loader>h1 { + opacity: 0; + width: 100%; + padding: 10px; + text-align: center; +} + +.loadertip { + width: 0; + height: 0; + padding: 0; + margin: 0; + border-radius: 50%; + place-self: center; + z-index: 12; + position: relative; + transition: 0.3s; +} + +.progress { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + border-top: 5px solid #56C1F9; + border-radius: 50%; + animation: loading 2s infinite ease-in-out; +} + +.loader.active { + width: 100vw; + height: 100vh; +} + +.loader.active > .loadertip { + width: 100px; + height: 100px; + border-bottom: 5px solid gray; + animation: loading 2s infinite ease-in-out; +} + +.loader.active>h1 { + opacity: 1; +} + +@keyframes loading { + 100% { + transform: rotate(360deg); + } +} \ No newline at end of file diff --git a/src/web/css/notification.css b/src/web/css/notification.css new file mode 100644 index 0000000..4b88067 --- /dev/null +++ b/src/web/css/notification.css @@ -0,0 +1,43 @@ +.notification { + width: max-content; + height: 0; + overflow: hidden; + pointer-events: none; + z-index: 10; + border-radius: 10px; + position: fixed; + top: 0; + right: 0; + transition: 0.3s; + cursor: pointer; + opacity: 0.8; + margin: 10px; + padding: 0 10px; +} + +.notificationtextbox { + width: 100%; + height: 100%; + display: grid; + justify-items: center; + align-items: center; + pointer-events: none; +} + +.notificationtext { + width: 100%; + text-align: center; + pointer-events: none; +} + +.notification.active.error { + pointer-events: all; + height: 10%; + background-color: rgb(233, 70, 70); +} + +.notification.active.success { + pointer-events: all; + height: 10%; + background-color: rgb(76, 209, 76); +} \ No newline at end of file diff --git a/src/web/css/settings.css b/src/web/css/settings.css new file mode 100644 index 0000000..93c8559 --- /dev/null +++ b/src/web/css/settings.css @@ -0,0 +1,146 @@ + .checkbox-wrapper-2 .ikxBAC { + appearance: none; + background-color: #dfe1e4; + border-radius: 72px; + border-style: none; + flex-shrink: 0; + height: 20px; + margin: 0; + position: relative; + width: 30px; + transition: 0.3s; + } + + .checkbox-wrapper-2 .ikxBAC::before { + bottom: -6px; + content: ""; + left: -6px; + position: absolute; + right: -6px; + top: -6px; + transition: 0.3s; + cursor: pointer; + } + + .checkbox-wrapper-2 .ikxBAC, + .checkbox-wrapper-2 .ikxBAC::after { + transition: 300ms; + } + + .checkbox-wrapper-2 .ikxBAC::after { + background-color: #fff; + border-radius: 50%; + content: ""; + height: 14px; + left: 3px; + position: absolute; + top: 3px; + width: 14px; + cursor: pointer; + } + + .checkbox-wrapper-2 input[type=checkbox] { + cursor: default; + } + + .checkbox-wrapper-2 .ikxBAC:hover { + background-color: #c9cbcd; + transition-duration: 0s; + } + + .checkbox-wrapper-2 .ikxBAC:checked { + background-color: green; + } + + .checkbox-wrapper-2 .ikxBAC:checked::after { + background-color: #fff; + left: 13px; + } + + .checkbox-wrapper-2 :focus:not(.focus-visible) { + outline: 0; + } + + .checkbox-wrapper-2 .ikxBAC:checked:hover { + background-color: hsl(from green h s 20%); + } + +.settingrect { + width: 25%; + height: max-content; + background-color: hsl(from black h s 20%); + padding: 20px; + border-radius: 20px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 10px; +} + +.settingrectheader { + width: 100%; + display: flex; + justify-content: space-between; +} + +.settingrectbody { + width: 100%; + height: 0; + overflow: hidden; + transition: 0.3s; +} + +.settingrectbody.active { + height: max-content; +} + +.settingrectbody>table { + width: 100%; + text-align: left; +} + +.settingrectfooter { + width: 100%; + display: flex; + align-items: center; + gap: 10px; +} + +.settingrectfooter>button { + width: 100%; +} + +table { + border: 2px solid ; + border-radius: 10px; +} + +thead>tr>th { + border-bottom: 2px solid; + padding: 10px; +} + +tbody>tr>th { + border: 2px solid; + padding: 10px; + border-radius: 10px; +} + +@media screen and (max-width: 1200px) { + .settingrect { + width: 50%; + } +} + +@media screen and (max-width: 600px) { + .settingrect { + width: 75%; + } +} + +@media screen and (max-width: 400px) { + .settingrect { + width: 100%; + } +} diff --git a/src/web/index.html b/src/web/index.html index de8aa5a..40ef04a 100644 --- a/src/web/index.html +++ b/src/web/index.html @@ -5,9 +5,66 @@ + + + + + Openrouter Admin +
+
+ +

Openrouter Admin

+
+

+ +
+
+ +
+
+
+

Telnet

+
+ +
+
+
+ + + + + + + + + + + +
usernamepassword
No users
+
+
+ + +
+
+
+
+ +
+
+

+
+
+

OpenRouter Login

@@ -24,9 +81,28 @@
- + +
+
+

Confirm reboot?

+
+ + +
+
+
+ +
+

Reboting

+
+
+
+
+ + + \ No newline at end of file diff --git a/src/web/js/login.js b/src/web/js/login.js index a91a788..2b1b6de 100644 --- a/src/web/js/login.js +++ b/src/web/js/login.js @@ -3,12 +3,15 @@ const loginformbody = document.querySelector('.loginformbody') const loginusername = document.querySelector("#loginusernameinput") const loginpassword = document.querySelector("#loginpasswordinput") const exitbutton = document.querySelector('.exitbutton') - -console.log(localStorage.getItem("token")) +const adminpanelsection = document.querySelector('.adminpanel') +const headerusername = document.querySelector('.headerusername') if (localStorage.getItem("token") === null) { + adminpanelsection.classList.remove('active') loginform.classList.add('active') - // loginform.style.background = "initial" +} else { + adminpanelsection.classList.add('active') + headerusername.innerHTML = JSON.parse(localStorage.getItem('userdata')).username } loginformbody.addEventListener('submit', (e) => { @@ -19,39 +22,47 @@ loginformbody.addEventListener('submit', (e) => { const login = async (username, password) => { const response = await fetch(routes.login(), { method: 'POST', - headers: { - Accept: 'application/json', - // 'Access-Control-Allow-Origin': '*', - 'Content-Type': 'application/json', - }, - // mode: 'no-cors', body: `{"username":"${username}","password":"${password}"}` }).then(data => data.json()).then(jsondata => jsondata).catch((error) => { if (error.message === "Unexpected end of JSON input") { console.log("error") - // notification(`Ошибка на сервере: Создайте файл users.json и запишите в него первого пользователя`, "error") + notification(`Ошибка на сервере: Создайте файл users.json и запишите в него первого пользователя`, "error") } else { console.log("error") - // notification(`Ошибка на сервере: ${error}`, "error") + notification(`Ошибка на сервере: ${error}`, "error") } }) if (response.status === "403") { console.log("Неправильный логин или пароль") - // notification("Неправильный логин или пароль", "error") + notification("Неправильный логин или пароль", "error") } if (response.token) { - // notification("Успешно", "success") + notification("Успешно", "success") loginform.classList.remove("active") localStorage.setItem("token", response.token) + adminpanelsection.classList.add('active') await get_user_data() - loginforminputusername.value = "" - loginforminputpassword.value = "" + loginusername.value = "" + loginpassword.value = "" + } +} + +const get_user_data = async () => { + const response = await fetch(routes.user(), { + method: "POST", + body: `{"token":"${localStorage.getItem("token")}"}` + }).then(data => data.json()).then(jsondata => jsondata).catch((error) => { + notification(`Ошибка на сервере: ${error}`, "error") + }) + if (response.id) { + headerusername.innerHTML = response.username + localStorage.setItem("userdata", JSON.stringify(response)) } } exitbutton.addEventListener('click', () => { localStorage.clear() loginform.classList.add('active') - loginusername.value = "" - loginpassword = "" + notification('Вы вышли', "success") + adminpanelsection.classList.remove('active') }) diff --git a/src/web/js/notification.js b/src/web/js/notification.js new file mode 100644 index 0000000..52b1e91 --- /dev/null +++ b/src/web/js/notification.js @@ -0,0 +1,23 @@ +const notificationbox = document.querySelector('.notification') +const notificationtext = document.querySelector('.notificationtext') + +const notification = (text, type) => { + if (type === "error") { + notificationbox.classList.remove('success') + notificationbox.classList.add('error') + } else { + notificationbox.classList.remove('error') + notificationbox.classList.add('success') + } + notificationtext.innerHTML = text + notificationbox.classList.add('active') + setTimeout(() => { + notificationbox.classList.remove('active') + }, 2000) +} + +const closenotification = () => { + notificationbox.classList.remove('active') +} + +notificationbox.addEventListener('click', closenotification) \ No newline at end of file diff --git a/src/web/js/reboot.js b/src/web/js/reboot.js new file mode 100644 index 0000000..ee92682 --- /dev/null +++ b/src/web/js/reboot.js @@ -0,0 +1,42 @@ +const rebootbutton = document.querySelector('#rebootbutton') +const confirmrebootform = document.querySelector('.confirmrebootform') +const cancelrebootbutton = document.querySelector('#cancelreboot') +const confirmrebootbutton = document.querySelector('#confirmreboot') +const loader = document.querySelector('.loader') + +rebootbutton.addEventListener('click', () => { + confirmrebootform.classList.add('active') +}) + +const reboot = () => { + loader.classList.add('active') + fetch(routes.reboot(), { + method: 'POST', + body: `{"token":"${localStorage.getItem("token")}"}` + }).then(data => data.json()).then(jsondata => { + + }).catch((error) => { + // notification(`Перезагрузка`, "success") + confirmrebootform.classList.remove('active') + // window.location.replace(window.location.origin) + loader.classList.add('active') + waitreboot() + }) +} + +cancelrebootbutton.addEventListener('click', () => { + confirmrebootform.classList.remove('active') +}) + +confirmrebootbutton.addEventListener('click', reboot) + +const waitreboot = () => { + fetch(routes.telnet_status(), { + method: 'POST', + body: `{"token":"${localStorage.getItem("token")}"}` + }).then(res => res.json()).then(jsondata => { + loader.classList.remove('active') + }).catch((error) => { + waitreboot() + }) +} diff --git a/src/web/js/routes.js b/src/web/js/routes.js index 04522a1..0d18124 100644 --- a/src/web/js/routes.js +++ b/src/web/js/routes.js @@ -1,9 +1,13 @@ -const host = 'http://localhost:43243' +const authhost = 'http://192.168.122.76:43243' +const host = 'http://192.168.122.76:43244' const prefix = 'api' const routes = { - login: () => [host, prefix, 'token'].join('/'), - // user: () => [host, prefix, 'users', 'user'].join('/'), + login: () => [authhost, prefix, 'token'].join('/'), + user: () => [authhost, prefix, 'users', 'user'].join('/'), + telnet_status: () => [host, prefix, 'settings', 'telnet', 'get'].join('/'), + telnet_status_set: () => [host, prefix, 'settings', 'telnet', 'set'].join('/'), + reboot: () => [host, prefix, 'reboot'].join('/') // all_users: () => [host, prefix, 'users', 'all'].join('/'), // access: () => [host, prefix, 'access'].join('/'), // adduser: () => [host, prefix, 'users', 'add'].join('/'), diff --git a/src/web/js/settings/telnet.js b/src/web/js/settings/telnet.js new file mode 100644 index 0000000..3c8a3df --- /dev/null +++ b/src/web/js/settings/telnet.js @@ -0,0 +1,47 @@ +const telnetenabled = document.querySelector('#telnetenable') +const telnetsettingbody = document.querySelector('.telnetsettingbody') +const settelnetsettingsbutton = document.querySelector('#set_telnet_settings') + +const get_telnet_enabled_status = () => { + fetch(routes.telnet_status(), { + method: 'POST', + body: `{"token":"${localStorage.getItem("token")}"}` + }).then(res => res.json()).then(jsondata => { + if (jsondata.enabled === '1') { + telnetenabled.checked = true + // telnetsettingbody.classList.add('active') + return; + } + }).catch((error) => { + notification(`Ошибка на сервере: ${error}`, "error") + }) +} + +const set_telnet_enabled_status = (status) => { + fetch(routes.telnet_status_set(), { + method: 'POST', + body: `{"token":"${localStorage.getItem("token")}","enabled":"${status?1:0}"}` + }).then(res => res.json()).then(jsondata => { + if (jsondata.enabled === '1') { + telnetenabled.checked = true + // telnetsettingbody.classList.add('active') + } + notification("Настройки telnet сохранены", "success") + }).catch((error) => { + notification(`Ошибка на сервере: ${error}`, "error") + }) +} + +get_telnet_enabled_status() + +telnetenabled.addEventListener('click', () => { + if (telnetenabled.checked) { + // telnetsettingbody.classList.add('active') + } else { + telnetsettingbody.classList.remove('active') + } +}) + +settelnetsettingsbutton.addEventListener('click', () => { + set_telnet_enabled_status(telnetenabled.checked) +})