Files
unifi-adblocker/main.go

92 lines
3.3 KiB
Go

package main
import (
"flag"
"fmt"
"io/fs"
"log"
"net/http"
"os"
"github.com/gorilla/mux"
"github.com/justinas/nosurf"
"golang.org/x/crypto/bcrypt"
)
func main() {
pw := flag.String("pw", "", "Generate hashed password (e.g., -pw 'MyPassword123!'). Outputs hash to terminal without starting app.")
mfaCmd := flag.String("mfa", "", "Manage MFA: 'on' (enforce), 'off' (disable), 'reset' (remove and show secret). Does not start app.")
port := flag.String("port", "", "Port to listen on (overrides config). Default: 8080")
bindAddr := flag.String("bind", "", "Bind address (overrides config). Default: 0.0.0.0")
flag.Parse()
// Handle password hashing flag
if *pw != "" {
hashed, err := bcrypt.GenerateFromPassword([]byte(*pw), bcrypt.DefaultCost)
if err != nil {
fmt.Fprintf(os.Stderr, "Error hashing password: %v\n", err)
os.Exit(1)
}
fmt.Printf("Hashed password (copy to config file):\n%s\n", string(hashed))
os.Exit(0)
}
loadConfig()
// Handle MFA management flag
if *mfaCmd != "" {
handleMFACommand(*mfaCmd)
os.Exit(0)
}
// Initialize authentication (set startup time)
initAuth()
// Override config with command-line flags if provided
if *port != "" {
config.Port = *port
}
if *bindAddr != "" {
config.BindAddr = *bindAddr
}
go monitorPID()
r := mux.NewRouter()
// Static files
staticFS, _ := fs.Sub(content, "static")
r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.FS(staticFS))))
// Public routes
r.HandleFunc("/login", loginHandler).Methods("GET", "POST")
r.HandleFunc("/logout", logoutHandler)
// Protected routes
r.HandleFunc("/profile", authMiddleware(profileHandler)).Methods("GET", "POST")
r.HandleFunc("/api/mfa-setup", authMiddleware(mfaSetupHandler)).Methods("POST")
r.HandleFunc("/api/search-domains", authMiddleware(searchDomainsHandler)).Methods("POST")
r.HandleFunc("/api/search-whitelist", authMiddleware(searchWhitelistHandler)).Methods("POST")
r.HandleFunc("/api/filter-search", authMiddleware(filterSearchHandler)).Methods("POST")
r.HandleFunc("/", authMiddleware(dashboardHandler))
r.HandleFunc("/filters", authMiddleware(filtersHandler))
r.HandleFunc("/filters/create", authMiddleware(createFilterHandler)).Methods("POST")
r.HandleFunc("/filters/edit", authMiddleware(editFilterHandler)).Methods("GET", "POST")
r.HandleFunc("/filter", authMiddleware(filterDetailHandler))
r.HandleFunc("/filter/blocklist", authMiddleware(filterBlocklistHandler)).Methods("GET", "POST")
r.HandleFunc("/filter/blocklist/urls", authMiddleware(filterBlocklistHandler)).Methods("GET", "POST")
r.HandleFunc("/filter/whitelist", authMiddleware(filterWhitelistHandler)).Methods("GET", "POST")
r.HandleFunc("/filter/whitelist/urls", authMiddleware(filterWhitelistHandler)).Methods("GET", "POST")
r.HandleFunc("/urllists", authMiddleware(urlListsHandler)).Methods("GET", "POST")
r.HandleFunc("/domains", authMiddleware(domainsHandler)).Methods("GET", "POST")
r.HandleFunc("/whitelist", authMiddleware(whitelistHandler)).Methods("GET", "POST")
r.HandleFunc("/apply", authMiddleware(applyHandler)).Methods("POST")
r.HandleFunc("/logs", authMiddleware(logsHandler))
// CSRF protection middleware
csrfHandler := nosurf.New(r)
listenAddr := config.BindAddr + ":" + config.Port
log.Printf("Starting server on %s", listenAddr)
http.ListenAndServe(listenAddr, csrfHandler)
}