refactor: centralize constants and reorganize documentation
- Create internal/constants package with all hardcoded values (environment, cookies, themes, headers, routes, cache) - Create internal/httputil package for HTTP helper functions - Update all handlers and middleware to use centralized constants - Reorganize documentation with numbered prefixes (00-26) - Remove duplicate docs from validation folder and docs/ - Delete handlers/constants.go (moved to internal/constants)
This commit is contained in:
@@ -4,6 +4,8 @@ import (
|
||||
"log"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/juanatsap/cv-site/internal/constants"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -21,7 +23,7 @@ const (
|
||||
func BrowserOnly(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
// Check 1: User-Agent validation
|
||||
userAgent := r.Header.Get("User-Agent")
|
||||
userAgent := r.Header.Get(constants.HeaderUserAgent)
|
||||
if userAgent == "" || isBotUserAgent(userAgent) {
|
||||
log.Printf("SECURITY: Blocked non-browser User-Agent from IP %s: %s", getRequestIP(r), userAgent)
|
||||
http.Error(w, "Forbidden: Browser access only", http.StatusForbidden)
|
||||
@@ -29,8 +31,8 @@ func BrowserOnly(next http.Handler) http.Handler {
|
||||
}
|
||||
|
||||
// Check 2: Require Referer or Origin header
|
||||
referer := r.Header.Get("Referer")
|
||||
origin := r.Header.Get("Origin")
|
||||
referer := r.Header.Get(constants.HeaderReferer)
|
||||
origin := r.Header.Get(constants.HeaderOrigin)
|
||||
|
||||
if referer == "" && origin == "" {
|
||||
log.Printf("SECURITY: Blocked request without Referer/Origin from IP %s", getRequestIP(r))
|
||||
@@ -41,7 +43,7 @@ func BrowserOnly(next http.Handler) http.Handler {
|
||||
// Check 3: Custom header validation (set by JavaScript)
|
||||
// For HTMX requests, check HX-Request header
|
||||
// For fetch/XMLHttpRequest, check X-Requested-With header
|
||||
hasHTMXHeader := r.Header.Get("HX-Request") == "true"
|
||||
hasHTMXHeader := r.Header.Get(constants.HeaderHXRequest) == "true"
|
||||
hasXMLHTTPHeader := r.Header.Get(browserHeaderName) == browserHeaderValue
|
||||
hasCustomBrowserHeader := r.Header.Get("X-Browser-Request") == "true"
|
||||
|
||||
@@ -96,7 +98,7 @@ func isBotUserAgent(ua string) bool {
|
||||
// getRequestIP extracts the client IP from the request
|
||||
func getRequestIP(r *http.Request) string {
|
||||
// Try X-Forwarded-For first (for proxies/load balancers)
|
||||
ip := r.Header.Get("X-Forwarded-For")
|
||||
ip := r.Header.Get(constants.HeaderXForwardedFor)
|
||||
if ip != "" {
|
||||
// Take first IP if multiple
|
||||
ips := strings.Split(ip, ",")
|
||||
@@ -104,7 +106,7 @@ func getRequestIP(r *http.Request) string {
|
||||
}
|
||||
|
||||
// Try X-Real-IP
|
||||
ip = r.Header.Get("X-Real-IP")
|
||||
ip = r.Header.Get(constants.HeaderXRealIP)
|
||||
if ip != "" {
|
||||
return ip
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user