KamoCRM

Meeting-provider OAuth state is an opaque one-time Redis token; refresh is locked and committed on its own

FixMediaService
Shipped
October 14, 2026 at 4:16 PM UTC
Author
Kamo
Commit
618ee73

state was base64 JSON {orgId, nonce, provider} built by the caller, the nonce was never stored or checked, and the sessionless callback trusted the decoded orgId - anyone could attach their own Zoom or Microsoft account to another org. MeetingOAuthStateStore now issues a random 64-hex token bound to org, member and provider (10-minute TTL); the callback spends it with GETDEL, one atomic command, so a forged, expired, replayed or concurrent second callback is refused before the provider is called. The redirect-URI lookup peeks. Token refresh had no lock and wrote inside the caller's transaction while Zoom rotates the refresh token on every use: two pods refreshing at once left one holding a revoked token. refreshIfNeeded now takes a Redis lock per (org, provider) (30 s lease, owner-checked release), re-reads the row in a REQUIRES_NEW transaction (a waiter usually finds the winner's fresh grant and never spends the refresh token), and stores the result through MeetingOAuthTokenWriter (REQUIRES_NEW), committed before the lock is freed.

All changes

Like what you see shipping?

All of it arrives in your workspace on its own. Start on the free plan and read this page again in a month.

Start Free ForeverView Pricing