mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-27 21:58:51 +01:00
🔃 fix: Token Refresh in Browser Only, Redirect on Refresh Failure (#9583)
* 🔃 fix: Token Refresh in Browser Only, Redirect on Refresh Failure
* chore: Update import for SearchResultData and fix FormattedToolResponse type build warning
This commit is contained in:
parent
180046a3c5
commit
e3a645e8fb
2 changed files with 63 additions and 61 deletions
|
|
@ -83,70 +83,75 @@ const processQueue = (error: AxiosError | null, token: string | null = null) =>
|
|||
failedQueue = [];
|
||||
};
|
||||
|
||||
axios.interceptors.response.use(
|
||||
(response) => response,
|
||||
async (error) => {
|
||||
const originalRequest = error.config;
|
||||
if (!error.response) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
if (typeof window !== 'undefined') {
|
||||
axios.interceptors.response.use(
|
||||
(response) => response,
|
||||
async (error) => {
|
||||
const originalRequest = error.config;
|
||||
if (!error.response) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
|
||||
if (originalRequest.url?.includes('/api/auth/2fa') === true) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
if (originalRequest.url?.includes('/api/auth/logout') === true) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
if (originalRequest.url?.includes('/api/auth/2fa') === true) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
if (originalRequest.url?.includes('/api/auth/logout') === true) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
if (originalRequest.url?.includes('/api/auth/refresh') === true) {
|
||||
// Refresh token itself failed - redirect to login
|
||||
console.log('Refresh token request failed, redirecting to login...');
|
||||
window.location.href = '/login';
|
||||
return Promise.reject(error);
|
||||
}
|
||||
|
||||
if (error.response.status === 401 && !originalRequest._retry) {
|
||||
console.warn('401 error, refreshing token');
|
||||
originalRequest._retry = true;
|
||||
if (error.response.status === 401 && !originalRequest._retry) {
|
||||
console.warn('401 error, refreshing token');
|
||||
originalRequest._retry = true;
|
||||
|
||||
if (isRefreshing) {
|
||||
try {
|
||||
const token = await new Promise((resolve, reject) => {
|
||||
failedQueue.push({ resolve, reject });
|
||||
});
|
||||
originalRequest.headers['Authorization'] = 'Bearer ' + token;
|
||||
return await axios(originalRequest);
|
||||
} catch (err) {
|
||||
return Promise.reject(err);
|
||||
}
|
||||
}
|
||||
|
||||
isRefreshing = true;
|
||||
|
||||
if (isRefreshing) {
|
||||
try {
|
||||
const token = await new Promise((resolve, reject) => {
|
||||
failedQueue.push({ resolve, reject });
|
||||
});
|
||||
originalRequest.headers['Authorization'] = 'Bearer ' + token;
|
||||
return await axios(originalRequest);
|
||||
const response = await refreshToken();
|
||||
|
||||
const token = response?.token ?? '';
|
||||
|
||||
if (token) {
|
||||
originalRequest.headers['Authorization'] = 'Bearer ' + token;
|
||||
dispatchTokenUpdatedEvent(token);
|
||||
processQueue(null, token);
|
||||
return await axios(originalRequest);
|
||||
} else if (window.location.href.includes('share/')) {
|
||||
console.log(
|
||||
`Refresh token failed from shared link, attempting request to ${originalRequest.url}`,
|
||||
);
|
||||
} else {
|
||||
window.location.href = '/login';
|
||||
}
|
||||
} catch (err) {
|
||||
processQueue(err as AxiosError, null);
|
||||
return Promise.reject(err);
|
||||
} finally {
|
||||
isRefreshing = false;
|
||||
}
|
||||
}
|
||||
|
||||
isRefreshing = true;
|
||||
|
||||
try {
|
||||
const response = await refreshToken(
|
||||
// Handle edge case where we get a blank screen if the initial 401 error is from a refresh token request
|
||||
originalRequest.url?.includes('api/auth/refresh') === true ? true : false,
|
||||
);
|
||||
|
||||
const token = response?.token ?? '';
|
||||
|
||||
if (token) {
|
||||
originalRequest.headers['Authorization'] = 'Bearer ' + token;
|
||||
dispatchTokenUpdatedEvent(token);
|
||||
processQueue(null, token);
|
||||
return await axios(originalRequest);
|
||||
} else if (window.location.href.includes('share/')) {
|
||||
console.log(
|
||||
`Refresh token failed from shared link, attempting request to ${originalRequest.url}`,
|
||||
);
|
||||
} else {
|
||||
window.location.href = '/login';
|
||||
}
|
||||
} catch (err) {
|
||||
processQueue(err as AxiosError, null);
|
||||
return Promise.reject(err);
|
||||
} finally {
|
||||
isRefreshing = false;
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.reject(error);
|
||||
},
|
||||
);
|
||||
return Promise.reject(error);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
export default {
|
||||
get: _get,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue