UNPKG

@replyke/core

Version:

Replyke: Build interactive apps with social features like comments, votes, feeds, user lists, notifications, and more.

44 lines 2.07 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const react_1 = require("react"); const axios_1 = require("./axios"); const auth_1 = require("../hooks/auth"); // Module-level mutex: prevents concurrent token rotations from racing let refreshPromise = null; const useAxiosPrivate = () => { const { accessToken, requestNewAccessToken } = (0, auth_1.useAuth)(); (0, react_1.useEffect)(() => { const requestIntercept = axios_1.axiosPrivate.interceptors.request.use((config) => { if (config.headers["Authorization"]) return config; config.headers["Authorization"] = `Bearer ${accessToken}`; return config; }, (error) => Promise.reject(error)); const responseIntercept = axios_1.axiosPrivate.interceptors.response.use((response) => response, async (error) => { const prevRequest = error?.config; if (error?.response?.status === 403 && !prevRequest?.sent) { prevRequest.sent = true; // Use mutex to prevent concurrent rotation races if (!refreshPromise) { refreshPromise = requestNewAccessToken?.()?.finally(() => { refreshPromise = null; }) ?? Promise.resolve(undefined); } const newAccessToken = await refreshPromise; if (!newAccessToken) { return Promise.reject(error); } prevRequest.headers["Authorization"] = `Bearer ${newAccessToken}`; return (0, axios_1.axiosPrivate)(prevRequest); } return Promise.reject(error); }); return () => { axios_1.axiosPrivate.interceptors.request.eject(requestIntercept); axios_1.axiosPrivate.interceptors.response.eject(responseIntercept); }; }, [accessToken, requestNewAccessToken]); return axios_1.axiosPrivate; }; exports.default = useAxiosPrivate; //# sourceMappingURL=useAxiosPrivate.js.map