cleanup: remove redundant and old architectural files
This commit is contained in:
@@ -1,162 +0,0 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"mal/api/anime"
|
||||
"mal/api/auth"
|
||||
"mal/api/playback"
|
||||
"mal/api/watchlist"
|
||||
"mal/integrations/jikan"
|
||||
"mal/internal/db"
|
||||
"mal/internal/middleware"
|
||||
pkgmiddleware "mal/pkg/middleware"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
DB *db.Queries
|
||||
SQLDB *sql.DB
|
||||
JikanClient *jikan.Client
|
||||
AuthService *auth.Service
|
||||
AuthLimiter *pkgmiddleware.Limiter
|
||||
PlaybackProxySecret string
|
||||
}
|
||||
|
||||
// withMimeTypes sets Content-Type for common static asset extensions
|
||||
func withMimeTypes(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
ext := strings.ToLower(filepath.Ext(r.URL.Path))
|
||||
switch ext {
|
||||
case ".js":
|
||||
w.Header().Set("Content-Type", "application/javascript")
|
||||
case ".css":
|
||||
w.Header().Set("Content-Type", "text/css")
|
||||
case ".svg":
|
||||
w.Header().Set("Content-Type", "image/svg+xml")
|
||||
case ".json":
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
}
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
// noCache sends headers to prevent caching of dynamic/static assets
|
||||
func noCache(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
|
||||
w.Header().Set("Pragma", "no-cache")
|
||||
w.Header().Set("Expires", "0")
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
// NewAuthLimiter returns a rate limiter for auth endpoints: 5 attempts per minute
|
||||
func NewAuthLimiter() *pkgmiddleware.Limiter {
|
||||
return pkgmiddleware.NewLimiter(pkgmiddleware.Config{
|
||||
MaxAttempts: 5,
|
||||
Window: time.Minute,
|
||||
})
|
||||
}
|
||||
|
||||
// NewRouter wires up all HTTP handlers and middleware.
|
||||
// Auth is enforced globally; public routes must opt-out via middleware policy.
|
||||
func NewRouter(cfg Config) http.Handler {
|
||||
mux := http.NewServeMux()
|
||||
|
||||
authHandler := auth.NewHandler(cfg.AuthService)
|
||||
|
||||
watchlistSvc := watchlist.NewService(cfg.DB, cfg.SQLDB, cfg.JikanClient)
|
||||
watchlistHandler := watchlist.NewHandler(watchlistSvc)
|
||||
|
||||
animeSvc := anime.NewService(cfg.JikanClient, cfg.DB)
|
||||
animeHandler := anime.NewHandler(animeSvc)
|
||||
|
||||
playbackSvc, err := playback.NewService(cfg.DB, cfg.SQLDB, playback.Config{
|
||||
ProxyTokenSecret: cfg.PlaybackProxySecret,
|
||||
})
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("failed to initialize playback service: %v", err))
|
||||
}
|
||||
playbackHandler := playback.NewHandler(playbackSvc, cfg.JikanClient)
|
||||
|
||||
// Serve static files with no-cache headers
|
||||
fs := noCache(http.FileServer(http.Dir("./static")))
|
||||
mux.Handle("/static/", http.StripPrefix("/static/", fs))
|
||||
|
||||
// Serve built frontend assets with no-cache headers
|
||||
dist := noCache(http.FileServer(http.Dir("./dist")))
|
||||
mux.Handle("/dist/", http.StripPrefix("/dist/", withMimeTypes(dist)))
|
||||
|
||||
// Serve Apple Touch Icons from static directory
|
||||
mux.HandleFunc("/apple-touch-icon.png", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "image/svg+xml")
|
||||
http.ServeFile(w, r, "./static/apple-touch-icon.svg")
|
||||
})
|
||||
mux.HandleFunc("/apple-touch-icon-precomposed.png", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "image/svg+xml")
|
||||
http.ServeFile(w, r, "./static/apple-touch-icon-precomposed.svg")
|
||||
})
|
||||
mux.HandleFunc("/apple-touch-icon-120x120.png", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "image/svg+xml")
|
||||
http.ServeFile(w, r, "./static/apple-touch-icon-120x120.svg")
|
||||
})
|
||||
mux.HandleFunc("/apple-touch-icon-120x120-precomposed.png", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "image/svg+xml")
|
||||
http.ServeFile(w, r, "./static/apple-touch-icon-120x120-precomposed.svg")
|
||||
})
|
||||
|
||||
mux.HandleFunc("/", animeHandler.HandleCatalog)
|
||||
mux.HandleFunc("/api/catalog/airing", animeHandler.HandleCatalogAiring)
|
||||
mux.HandleFunc("/api/catalog/popular", animeHandler.HandleCatalogPopular)
|
||||
mux.HandleFunc("/api/catalog/continue", animeHandler.HandleCatalogContinue)
|
||||
mux.HandleFunc("/search", animeHandler.HandleSearch)
|
||||
mux.HandleFunc("/browse", animeHandler.HandleBrowse)
|
||||
mux.HandleFunc("/discover", animeHandler.HandleDiscover)
|
||||
mux.HandleFunc("/api/discover/trending", animeHandler.HandleDiscoverTrending)
|
||||
mux.HandleFunc("/api/discover/upcoming", animeHandler.HandleDiscoverUpcoming)
|
||||
mux.HandleFunc("/api/discover/top", animeHandler.HandleDiscoverTop)
|
||||
mux.HandleFunc("/api/search-quick", animeHandler.HandleQuickSearch)
|
||||
mux.HandleFunc("/api/jikan/random/anime", animeHandler.HandleRandomAnime)
|
||||
mux.HandleFunc("/anime/", func(w http.ResponseWriter, r *http.Request) {
|
||||
if strings.HasSuffix(r.URL.Path, "/watch") {
|
||||
playbackHandler.HandleWatchPage(w, r)
|
||||
return
|
||||
}
|
||||
animeHandler.HandleAnimeDetails(w, r)
|
||||
})
|
||||
mux.HandleFunc("/api/watch-order", animeHandler.HandleHTMLWatchOrder)
|
||||
mux.HandleFunc("/watch/", playbackHandler.HandleWatchPage)
|
||||
mux.HandleFunc("/watch/proxy/stream", playbackHandler.HandleProxy)
|
||||
mux.HandleFunc("/watch/proxy/segment", playbackHandler.HandleProxy)
|
||||
mux.HandleFunc("/watch/proxy/subtitle", playbackHandler.HandleProxy)
|
||||
mux.HandleFunc("/api/watch-progress", playbackHandler.HandleSaveProgress)
|
||||
mux.HandleFunc("/api/watch-complete", playbackHandler.HandleCompleteAnime)
|
||||
mux.HandleFunc("/api/watch/episode/", playbackHandler.HandleEpisodeData)
|
||||
mux.HandleFunc("/api/watch/thumbnails/", playbackHandler.HandleEpisodeThumbnails)
|
||||
|
||||
// Auth Endpoints
|
||||
mux.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method == http.MethodGet {
|
||||
authHandler.HandleLoginPage(w, r)
|
||||
} else {
|
||||
cfg.AuthLimiter.AuthMiddleware(pkgmiddleware.VerifyOrigin(http.HandlerFunc(authHandler.HandleLogin))).ServeHTTP(w, r)
|
||||
}
|
||||
})
|
||||
mux.HandleFunc("/logout", authHandler.HandleLogout)
|
||||
|
||||
// Watchlist Endpoints
|
||||
mux.HandleFunc("/api/watchlist", watchlistHandler.HandleUpdateWatchlist)
|
||||
mux.HandleFunc("/api/watchlist/", watchlistHandler.HandleDeleteWatchlist)
|
||||
mux.HandleFunc("/api/continue-watching/", watchlistHandler.HandleDeleteContinueWatching)
|
||||
mux.HandleFunc("/watchlist", watchlistHandler.HandleGetWatchlist)
|
||||
|
||||
// Wrap mux with global CSRF origin verification and auth checking
|
||||
protectedHandler := middleware.RequireGlobalAuthWithPolicy(middleware.NewAccessPolicy())(pkgmiddleware.VerifyOrigin(mux))
|
||||
authenticatedHandler := middleware.Auth(cfg.AuthService)(protectedHandler)
|
||||
return pkgmiddleware.RequestLogger(authenticatedHandler)
|
||||
}
|
||||
Reference in New Issue
Block a user