You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
35 lines
1.1 KiB
Python
35 lines
1.1 KiB
Python
from __future__ import annotations
|
|
|
|
import random
|
|
import time
|
|
from enum import Enum
|
|
|
|
|
|
class VerificationCodeUsage(str, Enum):
|
|
LOGIN = "login"
|
|
REGISTER = "register"
|
|
UPDATE_PASSWORD = "updatePassword"
|
|
RESET_PASSWORD = "resetPassword"
|
|
|
|
|
|
_codes: dict[tuple[str, str], tuple[str, float]] = {}
|
|
|
|
|
|
def set_code(subject: str, usage: str | VerificationCodeUsage, ttl_seconds: int = 300) -> dict[str, str | int]:
|
|
usage_value = usage.value if isinstance(usage, VerificationCodeUsage) else usage
|
|
code = f"{random.randint(0, 999999):06d}"
|
|
_codes[(subject, usage_value)] = (code, time.time() + ttl_seconds)
|
|
return {"subject": subject, "usage": usage_value, "code": code, "ttlSeconds": ttl_seconds}
|
|
|
|
|
|
def check_code(subject: str, code: str, usage: str | VerificationCodeUsage) -> bool:
|
|
usage_value = usage.value if isinstance(usage, VerificationCodeUsage) else usage
|
|
value = _codes.get((subject, usage_value))
|
|
if value is None:
|
|
return False
|
|
cached_code, expires_at = value
|
|
if expires_at < time.time():
|
|
_codes.pop((subject, usage_value), None)
|
|
return False
|
|
return cached_code == code
|