fix: refresh token handling when reusing OpenID Tokens with no offline_access claim

- Updated the refreshController to check for access token and user ID when a refresh token is not provided, improving user session management.
- Added logic to handle expired access tokens, redirecting users to the login page if necessary.
- Enhanced logging in setOpenIDAuthTokens to provide clearer warnings when no refresh token is available, improving traceability of session issues.
This commit is contained in:
Danny Avila 2026-02-09 15:43:34 -05:00
parent 9054ca9c15
commit cc51ce4e73
No known key found for this signature in database
GPG key ID: BF31EEB2C5CA0956
2 changed files with 40 additions and 3 deletions

View file

@ -74,7 +74,42 @@ const refreshController = async (req, res) => {
const refreshToken = req.session?.openidTokens?.refreshToken || parsedCookies.refreshToken;
if (!refreshToken) {
return res.status(200).send('Refresh token not provided');
const accessToken = req.session?.openidTokens?.accessToken;
const storedUserId = req.session?.openidTokens?.userId;
if (!accessToken || !storedUserId) {
return res.status(200).send('Refresh token not provided');
}
let tokenExpired = false;
try {
const decoded = jwt.decode(accessToken);
if (decoded?.exp && decoded.exp < Date.now() / 1000) {
tokenExpired = true;
}
} catch {
const expiresAt = req.session?.openidTokens?.expiresAt;
if (expiresAt && expiresAt < Date.now()) {
tokenExpired = true;
}
}
if (tokenExpired) {
logger.warn('[refreshController] Access token expired and no refresh token available');
return res.status(401).redirect('/login');
}
const user = await getUserById(storedUserId, '-password -__v -totpSecret -backupCodes');
if (!user) {
return res.status(401).redirect('/login');
}
user.federatedTokens = {
access_token: accessToken,
expires_at: req.session?.openidTokens?.expiresAt,
};
return res.status(200).send({ token: accessToken, user });
}
try {

View file

@ -444,8 +444,9 @@ const setOpenIDAuthTokens = (tokenset, req, res, userId, existingRefreshToken) =
const refreshToken = tokenset.refresh_token || existingRefreshToken;
if (!refreshToken) {
logger.error('[setOpenIDAuthTokens] No refresh token available');
return;
logger.warn(
'[setOpenIDAuthTokens] No refresh token available — session will not auto-refresh',
);
}
/** Store tokens server-side in session to avoid large cookies */
@ -454,6 +455,7 @@ const setOpenIDAuthTokens = (tokenset, req, res, userId, existingRefreshToken) =
accessToken: tokenset.access_token,
refreshToken: refreshToken,
expiresAt: expirationDate.getTime(),
userId: userId,
};
} else {
logger.warn('[setOpenIDAuthTokens] No session available, falling back to cookies');