package accountHandler import ( "net/http" "time" "github.com/gin-gonic/gin" "github.com/justinas/nosurf" securityHelpers "synlotto-website/internal/helpers/security" templateHelpers "synlotto-website/internal/helpers/template" "synlotto-website/internal/logging" "synlotto-website/internal/models" "synlotto-website/internal/platform/bootstrap" auditlogStorage "synlotto-website/internal/storage/auditlog" usersStorage "synlotto-website/internal/storage/users" ) func LoginGet(c *gin.Context) { app := c.MustGet("app").(*bootstrap.App) sm := app.SessionManager ctx := templateHelpers.TemplateContext(c.Writer, c.Request, models.TemplateData{}) if f := sm.PopString(c.Request.Context(), "flash"); f != "" { ctx["Flash"] = f } ctx["CSRFToken"] = nosurf.Token(c.Request) tmpl := templateHelpers.LoadTemplateFiles("layout.html", "web/templates/account/login.html") c.Status(http.StatusOK) if err := tmpl.ExecuteTemplate(c.Writer, "layout", ctx); err != nil { logging.Info("❌ Template render error: %v", err) c.String(http.StatusInternalServerError, "Error rendering login page") } } func LoginPost(c *gin.Context) { app := c.MustGet("app").(*bootstrap.App) sm := app.SessionManager db := app.DB r := c.Request w := c.Writer username := r.FormValue("username") password := r.FormValue("password") logging.Info("🔐 Login attempt - Username: %s", username) user := usersStorage.GetUserByUsername(db, username) if user == nil { logging.Info("❌ User not found: %s", username) auditlogStorage.LogLoginAttempt(db, r.RemoteAddr, r.UserAgent(), username, false) sm.Put(r.Context(), "flash", "Invalid username or password.") c.Redirect(http.StatusSeeOther, "/account/login") return } if !securityHelpers.CheckPasswordHash(user.PasswordHash, password) { logging.Info("❌ Password mismatch for user: %s", username) auditlogStorage.LogLoginAttempt(db, r.RemoteAddr, r.UserAgent(), username, false) sm.Put(r.Context(), "flash", "Invalid username or password.") c.Redirect(http.StatusSeeOther, "/account/login") return } logging.Info("✅ Login successful for user: %s", username) auditlogStorage.LogLoginAttempt(db, r.RemoteAddr, r.UserAgent(), username, true) _ = sm.Destroy(r.Context()) _ = sm.RenewToken(r.Context()) sm.Put(r.Context(), "user_id", user.Id) sm.Put(r.Context(), "last_activity", time.Now().UTC()) sm.Put(r.Context(), "flash", "Welcome back, "+user.Username+"!") http.Redirect(w, r, "/", http.StatusSeeOther) }