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

mfa

package
v1.9.0 Latest Latest
Warning

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

Go to latest
Published: Nov 2, 2026 License: MIT Imports: 37 Imported by: 0

README

mfa

Second-factor authentication with TOTP, SMS and recovery codes.

TOTP is the default and the one to prefer: the user scans a QR code into Google Authenticator, 1Password or whatever they already use, and you're not paying per message or trusting a mobile carrier. SMS is there because some users will not install an app. Recovery codes exist because people lose phones.

The plugin injects a challenge after sign-in when the user has MFA enabled, so the session is not fully issued until the second factor clears.

Use it when

  • You hold anything worth stealing and passwords alone are not enough
  • Compliance asks for MFA and you'd rather not buy a separate product for it
  • You want step-up on sensitive actions, driven by riskengine

Skip it when

  • passkey already covers your users. A passkey is one factor that's stronger than password plus TOTP, and stacking both is friction for no gain
  • You're relying on SMS as the only option. SIM swap is a real attack and TOTP costs nothing
  • Your users have no second device at all

Wiring

authsome.WithPlugin(mfa.New(mfa.Config{
    Issuer: "My App",
}))

Issuer is the label users see in their authenticator app, so make it the product name they recognise.

Config

Field Type Default What it does
Issuer string AuthSome Name shown in the authenticator app

Settings

Key Default
mfa.issuer AuthSome

Endpoints

Registered under /v1/mfa.

Method Path Purpose
POST /enroll Start TOTP enrolment, returns the secret and QR payload
POST /verify Verify a TOTP code
POST /challenge Issue an MFA challenge
DELETE /enrollment Disable MFA for the user
POST /sms/send Send an SMS code
POST /sms/verify Verify an SMS code
POST /recovery/verify Redeem a recovery code
POST /recovery/regenerate Issue a fresh set of recovery codes

Lifecycle hooks

None on the hook bus. It's a RouteProvider, a SettingsProvider and a MigrationProvider for its enrolment tables.

phone uses the same SMS infrastructure but as a primary method rather than a second factor. riskengine can require an MFA challenge when a sign-in scores in the middle band.

Documentation

Overview

contract.go: Wires the mfa plugin into the forge-dashboard contract surface via plugin.ContractContributor.

Package mfa provides multi-factor authentication for AuthSome.

The MFA plugin supports TOTP (Time-based One-Time Password) enrollment and verification. It implements AfterSignIn to inject MFA challenges when users have MFA enabled, and provides HTTP routes for enrollment and verification.

Usage:

eng, _ := authsome.NewEngine(
    authsome.WithStore(store),
    authsome.WithPlugin(mfa.New(mfa.Config{
        Issuer: "My App",
    })),
)

Index

Constants

View Source
const DefaultRecoveryCodeCount = 8

DefaultRecoveryCodeCount is the number of recovery codes generated per enrollment.

Variables

View Source
var ErrEnrollmentNotFound = errors.New("mfa: enrollment not found")

ErrEnrollmentNotFound is returned when an MFA enrollment is not found.

View Source
var PostgresMigrations = migrate.NewGroup("authsome-mfa", migrate.DependsOn("authsome"))

PostgresMigrations is the postgres migration group for the MFA plugin.

View Source
var (
	// SettingIssuer controls the issuer name shown in authenticator apps.
	SettingIssuer = settings.Define("mfa.issuer", "AuthSome",
		settings.WithDisplayName("Issuer Name"),
		settings.WithDescription("Name shown in authenticator apps (e.g. Google Authenticator)"),
		settings.WithCategory("Multi-Factor Auth"),
		settings.WithScopes(settings.ScopeGlobal, settings.ScopeApp),
		settings.WithPlaceholder("AuthSome"),
		settings.WithHelpText("The issuer label users see in their authenticator app"),
		settings.WithOrder(10),
	)
)
View Source
var SqliteMigrations = migrate.NewGroup("authsome-mfa", migrate.DependsOn("authsome"))

SqliteMigrations is the SQLite migration group for the MFA plugin.

Functions

func GenerateSMSCode added in v1.9.0

func GenerateSMSCode(length int) (string, error)

GenerateSMSCode generates a random numeric code of the given length.

func GenerateTOTPCode added in v1.9.0

func GenerateTOTPCode(secret string) (string, error)

GenerateTOTPCode generates a current TOTP code for a given secret. Primarily useful for testing.

func GenerateTOTPCodeAt added in v1.9.0

func GenerateTOTPCodeAt(secret string, at time.Time) (string, error)

GenerateTOTPCodeAt generates the TOTP code for a given secret at a specific time. Primarily useful for testing flows that need two codes from different time-steps — a code is single-use within its acceptance window, so a step-up check cannot reuse the code that completed an earlier step.

Only offsets within the ±1-step acceptance window (see totpSkew) will still validate; ±30s is the usable distance from now.

func GenerateTOTPKey added in v1.9.0

func GenerateTOTPKey(cfg TOTPConfig) (*otp.Key, error)

GenerateTOTPKey creates a new TOTP secret key.

func ValidateSMSCode added in v1.9.0

func ValidateSMSCode(code string, challenge *SMSChallenge) bool

ValidateSMSCode checks whether the provided code matches the challenge and is not expired.

func ValidateTOTP added in v1.9.0

func ValidateTOTP(code, secret string) bool

ValidateTOTP validates a TOTP code against a secret.

func ValidateTOTPStep added in v1.9.0

func ValidateTOTPStep(code, secret string) (valid bool, step int64)

ValidateTOTPStep validates a code and, on success, returns the time-step (unix seconds / period) the code corresponds to. The step uniquely identifies the code within its validity window, letting callers reject a replay of the same code. Acceptance matches ValidateTOTP (±1 step).

func VerifyRecoveryCode added in v1.9.0

func VerifyRecoveryCode(plaintext string, code *RecoveryCode) bool

VerifyRecoveryCode checks if the given plaintext code matches the hashed code.

Types

type ChallengeRequest

type ChallengeRequest struct {
	Ticket string `json:"mfa_ticket" description:"Ticket returned by /v1/signin when MFA was required"`
	Code   string `json:"code"       description:"TOTP code from the user's authenticator (6 digits) or recovery code"`
}

ChallengeRequest is the request body for MFA challenge during the sign-in MFA gate. The mfa_ticket is what /v1/signin (or any other session-issuing endpoint) returned in the 403 body when MFA was required; the code is the user's TOTP digits or recovery code.

type ChallengeResponse

type ChallengeResponse struct {
	User         any    `json:"user"          description:"User object"`
	SessionToken string `json:"session_token" description:"Session token"`
	RefreshToken string `json:"refresh_token" description:"Refresh token"`
	ExpiresAt    string `json:"expires_at"    description:"Token expiration time (RFC3339)"`
}

ChallengeResponse is the AuthResponse-shaped body returned on a successful MFA challenge. The shape matches /v1/signin's success response so SDK consumers can persist a session via the same code path regardless of whether the MFA gate fired.

type Config

type Config struct {
	// Issuer is the name shown in authenticator apps (default: "AuthSome").
	Issuer string

	// StepUpWindow is how recently the caller must have signed in to enrol
	// a first factor on session auth alone (default: 5 minutes). Once a
	// factor is verified, enrolling another one asks for that factor.
	StepUpWindow time.Duration
}

Config configures the MFA plugin.

type DisableRequest added in v1.9.0

type DisableRequest struct {
	// Code re-proves possession of the second factor: a current TOTP code or
	// an unused recovery code. Required in practice, but optional to the
	// binder so an unauthenticated caller still gets 401 rather than a 400
	// that reports a missing field before authentication was even checked.
	Code string `json:"code,omitempty"`
}

DisableRequest is an empty request for disabling MFA.

type DisableResponse added in v1.9.0

type DisableResponse struct {
	Status string `json:"status"`
}

DisableResponse is returned when MFA is disabled.

type EncryptedStore added in v1.9.0

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

EncryptedStore wraps a Store, transparently encrypting the TOTP/SMS secret on an Enrollment before it reaches the underlying storage and decrypting it on the way back out.

It is safe over a store that already holds legacy plaintext secrets: bridge.AESGCMEncryptor's Decrypt returns input unchanged when no envelope prefix is present. Recovery codes are already hashed by the caller, so those methods delegate without modification.

func NewEncryptedStore added in v1.9.0

func NewEncryptedStore(inner Store, enc bridge.Encryptor) *EncryptedStore

NewEncryptedStore wraps inner with at-rest secret encryption. A nil encryptor falls back to bridge.NoopEncryptor (no encryption).

func (*EncryptedStore) ConsumeRecoveryCode added in v1.9.0

func (s *EncryptedStore) ConsumeRecoveryCode(ctx context.Context, codeID id.RecoveryCodeID) error

func (*EncryptedStore) CreateEnrollment added in v1.9.0

func (s *EncryptedStore) CreateEnrollment(ctx context.Context, e *Enrollment) error

func (*EncryptedStore) CreateRecoveryCodes added in v1.9.0

func (s *EncryptedStore) CreateRecoveryCodes(ctx context.Context, codes []*RecoveryCode) error

Recovery codes are hashed by the caller — delegate unchanged.

func (*EncryptedStore) DeleteEnrollment added in v1.9.0

func (s *EncryptedStore) DeleteEnrollment(ctx context.Context, mfaID id.MFAID) error

func (*EncryptedStore) DeleteRecoveryCodes added in v1.9.0

func (s *EncryptedStore) DeleteRecoveryCodes(ctx context.Context, userID id.UserID) error

func (*EncryptedStore) GetEnrollment added in v1.9.0

func (s *EncryptedStore) GetEnrollment(ctx context.Context, userID id.UserID, method string) (*Enrollment, error)

func (*EncryptedStore) GetEnrollmentByID added in v1.9.0

func (s *EncryptedStore) GetEnrollmentByID(ctx context.Context, mfaID id.MFAID) (*Enrollment, error)

func (*EncryptedStore) GetRecoveryCodes added in v1.9.0

func (s *EncryptedStore) GetRecoveryCodes(ctx context.Context, userID id.UserID) ([]*RecoveryCode, error)

func (*EncryptedStore) ListEnrollments added in v1.9.0

func (s *EncryptedStore) ListEnrollments(ctx context.Context, userID id.UserID) ([]*Enrollment, error)

func (*EncryptedStore) UpdateEnrollment added in v1.9.0

func (s *EncryptedStore) UpdateEnrollment(ctx context.Context, e *Enrollment) error

type EnrollRequest added in v1.9.0

type EnrollRequest struct {
	Method string `json:"method,omitempty"` // "totp" or "sms"
	Phone  string `json:"phone,omitempty"`  // Required for SMS method
	// Code proves the factor the user already holds when enrolling a
	// further one: a current TOTP code or a recovery code.
	Code string `json:"code,omitempty"`
}

EnrollRequest is the request body for MFA enrollment.

type EnrollResponse added in v1.9.0

type EnrollResponse struct {
	ID         string `json:"id"`
	Method     string `json:"method"`
	Secret     string `json:"secret"`
	OTPAuthURL string `json:"otpauth_url"`
}

EnrollResponse is returned when MFA enrollment starts.

type Enrollment added in v1.9.0

type Enrollment struct {
	ID        id.MFAID  `json:"id"`
	UserID    id.UserID `json:"user_id"`
	Method    string    `json:"method"`   // "totp"
	Secret    string    `json:"-"`        // Base32-encoded TOTP secret (hidden from JSON)
	Verified  bool      `json:"verified"` // Set true after first successful verification
	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
}

Enrollment represents a user's MFA enrollment for a specific method.

type MemoryStore added in v1.9.0

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

MemoryStore is an in-memory Store for testing.

func NewMemoryStore added in v1.9.0

func NewMemoryStore() *MemoryStore

NewMemoryStore creates a new in-memory MFA enrollment store.

func (*MemoryStore) ConsumeRecoveryCode added in v1.9.0

func (s *MemoryStore) ConsumeRecoveryCode(_ context.Context, codeID id.RecoveryCodeID) error

ConsumeRecoveryCode marks a recovery code as used.

func (*MemoryStore) CreateEnrollment added in v1.9.0

func (s *MemoryStore) CreateEnrollment(_ context.Context, e *Enrollment) error

CreateEnrollment stores a new MFA enrollment.

func (*MemoryStore) CreateRecoveryCodes added in v1.9.0

func (s *MemoryStore) CreateRecoveryCodes(_ context.Context, codes []*RecoveryCode) error

CreateRecoveryCodes stores a batch of recovery codes.

func (*MemoryStore) DeleteEnrollment added in v1.9.0

func (s *MemoryStore) DeleteEnrollment(_ context.Context, mfaID id.MFAID) error

DeleteEnrollment removes an enrollment by ID.

func (*MemoryStore) DeleteRecoveryCodes added in v1.9.0

func (s *MemoryStore) DeleteRecoveryCodes(_ context.Context, userID id.UserID) error

DeleteRecoveryCodes removes all recovery codes for a user.

func (*MemoryStore) GetEnrollment added in v1.9.0

func (s *MemoryStore) GetEnrollment(_ context.Context, userID id.UserID, method string) (*Enrollment, error)

GetEnrollment finds an enrollment by user ID and method.

func (*MemoryStore) GetEnrollmentByID added in v1.9.0

func (s *MemoryStore) GetEnrollmentByID(_ context.Context, mfaID id.MFAID) (*Enrollment, error)

GetEnrollmentByID finds an enrollment by its ID.

func (*MemoryStore) GetRecoveryCodes added in v1.9.0

func (s *MemoryStore) GetRecoveryCodes(_ context.Context, userID id.UserID) ([]*RecoveryCode, error)

GetRecoveryCodes returns all recovery codes for a user.

func (*MemoryStore) ListEnrollments added in v1.9.0

func (s *MemoryStore) ListEnrollments(_ context.Context, userID id.UserID) ([]*Enrollment, error)

ListEnrollments returns all enrollments for a user.

func (*MemoryStore) UpdateEnrollment added in v1.9.0

func (s *MemoryStore) UpdateEnrollment(_ context.Context, e *Enrollment) error

UpdateEnrollment updates an existing enrollment.

type MongoStore added in v1.9.0

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

MongoStore implements mfa.Store using the Grove MongoDB driver.

func NewMongoStore added in v1.9.0

func NewMongoStore(db *grove.DB) *MongoStore

NewMongoStore creates a new MongoDB-backed MFA store.

func (*MongoStore) ConsumeRecoveryCode added in v1.9.0

func (s *MongoStore) ConsumeRecoveryCode(ctx context.Context, codeID id.RecoveryCodeID) error

func (*MongoStore) CreateEnrollment added in v1.9.0

func (s *MongoStore) CreateEnrollment(ctx context.Context, e *Enrollment) error

func (*MongoStore) CreateRecoveryCodes added in v1.9.0

func (s *MongoStore) CreateRecoveryCodes(ctx context.Context, codes []*RecoveryCode) error

func (*MongoStore) DeleteEnrollment added in v1.9.0

func (s *MongoStore) DeleteEnrollment(ctx context.Context, mfaID id.MFAID) error

func (*MongoStore) DeleteRecoveryCodes added in v1.9.0

func (s *MongoStore) DeleteRecoveryCodes(ctx context.Context, userID id.UserID) error

func (*MongoStore) GetEnrollment added in v1.9.0

func (s *MongoStore) GetEnrollment(ctx context.Context, userID id.UserID, method string) (*Enrollment, error)

func (*MongoStore) GetEnrollmentByID added in v1.9.0

func (s *MongoStore) GetEnrollmentByID(ctx context.Context, mfaID id.MFAID) (*Enrollment, error)

func (*MongoStore) GetRecoveryCodes added in v1.9.0

func (s *MongoStore) GetRecoveryCodes(ctx context.Context, userID id.UserID) ([]*RecoveryCode, error)

func (*MongoStore) ListEnrollments added in v1.9.0

func (s *MongoStore) ListEnrollments(ctx context.Context, userID id.UserID) ([]*Enrollment, error)

func (*MongoStore) UpdateEnrollment added in v1.9.0

func (s *MongoStore) UpdateEnrollment(ctx context.Context, e *Enrollment) error

type Plugin

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

Plugin is the MFA authentication plugin.

func New added in v1.9.0

func New(cfg ...Config) *Plugin

New creates a new MFA plugin.

func (*Plugin) DeclareSettings added in v1.9.0

func (p *Plugin) DeclareSettings(m *settings.Manager) error

DeclareSettings implements plugin.SettingsProvider.

func (*Plugin) HasMFA added in v1.9.0

func (p *Plugin) HasMFA(ctx context.Context, userID id.UserID) bool

HasMFA returns true if the user has a verified MFA enrollment.

func (*Plugin) MigrationGroups added in v1.9.0

func (p *Plugin) MigrationGroups(driverName string) []*migrate.Group

MigrationGroups implements plugin.MigrationProvider.

func (*Plugin) Name added in v1.9.0

func (p *Plugin) Name() string

Name returns the plugin name.

func (*Plugin) OnBeforeUserDelete added in v1.9.0

func (p *Plugin) OnBeforeUserDelete(ctx context.Context, userID id.UserID) error

OnBeforeUserDelete removes a deleted user's MFA enrollments and recovery codes: a second factor for an account that no longer exists is a secret with no owner.

func (*Plugin) OnInit added in v1.9.0

func (p *Plugin) OnInit(_ context.Context, engine plugin.Engine) error

OnInit is called during engine initialization. It auto-discovers the SMS sender, chronicle, relay, hooks, logger, and ceremony store from the engine.

func (*Plugin) RegisterContract added in v1.9.0

func (p *Plugin) RegisterContract(
	d *dispatcher.Dispatcher,
	reg contract.Registry,
	wreg contract.WardenRegistry,
	engine plugin.Engine,
) error

func (*Plugin) RegisterRoutes

func (p *Plugin) RegisterRoutes(router forge.Router) error

RegisterRoutes registers MFA HTTP endpoints on a forge.Router.

func (*Plugin) SetSMSSender added in v1.9.0

func (p *Plugin) SetSMSSender(s bridge.SMSSender)

SetSMSSender sets the SMS sender for testing.

func (*Plugin) SetStore added in v1.9.0

func (p *Plugin) SetStore(s Store)

SetStore sets the MFA enrollment store for testing.

type PostgresStore added in v1.9.0

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

PostgresStore implements mfa.Store using the Grove ORM with PostgreSQL.

func NewPostgresStore added in v1.9.0

func NewPostgresStore(db *grove.DB) *PostgresStore

NewPostgresStore creates a new PostgreSQL-backed MFA store.

func (*PostgresStore) ConsumeRecoveryCode added in v1.9.0

func (s *PostgresStore) ConsumeRecoveryCode(ctx context.Context, codeID id.RecoveryCodeID) error

func (*PostgresStore) CreateEnrollment added in v1.9.0

func (s *PostgresStore) CreateEnrollment(ctx context.Context, e *Enrollment) error

func (*PostgresStore) CreateRecoveryCodes added in v1.9.0

func (s *PostgresStore) CreateRecoveryCodes(ctx context.Context, codes []*RecoveryCode) error

func (*PostgresStore) DeleteEnrollment added in v1.9.0

func (s *PostgresStore) DeleteEnrollment(ctx context.Context, mfaID id.MFAID) error

func (*PostgresStore) DeleteRecoveryCodes added in v1.9.0

func (s *PostgresStore) DeleteRecoveryCodes(ctx context.Context, userID id.UserID) error

func (*PostgresStore) GetEnrollment added in v1.9.0

func (s *PostgresStore) GetEnrollment(ctx context.Context, userID id.UserID, method string) (*Enrollment, error)

func (*PostgresStore) GetEnrollmentByID added in v1.9.0

func (s *PostgresStore) GetEnrollmentByID(ctx context.Context, mfaID id.MFAID) (*Enrollment, error)

func (*PostgresStore) GetRecoveryCodes added in v1.9.0

func (s *PostgresStore) GetRecoveryCodes(ctx context.Context, userID id.UserID) ([]*RecoveryCode, error)

func (*PostgresStore) ListEnrollments added in v1.9.0

func (s *PostgresStore) ListEnrollments(ctx context.Context, userID id.UserID) ([]*Enrollment, error)

func (*PostgresStore) UpdateEnrollment added in v1.9.0

func (s *PostgresStore) UpdateEnrollment(ctx context.Context, e *Enrollment) error

type RecoveryCode added in v1.9.0

type RecoveryCode struct {
	ID        id.RecoveryCodeID `json:"id"`
	UserID    id.UserID         `json:"user_id"`
	CodeHash  string            `json:"-"`    // bcrypt hash of the plaintext code
	Used      bool              `json:"used"` // true after one-time use
	UsedAt    *time.Time        `json:"used_at,omitempty"`
	CreatedAt time.Time         `json:"created_at"`
}

RecoveryCode represents a single MFA recovery (backup) code.

func GenerateRecoveryCodes added in v1.9.0

func GenerateRecoveryCodes(userID id.UserID, count int) ([]*RecoveryCode, []string, error)

GenerateRecoveryCodes creates a set of plaintext recovery codes and their bcrypt-hashed RecoveryCode records. Returns both the records (for storage) and the plaintext codes (to show the user once).

type RecoveryRegenerateRequest added in v1.9.0

type RecoveryRegenerateRequest struct{}

RecoveryRegenerateRequest is an empty request for regenerating recovery codes.

type RecoveryRegenerateResponse added in v1.9.0

type RecoveryRegenerateResponse struct {
	Codes []string `json:"codes"`
}

RecoveryRegenerateResponse is returned with new recovery codes.

type RecoveryVerifyRequest added in v1.9.0

type RecoveryVerifyRequest struct {
	Code string `json:"code"`
}

RecoveryVerifyRequest is the request body for verifying an MFA recovery code.

type RecoveryVerifyResponse added in v1.9.0

type RecoveryVerifyResponse struct {
	ChallengePassed bool `json:"challenge_passed"`
	CodesRemaining  int  `json:"codes_remaining"`
}

RecoveryVerifyResponse is returned on successful recovery code verification.

type SMSChallenge added in v1.9.0

type SMSChallenge struct {
	Code      string
	ExpiresAt time.Time
}

SMSChallenge represents a pending SMS verification challenge.

func SendSMSChallenge added in v1.9.0

func SendSMSChallenge(ctx context.Context, sender bridge.SMSSender, phone string) (*SMSChallenge, error)

SendSMSChallenge generates a code and sends it via the SMS bridge.

type SMSSendRequest added in v1.9.0

type SMSSendRequest struct {
	Phone string `json:"phone,omitempty"` // Optional: override the enrolled phone
}

SMSSendRequest is the request body for sending an SMS verification code.

type SMSSendResponse added in v1.9.0

type SMSSendResponse struct {
	Sent      bool   `json:"sent"`
	ExpiresIn int    `json:"expires_in_seconds"`
	Phone     string `json:"phone_masked"`
}

SMSSendResponse is returned when an SMS code is sent.

type SMSVerifyRequest added in v1.9.0

type SMSVerifyRequest struct {
	Code string `json:"code"`
}

SMSVerifyRequest is the request body for verifying an SMS code.

type SMSVerifyResponse added in v1.9.0

type SMSVerifyResponse struct {
	Verified bool   `json:"verified"`
	Method   string `json:"method"`
}

SMSVerifyResponse is returned on successful SMS code verification.

type SqliteStore added in v1.9.0

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

SqliteStore implements mfa.Store using the Grove ORM with SQLite.

func NewSqliteStore added in v1.9.0

func NewSqliteStore(db *grove.DB) *SqliteStore

NewSqliteStore creates a new SQLite-backed MFA store.

