You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

185 lines
4.9 KiB

package app
import (
"encoding/json"
"net/http"
"strconv"
lol "lol.mleku.dev"
"lol.mleku.dev/chk"
"git.mleku.dev/mleku/nostr/httpauth"
"next.orly.dev/pkg/acl"
"next.orly.dev/pkg/logbuffer"
)
// LogsResponse is the response structure for GET /api/logs
type LogsResponse struct {
Logs []logbuffer.LogEntry `json:"logs"`
Total int `json:"total"`
HasMore bool `json:"has_more"`
}
// LogLevelResponse is the response structure for GET /api/logs/level
type LogLevelResponse struct {
Level string `json:"level"`
}
// LogLevelRequest is the request structure for POST /api/logs/level
type LogLevelRequest struct {
Level string `json:"level"`
}
// handleGetLogs handles GET /api/logs
func (s *Server) handleGetLogs(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
// Validate NIP-98 authentication
valid, pubkey, err := httpauth.CheckAuth(r)
if chk.E(err) || !valid {
errorMsg := "NIP-98 authentication validation failed"
if err != nil {
errorMsg = err.Error()
}
http.Error(w, errorMsg, http.StatusUnauthorized)
return
}
// Check permissions - require owner level only
accessLevel := acl.Registry.GetAccessLevel(pubkey, r.RemoteAddr)
if accessLevel != "owner" {
http.Error(w, "Owner permission required", http.StatusForbidden)
return
}
// Check if log buffer is available
if logbuffer.GlobalBuffer == nil {
http.Error(w, "Log buffer not enabled", http.StatusServiceUnavailable)
return
}
// Parse query parameters
offset := 0
limit := 100
if offsetStr := r.URL.Query().Get("offset"); offsetStr != "" {
if v, err := strconv.Atoi(offsetStr); err == nil && v >= 0 {
offset = v
}
}
if limitStr := r.URL.Query().Get("limit"); limitStr != "" {
if v, err := strconv.Atoi(limitStr); err == nil && v > 0 && v <= 500 {
limit = v
}
}
// Get logs from buffer
logs := logbuffer.GlobalBuffer.Get(offset, limit)
total := logbuffer.GlobalBuffer.Count()
hasMore := offset+len(logs) < total
response := LogsResponse{
Logs: logs,
Total: total,
HasMore: hasMore,
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
}
// handleClearLogs handles POST /api/logs/clear
func (s *Server) handleClearLogs(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
// Validate NIP-98 authentication
valid, pubkey, err := httpauth.CheckAuth(r)
if chk.E(err) || !valid {
errorMsg := "NIP-98 authentication validation failed"
if err != nil {
errorMsg = err.Error()
}
http.Error(w, errorMsg, http.StatusUnauthorized)
return
}
// Check permissions - require owner level only
accessLevel := acl.Registry.GetAccessLevel(pubkey, r.RemoteAddr)
if accessLevel != "owner" {
http.Error(w, "Owner permission required", http.StatusForbidden)
return
}
// Check if log buffer is available
if logbuffer.GlobalBuffer == nil {
http.Error(w, "Log buffer not enabled", http.StatusServiceUnavailable)
return
}
// Clear the buffer
logbuffer.GlobalBuffer.Clear()
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]string{"status": "ok"})
}
// handleLogLevel handles GET and POST /api/logs/level
func (s *Server) handleLogLevel(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
s.handleGetLogLevel(w, r)
case http.MethodPost:
s.handleSetLogLevel(w, r)
default:
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
}
}
// handleGetLogLevel handles GET /api/logs/level
func (s *Server) handleGetLogLevel(w http.ResponseWriter, r *http.Request) {
// No auth required for reading log level
level := logbuffer.GetCurrentLevel()
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(LogLevelResponse{Level: level})
}
// handleSetLogLevel handles POST /api/logs/level
func (s *Server) handleSetLogLevel(w http.ResponseWriter, r *http.Request) {
// Validate NIP-98 authentication
valid, pubkey, err := httpauth.CheckAuth(r)
if chk.E(err) || !valid {
errorMsg := "NIP-98 authentication validation failed"
if err != nil {
errorMsg = err.Error()
}
http.Error(w, errorMsg, http.StatusUnauthorized)
return
}
// Check permissions - require owner level only
accessLevel := acl.Registry.GetAccessLevel(pubkey, r.RemoteAddr)
if accessLevel != "owner" {
http.Error(w, "Owner permission required", http.StatusForbidden)
return
}
// Parse request body
var req LogLevelRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "Invalid request body", http.StatusBadRequest)
return
}
// Validate and set log level
level := logbuffer.SetCurrentLevel(req.Level)
lol.SetLogLevel(level)
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(LogLevelResponse{Level: level})
}