mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-07-22 23:31:12 +02:00
chore: linting
This commit is contained in:
parent
0a012dbc79
commit
ce952d2ad1
127 changed files with 821 additions and 517 deletions
|
|
@ -1,8 +1,9 @@
|
|||
from fastapi import APIRouter, Depends
|
||||
|
||||
from app.automations.api import router as automations_router
|
||||
from app.gateway import require_gateway_enabled
|
||||
from app.file_storage.api import router as file_storage_router
|
||||
from app.gateway import require_gateway_enabled
|
||||
from app.notifications.api import router as notifications_router
|
||||
|
||||
from .agent_action_log_route import router as agent_action_log_router
|
||||
from .agent_flags_route import router as agent_flags_router
|
||||
|
|
@ -46,7 +47,6 @@ from .model_list_routes import router as model_list_router
|
|||
from .new_chat_routes import router as new_chat_router
|
||||
from .new_llm_config_routes import router as new_llm_config_router
|
||||
from .notes_routes import router as notes_router
|
||||
from app.notifications.api import router as notifications_router
|
||||
from .notion_add_connector_route import router as notion_add_connector_router
|
||||
from .obsidian_plugin_routes import router as obsidian_plugin_router
|
||||
from .onedrive_add_connector_route import router as onedrive_add_connector_router
|
||||
|
|
@ -76,8 +76,12 @@ router.include_router(documents_router)
|
|||
router.include_router(folders_router)
|
||||
_gateway_enabled_dep = [Depends(require_gateway_enabled)]
|
||||
router.include_router(gateway_router, dependencies=_gateway_enabled_dep)
|
||||
router.include_router(gateway_whatsapp_webhook_router, dependencies=_gateway_enabled_dep)
|
||||
router.include_router(gateway_whatsapp_baileys_router, dependencies=_gateway_enabled_dep)
|
||||
router.include_router(
|
||||
gateway_whatsapp_webhook_router, dependencies=_gateway_enabled_dep
|
||||
)
|
||||
router.include_router(
|
||||
gateway_whatsapp_baileys_router, dependencies=_gateway_enabled_dep
|
||||
)
|
||||
router.include_router(notes_router)
|
||||
router.include_router(new_chat_router) # Chat with assistant-ui persistence
|
||||
router.include_router(agent_revert_router) # POST /threads/{id}/revert/{action_id}
|
||||
|
|
|
|||
|
|
@ -119,21 +119,35 @@ def _discord_redirect_uri() -> str:
|
|||
return f"{base.rstrip('/')}/api/v1/gateway/discord/callback"
|
||||
|
||||
|
||||
def _slack_frontend_redirect(space_id: int, *, success: bool = False, error: str | None = None) -> RedirectResponse:
|
||||
qs = "slack_gateway=connected" if success else f"error={error or 'slack_gateway_failed'}"
|
||||
def _slack_frontend_redirect(
|
||||
space_id: int, *, success: bool = False, error: str | None = None
|
||||
) -> RedirectResponse:
|
||||
qs = (
|
||||
"slack_gateway=connected"
|
||||
if success
|
||||
else f"error={error or 'slack_gateway_failed'}"
|
||||
)
|
||||
return RedirectResponse(
|
||||
url=f"{config.NEXT_FRONTEND_URL}/dashboard/{space_id}/user-settings?{qs}"
|
||||
)
|
||||
|
||||
|
||||
def _discord_frontend_redirect(space_id: int, *, success: bool = False, error: str | None = None) -> RedirectResponse:
|
||||
qs = "discord_gateway=connected" if success else f"error={error or 'discord_gateway_failed'}"
|
||||
def _discord_frontend_redirect(
|
||||
space_id: int, *, success: bool = False, error: str | None = None
|
||||
) -> RedirectResponse:
|
||||
qs = (
|
||||
"discord_gateway=connected"
|
||||
if success
|
||||
else f"error={error or 'discord_gateway_failed'}"
|
||||
)
|
||||
return RedirectResponse(
|
||||
url=f"{config.NEXT_FRONTEND_URL}/dashboard/{space_id}/user-settings?{qs}"
|
||||
)
|
||||
|
||||
|
||||
def verify_slack_signature(*, signing_secret: str, timestamp: str | None, signature: str | None, body: bytes) -> bool:
|
||||
def verify_slack_signature(
|
||||
*, signing_secret: str, timestamp: str | None, signature: str | None, body: bytes
|
||||
) -> bool:
|
||||
if not signing_secret or not timestamp or not signature:
|
||||
return False
|
||||
try:
|
||||
|
|
@ -239,7 +253,9 @@ async def install_slack_gateway(
|
|||
session: AsyncSession = Depends(get_async_session),
|
||||
) -> dict[str, str]:
|
||||
if not _slack_gateway_enabled():
|
||||
raise HTTPException(status_code=500, detail="Slack gateway OAuth is not configured")
|
||||
raise HTTPException(
|
||||
status_code=500, detail="Slack gateway OAuth is not configured"
|
||||
)
|
||||
await check_search_space_access(session, user, search_space_id)
|
||||
state = _get_state_manager().generate_secure_state(search_space_id, user.id)
|
||||
auth_params = {
|
||||
|
|
@ -269,11 +285,17 @@ async def slack_gateway_callback(
|
|||
state_data = None
|
||||
|
||||
if error:
|
||||
return _slack_frontend_redirect(space_id or 0, error="slack_gateway_oauth_denied")
|
||||
return _slack_frontend_redirect(
|
||||
space_id or 0, error="slack_gateway_oauth_denied"
|
||||
)
|
||||
if not code or state_data is None:
|
||||
raise HTTPException(status_code=400, detail="Invalid Slack gateway OAuth callback")
|
||||
raise HTTPException(
|
||||
status_code=400, detail="Invalid Slack gateway OAuth callback"
|
||||
)
|
||||
if not _slack_gateway_enabled():
|
||||
raise HTTPException(status_code=500, detail="Slack gateway OAuth is not configured")
|
||||
raise HTTPException(
|
||||
status_code=500, detail="Slack gateway OAuth is not configured"
|
||||
)
|
||||
|
||||
user_id = UUID(state_data["user_id"])
|
||||
token_payload = {
|
||||
|
|
@ -300,7 +322,9 @@ async def slack_gateway_callback(
|
|||
team = token_json.get("team") or {}
|
||||
team_id = team.get("id")
|
||||
if not bot_token or not team_id:
|
||||
raise HTTPException(status_code=400, detail="Slack gateway OAuth returned incomplete data")
|
||||
raise HTTPException(
|
||||
status_code=400, detail="Slack gateway OAuth returned incomplete data"
|
||||
)
|
||||
|
||||
bot_user_id = token_json.get("bot_user_id")
|
||||
app_id = token_json.get("app_id")
|
||||
|
|
@ -388,7 +412,9 @@ async def install_discord_gateway(
|
|||
session: AsyncSession = Depends(get_async_session),
|
||||
) -> dict[str, str]:
|
||||
if not _discord_gateway_enabled():
|
||||
raise HTTPException(status_code=500, detail="Discord gateway OAuth is not configured")
|
||||
raise HTTPException(
|
||||
status_code=500, detail="Discord gateway OAuth is not configured"
|
||||
)
|
||||
await check_search_space_access(session, user, search_space_id)
|
||||
state = _get_state_manager().generate_secure_state(search_space_id, user.id)
|
||||
auth_params = {
|
||||
|
|
@ -420,11 +446,17 @@ async def discord_gateway_callback(
|
|||
state_data = None
|
||||
|
||||
if error:
|
||||
return _discord_frontend_redirect(space_id or 0, error="discord_gateway_oauth_denied")
|
||||
return _discord_frontend_redirect(
|
||||
space_id or 0, error="discord_gateway_oauth_denied"
|
||||
)
|
||||
if not code or state_data is None:
|
||||
raise HTTPException(status_code=400, detail="Invalid Discord gateway OAuth callback")
|
||||
raise HTTPException(
|
||||
status_code=400, detail="Invalid Discord gateway OAuth callback"
|
||||
)
|
||||
if not _discord_gateway_enabled():
|
||||
raise HTTPException(status_code=500, detail="Discord gateway OAuth is not configured")
|
||||
raise HTTPException(
|
||||
status_code=500, detail="Discord gateway OAuth is not configured"
|
||||
)
|
||||
|
||||
user_id = UUID(state_data["user_id"])
|
||||
token_payload = {
|
||||
|
|
@ -535,7 +567,10 @@ async def discord_gateway_callback(
|
|||
elif binding.user_id == user_id:
|
||||
binding.search_space_id = space_id
|
||||
binding.external_username = discord_username or binding.external_username
|
||||
binding.external_metadata = {**(binding.external_metadata or {}), **metadata}
|
||||
binding.external_metadata = {
|
||||
**(binding.external_metadata or {}),
|
||||
**metadata,
|
||||
}
|
||||
|
||||
await session.commit()
|
||||
return _discord_frontend_redirect(space_id, success=True)
|
||||
|
|
@ -614,7 +649,9 @@ async def _resolve_webhook_account(
|
|||
if account is None or account.platform != ExternalChatPlatform.TELEGRAM:
|
||||
raise HTTPException(status_code=404, detail="Gateway account not found")
|
||||
expected_secret = account.webhook_secret or ""
|
||||
if not expected_secret or not hmac.compare_digest(header_secret or "", expected_secret):
|
||||
if not expected_secret or not hmac.compare_digest(
|
||||
header_secret or "", expected_secret
|
||||
):
|
||||
raise HTTPException(status_code=403, detail="Invalid Telegram webhook secret")
|
||||
return account
|
||||
|
||||
|
|
@ -654,7 +691,9 @@ async def telegram_webhook(
|
|||
event_dedupe_key=telegram_event_dedupe_key(update_id),
|
||||
external_event_id=str(update_id),
|
||||
external_message_id=(
|
||||
str(message["message_id"]) if message.get("message_id") is not None else None
|
||||
str(message["message_id"])
|
||||
if message.get("message_id") is not None
|
||||
else None
|
||||
),
|
||||
event_kind=_classify_telegram_event(payload),
|
||||
raw_payload=payload,
|
||||
|
|
@ -739,7 +778,10 @@ async def list_bindings(
|
|||
) -> list[dict[str, Any]]:
|
||||
result = await session.execute(
|
||||
select(ExternalChatBinding, ExternalChatAccount)
|
||||
.join(ExternalChatAccount, ExternalChatBinding.account_id == ExternalChatAccount.id)
|
||||
.join(
|
||||
ExternalChatAccount,
|
||||
ExternalChatBinding.account_id == ExternalChatAccount.id,
|
||||
)
|
||||
.where(ExternalChatBinding.user_id == user.id)
|
||||
)
|
||||
return [
|
||||
|
|
@ -777,13 +819,20 @@ async def list_connections(
|
|||
]
|
||||
if platform is not None:
|
||||
filters.append(ExternalChatAccount.platform == platform)
|
||||
if platform == ExternalChatPlatform.WHATSAPP and active_whatsapp_mode is not None:
|
||||
if (
|
||||
platform == ExternalChatPlatform.WHATSAPP
|
||||
and active_whatsapp_mode is not None
|
||||
):
|
||||
filters.append(ExternalChatAccount.mode == active_whatsapp_mode)
|
||||
else:
|
||||
if not _telegram_gateway_enabled():
|
||||
filters.append(ExternalChatAccount.platform != ExternalChatPlatform.TELEGRAM)
|
||||
filters.append(
|
||||
ExternalChatAccount.platform != ExternalChatPlatform.TELEGRAM
|
||||
)
|
||||
if active_whatsapp_mode is None:
|
||||
filters.append(ExternalChatAccount.platform != ExternalChatPlatform.WHATSAPP)
|
||||
filters.append(
|
||||
ExternalChatAccount.platform != ExternalChatPlatform.WHATSAPP
|
||||
)
|
||||
else:
|
||||
filters.append(
|
||||
or_(
|
||||
|
|
@ -794,7 +843,10 @@ async def list_connections(
|
|||
|
||||
result = await session.execute(
|
||||
select(ExternalChatBinding, ExternalChatAccount)
|
||||
.join(ExternalChatAccount, ExternalChatBinding.account_id == ExternalChatAccount.id)
|
||||
.join(
|
||||
ExternalChatAccount,
|
||||
ExternalChatBinding.account_id == ExternalChatAccount.id,
|
||||
)
|
||||
.where(*filters)
|
||||
)
|
||||
|
||||
|
|
@ -828,7 +880,9 @@ async def list_connections(
|
|||
baileys_account_ids.add(int(account.id))
|
||||
route_type = "account"
|
||||
connection_id = account.id
|
||||
search_space_id = account.owner_search_space_id or binding.search_space_id
|
||||
search_space_id = (
|
||||
account.owner_search_space_id or binding.search_space_id
|
||||
)
|
||||
display_name = "WhatsApp Bridge"
|
||||
|
||||
connections.append(
|
||||
|
|
@ -853,9 +907,8 @@ async def list_connections(
|
|||
}
|
||||
)
|
||||
|
||||
if (
|
||||
active_whatsapp_mode == ExternalChatAccountMode.SELF_HOST_BYO
|
||||
and (platform is None or platform == ExternalChatPlatform.WHATSAPP)
|
||||
if active_whatsapp_mode == ExternalChatAccountMode.SELF_HOST_BYO and (
|
||||
platform is None or platform == ExternalChatPlatform.WHATSAPP
|
||||
):
|
||||
account_result = await session.execute(
|
||||
select(ExternalChatAccount).where(
|
||||
|
|
@ -940,7 +993,9 @@ async def update_binding_search_space(
|
|||
ExternalChatBindingState.BOUND,
|
||||
ExternalChatBindingState.SUSPENDED,
|
||||
}:
|
||||
raise HTTPException(status_code=400, detail="Only active bindings can be routed")
|
||||
raise HTTPException(
|
||||
status_code=400, detail="Only active bindings can be routed"
|
||||
)
|
||||
account = await session.get(ExternalChatAccount, binding.account_id)
|
||||
if account is None or _is_inactive_whatsapp_account(account):
|
||||
raise HTTPException(status_code=404, detail="Binding not found")
|
||||
|
|
@ -1062,4 +1117,3 @@ async def resume_external_chat_binding(
|
|||
binding.updated_at = datetime.now(UTC)
|
||||
await session.commit()
|
||||
return {"ok": True}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,9 @@ class BaileysPairRequest(BaseModel):
|
|||
|
||||
def _ensure_baileys_enabled() -> None:
|
||||
if config.GATEWAY_WHATSAPP_INTAKE_MODE != "baileys":
|
||||
raise HTTPException(status_code=404, detail="WhatsApp Baileys gateway is disabled")
|
||||
raise HTTPException(
|
||||
status_code=404, detail="WhatsApp Baileys gateway is disabled"
|
||||
)
|
||||
if config.is_cloud():
|
||||
raise HTTPException(
|
||||
status_code=403,
|
||||
|
|
|
|||
|
|
@ -79,7 +79,9 @@ async def whatsapp_webhook(
|
|||
|
||||
def _verify_signature(raw_body: bytes, header_signature: str | None) -> None:
|
||||
if not config.WHATSAPP_WEBHOOK_APP_SECRET:
|
||||
raise HTTPException(status_code=500, detail="WhatsApp app secret is not configured")
|
||||
raise HTTPException(
|
||||
status_code=500, detail="WhatsApp app secret is not configured"
|
||||
)
|
||||
received = (header_signature or "").removeprefix("sha256=")
|
||||
expected = hmac.new(
|
||||
config.WHATSAPP_WEBHOOK_APP_SECRET.encode(),
|
||||
|
|
@ -87,7 +89,9 @@ def _verify_signature(raw_body: bytes, header_signature: str | None) -> None:
|
|||
hashlib.sha256,
|
||||
).hexdigest()
|
||||
if not received or not hmac.compare_digest(received, expected):
|
||||
raise HTTPException(status_code=403, detail="Invalid WhatsApp webhook signature")
|
||||
raise HTTPException(
|
||||
status_code=403, detail="Invalid WhatsApp webhook signature"
|
||||
)
|
||||
|
||||
|
||||
async def _process_payload(session: AsyncSession, payload: dict[str, Any]) -> None:
|
||||
|
|
@ -114,7 +118,9 @@ async def _process_messages_change(
|
|||
change: dict[str, Any],
|
||||
value: dict[str, Any],
|
||||
) -> None:
|
||||
statuses = [status for status in value.get("statuses") or [] if isinstance(status, dict)]
|
||||
statuses = [
|
||||
status for status in value.get("statuses") or [] if isinstance(status, dict)
|
||||
]
|
||||
for status in statuses:
|
||||
record_gateway_outbound(
|
||||
platform="whatsapp",
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ from app.db import (
|
|||
User,
|
||||
get_async_session,
|
||||
)
|
||||
from app.notifications.service import NotificationService
|
||||
from app.schemas.obsidian_plugin import (
|
||||
ALLOWED_ATTACHMENT_EXTENSIONS,
|
||||
ATTACHMENT_MIME_TYPES,
|
||||
|
|
@ -43,7 +44,6 @@ from app.schemas.obsidian_plugin import (
|
|||
SyncAckItem,
|
||||
SyncBatchRequest,
|
||||
)
|
||||
from app.notifications.service import NotificationService
|
||||
from app.services.obsidian_plugin_indexer import (
|
||||
delete_note,
|
||||
get_manifest,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue