package handlers import ( "crypto/subtle" "net/http" "net/url" "regexp" "crowdsec-dashy/internal/middleware" ) var validNameRE = regexp.MustCompile(`^[a-zA-Z0-9_\-]{1,64}$`) func matchName(name string) (bool, error) { return validNameRE.MatchString(name), nil } // flashRedirect redirects with flash type and message as query params. func flashRedirect(w http.ResponseWriter, r *http.Request, to, flashType, msg string) { v := url.Values{} v.Set("flash", flashType) v.Set("msg", msg) http.Redirect(w, r, to+"?"+v.Encode(), http.StatusSeeOther) } // readFlash extracts a validated flash message from URL query params. func readFlash(r *http.Request) FlashMessage { flash := r.URL.Query().Get("flash") msg := r.URL.Query().Get("msg") if flash == "" || msg == "" { return FlashMessage{} } switch flash { case "success", "error", "warning", "info": return FlashMessage{Type: flash, Message: msg} } return FlashMessage{} } // checkCSRF verifies the _csrf form field against the token in the request context. // Must be called after r.ParseForm(). func checkCSRF(r *http.Request) bool { expected := middleware.CSRFFromContext(r) if expected == "" { return false } got := r.FormValue("_csrf") return subtle.ConstantTimeCompare([]byte(got), []byte(expected)) == 1 }