from __future__ import annotations import hmac import secrets def create_download_token(secret: str, job_id: str) -> str: nonce = secrets.token_urlsafe(18) signature = hmac.digest(secret.encode("utf-8"), f"{job_id}:{nonce}".encode("utf-8"), "sha256").hex() return f"{nonce}.{signature}" def verify_download_token(secret: str, job_id: str, token: str | None) -> bool: if not token or "." not in token: return False nonce, signature = token.split(".", 1) expected = hmac.digest(secret.encode("utf-8"), f"{job_id}:{nonce}".encode("utf-8"), "sha256").hex() return hmac.compare_digest(signature, expected)