add rate limiting, CSRF, newsletter, auto-checker, /uses and /projects pages
This commit is contained in:
@@ -5,12 +5,17 @@ import (
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
chromahtml "github.com/alecthomas/chroma/v2/formatters/html"
|
||||
"github.com/alecthomas/chroma/v2/styles"
|
||||
|
||||
"ridgwaysystems.org/website/internal/blog"
|
||||
"ridgwaysystems.org/website/internal/checker"
|
||||
"ridgwaysystems.org/website/internal/handler"
|
||||
"ridgwaysystems.org/website/internal/newsletter"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -28,11 +33,21 @@ func main() {
|
||||
log.Fatal("store:", err)
|
||||
}
|
||||
|
||||
h := handler.New(store, dataDir)
|
||||
news, err := newsletter.NewStore(filepath.Join(dataDir, "subscribers.json"))
|
||||
if err != nil {
|
||||
log.Fatal("newsletter store:", err)
|
||||
}
|
||||
|
||||
h := handler.New(store, news, dataDir)
|
||||
|
||||
// Start service auto-checker
|
||||
checkInterval := checkerInterval()
|
||||
checker.Start(dataDir, checkInterval)
|
||||
log.Printf("service checker running every %s", checkInterval)
|
||||
|
||||
mux := http.NewServeMux()
|
||||
|
||||
// Static files (includes robots.txt via static/robots.txt)
|
||||
// Static files
|
||||
mux.Handle("GET /static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
|
||||
|
||||
// robots.txt at root
|
||||
@@ -48,9 +63,12 @@ func main() {
|
||||
mux.HandleFunc("GET /infrastructure", h.Infrastructure)
|
||||
mux.HandleFunc("GET /status", h.Status)
|
||||
mux.HandleFunc("GET /about", h.About)
|
||||
mux.HandleFunc("GET /uses", h.Uses)
|
||||
mux.HandleFunc("GET /projects", h.Projects)
|
||||
mux.HandleFunc("GET /hire", h.Hire)
|
||||
mux.HandleFunc("POST /hire", h.HirePost)
|
||||
mux.HandleFunc("GET /resume", h.Resume)
|
||||
mux.HandleFunc("POST /newsletter", h.NewsletterPost)
|
||||
mux.HandleFunc("GET /sitemap.xml", h.Sitemap)
|
||||
|
||||
// Admin routes (auth handled per-handler)
|
||||
@@ -66,19 +84,26 @@ func main() {
|
||||
log.Fatal(http.ListenAndServe(":"+port, srv))
|
||||
}
|
||||
|
||||
// checkerInterval returns the status check interval from CHECK_INTERVAL env (minutes).
|
||||
func checkerInterval() time.Duration {
|
||||
if s := os.Getenv("CHECK_INTERVAL"); s != "" {
|
||||
if n, err := strconv.Atoi(s); err == nil && n > 0 {
|
||||
return time.Duration(n) * time.Minute
|
||||
}
|
||||
}
|
||||
return 5 * time.Minute
|
||||
}
|
||||
|
||||
// generateSyntaxCSS writes a chroma CSS file with light and dark themes.
|
||||
func generateSyntaxCSS(path string) error {
|
||||
formatter := chromahtml.New(chromahtml.WithClasses(true))
|
||||
|
||||
var buf bytes.Buffer
|
||||
|
||||
// Light theme (github)
|
||||
buf.WriteString("/* Auto-generated by chroma at server startup. Do not edit. */\n\n")
|
||||
if err := formatter.WriteCSS(&buf, styles.Get("github")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Dark theme wrapped in prefers-color-scheme media query
|
||||
buf.WriteString("\n@media (prefers-color-scheme: dark) {\n")
|
||||
var dark bytes.Buffer
|
||||
if err := formatter.WriteCSS(&dark, styles.Get("github-dark")); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user