subscription

package
v0.1.11 Latest Latest
Warning

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

Go to latest
Published: Oct 8, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package subscription manages per-user subscription links: an unguessable capability token that grants read-only access to one user's subscription page (traffic, expiry, devices, per-device QR/config). The token is a 256-bit crypto/rand value, stored AES-GCM encrypted for panel re-display and SHA-256 hashed for lookup — plaintext tokens are never persisted in the clear and never logged (docs/operations/security.md).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func HashToken

func HashToken(token string) string

HashToken is the at-rest lookup form of a token (SHA-256 hex).

func NewToken

func NewToken() (string, error)

NewToken mints a 256-bit URL-safe token (43 chars, RawURLEncoding).

Types

type Link struct {
	UserID    string
	Token     string
	CreatedAt time.Time
	RotatedAt *time.Time
	RevokedAt *time.Time
}

Link is a stored subscription link. Token is the decrypted capability value (empty when decryption fails — the hash lookup path still works).

func (*Link) Revoked

func (l *Link) Revoked() bool

Revoked reports whether the link is currently disabled.

type Service

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

Service holds the storage rules. All writes serialize on SQLite's write lock; uniqueness of token_hash is enforced by the schema.

func NewService

func NewService(db *database.DB, ring *secrets.KeyRing) *Service

func (*Service) CreateTx added in v0.1.3

func (s *Service) CreateTx(ctx context.Context, tx *sql.Tx, userID string) (*Link, error)

CreateTx issues the initial capability inside a caller-owned transaction. Provisioning can therefore commit user, device and recovery link together. The plaintext capability is returned in memory only, never journaled.

func (*Service) Ensure

func (s *Service) Ensure(ctx context.Context, userID string) (*Link, error)

Ensure returns the user's link, creating one if none exists yet (idempotent — safe to call from the creation flow and the detail page alike).

func (*Service) ForUser

func (s *Service) ForUser(ctx context.Context, userID string) (*Link, error)

ForUser returns the user's link, or (nil, nil) when none exists yet.

func (*Service) ForUsers

func (s *Service) ForUsers(ctx context.Context, userIDs []string) (map[string]*Link, error)

ForUsers batch-loads links for a page of users (list view).

func (*Service) Regenerate

func (s *Service) Regenerate(ctx context.Context, userID string) (*Link, error)

Regenerate replaces the token (the old one stops working immediately) and clears the revoked flag — a fresh link is a working link.

func (*Service) RegenerateTx

func (s *Service) RegenerateTx(ctx context.Context, tx *sql.Tx, userID string) (*Link, error)

RegenerateTx replaces a link capability inside a caller-owned transaction. Coordinated security workflows use this to rotate the link and every device credential atomically. The returned token exists only in process memory.

func (*Service) Resolve

func (s *Service) Resolve(ctx context.Context, token string) (string, error)

Resolve maps a presented token onto its user. Any failure — unknown hash, revoked link, malformed input — is the same error (no enumeration oracle). The caller is responsible for loading the user and checking liveness.

func (*Service) RotateAccess added in v0.1.3

func (s *Service) RotateAccess(ctx context.Context, devices *device.Service, userID string) (*Link, int, error)

RotateAccess replaces the customer link and every existing device key in one transaction. The old capability and configurations are retired even if runtime reconciliation later needs a retry; callers reconcile before reporting an access-rotation success to their client.

func (*Service) SetRevoked

func (s *Service) SetRevoked(ctx context.Context, userID string, revoked bool) (*Link, error)

SetRevoked toggles the revoked flag. Revoked links answer "not found" on the public surface but keep their token — restoring re-enables the same URL.

Jump to

Keyboard shortcuts

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