Skip to content

Email verification

Email verification is opt-in. You enable it by providing an async function that sends the verification email.

Setup

async def send_verify_email(email: str, token: str) -> None:
    """Send a verification email. Called by bluefox-auth."""
    verify_url = f"https://app.example.com/verify-email?token={token}"
    await your_email_service.send(
        to=email,
        subject="Verify your email",
        body=f"Click here to verify your email: {verify_url}",
    )

BluefoxAuth(app, settings, email_verify_send_fn=send_verify_email)

Without this hook, the /email-verification endpoint returns 501 Not Implemented.

Flow

1. User requests verification

This endpoint requires authentication (the user must be logged in):

POST /auth/email-verification
Authorization: Bearer <access_token>

Response:

{"message": "Verification email sent."}

If the user is already verified, it short-circuits:

{"message": "Email is already verified."}

2. User confirms verification

The user clicks the link in the email, and your frontend sends:

POST /auth/email-verification/confirm
Content-Type: application/json

{"token": "eyJhbG..."}

Response:

{"message": "Email verified."}

Security

  • One-time use — once email_verified is set to True, the same token is rejected
  • 24 hour expiry — tokens expire after 24 hours
  • Type-checked — an email verification token cannot be used for password reset
  • Requires authentication — only logged-in users can request a verification email

Checking verification status

Use the /me endpoint to check:

{
  "id": 1,
  "email": "user@example.com",
  "is_active": true,
  "is_superuser": false,
  "email_verified": true
}

No enforcement yet

v0.1 does not enforce email verification for route access. The email_verified field is available for your application logic. v0.2 will add require_email_verification and a current_verified_user dependency.