Files
passkey-auth/passkey/util/tokens.py

45 lines
1.4 KiB
Python

import base64
import hashlib
import secrets
from .passphrase import is_well_formed
def create_token() -> str:
return secrets.token_urlsafe(12) # 16 characters Base64
def session_key(token: str) -> bytes:
if len(token) != 16:
raise ValueError("Session token must be exactly 16 characters long")
return b"sess" + base64.urlsafe_b64decode(token)
def encode_session_key(key: bytes) -> str:
"""Encode an opaque session key for external representation."""
return base64.urlsafe_b64encode(key).decode().rstrip("=")
def decode_session_key(encoded: str) -> bytes:
"""Decode an opaque session key from its public representation."""
if not encoded:
raise ValueError("Invalid session identifier")
padding = "=" * (-len(encoded) % 4)
try:
raw = base64.urlsafe_b64decode(encoded + padding)
except Exception as exc: # pragma: no cover - defensive
raise ValueError("Invalid session identifier") from exc
if not raw.startswith(b"sess"):
raise ValueError("Invalid session identifier")
return raw
def reset_key(passphrase: str) -> bytes:
if not is_well_formed(passphrase):
raise ValueError(
"Trying to reset with a session token in place of a passphrase"
if len(passphrase) == 16
else "Invalid passphrase format"
)
return b"rset" + hashlib.sha512(passphrase.encode()).digest()[:12]