92 lines
3.3 KiB
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)
|
|
} |