trypost/app
Paulo Castellano 2f4b974130 Fix X token chain breaking from over-rotation
X OAuth2 refresh tokens are single-use: each refresh rotates the pair and
invalidates the previous refresh_token, and reusing a rotated one kills the
whole family. Three things made this fragile and disconnected accounts far
more often than necessary:

- The proactive refresh job called refreshToken() directly, bypassing the
  access-token-first guard in verify() and rotating on every run.
- RefreshExpiringTokens used a 2h window on an hourly schedule — equal to the
  2h access-token lifetime — so every X account was rotated every hour even
  while its token was still valid.
- A single 4xx refresh failure disconnected the account without checking
  whether a concurrent refresh had already persisted a working token.

Changes:
- RefreshSocialToken now routes through verify() (access-token-first), so it
  only rotates when the access_token is actually invalid.
- Shrink the proactive window to 30m and run the command every 15m, so the
  window still covers the run interval but rotation happens near real expiry.
- verify() tolerates the lost-rotation race: on a 4xx refresh, reload and
  verify with a concurrently-refreshed token before marking TokenExpired.

Refs #126
2026-07-02 20:32:55 -03:00
..
Actions fix(workspace): default content_language to the app locale, not 'en' 2026-07-01 13:49:48 -03:00
Ai refactor(ai): introduce GeneratorFormat enum and drop stringly-typed format 2026-06-18 11:11:23 -03:00
Broadcasting feat(automations): implement automation features and UI enhancements 2026-05-24 09:17:19 -03:00
Concerns refactor: settings redesign, Spanish translations, language system, strict_types 2026-03-30 00:20:43 -03:00
Console/Commands Fix X token chain breaking from over-rotation 2026-07-02 20:32:55 -03:00
DataTransferObjects fix(tiktok): resize oversized photos before PULL_FROM_URL 2026-06-26 12:23:56 -03:00
Enums test(onboarding): cover the full flow; drop goal exclusivity rule 2026-06-25 21:01:46 -03:00
Events feat(telegram): surface connect failure in the dialog instead of silent expiry 2026-06-22 09:55:12 -03:00
Exceptions feat: per-workspace pricing, onboarding, and billing overhaul 2026-06-21 20:40:03 -03:00
Helpers fix: correct Upload.php filename case for Linux CI 2026-03-31 12:01:48 -03:00
Http fix(tracking): fire begin_checkout when onboarding checkout starts 2026-07-02 09:21:31 -03:00
Jobs Fix X token chain breaking from over-rotation 2026-07-02 20:32:55 -03:00
Listeners refactor(billing): replace MonthlyCreditsLimit Pennant feature with BillingCycle 2026-06-22 09:55:03 -03:00
Mail feat: @mentions in comments, AI Action layer + MCP tools, settings tabs 2026-05-01 20:59:03 -03:00
Mcp fix(linkedin): align PDF compatibility across editor, MCP schedule, and tests 2026-06-24 17:36:39 -03:00
Models refactor(social): trim verbose comments + harden X chunked upload from review 2026-06-28 20:37:04 -03:00
Observers fix: merge-readiness — close two billing/network bugs, harden tests 2026-06-22 09:26:31 -03:00
Policies refactor(permissions): drop explanatory comments, fix stale PostPolicy docblock 2026-06-22 16:35:27 -03:00
Providers fix(ci): drop unused Pennant feature discovery 2026-06-22 13:09:02 -03:00
Rules refactor(media): centralize image/video/document detection in Media\Type 2026-06-25 10:57:57 -03:00
Services Fix X token chain breaking from over-rotation 2026-07-02 20:32:55 -03:00
Socialite feat(channels): add Discord as a social channel 2026-06-16 14:44:00 -03:00
Support fix(api): roll back hosted media when an inline url batch partially fails 2026-06-28 20:59:21 -03:00