Fetch can resolve when headers arrive, so a stalled res.text() hung
outside withTimeout and never rotated accounts. Read and parse the
body inside the timed callback so AbortError retries then rotates.
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
* fix(threads): reject off-origin redirects on account-proxy fetches
Stop fetch from auto-following Location hops with session cookies.
workerd does not implement redirect: 'error', so use manual mode and
only follow same-origin HTTPS targets.
Co-authored-by: dangered wolf <d@ngeredwolf.me>
* fix(instagram): apply same-origin HTTPS redirect policy to account-proxy
Instagram's private API fetch had the same cookie-forwarding default as
Threads. Share fetchSameOriginHttps and use it in both account proxies.
Co-authored-by: dangered wolf <d@ngeredwolf.me>
* test: use an unparseable Location in same-origin redirect coverage
`::::` is a valid relative path against the request URL, so it was not
a useful junk-Location case.
Co-authored-by: dangered wolf <d@ngeredwolf.me>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
* feat: improve APi coverage of instagram / threads
* Update packages/atmosphere/src/providers/threads/private-processor.ts
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* fix(instagram): rotate accounts on private API status=fail (#2391)
* fix(instagram): treat private API status=fail as rotation failure
Parseable 2xx bodies with status: fail (checkpoint, spam block) were
returned as ok: true, which hid empty results and skipped the next
configured account. Match the Threads proxy: mark them failed and rotate.
Co-authored-by: dangered wolf <d@ngeredwolf.me>
* style: prettier Instagram status=fail test fixture
Co-authored-by: dangered wolf <d@ngeredwolf.me>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
* fix(instagram,threads): constrain private-API pages to requested count (#2394)
Pass count through Instagram comments and Threads replies/profile-feed
fetches so next-page cursors match the truncated page instead of skipping
items.
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
* fix(threads): decode search cursors as UTF-8 before JSON.parse (#2395)
b64urlDecode returns an atob binary string. Search queries can contain
non-ASCII text, so convert those bytes with TextDecoder before parsing.
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
* fix(threads): apply request timeout to private API body read (#2396)
* fix(threads): apply request timeout to private API body read
Fetch can resolve once headers arrive, leaving res.text() and JSON.parse
outside withTimeout. Keep both inside the timed operation so a stalled
body aborts, retries, and rotates accounts.
Co-authored-by: dangered wolf <d@ngeredwolf.me>
* fix(threads): drop unused initializers in private API timeout path
Co-authored-by: dangered wolf <d@ngeredwolf.me>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
* fix(threads): reject redirects on cookie-authenticated private API fetches
Do not follow 3xx responses when sending account session cookies, so a
redirect cannot leak credentials to another origin.
Co-authored-by: dangered wolf <d@ngeredwolf.me>
---------
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
* fix(threads): apply request timeout to private API body read
Fetch can resolve once headers arrive, leaving res.text() and JSON.parse
outside withTimeout. Keep both inside the timed operation so a stalled
body aborts, retries, and rotates accounts.
Co-authored-by: dangered wolf <d@ngeredwolf.me>
* fix(threads): drop unused initializers in private API timeout path
Co-authored-by: dangered wolf <d@ngeredwolf.me>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
b64urlDecode returns an atob binary string. Search queries can contain
non-ASCII text, so convert those bytes with TextDecoder before parsing.
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Pass count through Instagram comments and Threads replies/profile-feed
fetches so next-page cursors match the truncated page instead of skipping
items.
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
* fix(instagram): treat private API status=fail as rotation failure
Parseable 2xx bodies with status: fail (checkpoint, spam block) were
returned as ok: true, which hid empty results and skipped the next
configured account. Match the Threads proxy: mark them failed and rotate.
Co-authored-by: dangered wolf <d@ngeredwolf.me>
* style: prettier Instagram status=fail test fixture
Co-authored-by: dangered wolf <d@ngeredwolf.me>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Reject oversized search queries with HTTP 400 before calling X, matching
SearchTimeline's rawQuery limit, and map the upstream length error if it
still appears.
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Telegram can only preview one video in a link card. Instant View already
renders every video in the body when forced via i., but video-only posts
never opted into IV automatically. Turn it on when a post has more than
one video so all clips are reachable from the preview.
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Instagram author profile details are incomplete, so omit the
about-author footer in Instant View the same way we do for Bluesky.
Co-authored-by: Cursor Agent <cursoragent@cursor.com>