package handlers import ( "fmt" "net/http" "strings" "amnezia-share/internal/panel" "amnezia-share/internal/settings" "amnezia-share/internal/web" ) type adminSettingsView struct { adminLayout PanelURL string APIToken string ServerLabelsJSON string TrafficNotices string Maintenance bool PocketURL string PocketClientID string PocketSecret string MemberDays string MemberMaxUses string TestResult string TestError string } func loadAdminSettingsView(a *web.App, r *http.Request) adminSettingsView { ctx := r.Context() vals, _ := a.Settings.GetMany(ctx, settings.KeyPanelURL, settings.KeyAPIToken, settings.KeyServerLabelsJSON, settings.KeyTrafficNotices, settings.KeyMaintenance, settings.KeyPocketURL, settings.KeyPocketClientID, settings.KeyPocketSecret, settings.KeyMemberDays, settings.KeyMemberMaxUses, ) return adminSettingsView{ adminLayout: newAdminLayout(a, r, "settings"), PanelURL: vals[settings.KeyPanelURL], APIToken: vals[settings.KeyAPIToken], ServerLabelsJSON: vals[settings.KeyServerLabelsJSON], TrafficNotices: vals[settings.KeyTrafficNotices], Maintenance: vals[settings.KeyMaintenance] == "1", PocketURL: vals[settings.KeyPocketURL], PocketClientID: vals[settings.KeyPocketClientID], PocketSecret: vals[settings.KeyPocketSecret], MemberDays: vals[settings.KeyMemberDays], MemberMaxUses: vals[settings.KeyMemberMaxUses], } } // AdminSettingsGet renders the settings form (admin/settings.php GET). func AdminSettingsGet(a *web.App) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { view := loadAdminSettingsView(a, r) view.OK, view.Error = flashFromQuery(r) a.Render(w, r, "page_admin_settings", view) } } // AdminSettingsPost saves settings, or runs a connectivity test against the // Amnezia panel without saving (admin/settings.php POST). func AdminSettingsPost(a *web.App) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx := r.Context() if r.FormValue("action") == "test" { view := loadAdminSettingsView(a, r) baseURL := strings.TrimSpace(r.FormValue("panel_url")) token := panel.NormalizeToken(r.FormValue("api_token")) if baseURL == "" || token == "" { view.TestError = "Укажите URL панели и токен." } else if !panel.TokenOK(token) { view.TestError = "Токен имеет неверный формат (ожидается awp_...)." } else { servers, err := a.Panel.ListServers(ctx, baseURL, token) if err != nil { view.TestError = err.Error() } else { view.TestResult = fmt.Sprintf("Соединение установлено. Серверов обнаружено: %d.", len(servers)) } } view.PanelURL = baseURL view.APIToken = r.FormValue("api_token") a.Render(w, r, "page_admin_settings", view) return } set := func(key, value string) error { return a.Settings.Set(ctx, key, value) } maintenance := "0" if r.FormValue("maintenance") == "1" { maintenance = "1" } var err error for _, kv := range []struct{ key, value string }{ {settings.KeyPanelURL, strings.TrimSpace(r.FormValue("panel_url"))}, {settings.KeyAPIToken, panel.NormalizeToken(r.FormValue("api_token"))}, {settings.KeyServerLabelsJSON, r.FormValue("server_labels_json")}, {settings.KeyTrafficNotices, r.FormValue("traffic_notices_json")}, {settings.KeyMaintenance, maintenance}, {settings.KeyPocketURL, strings.TrimSpace(r.FormValue("pocket_url"))}, {settings.KeyPocketClientID, strings.TrimSpace(r.FormValue("pocket_client_id"))}, {settings.KeyPocketSecret, strings.TrimSpace(r.FormValue("pocket_secret"))}, {settings.KeyMemberDays, strings.TrimSpace(r.FormValue("member_days"))}, {settings.KeyMemberMaxUses, strings.TrimSpace(r.FormValue("member_max_uses"))}, } { if serr := set(kv.key, kv.value); serr != nil { err = serr } } a.Panel.ClearCache() okMsg := "Настройки сохранены." errText := "" if err != nil { okMsg = "" errText = err.Error() } redirectWithFlash(w, r, a, "admin/settings", okMsg, errText) } }