diff --git a/CMakeLists.txt b/CMakeLists.txt index 60fbef9..5602614 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,7 @@ add_executable( src/security/cors.cpp src/settings/settings.cpp + src/settings/backup.cpp src/settings/telnet/enabled.cpp src/settings/telnet/port.cpp diff --git a/Makefile b/Makefile index 358c142..7ef417e 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,7 @@ CXXFLAGS=-Wall -I src/libs -I src -std=c++20 SOURCES=src/openrouter.cpp \ src/security/cors.cpp \ src/settings/settings.cpp \ + src/settings/backup.cpp \ src/settings/telnet/enabled.cpp \ src/settings/telnet/port.cpp \ src/settings/ssh/status.cpp \ diff --git a/config.json b/config.json index 16eb67b..bfe0702 100644 --- a/config.json +++ b/config.json @@ -1,5 +1,9 @@ { "auth_service": "http://127.0.0.1:43243", + "server": { + "ip": "0.0.0.0", + "port": 43244 + }, "settings": { "dns": { "enabled": false, @@ -31,10 +35,10 @@ }, "telnet": { "enabled": false, - "port": "29" + "port": "23" }, "wifi": { - "channel": "1", + "channel": "11", "enabled": false, "name": "home", "password": "OpenRouterPassword" @@ -45,4 +49,4 @@ "js": "../src/web/js", "root": "../src/web" } -} \ No newline at end of file +} diff --git a/config_default.json b/config_default.json new file mode 100644 index 0000000..bfe0702 --- /dev/null +++ b/config_default.json @@ -0,0 +1,52 @@ +{ + "auth_service": "http://127.0.0.1:43243", + "server": { + "ip": "0.0.0.0", + "port": 43244 + }, + "settings": { + "dns": { + "enabled": false, + "localdomains": [ + { + "domain": "localhost", + "ip": "127.0.0.1" + }, + { + "domain": "openrouter.local.com", + "ip": "192.168.200.1" + } + ], + "servers": [ + "8.8.8.8" + ] + }, + "ftp": { + "enabled": false + }, + "ssh": { + "enabled": false, + "keys": [ + "key1", + "key2" + ], + "port": "22", + "server": "dropbear" + }, + "telnet": { + "enabled": false, + "port": "23" + }, + "wifi": { + "channel": "11", + "enabled": false, + "name": "home", + "password": "OpenRouterPassword" + } + }, + "static": { + "css": "../src/web/css", + "js": "../src/web/js", + "root": "../src/web" + } +} diff --git a/meson.build b/meson.build index 3c081fc..f8de5af 100644 --- a/meson.build +++ b/meson.build @@ -6,6 +6,7 @@ executable( 'src/security/cors.cpp', 'src/settings/settings.cpp', + 'src/settings/backup.cpp', 'src/settings/telnet/enabled.cpp', 'src/settings/telnet/port.cpp', diff --git a/src/OpenRouter/OpenRouter.cpp b/src/OpenRouter/OpenRouter.cpp index 85230af..588a9dc 100644 --- a/src/OpenRouter/OpenRouter.cpp +++ b/src/OpenRouter/OpenRouter.cpp @@ -13,6 +13,9 @@ OpenRouter::OpenRouter() this->srv.Post("/api/settings/get", api::settings::get); this->srv.Post("/api/settings/set", api::settings::set); + this->srv.Get("/api/settings/backup", api::settings::backup); + this->srv.Post("/api/settings/restore", api::settings::restore); + this->srv.Post("/api/settings/restore/defaults", api::settings::restore_defaults); this->srv.Post("/api/reboot", api::system::reboot); diff --git a/src/auth/auth.cpp b/src/auth/auth.cpp index 1d599d2..fff8eb5 100644 --- a/src/auth/auth.cpp +++ b/src/auth/auth.cpp @@ -6,7 +6,6 @@ bool authenticate(const std::string &token) { - // config::config.setConfig(std::string("../config.json")); httplib::Client cli(config::config.getConfig()["auth_service"]); std::string body = R"({"token":")" + token + R"("})"; diff --git a/src/config/config.hpp b/src/config/config.hpp index dd29eea..171f7a4 100644 --- a/src/config/config.hpp +++ b/src/config/config.hpp @@ -3,4 +3,4 @@ namespace config { static ConfigManager config(std::string("../config.json")); -} \ No newline at end of file +} diff --git a/src/libs/ConfigManager.hpp b/src/libs/ConfigManager.hpp index 571a298..087d55b 100644 --- a/src/libs/ConfigManager.hpp +++ b/src/libs/ConfigManager.hpp @@ -38,6 +38,9 @@ public: this->config = nullptr; this->configfile.close(); } + std::string getConfigFileName() { + return this->configFileName; + } nlohmann::json getConfig() { return this->config; diff --git a/src/openrouter.cpp b/src/openrouter.cpp index c47ec2c..04aef39 100644 --- a/src/openrouter.cpp +++ b/src/openrouter.cpp @@ -1,4 +1,5 @@ #include +#include int main() { @@ -6,6 +7,6 @@ int main() #ifdef TEST return 0; #else - return router.serve("0.0.0.0", 43244); + return router.serve(config::config.getConfig()["server"]["ip"], config::config.getConfig()["server"]["port"]); #endif } diff --git a/src/settings/backup.cpp b/src/settings/backup.cpp new file mode 100644 index 0000000..f1088b5 --- /dev/null +++ b/src/settings/backup.cpp @@ -0,0 +1,64 @@ +#include +#include +#include +#include +#include +#include + +namespace api +{ + namespace settings + { + void backup(const httplib::Request& request, httplib::Response& response) + { + std::ifstream backup_file(config::config.getConfigFileName()); + std::stringstream backup_file_buffer; + backup_file_buffer << backup_file.rdbuf(); + backup_file.close(); + response.set_content(backup_file_buffer.str(), JSON_TYPE); + } + + void restore(const httplib::Request& request, httplib::Response& response) + { + std::size_t size = request.files.size(); + std::cout << "file size::" << size << std::endl; + bool ret = request.has_file("restore_settings"); + std::cout << "file ret::" << ret << std::endl; + const httplib::MultipartFormData& file = request.get_file_value("restore_settings"); + if (file.content_type == JSON_TYPE) { + nlohmann::json new_config = nlohmann::json::parse(file.content); + config::config.setConfig(new_config); + config::config.saveConfig(); + set_all_settings(config::config.getConfig()); + response.set_content(R"({"status":true})", JSON_TYPE); + system("rc restart auth_service"); + system("rc restart openrouter"); + return; + } + response.set_content(R"({"status":false})", JSON_TYPE); + } + + void restore_defaults(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 (!check_body(request)) + { + response.set_content(ACCESS_REQUIRED_STRING, JSON_TYPE); + return; + } + if (std::filesystem::exists(config::config.getConfigFileName())) { + std::filesystem::remove(config::config.getConfigFileName()); + std::filesystem::copy("../config_default.json", config::config.getConfigFileName()); + usleep(300); + config::config.setConfig(config::config.getConfigFileName()); + set_all_settings(config::config.getConfig()); + response.set_content(R"({"status":true})", JSON_TYPE); + system("rc restart auth_service"); + system("rc restart openrouter"); + return; + } + response.set_content(R"({"status":false})", JSON_TYPE); + } + } +} diff --git a/src/settings/settings.cpp b/src/settings/settings.cpp index 1f06827..0485fc3 100644 --- a/src/settings/settings.cpp +++ b/src/settings/settings.cpp @@ -13,6 +13,30 @@ namespace api { namespace settings { + void set_all_settings(nlohmann::json json_body) + { + api::settings::wifi::set_wifi_status(json_body["settings"]["wifi"]["enabled"]); + std::string wifichannel = json_body["settings"]["wifi"]["channel"]; + api::settings::wifi::set_wifi_channel(std::stoi(wifichannel)); + api::settings::wifi::set_wifi_name(json_body["settings"]["wifi"]["name"]); + + api::settings::telnet::set_telnet(json_body["settings"]["telnet"]["enabled"]); + std::string telnetport = json_body["settings"]["telnet"]["port"]; + api::settings::telnet::set_telnet_port(std::stoi(telnetport)); + + api::settings::ssh::set_ssh_status(json_body["settings"]["ssh"]["enabled"]); + api::settings::ssh::set_ssh_server(json_body["settings"]["ssh"]["server"]); + std::string sshport = json_body["settings"]["ssh"]["port"]; + api::settings::ssh::set_ssh_port(std::stoi(sshport)); + api::settings::ssh::set_ssh_keys(json_body["settings"]["ssh"]["keys"]); + + api::settings::ftp::set_ftp(json_body["settings"]["ftp"]["enabled"]); + + api::settings::dns::set_dns(json_body["settings"]["dns"]["enabled"]); + api::settings::dns::set_dns_servers(json_body["settings"]["dns"]["servers"]); + api::settings::dns::set_local_domains(json_body["settings"]["dns"]["localdomains"]); + } + void get(const httplib::Request& request, httplib::Response& response) { std::cout << GREEN << request.path << RESET << " " << request.method << std::endl; @@ -29,7 +53,7 @@ namespace api response.set_content(R"({"access":"reject"})", JSON_TYPE); return; } - config::config.setConfig(std::string("../config.json")); + config::config.setConfig(config::config.getConfigFileName()); std::string responsedata = R"({"settings":)" + config::config.getConfig()["settings"].dump() + R"(})"; response.set_content(responsedata, JSON_TYPE); } @@ -56,33 +80,35 @@ namespace api response.set_content(R"({"access":"reject"})", JSON_TYPE); return; } - sleep(1); - config::config.setConfig(std::string("../config.json")); + usleep(300); + config::config.setConfig(config::config.getConfigFileName()); nlohmann::json new_config = config::config.getConfig(); new_config["settings"] = json_body["settings"]; config::config.setConfig(new_config); config::config.saveConfig(); - api::settings::wifi::set_wifi_status(json_body["settings"]["wifi"]["enabled"]); - std::string wifichannel = json_body["settings"]["wifi"]["channel"]; - api::settings::wifi::set_wifi_channel(std::stoi(wifichannel)); - api::settings::wifi::set_wifi_name(json_body["settings"]["wifi"]["name"]); + set_all_settings(json_body); - api::settings::telnet::set_telnet(json_body["settings"]["telnet"]["enabled"]); - std::string telnetport = json_body["settings"]["telnet"]["port"]; - api::settings::telnet::set_telnet_port(std::stoi(telnetport)); + // api::settings::wifi::set_wifi_status(json_body["settings"]["wifi"]["enabled"]); + // std::string wifichannel = json_body["settings"]["wifi"]["channel"]; + // api::settings::wifi::set_wifi_channel(std::stoi(wifichannel)); + // api::settings::wifi::set_wifi_name(json_body["settings"]["wifi"]["name"]); - api::settings::ssh::set_ssh_status(json_body["settings"]["ssh"]["enabled"]); - api::settings::ssh::set_ssh_server(json_body["settings"]["ssh"]["server"]); - std::string sshport = json_body["settings"]["ssh"]["port"]; - api::settings::ssh::set_ssh_port(std::stoi(sshport)); - api::settings::ssh::set_ssh_keys(json_body["settings"]["ssh"]["keys"]); + // api::settings::telnet::set_telnet(json_body["settings"]["telnet"]["enabled"]); + // std::string telnetport = json_body["settings"]["telnet"]["port"]; + // api::settings::telnet::set_telnet_port(std::stoi(telnetport)); - api::settings::ftp::set_ftp(json_body["settings"]["ftp"]["enabled"]); + // api::settings::ssh::set_ssh_status(json_body["settings"]["ssh"]["enabled"]); + // api::settings::ssh::set_ssh_server(json_body["settings"]["ssh"]["server"]); + // std::string sshport = json_body["settings"]["ssh"]["port"]; + // api::settings::ssh::set_ssh_port(std::stoi(sshport)); + // api::settings::ssh::set_ssh_keys(json_body["settings"]["ssh"]["keys"]); - api::settings::dns::set_dns(json_body["settings"]["dns"]["enabled"]); - api::settings::dns::set_dns_servers(json_body["settings"]["dns"]["servers"]); - api::settings::dns::set_local_domains(json_body["settings"]["dns"]["localdomains"]); + // api::settings::ftp::set_ftp(json_body["settings"]["ftp"]["enabled"]); + + // api::settings::dns::set_dns(json_body["settings"]["dns"]["enabled"]); + // api::settings::dns::set_dns_servers(json_body["settings"]["dns"]["servers"]); + // api::settings::dns::set_local_domains(json_body["settings"]["dns"]["localdomains"]); std::string responsedata = R"({"settings":)" + config::config.getConfig()["settings"].dump() + R"(})"; response.set_content(responsedata, JSON_TYPE); diff --git a/src/settings/settings.hpp b/src/settings/settings.hpp index bd8b57e..473037e 100644 --- a/src/settings/settings.hpp +++ b/src/settings/settings.hpp @@ -11,6 +11,10 @@ namespace api { namespace settings { + void set_all_settings(nlohmann::json json_body); + void backup(const httplib::Request& request, httplib::Response& response); + void restore(const httplib::Request& request, httplib::Response& response); + void restore_defaults(const httplib::Request& request, httplib::Response& response); void get(const httplib::Request& request, httplib::Response& response); void set(const httplib::Request& request, httplib::Response& response); } diff --git a/src/settings/ssh/port.cpp b/src/settings/ssh/port.cpp index f0732b6..ef21eb6 100644 --- a/src/settings/ssh/port.cpp +++ b/src/settings/ssh/port.cpp @@ -4,9 +4,11 @@ #include #include #include +#include #define SSH_PORT_REQUIRED_STRING R"({"required":"[token,port]"})" -#define SSH_PORT_PATH "/etc/openrouter/ssh/port" +#define DROPBEAR_DEFAULT_FILE "/etc/default/dropbear" +#define SSHD_CONFIG_FILE "/etc/ssh/sshd_config" namespace api { @@ -16,21 +18,15 @@ namespace api { void set_ssh_port(int new_ssh_port) { - std::ifstream oldsshportfile(SSH_PORT_PATH); - int old_ssh_port; - oldsshportfile >> old_ssh_port; - oldsshportfile.close(); - std::ofstream sshportfileout(SSH_PORT_PATH); - sshportfileout << new_ssh_port; - sshportfileout.close(); + std::string old_ssh_port = config::config.getConfig()["settings"]["ssh"]["port"]; std::stringstream systemrequest; if (get_ssh_server() == DROPBEAR_SSH) { - systemrequest << "sed -i \"s/DROPBEAR_PORT=" << old_ssh_port << "/DROPBEAR_PORT=" << new_ssh_port << "/g\" /etc/default/dropbear"; + systemrequest << "sed -i \"s/DROPBEAR_PORT=" << old_ssh_port << "/DROPBEAR_PORT=" << new_ssh_port << "/g\" " << DROPBEAR_DEFAULT_FILE; } else if (get_ssh_server() == OPENSSH_SSH) { - systemrequest << "sed -i \"/Port " << old_ssh_port << "/s//Port " << new_ssh_port << "/\" /etc/ssh/sshd_config"; + systemrequest << "sed -i \"/Port " << old_ssh_port << "/s//Port " << new_ssh_port << "/\" " << SSHD_CONFIG_FILE; } std::cout << systemrequest.str() << std::endl; system(systemrequest.str().c_str()); diff --git a/src/settings/ssh/server.cpp b/src/settings/ssh/server.cpp index c6c8e73..8989bda 100644 --- a/src/settings/ssh/server.cpp +++ b/src/settings/ssh/server.cpp @@ -11,7 +11,7 @@ namespace api { std::string get_ssh_server() { - config::config.setConfig(std::string("../config.json")); + config::config.setConfig(config::config.getConfigFileName()); return config::config.getConfig()["settings"]["ssh"]["server"]; } diff --git a/src/settings/telnet/port.cpp b/src/settings/telnet/port.cpp index 0f69b0d..a4e6154 100644 --- a/src/settings/telnet/port.cpp +++ b/src/settings/telnet/port.cpp @@ -1,6 +1,10 @@ #include #include #include +#include +#include + +#define TELNET_PORT_FILE "/etc/default/telnet" namespace api { @@ -10,6 +14,11 @@ namespace api { void set_telnet_port(int new_telnet_port) { + std::string old_telnet_port = config::config.getConfig()["settings"]["telnet"]["port"]; + std::stringstream systemrequest; + systemrequest << "sed -i \"s/TELNET_PORT=" << old_telnet_port << "/TELNET_PORT=" << new_telnet_port << "/g\" " << TELNET_PORT_FILE; + std::cout << systemrequest.str() << std::endl; + system(systemrequest.str().c_str()); system("rc restart telnet"); std::string syslogstring = "Telnet port changed to " + new_telnet_port; syslog(LOG_INFO, "%s", syslogstring.c_str()); diff --git a/src/settings/wifi/password.cpp b/src/settings/wifi/password.cpp index 06ee209..2a18af9 100644 --- a/src/settings/wifi/password.cpp +++ b/src/settings/wifi/password.cpp @@ -61,8 +61,8 @@ namespace api system("rc restart hostapd"); std::string syslogstring = "WIFI password changed"; syslog(LOG_INFO, "%s", syslogstring.c_str()); - sleep(1); - config::config.setConfig(std::string("../config.json")); + usleep(500); + config::config.setConfig(config::config.getConfigFileName()); nlohmann::json new_config = config::config.getConfig(); new_config["settings"]["wifi"]["password"] = new_wifi_password; config::config.setConfig(new_config); diff --git a/src/settings/wifi/qr.cpp b/src/settings/wifi/qr.cpp index e060c4b..9796448 100644 --- a/src/settings/wifi/qr.cpp +++ b/src/settings/wifi/qr.cpp @@ -30,7 +30,7 @@ namespace api response.set_content(R"({"access":"reject"})", JSON_TYPE); return; } - config::config.setConfig(std::string("../config.json")); + config::config.setConfig(config::config.getConfigFileName()); std::string wifi_password = config::config.getConfig()["settings"]["wifi"]["password"]; std::string wifi_name = config::config.getConfig()["settings"]["wifi"]["name"]; std::stringstream toqrstring; diff --git a/src/web/index.html b/src/web/index.html index 4988713..b41bc77 100644 --- a/src/web/index.html +++ b/src/web/index.html @@ -197,11 +197,14 @@

Backup settings

-
- - +
+ + + + +
@@ -284,6 +287,7 @@ + diff --git a/src/web/js/header.js b/src/web/js/header.js index 6882762..49a2cf4 100644 --- a/src/web/js/header.js +++ b/src/web/js/header.js @@ -45,9 +45,3 @@ infobutton.addEventListener('click', () => { infosection.classList.add('active') uptimeintervalid = setInterval(get_uptime, 1000) }) - -// if (window.screenX > 600) { -// header.removeChild(headermenubutton) -// } else { -// header.prepend(headermenubutton) -// } diff --git a/src/web/js/routes.js b/src/web/js/routes.js index 5afb1f8..499c56c 100644 --- a/src/web/js/routes.js +++ b/src/web/js/routes.js @@ -10,6 +10,9 @@ const routes = { settings_get: () => [host, prefix, 'settings', 'get'].join('/'), settings_set: () => [host, prefix, 'settings', 'set'].join('/'), + settings_backup: () => [host, prefix, 'settings', 'backup'].join('/'), + settings_restore: () => [host, prefix, 'settings', 'restore'].join('/'), + restore_defaults: () => [host, prefix, 'settings', 'restore', 'defaults'].join('/'), reboot: () => [host, prefix, 'reboot'].join('/'), syslog: () => [host, prefix, 'syslog'].join('/'), diff --git a/src/web/js/settings/backup.js b/src/web/js/settings/backup.js new file mode 100644 index 0000000..1b69918 --- /dev/null +++ b/src/web/js/settings/backup.js @@ -0,0 +1,49 @@ +const backup_settings_button = document.querySelector('#backup_settings') +const restore_setings_button = document.querySelector('#restore_settings') +const restore_settings_input = document.querySelector('#restore_settings_input') +const start_restore_settings = document.querySelector('#start_restore_settings') +const restore_default_settings = document.querySelector('#restore_default_settings') + +backup_settings_button.href = routes.settings_backup() + +restore_setings_button.addEventListener('click', () => restore_settings_input.click()) + +start_restore_settings.addEventListener('click', () => { + let restore_file = restore_settings_input.files[0] + console.log(restore_file) + let formData = new FormData() + formData.append('restore_settings', restore_file) + fetch(routes.settings_restore(), {method:"POST", body: formData}) + .then(data => data.json()) + .then(jsondata => { + console.log(jsondata) + if (jsondata.status) { + notification('Настройки применены', 'success') + get_all_settings() + } else { + notification('Некорректный файл', 'error') + } + }).catch((error) => { + notification(`Ошибка на сервере: ${error}`, "error") + }) +}) + +restore_default_settings.addEventListener('click', () => { + fetch(routes.restore_defaults(), { + method: 'POST', + body: `{"token":"${localStorage.getItem("token")}"}` + }).then(data => data.json()).then(jsondata => { + if (jsondata.status) { + notification(`Настройки успешно сохранены`, "success"); + get_all_settings() + } else { + notification(`Неизвестная ошибка`, "error"); + } + }).catch((error) => { + notification(`Ошибка на сервере: ${error}`, "error") + }) +}) + +// restore_settings_input.addEventListener('click', () => { + +// }) diff --git a/src/web/js/settings/dns.js b/src/web/js/settings/dns.js index 9a92e0c..26a0b34 100644 --- a/src/web/js/settings/dns.js +++ b/src/web/js/settings/dns.js @@ -17,6 +17,9 @@ const get_dns_enabled_status = () => { addlocaldomainbutton.classList.add('active') } else { adddnsserverbutton.parentElement.classList.add('onebutton') + dnssettingbody.classList.remove('active') + adddnsserverbutton.classList.remove('active') + addlocaldomainbutton.classList.remove('active') } } diff --git a/src/web/js/settings/ssh.js b/src/web/js/settings/ssh.js index f1e4887..6b21be9 100644 --- a/src/web/js/settings/ssh.js +++ b/src/web/js/settings/ssh.js @@ -15,6 +15,10 @@ const get_ssh_status = () => { sshsettingsbody.classList.add('active') add_ssh_key_button.classList.add('active') add_ssh_key_button.parentElement.classList.remove('onebutton') + } else { + sshsettingsbody.classList.remove('active') + add_ssh_key_button.classList.remove('active') + add_ssh_key_button.parentElement.classList.add('onebutton') } } diff --git a/src/web/js/settings/telnet.js b/src/web/js/settings/telnet.js index 7dd2707..7ce24d8 100644 --- a/src/web/js/settings/telnet.js +++ b/src/web/js/settings/telnet.js @@ -7,6 +7,8 @@ const get_telnet_enabled_status = () => { telnetenabled.checked = settings.telnet.enabled if (settings.telnet.enabled) { telnetsettingbody.classList.add('active') + } else { + telnetsettingbody.classList.remove('active') } } diff --git a/src/web/js/settings/wifi.js b/src/web/js/settings/wifi.js index 7a5f429..cf017e2 100644 --- a/src/web/js/settings/wifi.js +++ b/src/web/js/settings/wifi.js @@ -16,6 +16,8 @@ const get_wifi_status = () => { wifistatus.checked = settings.wifi.enabled if (settings.wifi.enabled) { wifisettingsbody.classList.add('active') + } else { + wifisettingsbody.classList.remove('active') } }