90 lines
1.9 KiB
Python
90 lines
1.9 KiB
Python
import hashlib
|
|
import os
|
|
import secrets
|
|
import uuid
|
|
from datetime import datetime, timedelta, timezone
|
|
|
|
import jwt
|
|
from pwdlib import PasswordHash
|
|
|
|
|
|
password_hash = PasswordHash.recommended()
|
|
|
|
JWT_SECRET = os.environ["JWT_SECRET"]
|
|
ACCESS_TOKEN_MINUTES = int(os.environ.get("ACCESS_TOKEN_MINUTES", "15"))
|
|
REFRESH_TOKEN_DAYS = int(os.environ.get("REFRESH_TOKEN_DAYS", "30"))
|
|
|
|
JWT_ALGORITHM = "HS256"
|
|
|
|
|
|
def normalize_email(email: str) -> str:
|
|
return email.strip().lower()
|
|
|
|
|
|
def hash_password(password: str) -> str:
|
|
return password_hash.hash(password)
|
|
|
|
|
|
def verify_password(password: str, hashed: str) -> bool:
|
|
return password_hash.verify(password, hashed)
|
|
|
|
|
|
def create_access_token(
|
|
user_id: uuid.UUID,
|
|
session_id: uuid.UUID,
|
|
) -> str:
|
|
now = datetime.now(timezone.utc)
|
|
|
|
payload = {
|
|
"sub": str(user_id),
|
|
"sid": str(session_id),
|
|
"iat": now,
|
|
"exp": now + timedelta(minutes=ACCESS_TOKEN_MINUTES),
|
|
"type": "access",
|
|
}
|
|
|
|
return jwt.encode(
|
|
payload,
|
|
JWT_SECRET,
|
|
algorithm=JWT_ALGORITHM,
|
|
)
|
|
|
|
|
|
def create_refresh_token() -> tuple[str, str]:
|
|
raw = secrets.token_urlsafe(64)
|
|
|
|
digest = hashlib.sha256(
|
|
raw.encode("utf-8")
|
|
).hexdigest()
|
|
|
|
return raw, digest
|
|
|
|
|
|
def hash_refresh_token(token: str) -> str:
|
|
return hashlib.sha256(
|
|
token.encode("utf-8")
|
|
).hexdigest()
|
|
|
|
|
|
def create_one_time_token() -> tuple[str, str]:
|
|
raw = secrets.token_urlsafe(48)
|
|
return raw, hashlib.sha256(raw.encode("utf-8")).hexdigest()
|
|
|
|
|
|
def hash_one_time_token(token: str) -> str:
|
|
return hashlib.sha256(token.encode("utf-8")).hexdigest()
|
|
|
|
|
|
def refresh_expiry() -> datetime:
|
|
return datetime.now(timezone.utc) + timedelta(
|
|
days=REFRESH_TOKEN_DAYS
|
|
)
|
|
|
|
|
|
def decode_access_token(token: str) -> dict:
|
|
return jwt.decode(
|
|
token,
|
|
JWT_SECRET,
|
|
algorithms=[JWT_ALGORITHM],
|
|
)
|