// FIXME: This file should handle the authentication // Exports must include: // - authedAPIRequest (make an authenticated request to the API) /** * This function makes an authenticated request to the API * This function must always hit the /api/* endpoint. * @param {string} endpoint * @param {object} options This object should at least contain the method. * For the other options, you can refer to the fetch documentation as it should be the same. * @returns {Promise} the response * We want a {Promise} so we can read the headers as well as the body, rather than * just the body. **/ export async function authedAPIRequest(endpoint, options) { if (localStorage.getItem("token")) { // essaye de contacter l'endpoint const headers = { Authorization: `Bearer ${localStorage.getItem("token")}`, }; if (options["headers"]) { options["headers"]["Authorization"] = `Bearer ${localStorage.getItem("token")}`; } else { options["headers"] = headers; } const apiURL = `${import.meta.env.VITE_URL}/api${endpoint}`; try { const response = await fetch(apiURL, options); if (response.status === 200) { return response; } else { console.log("request error"); console.log(response); if ( response.status === 401 && (await response.json()).message.match(/Token expired/) ) { localStorage.removeItem("token"); if (!(await sendTokenRequest())) { return null; } const response = await authedAPIRequest(endpoint, options); if (!response) { return null; } return response; } else { localStorage.clear(); // window.location.replace(import.meta.env.VITE_URL); await sendTokenRequest(); return null; } } } catch { console.log("an error occured while fetching"); return null; } } await sendTokenRequest(); return null; } // Functions may include: // - sendTokenRequest (get a token or refresh it) export async function sendTokenRequest() { if ( !localStorage.getItem("token") && !localStorage.getItem("refresh_token") ) { const authQueryParams = { client_id: import.meta.env.VITE_CLIENT_ID, scope: "epita profile picture", redirect_uri: `${import.meta.env.VITE_URL}/complete/epita/`, response_type: "code", }; const url = new URL(`${import.meta.env.VITE_AUTH_URL}/authorize`); //`?client_id=${authQueryParams.client_id}&scope=${authQueryParams.scope}&redirect_uri=${authQueryParams.redirect_uri}&response_type=${authQueryParams.response_type}`, url.searchParams.append("client_id", authQueryParams.client_id); url.searchParams.append("scope", authQueryParams.scope); url.searchParams.append("redirect_uri", authQueryParams.redirect_uri); url.searchParams.append("response_type", authQueryParams.response_type); window.location.replace(url); return false; } else if (localStorage.getItem("refresh_token")) { const form = new FormData(); form.append("client_id", import.meta.env.VITE_CLIENT_ID); form.append( "redirect_uri", `${import.meta.env.VITE_URL}/complete/epita/`, ); form.append("grant_type", "refresh_token"); form.append("refresh_token", localStorage.getItem("refresh_token")); const res = await fetch(`${import.meta.env.VITE_URL}/auth-api/token`, { method: "POST", body: form, }); if (res.status === 200) { const response = await res.json(); localStorage.setItem("token", response.id_token); localStorage.setItem("refresh_token", response.refresh_token); return true; } else { localStorage.clear(); // window.location.replace(import.meta.env.VITE_URL); // HERE ptetre return direct senTokenRequest await sendTokenRequest(); return false; } } }