# `PhoenixKit.Users.RateLimiter`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/phoenix_kit/users/rate_limiter.ex#L8)

Rate limiting for authentication endpoints to prevent brute-force attacks.

This module provides comprehensive rate limiting protection for:
- Login attempts (prevents password brute-forcing)
- Magic link generation (prevents token enumeration)
- Password reset requests (prevents mass reset attacks)
- User registration (prevents spam account creation)

## Configuration

Rate limits can be configured in your application config:

    # config/config.exs
    config :phoenix_kit, PhoenixKit.Users.RateLimiter,
      login_limit: 5,                    # Max login attempts per window
      login_window_ms: 60_000,           # 1 minute window
      magic_link_limit: 3,               # Max magic link requests per window
      magic_link_window_ms: 300_000,     # 5 minute window
      password_reset_limit: 3,           # Max password reset requests per window
      password_reset_window_ms: 300_000, # 5 minute window
      registration_limit: 3,             # Max registration attempts per window
      registration_window_ms: 3600_000,  # 1 hour window
      registration_ip_limit: 10,         # Max registrations per IP per window
      registration_ip_window_ms: 3600_000 # 1 hour window

## Security Features

- **Email-based rate limiting**: Prevents targeted attacks on specific accounts
- **IP-based rate limiting**: Prevents distributed attacks from single sources
- **Timing attack mitigation**: Consistent response times for valid/invalid emails
- **Exponential backoff**: Automatically enforced through time windows
- **Comprehensive logging**: All rate limit violations are logged for security monitoring

## Usage Examples

    # Check login rate limit
    case PhoenixKit.Users.RateLimiter.check_login_rate_limit(email, ip_address) do
      :ok -> proceed_with_login()
      {:error, :rate_limit_exceeded} -> show_rate_limit_error()
    end

    # Check magic link rate limit
    case PhoenixKit.Users.RateLimiter.check_magic_link_rate_limit(email) do
      :ok -> generate_magic_link()
      {:error, :rate_limit_exceeded} -> show_cooldown_message()
    end

## Production Recommendations

- Use Redis backend for distributed systems (hammer_backend_redis)
- Monitor rate limit violations for security threats
- Adjust limits based on your application's usage patterns
- Consider implementing CAPTCHA after multiple violations

# `check_login_rate_limit`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/phoenix_kit/users/rate_limiter.ex#L105)

Checks if login attempts are within rate limit.

Returns `:ok` if the request is allowed, or `{:error, :rate_limit_exceeded}` if the limit is exceeded.

This function implements dual rate limiting:
- Per-email rate limiting (prevents targeted attacks on specific accounts)
- Per-IP rate limiting (prevents distributed brute-force attacks)

## Examples

    iex> PhoenixKit.Users.RateLimiter.check_login_rate_limit("user@example.com", "192.168.1.1")
    :ok

    # After 5 failed attempts:
    iex> PhoenixKit.Users.RateLimiter.check_login_rate_limit("user@example.com", "192.168.1.1")
    {:error, :rate_limit_exceeded}

# `check_magic_link_rate_limit`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/phoenix_kit/users/rate_limiter.ex#L156)

Checks if magic link generation is within rate limit.

Returns `:ok` if the request is allowed, or `{:error, :rate_limit_exceeded}` if the limit is exceeded.

Magic links have stricter rate limits to prevent token enumeration attacks.

## Examples

    iex> PhoenixKit.Users.RateLimiter.check_magic_link_rate_limit("user@example.com")
    :ok

    # After 3 requests in 5 minutes:
    iex> PhoenixKit.Users.RateLimiter.check_magic_link_rate_limit("user@example.com")
    {:error, :rate_limit_exceeded}

# `check_password_reset_rate_limit`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/phoenix_kit/users/rate_limiter.ex#L191)

Checks if password reset requests are within rate limit.

Returns `:ok` if the request is allowed, or `{:error, :rate_limit_exceeded}` if the limit is exceeded.

Password reset requests have moderate rate limits to prevent mass reset attacks
while still allowing legitimate users to recover their accounts.

## Examples

    iex> PhoenixKit.Users.RateLimiter.check_password_reset_rate_limit("user@example.com")
    :ok

    # After 3 requests in 5 minutes:
    iex> PhoenixKit.Users.RateLimiter.check_password_reset_rate_limit("user@example.com")
    {:error, :rate_limit_exceeded}

# `check_registration_rate_limit`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/phoenix_kit/users/rate_limiter.ex#L227)

Checks if registration attempts are within rate limit.

Returns `:ok` if the request is allowed, or `{:error, :rate_limit_exceeded}` if the limit is exceeded.

Registration has dual rate limiting:
- Per-email rate limiting (prevents spam account creation with same email)
- Per-IP rate limiting (prevents mass account creation from single source)

## Examples

    iex> PhoenixKit.Users.RateLimiter.check_registration_rate_limit("user@example.com", "192.168.1.1")
    :ok

    # After limit exceeded:
    iex> PhoenixKit.Users.RateLimiter.check_registration_rate_limit("user@example.com", "192.168.1.1")
    {:error, :rate_limit_exceeded}

# `get_config`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/phoenix_kit/users/rate_limiter.ex#L364)

# `get_remaining_attempts`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/phoenix_kit/users/rate_limiter.ex#L311)

Gets the remaining attempts for a specific action and identifier.

Returns the number of attempts remaining before rate limit is exceeded.

For login and registration actions, returns the email-based limit.
For magic_link and password_reset, returns the limit for the email.

Note: With Hammer 7.x, this uses the get/2 function to retrieve the current count.

## Examples

    iex> PhoenixKit.Users.RateLimiter.get_remaining_attempts(:login, "user@example.com")
    5

    iex> PhoenixKit.Users.RateLimiter.get_remaining_attempts(:magic_link, "user@example.com")
    3

# `reset_rate_limit`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.71/lib/phoenix_kit/users/rate_limiter.ex#L284)

> This function is deprecated. Hammer 7.x removed delete_buckets. Rate limits expire after their time window..

Resets rate limit for a specific action and identifier.

**DEPRECATED:** Hammer 7.x removed `delete_buckets` with no replacement.
This function now returns an error as Backend.set/3 requires positive integers (cannot set to 0).

Rate limits will naturally expire after their configured window period.

## Migration

- **For testing**: Use `Application.put_env` to disable rate limiting
- **For admin intervention**: Wait for the time window to expire
- **For immediate reset**: Restart the application (clears ETS tables)

See: https://hexdocs.pm/hammer/upgrade-v7.html

## Examples

    iex> PhoenixKit.Users.RateLimiter.reset_rate_limit(:login, "email:user@example.com")
    {:error, :not_supported}

---

*Consult [api-reference.md](api-reference.md) for complete listing*
