passwordreset

package
v0.6.0 Latest Latest
Warning

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

Go to latest
Published: Nov 3, 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]

Issued carries a committed password-reset challenge for model M.

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
}

Reset binds single-use password-reset challenges to password policy and transactional model changes.

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)

New validates the hasher and model callbacks and binds reset challenges to the current email revision and password hash.

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)

Issue creates a reset challenge for the current subject identified by reference.

func (*Reset[M, K]) Prune

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

Prune removes up to limit expired reset challenges.

func (*Reset[M, K]) Revoke

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

Revoke removes the subject's reset challenge and reports whether one existed.

func (*Reset[M, K]) Validate

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

Validate checks that the password-reset flow is configured.

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]

Token is a password-reset secret retaining its model type.

func ParseToken

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

ParseToken validates reset-token syntax without checking its stored validity.

Jump to

Keyboard shortcuts

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