mirror of
https://github.com/Floriansylvain/RenewCMS.git
synced 2026-08-19 11:43:22 +02:00
feat: password reset #32
This commit is contained in:
+17
@@ -105,30 +105,47 @@ func NewPageRouter() http.Handler {
|
||||
r.Handle("/static/*", http.StripPrefix("/static/", fileServer))
|
||||
|
||||
r.Get("/", GetLogin)
|
||||
|
||||
r.Get(LoginRoute, GetLoginPageHandler(EmptyLoginPage))
|
||||
r.Post(LoginRoute, GetLoginPageHandler(EmptyLoginPage))
|
||||
|
||||
r.Get("/register", GetRegisterPageHandler(EmptyRegisterPage))
|
||||
r.Post("/register", GetRegisterPageHandler(EmptyRegisterPage))
|
||||
|
||||
r.Get("/logout", GetLogout)
|
||||
|
||||
r.Get("/register/reset/request", GetPasswordResetRequest)
|
||||
r.Post("/register/reset/request", PostPasswordResetRequest)
|
||||
|
||||
r.Get("/register/reset/validate", GetPasswordResetValidate)
|
||||
r.Post("/register/reset/validate", PostPasswordResetValidate)
|
||||
|
||||
r.Group(func(r chi.Router) {
|
||||
r.Use(IsLoggedInMiddleware)
|
||||
r.Use(IsNotVerifiedMiddleware)
|
||||
|
||||
r.Get("/register/pending", GetRegisterPendingPage)
|
||||
r.Post("/register/pending", PostRegisterPendingPage)
|
||||
|
||||
r.Get("/register/validate", GetRegisterValidatePage)
|
||||
})
|
||||
|
||||
r.Group(func(r chi.Router) {
|
||||
r.Use(IsLoggedInMiddleware)
|
||||
r.Use(IsVerifiedMiddleware)
|
||||
|
||||
r.Get("/home", GetHomePage)
|
||||
|
||||
r.Get("/post", GetPostsPage)
|
||||
|
||||
r.Get("/post/{id}/edit", GetPostEditPage)
|
||||
r.Post("/post/{id}/edit", PostPostEditPage)
|
||||
|
||||
r.Get("/post/{id}/delete", GetPostDeletePage)
|
||||
|
||||
r.Get("/post/create", GetPostCreatePage)
|
||||
r.Post("/post/create", PostPostCreatePage)
|
||||
|
||||
r.Post("/post/{id}/image/create", postImage)
|
||||
})
|
||||
|
||||
|
||||
+4
-4
@@ -2,6 +2,7 @@ package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
const LoginRoute = "/login"
|
||||
@@ -30,14 +31,13 @@ func GetLoginPageHandler(loginPage *LoginPage) http.HandlerFunc {
|
||||
http.Redirect(w, r, "/register", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
bs, err := Container.GetPageUseCase.GetPage("login", map[string]interface{}{
|
||||
success, _ := url.QueryUnescape(r.URL.Query().Get("success"))
|
||||
bs, _ := Container.GetPageUseCase.GetPage("login", map[string]interface{}{
|
||||
"PageError": loginPage.PageError,
|
||||
"Username": loginPage.Username,
|
||||
"Head": headTmpl,
|
||||
"Success": success,
|
||||
})
|
||||
if err != nil {
|
||||
_, _ = w.Write([]byte(err.Error()))
|
||||
}
|
||||
_, _ = w.Write(bs)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"github.com/google/uuid"
|
||||
"net/http"
|
||||
"os"
|
||||
)
|
||||
|
||||
type PasswordResetRequest struct {
|
||||
Email string `json:"email"`
|
||||
}
|
||||
|
||||
var successMessage = "An email has been sent to the provided email address if it exists."
|
||||
|
||||
func GetPasswordResetRequest(w http.ResponseWriter, r *http.Request) {
|
||||
success := r.URL.Query().Get("success")
|
||||
email := r.URL.Query().Get("email")
|
||||
|
||||
bs, _ := Container.GetPageUseCase.GetPage("passwordResetRequest", map[string]interface{}{
|
||||
"Head": headTmpl,
|
||||
"Email": email,
|
||||
"Success": success,
|
||||
})
|
||||
_, _ = w.Write(bs)
|
||||
}
|
||||
|
||||
func PostPasswordResetRequest(w http.ResponseWriter, r *http.Request) {
|
||||
_ = r.ParseForm()
|
||||
passResetReq := PasswordResetRequest{
|
||||
Email: r.FormValue("email"),
|
||||
}
|
||||
var getRedirectUrl = "/register/reset/request?success=" + successMessage + "&email=" + passResetReq.Email
|
||||
|
||||
err := validate.Struct(passResetReq)
|
||||
if err != nil {
|
||||
http.Redirect(w, r, getRedirectUrl, http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
|
||||
fetchedUser, err := Container.GetUserUseCase.GetUserByEmail(passResetReq.Email)
|
||||
if err != nil {
|
||||
http.Redirect(w, r, getRedirectUrl, http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
|
||||
verificationCode := uuid.NewString()
|
||||
updatedUser, _ := Container.UpdateUserUseCase.UpdatePasswordResetCode(fetchedUser.ID, verificationCode)
|
||||
|
||||
_ = Container.SendMailUseCase.SendMail(updatedUser.Email, "passwordReset", map[string]string{
|
||||
"Host": os.Getenv("HOST"),
|
||||
"VerificationCode": verificationCode,
|
||||
"Email": updatedUser.Email,
|
||||
})
|
||||
|
||||
http.Redirect(w, r, getRedirectUrl, http.StatusSeeOther)
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
var PasswordLinkErrorMessage = "The reset password link you used is invalid."
|
||||
var PasswordLinkSuccessMessage = "Your account password was successfully updated."
|
||||
|
||||
func GetPasswordResetValidate(w http.ResponseWriter, r *http.Request) {
|
||||
failure := r.URL.Query().Get("failure")
|
||||
pageError := NewPageError("")
|
||||
if failure != "" {
|
||||
pageError = NewPageError(failure)
|
||||
}
|
||||
template, _ := Container.GetPageUseCase.GetPage("passwordResetValidate", map[string]interface{}{
|
||||
"Head": headTmpl,
|
||||
"Error": pageError,
|
||||
"Email": r.URL.Query().Get("email"),
|
||||
"Code": r.URL.Query().Get("c"),
|
||||
})
|
||||
_, _ = w.Write(template)
|
||||
}
|
||||
|
||||
func PostPasswordResetValidate(w http.ResponseWriter, r *http.Request) {
|
||||
_ = r.ParseForm()
|
||||
email := r.FormValue("email")
|
||||
password := r.FormValue("password")
|
||||
resetCode := r.FormValue("code")
|
||||
|
||||
var redirectionErrorLink = "/register/reset/validate?email=" + email + "&c=" + resetCode
|
||||
|
||||
if len(password) < 8 {
|
||||
http.Redirect(w, r, redirectionErrorLink+"&failure=Password length should be at least 8 characters.", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
|
||||
fetchedUser, err := Container.GetUserUseCase.GetUserByEmail(email)
|
||||
if err != nil {
|
||||
http.Redirect(w, r, redirectionErrorLink+"&failure="+PasswordLinkErrorMessage, http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
|
||||
err = bcrypt.CompareHashAndPassword([]byte(fetchedUser.PasswordResetCode), []byte(resetCode))
|
||||
if err != nil {
|
||||
http.Redirect(w, r, redirectionErrorLink+"&failure="+PasswordLinkErrorMessage, http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
|
||||
_, _ = Container.UpdateUserUseCase.UpdatePassword(fetchedUser.ID, password)
|
||||
_, _ = Container.UpdateUserUseCase.UpdatePasswordResetCode(fetchedUser.ID, "")
|
||||
|
||||
http.Redirect(w, r, "/login?success="+PasswordLinkSuccessMessage, http.StatusSeeOther)
|
||||
}
|
||||
Reference in New Issue
Block a user