102 lines
2.8 KiB
Go
102 lines
2.8 KiB
Go
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)
|
|
success, err := db.SaveAccount(account)
|
|
if err != nil {
|
|
errorResponse(w, r, http.StatusInternalServerError,
|
|
fmt.Errorf("failed to save account: %w", err))
|
|
return
|
|
}
|
|
if !success {
|
|
errorResponse(w, r, http.StatusInternalServerError,
|
|
fmt.Errorf("failed to save account: table constraint error"))
|
|
return
|
|
}
|
|
render(w, accountsIdResetPasswordTemplates, http.StatusOK,
|
|
AccountsIdResetPasswordPage{
|
|
Account: account,
|
|
Page: makePage(r, &Page{Title: "Password Reset", Section: "reset"}),
|
|
PasswordChanged: true,
|
|
})
|
|
})
|
|
}
|