diff options
| author | Bobby <[email protected]> | 2026-03-05 13:14:50 +0530 |
|---|---|---|
| committer | Bobby <[email protected]> | 2026-03-05 13:14:50 +0530 |
| commit | c3677e1a4dc0b662579c82755aef6e0e9573eee8 (patch) | |
| tree | 1fa31644b3e75fabbf14642e7725cb1c193ef72d | |
| parent | d05edfba524b27b58eb98f7ca533bf6cd2c40862 (diff) | |
| download | pagoda-c3677e1a4dc0b662579c82755aef6e0e9573eee8.tar.xz pagoda-c3677e1a4dc0b662579c82755aef6e0e9573eee8.zip | |
feat: add resend activation functionality and update verification process
| -rw-r--r-- | shrine/controllers/auth.go | 46 | ||||
| -rw-r--r-- | shrine/repositories/user.go | 6 | ||||
| -rw-r--r-- | shrine/router/auth.go | 1 | ||||
| -rw-r--r-- | shrine/types/request.go | 5 |
4 files changed, 56 insertions, 2 deletions
diff --git a/shrine/controllers/auth.go b/shrine/controllers/auth.go index 8eedb38..1e49b37 100644 --- a/shrine/controllers/auth.go +++ b/shrine/controllers/auth.go @@ -99,14 +99,21 @@ func VerifyController(context *fiber.Ctx) error { return BadRequest(context, errors.New("Verification token is required.")) } + verificationType := enums.VerificationType(body.Type) + tokenHash := auth.HashToken(body.Token) - user, err := repositories.FindUserByVerification(tokenHash, enums.Activation) + user, err := repositories.FindUserByVerification(tokenHash, verificationType) if err != nil { return BadRequest(context, errors.New("Your verification link is invalid or has expired.")) } - user.VerifyEmail() + switch verificationType { + case enums.Activation: + user.VerifyEmail() + default: + return BadRequest(context, errors.New("Invalid verification type.")) + } if err := repositories.UpdateUser(user); err != nil { return InternalServerError(context, errors.New("Failed to verify your account.")) @@ -117,6 +124,41 @@ func VerifyController(context *fiber.Ctx) error { }) } +func ResendActivationController(context *fiber.Ctx) error { + body, err := meta.Body[types.ResendActivationRequest](context) + if err != nil { + return BadRequest(context, errors.New("Invalid request body.")) + } + + user, err := repositories.FindUserByEmail(body.Email) + if err != nil { + return BadRequest(context, errors.New("No account exists with that email address.")) + } + + if user.IsVerified() { + return BadRequest(context, errors.New("This account has already been verified.")) + } + + token, err := auth.GenerateToken() + if err != nil { + return InternalServerError(context, errors.New("Failed to generate verification token.")) + } + + user.SetVerification(auth.HashToken(token), time.Now().Add(24*time.Hour), enums.Activation) + + if err := repositories.UpdateUser(user); err != nil { + return InternalServerError(context, errors.New("Failed to store verification token.")) + } + + if err := emails.SendActivation(user.Email, user.Username, token); err != nil { + logger.Errorf("Auth", "Failed to send verification email to %s: %v", user.Email, err) + } + + return Success(context, types.MessageResponse{ + Message: "A new verification email has been sent. Please check your inbox.", + }) +} + func LogoutController(context *fiber.Ctx) error { tokenHash := auth.GetTokenHash(context) if err := repositories.DeleteToken(tokenHash); err != nil { diff --git a/shrine/repositories/user.go b/shrine/repositories/user.go index 697c5df..1161257 100644 --- a/shrine/repositories/user.go +++ b/shrine/repositories/user.go @@ -30,6 +30,12 @@ func UpdateUser(user *models.User) error { return database.DB.Save(user).Error } +func FindUserByEmail(email string) (*models.User, error) { + var user models.User + err := database.DB.Where("email = ?", email).First(&user).Error + return &user, err +} + func FindUserByVerification(hash string, verificationType enums.VerificationType) (*models.User, error) { var user models.User err := database.DB.Where("verification_hash = ? AND verification_type = ? AND verification_expiry > ?", hash, verificationType, time.Now()).First(&user).Error diff --git a/shrine/router/auth.go b/shrine/router/auth.go index 7c566eb..5ad5fee 100644 --- a/shrine/router/auth.go +++ b/shrine/router/auth.go @@ -13,6 +13,7 @@ func init() { urls.Path(types.POST, "/register", controllers.RegisterController, "register") urls.Path(types.POST, "/login", controllers.LoginController, "login") urls.Path(types.POST, "/verify", controllers.VerifyController, "verify") + urls.Path(types.POST, "/reactivate", controllers.ResendActivationController, "reactivate") urls.Path(types.POST, "/logout", auth.RequireAuthentication(controllers.LogoutController), "logout") urls.Path(types.GET, "/me", auth.RequireAuthentication(controllers.MeController), "me") }
\ No newline at end of file diff --git a/shrine/types/request.go b/shrine/types/request.go index 32e81a9..a782efd 100644 --- a/shrine/types/request.go +++ b/shrine/types/request.go @@ -14,4 +14,9 @@ type LoginRequest struct { type VerifyRequest struct { Token string `json:"token"` + Type string `json:"type"` +} + +type ResendActivationRequest struct { + Email string `json:"email"` }
\ No newline at end of file |
