#!/usr/bin/env python3 """Mint a cf_clearance cookie for miruro.tv and write it into backend/.env. Usage: pip install nodriver python scripts/mint_cf_clearance.py [--domain www.miruro.tv] [--timeout 60] The script opens a real (undetected) Chrome window, lets Cloudflare's JS challenge complete, extracts the `cf_clearance` cookie, and writes/updates `CF_CLEARANCE=` in backend/.env. Notes: * Mint on the SAME machine/network that runs the backend (the cookie is bound to your IP + User-Agent). * If Cloudflare shows an interactive CAPTCHA (Turnstile), solve it in the opened window — the script waits for you. * The cookie expires — re-run periodically. """ from __future__ import annotations import argparse import re import sys import time from pathlib import Path BACKEND_ENV = Path(__file__).resolve().parent.parent / "backend" / ".env" COOKIE_NAME = "cf_clearance" def find_cookie(cookies: list[dict]) -> str | None: for c in cookies: if c.get("name") == COOKIE_NAME: return c.get("value") return None def write_env(domain: str, value: str) -> None: BACKEND_ENV.parent.mkdir(parents=True, exist_ok=True) text = BACKEND_ENV.read_text(encoding="utf-8") if BACKEND_ENV.exists() else "" if not re.search(r"^\s*CF_CLEARANCE\s*=", text, flags=re.MULTILINE): text = text.rstrip() + f"\nCF_CLEARANCE={value}\n" else: text = re.sub( r"^\s*CF_CLEARANCE\s*=.*$", f"CF_CLEARANCE={value}", text, flags=re.MULTILINE, ) BACKEND_ENV.write_text(text, encoding="utf-8") print(f"✔ Wrote CF_CLEARANCE to {BACKEND_ENV} ({len(value)} chars)") def main() -> int: parser = argparse.ArgumentParser(description="Mint a cf_clearance cookie for Miruro") parser.add_argument("--domain", default="www.miruro.tv") parser.add_argument("--timeout", type=int, default=60, help="max seconds to wait") args = parser.parse_args() try: import nodriver as uc except ImportError: print("nodriver is required. Install it with: pip install nodriver") return 1 print(f"Opening {args.domain} in an undetected Chrome window…") print("If a CAPTCHA appears, solve it manually in the window.") async def run(): browser = await uc.start() try: tab = await browser.get(f"https://{args.domain}/") deadline = time.monotonic() + args.timeout while time.monotonic() < deadline: cookies = await tab.cookies.all() value = find_cookie(cookies) if value: write_env(args.domain, value) return 0 time.sleep(2) print(f"✖ No {COOKIE_NAME} cookie within {args.timeout}s. " "Try increasing --timeout or solving an interactive CAPTCHA.") return 1 finally: await browser.stop() try: import asyncio return asyncio.run(run()) except KeyboardInterrupt: print("\nAborted.") return 1 if __name__ == "__main__": sys.exit(main())