diff --git a/surfsense_backend/app/agents/new_chat/tools/gmail/create_draft.py b/surfsense_backend/app/agents/new_chat/tools/gmail/create_draft.py index 246c7d16f..aed5669fb 100644 --- a/surfsense_backend/app/agents/new_chat/tools/gmail/create_draft.py +++ b/surfsense_backend/app/agents/new_chat/tools/gmail/create_draft.py @@ -263,10 +263,29 @@ def create_create_gmail_draft_tool( logger.warning( f"Insufficient permissions for connector {actual_connector_id}: {api_err}" ) + try: + from sqlalchemy.orm.attributes import flag_modified + + _res = await db_session.execute( + select(SearchSourceConnector).where( + SearchSourceConnector.id == actual_connector_id + ) + ) + _conn = _res.scalar_one_or_none() + if _conn and not _conn.config.get("auth_expired"): + _conn.config = {**_conn.config, "auth_expired": True} + flag_modified(_conn, "config") + await db_session.commit() + except Exception: + logger.warning( + "Failed to persist auth_expired for connector %s", + actual_connector_id, + exc_info=True, + ) return { "status": "insufficient_permissions", "connector_id": actual_connector_id, - "message": "This Gmail account needs additional permissions. Please re-authenticate.", + "message": "This Gmail account needs additional permissions. Please re-authenticate in connector settings.", } raise diff --git a/surfsense_backend/app/agents/new_chat/tools/gmail/send_email.py b/surfsense_backend/app/agents/new_chat/tools/gmail/send_email.py index 93c7933a5..dd4d66a57 100644 --- a/surfsense_backend/app/agents/new_chat/tools/gmail/send_email.py +++ b/surfsense_backend/app/agents/new_chat/tools/gmail/send_email.py @@ -264,10 +264,29 @@ def create_send_gmail_email_tool( logger.warning( f"Insufficient permissions for connector {actual_connector_id}: {api_err}" ) + try: + from sqlalchemy.orm.attributes import flag_modified + + _res = await db_session.execute( + select(SearchSourceConnector).where( + SearchSourceConnector.id == actual_connector_id + ) + ) + _conn = _res.scalar_one_or_none() + if _conn and not _conn.config.get("auth_expired"): + _conn.config = {**_conn.config, "auth_expired": True} + flag_modified(_conn, "config") + await db_session.commit() + except Exception: + logger.warning( + "Failed to persist auth_expired for connector %s", + actual_connector_id, + exc_info=True, + ) return { "status": "insufficient_permissions", "connector_id": actual_connector_id, - "message": "This Gmail account needs additional permissions. Please re-authenticate.", + "message": "This Gmail account needs additional permissions. Please re-authenticate in connector settings.", } raise diff --git a/surfsense_backend/app/agents/new_chat/tools/gmail/trash_email.py b/surfsense_backend/app/agents/new_chat/tools/gmail/trash_email.py index 417839bb1..9e8edb47e 100644 --- a/surfsense_backend/app/agents/new_chat/tools/gmail/trash_email.py +++ b/surfsense_backend/app/agents/new_chat/tools/gmail/trash_email.py @@ -254,10 +254,23 @@ def create_trash_gmail_email_tool( logger.warning( f"Insufficient permissions for connector {connector.id}: {api_err}" ) + try: + from sqlalchemy.orm.attributes import flag_modified + + if not connector.config.get("auth_expired"): + connector.config = {**connector.config, "auth_expired": True} + flag_modified(connector, "config") + await db_session.commit() + except Exception: + logger.warning( + "Failed to persist auth_expired for connector %s", + connector.id, + exc_info=True, + ) return { "status": "insufficient_permissions", "connector_id": connector.id, - "message": "This Gmail account needs additional permissions. Please re-authenticate.", + "message": "This Gmail account needs additional permissions. Please re-authenticate in connector settings.", } raise diff --git a/surfsense_backend/app/agents/new_chat/tools/google_calendar/create_event.py b/surfsense_backend/app/agents/new_chat/tools/google_calendar/create_event.py index cf96870df..14a43975c 100644 --- a/surfsense_backend/app/agents/new_chat/tools/google_calendar/create_event.py +++ b/surfsense_backend/app/agents/new_chat/tools/google_calendar/create_event.py @@ -251,12 +251,45 @@ def create_create_calendar_event_tool( {"email": e.strip()} for e in final_attendees if e.strip() ] - created = await asyncio.get_event_loop().run_in_executor( - None, - lambda: service.events() - .insert(calendarId="primary", body=event_body) - .execute(), - ) + try: + created = await asyncio.get_event_loop().run_in_executor( + None, + lambda: service.events() + .insert(calendarId="primary", body=event_body) + .execute(), + ) + except Exception as api_err: + from googleapiclient.errors import HttpError + + if isinstance(api_err, HttpError) and api_err.resp.status == 403: + logger.warning( + f"Insufficient permissions for connector {actual_connector_id}: {api_err}" + ) + try: + from sqlalchemy.orm.attributes import flag_modified + + _res = await db_session.execute( + select(SearchSourceConnector).where( + SearchSourceConnector.id == actual_connector_id + ) + ) + _conn = _res.scalar_one_or_none() + if _conn and not _conn.config.get("auth_expired"): + _conn.config = {**_conn.config, "auth_expired": True} + flag_modified(_conn, "config") + await db_session.commit() + except Exception: + logger.warning( + "Failed to persist auth_expired for connector %s", + actual_connector_id, + exc_info=True, + ) + return { + "status": "insufficient_permissions", + "connector_id": actual_connector_id, + "message": "This Google Calendar account needs additional permissions. Please re-authenticate in connector settings.", + } + raise logger.info( f"Calendar event created: id={created.get('id')}, summary={created.get('summary')}" diff --git a/surfsense_backend/app/agents/new_chat/tools/google_calendar/delete_event.py b/surfsense_backend/app/agents/new_chat/tools/google_calendar/delete_event.py index 3a4570737..04858751f 100644 --- a/surfsense_backend/app/agents/new_chat/tools/google_calendar/delete_event.py +++ b/surfsense_backend/app/agents/new_chat/tools/google_calendar/delete_event.py @@ -230,12 +230,45 @@ def create_delete_calendar_event_tool( None, lambda: build("calendar", "v3", credentials=creds) ) - await asyncio.get_event_loop().run_in_executor( - None, - lambda: service.events() - .delete(calendarId="primary", eventId=final_event_id) - .execute(), - ) + try: + await asyncio.get_event_loop().run_in_executor( + None, + lambda: service.events() + .delete(calendarId="primary", eventId=final_event_id) + .execute(), + ) + except Exception as api_err: + from googleapiclient.errors import HttpError + + if isinstance(api_err, HttpError) and api_err.resp.status == 403: + logger.warning( + f"Insufficient permissions for connector {actual_connector_id}: {api_err}" + ) + try: + from sqlalchemy.orm.attributes import flag_modified + + _res = await db_session.execute( + select(SearchSourceConnector).where( + SearchSourceConnector.id == actual_connector_id + ) + ) + _conn = _res.scalar_one_or_none() + if _conn and not _conn.config.get("auth_expired"): + _conn.config = {**_conn.config, "auth_expired": True} + flag_modified(_conn, "config") + await db_session.commit() + except Exception: + logger.warning( + "Failed to persist auth_expired for connector %s", + actual_connector_id, + exc_info=True, + ) + return { + "status": "insufficient_permissions", + "connector_id": actual_connector_id, + "message": "This Google Calendar account needs additional permissions. Please re-authenticate in connector settings.", + } + raise logger.info( f"Calendar event deleted: event_id={final_event_id}" diff --git a/surfsense_backend/app/agents/new_chat/tools/google_calendar/update_event.py b/surfsense_backend/app/agents/new_chat/tools/google_calendar/update_event.py index 98f20a3c7..505b07f39 100644 --- a/surfsense_backend/app/agents/new_chat/tools/google_calendar/update_event.py +++ b/surfsense_backend/app/agents/new_chat/tools/google_calendar/update_event.py @@ -271,12 +271,45 @@ def create_update_calendar_event_tool( "message": "No changes specified. Please provide at least one field to update.", } - updated = await asyncio.get_event_loop().run_in_executor( - None, - lambda: service.events() - .patch(calendarId="primary", eventId=final_event_id, body=update_body) - .execute(), - ) + try: + updated = await asyncio.get_event_loop().run_in_executor( + None, + lambda: service.events() + .patch(calendarId="primary", eventId=final_event_id, body=update_body) + .execute(), + ) + except Exception as api_err: + from googleapiclient.errors import HttpError + + if isinstance(api_err, HttpError) and api_err.resp.status == 403: + logger.warning( + f"Insufficient permissions for connector {actual_connector_id}: {api_err}" + ) + try: + from sqlalchemy.orm.attributes import flag_modified + + _res = await db_session.execute( + select(SearchSourceConnector).where( + SearchSourceConnector.id == actual_connector_id + ) + ) + _conn = _res.scalar_one_or_none() + if _conn and not _conn.config.get("auth_expired"): + _conn.config = {**_conn.config, "auth_expired": True} + flag_modified(_conn, "config") + await db_session.commit() + except Exception: + logger.warning( + "Failed to persist auth_expired for connector %s", + actual_connector_id, + exc_info=True, + ) + return { + "status": "insufficient_permissions", + "connector_id": actual_connector_id, + "message": "This Google Calendar account needs additional permissions. Please re-authenticate in connector settings.", + } + raise logger.info( f"Calendar event updated: event_id={final_event_id}" diff --git a/surfsense_backend/app/agents/new_chat/tools/google_drive/create_file.py b/surfsense_backend/app/agents/new_chat/tools/google_drive/create_file.py index 7a990c98d..d39e9c640 100644 --- a/surfsense_backend/app/agents/new_chat/tools/google_drive/create_file.py +++ b/surfsense_backend/app/agents/new_chat/tools/google_drive/create_file.py @@ -232,10 +232,29 @@ def create_create_google_drive_file_tool( logger.warning( f"Insufficient permissions for connector {actual_connector_id}: {http_err}" ) + try: + from sqlalchemy.orm.attributes import flag_modified + + _res = await db_session.execute( + select(SearchSourceConnector).where( + SearchSourceConnector.id == actual_connector_id + ) + ) + _conn = _res.scalar_one_or_none() + if _conn and not _conn.config.get("auth_expired"): + _conn.config = {**_conn.config, "auth_expired": True} + flag_modified(_conn, "config") + await db_session.commit() + except Exception: + logger.warning( + "Failed to persist auth_expired for connector %s", + actual_connector_id, + exc_info=True, + ) return { "status": "insufficient_permissions", "connector_id": actual_connector_id, - "message": "This Google Drive account needs additional permissions. Please re-authenticate.", + "message": "This Google Drive account needs additional permissions. Please re-authenticate in connector settings.", } raise diff --git a/surfsense_backend/app/agents/new_chat/tools/google_drive/trash_file.py b/surfsense_backend/app/agents/new_chat/tools/google_drive/trash_file.py index 3fcc2532a..4c037625f 100644 --- a/surfsense_backend/app/agents/new_chat/tools/google_drive/trash_file.py +++ b/surfsense_backend/app/agents/new_chat/tools/google_drive/trash_file.py @@ -207,10 +207,23 @@ def create_delete_google_drive_file_tool( logger.warning( f"Insufficient permissions for connector {connector.id}: {http_err}" ) + try: + from sqlalchemy.orm.attributes import flag_modified + + if not connector.config.get("auth_expired"): + connector.config = {**connector.config, "auth_expired": True} + flag_modified(connector, "config") + await db_session.commit() + except Exception: + logger.warning( + "Failed to persist auth_expired for connector %s", + connector.id, + exc_info=True, + ) return { "status": "insufficient_permissions", "connector_id": connector.id, - "message": "This Google Drive account needs additional permissions. Please re-authenticate.", + "message": "This Google Drive account needs additional permissions. Please re-authenticate in connector settings.", } raise diff --git a/surfsense_backend/app/routes/google_calendar_add_connector_route.py b/surfsense_backend/app/routes/google_calendar_add_connector_route.py index 3f3201043..9a2308bec 100644 --- a/surfsense_backend/app/routes/google_calendar_add_connector_route.py +++ b/surfsense_backend/app/routes/google_calendar_add_connector_route.py @@ -34,7 +34,7 @@ logger = logging.getLogger(__name__) router = APIRouter() -SCOPES = ["https://www.googleapis.com/auth/calendar.readonly"] +SCOPES = ["https://www.googleapis.com/auth/calendar.events"] REDIRECT_URI = config.GOOGLE_CALENDAR_REDIRECT_URI # Initialize security utilities diff --git a/surfsense_backend/app/routes/google_gmail_add_connector_route.py b/surfsense_backend/app/routes/google_gmail_add_connector_route.py index dd8e6bfac..750a64819 100644 --- a/surfsense_backend/app/routes/google_gmail_add_connector_route.py +++ b/surfsense_backend/app/routes/google_gmail_add_connector_route.py @@ -73,7 +73,7 @@ def get_google_flow(): } }, scopes=[ - "https://www.googleapis.com/auth/gmail.readonly", + "https://www.googleapis.com/auth/gmail.modify", "https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile", "openid", diff --git a/surfsense_web/components/tool-ui/gmail/create-draft.tsx b/surfsense_web/components/tool-ui/gmail/create-draft.tsx index c42901a4e..4f1181039 100644 --- a/surfsense_web/components/tool-ui/gmail/create-draft.tsx +++ b/surfsense_web/components/tool-ui/gmail/create-draft.tsx @@ -3,8 +3,6 @@ import { makeAssistantToolUI } from "@assistant-ui/react"; import { CornerDownLeftIcon, - FileEditIcon, - MailIcon, Pen, UserIcon, UsersIcon, @@ -66,10 +64,17 @@ interface AuthErrorResult { connector_type?: string; } +interface InsufficientPermissionsResult { + status: "insufficient_permissions"; + connector_id: number; + message: string; +} + type CreateGmailDraftResult = | InterruptResult | SuccessResult | ErrorResult + | InsufficientPermissionsResult | AuthErrorResult; function isInterruptResult(result: unknown): result is InterruptResult { @@ -99,6 +104,15 @@ function isAuthErrorResult(result: unknown): result is AuthErrorResult { ); } +function isInsufficientPermissionsResult(result: unknown): result is InsufficientPermissionsResult { + return ( + typeof result === "object" && + result !== null && + "status" in result && + (result as InsufficientPermissionsResult).status === "insufficient_permissions" + ); +} + function ApprovalCard({ args, interruptData, @@ -168,7 +182,6 @@ function ApprovalCard({ {/* Header */}
-

{decided === "reject" @@ -388,12 +401,27 @@ function AuthErrorCard({ result }: { result: AuthErrorResult }) { ); } +function InsufficientPermissionsCard({ result }: { result: InsufficientPermissionsResult }) { + return ( +

+
+

+ Additional Gmail permissions required +

+
+
+
+

{result.message}

+
+
+ ); +} + function SuccessCard({ result }: { result: SuccessResult }) { return (
-

{result.message || "Gmail draft created successfully"}

@@ -443,6 +471,8 @@ export const CreateGmailDraftToolUI = makeAssistantToolUI< } if (isAuthErrorResult(result)) return ; + if (isInsufficientPermissionsResult(result)) + return ; if (isErrorResult(result)) return ; return ; diff --git a/surfsense_web/components/tool-ui/gmail/send-email.tsx b/surfsense_web/components/tool-ui/gmail/send-email.tsx index 79697157d..5414fdb71 100644 --- a/surfsense_web/components/tool-ui/gmail/send-email.tsx +++ b/surfsense_web/components/tool-ui/gmail/send-email.tsx @@ -65,10 +65,17 @@ interface AuthErrorResult { connector_type?: string; } +interface InsufficientPermissionsResult { + status: "insufficient_permissions"; + connector_id: number; + message: string; +} + type SendGmailEmailResult = | InterruptResult | SuccessResult | ErrorResult + | InsufficientPermissionsResult | AuthErrorResult; function isInterruptResult(result: unknown): result is InterruptResult { @@ -98,6 +105,15 @@ function isAuthErrorResult(result: unknown): result is AuthErrorResult { ); } +function isInsufficientPermissionsResult(result: unknown): result is InsufficientPermissionsResult { + return ( + typeof result === "object" && + result !== null && + "status" in result && + (result as InsufficientPermissionsResult).status === "insufficient_permissions" + ); +} + function ApprovalCard({ args, interruptData, @@ -387,6 +403,22 @@ function AuthErrorCard({ result }: { result: AuthErrorResult }) { ); } +function InsufficientPermissionsCard({ result }: { result: InsufficientPermissionsResult }) { + return ( +
+
+

+ Additional Gmail permissions required +

+
+
+
+

{result.message}

+
+
+ ); +} + function SuccessCard({ result }: { result: SuccessResult }) { return (
@@ -442,6 +474,8 @@ export const SendGmailEmailToolUI = makeAssistantToolUI< } if (isAuthErrorResult(result)) return ; + if (isInsufficientPermissionsResult(result)) + return ; if (isErrorResult(result)) return ; return ; diff --git a/surfsense_web/components/tool-ui/gmail/trash-email.tsx b/surfsense_web/components/tool-ui/gmail/trash-email.tsx index bffed373c..2becf5dcc 100644 --- a/surfsense_web/components/tool-ui/gmail/trash-email.tsx +++ b/surfsense_web/components/tool-ui/gmail/trash-email.tsx @@ -72,11 +72,18 @@ interface AuthErrorResult { connector_type?: string; } +interface InsufficientPermissionsResult { + status: "insufficient_permissions"; + connector_id: number; + message: string; +} + type TrashGmailEmailResult = | InterruptResult | SuccessResult | ErrorResult | NotFoundResult + | InsufficientPermissionsResult | AuthErrorResult; function isInterruptResult(result: unknown): result is InterruptResult { @@ -115,6 +122,15 @@ function isAuthErrorResult(result: unknown): result is AuthErrorResult { ); } +function isInsufficientPermissionsResult(result: unknown): result is InsufficientPermissionsResult { + return ( + typeof result === "object" && + result !== null && + "status" in result && + (result as InsufficientPermissionsResult).status === "insufficient_permissions" + ); +} + function formatDate(dateStr: string): string { return new Date(dateStr).toLocaleDateString(undefined, { dateStyle: "medium" }); } @@ -318,6 +334,22 @@ function AuthErrorCard({ result }: { result: AuthErrorResult }) { ); } +function InsufficientPermissionsCard({ result }: { result: InsufficientPermissionsResult }) { + return ( +
+
+

+ Additional Gmail permissions required +

+
+
+
+

{result.message}

+
+
+ ); +} + function NotFoundCard({ result }: { result: NotFoundResult }) { return (
@@ -398,6 +430,8 @@ export const TrashGmailEmailToolUI = makeAssistantToolUI< } if (isAuthErrorResult(result)) return ; + if (isInsufficientPermissionsResult(result)) + return ; if (isNotFoundResult(result)) return ; if (isErrorResult(result)) return ; diff --git a/surfsense_web/components/tool-ui/google-calendar/create-event.tsx b/surfsense_web/components/tool-ui/google-calendar/create-event.tsx index 08c098e99..fcf8f804f 100644 --- a/surfsense_web/components/tool-ui/google-calendar/create-event.tsx +++ b/surfsense_web/components/tool-ui/google-calendar/create-event.tsx @@ -74,10 +74,17 @@ interface AuthErrorResult { connector_type?: string; } +interface InsufficientPermissionsResult { + status: "insufficient_permissions"; + connector_id: number; + message: string; +} + type CreateCalendarEventResult = | InterruptResult | SuccessResult | ErrorResult + | InsufficientPermissionsResult | AuthErrorResult; function isInterruptResult(result: unknown): result is InterruptResult { @@ -107,6 +114,15 @@ function isAuthErrorResult(result: unknown): result is AuthErrorResult { ); } +function isInsufficientPermissionsResult(result: unknown): result is InsufficientPermissionsResult { + return ( + typeof result === "object" && + result !== null && + "status" in result && + (result as InsufficientPermissionsResult).status === "insufficient_permissions" + ); +} + function formatDateTime(iso: string): string { try { return new Date(iso).toLocaleString(undefined, { @@ -478,6 +494,22 @@ function AuthErrorCard({ result }: { result: AuthErrorResult }) { ); } +function InsufficientPermissionsCard({ result }: { result: InsufficientPermissionsResult }) { + return ( +
+
+

+ Additional Google Calendar permissions required +

+
+
+
+

{result.message}

+
+
+ ); +} + function SuccessCard({ result }: { result: SuccessResult }) { return (
@@ -552,6 +584,8 @@ export const CreateCalendarEventToolUI = makeAssistantToolUI< } if (isAuthErrorResult(result)) return ; + if (isInsufficientPermissionsResult(result)) + return ; if (isErrorResult(result)) return ; return ; diff --git a/surfsense_web/components/tool-ui/google-calendar/delete-event.tsx b/surfsense_web/components/tool-ui/google-calendar/delete-event.tsx index 590e2d99e..ce7b9ec8f 100644 --- a/surfsense_web/components/tool-ui/google-calendar/delete-event.tsx +++ b/surfsense_web/components/tool-ui/google-calendar/delete-event.tsx @@ -81,12 +81,19 @@ interface AuthErrorResult { connector_type?: string; } +interface InsufficientPermissionsResult { + status: "insufficient_permissions"; + connector_id: number; + message: string; +} + type DeleteCalendarEventResult = | InterruptResult | SuccessResult | ErrorResult | NotFoundResult | WarningResult + | InsufficientPermissionsResult | AuthErrorResult; function isInterruptResult(result: unknown): result is InterruptResult { @@ -125,6 +132,15 @@ function isAuthErrorResult(result: unknown): result is AuthErrorResult { ); } +function isInsufficientPermissionsResult(result: unknown): result is InsufficientPermissionsResult { + return ( + typeof result === "object" && + result !== null && + "status" in result && + (result as InsufficientPermissionsResult).status === "insufficient_permissions" + ); +} + function isWarningResult(result: unknown): result is WarningResult { return ( typeof result === "object" && @@ -355,6 +371,22 @@ function AuthErrorCard({ result }: { result: AuthErrorResult }) { ); } +function InsufficientPermissionsCard({ result }: { result: InsufficientPermissionsResult }) { + return ( +
+
+

+ Additional Google Calendar permissions required +

+
+
+
+

{result.message}

+
+
+ ); +} + function NotFoundCard({ result }: { result: NotFoundResult }) { return (
@@ -452,6 +484,8 @@ export const DeleteCalendarEventToolUI = makeAssistantToolUI< if (isNotFoundResult(result)) return ; if (isWarningResult(result)) return ; if (isAuthErrorResult(result)) return ; + if (isInsufficientPermissionsResult(result)) + return ; if (isErrorResult(result)) return ; return ; diff --git a/surfsense_web/components/tool-ui/google-calendar/update-event.tsx b/surfsense_web/components/tool-ui/google-calendar/update-event.tsx index 7629b9821..5fc72f6f4 100644 --- a/surfsense_web/components/tool-ui/google-calendar/update-event.tsx +++ b/surfsense_web/components/tool-ui/google-calendar/update-event.tsx @@ -79,11 +79,18 @@ interface AuthErrorResult { connector_type?: string; } +interface InsufficientPermissionsResult { + status: "insufficient_permissions"; + connector_id: number; + message: string; +} + type UpdateCalendarEventResult = | InterruptResult | SuccessResult | ErrorResult | NotFoundResult + | InsufficientPermissionsResult | AuthErrorResult; function isInterruptResult(result: unknown): result is InterruptResult { @@ -122,6 +129,15 @@ function isAuthErrorResult(result: unknown): result is AuthErrorResult { ); } +function isInsufficientPermissionsResult(result: unknown): result is InsufficientPermissionsResult { + return ( + typeof result === "object" && + result !== null && + "status" in result && + (result as InsufficientPermissionsResult).status === "insufficient_permissions" + ); +} + function formatDateTime(iso: string): string { try { return new Date(iso).toLocaleString(undefined, { @@ -501,6 +517,22 @@ function AuthErrorCard({ result }: { result: AuthErrorResult }) { ); } +function InsufficientPermissionsCard({ result }: { result: InsufficientPermissionsResult }) { + return ( +
+
+

+ Additional Google Calendar permissions required +

+
+
+
+

{result.message}

+
+
+ ); +} + function NotFoundCard({ result }: { result: NotFoundResult }) { return (
@@ -595,6 +627,8 @@ export const UpdateCalendarEventToolUI = makeAssistantToolUI< if (isNotFoundResult(result)) return ; if (isAuthErrorResult(result)) return ; + if (isInsufficientPermissionsResult(result)) + return ; if (isErrorResult(result)) return ; return ; diff --git a/surfsense_web/components/tool-ui/google-drive/create-file.tsx b/surfsense_web/components/tool-ui/google-drive/create-file.tsx index 801223106..aa2eb9eee 100644 --- a/surfsense_web/components/tool-ui/google-drive/create-file.tsx +++ b/surfsense_web/components/tool-ui/google-drive/create-file.tsx @@ -2,15 +2,11 @@ import { makeAssistantToolUI } from "@assistant-ui/react"; import { - AlertTriangleIcon, CornerDownLeftIcon, FileIcon, Pen, - RefreshCwIcon, } from "lucide-react"; -import { useParams } from "next/navigation"; import { useCallback, useEffect, useMemo, useState } from "react"; -import { toast } from "sonner"; import { Button } from "@/components/ui/button"; import { Select, @@ -21,7 +17,6 @@ import { } from "@/components/ui/select"; import { PlateEditor } from "@/components/editor/plate-editor"; import { TextShimmerLoader } from "@/components/prompt-kit/loader"; -import { authenticatedFetch } from "@/lib/auth-utils"; import { useSetAtom } from "jotai"; import { openHitlEditPanelAtom } from "@/atoms/chat/hitl-edit-panel.atom"; @@ -414,52 +409,16 @@ function ApprovalCard({ } function InsufficientPermissionsCard({ result }: { result: InsufficientPermissionsResult }) { - const params = useParams(); - const searchSpaceId = params.search_space_id as string; - const [loading, setLoading] = useState(false); - - async function handleReauth() { - setLoading(true); - try { - const backendUrl = process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL || "http://localhost:8000"; - const url = new URL(`${backendUrl}/api/v1/auth/google/drive/connector/reauth`); - url.searchParams.set("connector_id", String(result.connector_id)); - url.searchParams.set("space_id", searchSpaceId); - url.searchParams.set("return_url", window.location.pathname); - const response = await authenticatedFetch(url.toString()); - if (!response.ok) { - const data = await response.json().catch(() => ({})); - toast.error(data.detail ?? "Failed to initiate re-authentication. Please try again."); - return; - } - const data = await response.json(); - if (data.auth_url) { - window.location.href = data.auth_url; - } - } catch { - toast.error("Failed to initiate re-authentication. Please try again."); - } finally { - setLoading(false); - } - } - return ( -
+
-
- -

- Additional permissions required -

-
+

+ Additional Google Drive permissions required +

-
-
+
+

{result.message}

-
); diff --git a/surfsense_web/components/tool-ui/google-drive/trash-file.tsx b/surfsense_web/components/tool-ui/google-drive/trash-file.tsx index 3eb8651b8..f9fc4c266 100644 --- a/surfsense_web/components/tool-ui/google-drive/trash-file.tsx +++ b/surfsense_web/components/tool-ui/google-drive/trash-file.tsx @@ -2,19 +2,14 @@ import { makeAssistantToolUI } from "@assistant-ui/react"; import { - AlertTriangleIcon, CornerDownLeftIcon, InfoIcon, - RefreshCwIcon, TriangleAlertIcon, } from "lucide-react"; -import { useParams } from "next/navigation"; import { useCallback, useEffect, useState } from "react"; -import { toast } from "sonner"; import { Button } from "@/components/ui/button"; import { Checkbox } from "@/components/ui/checkbox"; import { TextShimmerLoader } from "@/components/prompt-kit/loader"; -import { authenticatedFetch } from "@/lib/auth-utils"; interface GoogleDriveAccount { id: number; @@ -327,52 +322,16 @@ function ApprovalCard({ } function InsufficientPermissionsCard({ result }: { result: InsufficientPermissionsResult }) { - const params = useParams(); - const searchSpaceId = params.search_space_id as string; - const [loading, setLoading] = useState(false); - - async function handleReauth() { - setLoading(true); - try { - const backendUrl = process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL || "http://localhost:8000"; - const url = new URL(`${backendUrl}/api/v1/auth/google/drive/connector/reauth`); - url.searchParams.set("connector_id", String(result.connector_id)); - url.searchParams.set("space_id", searchSpaceId); - url.searchParams.set("return_url", window.location.pathname); - const response = await authenticatedFetch(url.toString()); - if (!response.ok) { - const data = await response.json().catch(() => ({})); - toast.error(data.detail ?? "Failed to initiate re-authentication. Please try again."); - return; - } - const data = await response.json(); - if (data.auth_url) { - window.location.href = data.auth_url; - } - } catch { - toast.error("Failed to initiate re-authentication. Please try again."); - } finally { - setLoading(false); - } - } - return ( -
+
-
- -

- Additional permissions required -

-
+

+ Additional Google Drive permissions required +

-
-
+
+

{result.message}

-
);