UNPKG

bluesky-oauth-kit

Version:

A complete OAuth backend implementation for Bluesky

172 lines (146 loc) 5.63 kB
/** * Retrieves the value of a specified cookie. * @param {string} name - The name of the cookie to retrieve. * @returns {string|null} The cookie value if found, otherwise null. */ const getCookie = (name) => { const value = `; ${document.cookie}`; const parts = value.split(`; ${name}=`); if (parts.length === 2) return parts.pop().split(';').shift(); return null; }; /** * Performs a fetch request with authentication. * * This function retrieves a JWT token from sessionStorage or cookies, * attaches it to the Authorization header if available, and executes the fetch request. * It handles unauthorized responses by clearing the token and redirecting to the login page. * * @param {string} url - The URL to which the request is sent. * @param {object} [options={}] - Optional configurations for the fetch request. * @param {boolean} [options.plain=false] - If true, omits the 'Content-Type' header. * @param {object} [options.headers={}] - Additional headers to include in the request. * @returns {Promise<object|undefined>} - Resolves with the parsed JSON response if successful, otherwise undefined. */ const fetchWithAuth = async (url, options = {}) => { // Retrieve the token from sessionStorage let token = sessionStorage.getItem('_token'); // If not in sessionStorage, attempt to retrieve from cookies if (!token) { token = getCookie('token'); } // Default headers const headers = { ...options.headers, // Include any additional headers provided }; if (!options.plain) headers['Content-Type'] = 'application/json'; else delete options.plain; // Add the Authorization header if the token exists if (token) { headers['Authorization'] = `Bearer ${token}`; } // Configure the fetch options const fetchOptions = { ...options, headers, credentials: 'include', // Include cookies in requests }; try { // Perform the fetch const response = await fetch(url, fetchOptions); // If the response is unauthorized or forbidden, clear the token if (response.status === 401 || response.status === 403) { sessionStorage.removeItem('_token'); // Optionally, remove the cookie if accessible document.cookie = 'token=; Max-Age=0; path=/;'; location.href = '/login'; return console.warn('Authentication failed. Token has been removed.'); } // Throw an error if the response is not ok (excluding 401/403 handled above) if (!response.ok) { console.warn(`HTTP error! status: ${response.status}`); return; } // Return the parsed response data return await response.json(); } catch (error) { console.error(error); throw error; // Re-throw the error for upstream handling } }; /** * Stashes specific query parameters into sessionStorage. * * This function extracts designated parameters from the URL's query string * and stores their values in sessionStorage with a prefixed key. * After stashing, it cleans up the URL by removing the query parameters without reloading the page. */ const stashQueryParamsInSessionStorage = () => { // Get the query string from the current URL const queryString = window.location.search; // Parse the query parameters const params = new URLSearchParams(queryString); // Check if the 'token' parameter exists if (!params.has('token')) { return; // Do nothing if there's no 'token' } // Define the keys you want to stash const keysToStash = ['token', 'did', 'handle', 'displayName', 'avatar']; // Loop through each key and store its value in sessionStorage keysToStash.forEach((key) => { const value = params.get(key); if (value) { sessionStorage.setItem(`_${ key }`, value); } }); // Clean up the URL by removing query parameters without redirecting const newUrl = window.location.pathname + window.location.hash; window.history.replaceState(null, '', newUrl); }; // Execute the function to stash query parameters upon script load stashQueryParamsInSessionStorage(); /** * Logs out the user by clearing authentication tokens and redirecting to the login page. * * This function removes the JWT token from sessionStorage and deletes the corresponding cookie. * After clearing the tokens, it redirects the user to the '/login' page. */ function logout() { // Remove the token from sessionStorage sessionStorage.removeItem('_token'); // Remove the token cookie by setting its Max-Age to 0 document.cookie = 'token=; Max-Age=0; path=/;'; // Redirect to the login page location.href = '/login'; } /** * Checks if the user is currently logged in. * * This function verifies the presence of a JWT token in sessionStorage. * If the token exists, it returns true, indicating that the user is logged in. * Otherwise, it returns false. * * @returns {boolean} True if the user is logged in, false otherwise. */ function isLoggedIn() { let token = sessionStorage.getItem('_token'); if (!token) token = getCookie('token'); return !!token; } // EXAMPLES // (async () => { // try { // const data = await fetchWithAuth('/me', { // method: 'GET', // Or 'POST', 'PUT', etc. // }); // // console.log('Response Data:', data); // } catch (error) { // console.error('Error fetching data:', error); // } // })(); // if (isLoggedIn()) { // // } else { // // }