Add password complexity requirements
Require at least one uppercase letter, one lowercase letter, and one digit in addition to the existing 8-character minimum. Fixes #31 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
fdcccce476
commit
cba9b5c408
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
"unicode"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/mattnite/forgejo-tickets/internal/auth"
|
"github.com/mattnite/forgejo-tickets/internal/auth"
|
||||||
|
|
@ -11,6 +12,28 @@ import (
|
||||||
"github.com/rs/zerolog/log"
|
"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 {
|
type AuthHandler struct {
|
||||||
deps Dependencies
|
deps Dependencies
|
||||||
}
|
}
|
||||||
|
|
@ -85,8 +108,8 @@ func (h *AuthHandler) Register(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(password) < 8 {
|
if errMsg := validatePassword(password); errMsg != "" {
|
||||||
data["Error"] = "Password must be at least 8 characters"
|
data["Error"] = errMsg
|
||||||
h.deps.Renderer.Render(c.Writer, c.Request, "register", data)
|
h.deps.Renderer.Render(c.Writer, c.Request, "register", data)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -189,10 +212,10 @@ func (h *AuthHandler) ResetPassword(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(password) < 8 {
|
if errMsg := validatePassword(password); errMsg != "" {
|
||||||
h.deps.Renderer.Render(c.Writer, c.Request, "reset-password", map[string]interface{}{
|
h.deps.Renderer.Render(c.Writer, c.Request, "reset-password", map[string]interface{}{
|
||||||
"Token": token,
|
"Token": token,
|
||||||
"Error": "Password must be at least 8 characters",
|
"Error": errMsg,
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue