infrastructure.security.password_reset_token_service¶
src.infrastructure.security.password_reset_token_service
¶
Password reset token service.
This service handles generation of password reset tokens.
Architecture
- Infrastructure service (no protocol needed)
- Used by application handlers directly
- Tokens stored in plain text (already unguessable)
Token Strategy
- 32-byte random hex string (64 characters)
- 15-minute expiration (security vs UX)
- One-time use (marked as used_at)
- Very short-lived (security-sensitive operation)
Reference
- docs/architecture/authentication-architecture.md (Lines 425-442)
Attributes¶
Classes¶
PasswordResetTokenService
¶
Password reset token generation service.
Generates unguessable tokens for password reset links. Very short-lived (15 minutes) for security.
Usage
Application handler uses directly¶
service = PasswordResetTokenService(expiration_minutes=15)
Generate token¶
token = service.generate_token()
Store in database¶
await password_reset_repo.save( user_id=user_id, token=token, expires_at=service.calculate_expiration(), ip_address=request.client.host, user_agent=request.headers.get("User-Agent"), )
Send in email (URL built using settings.verification_url_base)¶
Note: Actual endpoint is POST /api/v1/auth/password-reset/confirm with token in body¶
This URL is for GET request that redirects/renders form¶
reset_url = f"{settings.verification_url_base}/api/v1/auth/password-reset/confirm?token={token}"
Source code in src/infrastructure/security/password_reset_token_service.py
Functions¶
__init__
¶
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
expiration_minutes
|
int
|
Token expiration in minutes (default: 15). |
15
|
Note
15 minutes balances security (short window) with UX (enough time). Password reset is security-sensitive, so very short expiration.
Source code in src/infrastructure/security/password_reset_token_service.py
generate_token
¶
Generate password reset token.
Returns:
| Type | Description |
|---|---|
str
|
64-character hex string (32 bytes of entropy). |
Example
service = PasswordResetTokenService() token = service.generate_token() len(token) 64 all(c in '0123456789abcdef' for c in token) True
Note
- Token is 32 bytes = 256 bits of entropy
- 2^256 possibilities (unguessable)
- No hashing needed (already cryptographically secure)
- Each generation produces unique token
Source code in src/infrastructure/security/password_reset_token_service.py
calculate_expiration
¶
Calculate expiration timestamp for new token.
Returns:
| Type | Description |
|---|---|
datetime
|
Expiration datetime (UTC) based on configured expiration_minutes. |
Example
service = PasswordResetTokenService(expiration_minutes=15) expires_at = service.calculate_expiration()
~15 minutes from now¶
Note
- Always returns UTC timestamp
- Add configured minutes to current time
- Very short expiration for security