final class DbPasswordResetTokenRepository implements PasswordResetTokenRepositoryInterface (View source)

SQL persistence for password reset tokens and their rate-limit counters in password_reset_tokens.

Methods

__construct(PDO $db, ConfigurationInterface $config)

No description

static string
hashToken(string $token)

One-way hash applied to a reset token before persistence. SHA-256 is sufficient because tokens are 256 bits of entropy from random_bytes(32); brute force across the keyspace is infeasible without a salt. The sha256$ prefix matches the API key repository so the same shape gate defends both surfaces against pass-the-hash from a DB-read leak.

bool
create(array $data)

Store a reset token. The raw token is supplied; the implementation stores its hash and findByToken() expects that same hash.

array|null
findByToken(string $token)

Find a token by its value

bool
markAsUsed(int $tokenId)

Mark a token as used. Only an unused token can be claimed, so of two requests redeeming the same token only the first gets true.

bool
releaseClaim(int $tokenId)

Undo markAsUsed() after the password change it guarded failed, so the link works again.

int
countRecentAttempts(string $email, int $seconds)

Count recent attempts for an email address

int
countRecentAttemptsByIp(string $ip, int $seconds)

Count recent attempts by IP address

int
deleteExpired()

Delete expired tokens

bool
deleteById(int $tokenId)

Delete a specific token by ID

Details

__construct(PDO $db, ConfigurationInterface $config)

No description

Parameters

PDO $db
ConfigurationInterface $config

static string hashToken(string $token)

One-way hash applied to a reset token before persistence. SHA-256 is sufficient because tokens are 256 bits of entropy from random_bytes(32); brute force across the keyspace is infeasible without a salt. The sha256$ prefix matches the API key repository so the same shape gate defends both surfaces against pass-the-hash from a DB-read leak.

Parameters

string $token

Return Value

string

bool create(array $data)

Store a reset token. The raw token is supplied; the implementation stores its hash and findByToken() expects that same hash.

Parameters

array $data

Token row: email, token, expires_at, ip_address

Return Value

bool

array|null findByToken(string $token)

Find a token by its value

Parameters

string $token

Return Value

array|null

bool markAsUsed(int $tokenId)

Mark a token as used. Only an unused token can be claimed, so of two requests redeeming the same token only the first gets true.

Parameters

int $tokenId

Return Value

bool

bool releaseClaim(int $tokenId)

Undo markAsUsed() after the password change it guarded failed, so the link works again.

Parameters

int $tokenId

Return Value

bool

int countRecentAttempts(string $email, int $seconds)

Count recent attempts for an email address

Parameters

string $email
int $seconds

Return Value

int

int countRecentAttemptsByIp(string $ip, int $seconds)

Count recent attempts by IP address

Parameters

string $ip
int $seconds

Return Value

int

int deleteExpired()

Delete expired tokens

Current cleanup strategy:

  • Delete tokens that have passed their expiration time
  • Delete used tokens that are older than 7 days (kept temporarily for audit trail)

This method is called automatically:

  • When creating new password reset requests
  • When validating tokens
  • After successful password resets

Return Value

int

Number of deleted rows

bool deleteById(int $tokenId)

Delete a specific token by ID

Parameters

int $tokenId

Return Value

bool