eb18994b7d
- Migrate 660+ datetime.utcnow() across 153 files to datetime.now(UTC) - Migrate 30+ datetime.now() without UTC to datetime.now(UTC) - Convert all 170 DateTime columns to DateTime(timezone=True) - Add migrate_datetime_to_timestamptz() in universal_migration with SET LOCAL timezone='UTC' safety - Remove 70+ .replace(tzinfo=None) workarounds - Fix utcfromtimestamp → fromtimestamp(..., tz=UTC) - Fix fromtimestamp() without tz= (system_logs, backup_service, referral_diagnostics) - Fix fromisoformat/isoparse to ensure aware output (platega, yookassa, wata, miniapp, nalogo) - Fix strptime() to add .replace(tzinfo=UTC) (backup_service, referral_diagnostics) - Fix datetime.combine() to include tzinfo=UTC (remnawave_sync, traffic_monitoring) - Fix datetime.max/datetime.min sentinels with .replace(tzinfo=UTC) - Rename panel_datetime_to_naive_utc → panel_datetime_to_utc - Remove DTZ003 from ruff ignore list
85 lines
2.0 KiB
Python
85 lines
2.0 KiB
Python
"""Email verification token generation and validation."""
|
|
|
|
import secrets
|
|
from datetime import UTC, datetime, timedelta
|
|
|
|
from app.config import settings
|
|
|
|
|
|
def generate_email_change_code() -> str:
|
|
"""
|
|
Generate a 6-digit verification code for email change.
|
|
|
|
Returns:
|
|
6-digit numeric string
|
|
"""
|
|
return str(secrets.randbelow(900000) + 100000)
|
|
|
|
|
|
def get_email_change_expires_at() -> datetime:
|
|
"""
|
|
Get the expiration datetime for an email change code.
|
|
|
|
Returns:
|
|
Datetime when the email change code expires
|
|
"""
|
|
minutes = settings.get_cabinet_email_change_code_expire_minutes()
|
|
return datetime.now(UTC) + timedelta(minutes=minutes)
|
|
|
|
|
|
def generate_verification_token() -> str:
|
|
"""
|
|
Generate a secure random verification token.
|
|
|
|
Returns:
|
|
32-character hex token string
|
|
"""
|
|
return secrets.token_hex(32)
|
|
|
|
|
|
def generate_password_reset_token() -> str:
|
|
"""
|
|
Generate a secure random password reset token.
|
|
|
|
Returns:
|
|
32-character hex token string
|
|
"""
|
|
return secrets.token_hex(32)
|
|
|
|
|
|
def get_verification_expires_at() -> datetime:
|
|
"""
|
|
Get the expiration datetime for a verification token.
|
|
|
|
Returns:
|
|
Datetime when the verification token expires
|
|
"""
|
|
hours = settings.get_cabinet_email_verification_expire_hours()
|
|
return datetime.now(UTC) + timedelta(hours=hours)
|
|
|
|
|
|
def get_password_reset_expires_at() -> datetime:
|
|
"""
|
|
Get the expiration datetime for a password reset token.
|
|
|
|
Returns:
|
|
Datetime when the password reset token expires
|
|
"""
|
|
hours = settings.get_cabinet_password_reset_expire_hours()
|
|
return datetime.now(UTC) + timedelta(hours=hours)
|
|
|
|
|
|
def is_token_expired(expires_at: datetime | None) -> bool:
|
|
"""
|
|
Check if a token has expired.
|
|
|
|
Args:
|
|
expires_at: Token expiration datetime
|
|
|
|
Returns:
|
|
True if expired or no expiration set, False otherwise
|
|
"""
|
|
if expires_at is None:
|
|
return True
|
|
return datetime.now(UTC) > expires_at
|