diff --git a/internal/handlers/public/auth.go b/internal/handlers/public/auth.go index 1e029f2..2b32abc 100644 --- a/internal/handlers/public/auth.go +++ b/internal/handlers/public/auth.go @@ -3,6 +3,7 @@ package public import ( "net/http" "strings" + "unicode" "github.com/gin-gonic/gin" "github.com/mattnite/forgejo-tickets/internal/auth" @@ -11,6 +12,28 @@ import ( "github.com/rs/zerolog/log" ) +// validatePassword checks password complexity requirements. +func validatePassword(password string) string { + if len(password) < 8 { + return "Password must be at least 8 characters" + } + var hasUpper, hasLower, hasDigit bool + for _, r := range password { + switch { + case unicode.IsUpper(r): + hasUpper = true + case unicode.IsLower(r): + hasLower = true + case unicode.IsDigit(r): + hasDigit = true + } + } + if !hasUpper || !hasLower || !hasDigit { + return "Password must contain at least one uppercase letter, one lowercase letter, and one digit" + } + return "" +} + type AuthHandler struct { deps Dependencies } @@ -85,8 +108,8 @@ func (h *AuthHandler) Register(c *gin.Context) { return } - if len(password) < 8 { - data["Error"] = "Password must be at least 8 characters" + if errMsg := validatePassword(password); errMsg != "" { + data["Error"] = errMsg h.deps.Renderer.Render(c.Writer, c.Request, "register", data) return } @@ -183,10 +206,10 @@ func (h *AuthHandler) ResetPassword(c *gin.Context) { return } - if len(password) < 8 { + if errMsg := validatePassword(password); errMsg != "" { h.deps.Renderer.Render(c.Writer, c.Request, "reset-password", map[string]interface{}{ "Token": token, - "Error": "Password must be at least 8 characters", + "Error": errMsg, }) return }