diff --git a/server/app/component/auth.py b/server/app/component/auth.py index 292af0fa5..222acf50a 100644 --- a/server/app/component/auth.py +++ b/server/app/component/auth.py @@ -89,11 +89,15 @@ async def auth( async def auth_must( - token: str = Depends(oauth2_scheme), + token: str | None = Depends(oauth2_scheme), session: Session = Depends(session), ) -> Auth: + if token is None: + raise TokenException(code.token_invalid, _("Authentication required")) model = Auth.decode_token(token) user = session.get(User, model.id) + if not user: + raise TokenException(code.token_invalid, _("User not found")) model._user = user return model diff --git a/server/app/controller/chat/history_controller.py b/server/app/controller/chat/history_controller.py index 8cc169b8a..213fdfb07 100644 --- a/server/app/controller/chat/history_controller.py +++ b/server/app/controller/chat/history_controller.py @@ -121,6 +121,7 @@ def list_grouped_chat_history( "tasks": [], "total_completed_tasks": 0, "total_ongoing_tasks": 0, + "total_failed_tasks": 0, "average_tokens_per_task": 0, } ) diff --git a/server/app/controller/mcp/mcp_controller.py b/server/app/controller/mcp/mcp_controller.py index 17e92dc26..bb7842650 100644 --- a/server/app/controller/mcp/mcp_controller.py +++ b/server/app/controller/mcp/mcp_controller.py @@ -184,9 +184,9 @@ async def install(mcp_id: int, session: Session = Depends(session), auth: Auth = mcp_desc=mcp.description, type=mcp.type, status=Status.enable, - command=install_command["command"], - args=install_command["args"], - env=install_command["env"], + command=install_command.get("command"), + args=install_command.get("args", []), + env=install_command.get("env", {}), server_url=None, ) mcp_user.save() diff --git a/server/app/controller/mcp/user_controller.py b/server/app/controller/mcp/user_controller.py index 0d8ca33b8..610e60ac0 100644 --- a/server/app/controller/mcp/user_controller.py +++ b/server/app/controller/mcp/user_controller.py @@ -95,13 +95,14 @@ async def list_mcp_users( @router.get("/mcp/users/{mcp_user_id}", name="get mcp user", response_model=McpUserOut) async def get_mcp_user(mcp_user_id: int, session: Session = Depends(session), auth: Auth = Depends(auth_must)): """Get MCP user details.""" - query = select(McpUser).where(McpUser.id == mcp_user_id) + user_id = auth.user.id + query = select(McpUser).where(McpUser.id == mcp_user_id, McpUser.user_id == user_id) mcp_user = session.exec(query).first() if not mcp_user: - logger.warning("MCP user not found", extra={"user_id": auth.user.id, "mcp_user_id": mcp_user_id}) + logger.warning("MCP user not found", extra={"user_id": user_id, "mcp_user_id": mcp_user_id}) raise HTTPException(status_code=404, detail=_("McpUser not found")) logger.debug( - "MCP user retrieved", extra={"user_id": auth.user.id, "mcp_user_id": mcp_user_id, "mcp_id": mcp_user.mcp_id} + "MCP user retrieved", extra={"user_id": user_id, "mcp_user_id": mcp_user_id, "mcp_id": mcp_user.mcp_id} ) return mcp_user @@ -193,6 +194,13 @@ async def delete_mcp_user(mcp_user_id: int, session: Session = Depends(session), logger.warning("MCP user not found for deletion", extra={"user_id": user_id, "mcp_user_id": mcp_user_id}) raise HTTPException(status_code=404, detail=_("Mcp Info not found")) + if db_mcp_user.user_id != user_id: + logger.warning( + "Unauthorized MCP user deletion", + extra={"user_id": user_id, "mcp_user_id": mcp_user_id, "owner_id": db_mcp_user.user_id}, + ) + raise HTTPException(status_code=403, detail=_("You are not allowed to delete this MCP")) + try: session.delete(db_mcp_user) session.commit() diff --git a/server/app/controller/redirect_controller.py b/server/app/controller/redirect_controller.py index 677af5389..3a770ca2d 100644 --- a/server/app/controller/redirect_controller.py +++ b/server/app/controller/redirect_controller.py @@ -13,6 +13,7 @@ # ========= Copyright 2025-2026 @ Eigent.ai All Rights Reserved. ========= import json +from urllib.parse import quote from fastapi import APIRouter, Request from fastapi.responses import HTMLResponse @@ -25,6 +26,8 @@ def redirect_callback(code: str, request: Request): cookies = request.cookies cookies_json = json.dumps(cookies) + safe_code = quote(code, safe='') + html_content = f""" @@ -72,7 +75,7 @@ def redirect_callback(code: str, request: Request):