109 lines
No EOL
2.5 KiB
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
|
|
} |