package server import ( "net/http" "time" "github.com/gin-gonic/gin" "weatherstation/core/internal/auth" "weatherstation/core/internal/data" ) func handleLogin(opts Options) gin.HandlerFunc { secret := []byte(opts.AuthSecret) return func(c *gin.Context) { username := c.PostForm("username") password := c.PostForm("password") if username == "" || password == "" { c.String(http.StatusBadRequest, "missing username or password") return } u, err := data.GetUser(username) if err != nil { c.String(http.StatusInternalServerError, "login error") return } if u == nil || !auth.CheckPassword(u.Password, password) { // simple failure c.String(http.StatusUnauthorized, "invalid credentials") return } token, exp := auth.MakeSessionToken(username, 24*time.Hour, secret) // set HttpOnly cookie // maxAge in seconds maxAge := int(time.Until(exp).Seconds()) c.SetCookie("core_session", token, maxAge, "/", "", false, true) c.Redirect(http.StatusFound, "/bigscreen") } } func handleLogout(opts Options) gin.HandlerFunc { return func(c *gin.Context) { // expire cookie immediately c.SetCookie("core_session", "", -1, "/", "", false, true) c.Redirect(http.StatusFound, "/admin/login") } } // parseToken wraps auth.ParseSessionToken for local use. func parseToken(token string, secret []byte) (string, bool) { return auth.ParseSessionToken(token, secret) }