package auth import ( "net/http" "time" "github.com/gorilla/sessions" ) // SessionManager manages user sessions type SessionManager struct { store *sessions.CookieStore options *sessions.Options } // Session keys const ( SessionKeyUserEmail = "user_email" SessionKeyLoggedIn = "logged_in" ) // NewSessionManager creates a new session manager with the given secret key func NewSessionManager(secretKey string) *SessionManager { store := sessions.NewCookieStore([]byte(secretKey)) // Secure session options options := &sessions.Options{ Path: "/", MaxAge: 86400 * 7, // 7 days HttpOnly: true, Secure: true, // Requires HTTPS SameSite: http.SameSiteStrictMode, } return &SessionManager{ store: store, options: options, } } // CreateSession creates a new session for the user func (sm *SessionManager) CreateSession(w http.ResponseWriter, r *http.Request, email string) error { session, err := sm.store.Get(r, "inboxer_session") if err != nil { return err } session.Values[SessionKeyUserEmail] = email session.Values[SessionKeyLoggedIn] = true session.Options = sm.options return session.Save(r, w) } // GetUserEmail returns the email from the session if the user is logged in func (sm *SessionManager) GetUserEmail(r *http.Request) (string, bool) { session, err := sm.store.Get(r, "inboxer_session") if err != nil { return "", false } // Check if logged in loggedIn, ok := session.Values[SessionKeyLoggedIn].(bool) if !ok || !loggedIn { return "", false } email, ok := session.Values[SessionKeyUserEmail].(string) if !ok { return "", false } return email, true } // DestroySession removes the user session (logout) func (sm *SessionManager) DestroySession(w http.ResponseWriter, r *http.Request) error { session, err := sm.store.Get(r, "inboxer_session") if err != nil { return err } // Clear session values session.Values = make(map[interface{}]interface{}) session.Options = &sessions.Options{ Path: "/", MaxAge: -1, // Immediately expire HttpOnly: true, } return session.Save(r, w) } // IsLoggedIn checks if the user is logged in func (sm *SessionManager) IsLoggedIn(r *http.Request) bool { session, err := sm.store.Get(r, "inboxer_session") if err != nil { return false } loggedIn, ok := session.Values[SessionKeyLoggedIn].(bool) return ok && loggedIn } // UpdateSessionOptions updates session options (e.g., for development without HTTPS) func (sm *SessionManager) UpdateSessionOptions(secure bool, maxAge int) { sm.options.Secure = secure sm.options.MaxAge = maxAge }