totp

package
v2.1.1 Latest Latest
Warning

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

Go to latest
Published: Sep 25, 2026 License: MIT Imports: 26 Imported by: 0

Documentation

Overview

Package totp adds TOTP (RFC 6238) two-factor authentication to Aegis.

The plugin extends the user table with a pending/enabled credential and keeps per-session verification in its own table, so a session that has not cleared the second factor can be restricted with RequireVerification without touching the core session schema.

Flow:

  1. POST /totp/setup → returns a secret + otpauth URL (not yet enabled)
  2. POST /totp/enable → confirms a code, enables TOTP, returns recovery codes
  3. POST /totp/verify → step-up: marks the current session verified
  4. POST /totp/disable → removes the credential and session verifications
  5. GET /totp/status → enabled + current-session verification state

Recovery codes are stored as one-time core verification tokens, so they are hashed at rest and consumed on use without a plugin-owned table.

Index

Constants

View Source
const (
	SchemaSetupResponse     = "TOTPSetupResponse"
	SchemaEnableRequest     = "TOTPEnableRequest"
	SchemaEnableResponse    = "TOTPEnableResponse"
	SchemaVerifyRequest     = "TOTPVerifyRequest"
	SchemaStatusResponse    = "TOTPStatusResponse"
	SchemaRegenerateRequest = "TOTPRegenerateRequest"
)

Schema names for OpenAPI specification generation.

Variables

View Source
var (
	ErrAlreadyEnabled = errors.New("two-factor is already enabled")
	ErrNotSetup       = errors.New("two-factor setup has not been started")
	ErrNotEnabled     = errors.New("two-factor is not enabled")
	ErrInvalidCode    = errors.New("invalid code")
)

Sentinel errors returned by the programmatic API.

Functions

func GetMigrations

func GetMigrations(dialect plugins.Dialect) ([]plugins.Migration, error)

GetMigrations returns all database migrations for the TOTP plugin.

This function loads migrations from embedded SQL files and returns them in version order.

Version Numbering:

  • Version 001+: Migrations from migrations/<dialect>/<version>_<description>.<up|down>.sql

Migration File Format:

  • Up migration: 001_initial.up.sql
  • Down migration: 001_initial.down.sql

Parameters:

  • dialect: Database dialect (postgres, mysql, sqlite)

Returns:

  • []plugins.Migration: Sorted list of migrations (oldest first)
  • error: If migration files cannot be read or parsed

Types

type Config

type Config struct {
	// Issuer labels credentials in authenticator apps (default: "Aegis").
	Issuer string
	// Digits is the code length (default: 6).
	Digits int
	// Period is the time step (default: 30s).
	Period time.Duration
	// Skew is how many steps before/after now are accepted (default: 1).
	Skew int
	// SecretBytes is the entropy of generated secrets (default: 20).
	SecretBytes int
	// RecoveryCodes is how many single-use recovery codes are generated on
	// enable (default: 10). Set it to a negative value to disable recovery
	// codes; 0 means "use the default", so an unset field cannot silently
	// drop recovery codes.
	RecoveryCodes int
	// SessionTTL is how long a session stays verified after a successful code
	// (default: 12h).
	SessionTTL time.Duration
}

Config holds TOTP plugin configuration.

type Handlers

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

Handlers encapsulates TOTP plugin HTTP handlers.

func NewHandlers

func NewHandlers(plugin *Plugin) *Handlers

NewHandlers creates TOTP plugin handlers.

func (*Handlers) DisableHandler

func (h *Handlers) DisableHandler(w http.ResponseWriter, r *http.Request)

DisableHandler removes the credential after confirming a TOTP code.

func (*Handlers) EnableHandler

func (h *Handlers) EnableHandler(w http.ResponseWriter, r *http.Request)

EnableHandler confirms a code and activates TOTP.

func (*Handlers) RegenerateRecoveryCodesHandler

func (h *Handlers) RegenerateRecoveryCodesHandler(w http.ResponseWriter, r *http.Request)

RegenerateRecoveryCodesHandler replaces the recovery codes after confirming a TOTP code.

func (*Handlers) SetupHandler

func (h *Handlers) SetupHandler(w http.ResponseWriter, r *http.Request)

SetupHandler starts enrollment.

func (*Handlers) StatusHandler

func (h *Handlers) StatusHandler(w http.ResponseWriter, r *http.Request)

StatusHandler reports enrollment and current-session state.

func (*Handlers) VerifyHandler

func (h *Handlers) VerifyHandler(w http.ResponseWriter, r *http.Request)

VerifyHandler steps up the current session with a TOTP or recovery code.

type Plugin

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

Plugin provides TOTP two-factor authentication.

func New

