updated added classes and updated web
Prepare Build and Testing executable binary / Prepare-Build-Testing-With-Make (push) Has been cancelled
Prepare Build and Testing executable binary / Prepare-Build-Testing-With-CMake (push) Has been cancelled
Prepare Build and Testing executable binary / Prepare-Build-Testing-With-Meson (push) Has been cancelled

This commit is contained in:
wt
2025-04-24 13:56:58 +07:00
parent cba48908e4
commit 6fe6a1aaf8
50 changed files with 440 additions and 435 deletions
+5 -5
View File
@@ -1,4 +1,4 @@
cmake_minimum_required (VERSION 2.6)
cmake_minimum_required (VERSION 3.6)
project(openrouter)
set(CMAKE_CXX_STANDARD 20)
@@ -33,10 +33,10 @@ add_executable(
src/settings/ftp/ftp.cpp
src/system/reboot/reboot.cpp
src/system/syslog/syslog.cpp
src/system/uptime/uptime.cpp
src/system/update/update.cpp
src/system/reboot.cpp
src/system/syslog.cpp
src/system/uptime.cpp
src/system/update.cpp
src/OpenRouter/OpenRouter.cpp
+4 -4
View File
@@ -20,10 +20,10 @@ SOURCES=src/openrouter.cpp \
src/settings/wifi/qr.cpp \
src/settings/wifi/channel.cpp \
src/settings/ftp/ftp.cpp \
src/system/reboot/reboot.cpp \
src/system/syslog/syslog.cpp \
src/system/uptime/uptime.cpp \
src/system/update/update.cpp \
src/system/reboot.cpp \
src/system/syslog.cpp \
src/system/uptime.cpp \
src/system/update.cpp \
src/OpenRouter/OpenRouter.cpp \
src/auth/auth.cpp \
src/libs/QR-Code-generator/qrcodegen.cpp \
+4 -4
View File
@@ -32,10 +32,10 @@ executable(
'src/settings/ftp/ftp.cpp',
'src/system/reboot/reboot.cpp',
'src/system/syslog/syslog.cpp',
'src/system/uptime/uptime.cpp',
'src/system/update/update.cpp',
'src/system/reboot.cpp',
'src/system/syslog.cpp',
'src/system/uptime.cpp',
'src/system/update.cpp',
'src/OpenRouter/OpenRouter.cpp',
'src/auth/auth.cpp',
+30 -27
View File
@@ -6,41 +6,44 @@
#include <security/cors.hpp>
#include <config/config.hpp>
OpenRouter::OpenRouter()
namespace OpenRouter
{
this->srv.Post("/api/settings/wifi/password/set", api::settings::wifi::set_wifi_password);
this->srv.Post("/api/settings/wifi/qr/get", api::settings::wifi::get_wifi_qr);
OpenRouter::OpenRouter()
{
this->srv.Post("/api/settings/wifi/password/set", api::settings::wifi::Wifi::set_wifi_password);
this->srv.Post("/api/settings/wifi/qr/get", api::settings::wifi::Wifi::get_wifi_qr);
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/settings/get", api::settings::Settings::get);
this->srv.Post("/api/settings/set", api::settings::Settings::set);
this->srv.Get("/api/settings/backup", api::settings::Settings::backup);
this->srv.Post("/api/settings/restore", api::settings::Settings::restore);
this->srv.Post("/api/settings/restore/defaults", api::settings::Settings::restore_defaults);
this->srv.Post("/api/system/reboot", api::system::reboot);
this->srv.Get("/api/system/syslog", api::system::get_syslog);
this->srv.Post("/api/system/reboot", api::system::System::reboot);
this->srv.Get("/api/system/syslog", api::system::System::get_syslog);
#ifdef __linux__
this->srv.Get("/api/system/uptime", api::system::get_uptime);
this->srv.Get("/api/system/uptime", api::system::System::get_uptime);
#endif // __linux__
this->srv.Post("/api/system/update/upload", api::system::update::upload);
this->srv.Post("/api/system/update/update", api::system::update::update);
this->srv.Get("/api/system/update/progress", api::system::update::progress);
this->srv.Post("/api/system/update/upload", api::system::System::upload);
this->srv.Post("/api/system/update/update", api::system::System::update);
this->srv.Get("/api/system/update/progress", api::system::System::progress);
this->srv.Options("/(.*)", api::security::set_cors_headers);
this->srv.Options("/(.*)", api::security::set_cors_headers);
this->srv.set_mount_point("/", config::config.getConfig()["static"]["root"]);
this->srv.set_mount_point("/js", config::config.getConfig()["static"]["js"]);
this->srv.set_mount_point("/css", config::config.getConfig()["static"]["css"]);
}
this->srv.set_mount_point("/", config::config.getConfig()["static"]["root"]);
this->srv.set_mount_point("/js", config::config.getConfig()["static"]["js"]);
this->srv.set_mount_point("/css", config::config.getConfig()["static"]["css"]);
}
OpenRouter::~OpenRouter() = default;
OpenRouter::~OpenRouter() = default;
int OpenRouter::serve(const std::string& ip, int port, int socket_flags)
{
std::cout << GREEN << "Starting" << RESET << " server on [ " << YELLOW
<< "0.0.0.0" << RESET << ":" << CYAN << "43244" << RESET << " ]" << std::endl;
int OpenRouter::serve(const std::string& ip, int port, int socket_flags)
{
std::cout << GREEN << "Starting" << RESET << " server on [ " << YELLOW
<< "0.0.0.0" << RESET << ":" << CYAN << "43244" << RESET << " ]" << std::endl;
syslog(LOG_INFO, "openrouter administration software started.");
this->srv.listen(ip, port, socket_flags);
return 0;
syslog(LOG_INFO, "openrouter administration software started.");
this->srv.listen(ip, port, socket_flags);
return 0;
}
}
+11 -8
View File
@@ -4,13 +4,16 @@
#define CORS_ENABLE
class OpenRouter
namespace OpenRouter
{
private:
httplib::Server srv;
class OpenRouter
{
private:
httplib::Server srv;
public:
OpenRouter();
~OpenRouter();
int serve(const std::string& ip, int port, int socket_flags = 0);
};
public:
OpenRouter();
~OpenRouter();
int serve(const std::string& ip, int port, int socket_flags = 0);
};
}
+5 -2
View File
@@ -3,10 +3,13 @@
int main()
{
OpenRouter router;
OpenRouter::OpenRouter router;
#ifdef TEST
return 0;
#else
return router.serve(config::config.getConfig()["server"]["ip"], config::config.getConfig()["server"]["port"]);
return router.serve(
config::config.getConfig()["server"]["ip"],
config::config.getConfig()["server"]["port"]
);
#endif
}
+1 -1
View File
@@ -7,7 +7,7 @@ namespace api
{
void set_cors_headers(const httplib::Request& request, httplib::Response& response)
{
std::cout << GREEN << request.path << " " << std::endl;
std::cout << GREEN << request.path << " " << request.method << std::endl;
response.set_header("Access-Control-Allow-Origin", "*");
response.set_header("Access-Control-Allow-Methods", "GET,POST,OPTIONS");
response.set_header("Access-Control-Allow-Headers", "Authorization,X-Custom,Content-Type");
+3 -3
View File
@@ -9,7 +9,7 @@ namespace api
{
namespace settings
{
void backup(const httplib::Request& request, httplib::Response& response)
void Settings::backup(const httplib::Request& request, httplib::Response& response)
{
std::ifstream backup_file(config::config.getConfigFileName());
std::stringstream backup_file_buffer;
@@ -18,7 +18,7 @@ namespace api
response.set_content(backup_file_buffer.str(), JSON_TYPE);
}
void restore(const httplib::Request& request, httplib::Response& response)
void Settings::restore(const httplib::Request& request, httplib::Response& response)
{
const httplib::MultipartFormData& file = request.get_file_value("restore_settings");
if (file.content_type == JSON_TYPE) {
@@ -34,7 +34,7 @@ namespace api
response.set_content(R"({"status":false})", JSON_TYPE);
}
void restore_defaults(const httplib::Request& request, httplib::Response& response)
void Settings::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", "*");
+6 -3
View File
@@ -7,9 +7,12 @@ namespace api
{
namespace dns
{
void set_dns(bool new_dns_enabled);
void set_dns_servers(nlohmann::json servers);
void set_local_domains(nlohmann::json domains);
class Dns {
public:
static void set_dns(bool new_dns_enabled);
static void set_dns_servers(nlohmann::json servers);
static void set_local_domains(nlohmann::json domains);
};
}
}
}
+1 -1
View File
@@ -7,7 +7,7 @@ namespace api
{
namespace dns
{
void set_dns(bool new_dns_enabled)
void Dns::set_dns(bool new_dns_enabled)
{
if (!new_dns_enabled)
{
+1 -1
View File
@@ -8,7 +8,7 @@ namespace api
{
namespace dns
{
void set_local_domains(nlohmann::json domains)
void Dns::set_local_domains(nlohmann::json domains)
{
std::ofstream domainsfile("/etc/dnsmasq.conf.d/hosts");
for (nlohmann::json_abi_v3_11_3::json domain : domains)
+1 -1
View File
@@ -8,7 +8,7 @@ namespace api
{
namespace dns
{
void set_dns_servers(nlohmann::json servers)
void Dns::set_dns_servers(nlohmann::json servers)
{
std::ofstream dnsserversfile("/etc/dnsmasq.conf.d/resolv.conf");
for (const nlohmann::json_abi_v3_11_3::json& server : servers)
+1 -1
View File
@@ -10,7 +10,7 @@ namespace api
{
namespace ftp
{
void set_ftp(bool new_ftp_enabled)
void Ftp::set_ftp(bool new_ftp_enabled)
{
if (!new_ftp_enabled)
{
+4 -1
View File
@@ -5,7 +5,10 @@ namespace api
{
namespace ftp
{
void set_ftp(bool new_ftp_enabled);
class Ftp {
public:
static void set_ftp(bool new_ftp_enabled);
};
}
}
}
+16 -16
View File
@@ -13,31 +13,31 @@ namespace api
{
namespace settings
{
void set_all_settings(nlohmann::json json_body)
void Settings::set_all_settings(nlohmann::json json_body)
{
api::settings::wifi::set_wifi_status(json_body["settings"]["wifi"]["enabled"]);
api::settings::wifi::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::wifi::Wifi::set_wifi_channel(std::stoi(wifichannel));
api::settings::wifi::Wifi::set_wifi_name(json_body["settings"]["wifi"]["name"]);
api::settings::telnet::set_telnet(json_body["settings"]["telnet"]["enabled"]);
api::settings::telnet::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::telnet::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"]);
api::settings::ssh::Ssh::set_ssh_status(json_body["settings"]["ssh"]["enabled"]);
api::settings::ssh::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::ssh::Ssh::set_ssh_port(std::stoi(sshport));
api::settings::ssh::Ssh::set_ssh_keys(json_body["settings"]["ssh"]["keys"]);
api::settings::ftp::set_ftp(json_body["settings"]["ftp"]["enabled"]);
api::settings::ftp::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"]);
api::settings::dns::Dns::set_dns(json_body["settings"]["dns"]["enabled"]);
api::settings::dns::Dns::set_dns_servers(json_body["settings"]["dns"]["servers"]);
api::settings::dns::Dns::set_local_domains(json_body["settings"]["dns"]["localdomains"]);
}
void get(const httplib::Request& request, httplib::Response& response)
void Settings::get(const httplib::Request& request, httplib::Response& response)
{
std::cout << GREEN << request.path << RESET << " " << request.method << std::endl;
response.set_header("Access-Control-Allow-Origin", "*");
@@ -53,7 +53,7 @@ namespace api
response.set_content(responsedata, JSON_TYPE);
}
void set(const httplib::Request& request, httplib::Response& response)
void Settings::set(const httplib::Request& request, httplib::Response& response)
{
std::cout << GREEN << request.path << RESET << " " << request.method << std::endl;
response.set_header("Access-Control-Allow-Origin", "*");
+10 -6
View File
@@ -9,11 +9,15 @@ 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);
class Settings {
private:
static void set_all_settings(nlohmann::json json_body);
public:
static void backup(const httplib::Request& request, httplib::Response& response);
static void restore(const httplib::Request& request, httplib::Response& response);
static void restore_defaults(const httplib::Request& request, httplib::Response& response);
static void get(const httplib::Request& request, httplib::Response& response);
static void set(const httplib::Request& request, httplib::Response& response);
};
}
}
+4 -3
View File
@@ -13,19 +13,20 @@ namespace api
{
namespace ssh
{
void set_ssh_keys(nlohmann::json keys)
void Ssh::set_ssh_keys(nlohmann::json keys)
{
std::ofstream keysfile(KEYS_PATH);
std::string ssh_server = get_ssh_server();
for (std::string key : keys)
{
keysfile << key << "\n";
}
keysfile.close();
if (get_ssh_server() == OPENSSH_SSH)
if (ssh_server == OPENSSH_SSH)
{
system("rc restart ssh");
}
else if (get_ssh_server() == DROPBEAR_SSH)
else if (ssh_server == DROPBEAR_SSH)
{
system("rc restart dropbear");
}
+6 -5
View File
@@ -15,12 +15,13 @@ namespace api
{
namespace ssh
{
void set_ssh_port(int new_ssh_port)
void Ssh::set_ssh_port(int new_ssh_port)
{
std::string old_ssh_port_string = config::config.getConfig()["settings"]["ssh"]["port"];
int old_ssh_port = std::stoi(old_ssh_port_string);
std::string systemrequest;
if (get_ssh_server() == DROPBEAR_SSH)
std::string ssh_server = get_ssh_server();
if (ssh_server == DROPBEAR_SSH)
{
systemrequest += "sed -i \"s/DROPBEAR_PORT=" \
+ std::to_string(old_ssh_port) \
@@ -29,7 +30,7 @@ namespace api
+ "/g\" " \
+ DROPBEAR_DEFAULT_FILE;
}
else if (get_ssh_server() == OPENSSH_SSH)
else if (ssh_server == OPENSSH_SSH)
{
systemrequest += "sed -i \"/Port " \
+ std::to_string(old_ssh_port) \
@@ -40,11 +41,11 @@ namespace api
}
std::cout << systemrequest << std::endl;
system(systemrequest.c_str());
if (get_ssh_server() == OPENSSH_SSH)
if (ssh_server == OPENSSH_SSH)
{
system("rc restart ssh");
}
else if (get_ssh_server() == DROPBEAR_SSH)
else if (ssh_server == DROPBEAR_SSH)
{
system("rc restart dropbear");
}
+2 -2
View File
@@ -9,13 +9,13 @@ namespace api
{
namespace ssh
{
std::string get_ssh_server()
std::string Ssh::get_ssh_server()
{
config::config.setConfig(config::config.getConfigFileName());
return config::config.getConfig()["settings"]["ssh"]["server"];
}
void set_ssh_server(std::string new_server)
void Ssh::set_ssh_server(std::string new_server)
{
if (new_server == DROPBEAR_SSH)
{
+9 -5
View File
@@ -10,11 +10,15 @@ namespace api
{
namespace ssh
{
std::string get_ssh_server();
void set_ssh_server(std::string new_server);
void set_ssh_status(bool new_ssh_status);
void set_ssh_keys(nlohmann::json keys);
void set_ssh_port(int port);
class Ssh {
private:
static std::string get_ssh_server();
public:
static void set_ssh_server(std::string new_server);
static void set_ssh_status(bool new_ssh_status);
static void set_ssh_keys(nlohmann::json keys);
static void set_ssh_port(int port);
};
}
}
}
+6 -5
View File
@@ -9,16 +9,17 @@ namespace api
{
namespace ssh
{
void set_ssh_status(bool new_ssh_status)
void Ssh::set_ssh_status(bool new_ssh_status)
{
std::string ssh_server = get_ssh_server();
if (!new_ssh_status)
{
if (get_ssh_server() == DROPBEAR_SSH)
if (ssh_server == DROPBEAR_SSH)
{
system("rc stop dropbear");
system("rc del dropbear");
}
else if (get_ssh_server() == OPENSSH_SSH) {
else if (ssh_server == OPENSSH_SSH) {
system("rc stop ssh");
system("rc del ssh");
}
@@ -26,12 +27,12 @@ namespace api
}
else
{
if (get_ssh_server() == DROPBEAR_SSH)
if (ssh_server == DROPBEAR_SSH)
{
system("rc start dropbear");
system("rc add dropbear");
}
else if (get_ssh_server() == OPENSSH_SSH) {
else if (ssh_server == OPENSSH_SSH) {
system("rc start ssh");
system("rc add ssh");
}
+1 -1
View File
@@ -10,7 +10,7 @@ namespace api
{
namespace telnet
{
void set_telnet(bool new_telnet_enabled)
void Telnet::set_telnet(bool new_telnet_enabled)
{
if (!new_telnet_enabled)
{
+1 -1
View File
@@ -11,7 +11,7 @@ namespace api
{
namespace telnet
{
void set_telnet_port(int new_telnet_port)
void Telnet::set_telnet_port(int new_telnet_port)
{
std::string old_telnet_port_string = config::config.getConfig()["settings"]["telnet"]["port"];
int old_telnet_port = std::stoi(old_telnet_port_string);
+5 -2
View File
@@ -5,8 +5,11 @@ namespace api
{
namespace telnet
{
void set_telnet(bool new_telnet_enabled);
void set_telnet_port(int new_telnet_port);
class Telnet {
public:
static void set_telnet(bool new_telnet_enabled);
static void set_telnet_port(int new_telnet_port);
};
}
}
}
+1 -1
View File
@@ -11,7 +11,7 @@ namespace api
{
namespace wifi
{
void set_wifi_channel(int new_channel)
void Wifi::set_wifi_channel(int new_channel)
{
std::ifstream wifisettingsfile(WIFI_SETTINGS_PATH);
std::string old_channel_string;
+1 -1
View File
@@ -11,7 +11,7 @@ namespace api
{
namespace wifi
{
void set_wifi_name(std::string new_wifi_name)
void Wifi::set_wifi_name(std::string new_wifi_name)
{
std::ifstream wifisettingsfile(WIFI_SETTINGS_PATH);
std::string old_wifi_name;
+1 -1
View File
@@ -17,7 +17,7 @@ namespace api
{
namespace wifi
{
void set_wifi_password(const httplib::Request& request, httplib::Response& response)
void Wifi::set_wifi_password(const httplib::Request& request, httplib::Response& response)
{
std::cout << GREEN << request.path << RESET << " " << request.method << std::endl;
response.set_header("Access-Control-Allow-Origin", "*");
+1 -1
View File
@@ -14,7 +14,7 @@ namespace api
{
namespace wifi
{
void get_wifi_qr(const httplib::Request& request, httplib::Response& response)
void Wifi::get_wifi_qr(const httplib::Request& request, httplib::Response& response)
{
std::cout << GREEN << request.path << RESET << " " << request.method << std::endl;
response.set_header("Access-Control-Allow-Origin", "*");
+1 -1
View File
@@ -9,7 +9,7 @@ namespace api
{
namespace wifi
{
void set_wifi_status(bool new_wifi_status)
void Wifi::set_wifi_status(bool new_wifi_status)
{
if (!new_wifi_status)
{
+8 -5
View File
@@ -9,11 +9,14 @@ namespace api
{
namespace wifi
{
void set_wifi_status(bool new_wifi_status);
void set_wifi_name(std::string new_wifi_name);
void set_wifi_password(const httplib::Request& request, httplib::Response& response);
void get_wifi_qr(const httplib::Request& request, httplib::Response& response);
void set_wifi_channel(int new_channel);
class Wifi {
public:
static void set_wifi_status(bool new_wifi_status);
static void set_wifi_name(std::string new_wifi_name);
static void set_wifi_password(const httplib::Request& request, httplib::Response& response);
static void get_wifi_qr(const httplib::Request& request, httplib::Response& response);
static void set_wifi_channel(int new_channel);
};
}
}
}
@@ -1,4 +1,4 @@
#include <system/reboot/reboot.hpp>
#include <system/system.hpp>
#include <json.hpp>
#include <colors.h>
#include <types.hpp>
@@ -9,7 +9,7 @@ namespace api
{
namespace system
{
void reboot(const httplib::Request& request, httplib::Response& response)
void System::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", "*");
-11
View File
@@ -1,11 +0,0 @@
#pragma once
#include <httplib.h>
namespace api
{
namespace system
{
void reboot(const httplib::Request& request, httplib::Response& response);
}
}
@@ -1,4 +1,4 @@
#include <system/syslog/syslog.hpp>
#include <system/system.hpp>
#include <types.hpp>
#include <json.hpp>
#include <iostream>
@@ -11,7 +11,7 @@ namespace api
{
namespace system
{
void get_syslog(const httplib::Request& request, httplib::Response& response)
void System::get_syslog(const httplib::Request& request, httplib::Response& response)
{
std::stringstream responsedata;
std::ifstream syslogfile(SYSLOG_FILE);
-11
View File
@@ -1,11 +0,0 @@
#pragma once
#include <httplib.h>
namespace api
{
namespace system
{
void get_syslog(const httplib::Request& request, httplib::Response& response);
}
}
+19 -6
View File
@@ -1,8 +1,21 @@
#pragma once
#ifdef __linux__
#include <system/uptime/uptime.hpp>
#endif // __linux__
#include <system/syslog/syslog.hpp>
#include <system/reboot/reboot.hpp>
#include <system/update/update.hpp>
#include <httplib.h>
namespace api
{
namespace system
{
class System {
private:
static bool compareFile(std::string tmpfilename, std::string dstfilename);
public:
static void get_uptime(const httplib::Request& request, httplib::Response& response);
static void upload(const httplib::Request& request, httplib::Response& response);
static void update(const httplib::Request& request, httplib::Response& response);
static void progress(const httplib::Request& request, httplib::Response& response);
static void get_syslog(const httplib::Request& request, httplib::Response& response);
static void reboot(const httplib::Request& request, httplib::Response& response);
};
}
}
+133
View File
@@ -0,0 +1,133 @@
#include <system/system.hpp>
#include <types.hpp>
#include <auth/auth.hpp>
#include <filesystem>
#include <colors.h>
#include <iostream>
#include <json.hpp>
#include <pthread.h>
#include <helpers.hpp>
#define DEFAULT_TMP_FILE_NAME "/tmp/image"
#define DEFAULT_DST_FILE_NAME "/images/image"
#define BLOCK_SIZE 131072
namespace api
{
namespace system
{
static int update_progress = 0;
static bool compare = false;
bool System::compareFile(std::string tmpfilename, std::string dstfilename)
{
FILE* tmp = fopen(tmpfilename.c_str(), "r");
FILE* dst = fopen(dstfilename.c_str(), "r");
char tmpbuffer[BLOCK_SIZE];
char dstbuffer[BLOCK_SIZE];
do {
size_t tmpread = fread(tmpbuffer, 1, BLOCK_SIZE, tmp);
size_t dstread = fread(dstbuffer, 1, BLOCK_SIZE, dst);
if (tmpread != dstread || memcmp(tmpbuffer, dstbuffer, tmpread)) {
fclose(tmp);
fclose(dst);
return false;
}
} while (!feof(tmp) || !feof(dst));
fclose(tmp);
fclose(dst);
return true;
}
void System::upload(const httplib::Request& request, httplib::Response& response)
{
std::cout << GREEN << request.path << RESET << " " << request.method << std::endl;
bool ret = request.has_file("image");
if (!ret) {
response.set_content(R"({"required":[token, file]})", JSON_TYPE);
}
bool has_token = request.has_file("token");
if (!has_token) {
response.set_content(ACCESS_REQUIRED_STRING, JSON_TYPE);
return;
}
if (!authenticate(request.get_file_value("token").content))
{
response.set_content(R"({"access":"reject"})", JSON_TYPE);
return;
}
const httplib::MultipartFormData& file = request.get_file_value("image");
std::ofstream tmp_image_file(DEFAULT_TMP_FILE_NAME);
tmp_image_file << file.content;
tmp_image_file.close();
response.set_content(R"({"status":true})", JSON_TYPE);
}
void System::update(const httplib::Request& request, httplib::Response& response)
{
std::cout << GREEN << request.path << RESET << " " << request.method << std::endl;
response.set_header("Access-Control-Allow-Origin", "*");
check_body_empty(request, response, ACCESS_REQUIRED_STRING);
nlohmann::json json_body = nlohmann::json::parse(request.body);
check_body_data(json_body, "token", response, ACCESS_REQUIRED_STRING);
if (!authenticate(json_body["token"]))
{
response.set_content(R"({"access":"reject"})", JSON_TYPE);
return;
}
bool needAutoReboot = json_body["needAutoReboot"];
update_progress = 0;
compare = false;
int file_image_size = std::filesystem::file_size(DEFAULT_TMP_FILE_NAME);
int block_count = file_image_size / BLOCK_SIZE;
int remainder = file_image_size % BLOCK_SIZE;
int skip = 0;
char buffer[BLOCK_SIZE];
std::ifstream tmp(DEFAULT_TMP_FILE_NAME);
std::ofstream dst(DEFAULT_DST_FILE_NAME);
while (skip < block_count) {
tmp.read(buffer, BLOCK_SIZE);
dst.write(buffer, BLOCK_SIZE);
update_progress = 100 * skip / block_count;
skip++;
std::cout << update_progress << "% was copied" << std::endl;
memset(buffer, 0, BLOCK_SIZE);
}
if (remainder > 0) {
tmp.read(buffer, remainder);
dst.write(buffer, remainder);
update_progress = 100;
std::cout << update_progress << "% was copied" << std::endl;
}
update_progress = 100;
std::cout << update_progress << "% was copied" << std::endl;
tmp.close();
dst.close();
compare = compareFile(DEFAULT_TMP_FILE_NAME, DEFAULT_DST_FILE_NAME);
if (!compare) {
std::cout << "files not equvalents: writing file error." << std::endl;
response.set_content(R"({"success":false})", JSON_TYPE);
return;
}
std::remove(DEFAULT_TMP_FILE_NAME);
if (needAutoReboot) {
std::cout << "reboot" << std::endl;
std::system("sleep 2; reboot;");
return;
}
response.set_content(R"({"success":true})", JSON_TYPE);
}
void System::progress(const httplib::Request& request, httplib::Response& response)
{
std::cout << GREEN << request.path << RESET << " " << request.method << std::endl;
std::string responsedata = R"({"progress":)" + std::to_string(update_progress) + "}";
response.set_content(responsedata, JSON_TYPE);
}
}
}
-135
View File
@@ -1,135 +0,0 @@
#include <system/update/update.hpp>
#include <types.hpp>
#include <auth/auth.hpp>
#include <filesystem>
#include <colors.h>
#include <iostream>
#include <json.hpp>
#include <pthread.h>
#include <helpers.hpp>
#define DEFAULT_TMP_FILE_NAME "/tmp/image"
#define DEFAULT_DST_FILE_NAME "/images/image"
#define BLOCK_SIZE 131072
namespace api
{
namespace system
{
namespace update
{
static int update_progress = 0;
static bool compare = false;
bool compareFile(std::string tmpfilename, std::string dstfilename) {
FILE *tmp = fopen(tmpfilename.c_str(), "r");
FILE *dst = fopen(dstfilename.c_str(), "r");
char tmpbuffer[BLOCK_SIZE];
char dstbuffer[BLOCK_SIZE];
do {
size_t tmpread = fread(tmpbuffer, 1, BLOCK_SIZE, tmp);
size_t dstread = fread(dstbuffer, 1, BLOCK_SIZE, dst);
if (tmpread != dstread || memcmp(tmpbuffer, dstbuffer, tmpread)) {
fclose(tmp);
fclose(dst);
return false;
}
} while (!feof(tmp) || !feof(dst));
fclose(tmp);
fclose(dst);
return true;
}
void upload(const httplib::Request& request, httplib::Response& response)
{
std::cout << GREEN << request.path << RESET << " " << request.method << std::endl;
bool ret = request.has_file("image");
if (!ret) {
response.set_content(R"({"required":[token, file]})", JSON_TYPE);
}
bool has_token = request.has_file("token");
if (!has_token) {
response.set_content(ACCESS_REQUIRED_STRING, JSON_TYPE);
return;
}
if (!authenticate(request.get_file_value("token").content))
{
response.set_content(R"({"access":"reject"})", JSON_TYPE);
return;
}
const httplib::MultipartFormData& file = request.get_file_value("image");
std::ofstream tmp_image_file(DEFAULT_TMP_FILE_NAME);
tmp_image_file << file.content;
tmp_image_file.close();
response.set_content(R"({"status":true})", JSON_TYPE);
}
void update(const httplib::Request& request, httplib::Response& response)
{
std::cout << GREEN << request.path << RESET << " " << request.method << std::endl;
response.set_header("Access-Control-Allow-Origin", "*");
check_body_empty(request, response, ACCESS_REQUIRED_STRING);
nlohmann::json json_body = nlohmann::json::parse(request.body);
check_body_data(json_body, "token", response, ACCESS_REQUIRED_STRING);
if (!authenticate(json_body["token"]))
{
response.set_content(R"({"access":"reject"})", JSON_TYPE);
return;
}
bool needAutoReboot = json_body["needAutoReboot"];
update_progress = 0;
compare = false;
int file_image_size = std::filesystem::file_size(DEFAULT_TMP_FILE_NAME);
int block_count = file_image_size / BLOCK_SIZE;
int remainder = file_image_size % BLOCK_SIZE;
int skip = 0;
char buffer[BLOCK_SIZE];
std::ifstream tmp(DEFAULT_TMP_FILE_NAME);
std::ofstream dst(DEFAULT_DST_FILE_NAME);
while (skip < block_count) {
tmp.read(buffer, BLOCK_SIZE);
dst.write(buffer, BLOCK_SIZE);
update_progress = 100 * skip / block_count;
skip++;
std::cout << update_progress << "% was copied" << std::endl;
memset(buffer, 0, BLOCK_SIZE);
}
if (remainder > 0) {
tmp.read(buffer, remainder);
dst.write(buffer, remainder);
update_progress = 100;
std::cout << update_progress << "% was copied" << std::endl;
}
update_progress = 100;
std::cout << update_progress << "% was copied" << std::endl;
tmp.close();
dst.close();
compare = compareFile(DEFAULT_TMP_FILE_NAME, DEFAULT_DST_FILE_NAME);
if (!compare) {
std::cout << "files not equvalents: writing file error." << std::endl;
response.set_content(R"({"success":false})", JSON_TYPE);
return;
}
std::remove(DEFAULT_TMP_FILE_NAME);
if (needAutoReboot) {
std::cout << "reboot" << std::endl;
std::system("sleep 2; reboot;");
return;
}
response.set_content(R"({"success":true})", JSON_TYPE);
}
void progress(const httplib::Request& request, httplib::Response& response)
{
std::cout << GREEN << request.path << RESET << " " << request.method << std::endl;
std::string responsedata = R"({"progress":)" + std::to_string(update_progress) + "}";
response.set_content(responsedata, JSON_TYPE);
}
}
}
}
-16
View File
@@ -1,16 +0,0 @@
#pragma once
#include <httplib.h>
namespace api
{
namespace system
{
namespace update
{
void upload(const httplib::Request& request, httplib::Response& response);
void update(const httplib::Request& request, httplib::Response& response);
void progress(const httplib::Request& request, httplib::Response& response);
}
}
}
@@ -1,4 +1,4 @@
#include <system/uptime/uptime.hpp>
#include <system/system.hpp>
#ifdef __linux__
#include <sys/sysinfo.h>
#endif // __linux__
@@ -8,7 +8,7 @@ namespace api
{
namespace system
{
void get_uptime(const httplib::Request& request, httplib::Response& response)
void System::get_uptime(const httplib::Request& request, httplib::Response& response)
{
#ifdef __linux__
struct sysinfo x;
-11
View File
@@ -1,11 +0,0 @@
#pragma once
#include <httplib.h>
namespace api
{
namespace system
{
void get_uptime(const httplib::Request& request, httplib::Response& response);
}
}
-39
View File
@@ -11,7 +11,6 @@
padding: 10px;
transform: scale(0.5);
opacity: 0;
transition: 0.3s;
position: absolute;
margin: auto;
}
@@ -58,44 +57,6 @@
gap: 10px;
}
/* .forminputbody.confirmform>button {
width: 100%;
}
.forminputlabel {
text-align: center;
font-style: normal;
font-size: 20px;
margin: 5px 0;
}
.forminput {
padding: 10px;
border-radius: 10px;
border: 2px solid;
transition: 0.2s;
background-color: inherit;
}
.forminput>option {
background-color: inherit;
color: black;
}
.forminput:focus {
border: 5px solid;
}
.formbutton {
padding: 10px;
border-radius: 10px;
border: none;
cursor: pointer;
transition: 0.3s;
width: 100%;
} */
@media screen and (max-width: 800px) {
.forminputbody {
width: 100%;
+19 -1
View File
@@ -1,10 +1,13 @@
* {
transition: 0.3s;
}
.adminpanel {
position: relative;
width: 100%;
height: 100vh;
transform: scale(0.5);
opacity: 0;
transition: 0.3s;
display: flex;
flex-direction: column;
gap: 10px;
@@ -22,3 +25,18 @@
height: 100%;
width: 100%;
}
.somesection {
position: absolute;
top: 0;
left: 0;
width: 100%;
opacity: 0;
pointer-events: none;
}
.somesection.active {
opacity: 1;
pointer-events: all;
}
-2
View File
@@ -3,10 +3,8 @@
top: 0;
left: 0;
width: 100%;
/* height: 100%; */
opacity: 0;
pointer-events: none;
transition: 0.3s;
padding: 10px;
}
+2 -3
View File
@@ -2,7 +2,7 @@
width: max-content;
height: 100vh;
position: fixed;
top: 0;
top: 50px;
right: 0;
pointer-events: none;
z-index: 1;
@@ -18,7 +18,6 @@
/* position: fixed; */
top: 0;
right: 0;
transition: 0.3s;
cursor: pointer;
opacity: 0.8;
margin: 10px;
@@ -50,4 +49,4 @@
pointer-events: all;
height: 10%;
background-color: rgb(76, 209, 76);
}
}
-5
View File
@@ -8,7 +8,6 @@
margin: 0;
position: relative;
width: 30px;
transition: 0.3s;
}
.checkbox-wrapper-2 .ikxBAC::before {
@@ -18,13 +17,11 @@
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 {
@@ -45,7 +42,6 @@
.checkbox-wrapper-2 .ikxBAC:hover {
background-color: #c9cbcd;
transition-duration: 0s;
}
.checkbox-wrapper-2 .ikxBAC:checked {
@@ -72,7 +68,6 @@
width: 100%;
height: calc(100vh - 50px);
padding: 10px;
transition: 0.3s;
opacity: 0;
pointer-events: none;
overflow-y: auto;
-1
View File
@@ -6,7 +6,6 @@
height: 100%;
opacity: 0;
pointer-events: none;
transition: 0.3s;
padding: 10px;
}
+79 -66
View File
@@ -19,7 +19,7 @@
<!-- header -->
<nav class="navbar navbar-expand-lg bg-body-tertiary">
<div class="container-fluid">
<a class="navbar-brand" href="#">Openrouter</a>
<a class="navbar-brand" href="/">Openrouter</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
@@ -34,6 +34,12 @@
<li class="nav-item">
<button class="nav-link" id="infobutton">Info</button>
</li>
<li class="nav-item">
<button class="nav-link" id="backupsectionbutton">Backup</button>
</li>
<li class="nav-item">
<button class="nav-link" id="updatesectionbutton">Update</button>
</li>
<li class="nav-item">
<button class="nav-link" id="rebootbutton">Reboot</button>
</li>
@@ -82,7 +88,6 @@
</div>
</div>
<div class="card-footer d-grid">
<!-- <button class="settingrectfooterbutton hiddenbutton" id="add_telnet_user_button">Add telnet user</button> -->
<button
class="btn btn-primary"
id="set_telnet_settings"
@@ -234,7 +239,7 @@
</div>
<!-- ssh settings -->
<!-- Wi-Fi settings -->
<div class="card">
<div class="card mb-3">
<div class="card-header d-flex align-items-center justify-content-between">
<h2>WIFI</h2>
<div class="checkbox-wrapper-2">
@@ -307,6 +312,76 @@
</div>
</div>
<!-- Wi-Fi settings -->
</section>
<!-- syslog block -->
<section class="syslogsection">
<div class="d-flex flex-wrap gap-2 align-items-center">
<h2 class="syslogheader">Syslog</h2>
<button id="openrouterfilter" class="btn btn-primary">openrouter</button>
<button id="authservicefilter" class="btn btn-primary">auth_service</button>
<button id="refreshbutton" class="btn btn-primary">&#8634;</button>
<div class="form-check">
<label for="realtimesyslog" class="form-check-label">Realtime</label>
<input type="checkbox" id="realtimesyslog" class="form-check-input"/>
</div>
</div>
<div class="syslogdata"></div>
</section>
<!-- syslog block -->
<section class="infosection d-flex flex-wrap gap-2 justify-content-center align-items-start">
<div class="form-floating" style="height: min-content;">
<input id="infoversion" type="text" disabled class="form-control" value="0.1.1" placeholder="0.1.1">
<label for="infoversion">Version:</label>
</div>
<div class="form-floating" style="height: min-content;">
<input type="text" id="infouptime" class="form-control" placeholder="0h 0m 0s" disabled>
<label for="infouptime">Uptime:</label>
</div>
</section>
<!-- update firmware section -->
<section id="updatesection" class="somesection d-flex flex-wrap gap-2 justify-content-center align-items-start">
<!-- update firmware -->
<div class="card mb-3">
<div class="card-header">
<h2>Update Firmware</h2>
</div>
<div class="card-footer d-grid gap-2" style="flex-direction: column">
<input type="file" name="" id="upload_image_input" hidden/>
<button class="btn btn-primary" id="upload_image_button">Update firmware</button>
<div class="hidden" id="uploadprogress">
<div class="progress" role="progressbar" aria-lable="Upload progress" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">
<div class="progress-bar" id="uploadpercent"></div>
</div>
</div>
<div class="vstack hidden" style="width: 100%; gap: 10px; padding: 0" id="update_block">
<div class="hstack" style="justify-content: space-around;width: 100%;">
<label for="auto_reboot_flag">
Reboot after update?
</label>
<div class="checker">
<div class="checked"></div>
</div>
<div id="noyes">(No)</div>
</div>
<input
id="auto_reboot_flag"
type="checkbox"
hidden
/>
<button class="btn btn-primary" id="update_image_button">Update</button>
</div>
<div class="hidden" id="updateprogress">
<div class="progress" role="progressbar" aria-lable="Upload progress" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">
<div class="progress-bar" id="updatepercent"></div>
</div>
</div>
</div>
</div>
<!-- update firmware -->
</section>
<!-- update firmware section -->
<!-- backup settings section -->
<section id="backupsection" class="somesection d-flex flex-wrap gap-2 justify-content-center align-items-start">
<!-- backup settings -->
<div class="card">
<div class="card-header">
@@ -355,70 +430,8 @@
</div>
</div>
<!-- backup settings -->
<!-- update firmware -->
<div class="card mb-3">
<div class="card-header">
<h2>Update Firmware</h2>
</div>
<div class="card-footer d-grid gap-2" style="flex-direction: column">
<input type="file" name="" id="upload_image_input" hidden/>
<button class="btn btn-primary" id="upload_image_button">Update firmware</button>
<div class="hidden" id="uploadprogress">
<div class="progress" role="progressbar" aria-lable="Upload progress" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">
<div class="progress-bar" id="uploadpercent"></div>
</div>
</div>
<div class="vstack hidden" style="width: 100%; gap: 10px; padding: 0" id="update_block">
<div class="hstack" style="justify-content: space-around;width: 100%;">
<label for="auto_reboot_flag">
Reboot after update?
</label>
<div class="checker">
<div class="checked"></div>
</div>
<div id="noyes">(No)</div>
</div>
<input
id="auto_reboot_flag"
type="checkbox"
hidden
/>
<button class="btn btn-primary" id="update_image_button">Update</button>
</div>
<div class="hidden" id="updateprogress">
<div class="progress" role="progressbar" aria-lable="Upload progress" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">
<div class="progress-bar" id="updatepercent"></div>
</div>
</div>
</div>
</div>
<!-- update firmware -->
</section>
<!-- syslog block -->
<section class="syslogsection">
<div class="d-flex flex-wrap gap-2 align-items-center">
<h2 class="syslogheader">Syslog</h2>
<button id="openrouterfilter" class="btn btn-primary">openrouter</button>
<button id="authservicefilter" class="btn btn-primary">auth_service</button>
<button id="refreshbutton" class="btn btn-primary">&#8634;</button>
<div class="form-check">
<label for="realtimesyslog" class="form-check-label">Realtime</label>
<input type="checkbox" id="realtimesyslog" class="form-check-input"/>
</div>
</div>
<div class="syslogdata"></div>
</section>
<!-- syslog block -->
<section class="infosection d-flex flex-wrap gap-2 justify-content-center align-items-start">
<div class="form-floating" style="height: min-content;">
<input id="infoversion" type="text" disabled class="form-control" value="0.1.1" placeholder="0.1.1">
<label for="infoversion">Version:</label>
</div>
<div class="form-floating" style="height: min-content;">
<input type="text" id="infouptime" class="form-control" placeholder="0h 0m 0s" disabled>
<label for="infouptime">Uptime:</label>
</div>
</section>
<!-- backup settings section -->
</div>
<!-- settings block -->
</section>
+30 -2
View File
@@ -10,17 +10,21 @@ const headerlinks = document.querySelector('.links')
let uptimeintervalid
settingsbutton.addEventListener('click', () => {
settingssection.classList.add('active')
syslogsection.classList.remove('active')
infosection.classList.remove('active')
updatesection.classList.remove('active');
backupsection.classList.remove('active');
settingssection.classList.add('active')
clearInterval(uptimeintervalid)
get_all_settings()
})
syslogbutton.addEventListener('click', () => {
syslogsection.classList.add('active')
settingssection.classList.remove('active')
infosection.classList.remove('active')
updatesection.classList.remove('active');
backupsection.classList.remove('active');
syslogsection.classList.add('active')
clearInterval(uptimeintervalid)
get_syslog_data()
})
@@ -42,6 +46,30 @@ window.addEventListener('click', (e) => {
infobutton.addEventListener('click', () => {
syslogsection.classList.remove('active')
settingssection.classList.remove('active')
updatesection.classList.remove('active');
backupsection.classList.remove('active');
infosection.classList.add('active')
uptimeintervalid = setInterval(get_uptime, 1000)
})
const updatesectionbutton = document.querySelector('#updatesectionbutton');
const updatesection = document.querySelector('#updatesection');
updatesectionbutton.addEventListener('click', () => {
infosection.classList.remove('active');
settingssection.classList.remove('active');
syslogsection.classList.remove('active');
backupsection.classList.remove('active');
updatesection.classList.add('active');
})
const backupsectionbutton = document.querySelector('#backupsectionbutton');
const backupsection = document.querySelector('#backupsection');
backupsectionbutton.addEventListener('click', () => {
infosection.classList.remove('active');
settingssection.classList.remove('active');
syslogsection.classList.remove('active');
updatesection.classList.remove('active');
backupsection.classList.add('active');
})
-1
View File
@@ -64,7 +64,6 @@ const login = async (username, password) => {
await get_user_data();
loginusername.value = "";
loginpassword.value = "";
settingssection.classList.add("active");
}
};
+2 -1
View File
@@ -8,6 +8,7 @@ const notification = (text, type) => {
notificationtext.classList.add('notificationtext')
notificationtextbox.append(notificationtext)
notificationtextbox.classList.add('notificationtextbox')
notificationtextbox.classList.add('card-header')
notificationbox.append(notificationtextbox)
notificationbox.classList.add('notification')
notificationbox.addEventListener('click', () => {
@@ -37,4 +38,4 @@ const notification = (text, type) => {
// notificationbox.classList.remove('active')
// }
// notificationbox.addEventListener('click', closenotification)
// notificationbox.addEventListener('click', closenotification)