Token & session security
- Spotify tokens stored in HttpOnly, Secure cookies and cleared on logout
- Refresh flow runs server-side only; client never sees secrets
- Short-lived access tokens; refresh token retained for 30 days
Tech stack
The stack
Key features
Full OAuth flow with cookie-based session management, automatic token refresh, and server-side token caching. Supports both client credentials and user authorization flows.
Dynamic audio delivery with 55-minute URL expiration and intelligent caching. Server-side signing prevents credential exposure while maintaining performance.
Unified playback interface supporting both HTML5 Audio API for beats and Spotify Web Playback SDK for streaming. Context-aware controls adapt to the active source.
Audio continues playing seamlessly across page navigation using React Context and root layout mounting. Smart state management prevents interruptions during route changes.
Backend
/api/beatsReturns all beats with metadata/api/beats/playlistsReturns the beat packs/api/beats/signedUrlGenerates a signed URL for a specific beat/api/spotify/loginInitiates Spotify OAuth 2.0 authorization flow/api/spotify/callbackHandles OAuth callback and exchanges code for tokens/api/spotify/tokenRetrieves or refreshes Spotify access token/api/spotify/logoutClears the Spotify session cookies/api/spotify/playlistsFetches user playlists from Spotify API/api/spotify/playlist/[id]Fetches one playlist with its tracks/api/spotify/stats/topTracksFetches user’s most played tracks/api/spotify/stats/topArtistsFetches user’s top artistsUnder the hood
// Reuse a signed S3 URL until it's about to expire
const cached = urlCache.get(track.id)
const now = Date.now()
let audioUrl: string
if (cached && cached.expiresAt > now) {
audioUrl = cached.url
} else {
const url = await getBeatSignedUrl(track.id)
const expiresAt = now + 55 * 60 * 1000
audioUrl = url
setUrlCache(prev => new Map(prev).set(track.id, { url, expiresAt }))
}
setSelectedTrack({ ...track, audioUrl })
setIsPlaying(true)Performance
Security & best practices
View the full source code, architecture decisions, and implementation details. Clean codebase, full TypeScript, production-ready.