// session.go package session import ( "crypto/rand" "encoding/hex" "time" ) const ( DefaultExpiration = 24 * time.Hour IDLength = 32 ) // Session represents a user session type Session struct { ID string `json:"id"` UserID int `json:"user_id"` // 0 for guest sessions ExpiresAt int64 `json:"expires_at"` Data map[string]any `json:"data"` } // New creates a new session func New(userID int) *Session { return &Session{ ID: generateID(), UserID: userID, ExpiresAt: time.Now().Add(DefaultExpiration).Unix(), Data: make(map[string]any), } } // IsExpired checks if the session has expired func (s *Session) IsExpired() bool { return time.Now().Unix() > s.ExpiresAt } // Touch extends the session expiration func (s *Session) Touch() { s.ExpiresAt = time.Now().Add(DefaultExpiration).Unix() } // Set stores a value in the session func (s *Session) Set(key string, value any) { s.Data[key] = value } // Get retrieves a value from the session func (s *Session) Get(key string) (any, bool) { value, exists := s.Data[key] return value, exists } // Delete removes a value from the session func (s *Session) Delete(key string) { delete(s.Data, key) } // SetFlash stores a flash message (consumed on next Get) func (s *Session) SetFlash(key string, value any) { s.Set("flash_"+key, value) } // GetFlash retrieves and removes a flash message func (s *Session) GetFlash(key string) (any, bool) { flashKey := "flash_" + key value, exists := s.Get(flashKey) if exists { s.Delete(flashKey) } return value, exists } // RegenerateID creates a new session ID and updates storage func (s *Session) RegenerateID() { oldID := s.ID s.ID = generateID() if Manager != nil { Manager.mu.Lock() delete(Manager.sessions, oldID) Manager.sessions[s.ID] = s Manager.mu.Unlock() } } // generateID creates a random session ID func generateID() string { bytes := make([]byte, IDLength) rand.Read(bytes) return hex.EncodeToString(bytes) } // Package-level convenience functions func Create(userID int) *Session { return Manager.Create(userID) } func Get(sessionID string) (*Session, bool) { return Manager.Get(sessionID) } func Store(sess *Session) { Manager.Store(sess) } func Delete(sessionID string) { Manager.Delete(sessionID) } func Cleanup() { Manager.Cleanup() } func Stats() (total, active int) { return Manager.Stats() } func Close() error { return Manager.Close() } // RegenerateID regenerates the session ID for security (package-level convenience) func RegenerateID(sess *Session) { sess.RegenerateID() }