inboxer/src/internal/auth/session.go

109 lines
No EOL
2.5 KiB
Go

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
}