user = User.find_by(email: params[:email].to_s.downcase.strip)
if user
raw_token = SecureRandom.urlsafe_base64(32)
user.password_resets.create!(token_digest: Digest::SHA256.hexdigest(raw_token), expires_at: 30.minutes.from_now)
PasswordResetMailer.with(user: user, token: raw_token).deliver_later
class User < ApplicationRecord
has_secure_password
RESET_TOKEN_TTL = 30.minutes
def self.reset_verifier
from django.core.cache import cache
class RateLimiter:
def __init__(self, scope, limit, window_seconds):
self.scope = scope
CREATE TABLE password_reset_tokens (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
token_hash TEXT NOT NULL,
expires_at TIMESTAMPTZ NOT NULL,
used_at TIMESTAMPTZ,