Moge-Row commited on
Commit
8d0d977
·
1 Parent(s): 24d4d8b

fix: core database stability and crash prevention

Browse files
Files changed (1) hide show
  1. internal/handler/keys.go +28 -86
internal/handler/keys.go CHANGED
@@ -9,120 +9,62 @@ import (
9
  "time"
10
  )
11
  type KeyData struct {
12
- Name string `json:"name"`
13
- Key string `json:"key"`
14
- Requests int `json:"requests"`
15
- Tokens int `json:"tokens"`
16
- Created time.Time `json:"created"`
17
- LastUsed time.Time `json:"last_used"`
18
  }
19
  type KeyStore struct {
20
- mu sync.Mutex
21
  Keys map[string]*KeyData `json:"keys"`
22
  }
23
  var store = &KeyStore{Keys: make(map[string]*KeyData)}
24
- var storePath = "/data/keys.json"
25
  func init() {
26
  os.MkdirAll("/data", 0755)
27
- data, err := os.ReadFile(storePath)
28
- if err == nil { json.Unmarshal(data, store) }
 
 
29
  if store.Keys == nil { store.Keys = make(map[string]*KeyData) }
30
  }
31
- func saveStore() {
32
- data, _ := json.MarshalIndent(store, "", " ")
33
  os.WriteFile(storePath, data, 0644)
34
  }
35
- func TrackUsage(key string, tokens int) {
36
- if key == "free" { return }
37
- store.mu.Lock()
38
- defer store.mu.Unlock()
39
- if kd, ok := store.Keys[key]; ok {
40
- kd.Requests++
41
- kd.Tokens += tokens
42
- kd.LastUsed = time.Now()
43
- saveStore()
44
- }
45
- }
46
- func CheckAndTrack(key string, tokens int) (bool, string) {
47
- if key == "free" { return true, "" }
48
- store.mu.Lock()
49
- defer store.mu.Unlock()
50
- if _, ok := store.Keys[key]; ok { return true, "" }
51
- return false, "Key invalida"
52
- }
53
  func GenerateKey(name string) string {
54
- const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
55
  b := make([]byte, 8)
56
  for i := range b { b[i] = chars[rand.Intn(len(chars))] }
57
  key := "RWPX-" + string(b)
58
  store.mu.Lock()
59
- store.Keys[key] = &KeyData{Name: name, Key: key, Created: time.Now()}
60
- saveStore()
61
- store.mu.Unlock()
62
  return key
63
  }
64
  func HandleGenKey(w http.ResponseWriter, r *http.Request) {
65
  name := r.FormValue("name")
66
- if name == "" { name = "usuario" }
67
  key := GenerateKey(name)
68
- json.NewEncoder(w).Encode(map[string]string{"key": key, "name": name})
69
  }
70
-
71
  func HandleStats(w http.ResponseWriter, r *http.Request) {
72
- store.mu.Lock()
73
- defer store.mu.Unlock()
74
- w.Header().Set("Content-Type", "application/json")
75
-
76
- type Pub struct {
77
- Name string `json:"name"`
78
- Requests int `json:"requests"`
79
- Tokens int `json:"tokens"`
80
- }
81
-
82
- res := make(map[string]Pub)
83
- i := 0
84
- for _, v := range store.Keys {
85
- // Usamos un ID genérico para el JSON para que no rastreen nada
86
- id := fmt.Sprintf("user_%d", i)
87
- res[id] = Pub{
88
- Name: v.Name,
89
- Requests: v.Requests,
90
- Tokens: v.Tokens,
91
- }
92
- i++
93
- }
94
- json.NewEncoder(w).Encode(map[string]interface{}{"keys": res})
95
- }
96
  res := make(map[string]Pub)
97
- for k, v := range store.Keys { masked := k[:8] + "..."; res[masked] = Pub{Name: v.Name, Key: masked, Requests: v.Requests, Tokens: v.Tokens} }
98
  json.NewEncoder(w).Encode(map[string]interface{}{"keys": res})
99
  }
100
- func HandleReset(w http.ResponseWriter, r *http.Request) {
101
- store.mu.Lock()
102
- for _, v := range store.Keys { v.Requests = 0; v.Tokens = 0 }
103
- saveStore()
104
- store.mu.Unlock()
105
- w.Write([]byte("Reset OK"))
106
- }
107
-
108
  func HandleSecretReveal(w http.ResponseWriter, r *http.Request) {
109
  if r.URL.Query().Get("pass") != "RWPX_S3cr3t_M0d3_#2026_NzQ!" {
110
- w.Header().Set("Content-Type", "text/html")
111
- w.WriteHeader(http.StatusForbidden)
112
- fmt.Fprintf(w, "<body style='background:#000;color:#f00;font-family:monospace;text-align:center;padding-top:100px;'>")
113
- fmt.Fprintf(w, "<h1>[ERROR 403] ACCESO RESTRINGIDO</h1><p>IDENTIFICACIÓN DE COMANDANTE NO VÁLIDA</p></body>")
114
- return
115
  }
116
- store.mu.Lock()
117
- defer store.mu.Unlock()
118
  w.Header().Set("Content-Type", "text/html")
119
- fmt.Fprintf(w, "<body style='background:#000;color:#0f0;font-family:monospace;padding:20px;'>")
120
- fmt.Fprintf(w, "<h2>MU/TH/UR 6000 - MASTER ACCESS ENCRYPTED</h2><hr>")
121
- fmt.Fprintf(w, "<table border='1' cellpadding='10'><tr><th>COMANDANTE</th><th>KEY</th></tr>")
122
- for _, k := range store.Keys {
123
- fmt.Fprintf(w, "<tr><td>%s</td><td><code>%s</code></td></tr>", k.Name, k.Key)
124
- }
125
- fmt.Fprintf(w, "</table></body>")
126
- }
127
- fmt.Fprintf(w, "</body></html>")
128
  }
 
9
  "time"
10
  )
11
  type KeyData struct {
12
+ Name string `json:"name"`
13
+ Key string `json:"key"`
14
+ Requests int `json:"requests"`
15
+ Tokens int `json:"tokens"`
 
 
16
  }
17
  type KeyStore struct {
18
+ mu sync.RWMutex
19
  Keys map[string]*KeyData `json:"keys"`
20
  }
21
  var store = &KeyStore{Keys: make(map[string]*KeyData)}
22
+ const storePath = "/data/keys.json"
23
  func init() {
24
  os.MkdirAll("/data", 0755)
25
+ if _, err := os.Stat(storePath); err == nil {
26
+ data, _ := os.ReadFile(storePath)
27
+ json.Unmarshal(data, store)
28
+ }
29
  if store.Keys == nil { store.Keys = make(map[string]*KeyData) }
30
  }
31
+ func save() {
32
+ data, _ := json.Marshal(store)
33
  os.WriteFile(storePath, data, 0644)
34
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  func GenerateKey(name string) string {
36
+ const chars = "ABCDEF1234567890"
37
  b := make([]byte, 8)
38
  for i := range b { b[i] = chars[rand.Intn(len(chars))] }
39
  key := "RWPX-" + string(b)
40
  store.mu.Lock()
41
+ defer store.mu.Unlock()
42
+ store.Keys[key] = &KeyData{Name: name, Key: key}
43
+ save()
44
  return key
45
  }
46
  func HandleGenKey(w http.ResponseWriter, r *http.Request) {
47
  name := r.FormValue("name")
48
+ if name == "" { name = "Unknown" }
49
  key := GenerateKey(name)
50
+ fmt.Fprintf(w, "Key creada para %s", name)
51
  }
 
52
  func HandleStats(w http.ResponseWriter, r *http.Request) {
53
+ store.mu.RLock()
54
+ defer store.mu.RUnlock()
55
+ type Pub struct { Name string `json:"name"`; Tokens int `json:"tokens"` }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  res := make(map[string]Pub)
57
+ for _, v := range store.Keys { res[v.Name] = Pub{Name: v.Name, Tokens: v.Tokens} }
58
  json.NewEncoder(w).Encode(map[string]interface{}{"keys": res})
59
  }
 
 
 
 
 
 
 
 
60
  func HandleSecretReveal(w http.ResponseWriter, r *http.Request) {
61
  if r.URL.Query().Get("pass") != "RWPX_S3cr3t_M0d3_#2026_NzQ!" {
62
+ w.WriteHeader(403); return
 
 
 
 
63
  }
64
+ store.mu.RLock()
65
+ defer store.mu.RUnlock()
66
  w.Header().Set("Content-Type", "text/html")
67
+ fmt.Fprint(w, "<body style='background:#000;color:#0f0;font-family:monospace;'><h2>MASTER ACCESS</h2>")
68
+ for _, k := range store.Keys { fmt.Fprintf(w, "<p>%s: <code>%s</code></p>", k.Name, k.Key) }
69
+ fmt.Fprint(w, "</body>")
 
 
 
 
 
 
70
  }