Documentation
¶
Overview ¶
Package auth handles interactive sign-in via the OAuth 2.0 authorization code flow with PKCE, and caches the resulting tokens on disk so a login persists across commands.
PKCE rather than the plain authorization code flow because a CLI cannot keep a client secret — anyone with the binary has it. Spotify retired the implicit grant, so this is the only remaining flow for a public client.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrNotLoggedIn = errors.New("not logged in")
ErrNotLoggedIn means there is no cached session, or its refresh token has expired or been revoked. The fix is always `spotify auth login`.
var Scopes = []string{
"playlist-read-private",
"playlist-read-collaborative",
"playlist-modify-private",
"playlist-modify-public",
"user-read-private",
}
Scopes are the delegated permissions the CLI asks for.
Deliberately no user-read-email: the February 2026 revision dropped `email`, `country` and `product` from the user object, so the scope would buy a consent screen line and nothing else.
Functions ¶
func HasSession ¶
func HasSession() bool
HasSession reports whether a token cache exists. It says a session was started, not that the refresh token still works — proving that needs a round trip, which a status line should not silently pay for.
Types ¶
type Tokens ¶
type Tokens struct {
AccessToken string `json:"access_token"`
RefreshToken string `json:"refresh_token"`
Expiry time.Time `json:"expiry"`
Scope string `json:"scope,omitempty"`
}
Tokens is the cached session. Expiry is absolute rather than the API's relative expires_in, so a token cached an hour ago is correctly seen as stale.
func Login ¶
func Login(ctx context.Context, cfg config.Config, prompt io.Writer, openBrowser func(string) error) (Tokens, error)
Login runs the PKCE flow: it starts a loopback listener, sends the user to Spotify's consent page, and exchanges the returned code for tokens. It writes progress to prompt and blocks until the browser comes back or ctx is done.