This module serves as the central hub for all Spotify authentication operations,
integrating multiple specialized components into a cohesive authentication system.
It provides a clean, unified API for the rest of the application to handle all
aspects of the authentication lifecycle.
Features:
Single entry point for all authentication operations
Session state persistence across application restarts
Credential validation and management
Token encryption for enhanced security
Automatic token refresh scheduling with configurable timing
Authentication state validation with expiry checking
Clean dependency management through dynamic imports
Architecture:
This module implements a facade pattern to abstract authentication complexity,
delegating specialized tasks to five primary submodules:
Window - Authentication browser window management
Server - OAuth callback server for redirect handling
OAuth - Authorization flow coordination
Session - User session state management
Storage - Secure token persistence and retrieval
To prevent circular dependencies while maintaining a clean API, this module
uses dynamic imports for storage operations while providing a consistent
public interface to the rest of the application.
/** * Stores authentication tokens securely * * Persists the full set of OAuth tokens (access token, refresh token, * and expiry time) to secure storage. Dynamically imports the token * storage module to avoid circular dependencies. * * This function: * - Encrypts sensitive token data before storage * - Updates both memory state and persistent storage * - Triggers automatic token refresh scheduling * - Logs appropriate debugging information * - Handles errors gracefully with detailed reporting * * @paramtokens - Complete authentication token set * @returns Promise resolving when tokens are successfully stored * * @example * // Store tokens after successful authentication * await setTokens({ * accessToken: "spotify-access-token", * refreshToken: "spotify-refresh-token", * expiresIn: 3600 * }); * console.log("User is now authenticated and tokens are stored securely"); * @source */ exportasyncfunctionsetTokens(tokens: AuthTokens): Promise<void> { constmod = awaitimport("./storage/token-operations"); returnmod.setTokens(tokens); }
/** * Retrieves the current Spotify access token * * Gets the currently stored access token for API requests. * Dynamically imports the token module to avoid circular dependencies. * * This function: * - Attempts to retrieve token from memory state first * - Falls back to secure storage if not in memory * - Rehydrates memory state from storage when needed * - Returns null if no valid token exists * - Handles all retrieval errors gracefully * * @returns Promise resolving to the access token or null if not authenticated * * @example * // Get token for API request * const token = await getAccessToken(); * if (token) { * headers.Authorization = `Bearer ${token}`; * await makeApiRequest("/me", headers); * } else { * // Handle unauthenticated state * showLoginPrompt(); * } * @source */ exportasyncfunctiongetAccessToken(): Promise<string | null> { constmod = awaitimport("./storage/token-operations"); returnmod.getAccessToken(); }
/** * Retrieves the stored refresh token * * Gets the currently stored refresh token used for obtaining * new access tokens when they expire. Dynamically imports the * token module to avoid circular dependencies. * * This function: * - Attempts to retrieve token from memory state first * - Falls back to secure storage if not in memory * - Rehydrates memory state from storage when needed * - Returns null if no valid refresh token exists * - Handles all retrieval errors gracefully * * @returns Promise resolving to the refresh token or null if not authenticated * * @example * // Check if we have a refresh token before attempting refresh * const refreshToken = await getRefreshToken(); * if (refreshToken) { * const success = await refreshAccessToken(); * if (success) { * console.log("Successfully refreshed access token"); * } * } * @source */ exportasyncfunctiongetRefreshToken(): Promise<string | null> { constmod = awaitimport("./storage/token-operations"); returnmod.getRefreshToken(); }
/** * Retrieves the token expiration timestamp * * Gets the expiration time for the current access token. * Dynamically imports the token module to avoid circular dependencies. * * This function: * - Attempts to retrieve expiry from memory state first * - Falls back to secure storage if not in memory * - Rehydrates memory state from storage when needed * - Returns null if no expiry information exists * - Provides time in milliseconds since epoch format * * @returns Promise resolving to expiry timestamp (milliseconds since epoch) or null * * @example * // Check if token expires soon and needs refresh * const expiry = await getTokenExpiry(); * if (expiry) { * const timeUntilExpiry = expiry - Date.now(); * if (timeUntilExpiry < 300000) { // Less than 5 minutes * await refreshAccessToken(); * } * } * @source */ exportasyncfunctiongetTokenExpiry(): Promise<number | null> { constmod = awaitimport("./storage/token-operations"); returnmod.getTokenExpiry(); }
/** * Removes all stored authentication tokens * * Clears access and refresh tokens from secure storage during logout * or when authentication needs to be reset. Dynamically imports the * token module to avoid circular dependencies. * * This function: * - Clears tokens from memory state * - Removes tokens from secure persistent storage * - Resets the Spotify API module state * - Logs the action for debugging purposes * - Handles all cleanup errors gracefully * * @returns Promise resolving when tokens are successfully cleared * * @example * // Clear tokens during logout * logoutButton.addEventListener('click', async () => { * await clearTokens(); * showLoginScreen(); * displayMessage("You have been logged out successfully"); * }); * @source */ exportasyncfunctionclearTokens(): Promise<void> { constmod = awaitimport("./storage/token-operations"); returnmod.clearTokens(); }
/** * Checks if the user is currently authenticated * * Verifies whether valid authentication tokens exist and * are not expired. Dynamically imports the token module * to avoid circular dependencies. * * This function: * - Checks for the existence of both access and refresh tokens * - Validates that the access token has not expired * - Handles edge cases (missing tokens, invalid expiry) * - Works correctly even after application restart * * @returns Promise resolving to authentication status * * @example * // Check auth before making API request * if (await isAuthenticated()) { * // User is authenticated, proceed with operation * const userData = await fetchUserProfile(); * displayUserData(userData); * } else { * // User is not authenticated, show login * showLoginButton(); * hideUserContent(); * } * @source */ exportasyncfunctionisAuthenticated(): Promise<boolean> { constmod = awaitimport("./storage/token-operations"); returnmod.isAuthenticated(); }
/** * Renews the access token using the refresh token * * Uses the stored refresh token to obtain a new access token * when the current one expires. Dynamically imports the token * refresh module to avoid circular dependencies. * * This function: * - Retrieves the current refresh token * - Makes a request to Spotify's token endpoint * - Updates stored tokens with the new access token * - Schedules the next refresh based on expiry * - Handles API errors with appropriate logging * * @returns Promise resolving to refresh success status * * @example * // Refresh the token before making an important API call * const refreshSucceeded = await refreshAccessToken(); * if (refreshSucceeded) { * // Token is fresh, proceed with API call * const result = await performCriticalOperation(); * } else { * // Refresh failed, re-authenticate * showLoginPrompt("Your session has expired. Please log in again."); * } * @source */ exportasyncfunctionrefreshAccessToken(): Promise<boolean> { constmod = awaitimport("./storage/token-refresh"); returnmod.refreshAccessToken(); }
/** * Sets up automatic token refresh before expiry * * Schedules a token refresh operation to occur shortly before * the access token expires. Dynamically imports the token * refresh module to avoid circular dependencies. * * This function: * - Calculates the optimal time to refresh (before expiry) * - Sets up a timer to trigger refresh at the right moment * - Ensures only one refresh timer is active at a time * - Logs scheduling information for debugging * - Handles timer creation errors gracefully * * @paramexpiresIn - Token lifetime in seconds * @returns Promise resolving when refresh is scheduled * * @example * // Schedule refresh after receiving new tokens * await scheduleTokenRefresh(3600); // 1 hour token * console.log("Token refresh scheduled for shortly before expiration"); * @source */ exportasyncfunctionscheduleTokenRefresh(expiresIn: number): Promise<void> { constmod = awaitimport("./storage/token-refresh"); returnmod.scheduleTokenRefresh(expiresIn); }
Description
Authentication Service Module
This module serves as the central hub for all Spotify authentication operations, integrating multiple specialized components into a cohesive authentication system. It provides a clean, unified API for the rest of the application to handle all aspects of the authentication lifecycle.
Features:
Architecture: This module implements a facade pattern to abstract authentication complexity, delegating specialized tasks to five primary submodules:
To prevent circular dependencies while maintaining a clean API, this module uses dynamic imports for storage operations while providing a consistent public interface to the rest of the application.
Source