Skip to content

Authentication

Authentication

MiniFy uses Spotify’s OAuth 2.0 authentication to securely access your Spotify account. This page provides a comprehensive explanation of the authentication process, security measures, and troubleshooting guidance.

Overview

MiniFy implements the Authorization Code Flow with PKCE (Proof Key for Code Exchange), which is the most secure OAuth flow for public clients like desktop applications that cannot securely store a client secret.

┌─────────────────────────────────────────────────────────────────────────────┐
│ OAuth 2.0 PKCE Authentication Flow │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────────┐ │
│ │ MiniFy │ │ Spotify │ │
│ │ Desktop │ │ Servers │ │
│ └────┬─────┘ └──────┬───────┘ │
│ │ │ │
│ │ 1. Generate code_verifier (64 random chars) │ │
│ │ 2. Create code_challenge = SHA256(code_verifier) │ │
│ │ 3. Store state nonce (CSRF protection) │ │
│ │ │ │
│ │ ─────────────── Authorization Request ─────────────────▶│ │
│ │ (code_challenge, state) │ │
│ │ │ │
│ │ ┌────────────────────┐ │ │
│ │ │ User logs in & │ │ │
│ │ │ approves access │ │ │
│ │ └────────────────────┘ │ │
│ │ │ │
│ │ ◀────────────── Redirect to localhost:3000 ────────────│ │
│ │ (authorization_code, state) │ │
│ │ │ │
│ │ 4. Verify state matches (CSRF check) │ │
│ │ │ │
│ │ ─────────────── Token Exchange Request ────────────────▶│ │
│ │ (code + code_verifier) │ │
│ │ │ │
│ │ 5. Server verifies SHA256(code_verifier) │ │
│ │ matches original code_challenge │ │
│ │ │ │
│ │ ◀──────────────── Access & Refresh Tokens ─────────────│ │
│ │ │ │
│ │ 6. Store tokens securely in OS keyring │ │
│ ▼ ▼ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

Detailed Authentication Steps

  1. User initiates authentication

    When you click “Connect to Spotify”, MiniFy generates cryptographic values:

    • Code Verifier: A 64-character random string using URL-safe characters
    • Code Challenge: SHA-256 hash of the verifier, base64-URL encoded
    • State Nonce: A random 32-character hex string for CSRF protection
  2. Local callback server starts

    MiniFy starts a local HTTP server on 127.0.0.1:3000 to receive the OAuth callback. This server only accepts connections from localhost for security.

  3. Browser authorization

    Your default browser opens to Spotify’s authorization page with these parameters:

    • client_id: Your Spotify application ID
    • response_type: code
    • redirect_uri: http://127.0.0.1:3000/callback
    • scope: Requested permissions
    • code_challenge: The SHA-256 hash
    • code_challenge_method: S256
    • state: CSRF protection token
  4. User approves access

    You log in to Spotify (if not already) and approve MiniFy’s access request.

  5. Callback handling

    Spotify redirects to the local callback URL with:

    • code: Authorization code (one-time use)
    • state: Must match the original state nonce

    MiniFy validates the state parameter to prevent CSRF attacks.

  6. Token exchange

    MiniFy sends the authorization code along with the original code_verifier to Spotify. Spotify verifies that SHA256(code_verifier) == code_challenge before issuing tokens.

  7. Secure storage

    Tokens are stored in the operating system’s secure credential manager:

    • Access token (short-lived, ~1 hour)
    • Refresh token (long-lived)
    • Token expiry timestamp

Why PKCE?

PKCE provides several security advantages for desktop applications:

Traditional OAuthOAuth with PKCE
Requires client secretNo client secret needed
Secret could be extracted from appNothing sensitive to extract
Vulnerable to authorization code interceptionCodes useless without verifier
Single point of failureCryptographically secure

Required Permissions (Scopes)

MiniFy requests only the permissions necessary for its features:

Core Playback

ScopePurpose
user-read-playback-stateRead current playback state (track, progress, device)
user-modify-playback-stateControl playback (play, pause, skip, seek)
user-read-currently-playingGet the currently playing track

AI DJ Features

ScopePurpose
user-top-readAccess top tracks and artists for taste analysis
user-read-recently-playedView recently played tracks for recommendations
user-library-readRead saved tracks count
playlist-read-privateAccess private playlists

Token Lifecycle

Access Token

┌──────────────────────────────────────────────────────────────┐
│ Access Token Lifecycle │
├──────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ │
│ │ Token │ │
│ │ Issued │────▶ Valid for ~1 hour │
│ └─────────────┘ │
│ │ │
│ │ Used for all Spotify API requests │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ 5 minutes │ │
│ │ before │────▶ Background refresh task triggers │
│ │ expiry │ │
│ └─────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ New token │ │
│ │ issued │────▶ Seamlessly replaces old token │
│ └─────────────┘ │
│ │
└──────────────────────────────────────────────────────────────┘
  • Validity: ~1 hour (set by Spotify)
  • Auto-refresh: MiniFy runs a background task every 5 minutes that checks if the token will expire within 5 minutes and proactively refreshes it
  • Retry on 401: If a request fails with 401 Unauthorized, MiniFy automatically refreshes the token and retries the request

Refresh Token

  • Validity: Long-lived (months) unless revoked
  • Rotation: Spotify may issue a new refresh token with each use
  • Storage: Securely stored in OS keyring

Token Storage Locations

Credential Manager (Windows Credential Manager)

Target: minify:access_token
Target: minify:refresh_token
Target: minify:token_expiry
Target: minify:spotify_client_id

View with: Control Panel → User Accounts → Credential Manager

Client ID Configuration

MiniFy supports two ways to configure the Spotify Client ID:

Official MiniFy releases have a Client ID embedded at build time. Users don’t need to configure anything.

2. User-provided

For development or self-built versions:

  1. Go to Spotify Developer Dashboard
  2. Create a new application
  3. Add http://127.0.0.1:3000/callback to Redirect URIs
  4. Copy the Client ID
  5. Enter it in MiniFy’s setup screen

Disconnecting

To disconnect MiniFy from your Spotify account:

From MiniFy

  1. Open Settings (right-click → Settings)
  2. Navigate to “Connections”
  3. Click “Disconnect from Spotify”
  4. Confirm the disconnection

This will:

  • Delete all tokens from the OS keyring
  • Clear the stored Client ID (if user-provided)
  • Reset MiniFy to the initial setup state

From Spotify

You can also revoke MiniFy’s access from Spotify:

  1. Go to Spotify Account Apps
  2. Find MiniFy in the list
  3. Click “Remove Access”

Security Measures

CSRF Protection

Every OAuth flow generates a unique state nonce. The callback validates that the returned state matches the expected value, preventing cross-site request forgery attacks.

Code Verifier Security

  • Generated using cryptographically secure random number generator
  • Contains 64 characters from the URL-safe alphabet
  • Never transmitted over the network (only the hash is sent)
  • Cleared from memory after token exchange

Localhost-only Callback

The callback server binds exclusively to 127.0.0.1:3000, ensuring:

  • No external network access
  • No DNS rebinding attacks
  • Callback only works on the local machine

Token Encryption

Tokens are stored using OS-level encryption:

  • Windows: DPAPI (Data Protection API)
  • macOS: AES-256 via Keychain
  • Linux: Encryption depends on Secret Service implementation

Troubleshooting

”Port 3000 already in use”

Another application is using port 3000. Either:

  • Close the conflicting application
  • Wait for MiniFy’s timeout (5 minutes) and try again

”State mismatch” error

This occurs when:

  • You have old browser tabs open from previous auth attempts
  • Solution: Close all Spotify auth tabs and try again

Token refresh fails repeatedly

Your refresh token may have been revoked:

  1. Clear credentials: Settings → Connections → Disconnect
  2. Re-authenticate with Spotify

”Invalid redirect URI”

Your Spotify app configuration doesn’t include the callback URL:

  1. Go to Spotify Developer Dashboard
  2. Edit your application
  3. Add http://127.0.0.1:3000/callback to Redirect URIs
  4. Save changes

Browser doesn’t open

MiniFy couldn’t launch your default browser:

  • Ensure you have a default browser configured
  • Try manually opening the auth URL from the error message

For Developers

Environment Variables

Terminal window
# Embed Client ID at build time
SPOTIFY_CLIENT_ID=your_client_id pnpm desktop:build

Testing Authentication

Terminal window
# Clear all stored credentials for testing
pnpm desktop:clear

OAuth Flow Timeout

The OAuth callback server automatically shuts down after:

  • 5 minutes of inactivity
  • Successful token exchange
  • User cancellation