Help us shape the future of Go! Take the 2026 Go Developer Survey

session

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 10, 2026 License: AGPL-3.0 Imports: 9 Imported by: 0

Documentation

Overview

Package session owns the cookie-based session pipeline. S02 ships the AEAD-encrypted cookie store; the Store interface lets later sprints add a server-side store for revocation without touching handlers.

Index

Constants

View Source
const CookieName = "_shithub_session"

CookieName is the canonical session cookie name. Prefixed with an underscore so it doesn't collide with any future user-controllable name.

View Source
const DefaultMaxAge = 30 * 24 * time.Hour

DefaultMaxAge is the default cookie lifetime.

Variables

View Source
var (
	ErrInvalidKey = errors.New("session: invalid key size")
)

Sentinel errors callers may check for.

Functions

func GenerateKey

func GenerateKey() ([]byte, error)

GenerateKey returns a new random 32-byte key suitable for NewCookieStore. Used by the operator's first-run setup; production keys come from config.

Types

type CookieStore

type CookieStore struct {
	// contains filtered or unexported fields
}

CookieStore is the AEAD-encrypted-cookie implementation.

func NewCookieStore

func NewCookieStore(cfg CookieStoreConfig) (*CookieStore, error)

NewCookieStore constructs a store. Returns an error if the key is wrong size — this is a configuration error and must surface at startup.

func (*CookieStore) Clear

func (c *CookieStore) Clear(w http.ResponseWriter)

Clear deletes the session cookie.

func (*CookieStore) Load

func (c *CookieStore) Load(r *http.Request) (*Session, error)

Load returns the session bound to the cookie, or a fresh empty session when none is present or the cookie is invalid (expired / wrong key / tampered). Errors are surfaced for malformed input but a missing or invalid cookie yields an empty session, not an error — the caller can proceed with anonymous handling.

func (*CookieStore) Save

Save serializes, encrypts, and sets the session cookie.

type CookieStoreConfig

type CookieStoreConfig struct {
	Key      []byte
	MaxAge   time.Duration
	Secure   bool
	Domain   string
	Path     string
	SameSite http.SameSite
}

CookieStoreConfig holds the ergonomic options. Key MUST be 32 bytes.

type Session

type Session struct {
	UserID       int64 `json:"uid,omitempty"`
	Pre2FAUserID int64 `json:"p2,omitempty"` // set after password OK, before TOTP step
	Recent2FAAt  int64 `json:"r2,omitempty"` // unix-seconds of last successful 2FA challenge
	// Epoch is the users.session_epoch value at issue time. The session
	// loader compares it against the current DB value on every request;
	// "log out everywhere" bumps the column, invalidating every cookie
	// that still carries the old epoch. Zero is the unbumped baseline
	// and matches the migration's column default.
	Epoch     int32             `json:"e,omitempty"`
	CSRFToken string            `json:"csrf,omitempty"`
	Theme     string            `json:"theme,omitempty"`
	Flashes   []string          `json:"flashes,omitempty"`
	Extras    map[string]string `json:"extras,omitempty"`
	IssuedAt  int64             `json:"iat,omitempty"`
	// ImpersonatedUserID — when non-zero, the admin (UserID above) is
	// currently viewing as this user. ImpersonateWriteOK gates writes
	// (defaults false; admin opts in via the typed-name confirm step
	// in /admin/impersonate). ImpersonationStartedAt drives the
	// inactivity timeout (S34: 1 hour idle).
	ImpersonatedUserID     int64 `json:"imp,omitempty"`
	ImpersonateWriteOK     bool  `json:"impw,omitempty"`
	ImpersonationStartedAt int64 `json:"impt,omitempty"`
}

Session is the data carried in a cookie. The shape is intentionally small; anything that doesn't fit a few hundred bytes belongs server-side.

func (*Session) AddFlash

func (s *Session) AddFlash(msg string)

AddFlash appends a flash message; it'll be rendered + cleared on the next page load.

func (*Session) IsAnonymous

func (s *Session) IsAnonymous() bool

IsAnonymous returns true when no user is bound to the session.

func (*Session) PopFlashes

func (s *Session) PopFlashes() []string

PopFlashes returns and clears any pending flash messages.

type Store

type Store interface {
	Load(r *http.Request) (*Session, error)
	Save(w http.ResponseWriter, r *http.Request, s *Session) error
	Clear(w http.ResponseWriter)
}

Store is the abstraction every handler uses. The cookie implementation stores everything client-side; future implementations may persist server-side rows for revocation.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL