passwordreset

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Oct 30, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package passwordreset provides typed model-first password recovery. The challenge and model write commit together; resetting never signs a user in.

Index

Constants

View Source
const DefaultLifetime = time.Hour

Variables

This section is empty.

Functions

This section is empty.

Types

type Issued

type Issued[M any] = challenge.Issued[M, challenge.PasswordReset]

type Model

type Model[M model.Identifiable, K any] struct {
	Lock             func(context.Context, *database.Tx, K) (value.Optional[M], error)
	Email            func(M) string
	EmailRevision    func(M) challenge.Revision[M]
	Hash             func(M) password.Hash
	SetPassword      func(context.Context, *database.Tx, M, password.Hash) (M, error)
	ValidatePassword func(context.Context, password.Plaintext) error
	Invalidate       func(context.Context, *database.Tx, M) error
	Eligible         func(context.Context, M) (bool, error)
}

Model describes domain behavior using stored fields and generated mutations. Lock uses ForUpdate on tx. SetPassword must return the full updated model. ValidatePassword owns domain strength rules, not encoding/hashing policy. Invalidate MUST invalidate applicable credentials in the SAME transaction; failure rolls back the password change and link consumption. Do not call a store method that opens another transaction or defer revocation to after-commit. EmailRevision reads a nonzero persisted generation. Model lifecycle behavior must replace it whenever the stored email changes, even if an old email is restored later. Do not rotate it merely when issuing a link or resetting a password: verification links for an unchanged email remain independent. Additional outbox/audit writes may use tx. These callbacks must not send email. Eligible optionally replaces the provider's eligibility for this flow.

type Reset

type Reset[M model.Identifiable, K any] struct {
	// contains filtered or unexported fields
}

func New

func New[M model.Identifiable, K any](store *challenge.Store, provider auth.Provider[M, K], hasher *password.Hasher, binding Model[M, K], lifetime time.Duration) (*Reset[M, K], error)

func WithLockout

func WithLockout[M model.Identifiable, K, I any](reset *Reset[M, K], throttle lockout.Throttle[I], key func(M) I) (*Reset[M, K], error)

WithLockout returns a reset view that clears the login throttle for the reset account after the reset commits, using key to derive the same login key the PasswordLogin uses (for example the stored email). It clears the account ceiling and the resetting client's window. Clearing is best effort: the committed reset is never undone, and a lockout backend failure leaves the old windows to expire on their own.

func (*Reset[M, K]) Complete

func (r *Reset[M, K]) Complete(ctx context.Context, token Token[M], plain password.Plaintext) (M, error)

Complete checks the link and current model before expensive hashing. The bounded KDF runs while the model is locked, avoiding a gap between validation and replacement. Apply request throttling before this operation. It returns no authentication proof; MFA requirements remain unchanged.

func (*Reset[M, K]) Issue

func (r *Reset[M, K]) Issue(ctx context.Context, reference model.Reference[M, K]) (Issued[M], error)

func (*Reset[M, K]) Prune

func (r *Reset[M, K]) Prune(ctx context.Context, limit int) (uint64, error)

func (*Reset[M, K]) Revoke

func (r *Reset[M, K]) Revoke(ctx context.Context, reference model.Reference[M, K]) (bool, error)

func (*Reset[M, K]) Validate

func (r *Reset[M, K]) Validate() error

func (*Reset[M, K]) WithObserver

func (r *Reset[M, K]) WithObserver(observer auth.Observer) (*Reset[M, K], error)

WithObserver reports EventPasswordReset after each committed reset.

type Token

type Token[M any] = challenge.Token[M, challenge.PasswordReset]

func ParseToken

func ParseToken[M any](raw secret.String) (Token[M], error)

Jump to

Keyboard shortcuts

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