68 lines
2.0 KiB
Go
68 lines
2.0 KiB
Go
// Package sessions configures the SCS session manager and provides
|
|
// helpers for resolving player identity from the session.
|
|
package sessions
|
|
|
|
import (
|
|
"database/sql"
|
|
"log/slog"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/ryanhamamura/games/player"
|
|
|
|
"github.com/alexedwards/scs/sqlite3store"
|
|
"github.com/alexedwards/scs/v2"
|
|
)
|
|
|
|
// Session key names.
|
|
const (
|
|
KeyPlayerID = "player_id"
|
|
KeyUserID = "user_id"
|
|
KeyNickname = "nickname"
|
|
)
|
|
|
|
// SetupSessionManager creates a configured session manager backed by SQLite.
|
|
// Returns the manager and a cleanup function the caller should defer.
|
|
func SetupSessionManager(db *sql.DB) (*scs.SessionManager, func()) {
|
|
store := sqlite3store.New(db)
|
|
cleanup := func() { store.StopCleanup() }
|
|
|
|
sessionManager := scs.New()
|
|
sessionManager.Store = store
|
|
sessionManager.Lifetime = 30 * 24 * time.Hour
|
|
sessionManager.Cookie.Name = "games_session"
|
|
sessionManager.Cookie.Path = "/"
|
|
sessionManager.Cookie.HttpOnly = true
|
|
sessionManager.Cookie.Secure = false
|
|
sessionManager.Cookie.SameSite = http.SameSiteLaxMode
|
|
|
|
slog.Info("session manager configured")
|
|
|
|
return sessionManager, cleanup
|
|
}
|
|
|
|
// GetPlayerID returns the current player's identity from the session.
|
|
// Authenticated users get their user UUID; guests get a random ID that
|
|
// is generated and persisted on first access.
|
|
func GetPlayerID(sm *scs.SessionManager, r *http.Request) player.ID {
|
|
pid := sm.GetString(r.Context(), KeyPlayerID)
|
|
if pid == "" {
|
|
pid = player.GenerateID(8)
|
|
sm.Put(r.Context(), KeyPlayerID, pid)
|
|
}
|
|
if userID := sm.GetString(r.Context(), KeyUserID); userID != "" {
|
|
return player.ID(userID)
|
|
}
|
|
return player.ID(pid)
|
|
}
|
|
|
|
// GetUserID returns the authenticated user's UUID, or empty string for guests.
|
|
func GetUserID(sm *scs.SessionManager, r *http.Request) string {
|
|
return sm.GetString(r.Context(), KeyUserID)
|
|
}
|
|
|
|
// GetNickname returns the player's display name from the session.
|
|
func GetNickname(sm *scs.SessionManager, r *http.Request) string {
|
|
return sm.GetString(r.Context(), KeyNickname)
|
|
}
|