@router.get("/google/callback") async def google_callback(request: Request, code: str = "", state: str = "", error: str = "", db: AsyncSession = Depends(get_db)): """Handle Google's response: verify state, exchange code for tokens, store encrypted.""" from app.models import GmailAccount, OAuthClientConfig, OAuthToken if error: return HTMLResponse(f"
{str(e)[:500]}")
# 4) identify the Gmail address that authorized
try:
userinfo = gmail_service.get_userinfo(tokens["access_token"])
gmail_email = userinfo.get("email", "").lower()
except Exception as e:
raise HTTPException(502, f"Could not fetch userinfo: {e}")
if not gmail_email:
raise HTTPException(502, "Google did not return an email address")
# 5) persist account + encrypted tokens
account = (await db.execute(select(GmailAccount)
.where(GmailAccount.user_id == user_id,
GmailAccount.email == gmail_email))).scalar_one_or_none()
from datetime import timedelta as _td
expires_at = datetime.now(timezone.utc) + _td(seconds=int(tokens.get("expires_in", 3600)))
if account:
account.status = "authorized"
account.sending_method = account.sending_method or "api"
account.token_expiry = expires_at
if account.oauth_token: