# app/core/preview_token.py """ Signed preview tokens for POC site previews. Generates time-limited JWT tokens that allow viewing storefront pages for stores without active subscriptions (POC sites). The token is validated by StorefrontAccessMiddleware to bypass the subscription gate. """ import logging from datetime import UTC, datetime, timedelta from jose import JWTError, jwt from app.core.config import settings logger = logging.getLogger(__name__) PREVIEW_TOKEN_HOURS = 24 ALGORITHM = "HS256" def create_preview_token(store_id: int, store_code: str, site_id: int) -> str: """Create a signed preview token for a POC site. Token is valid for PREVIEW_TOKEN_HOURS (default 24h) and is tied to a specific store_id. Shareable with clients for preview access. """ payload = { "sub": f"preview:{store_id}", "store_id": store_id, "store_code": store_code, "site_id": site_id, "preview": True, "exp": datetime.now(UTC) + timedelta(hours=PREVIEW_TOKEN_HOURS), "iat": datetime.now(UTC), } return jwt.encode(payload, settings.jwt_secret_key, algorithm=ALGORITHM) def verify_preview_token(token: str, store_id: int) -> bool: """Verify a preview token is valid and matches the store. Returns True if: - Token signature is valid - Token has not expired - Token has preview=True claim - Token store_id matches the requested store """ try: payload = jwt.decode(token, settings.jwt_secret_key, algorithms=[ALGORITHM]) return payload.get("preview") is True and payload.get("store_id") == store_id except JWTError: return False