in apps/chat/src/utils/auth/auth-callbacks.ts [75:167]
async function refreshAccessToken(token: Token) {
const displayedTokenSub =
process.env.SHOW_TOKEN_SUB === 'true' ? token.sub : '******';
try {
if (!token.providerId) {
throw new Error(`No provider information exists in token`);
}
const client = NextClient.getClient(token.providerId);
if (!client) {
throw new Error(`No client for appropriate provider set`);
}
let msWaiting = 0;
// eslint-disable-next-line no-constant-condition
while (true) {
const refresh = NextClient.getRefreshToken(token.userId);
if (!refresh || !refresh.isRefreshing) {
const localToken: RefreshToken = refresh || {
isRefreshing: true,
token,
};
if (
typeof localToken.token?.accessTokenExpires === 'number' &&
Date.now() < localToken.token.accessTokenExpires
) {
return localToken.token;
}
NextClient.setIsRefreshTokenStart(token.userId, localToken);
break;
}
await NextClient.delay();
msWaiting += 50;
if (msWaiting >= waitRefreshTokenTimeout * 1000) {
throw new Error(
`Waiting more than ${waitRefreshTokenTimeout} seconds for refreshing token`,
);
}
}
const refreshedTokens = await client.refresh(
token.refreshToken as string | TokenSet,
);
if (
!refreshedTokens ||
(!refreshedTokens.expires_in && !refreshedTokens.expires_at)
) {
throw new Error(`Error from auth provider while refreshing token`);
}
if (!refreshedTokens.refresh_token) {
logger.warn(
`Auth provider didn't provide new refresh token. Sub: ${displayedTokenSub}`,
);
}
if (!refreshedTokens.refresh_token && !token.refreshToken) {
throw new Error('No refresh tokens exists');
}
const returnToken = {
...token,
user: getUser(refreshedTokens.access_token, token.providerId),
access_token: refreshedTokens.access_token,
accessTokenExpires: refreshedTokens.expires_in
? Date.now() + refreshedTokens.expires_in * 1000
: (refreshedTokens.expires_at as number) * 1000,
refreshToken: refreshedTokens.refresh_token ?? token.refreshToken, // Fall back to old refresh token
};
NextClient.setIsRefreshTokenStart(token.userId, {
isRefreshing: false,
token: returnToken,
});
return returnToken;
} catch (error: unknown) {
logger.error(
error,
`Error when refreshing token: ${
(error as Error).message
}. Sub: ${displayedTokenSub}`,
);
return {
...token,
error: 'RefreshAccessTokenError',
};
}
}