package auth import ( "fmt" "net/http" "github.com/gorilla/sessions" ) const sessionName = "startpage_session" const userIDKey = "user_id" // CookieSessionStore implements SessionStore using gorilla/sessions type CookieSessionStore struct { store *sessions.CookieStore } // NewCookieSessionStore creates a new cookie-based session store func NewCookieSessionStore(secretKey string, maxAge int) *CookieSessionStore { store := sessions.NewCookieStore([]byte(secretKey)) store.Options = &sessions.Options{ Path: "/", MaxAge: maxAge, HttpOnly: true, Secure: false, // Set to true in production with HTTPS SameSite: http.SameSiteLaxMode, } return &CookieSessionStore{ store: store, } } // CreateSession creates a new session for the user func (s *CookieSessionStore) CreateSession(w http.ResponseWriter, r *http.Request, userID string) error { session, err := s.store.Get(r, sessionName) if err != nil { // If there's an error getting the session, create a new one session, _ = s.store.New(r, sessionName) } session.Values[userIDKey] = userID if err := session.Save(r, w); err != nil { return fmt.Errorf("failed to save session: %w", err) } return nil } // GetUserID retrieves the user ID from the session func (s *CookieSessionStore) GetUserID(r *http.Request) (string, error) { session, err := s.store.Get(r, sessionName) if err != nil { return "", fmt.Errorf("failed to get session: %w", err) } userID, ok := session.Values[userIDKey].(string) if !ok || userID == "" { return "", fmt.Errorf("user ID not found in session") } return userID, nil } // ValidateSession checks if a valid session exists for the request func (s *CookieSessionStore) ValidateSession(r *http.Request) bool { _, err := s.GetUserID(r) return err == nil } // DestroySession destroys the user's session func (s *CookieSessionStore) DestroySession(w http.ResponseWriter, r *http.Request) error { session, err := s.store.Get(r, sessionName) if err != nil { // Session doesn't exist or is invalid, nothing to destroy return nil } // Set MaxAge to -1 to delete the cookie session.Options.MaxAge = -1 if err := session.Save(r, w); err != nil { return fmt.Errorf("failed to destroy session: %w", err) } return nil }