From 77fb7b0816a01559e18f8fe0787f416f97e802d7 Mon Sep 17 00:00:00 2001 From: TolaMironcenko Date: Mon, 1 Jul 2024 18:46:32 +0700 Subject: [PATCH] added dns local domains --- CMakeLists.txt | 5 +- src/openrouter.cpp | 2 + src/settings/dns/dns.hpp | 4 + src/settings/dns/{dns.cpp => enabled.cpp} | 0 src/settings/dns/local_domains.cpp | 98 +++++++++++++++ .../dns/{dns_servers.cpp => servers.cpp} | 15 ++- src/web/css/settings.css | 32 ++++- src/web/index.html | 34 ++++- src/web/js/login.js | 3 - src/web/js/routes.js | 2 + src/web/js/settings/confirm.js | 3 - src/web/js/settings/dns.js | 119 ++++++++++++++++-- src/web/js/settings/ftp.js | 1 - src/web/js/settings/settings.js | 3 + src/web/js/settings/telnet.js | 1 - 15 files changed, 296 insertions(+), 26 deletions(-) rename src/settings/dns/{dns.cpp => enabled.cpp} (100%) create mode 100644 src/settings/dns/local_domains.cpp rename src/settings/dns/{dns_servers.cpp => servers.cpp} (88%) diff --git a/CMakeLists.txt b/CMakeLists.txt index bb9decd..1e53148 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,8 +11,9 @@ add_executable( src/settings/telnet/telnet.cpp - src/settings/dns/dns.cpp - src/settings/dns/dns_servers.cpp + src/settings/dns/enabled.cpp + src/settings/dns/servers.cpp + src/settings/dns/local_domains.cpp src/settings/ftp/ftp.cpp diff --git a/src/openrouter.cpp b/src/openrouter.cpp index 57c99d3..a393f9d 100644 --- a/src/openrouter.cpp +++ b/src/openrouter.cpp @@ -19,6 +19,8 @@ int main() { srv.Post("/api/settings/dns/set", set_dns); srv.Post("/api/settings/dns/servers/get", get_dns_servers); srv.Post("/api/settings/dns/servers/set", set_dns_servers); + srv.Post("/api/settings/dns/domains/get", get_local_domains); + srv.Post("/api/settings/dns/domains/set", set_local_domains); srv.Post("/api/settings/ftp/get", get_ftp); srv.Post("/api/settings/ftp/set", set_ftp); diff --git a/src/settings/dns/dns.hpp b/src/settings/dns/dns.hpp index 802771b..81b5ebb 100644 --- a/src/settings/dns/dns.hpp +++ b/src/settings/dns/dns.hpp @@ -5,7 +5,11 @@ void get_dns(const httplib::Request &request, httplib::Response &response); void set_dns(const httplib::Request &request, httplib::Response &response); + void get_dns_servers(const httplib::Request &request, httplib::Response &response); void set_dns_servers(const httplib::Request &request, httplib::Response &response); +void get_local_domains(const httplib::Request &request, httplib::Response &response); +void set_local_domains(const httplib::Request &request, httplib::Response &response); + #endif // DNS_HPP \ No newline at end of file diff --git a/src/settings/dns/dns.cpp b/src/settings/dns/enabled.cpp similarity index 100% rename from src/settings/dns/dns.cpp rename to src/settings/dns/enabled.cpp diff --git a/src/settings/dns/local_domains.cpp b/src/settings/dns/local_domains.cpp new file mode 100644 index 0000000..1c789c4 --- /dev/null +++ b/src/settings/dns/local_domains.cpp @@ -0,0 +1,98 @@ +#include "dns.hpp" +#include +#include +#include "../../routes.hpp" +#include "../../types.hpp" + +void get_local_domains(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 domainsfile("/etc/dnsmasq.conf.d/hosts"); + std::stringstream responsedata; + responsedata << R"({"domains":[)"; + std::string ip_string = ""; + std::string domain_string = ""; + int iter = 0; + while (!domainsfile.eof()) { + domainsfile >> ip_string; + domainsfile >> domain_string; + if (domain_string == "") { + continue; + } + responsedata << R"({"ip":")" << ip_string << R"(","domain":")" << domain_string << R"("},)"; + ip_string = ""; + domain_string = ""; + iter++; + } + if (iter != 0) { + responsedata.str(responsedata.str().erase(responsedata.str().size()-1, 1) + "]}"); + } else { + responsedata << "]}"; + } + domainsfile.close(); + response.set_content(responsedata.str(), JSON_TYPE); + } +} + +void set_local_domains(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::ofstream domainsfile("/etc/dnsmasq.conf.d/hosts"); + nlohmann::json domains = json_body["domains"]; + for (nlohmann::json_abi_v3_11_3::json domain : domains) { + std::string ip = domain["ip"]; + std::string dom = domain["domain"]; + domainsfile << ip << " " << dom << "\n"; + } + domainsfile.close(); + system("/etc/init.d/dnsmasq restart"); + std::string responsedata = R"({"success":"true"})"; + response.set_content(responsedata, JSON_TYPE); + } +} diff --git a/src/settings/dns/dns_servers.cpp b/src/settings/dns/servers.cpp similarity index 88% rename from src/settings/dns/dns_servers.cpp rename to src/settings/dns/servers.cpp index b8515ba..cca2d85 100644 --- a/src/settings/dns/dns_servers.cpp +++ b/src/settings/dns/servers.cpp @@ -34,14 +34,20 @@ void get_dns_servers(const httplib::Request &request, httplib::Response &respons } std::ifstream dnsserversfile("/etc/dnsmasq.conf.d/resolv.conf"); std::stringstream responsedata; - responsedata << R"({"servers":[")"; + responsedata << R"({"servers":[)"; std::string dns_server_string = ""; + int iter = 0; while (std::getline(dnsserversfile, dns_server_string)) { dns_server_string.erase(0, 11); - responsedata << dns_server_string << R"(",")"; + responsedata << "\"" << dns_server_string << R"(",)"; dns_server_string = ""; + iter++; + } + if (iter != 0) { + responsedata.str(responsedata.str().erase(responsedata.str().size()-1, 1) + "]}"); + } else { + responsedata << "]}"; } - responsedata.str(responsedata.str().erase(responsedata.str().size()-2, 2) + "]}"); dnsserversfile.close(); response.set_content(responsedata.str(), JSON_TYPE); } @@ -77,6 +83,9 @@ void set_dns_servers(const httplib::Request &request, httplib::Response &respons nlohmann::json servers = json_body["servers"]; for (nlohmann::json_abi_v3_11_3::json server : servers) { std::string srv = server; + if (server == "") { + continue; + } dnsserversfile << "nameserver " << srv << "\n"; } dnsserversfile.close(); diff --git a/src/web/css/settings.css b/src/web/css/settings.css index 5033aec..8ff8fdc 100644 --- a/src/web/css/settings.css +++ b/src/web/css/settings.css @@ -67,7 +67,7 @@ .settingssection { display: flex; - flex-direction: column; + /* flex-direction: column; */ gap: 10px; } @@ -137,24 +137,50 @@ } table { + position: relative; width: 100%; border: 2px solid ; border-radius: 10px; + margin: 10px 0; } thead>tr>th { border-bottom: 2px solid; padding: 10px; - width: 100%; + width: 50%; } -tbody>tr>th { +.one { border: 2px solid; padding: 10px; border-radius: 10px; display: flex; align-items: center; justify-content: space-between; + width: 100%; +} + +.three { + width: 33%; +} + +/* tbody>tr>th.one { + border: 2px solid; + padding: 10px; + border-radius: 10px; + display: flex; + align-items: center; + justify-content: space-between; +} */ + +tbody>tr>th { + border: 2px solid; + padding: 10px; + border-radius: 10px; + width: 50%; + /* display: flex; + align-items: center; + justify-content: space-between; */ } @media screen and (max-width: 1200px) { diff --git a/src/web/index.html b/src/web/index.html index 2e1d4f1..0f0402b 100644 --- a/src/web/index.html +++ b/src/web/index.html @@ -76,8 +76,21 @@ +

Domains Table

+ + + + + + + + + + +
IPDomain
+
@@ -138,7 +151,7 @@

Add DNS server

- +
@@ -148,6 +161,25 @@
+ +
+
+

Add Local Domain

+
+ + +
+
+ + +
+
+ + +
+
+
+

Reboting

diff --git a/src/web/js/login.js b/src/web/js/login.js index 6167aa9..1ca3249 100644 --- a/src/web/js/login.js +++ b/src/web/js/login.js @@ -26,15 +26,12 @@ const login = async (username, password) => { 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") } else { - console.log("error") notification(`Ошибка на сервере: ${error}`, "error") } }) if (response.status === "403") { - console.log("Неправильный логин или пароль") notification("Неправильный логин или пароль", "error") } if (response.token) { diff --git a/src/web/js/routes.js b/src/web/js/routes.js index 049ad4c..6efd614 100644 --- a/src/web/js/routes.js +++ b/src/web/js/routes.js @@ -12,6 +12,8 @@ const routes = { dns_status_set: () => [host, prefix, 'settings', 'dns', 'set'].join('/'), dns_servers_get: () => [host, prefix, 'settings', 'dns', 'servers', 'get'].join('/'), dns_servers_set: () => [host, prefix, 'settings', 'dns', 'servers', 'set'].join('/'), + dns_local_domains_get: () => [host, prefix, 'settings', 'dns', 'domains', 'get'].join('/'), + dns_local_domains_set: () => [host, prefix, 'settings', 'dns', 'domains', 'set'].join('/'), ftp_status: () => [host, prefix, 'settings', 'ftp', 'get'].join('/'), ftp_status_set: () => [host, prefix, 'settings', 'ftp', 'set'].join('/'), diff --git a/src/web/js/settings/confirm.js b/src/web/js/settings/confirm.js index 1f3c55a..197ea86 100644 --- a/src/web/js/settings/confirm.js +++ b/src/web/js/settings/confirm.js @@ -8,11 +8,8 @@ const defaultcancelreqfunc = () => { } const get_confirm_form = (header, reqfunc = defaultcancelreqfunc, cancelreqfunc = defaultcancelreqfunc) => { - console.log("confirmform") confirmformheader.innerHTML = header - console.log("confirmformheader") confirmform.classList.add('active') - console.log("activeconfirmform") var confirmbutton = document.createElement('button') confirmbutton.classList.add('formbutton') diff --git a/src/web/js/settings/dns.js b/src/web/js/settings/dns.js index 7278e05..f30efaf 100644 --- a/src/web/js/settings/dns.js +++ b/src/web/js/settings/dns.js @@ -9,19 +9,28 @@ const adddnsservercancelbutton = document.querySelector('#adddnsservercancel') const adddnsserverconfirmbutton = document.querySelector('#adddnsserverconfirm') const adddnsserverinput = document.querySelector('#adddnsserverinput') +const localdomainstablebody = document.querySelector('#domainsstablebody') +const addlocaldomainbutton = document.querySelector('#add_local_domain_button') +const addlocaldomainform = document.querySelector('#addlocaldomainform') +const addlocaldomaincancelbutton = document.querySelector('#addlocaldomaincancel') +const addlocaldomainconfirmbutton = document.querySelector('#addlocaldomainconfirm') +const domaininput = document.querySelector('#domaininput') +const ipinput = document.querySelector('#ipinput') +const domainstablebody = document.querySelector('#domainsstablebody') + let dnsservers = [] +let localdomains = [] const get_dns_enabled_status = () => { fetch(routes.dns_status(), { method: 'POST', body: `{"token":"${localStorage.getItem("token")}"}` }).then(res => res.json()).then(jsondata => { - console.log(jsondata) if (jsondata.enabled === '1') { dnsenabled.checked = true dnssettingbody.classList.add('active') adddnsserverbutton.classList.add('active') - // adddnsserverbutton.parentElement.classList.remove('onebutton') + addlocaldomainbutton.classList.add('active') return; } else { adddnsserverbutton.parentElement.classList.add('onebutton') @@ -49,7 +58,10 @@ const set_dns_enabled_status = () => { const set_dns_settings = () => { set_dns_enabled_status() - set_dns_server() + if (dnsenabled.checked) { + set_dns_server() + set_local_domains() + } } setdnssettingsbutton.addEventListener('click', () =>{ @@ -60,11 +72,13 @@ dnsenabled.addEventListener('click', () => { if (dnsenabled.checked) { dnssettingbody.classList.add('active') adddnsserverbutton.classList.add('active') + addlocaldomainbutton.classList.add('active') adddnsserverbutton.parentElement.classList.remove('onebutton') get_dns_server() } else { dnssettingbody.classList.remove('active') adddnsserverbutton.classList.remove('active') + addlocaldomainbutton.classList.remove('active') adddnsserverbutton.parentElement.classList.add('onebutton') } }) @@ -74,11 +88,15 @@ const get_dns_server = () => { method: 'POST', body: `{"token":"${localStorage.getItem("token")}"}` }).then(res => res.json()).then(jsondata => { - console.log(jsondata) dnsservers = jsondata.servers dnsserverstablebody.innerHTML = "" for (const server in jsondata.servers) { - dnsserverstablebody.innerHTML += `${jsondata.servers[server]} ` + dnsserverstablebody.innerHTML += ` + + ${jsondata.servers[server]} + + + ` } }).catch((error) => { notification(`Ошибка на сервере: ${error}`, "error") @@ -87,13 +105,18 @@ const get_dns_server = () => { const set_dns_server = () => { start_loader("Load DNS") - console.log(`{"token":"${localStorage.getItem('token')}","servers":${JSON.stringify(dnsservers)}}`) + dnsservers.push(adddnsserverinput.value) fetch(routes.dns_servers_set(), { method: 'POST', body: `{"token":"${localStorage.getItem('token')}","servers":${JSON.stringify(dnsservers)}}` }).then(data => data.json()).then(jsondata => { stop_loader() - jsondata.success ? get_dns_server() : notification("Неизвестная ошибка", "error") + if (jsondata.success) { + get_dns_server() + notification("Настройки dns сохранены", "success") + } else { + notification("Неизвестная ошибка", "error") + } }).catch((error) => { notification(`Ошибка на сервере: ${error}`, "error") }) @@ -121,7 +144,6 @@ adddnsserverconfirmbutton.addEventListener('click', () => { if (adddnsserverinput.value === "") { return } - dnsservers.push(adddnsserverinput.value) get_confirm_form(`Confirm DNS settings? (Add DNS server: ${adddnsserverinput.value})`, set_dns_server, cancel_confirm_add_dns_server) }) @@ -129,7 +151,86 @@ dnsserverstablebody.addEventListener('click', (e) => { if (e.target.classList.contains('deldnsserverbutton')) { dnsservers.splice(dnsservers.indexOf(e.target.id), 1) set_dns_server() - console.log('del', e.target.id) get_dns_server() } }) + +// ---------------------- local domains --------------------------- + +const get_local_domains = () => { + fetch(routes.dns_local_domains_get(), { + method: 'POST', + body: `{"token":"${localStorage.getItem('token')}"}` + }).then(data => data.json()).then(jsondata => { + localdomains = jsondata.domains + localdomainstablebody.innerHTML = "" + for (const domain in jsondata.domains) { + localdomainstablebody.innerHTML += ` + ${jsondata.domains[domain].ip} + + ${jsondata.domains[domain].domain} + + + ` + } + }).catch((error) => { + notification(`Ошибка на сервере: ${error}`, "error") + }) +} + +const set_local_domains = (domains = localdomains) => { + start_loader() + fetch(routes.dns_local_domains_set(), { + method: 'POST', + body: `{"token":"${localStorage.getItem('token')}","domains":${JSON.stringify(domains)}}` + }).then(data => data.json()).then(jsondata => { + stop_loader() + if (jsondata.success) { + get_local_domains() + notification("Настройки dns сохранены", "success") + } else { + notification("Неизвестная ошибка", "error") + } + }).catch((error) => { + notification(`Ошибка на сервере: ${error}`, "error") + }) +} + +const cancel_confirm_add_localdomain = () => { + confirmform.classList.remove('active') + addlocaldomainform.classList.add('active') +} + +addlocaldomainbutton.addEventListener('click', () => { + addlocaldomainform.classList.add('active') +}) + +addlocaldomaincancelbutton.addEventListener('click', () => { + addlocaldomainform.classList.remove('active') + domaininput.value = ""; + ipinput.value = ""; +}) + +addlocaldomainconfirmbutton.addEventListener('click', () => { + addlocaldomainform.classList.remove('active') + get_confirm_form(`Confirm DNS settings? (Add Local Domain: ${ipinput.value} ${domaininput.value})`, () => { + localdomains.push({"ip": ipinput.value, "domain": domaininput.value}); + set_local_domains() + ipinput.value = "" + domaininput.value = "" + }, cancel_confirm_add_localdomain) +}) + +domainstablebody.addEventListener('click', (e) => { + if (e.target.classList.contains('deldomain')) { + // const delel = localdomains.find(dom => dom.domain === e.target.id) + // delete localdomains.domains[localdomains.indexOf(delel)] + localdomains.splice(localdomains.indexOf(localdomains.find(dom => dom.domain === e.target.id)), 1) + // get_confirm_form(`Confirm DNS settings? (delete Local Domain: ${e.target.id})`, () => set_local_domains(localdomains)) + set_local_domains() + get_local_domains() + } +}) + + +// ------------------------- local domains end -------------------- diff --git a/src/web/js/settings/ftp.js b/src/web/js/settings/ftp.js index f313623..d7a3ca1 100644 --- a/src/web/js/settings/ftp.js +++ b/src/web/js/settings/ftp.js @@ -6,7 +6,6 @@ const get_ftp_enabled_status = () => { method: 'POST', body: `{"token":"${localStorage.getItem("token")}"}` }).then(res => res.json()).then(jsondata => { - console.log(jsondata) if (jsondata.enabled === '1') { ftpenabled.checked = true // ftpsettingbody.classList.add('active') diff --git a/src/web/js/settings/settings.js b/src/web/js/settings/settings.js index bc457b4..0c49751 100644 --- a/src/web/js/settings/settings.js +++ b/src/web/js/settings/settings.js @@ -1,6 +1,9 @@ const get_all_settings = () => { get_dns_enabled_status() get_dns_server() + + get_local_domains() + get_ftp_enabled_status() get_telnet_enabled_status() } diff --git a/src/web/js/settings/telnet.js b/src/web/js/settings/telnet.js index 98bf9e4..d156a13 100644 --- a/src/web/js/settings/telnet.js +++ b/src/web/js/settings/telnet.js @@ -8,7 +8,6 @@ const get_telnet_enabled_status = () => { method: 'POST', body: `{"token":"${localStorage.getItem("token")}"}` }).then(res => res.json()).then(jsondata => { - console.log(jsondata) if (jsondata.enabled === '1') { telnetenabled.checked = true addtelnetuserbutton.classList.add('active')