fix(auth): refresh the access token instead of caching it once - #1
Open
emrementese wants to merge 1 commit into
Open
emrementese wants to merge 1 commit into
emrementese wants to merge 1 commit into
Conversation
`auth()` returned a bare `String` and dropped the `Authenticator`, so the
process ran on a single access token for its entire lifetime. Google's
access tokens expire after roughly an hour -- well inside a normal
broadcast -- after which every request fails with `UNAUTHENTICATED`, the
reconnect loop burns its five attempts in seconds and live chat is dead
for the rest of the stream. The refresh token was sitting on disk the
whole time, unusable because the authenticator that owns it was gone.
Keep the `Authenticator` in `YoutubeService` and ask it for a token
before each request. `yup-oauth2` serves the cached token and refreshes
it transparently near expiry, so long broadcasts no longer die.
While in here, three related fixes:
- The `reqwest::Client` carried `Authorization: Bearer <token>` as a
*default header*, and the same client fetches `profileImageUrl` values
taken straight from API responses. That sent the user's OAuth token to
whatever avatar host the payload named. The default header is gone;
auth is attached per-request, to googleapis.com calls only.
- The client had no timeouts at all, so a hung request could stall
forever. Added request and connect timeouts plus a real user agent.
- `auth()` had two panics (`install_default().unwrap()` and
`panic!("Couldn't get oauth token")`); both are now ordinary errors.
Credential files are created with `0600` and the app directory `0700`.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Aug 1, 2026
Author
|
Claude ile repodaki temel problemleri çözdüren bir Pr serisinin ilk aşamasıdır. Pr'lar bir birine bağımlı olduğu için conflict çıkmaması adına reviewlendikten ve test edildikten sonra sırayla merge edilmeli. bunun dısında test için bir CI da yazdirdim. İyi calismalar |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
auth()returned a bareStringand dropped theAuthenticator, so the process ran on a single access token for its entire lifetime. Google's access tokens expire after roughly an hour — well inside a normal broadcast.After that hour, every request fails with
UNAUTHENTICATED, the reconnect loop burns its five attempts in seconds, and live chat is dead for the rest of the stream. The refresh token was sitting on disk the whole time, unusable because the authenticator that owns it was gone.This is the single most likely cause of "chat keeps dropping mid-broadcast": it works at first, then dies and never comes back.
Fix
Keep the
AuthenticatorinYoutubeServiceand ask it for a token before each request.yup-oauth2serves the cached token and refreshes it transparently near expiry.Also in here
Three closely related fixes in the same code:
reqwest::ClientcarriedAuthorization: Bearer <token>as a default header, and the same client fetchesprofileImageUrlvalues taken straight from API responses — so the user's token went to whatever avatar host the payload named. The default header is gone; auth is attached per-request, to googleapis.com calls only.auth()(install_default().unwrap()andpanic!("Couldn't get oauth token")) are now ordinary errors. Credential files are created0600, the app directory0700.Verification
cargo build/cargo testclean. The refresh path itself needs a >1h live session to exercise end to end; I have not been able to run that.First of a 7-PR series splitting up a set of live-chat reliability fixes. Nothing depends on this one, but the rest build on it.
🤖 Generated with Claude Code