import os import random from fastapi import FastAPI, HTTPException from fastapi.responses import FileResponse from fastapi.middleware.cors import CORSMiddleware from pydantic import BaseModel from auth_handler import AuthManager app = FastAPI() auth = AuthManager() otp_storage = {} auth._init_db() app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"], ) class AuthData(BaseModel): username: str password: str email: str = None otp: str = None class SessionData(BaseModel): username: str score: int duration: int class EmailData(BaseModel): email: str @app.get("/") async def home(): return FileResponse("index.html") @app.post("/login") async def login(data: AuthData): success, msg = auth.login(data.username, data.password) return {"success": success, "message": msg} @app.post("/signup") async def signup(data: AuthData): success, msg = auth.signup(data.username, data.password, data.email) return {"success": success, "message": msg} @app.post("/send-otp") async def send_otp(data: EmailData): # 1. Generate a random 6-digit code otp_code = str(random.randint(100000, 999999)) # 2. Store it temporarily (or in your DB) # 3. Send it via Brevo success = auth.send_otp_via_brevo(data.email, otp_code) if success: return {"success": True, "message": "OTP Dispatched to Hangar"} else: return {"success": False, "message": "Signal Interrupted (Brevo Error)"} @app.post("/save-session") async def save_session(data: SessionData): # This logs the data to your NEW Supabase project success = auth.save_session(data.username, data.score, data.duration) return {"success": success} @app.get("/session-history/{username}") async def get_history(username: str): rows= auth.get_session_history(username) formatted_data = { "scores": [r[0] for r in rows], # Extract just the scores "labels": [r[1] for r in rows] # Extract just the timestamps } return formatted_data @app.post("/request-reset") async def request_reset(data: EmailData): email = data.email # Check if the pilot actually exists in Supabase if not auth.email_exists(email): return {"success": False, "message": "Callsign not found in deep space logs."} # Generate a code and store it in memory otp = str(random.randint(100000, 999999)) otp_storage[email] = otp # Dispatch via Brevo success = auth.send_otp_via_brevo(email, otp) if success: return {"success": True, "message": "Verification code dispatched to your hangar!"} else: return {"success": False, "message": "Comms failure: Brevo link interrupted."} @app.post("/confirm-reset") async def confirm_reset(data: AuthData): email = data.email otp = data.otp # 1. Verify the code matches what we stored if otp_storage.get(email) != otp: return {"success": False, "message": "Invalid code. Authorization denied."} # 2. Update the password in Supabase success, msg = auth.reset_password(email, data.username, data.password) if success: del otp_storage[email] # Clear code from memory return {"success": success, "message": msg}