console / keys.go
oki692's picture
Deploy API gateway + SvelteKit console
ff149f9 verified
package main
import (
"encoding/json"
"net/http"
"strings"
"sync"
"time"
)
type keyCache struct {
mu sync.RWMutex
keys map[string]bool
expires time.Time
}
var apiKeyCache = &keyCache{
keys: make(map[string]bool),
}
type APIKey struct {
ID string `json:"id,omitempty"`
Key string `json:"key"`
Name string `json:"name"`
Active bool `json:"active"`
CreatedAt string `json:"created_at,omitempty"`
}
func isValidAPIKey(key string) bool {
apiKeyCache.mu.RLock()
if time.Now().Before(apiKeyCache.expires) {
valid := apiKeyCache.keys[key]
apiKeyCache.mu.RUnlock()
return valid
}
apiKeyCache.mu.RUnlock()
return checkKeyInSupabase(key)
}
func checkKeyInSupabase(key string) bool {
data, status, err := supabaseServiceRequest("GET", "api_keys", "key=eq."+key+"&active=eq.true&select=key", nil)
if err != nil || status != 200 {
return false
}
var results []map[string]interface{}
if err := json.Unmarshal(data, &results); err != nil {
return false
}
found := len(results) > 0
if found {
apiKeyCache.mu.Lock()
apiKeyCache.keys[key] = true
if apiKeyCache.expires.IsZero() {
apiKeyCache.expires = time.Now().Add(60 * time.Second)
}
apiKeyCache.mu.Unlock()
}
return found
}
func refreshKeyCache() {
data, status, err := supabaseServiceRequest("GET", "api_keys", "active=eq.true&select=key", nil)
if err != nil || status != 200 {
return
}
var results []map[string]string
if err := json.Unmarshal(data, &results); err != nil {
return
}
apiKeyCache.mu.Lock()
apiKeyCache.keys = make(map[string]bool)
for _, r := range results {
apiKeyCache.keys[r["key"]] = true
}
apiKeyCache.expires = time.Now().Add(60 * time.Second)
apiKeyCache.mu.Unlock()
}
func authHeader(r *http.Request) string {
auth := r.Header.Get("Authorization")
if strings.HasPrefix(auth, "Bearer ") {
return strings.TrimPrefix(auth, "Bearer ")
}
return r.Header.Get("x-api-key")
}