Remove password reset functionality

Backend:
- Remove ForgotPassword API handler
- Remove password reset token model and database table
- Remove email service for sending reset emails
- Remove SMTP configuration

Frontend:
- Remove /auth/forgot page
- Remove forgot password link from login page
- Remove forgot route from auth-only routes check
This commit is contained in:
Christoph Haas 2026-03-23 22:35:30 +01:00
parent c459cc1efb
commit abd7e3a97f
9 changed files with 5 additions and 425 deletions

View file

@ -1,7 +1,6 @@
package handlers
import (
"log"
"net/http"
"strings"
"time"
@ -9,7 +8,6 @@ import (
"github.com/gin-gonic/gin"
"github.com/imc-vibe/backend/internal/auth"
"github.com/imc-vibe/backend/internal/db"
"github.com/imc-vibe/backend/internal/mail"
)
const MaxLoginAttempts = 5
@ -17,15 +15,13 @@ const MaxLoginAttempts = 5
type AuthHandler struct {
db *db.DB
jwtManager *auth.JWTManager
emailService *mail.EmailService
trustedProxies []string
}
func NewAuthHandler(database *db.DB, jwtManager *auth.JWTManager, emailService *mail.EmailService, trustedProxies []string) *AuthHandler {
func NewAuthHandler(database *db.DB, jwtManager *auth.JWTManager, trustedProxies []string) *AuthHandler {
return &AuthHandler{
db: database,
jwtManager: jwtManager,
emailService: emailService,
trustedProxies: trustedProxies,
}
}
@ -40,10 +36,6 @@ type ChangePasswordRequest struct {
NewPassword string `json:"newPassword" binding:"required,min=8"`
}
type ForgotPasswordRequest struct {
Identifier string `json:"identifier" binding:"required"`
}
type UserResponse struct {
ID uint `json:"id"`
Username string `json:"username"`
@ -128,47 +120,6 @@ func (h *AuthHandler) Me(c *gin.Context) {
})
}
func (h *AuthHandler) ForgotPassword(c *gin.Context) {
var req ForgotPasswordRequest
if err := c.ShouldBindJSON(&req); err != nil {
Error(c, http.StatusBadRequest, "invalid request")
return
}
req.Identifier = strings.TrimSpace(strings.ToLower(req.Identifier))
if req.Identifier == "" {
Error(c, http.StatusBadRequest, "identifier required")
return
}
user, err := h.db.GetImcUserByUsername(req.Identifier)
if err != nil {
Success(c, map[string]string{
"message": "If the account exists, a password reset link will be sent",
})
return
}
token := mail.GenerateToken()
expiresAt := time.Now().Add(1 * time.Hour)
if err := h.db.CreatePasswordResetToken(user.ID, token, expiresAt); err != nil {
log.Printf("Failed to create password reset token: %v", err)
Error(c, http.StatusInternalServerError, "failed to create reset token")
return
}
if err := h.emailService.SendPasswordReset(user.Username, token); err != nil {
log.Printf("Failed to send password reset email: %v", err)
Error(c, http.StatusInternalServerError, "failed to send email")
return
}
Success(c, map[string]string{
"message": "If the account exists, a password reset link will be sent",
})
}
func (h *AuthHandler) ChangePassword(c *gin.Context) {
authCtx := GetAuthContext(c)
if authCtx == nil {

View file

@ -8,7 +8,6 @@ import (
"github.com/imc-vibe/backend/internal/auth"
"github.com/imc-vibe/backend/internal/config"
"github.com/imc-vibe/backend/internal/db"
"github.com/imc-vibe/backend/internal/mail"
)
type Router struct {
@ -24,10 +23,9 @@ type Router struct {
func New(database *db.DB, cfg *config.Config) *Router {
jwtManager := auth.NewJWTManager(cfg.JWTSecret, "imc-vibe")
emailService := mail.NewEmailService(cfg)
r := &Router{
authHandler: handlers.NewAuthHandler(database, jwtManager, emailService, cfg.TrustedProxies),
authHandler: handlers.NewAuthHandler(database, jwtManager, cfg.TrustedProxies),
domainHandler: handlers.NewDomainHandler(database),
userHandler: handlers.NewUserHandler(database),
aliasHandler: handlers.NewAliasHandler(database),
@ -46,7 +44,6 @@ func (r *Router) RegisterRoutes(engine *gin.Engine) {
})
engine.POST("/api/auth/login", r.authHandler.Login)
engine.POST("/api/auth/forgot", r.authHandler.ForgotPassword)
engine.POST("/api/auth/logout", r.authHandler.Logout)
authGroup := engine.Group("/api")