111 lines
5.4 KiB
Go
111 lines
5.4 KiB
Go
package main
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
|
|
"chat/src/auth"
|
|
"chat/src/config"
|
|
"chat/src/db"
|
|
"chat/src/handlers"
|
|
"chat/src/metrics"
|
|
"chat/src/ws"
|
|
)
|
|
|
|
func generateShortID() string {
|
|
b := make([]byte, 6)
|
|
rand.Read(b)
|
|
return hex.EncodeToString(b)
|
|
}
|
|
|
|
func main() {
|
|
instanceID := fmt.Sprintf("chat-%s", generateShortID())
|
|
|
|
rateLimitMax := config.RateLimitMax()
|
|
rateLimitWindow := config.RateLimitWindow()
|
|
log.Printf("Rate limit: %d messages per %v", rateLimitMax, rateLimitWindow)
|
|
|
|
// Load persisted runtime configuration (Matomo + HLS settings)
|
|
if err := config.LoadRuntimeConfig(); err != nil {
|
|
log.Printf("Warning: failed to load runtime config: %v", err)
|
|
}
|
|
|
|
// Initialize Redis
|
|
redisWrapper := db.InitRedis(config.RedisAddress())
|
|
|
|
// Initialize DB
|
|
dbClient, dbDriver, err := db.InitDB(config.DatabaseURL())
|
|
if err != nil {
|
|
log.Fatalf("Failed to initialize database: %v", err)
|
|
}
|
|
|
|
// Initialize session store
|
|
sessionStore := auth.NewSessionStore()
|
|
userSessions := auth.NewUserSessionStore()
|
|
|
|
// Initialize WebSocket hub
|
|
hub := ws.NewHub(dbClient.DB, redisWrapper, instanceID, rateLimitMax, rateLimitWindow, config.AdminUsername())
|
|
|
|
// Start Redis pub/sub subscriber
|
|
go hub.SubscribeRoomMessages()
|
|
|
|
log.Printf("Instance ID: %s", instanceID)
|
|
|
|
// Build dependencies
|
|
deps := &handlers.Dependencies{
|
|
DB: dbClient.DB,
|
|
Redis: redisWrapper,
|
|
Hub: hub,
|
|
SessionStore: sessionStore,
|
|
UserSessions: userSessions,
|
|
DBDriver: dbDriver,
|
|
}
|
|
|
|
// Auth middleware
|
|
requireAdmin := auth.RequireAdmin(sessionStore, config.AdminSessionCookieName)
|
|
|
|
// Register routes
|
|
http.HandleFunc("/ws", hub.HandleConnection)
|
|
http.HandleFunc("/api/auth/register", metrics.WrapRequestTiming(handlers.HandleUserRegister(deps)))
|
|
http.HandleFunc("/api/auth/login", metrics.WrapRequestTiming(handlers.HandleUserLogin(deps)))
|
|
http.HandleFunc("/api/auth/session", metrics.WrapRequestTiming(handlers.HandleUserSession(deps)))
|
|
http.HandleFunc("/api/auth/logout", metrics.WrapRequestTiming(handlers.HandleUserLogout(deps)))
|
|
http.HandleFunc("/api/dm/history", metrics.WrapRequestTiming(handlers.HandleUserDMHistory(deps)))
|
|
http.HandleFunc("/api/dm/search", metrics.WrapRequestTiming(handlers.HandleUserDMSearch(deps)))
|
|
http.HandleFunc("/api/admin/login", metrics.WrapRequestTiming(handlers.HandleAdminLogin(deps)))
|
|
http.HandleFunc("/api/admin/logout", metrics.WrapRequestTiming(handlers.HandleAdminLogout(deps)))
|
|
http.HandleFunc("/api/admin/session", metrics.WrapRequestTiming(handlers.HandleAdminSession(deps)))
|
|
http.HandleFunc("/api/admin/overview", metrics.WrapRequestTiming(requireAdmin(handlers.HandleAdminOverview(deps))))
|
|
http.HandleFunc("/api/admin/playlist", metrics.WrapRequestTiming(requireAdmin(handlers.HandleAdminPlaylist(deps))))
|
|
http.HandleFunc("/api/admin/moderation/logs", metrics.WrapRequestTiming(requireAdmin(handlers.HandleAdminModerationLogs(deps))))
|
|
http.HandleFunc("/api/admin/moderation/actions", metrics.WrapRequestTiming(requireAdmin(handlers.HandleAdminModerationAction(deps))))
|
|
http.HandleFunc("/api/admin/analytics", metrics.WrapRequestTiming(requireAdmin(handlers.HandleAdminAnalytics(deps))))
|
|
http.HandleFunc("/api/admin/system", metrics.WrapRequestTiming(requireAdmin(handlers.HandleAdminSystemSummary(deps))))
|
|
http.HandleFunc("/api/admin/config", metrics.WrapRequestTiming(requireAdmin(handlers.HandleAdminConfig(deps))))
|
|
http.HandleFunc("/api/admin/restart", metrics.WrapRequestTiming(requireAdmin(handlers.HandleAdminRestart(deps))))
|
|
http.HandleFunc("/api/admin/users", metrics.WrapRequestTiming(requireAdmin(handlers.HandleAdminUsers(deps))))
|
|
http.HandleFunc("/api/admin/schedule", metrics.WrapRequestTiming(requireAdmin(handlers.HandleAdminSchedule(deps))))
|
|
http.HandleFunc("/api/admin/schedule/overrides", metrics.WrapRequestTiming(requireAdmin(handlers.HandleAdminScheduleOverrides(deps))))
|
|
http.HandleFunc("/api/schedule", metrics.WrapRequestTiming(handlers.HandlePublicSchedule(deps)))
|
|
http.HandleFunc("/api/matomo", metrics.WrapRequestTiming(handlers.HandlePublicMatomo()))
|
|
http.HandleFunc("/api/admin/media", metrics.WrapRequestTiming(requireAdmin(handlers.HandleAdminMedia(deps))))
|
|
http.HandleFunc("/api/admin/media/uploads", metrics.WrapRequestTiming(requireAdmin(handlers.HandleAdminMediaUploads(deps))))
|
|
http.HandleFunc("/api/admin/media/uploads/", metrics.WrapRequestTiming(requireAdmin(handlers.HandleAdminMediaUploads(deps))))
|
|
http.HandleFunc("/api/admin/media/", metrics.WrapRequestTiming(requireAdmin(handlers.HandleAdminMediaByID(deps))))
|
|
http.HandleFunc("/api/admin/chat-log/bulk", metrics.WrapRequestTiming(requireAdmin(handlers.HandleAdminChatLogBulk(deps))))
|
|
http.HandleFunc("/api/admin/chat-log/export", metrics.WrapRequestTiming(requireAdmin(handlers.HandleAdminChatLogExport(deps))))
|
|
http.HandleFunc("/api/admin/chat-log/", metrics.WrapRequestTiming(requireAdmin(handlers.HandleAdminChatLogByID(deps))))
|
|
http.HandleFunc("/api/admin/chat-log", metrics.WrapRequestTiming(requireAdmin(handlers.HandleAdminChatLog(deps))))
|
|
http.HandleFunc("/metrics", metrics.HandleMetrics(dbClient.DB, redisWrapper, hub, sessionStore, dbDriver, instanceID))
|
|
http.HandleFunc("/health", metrics.WrapRequestTiming(metrics.HandleHealth()))
|
|
http.HandleFunc("/", metrics.WrapRequestTiming(metrics.HandleNotFound()))
|
|
|
|
port := config.ChatPort()
|
|
log.Printf("Chat service starting on :%s", port)
|
|
if err := http.ListenAndServe(":"+port, nil); err != nil {
|
|
log.Fatalf("Server failed: %v", err)
|
|
}
|
|
} |