token

package
v0.3.1 Latest Latest
Warning

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

Go to latest
Published: Jul 2, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package token provides single-use, time-limited tokens for the Gas ecosystem. Tokens are used for magic links, email verification, password reset, and invite links. They implement gas.Service but NOT gas.Authenticator — tokens are verified once and consumed.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrTokenInvalid indicates that the token does not exist or has already
	// been consumed.
	ErrTokenInvalid = errors.New("invalid token")
	// ErrTokenExpired indicates that the token has expired.
	ErrTokenExpired = errors.New("token expired")
)

Sentinel errors for token operations.

Functions

func New

New captures options and returns a DI-injectable constructor.

Types

type Config

type Config struct {
	env.WithGasEnv

	Token Settings
}

Config holds token service settings.

func DefaultConfig

func DefaultConfig() *Config

DefaultConfig returns a Config with sensible defaults.

func (*Config) Validate

func (c *Config) Validate() error

Validate checks the Config for correctness.

type Option

type Option func(*Service)

Option configures a Service.

func WithConfig

func WithConfig(cfg *Config) Option

WithConfig sets a custom configuration, skipping auto-bind from ConfigProvider.

type Provider

type Provider interface {
	// Issue generates a random token, stores its hash with purpose, subject, and
	// expiry, and returns the raw token. If ttl is 0, DefaultTTL is used.
	Issue(ctx context.Context, subject, purpose string, ttl time.Duration) (string, error)
	// Verify hashes the raw token, looks it up by hash, unconditionally deletes it,
	// then checks purpose match and expiry. Returns the subject on success.
	//
	// The token is deleted before validation so that a single presentation always
	// consumes it — regardless of whether the caller supplied the wrong purpose or
	// the token has expired. This keeps a simple invariant: once the raw secret has
	// been presented, it cannot be reused.
	Verify(ctx context.Context, rawToken, purpose string) (subject string, err error)
	// Revoke deletes a specific token by its raw value.
	Revoke(ctx context.Context, rawToken string) error
	// RevokeAllByPurpose deletes all tokens for a subject with the given purpose.
	RevokeAllByPurpose(ctx context.Context, subject, purpose string) error
}

Provider defines the contract for managing and validating single-use tokens.

type Service

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

Service manages single-use tokens. It implements gas.Service.

func (*Service) Close

func (s *Service) Close() error

Close stops the background cleanup goroutine.

func (*Service) Init

func (s *Service) Init() error

Init validates configuration, initializes the store, and starts the background cleanup goroutine.

func (*Service) Issue

func (s *Service) Issue(ctx context.Context, subject, purpose string, ttl time.Duration) (string, error)

Issue generates a random token, stores its hash with purpose, subject, and expiry, and returns the raw token. If ttl is 0, DefaultTTL is used.

func (*Service) Name

func (s *Service) Name() string

Name returns the service identifier.

func (*Service) Revoke

func (s *Service) Revoke(ctx context.Context, rawToken string) error

Revoke deletes a specific token by its raw value.

func (*Service) RevokeAllByPurpose

func (s *Service) RevokeAllByPurpose(ctx context.Context, subject, purpose string) error

RevokeAllByPurpose deletes all tokens for a subject with the given purpose.

func (*Service) Verify

func (s *Service) Verify(ctx context.Context, rawToken, purpose string) (subject string, err error)

Verify hashes the raw token, atomically fetches-and-deletes it, then checks purpose match and expiry. Returns the subject on success.

The fetch-and-delete happens in a single atomic store operation so that concurrent Verify calls for the same raw token cannot both succeed: only one caller observes the record, the other sees ErrTokenInvalid.

Deletion is unconditional on validation outcome: once the raw secret has been presented, it is burned regardless of whether purpose matches or the token has expired. This keeps a simple invariant — once the raw secret has been presented, it cannot be reused — and prevents an attacker who has the hash but guesses the wrong purpose from retrying indefinitely.

Trade-off: a bug that sends the wrong purpose string will silently consume a valid token. This is the preferable failure mode — it surfaces the bug immediately rather than masking cross-flow confusion.

type Settings

type Settings struct {
	// DefaultTTL is the default token lifetime when Issue is called with ttl == 0.
	DefaultTTL time.Duration
	// TokenLength is the number of random bytes used for token generation.
	TokenLength int
	// CleanupInterval is the interval for the expired token cleanup goroutine.
	CleanupInterval time.Duration
	// CleanupTimeout is the timeout for the expired token cleanup goroutine.
	CleanupTimeout time.Duration
}

Settings represents the token configuration values.

Directories

Path Synopsis
db

Jump to

Keyboard shortcuts

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