@router.post("/logout")
async def logout(response: Response):
    response.delete_cookie(settings.SESSION_COOKIE_NAME)
    response.delete_cookie(settings.CSRF_COOKIE_NAME)
    return {"ok": True}


@router.get("/me")
async def me(user=Depends(get_current_user)):
    return {"id": user.id, "email": user.email, "full_name": user.full_name,
            "is_admin": user.is_admin}


# ---------------------------------------------------------------------------
# Google OAuth 2.0 (authorization code flow with state verification)
# ---------------------------------------------------------------------------
async def google_start_impl(user):
    """Shared implementation: generate state, persist, return Google's authorization URL."""
    client = gmail_service.resolve_client_config()
    state = gmail_service.generate_state()
    if _oauth_redis is not None:
        _oauth_redis.setex(f"oauthstate:{state}", 600, json.dumps({"user_id": user.id}))
    else:
        _pending_oauth_states[state] = {"user_id": user.id}
    auth_url = gmail_service.build_authorization_url(client, state)
    return {"authorization_url": auth_url}


_pending_oauth_states: dict = {}


@router.get("/google/start")
async def google_start(request: Request, user=Depends(get_current_user)):
    return await google_start_impl(user)


@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"<h3>Google authorization failed: {error}</h3>"
                            f"<p><a href='{settings.FRONTEND_BASE_URL}/gmail-accounts.html'>Back</a></p>")
    if not code or not state:
        raise HTTPException(400, "Missing code or state")

    # 1) verify state (CSRF protection of OAuth handshake)
    user_id = None
    if _oauth_redis is not None:
        raw = _oauth_redis.get(f"oauthstate:{state}")
        if not raw:
            raise HTTPException(400, "Invalid or expired OAuth state")
        data = json.loads(raw)
        _oauth_redis.delete(f"oauthstate:{state}")
===FRONTEND-LOGOUT===
static/js/app.js:216:  try { await POST("/auth/logout"); } catch {}
