Initial DDC release

This commit is contained in:
SirBlob committed 2026-10-25 20:24:50 -04:00
commit 434f6441da
57 files changed
+4606

No files matched your search

+73
View File
@@ -0,0 +1,73 @@
package server
import (
"net/http"
"net/url"
"strings"
)
const (
sessionCookieName = "ddc_session"
maxRequestBodyBytes = 64 << 10
contentSecurityPolicy = "default-src 'self'; img-src 'self' data:; object-src 'none'; base-uri 'none'; frame-ancestors 'none'; form-action 'self'"
)
func securityHeaders(next http.Handler) http.Handler {
return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
header := writer.Header()
header.Set("Content-Security-Policy", contentSecurityPolicy)
header.Set("X-Content-Type-Options", "nosniff")
header.Set("X-Frame-Options", "DENY")
header.Set("Referrer-Policy", "no-referrer")
header.Set("Cross-Origin-Opener-Policy", "same-origin")
header.Set("Permissions-Policy", "camera=(), microphone=(), geolocation=()")
if strings.HasPrefix(request.URL.Path, "/api/") {
header.Set("Cache-Control", "no-store")
}
next.ServeHTTP(writer, request)
})
}
func protectStateChanges(next http.Handler) http.Handler {
return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
if request.Method == http.MethodGet || request.Method == http.MethodHead {
next.ServeHTTP(writer, request)
return
}
if !isSameOrigin(request) {
writeError(writer, http.StatusForbidden, "cross-origin request rejected")
return
}
if request.Method == http.MethodPost && !strings.HasPrefix(request.Header.Get("Content-Type"), "application/json") {
writeError(writer, http.StatusUnsupportedMediaType, "content type must be application/json")
return
}
request.Body = http.MaxBytesReader(writer, request.Body, maxRequestBodyBytes)
next.ServeHTTP(writer, request)
})
}
func isSameOrigin(request *http.Request) bool {
origin := request.Header.Get("Origin")
if origin == "" {
fetchSite := request.Header.Get("Sec-Fetch-Site")
return fetchSite == "" || fetchSite == "same-origin" || fetchSite == "none"
}
parsed, err := url.Parse(origin)
return err == nil && strings.EqualFold(parsed.Host, request.Host)
}
func (server *Server) requireSession(next http.Handler) http.Handler {
return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
if !server.authenticated(request) {
writeError(writer, http.StatusUnauthorized, "authentication required")
return
}
next.ServeHTTP(writer, request)
})
}
func (server *Server) authenticated(request *http.Request) bool {
cookie, err := request.Cookie(sessionCookieName)
return err == nil && server.sessions.Valid(cookie.Value)
}