mirror of
https://github.com/Floriansylvain/RenewCMS.git
synced 2026-08-19 19:53:21 +02:00
feat: complete email verification flow
This commit is contained in:
+11
-1
@@ -47,6 +47,16 @@ func SetJwtCookie(w *http.ResponseWriter, userId uint32) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func SomeUsersVerified() bool {
|
||||
users := Container.ListUsersUseCase.ListUsers()
|
||||
for _, localUser := range users {
|
||||
if localUser.IsVerified {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func IsUserTableEmpty() bool {
|
||||
users := Container.ListUsersUseCase.ListUsers()
|
||||
return len(users) == 0
|
||||
@@ -131,7 +141,7 @@ func login(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func register(w http.ResponseWriter, r *http.Request) {
|
||||
if !IsLoggedIn(r) && !IsUserTableEmpty() {
|
||||
if !IsLoggedIn(r) && !SomeUsersVerified() {
|
||||
http.Error(w, "You are not allowed to create a user. Log in or reset database.", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ type UseCases struct {
|
||||
GetUserUseCase *useCases.GetUserUseCase
|
||||
CreateUserUseCase *useCases.CreateUserUseCase
|
||||
UpdateUserUseCase *useCases.UpdateUserUseCase
|
||||
DeleteUserUseCase *useCases.DeleteUserUseCase
|
||||
ListUsersUseCase *useCases.ListUsersUseCase
|
||||
GetPageUseCase *useCases.GetPageUseCase
|
||||
SendMailUseCase *useCases.SendMailUseCase
|
||||
@@ -51,6 +52,7 @@ func InitContainer() {
|
||||
GetUserUseCase: useCases.NewGetUserUseCase(db),
|
||||
CreateUserUseCase: useCases.NewCreateUserUseCase(db),
|
||||
UpdateUserUseCase: useCases.NewUpdateUserUseCase(db),
|
||||
DeleteUserUseCase: useCases.NewDeleteUserUseCase(db),
|
||||
ListUsersUseCase: useCases.NewListUsersUseCase(db),
|
||||
GetPageUseCase: useCases.NewGetPageUseCase(),
|
||||
SendMailUseCase: useCases.NewSendMailUseCase(),
|
||||
|
||||
@@ -113,6 +113,7 @@ func NewPageRouter() http.Handler {
|
||||
r.Use(IsLoggedInMiddleware)
|
||||
r.Use(IsNotVerifiedMiddleware)
|
||||
r.Get("/register/pending", GetRegisterPendingPage)
|
||||
r.Post("/register/pending", PostRegisterPendingPage)
|
||||
r.Get("/register/validate", GetRegisterValidatePage)
|
||||
})
|
||||
|
||||
|
||||
+2
-2
@@ -53,7 +53,7 @@ func PostLoginPage(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
r.Method = http.MethodGet
|
||||
GetLoginPageHandler(&LoginPage{
|
||||
PageError: NewPageError("Invalid form data format."),
|
||||
PageError: NewPageError("Invalid username or password format."),
|
||||
Username: r.FormValue("username"),
|
||||
})(w, r)
|
||||
return
|
||||
@@ -63,7 +63,7 @@ func PostLoginPage(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
r.Method = http.MethodGet
|
||||
GetLoginPageHandler(&LoginPage{
|
||||
PageError: NewPageError("Invalid username or password."),
|
||||
PageError: NewPageError("Invalid username or password combination."),
|
||||
Username: r.FormValue("username"),
|
||||
})(w, r)
|
||||
return
|
||||
|
||||
+35
-15
@@ -6,21 +6,31 @@ import (
|
||||
"os"
|
||||
)
|
||||
|
||||
type RegisterPageError struct {
|
||||
Email bool `json:"email"`
|
||||
Password bool `json:"password"`
|
||||
Username bool `json:"username"`
|
||||
}
|
||||
|
||||
type RegisterPage struct {
|
||||
PageError *PageError `json:"error"`
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
PageError *RegisterPageError `json:"error"`
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
}
|
||||
|
||||
var EmptyRegisterPage = &RegisterPage{
|
||||
PageError: NewPageError(""),
|
||||
Username: "",
|
||||
Email: "",
|
||||
PageError: &RegisterPageError{
|
||||
Email: false,
|
||||
Password: false,
|
||||
Username: false,
|
||||
},
|
||||
Username: "",
|
||||
Email: "",
|
||||
}
|
||||
|
||||
func GetRegisterPageHandler(registerPage *RegisterPage) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
if IsLoggedIn(r) || !IsUserTableEmpty() {
|
||||
if (IsLoggedIn(r) && IsVerified(r)) || SomeUsersVerified() {
|
||||
http.Redirect(w, r, "/home", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
@@ -53,9 +63,13 @@ func PostRegisterPage(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
r.Method = http.MethodGet
|
||||
GetRegisterPageHandler(&RegisterPage{
|
||||
PageError: NewPageError("Invalid register form data format."),
|
||||
Username: r.FormValue("username"),
|
||||
Email: r.FormValue("email"),
|
||||
PageError: &RegisterPageError{
|
||||
Email: true,
|
||||
Password: true,
|
||||
Username: true,
|
||||
},
|
||||
Username: r.FormValue("username"),
|
||||
Email: r.FormValue("email"),
|
||||
})(w, r)
|
||||
return
|
||||
}
|
||||
@@ -63,17 +77,23 @@ func PostRegisterPage(w http.ResponseWriter, r *http.Request) {
|
||||
verificationCode := uuid.NewString()
|
||||
createdUser, err := getNewUser(credentials, verificationCode)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
r.Method = http.MethodGet
|
||||
GetRegisterPageHandler(&RegisterPage{
|
||||
PageError: &RegisterPageError{
|
||||
Email: true,
|
||||
Password: false,
|
||||
Username: false,
|
||||
},
|
||||
Username: r.FormValue("username"),
|
||||
Email: r.FormValue("email"),
|
||||
})(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
err = Container.SendMailUseCase.SendMail(createdUser.Email, "mailValidation", map[string]string{
|
||||
_ = Container.SendMailUseCase.SendMail(createdUser.Email, "mailValidation", map[string]string{
|
||||
"Host": os.Getenv("HOST"),
|
||||
"VerificationCode": verificationCode,
|
||||
})
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
_ = SetJwtCookie(&w, createdUser.ID)
|
||||
|
||||
|
||||
@@ -1,6 +1,29 @@
|
||||
package api
|
||||
|
||||
import "net/http"
|
||||
import (
|
||||
"github.com/go-chi/jwtauth/v5"
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func PostRegisterPendingPage(w http.ResponseWriter, r *http.Request) {
|
||||
token, _ := jwtauth.VerifyRequest(
|
||||
TokenAuth, r,
|
||||
jwtauth.TokenFromCookie,
|
||||
jwtauth.TokenFromHeader,
|
||||
jwtauth.TokenFromQuery)
|
||||
userId := token.PrivateClaims()["user_id"].(float64)
|
||||
err := Container.DeleteUserUseCase.DeleteUser(uint32(userId))
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
r.Method = http.MethodGet
|
||||
http.Redirect(w, r, "/register/pending", http.StatusSeeOther)
|
||||
}
|
||||
|
||||
RemoveJwtCookie(w)
|
||||
|
||||
http.Redirect(w, r, "/register", http.StatusSeeOther)
|
||||
}
|
||||
|
||||
func GetRegisterPendingPage(w http.ResponseWriter, _ *http.Request) {
|
||||
registerPendingTmpl, _ := Container.GetPageUseCase.GetPage("registerPending", map[string]interface{}{
|
||||
|
||||
Reference in New Issue
Block a user