Update asset verification and documentation features

- Added a flag to disable the verifier UI and logic for user preferences.
- Implemented Cache-Control headers for static assets in production.
- Updated the SoftwareCard component to include a copy hash feature and display release dates.
- Introduced a Markdown component for rendering documentation content.
- Enhanced the verification process with speed updates during asset downloads.
- Improved the user interface for verification toasts and modals.
- Updated legal documents with new versions and additional privacy features.
- Added new API documentation and routes for better user guidance.
This commit is contained in:
2025-12-27 18:07:12 -06:00
parent 8f94411747
commit 5b8daa638d
31 changed files with 1311 additions and 161 deletions

22
main.go
View File

@@ -42,6 +42,7 @@ func main() {
uaBlocklistPath := flag.String("ua-blocklist", getEnv("UA_BLOCKLIST_PATH", "ua-blocklist.txt"), "Path to ua-blocklist.txt (optional)")
port := flag.String("p", getEnv("PORT", "8080"), "Server port")
isProd := flag.Bool("prod", os.Getenv("NODE_ENV") == "production", "Run in production mode")
disableVerifier := flag.Bool("disable-verifier", getEnv("DISABLE_VERIFIER", "false") == "true", "Completely disable the verifier UI and logic")
updateInterval := flag.Duration("u", 1*time.Hour, "Software update interval")
flag.Parse()
@@ -125,6 +126,19 @@ func main() {
path = strings.TrimPrefix(path, "/")
}
// Set Cache-Control headers for static assets
if *isProd {
if strings.HasPrefix(path, "_app/immutable/") {
// SvelteKit immutable assets (fingerprinted)
w.Header().Set("Cache-Control", "public, max-age=31536000, immutable")
} else if strings.HasSuffix(path, ".js") || strings.HasSuffix(path, ".css") ||
strings.HasSuffix(path, ".png") || strings.HasSuffix(path, ".webp") ||
strings.HasSuffix(path, ".svg") || strings.HasSuffix(path, ".wasm") {
// Other static assets (1 week)
w.Header().Set("Cache-Control", "public, max-age=604800")
}
}
f, err := contentStatic.Open(path)
if err != nil {
if strings.HasPrefix(r.URL.Path, "/api") {
@@ -137,7 +151,13 @@ func main() {
http.Error(w, "Index not found", http.StatusInternalServerError)
return
}
http.ServeContent(w, r, "index.html", time.Unix(0, 0), strings.NewReader(string(indexData)))
// Inject global configuration
html := string(indexData)
configJS := fmt.Sprintf("<script>window.VERIFIER_GLOBALLY_DISABLED = %v;</script>", *disableVerifier)
html = strings.Replace(html, "</head>", configJS+"</head>", 1)
http.ServeContent(w, r, "index.html", time.Unix(0, 0), strings.NewReader(html))
return
}
if err := f.Close(); err != nil {