""" WyConnect (Sign in with Lee Wyatt Corp) - server-side token verification (Python 3.8+). After the connector delivers a session to your front end, send the access_token to your backend (Authorization: Bearer ) and verify it here before trusting the user. This calls the Lee Wyatt Corp identity provider (Supabase GoTrue) to confirm the token is valid and resolves the real Lee Wyatt Corp user. from verify_token import verify_lwc_token user = verify_lwc_token(token) if not user: # reject with 401 ... # user["id"], user["email"] are trustworthy No service-role or secret key is needed - only the public anon key, which is safe to ship. RLS protects all data on the Lee Wyatt Corp project. Uses only the Python standard library (urllib) so there are no dependencies. """ import json import os import urllib.request import urllib.error LWC_SUPABASE_URL = os.environ.get( "LWC_SUPABASE_URL", "https://cgwxlbenwaiowesagayo.supabase.co" ) LWC_SUPABASE_ANON_KEY = os.environ.get( "LWC_SUPABASE_ANON_KEY", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImNnd3hsYmVud2Fpb3dlc2FnYXlvIiwicm9sZSI6ImFub24iLCJpYXQiOjE3Nzk4NDUyNTMsImV4cCI6MjA5NTQyMTI1M30.2S_ouKEMhhDCk8ZOHtBbuA6zkClc-P4uLm_0pnS9Skk", ) def verify_lwc_token(access_token, timeout=8): """Verify a Lee Wyatt Corp access token. Returns a dict with id/email/display_name/raw, or None if invalid. """ if not access_token or not isinstance(access_token, str): return None token = access_token.strip() if token.lower().startswith("bearer "): token = token[7:].strip() if not token: return None req = urllib.request.Request( LWC_SUPABASE_URL + "/auth/v1/user", headers={ "apikey": LWC_SUPABASE_ANON_KEY, "Authorization": "Bearer " + token, }, ) try: with urllib.request.urlopen(req, timeout=timeout) as resp: if resp.status != 200: return None user = json.loads(resp.read().decode("utf-8")) except (urllib.error.URLError, urllib.error.HTTPError, ValueError, TimeoutError): return None if not user or not user.get("id"): return None meta = user.get("user_metadata") or {} return { "id": user["id"], "email": user.get("email"), "display_name": meta.get("display_name"), "raw": user, }