export async function getValidAccessToken(userId: string, providerId: string = "microsoft") {
// Find the account for the user and provider
const account = await db.account.findFirst({
where: {
userId,
providerId,
},
});
if (!account) {
throw new Error(`No ${providerId} account found for user ${userId}`);
}
// Check if the access token is expired or will expire soon (within 5 minutes)
const isExpiredOrExpiringSoon = !account.accessTokenExpiresAt ||
account.accessTokenExpiresAt.getTime() < Date.now() + 5 * 60 * 1000;
// If the token is expired or will expire soon, refresh it
if (isExpiredOrExpiringSoon && account.refreshToken) {
try {
console.log(`Access token is expired or will expire soon. Refreshing...`);
// Get the provider configuration from auth
const providerConfig = auth.options.socialProviders?.[providerId];
if (!providerConfig || !providerConfig.refreshAccessToken) {
throw new Error(`Provider ${providerId} does not support token refreshing`);
}
// Call the refreshAccessToken function
const tokens = await providerConfig.refreshAccessToken(account.refreshToken);
// Update the account with the new tokens
await db.account.update({
where: { id: account.id },
data: {
accessToken: tokens.accessToken,
refreshToken: tokens.refreshToken,
accessTokenExpiresAt: tokens.accessTokenExpiresAt,
refreshTokenExpiresAt: tokens.refreshTokenExpiresAt,
idToken: tokens.idToken,
},
});
console.log(`Access token refreshed successfully. New expiration: ${tokens.accessTokenExpiresAt}`);
return tokens.accessToken;
} catch (error) {
console.error("Error refreshing access token:", error);
throw error;
}
}
// Return the current access token if it's still valid
return account.accessToken;
}
export async function getValidAccessToken(userId: string, providerId: string = "microsoft") {
// Find the account for the user and provider
const account = await db.account.findFirst({
where: {
userId,
providerId,
},
});
if (!account) {
throw new Error(`No ${providerId} account found for user ${userId}`);
}
// Check if the access token is expired or will expire soon (within 5 minutes)
const isExpiredOrExpiringSoon = !account.accessTokenExpiresAt ||
account.accessTokenExpiresAt.getTime() < Date.now() + 5 * 60 * 1000;
// If the token is expired or will expire soon, refresh it
if (isExpiredOrExpiringSoon && account.refreshToken) {
try {
console.log(`Access token is expired or will expire soon. Refreshing...`);
// Get the provider configuration from auth
const providerConfig = auth.options.socialProviders?.[providerId];
if (!providerConfig || !providerConfig.refreshAccessToken) {
throw new Error(`Provider ${providerId} does not support token refreshing`);
}
// Call the refreshAccessToken function
const tokens = await providerConfig.refreshAccessToken(account.refreshToken);
// Update the account with the new tokens
await db.account.update({
where: { id: account.id },
data: {
accessToken: tokens.accessToken,
refreshToken: tokens.refreshToken,
accessTokenExpiresAt: tokens.accessTokenExpiresAt,
refreshTokenExpiresAt: tokens.refreshTokenExpiresAt,
idToken: tokens.idToken,
},
});
console.log(`Access token refreshed successfully. New expiration: ${tokens.accessTokenExpiresAt}`);
return tokens.accessToken;
} catch (error) {
console.error("Error refreshing access token:", error);
throw error;
}
}
// Return the current access token if it's still valid
return account.accessToken;
}