mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 08:50:15 +01:00
fix: getLogStores Property and Handle 401 Error from Refresh Token Request (#1084)
* fix(getLogStores): correct wrong prop passed to keyv opts: duration -> ttl * fix: edge case where we get a blank screen if the initially intercepted 401 error is from a refresh token request; in this case, make explicit to the server that we are retrying from a refreshToken request
This commit is contained in:
parent
abbc57a49a
commit
6cb561abcf
5 changed files with 33 additions and 27 deletions
2
api/cache/getLogStores.js
vendored
2
api/cache/getLogStores.js
vendored
|
|
@ -19,7 +19,7 @@ const pending_req = isEnabled(USE_REDIS)
|
||||||
|
|
||||||
const namespaces = {
|
const namespaces = {
|
||||||
pending_req,
|
pending_req,
|
||||||
ban: new Keyv({ store: keyvMongo, namespace: 'bans', duration }),
|
ban: new Keyv({ store: keyvMongo, namespace: 'bans', ttl: duration }),
|
||||||
general: new Keyv({ store: logFile, namespace: 'violations' }),
|
general: new Keyv({ store: logFile, namespace: 'violations' }),
|
||||||
concurrent: createViolationInstance('concurrent'),
|
concurrent: createViolationInstance('concurrent'),
|
||||||
non_browser: createViolationInstance('non_browser'),
|
non_browser: createViolationInstance('non_browser'),
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,9 @@ const refreshController = async (req, res) => {
|
||||||
const token = await setAuthTokens(userId, res, session._id);
|
const token = await setAuthTokens(userId, res, session._id);
|
||||||
const userObj = user.toJSON();
|
const userObj = user.toJSON();
|
||||||
res.status(200).send({ token, user: userObj });
|
res.status(200).send({ token, user: userObj });
|
||||||
|
} else if (req?.query?.retry) {
|
||||||
|
// Retrying from a refresh token request that failed (401)
|
||||||
|
res.status(403).send('No session found');
|
||||||
} else if (payload.exp < Date.now() / 1000) {
|
} else if (payload.exp < Date.now() / 1000) {
|
||||||
res.status(403).redirect('/login');
|
res.status(403).redirect('/login');
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ export const loginFacebook = () => '/api/auth/facebook';
|
||||||
|
|
||||||
export const loginGoogle = () => '/api/auth/google';
|
export const loginGoogle = () => '/api/auth/google';
|
||||||
|
|
||||||
export const refreshToken = () => '/api/auth/refresh';
|
export const refreshToken = (retry?: boolean) => `/api/auth/refresh${retry ? '?retry=true' : ''}`;
|
||||||
|
|
||||||
export const requestPasswordReset = () => '/api/auth/requestPasswordReset';
|
export const requestPasswordReset = () => '/api/auth/requestPasswordReset';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,7 @@ export const register = (payload: t.TRegisterUser) => {
|
||||||
return request.post(endpoints.register(), payload);
|
return request.post(endpoints.register(), payload);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const refreshToken = () => request.post(endpoints.refreshToken());
|
export const refreshToken = (retry?: boolean) => request.post(endpoints.refreshToken(retry));
|
||||||
|
|
||||||
export const userKeyQuery = (name: string): Promise<t.TCheckUserKeyResponse> =>
|
export const userKeyQuery = (name: string): Promise<t.TCheckUserKeyResponse> =>
|
||||||
request.get(endpoints.userKeyQuery(name));
|
request.get(endpoints.userKeyQuery(name));
|
||||||
|
|
|
||||||
|
|
@ -23,44 +23,47 @@ axios.interceptors.response.use(
|
||||||
(response) => response,
|
(response) => response,
|
||||||
async (error) => {
|
async (error) => {
|
||||||
const originalRequest = error.config;
|
const originalRequest = error.config;
|
||||||
|
|
||||||
if (error.response.status === 401 && !originalRequest._retry) {
|
if (error.response.status === 401 && !originalRequest._retry) {
|
||||||
|
originalRequest._retry = true;
|
||||||
|
|
||||||
if (isRefreshing) {
|
if (isRefreshing) {
|
||||||
try {
|
try {
|
||||||
const token = await new Promise(function (resolve, reject) {
|
const token = await new Promise((resolve, reject) => {
|
||||||
failedQueue.push({ resolve, reject });
|
failedQueue.push({ resolve, reject });
|
||||||
});
|
});
|
||||||
originalRequest.headers['Authorization'] = 'Bearer ' + token;
|
originalRequest.headers['Authorization'] = 'Bearer ' + token;
|
||||||
return await axios(originalRequest);
|
return await axios(originalRequest);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return await Promise.reject(err);
|
return Promise.reject(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
originalRequest._retry = true;
|
|
||||||
isRefreshing = true;
|
isRefreshing = true;
|
||||||
|
|
||||||
return new Promise(function (resolve, reject) {
|
try {
|
||||||
refreshToken()
|
const { token } = await refreshToken(
|
||||||
.then(({ token }) => {
|
// Handle edge case where we get a blank screen if the initial 401 error is from a refresh token request
|
||||||
if (token) {
|
originalRequest.url?.includes('api/auth/refresh') ? true : false,
|
||||||
originalRequest.headers['Authorization'] = 'Bearer ' + token;
|
);
|
||||||
setTokenHeader(token);
|
|
||||||
window.dispatchEvent(new CustomEvent('tokenUpdated', { detail: token }));
|
if (token) {
|
||||||
processQueue(null, token);
|
originalRequest.headers['Authorization'] = 'Bearer ' + token;
|
||||||
resolve(axios(originalRequest));
|
setTokenHeader(token);
|
||||||
} else {
|
window.dispatchEvent(new CustomEvent('tokenUpdated', { detail: token }));
|
||||||
window.location.href = '/login';
|
processQueue(null, token);
|
||||||
}
|
return await axios(originalRequest);
|
||||||
})
|
} else {
|
||||||
.catch((err) => {
|
window.location.href = '/login';
|
||||||
processQueue(err, null);
|
}
|
||||||
reject(err);
|
} catch (err) {
|
||||||
})
|
processQueue(err as AxiosError, null);
|
||||||
.then(() => {
|
return Promise.reject(err);
|
||||||
isRefreshing = false;
|
} finally {
|
||||||
});
|
isRefreshing = false;
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue