Documentation
¶
Overview ¶
Package emailtoken creates and checks the single-use tokens sent in emails: verification, password reset, and email change.
Like session tokens, only a token's SHA-256 hash is stored. A token works once, for one kind of action, until it expires. Creating a token cancels the user's earlier unused tokens of the same kind, and a user gets at most one new token of each kind per Cooldown, which limits how many emails anyone can trigger until real rate limiting exists.
Index ¶
- Constants
- Variables
- type Conn
- type Kind
- type Manager
- func (m *Manager) Create(ctx context.Context, userID uuid.UUID, kind Kind, newEmail string) (string, Token, error)
- func (m *Manager) DeleteSpent(ctx context.Context) (int64, error)
- func (m *Manager) Lookup(ctx context.Context, tok string, kind Kind) (Token, error)
- func (m *Manager) RecordFailure(ctx context.Context, id uuid.UUID) error
- func (m *Manager) Use(ctx context.Context, id uuid.UUID) error
- type Token
Constants ¶
const Cooldown = 60 * time.Second
Cooldown is the minimum time between two tokens of the same kind for one user.
const MaxFailedAttempts = 5
MaxFailedAttempts is how many wrong passwords can be entered with a token before it stops working, so a stolen link can't be used to guess a password.
Variables ¶
var ( // ErrInvalid means a token is malformed, unknown, for a different kind // of action, used, expired, or locked by failed attempts. These cases // are deliberately indistinguishable to callers. ErrInvalid = errors.New("email token is invalid or expired") // ErrCooldown means the user was sent a token of this kind less than // Cooldown ago. ErrCooldown = errors.New("email token requested too soon") )
Functions ¶
This section is empty.
Types ¶
type Conn ¶
Conn is a database connection that can start a transaction: a pool, or a transaction (which starts a savepoint).
type Kind ¶
type Kind string
Kind is what a token is for.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager manages email tokens in the database.
func NewManager ¶
NewManager returns a Manager using conn. now supplies the current time; pass time.Now outside tests.
func (*Manager) Create ¶
func (m *Manager) Create(ctx context.Context, userID uuid.UUID, kind Kind, newEmail string) (string, Token, error)
Create makes a new token of kind for userID and returns it. The token is returned only here, to be put in an email. newEmail is required for ChangeEmail and must be empty otherwise. It returns ErrCooldown if the user got a token of this kind less than Cooldown ago.
func (*Manager) DeleteSpent ¶
DeleteSpent removes used and expired tokens and returns how many were removed. Run it periodically; spent tokens are already rejected, so this only frees space.
func (*Manager) Lookup ¶
Lookup returns the token tok if it's usable for kind, without using it. Call Use to spend it.
func (*Manager) RecordFailure ¶
RecordFailure counts a wrong password entered with token id. After MaxFailedAttempts the token stops working.
func (*Manager) Use ¶
Use spends token id so it can't be used again. It returns ErrInvalid if the token stopped being usable since Lookup, e.g. because a concurrent request used it first. Call it in the same transaction as the action the token authorizes, so the token is spent only if the action happens.