package middleware import ( "strings" "time" "github.com/gin-gonic/gin" sessionHelper "synlotto-website/internal/helpers/session" "synlotto-website/internal/platform/bootstrap" "synlotto-website/internal/platform/sessionkeys" ) // Remember checks if a remember-me cookie exists and restores the session if valid. func Remember(app *bootstrap.App) gin.HandlerFunc { return func(c *gin.Context) { sm := app.SessionManager ctx := c.Request.Context() // Already logged in? skip. if sm.Exists(ctx, sessionkeys.UserID) { c.Next() return } // Look for remember-me cookie cookie, err := c.Request.Cookie(app.Config.Session.RememberCookieName) if err != nil { c.Next() return } parts := strings.SplitN(cookie.Value, ":", 2) if len(parts) != 2 { c.Next() return } selector, verifier := parts[0], parts[1] if selector == "" || verifier == "" { c.Next() return } userID, hash, expiresAt, revokedAt, err := sessionHelper.FindToken(app.DB, selector) if err != nil || revokedAt != nil || time.Now().After(expiresAt) { c.Next() return } // Constant-time compare via hashing the verifier if sessionHelper.HashVerifier(verifier) != hash { _ = sessionHelper.RevokeToken(app.DB, selector) // tampered → revoke c.Next() return } // ✅ Valid token → create a new session for the user _ = sm.RenewToken(ctx) sm.Put(ctx, sessionkeys.UserID, userID) sm.Put(ctx, sessionkeys.LastActivity, time.Now().UTC()) // (Optional TODO): rotate token and set a fresh cookie. c.Next() } }