package handlers import ( "net/http" "time" "github.com/gin-gonic/gin" "github.com/dchest/captcha" "go-dy/internal/auth" "go-dy/internal/config" dbpkg "go-dy/internal/db" "go-dy/internal/repo" "go-dy/internal/resp" ) func LoginHandler(cfg config.Config) gin.HandlerFunc { return func(c *gin.Context) { // Expect form data: name, password (+ optional captcha when enabled) name := c.PostForm("name") password := c.PostForm("password") if name == "" || password == "" { resp.Error(c, http.StatusBadRequest, "missing name or password") return } // captcha gate (if enabled) if cfg.LoginRequireCaptcha { cid := c.PostForm("captcha_id") ccode := c.PostForm("captcha_code") if cid == "" || ccode == "" { resp.Error(c, http.StatusBadRequest, "missing captcha_id or captcha_code") return } if !captcha.VerifyString(cid, ccode) { resp.Error(c, http.StatusUnauthorized, "invalid captcha") return } } // Database-backed login only: always check users table db, err := dbpkg.Get(cfg) if err != nil { resp.Error(c, http.StatusServiceUnavailable, "database unavailable") return } u, err := repo.GetUserByName(db, name) if err != nil { resp.Error(c, http.StatusInternalServerError, "query user failed") return } if u == nil || !repo.CheckPassword(u, password) { resp.Error(c, http.StatusUnauthorized, "invalid credentials") return } token, err := auth.GenerateToken(name, cfg.JWTSecret, 24*time.Hour) if err != nil { resp.Error(c, http.StatusInternalServerError, "could not generate token") return } resp.OK(c, gin.H{"token": token}) } }