func (*SqliteStore) ConsumeRecoveryCode added in v1.9.0

func (s *SqliteStore) ConsumeRecoveryCode(ctx context.Context, codeID id.RecoveryCodeID) error

func (*SqliteStore) CreateEnrollment added in v1.9.0

func (s *SqliteStore) CreateEnrollment(ctx context.Context, e *Enrollment) error

func (*SqliteStore) CreateRecoveryCodes added in v1.9.0

func (s *SqliteStore) CreateRecoveryCodes(ctx context.Context, codes []*RecoveryCode) error

func (*SqliteStore) DeleteEnrollment added in v1.9.0

func (s *SqliteStore) DeleteEnrollment(ctx context.Context, mfaID id.MFAID) error

func (*SqliteStore) DeleteRecoveryCodes added in v1.9.0

func (s *SqliteStore) DeleteRecoveryCodes(ctx context.Context, userID id.UserID) error

func (*SqliteStore) GetEnrollment added in v1.9.0

func (s *SqliteStore) GetEnrollment(ctx context.Context, userID id.UserID, method string) (*Enrollment, error)

func (*SqliteStore) GetEnrollmentByID added in v1.9.0

func (s *SqliteStore) GetEnrollmentByID(ctx context.Context, mfaID id.MFAID) (*Enrollment, error)

func (*SqliteStore) GetRecoveryCodes added in v1.9.0

func (s *SqliteStore) GetRecoveryCodes(ctx context.Context, userID id.UserID) ([]*RecoveryCode, error)

func (*SqliteStore) ListEnrollments added in v1.9.0

func (s *SqliteStore) ListEnrollments(ctx context.Context, userID id.UserID) ([]*Enrollment, error)

func (*SqliteStore) UpdateEnrollment added in v1.9.0

func (s *SqliteStore) UpdateEnrollment(ctx context.Context, e *Enrollment) error

type Store added in v1.9.0

type Store interface {
	// Enrollment CRUD
	CreateEnrollment(ctx context.Context, e *Enrollment) error
	GetEnrollment(ctx context.Context, userID id.UserID, method string) (*Enrollment, error)
	GetEnrollmentByID(ctx context.Context, mfaID id.MFAID) (*Enrollment, error)
	UpdateEnrollment(ctx context.Context, e *Enrollment) error
	DeleteEnrollment(ctx context.Context, mfaID id.MFAID) error
	ListEnrollments(ctx context.Context, userID id.UserID) ([]*Enrollment, error)

	// Recovery codes
	CreateRecoveryCodes(ctx context.Context, codes []*RecoveryCode) error
	GetRecoveryCodes(ctx context.Context, userID id.UserID) ([]*RecoveryCode, error)
	ConsumeRecoveryCode(ctx context.Context, codeID id.RecoveryCodeID) error
	DeleteRecoveryCodes(ctx context.Context, userID id.UserID) error
}

Store persists MFA enrollment data and recovery codes.

type TOTPConfig

type TOTPConfig struct {
	// Issuer is the name of the application (shown in authenticator apps).
	Issuer string

	// AccountName is the user's identifier (usually email).
	AccountName string
}

TOTPConfig configures TOTP generation.

type VerifyMFARequest added in v1.9.0

type VerifyMFARequest struct {
	Code string `json:"code"`
}

VerifyMFARequest is the request body for MFA verification.

type VerifyMFAResponse added in v1.9.0

type VerifyMFAResponse struct {
	Verified      bool     `json:"verified"`
	Method        string   `json:"method"`
	RecoveryCodes []string `json:"recovery_codes,omitempty"`
}

VerifyMFAResponse is returned on successful MFA verification.

Directories

Path Synopsis
Package contract wires the mfa plugin's deep-link settings page into the forge-dashboard contract registry.
Package contract wires the mfa plugin's deep-link settings page into the forge-dashboard contract registry.
Package mfatest provides a backend-agnostic conformance suite for the mfa.Store interface.
Package mfatest provides a backend-agnostic conformance suite for the mfa.Store interface.

Jump to

Keyboard shortcuts

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