func New(cfg *Config, store totptypes.Store, dialect ...plugins.Dialect) *Plugin

New creates a new TOTP plugin instance.

Parameters:

  • cfg: Plugin configuration (can be nil for defaults)
  • store: Custom Store implementation (can be nil, will use DefaultTOTPStore)
  • dialect: Database dialect (optional, defaults to PostgreSQL)

func (*Plugin) Dependencies

func (p *Plugin) Dependencies() []plugins.Dependency

Dependencies returns external package dependencies.

func (*Plugin) Description

func (p *Plugin) Description() string

Description returns a human-readable description for logging.

func (*Plugin) Disable

func (p *Plugin) Disable(ctx context.Context, userID, code string) error

Disable clears the credential, every session verification and any outstanding recovery codes. A valid TOTP code is required so a hijacked session cannot silently remove the second factor. Disabling an account that has no credential is a no-op, so callers stay idempotent.

func (*Plugin) Enable

func (p *Plugin) Enable(ctx context.Context, userID, code string) ([]string, error)

Enable confirms a code from the pending secret and activates TOTP. It returns the freshly generated single-use recovery codes.

func (*Plugin) EnrichUser

func (p *Plugin) EnrichUser(ctx context.Context, user *core.EnrichedUser) error

EnrichUser adds the TOTP-enabled flag to authenticated user responses.

func (*Plugin) GetMigrations

func (p *Plugin) GetMigrations() []plugins.Migration

GetMigrations returns the plugin migrations.

func (*Plugin) Init

func (p *Plugin) Init(ctx context.Context, a plugins.Aegis) error

Init initializes the plugin.

func (*Plugin) IsEnabled

func (p *Plugin) IsEnabled(ctx context.Context, userID string) (bool, error)

IsEnabled reports whether TOTP is active for the user.

func (*Plugin) IsSessionVerified

func (p *Plugin) IsSessionVerified(ctx context.Context, sessionID, userID string) bool

IsSessionVerified reports whether sessionID cleared the second factor within the configured session TTL.

func (*Plugin) MarkSessionVerified

func (p *Plugin) MarkSessionVerified(ctx context.Context, sessionID, userID string) error

MarkSessionVerified records that sessionID cleared the second factor.

func (*Plugin) MountRoutes

func (p *Plugin) MountRoutes(r router.Router, prefix string)

MountRoutes registers HTTP routes for the TOTP plugin.

func (*Plugin) Name

func (p *Plugin) Name() string

Name returns the plugin identifier.

func (*Plugin) ProvidesAuthMethods

func (p *Plugin) ProvidesAuthMethods() []string

ProvidesAuthMethods returns authentication methods provided.

func (*Plugin) RegenerateRecoveryCodes

func (p *Plugin) RegenerateRecoveryCodes(ctx context.Context, userID, code string) ([]string, error)

RegenerateRecoveryCodes replaces the user's recovery codes. A valid TOTP code is required so a hijacked session cannot mint new recovery codes.

func (*Plugin) RequireVerification

func (p *Plugin) RequireVerification(next http.Handler) http.Handler

RequireVerification blocks requests for users with TOTP enabled until the current session has cleared the second factor. Unauthenticated requests pass through, so this composes with RequireAuthMiddleware (mount it after auth).

func (*Plugin) RequiresTables

func (p *Plugin) RequiresTables() []string

RequiresTables returns the core tables this plugin reads from.

func (*Plugin) Setup

func (p *Plugin) Setup(ctx context.Context, userID string) (totptypes.SetupResponse, error)

Setup generates a new secret and stores it in the pending (disabled) state. Returns the secret and an otpauth:// URL for authenticator apps. Call Enable with a code from the authenticator to activate it.

Re-running Setup replaces a pending secret; it refuses while TOTP is enabled so a stolen session cannot silently re-enroll the account.

func (*Plugin) Verify

func (p *Plugin) Verify(ctx context.Context, userID, code string) (bool, error)

Verify reports whether code is a valid TOTP code for the user.

func (*Plugin) VerifyRecoveryCode

func (p *Plugin) VerifyRecoveryCode(ctx context.Context, userID, code string) (bool, error)

VerifyRecoveryCode consumes a single-use recovery code. Invalid, expired and already-used codes all report false.

func (*Plugin) Version

func (p *Plugin) Version() string

Version returns the plugin version for compatibility tracking.

Directories

Path Synopsis
Package defaultstore implements the SQL-backed default store for the totp plugin.
Package defaultstore implements the SQL-backed default store for the totp plugin.
internal
Package types defines the domain models and store contract for the TOTP plugin.
Package types defines the domain models and store contract for the TOTP plugin.

Jump to

Keyboard shortcuts

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