verifycode

package
v0.9.77 Latest Latest
Warning

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

Go to latest
Published: Nov 6, 2026 License: GPL-3.0 Imports: 13 Imported by: 0

Documentation

Overview

Package verifycode provides the shared primitives for 6-digit email verification codes used by both the operator control panel and the player-facing player flow:

  • 6-digit numeric code generation
  • per-user salt + SHA-256 hashing (avoids precomputed rainbow tables on the small 10^6 code space)
  • expiry / attempt / resend-cooldown checks

Invite-link codes use a longer URL-safe alphabet; both kinds of codes share the salt+hash storage convention.

Index

Constants

View Source
const (
	// CodeTTL is the lifetime of a 6-digit verification code.
	CodeTTL = 15 * time.Minute

	// InviteTTL is the lifetime of an invitation link's URL-safe code.
	InviteTTL = 3 * 24 * time.Hour

	// ResendCooldown caps how often a new code can be sent to the same address.
	ResendCooldown = 1 * time.Minute

	// MaxAttempts is the number of wrong code submissions before the code
	// is invalidated and the user has to request a new one.
	MaxAttempts = 5

	// MaxLifetimeAttempts is the per-account cap that survives /resend.
	// Without this, an attacker could mint a fresh code each minute and
	// keep burning the MaxAttempts budget forever; this counter only
	// resets on successful verification.
	MaxLifetimeAttempts = 20

	// LockoutDuration is how long an account stays locked after hitting
	// MaxLifetimeAttempts. Operator support unlocks earlier by clearing
	// the column.
	LockoutDuration = 24 * time.Hour
)
View Source
const (
	// SigningKeySize is the required email-verification cookie HMAC key size.
	SigningKeySize = 32
)

Variables

This section is empty.

Functions

func AccountLocked

func AccountLocked(lockedUntil, now time.Time) bool

AccountLocked reports whether lockedUntil is in the future.

func AttemptsExhausted

func AttemptsExhausted(attempts int) bool

AttemptsExhausted reports whether the attempt counter has reached MaxAttempts.

func CanResend

func CanResend(lastSent, now time.Time) bool

CanResend reports whether enough time has elapsed since the last send to allow another one.

func Expired

func Expired(expiresAt, now time.Time) bool

Expired reports whether the code's expiry has passed (or was never set).

func GenerateCode

func GenerateCode() (string, error)

GenerateCode returns a fresh 6-digit numeric code as a string with leading zeros preserved. Uses crypto/rand.Int to avoid modulo bias (2^32 is not a multiple of 10^6).

func GenerateInviteCode

func GenerateInviteCode() (string, error)

GenerateInviteCode returns a URL-safe random string suitable for an invitation magic link.

func Hash

func Hash(salt []byte, code string) []byte

Hash returns SHA-256(salt || ":" || code).

func LifetimeExhausted

func LifetimeExhausted(attempts int) bool

LifetimeExhausted reports whether the lifetime attempt counter has reached MaxLifetimeAttempts — the account is locked at this point.

func LoadSigningKey

func LoadSigningKey(ctx context.Context, pool *db.Pool, envHex string) ([]byte, error)

LoadSigningKey resolves the shared player/control-panel verification-cookie key. An external key wins and leaves no database copy. Otherwise the first process generates a versioned server_secrets row and concurrent processes read back the same winning value.

func NewSalt

func NewSalt() ([]byte, error)

NewSalt returns a random per-user salt for code hashing.

Types

This section is empty.

Jump to

Keyboard shortcuts

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