Files
periscope/backend/services/local_jwt.py
T
michele a63e5bd7ab Fase A identity on PCB HEAD: operator fence, keep BOM/SPOF/EMI.
Replace Faradworks Inc. TOS/privacy/contact/metadata with Michele Bigi.
Dual-read pinscope_* keys; write periscope_* only. AGPL LICENSE and
GitHub fork parent unchanged. validate.py not edited.
2026-09-20 12:41:17 +02:00

50 lines
1.3 KiB
Python

"""Periscope local JWT helpers (HS256)."""
from __future__ import annotations
from datetime import datetime, timedelta, timezone
from typing import Any
import jwt
from backend.config import settings
from backend.pinscope_compat import JWT_ISSUER, READ_JWT_ISSUERS
ALGORITHM = "HS256"
TOKEN_TTL_DAYS = 30
def issue_token(user_id: str, email: str) -> str:
secret = settings.auth_jwt_secret
if not secret:
raise RuntimeError("AUTH_JWT_SECRET is not configured")
now = datetime.now(timezone.utc)
payload = {
"sub": user_id,
"email": email,
"iss": JWT_ISSUER,
"iat": now,
"exp": now + timedelta(days=TOKEN_TTL_DAYS),
}
return jwt.encode(payload, secret, algorithm=ALGORITHM)
def decode_token(token: str) -> dict[str, Any] | None:
secret = settings.auth_jwt_secret
if not secret:
return None
# Dual-read PinScope issuer; never write it (see pinscope_compat).
for issuer in READ_JWT_ISSUERS:
try:
return jwt.decode(
token,
secret,
algorithms=[ALGORITHM],
issuer=issuer,
options={"verify_aud": False},
leeway=10,
)
except jwt.PyJWTError:
continue
return None