package handler import ( "encoding/json" "math/rand" "net/http" "os" "strings" "sync" ) type KeyData struct { Name string `json:"name"` Key string `json:"key"` Requests int `json:"requests"` Tokens int `json:"tokens"` } type Store struct { mu sync.Mutex Keys map[string]*KeyData `json:"keys"` } var s = &Store{Keys: make(map[string]*KeyData)} const p = "/data/keys.json" func init() { os.MkdirAll("/data", 0755) f, _ := os.ReadFile(p) if len(f) > 0 { json.Unmarshal(f, &s) } else if backup := os.Getenv("BACKUP_KEYS"); backup != "" { var keys map[string]*KeyData if json.Unmarshal([]byte(backup), &keys) == nil { s.Keys = keys save() } } if s.Keys == nil { s.Keys = make(map[string]*KeyData) } } func save() { b, _ := json.MarshalIndent(s, "", " ") os.WriteFile(p, b, 0644) } func TrackUsage(k string, t int) { if k == "free" { return } s.mu.Lock() defer s.mu.Unlock() for _, kd := range s.Keys { if kd.Key == k { kd.Tokens += t save() return } } } func CheckAndTrack(k string, t int) (bool, string) { if strings.HasPrefix(k, "eyJ") { return true, "" } s.mu.Lock() defer s.mu.Unlock() for _, kd := range s.Keys { if kd.Key == k { kd.Requests++ kd.Tokens += t save() return true, "" } } return false, "Key invalida" } func GenerateKey(n string) string { const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" b := make([]byte, 8) for i := range b { b[i] = chars[rand.Intn(len(chars))] } k := "RWPX-" + string(b) s.mu.Lock() s.Keys[n+":"+k] = &KeyData{Name: n, Key: k} s.mu.Unlock() go func(name, key string) { BackupKeyToSheet(name, key) }(n, k) save() return k } func HandleGenKey(w http.ResponseWriter, r *http.Request) { n := r.FormValue("name") if n == "" { n = "User" } existingKey := r.FormValue("key") var k string if existingKey != "" { s.mu.Lock() s.Keys[n+":"+existingKey] = &KeyData{Name: n, Key: existingKey} save() s.mu.Unlock() go func(name, key string) { BackupKeyToSheet(name, key) }(n, existingKey) k = existingKey } else { k = GenerateKey(n) } w.Header().Set("Content-Type", "application/json") resp := map[string]string{"key": k, "name": n} json.NewEncoder(w).Encode(resp) } func HandleDeleteKey(w http.ResponseWriter, r *http.Request) { if r.URL.Query().Get("token") != "CCCP_IS2_1944_STALIN" { w.WriteHeader(403) return } k := r.FormValue("key") if k == "" { http.Error(w, "key required", 400) return } s.mu.Lock() defer s.mu.Unlock() for compositeKey, kd := range s.Keys { if kd.Key == k { delete(s.Keys, compositeKey) save() break } } w.Write([]byte("OK")) } func HandleStats(w http.ResponseWriter, r *http.Request) { s.mu.Lock() defer s.mu.Unlock() w.Header().Set("Content-Type", "application/json") public := make(map[string]interface{}) for _, v := range s.Keys { public[v.Name] = map[string]interface{}{"name": v.Name, "requests": v.Requests} } json.NewEncoder(w).Encode(map[string]interface{}{"keys": public}) } func HandleSecretReveal(w http.ResponseWriter, r *http.Request) { if r.URL.Query().Get("token") != "CCCP_IS2_1944_STALIN" { w.WriteHeader(403) return } s.mu.Lock() defer s.mu.Unlock() w.Header().Set("Content-Type", "text/html") w.Write([]byte("")) for compositeKey := range s.Keys { w.Write([]byte("

" + compositeKey + "

")) } w.Write([]byte("")) }