session

package
v1.5.1-0...-475df33 Latest Latest
Warning

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

Go to latest
Published: Aug 10, 2026 License: MIT Imports: 45 Imported by: 0

Documentation

Overview

Package session is Stage 11's socket-event contract wiring: the Go equivalent of server/client.ts plus the per-connection portion of server/server.ts (everything from `sockets.on("connect", ...)` down to the individual `socket.on(...)` handler bodies). It owns the one Manager per running server, ties every subsystem built in Stages 3-10 together (auth, ircbridge, model, incommands, irchandlers, store, uploads, shortlinks, themes, webpush, sts, changelog, partyline, emailverifier, clientcert, publicmode), and exposes a wsproto.Dispatch entry point that a real HTTP server (Stage 13's internal/httpapi, or a test harness) can mount at the WebSocket route.

Deliberately out of scope here, left for Stage 13: CSP/static asset serving, the OIDC authorization-redirect HTTP routes (BuildAuthorizationURL/ CompleteAuthentication - only the WS-side "auth:oidc" grant consumption lives here), the identd TCP listener's own lifecycle, and graceful shutdown sequencing. Manager still constructs the identd server and STS/ webpush/changelog services so this package's own tests can exercise against them, but a production binary's main() (Stage 12/13) decides when to actually Start() the ones that run their own background loop.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Manager

type Manager struct {
	Cfg       *config.Loaded
	Clients   *auth.ClientManager
	StartedAt time.Time

	// GlobalHub holds every currently-connected WebSocket, authenticated or
	// not - the Go equivalent of Node's `manager.sockets` (unfiltered). Used
	// only for true all-connections broadcasts (e.g. "setup:complete"); any
	// per-account emission goes through that Client's own Hub instead (see
	// auth.Client.Hub's doc comment).
	GlobalHub *wsproto.Hub

	WebAuthn      *auth.WebAuthnService
	OIDC          *auth.OIDCService
	STS           *sts.Store
	ClientCert    *clientcert.Store
	WebPush       *webpush.Pusher
	Changelog     *changelog.Checker
	EmailVerifier *emailverifier.Store
	Themes        *themes.Manager

	// Ident mirrors server.ts's always-constructed `new Identification(...)`
	// - built unconditionally (matching Node) so dialNetwork can always call
	// AddSocket/RemoveSocket around a live IRC connection regardless of
	// whether the RFC1413 listener itself is enabled (Config.values.identd.
	// enable) or oidentd file generation is configured: both AddSocket and
	// Refresh are safe, cheap no-ops when neither is active. Missing this
	// wiring entirely (as this backend did until now) meant the listener,
	// when enabled, answered every real query with NO-USER - identd.Server
	// was fully implemented and unit-tested, just never fed a live socket.
	Ident *identd.Server

	// PrefetchStore mirrors storage.ts's module-level Storage singleton,
	// used by link.go to cache a fetched link-preview thumbnail locally
	// instead of linking directly to it. Only constructed when
	// Config.values.prefetchStorage is on - nil otherwise, which
	// irchandlers.Deps.PrefetchStore (via irchandlersDeps) treats as "link
	// directly", matching Node's own `!Config.values.prefetchStorage`
	// branch.
	PrefetchStore *prefetchstore.Store

	ShortLinks       *shortlinks.Store
	ShortLinkCleaner *shortlinks.Cleaner

	UploadTokens *uploads.TokenStore
	UploadIndex  *uploads.Index
	UploadRouter *uploads.Router
	UploadClean  *uploads.Cleaner

	// ServerHash mirrors server.ts's serverHash: a random value sent in
	// "auth:start" so a client whose in-memory copy differs (the server
	// restarted) knows to hard-reload rather than trust a stale WASM/JS
	// bundle against a new backend.
	ServerHash int64
	// contains filtered or unexported fields
}

Manager is the one-per-running-server object tying every subsystem together - the Go analogue of the combination of server.ts's module-level state and ClientManager. It owns the WS route's Dispatch function (see dispatch.go).

func NewManager

func NewManager(cfg *config.Loaded) (*Manager, error)

NewManager mirrors server.ts's startup sequence: construct ClientManager and every subsystem, load themes/users, but start no background loop (identd, the changelog poller, storage cleaners) - that's an explicit Start() call so tests can construct a Manager without side effects.

func (*Manager) ConnectToNetwork

func (m *Manager) ConnectToNetwork(client *auth.Client, args map[string]any) (*model.Network, error)

ConnectToNetwork mirrors Client.connectToNetwork: builds the network from args, adds it (assigning the lobby its own channel id up front, matching Node's ordering so ids come out the same), broadcasts "network", runs Validate, and - unless the network was created already-disconnected - dials it. Returns the new network so callers (the "network:new" WS handler) can react further; isStartup, when true, skips dialing (used when restoring persisted networks at load time - see connectClient).

func (*Manager) DisconnectNetwork

func (m *Manager) DisconnectNetwork(client *auth.Client, network *model.Network)

DisconnectNetwork mirrors the disconnect.ts input command's underlying effect (network.userDisconnected = true; network.quit()) as a reusable helper, since sign-out/account-removal call the same shape without going through the /disconnect command's chan/args plumbing.

func (*Manager) Dispatch

func (m *Manager) Dispatch(conn *wsproto.Conn, env wsproto.Envelope)

Dispatch mirrors server.ts's per-event `socket.on(...)` bodies' unmarshal-and-validate-then-call-through shape, routed via registry. Unknown events and malformed payloads are silently dropped, exactly like every real handler's own `if (!_.isPlainObject(data)) return;` guard - there is no protocol-level error reply for either case on the Node side.

func (*Manager) Handler

func (m *Manager) Handler(insecureSkipOriginCheck bool) http.HandlerFunc

Handler builds the http.HandlerFunc for the WebSocket route: every connection gets Manager's GlobalHub registration, per-request metadata capture (acceptHook), Dispatch as its envelope router, and disconnect cleanup (disconnectHook). insecureSkipOriginCheck must only ever be true in tests (see wsproto.Handler's own doc comment).

func (*Manager) QuitClient

func (m *Manager) QuitClient(client *auth.Client)

QuitClient mirrors Client.quit: disconnect every network this account owns and close its message storage. signOut additionally mirrors the "sign-out" broadcast to every attached session, done by the caller (dispatch.go's sign-out handler) since it needs the live *wsproto.Conn set, which this package's lifecycle helpers don't track directly.

func (*Manager) QuitClientForDeletion

func (m *Manager) QuitClientForDeletion(client *auth.Client)

QuitClientForDeletion disconnects every network an account owns with the deletion-specific IRC quit message, then closes its message storage.

func (*Manager) Start

func (m *Manager) Start(ctx context.Context)

Start begins every background loop Manager's subsystems own: the changelog poller (broadcasts "changelog:newversion" to GlobalHub), the upload/shortlink expiry cleaners, and the users/ directory watcher. Mirrors the tail end of server.ts's bootstrap (changelog.checkForUpdates, storageCleaner instances, ClientManager's autoloadUsers, etc.).

func (*Manager) ValidateKlipyToken

func (m *Manager) ValidateKlipyToken(token string) bool

ValidateKlipyToken mirrors server.ts's klipyTokens.has(token) lookup against its module-level map: reconstructed here by scanning GlobalHub's live connections instead, since each connection's currently-issued token lives in its own connState (see handleKlipyAuth above) rather than a package-level map. Called from internal/httpapi's KLIPY proxy routes, the HTTP-side half of the "klipy:auth" WS handshake above.

Jump to

Keyboard shortcuts

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