auth

package
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 11, 2026 License: MIT Imports: 21 Imported by: 0

Documentation

Overview

Package auth handles Spotify OAuth2 with PKCE: interactive login via a local callback server, token persistence on disk, and proactive token refresh to avoid blocking API calls on an expiring token.

Typical flow:

token, authorizedAt, _ := auth.LoadTokenWithAuth()
if token == nil {
    token, _ = auth.Login(ctx, authenticator, redirectURL)
    _ = auth.SaveFreshToken(token)
}
httpClient, saveErrCh, revokedCh, cleanup, _ := auth.NewSavingClient(ctx, authenticator, token)
defer cleanup()

NewSavingClient returns an *http.Client that refreshes and re-persists the token automatically; its cleanup stops the proactive-refresh goroutine. Refresh failures that can't block the caller (disk write errors) are surfaced on saveErrCh so the UI can warn the user. revokedCh fires once if Spotify rejects the refresh token as permanently invalid, so the caller can prompt for a fresh login.

Refresh-token lifetime

Spotify's 2026-06-18 policy gives refresh tokens a hard 6-month lifetime measured from the user's original authorization; access-token refreshes do not extend it. The package records the authorization moment as `authorized_at` in token.json (via SaveFreshToken) and exposes it through LoadTokenWithAuth so callers can warn the user before the token expires. When a refresh ultimately fails with "invalid_grant", the package signals via revokedCh and deletes the stale token file — the next launch will run a fresh login.

Index

Constants

This section is empty.

Variables

View Source
var ErrTokenRevoked = errors.New("spotify refresh token revoked")

ErrTokenRevoked wraps errors returned by the OAuth2 library when the stored refresh token is no longer valid (user-initiated app revocation, long inactivity, password reset, etc.). Detectable via errors.Is so callers can distinguish a permanent failure from transient network blips and react accordingly (e.g. delete the stale token, exit).

Functions

func LoadToken

func LoadToken() (*oauth2.Token, error)

LoadToken reads the persisted oauth2 token. Returns (nil, nil) if no token has been saved.

func LoadTokenWithAuth added in v0.6.0

func LoadTokenWithAuth() (*oauth2.Token, time.Time, error)

LoadTokenWithAuth returns the persisted token alongside the authorized_at timestamp recorded at original authorization. Zero time means the timestamp is missing — either an old tuify version wrote the file before the field existed, or no token has been saved yet.

func Login

func Login(ctx context.Context, a *spotifyauth.Authenticator, redirectURL string) (*oauth2.Token, error)

Login runs the interactive PKCE flow: spins up a local callback server, opens the browser, and blocks until the user completes auth. Cancel ctx to abort a login that is stuck waiting for the browser callback.

func NewAuthenticator

func NewAuthenticator(clientID, redirectURL string) *spotifyauth.Authenticator

func NewSavingClient

func NewSavingClient(ctx context.Context, a *spotifyauth.Authenticator, token *oauth2.Token) (*http.Client, <-chan error, <-chan struct{}, func(), error)

NewSavingClient creates an HTTP client that auto-refreshes OAuth tokens and persists them to disk on each refresh. The returned cleanup function stops the proactive-refresh goroutine; callers must invoke it on shutdown. saveErrCh emits persistence failures (buffered, lossy on full) so the caller can surface them to the user. revokedCh fires exactly once if Spotify rejects the refresh token as permanently invalid ("invalid_grant" — most commonly Spotify's 6-month refresh-token lifetime (measured from original authorization, not extended by refresh), or the user revoking the app in their account settings); the stale token file is deleted before the signal so the next launch runs login cleanly. ctx is the parent lifetime: when it is cancelled, the proactive-refresh goroutine exits and in-flight oauth2 refresh requests are cancelled too.

func SaveFreshToken added in v0.6.0

func SaveFreshToken(token *oauth2.Token) error

SaveFreshToken persists a token freshly obtained from a Login flow, stamping authorized_at to time.Now(). That timestamp is what powers the "your authorization will expire" warning at startup.

func SaveToken

func SaveToken(token *oauth2.Token) error

SaveToken persists a refreshed token. The authorized_at timestamp from any prior token.json is preserved — refreshes never reset Spotify's 6-month refresh-token clock. Use SaveFreshToken when stamping a token freshly obtained from the Login flow.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL