from fastapi import APIRouter, HTTPException, Request from pydantic import BaseModel from app.services.auth_service import get_user_for_session from app.services.auto_login_service import ( delete_auto_login_credentials, execute_auto_login, get_auto_login_status, save_auto_login_credentials, ) router = APIRouter(prefix="/api/auto-login") def _require_user(request: Request): session_id = request.cookies.get("session_id") if not session_id: raise HTTPException(status_code=401, detail="Not authenticated") user = get_user_for_session(session_id) if not user: raise HTTPException(status_code=401, detail="Not authenticated") return user class AutoLoginSetupRequest(BaseModel): zerodha_login_id: str password: str totp_secret: str @router.post("/setup") async def setup_auto_login(payload: AutoLoginSetupRequest, request: Request): user = _require_user(request) if not payload.zerodha_login_id.strip(): raise HTTPException(status_code=400, detail="Zerodha login ID is required") if not payload.password: raise HTTPException(status_code=400, detail="Password is required") totp_clean = payload.totp_secret.strip().replace(" ", "") if len(totp_clean) < 16: raise HTTPException(status_code=400, detail="TOTP secret must be at least 16 characters") save_auto_login_credentials( user_id=user["id"], zerodha_login_id=payload.zerodha_login_id.strip(), password=payload.password, totp_secret=totp_clean, ) # Immediately test the credentials with a live login attempt result = execute_auto_login(user_id=user["id"], email=user["username"]) if not result["success"]: # Roll back — bad credentials shouldn't be saved delete_auto_login_credentials(user["id"]) raise HTTPException( status_code=400, detail=f"Credentials saved but login test failed: {result.get('error', 'Unknown error')}. " "Please check your Zerodha login ID, password, and TOTP secret.", ) return {"configured": True, "message": "Auto-login set up and verified successfully"} @router.get("/status") async def auto_login_status(request: Request): user = _require_user(request) return get_auto_login_status(user["id"]) @router.delete("/setup") async def remove_auto_login(request: Request): user = _require_user(request) delete_auto_login_credentials(user["id"]) return {"configured": False, "message": "Auto-login credentials removed"} @router.post("/trigger") async def trigger_auto_login(request: Request): """Manually trigger an immediate token refresh.""" user = _require_user(request) status = get_auto_login_status(user["id"]) if not status.get("configured"): raise HTTPException(status_code=400, detail="Auto-login is not configured") result = execute_auto_login(user_id=user["id"], email=user["username"]) if not result["success"]: raise HTTPException(status_code=502, detail=result.get("error", "Auto-login failed")) return {"success": True, "message": "Zerodha session refreshed successfully"}