|
|
@@ -28,6 +28,7 @@
|
|
|
#include "util/json.h"
|
|
|
|
|
|
#include <atomic>
|
|
|
+#include <cctype>
|
|
|
#include <chrono>
|
|
|
#include <cstdint>
|
|
|
#include <cstdlib>
|
|
|
@@ -336,12 +337,43 @@ void reg(ylib::network::http::router* router, const std::string& path,
|
|
|
|
|
|
// ---- handlers ----
|
|
|
|
|
|
+std::string trim_copy(std::string s) {
|
|
|
+ size_t a = 0;
|
|
|
+ while (a < s.size() &&
|
|
|
+ std::isspace(static_cast<unsigned char>(s[a]))) {
|
|
|
+ ++a;
|
|
|
+ }
|
|
|
+ size_t b = s.size();
|
|
|
+ while (b > a && std::isspace(static_cast<unsigned char>(s[b - 1]))) {
|
|
|
+ --b;
|
|
|
+ }
|
|
|
+ return s.substr(a, b - a);
|
|
|
+}
|
|
|
+
|
|
|
+std::string panel_display_name() {
|
|
|
+ std::string n = trim_copy(store::get_setting("panel.name", ""));
|
|
|
+ if (n.empty()) {
|
|
|
+ return "NGS";
|
|
|
+ }
|
|
|
+ if (n.size() > 64) {
|
|
|
+ n.resize(64);
|
|
|
+ }
|
|
|
+ return n;
|
|
|
+}
|
|
|
+
|
|
|
+ylib::json settings_json() {
|
|
|
+ ylib::json data;
|
|
|
+ data["panel_name"] = panel_display_name();
|
|
|
+ return data;
|
|
|
+}
|
|
|
+
|
|
|
void h_ping(request* req, response* resp) {
|
|
|
if (!require_method(req, resp, "GET")) {
|
|
|
return;
|
|
|
}
|
|
|
ylib::json data;
|
|
|
data["name"] = "ngs";
|
|
|
+ data["panel_name"] = panel_display_name();
|
|
|
data["listen"] = std::string(kDefaultListenAddr) + ":" +
|
|
|
std::to_string(kDefaultListenPort);
|
|
|
reply_ok(resp, data);
|
|
|
@@ -713,9 +745,43 @@ void h_status(request* req, response* resp) {
|
|
|
data["redis"] = rd;
|
|
|
|
|
|
data["sites"] = static_cast<int>(website::list_sites().size());
|
|
|
+ data["panel_name"] = panel_display_name();
|
|
|
reply_ok(resp, data);
|
|
|
}
|
|
|
|
|
|
+void h_settings(request* req, response* resp) {
|
|
|
+ const std::string method = req->method();
|
|
|
+ if (method == "GET") {
|
|
|
+ reply_ok(resp, settings_json());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (method == "POST") {
|
|
|
+ const auto body = parse_body(req);
|
|
|
+ std::string name = trim_copy(json_str(body, "panel_name"));
|
|
|
+ if (name.empty()) {
|
|
|
+ reply_err(resp, "请填写网站名称");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (name.size() > 64) {
|
|
|
+ reply_err(resp, "网站名称最多 64 个字符");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ for (unsigned char c : name) {
|
|
|
+ if (c < 0x20) {
|
|
|
+ reply_err(resp, "网站名称不能包含控制字符");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!store::set_setting("panel.name", name)) {
|
|
|
+ reply_err(resp, "保存失败");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ reply_ok(resp, settings_json(), "已保存");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ reply_err(resp, "method not allowed", 405);
|
|
|
+}
|
|
|
+
|
|
|
ylib::json self_info_json(const selfupdate::Info& info) {
|
|
|
ylib::json data;
|
|
|
data["source_dir"] = info.source_dir;
|
|
|
@@ -2498,6 +2564,7 @@ void register_routes(ylib::network::http::router* router) {
|
|
|
reg(router, "/api/auth/me", h_auth_me, false);
|
|
|
|
|
|
reg(router, "/api/status", h_status);
|
|
|
+ reg(router, "/api/settings", h_settings);
|
|
|
reg(router, "/api/self/version", h_self_version);
|
|
|
reg(router, "/api/self/check", h_self_check);
|
|
|
reg(router, "/api/self/update", h_self_update);
|