mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-09-22 17:44:53 +02:00
Closes the loop on the Twitter MCP: instead of pointing operators at `python -m backend.apps.twitter.import_cookies`, the Tools page now has a Slack-style "Sign in with X" button that opens an Electron BrowserWindow at x.com, waits for a real sign-in, scrapes auth_token + ct0 from the (HttpOnly) cookie jar, and POSTs them to a new backend route that plugs them into the live pool. - electron/main.js: new `connect-twitter` IPC handler. Mirrors `connect-slack` but reads cookies via session.cookies.get() since auth_token/ct0 are HttpOnly (executeJavaScript on document.cookie returns nothing). Guards against the pre-auth ct0 by requiring the popup URL to have left /i/flow/login and auth_token.length > 20. - electron/preload.js: expose `connectTwitter` on the openswarm bridge. - backend/apps/twitter/models.py: `CookieImportRequest` — auth_token + ct0 with strip/non-empty validator, optional id/handle for in-place re-login, optional label/role. - backend/apps/twitter/twitter.py: `POST /accounts/import`. HTTP sibling of import_cookies.py — same on-disk format via the shared `_write_cookies` helper, but hydrates the live AccountPool and runs an inline `_verify_account` so the UI gets the verified state in one round-trip. Re-login by id or handle reuses the existing record; failed verify returns 200 with a downgraded state (needs_relogin / locked / suspended), never echoes cookies in the response. - frontend/src/app/pages/Tools/Tools.tsx: Twitter integration entry + `handleTwitterAutoConnect`. Generalizes the Slack-only dialog branching into a `browserAuthHandlers` lookup so future in-app auth flows are one entry, not a third hardcoded id === 'slack' check. - tests/test_twitter_routes.py: covers happy path (cookies on disk 0o600, pool size 1), idempotent re-login by id, dedupe by handle, 422 on empty/whitespace tokens, the no-cookie-echo contract, and the verify-failure → state=needs_relogin degraded path. Uses a patched twikit.Client so nothing actually hits x.com.