This commit is contained in:
2026-02-13 21:50:00 +01:00
parent dbfd99f410
commit 1825b50dec
11 changed files with 276 additions and 30 deletions

View File

@@ -683,3 +683,106 @@ func (s *Server) handleAdminUI(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html; charset=utf-8")
w.Write([]byte(adminPanelHTML))
}
// handleAdminResetClientPassword resets a client's API key to a new random value
func (s *Server) handleAdminResetClientPassword(w http.ResponseWriter, r *http.Request) {
admin, err := s.authenticateAdmin(r)
if err != nil || admin == nil {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
if r.Method != http.MethodPost {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
clientID := r.URL.Query().Get("client_id")
if clientID == "" {
http.Error(w, "client_id required", http.StatusBadRequest)
return
}
// Get existing client
client, err := s.db.GetClient(clientID)
if err != nil {
http.Error(w, "Database error", http.StatusInternalServerError)
return
}
if client == nil {
http.Error(w, "Client not found", http.StatusNotFound)
return
}
// Generate new random API key
newAPIKey, err := generateToken()
if err != nil {
http.Error(w, "Failed to generate new API key", http.StatusInternalServerError)
return
}
// Update client with new API key
client.APIKey = hashAPIKey(newAPIKey)
if err := s.db.SaveClient(client); err != nil {
http.Error(w, "Failed to update client", http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]interface{}{
"success": true,
"message": "Client password reset successfully",
"api_key": newAPIKey, // Return the new key (only shown once!)
})
}
// handleClientChangePassword allows a client to change its own API key
func (s *Server) handleClientChangePassword(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
var req struct {
ClientID string `json:"client_id"`
CurrentKey string `json:"current_key"`
NewKey string `json:"new_key"`
}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "Invalid request body", http.StatusBadRequest)
return
}
if req.ClientID == "" || req.CurrentKey == "" || req.NewKey == "" {
http.Error(w, "client_id, current_key, and new_key required", http.StatusBadRequest)
return
}
// Authenticate with current key
if !s.authenticate(req.ClientID, req.CurrentKey) {
http.Error(w, "Invalid current API key", http.StatusUnauthorized)
return
}
// Get client
client, err := s.db.GetClient(req.ClientID)
if err != nil || client == nil {
http.Error(w, "Client not found", http.StatusNotFound)
return
}
// Update with new key
client.APIKey = hashAPIKey(req.NewKey)
if err := s.db.SaveClient(client); err != nil {
http.Error(w, "Failed to update password", http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]interface{}{
"success": true,
"message": "Password changed successfully",
})
}