package webui import ( "fmt" "html/template" "net/http" "git.adyxax.org/adyxax/tfstated/pkg/database" "git.adyxax.org/adyxax/tfstated/pkg/model" "go.n16f.net/uuid" ) type AccountsIdResetPasswordPage struct { Account *model.Account Page *Page PasswordInvalid bool PasswordChanged bool Token string } var accountsIdResetPasswordTemplates = template.Must(template.ParseFS(htmlFS, "html/base.html", "html/accountsIdResetPassword.html")) func processAccountsIdResetPasswordPathValues(db *database.DB, w http.ResponseWriter, r *http.Request) *model.Account { var accountId uuid.UUID if err := accountId.Parse(r.PathValue("id")); err != nil { return nil } var token uuid.UUID if err := token.Parse(r.PathValue("token")); err != nil { errorResponse(w, r, http.StatusBadRequest, err) return nil } account, err := db.LoadAccountById(&accountId) if err != nil { errorResponse(w, r, http.StatusInternalServerError, err) return nil } if account == nil || account.PasswordReset == nil { errorResponse(w, r, http.StatusBadRequest, err) return nil } if !account.PasswordReset.Equal(token) { errorResponse(w, r, http.StatusBadRequest, err) return nil } return account } func handleAccountsIdResetPasswordGET(db *database.DB) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { account := processAccountsIdResetPasswordPathValues(db, w, r) if account == nil { return } render(w, accountsIdResetPasswordTemplates, http.StatusOK, AccountsIdResetPasswordPage{ Account: account, Page: makePage(r, &Page{Title: "Password Reset", Section: "reset"}), Token: r.PathValue("token"), }) }) } func handleAccountsIdResetPasswordPOST(db *database.DB) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { account := processAccountsIdResetPasswordPathValues(db, w, r) if account == nil { return } if err := r.ParseForm(); err != nil { errorResponse(w, r, http.StatusBadRequest, fmt.Errorf("failed to parse form: %w", err)) return } if !verifyCSRFToken(w, r) { return } password := r.FormValue("password") if len(password) < 8 { errorResponse(w, r, http.StatusBadRequest, nil) return } account.SetPassword(password) if err := db.SaveAccount(account); err != nil { errorResponse(w, r, http.StatusInternalServerError, err) return } render(w, accountsIdResetPasswordTemplates, http.StatusOK, AccountsIdResetPasswordPage{ Account: account, Page: makePage(r, &Page{Title: "Password Reset", Section: "reset"}), PasswordChanged: true, }) }) }