SIMPLE_AI / auth.py
tiahchia's picture
Update auth.py
a772ebc verified
import os
from typing import Any, Dict, Optional, Tuple
import requests
from flask import Blueprint, jsonify, request
import db
auth_blueprint = Blueprint("auth", __name__)
SUPABASE_URL = os.getenv("SUPABASE_URL")
SUPABASE_ANON_KEY = os.getenv("SUPABASE_ANON_KEY")
SUPABASE_SERVICE_ROLE_KEY = os.getenv("SUPABASE_SERVICE_ROLE_KEY")
if not SUPABASE_URL or not SUPABASE_ANON_KEY or not SUPABASE_SERVICE_ROLE_KEY:
raise RuntimeError("Supabase credentials (URL, ANON key, service role key) must be configured.")
AUTH_BASE = f"{SUPABASE_URL}/auth/v1"
def _extract_token_from_header() -> Optional[str]:
auth_header = request.headers.get("Authorization", "")
if not auth_header.startswith("Bearer "):
return None
return auth_header.split(" ", maxsplit=1)[1].strip()
def _fetch_supabase_user(accessToken: str) -> Tuple[Optional[Dict[str, Any]], Optional[Tuple[str, int]]]:
"""Validate the Supabase access token and return the user payload."""
response = requests.get(
f"{AUTH_BASE}/user",
headers={
"Authorization": f"Bearer {accessToken}",
"apikey": SUPABASE_ANON_KEY,
},
timeout=10,
)
if response.status_code != 200:
return None, ("Invalid Supabase access token.", 401)
return response.json(), None
def verify_request_token() -> Tuple[Optional[Dict[str, Any]], Optional[Tuple[str, int]]]:
token = _extract_token_from_header()
if not token:
return None, ("Authorization header missing or invalid.", 401)
return _fetch_supabase_user(token)
@auth_blueprint.route("/session", methods=["GET"])
def session_info():
"""Return the Supabase-authenticated user profile."""
user_payload, error = verify_request_token()
if error:
message, status = error
return jsonify({"error": message}), status
user_id = user_payload.get("id")
profile = db.get_user_profile(user_id)
return jsonify({"user": user_payload, "profile": profile})