async function saveOAuth2UserTokens(req, accessToken, refreshToken, accessTokenExpiration, refreshTokenExpiration, providerName, tokenConfig = {}) {
  try {
    let user = await User.findById(req.user._id);
    if (!user) {
      // If user is not found in DB, use the one from the request because we are creating a new user
      user = req.user;
    }
    const providerToken = user.tokens.find((token) => token.kind === providerName);
    if (providerToken) {
      providerToken.accessToken = accessToken;
      if (accessTokenExpiration) {
        providerToken.accessTokenExpires = moment().add(accessTokenExpiration, 'seconds').format();
      } else {
        delete providerToken.accessTokenExpires;
      }
      if (refreshToken) {
        providerToken.refreshToken = refreshToken;
      }
      if (refreshTokenExpiration) {
        providerToken.refreshTokenExpires = moment().add(refreshTokenExpiration, 'seconds').format();
      } else if (refreshToken) {
        // Only delete refresh token expiration if we got a new refresh token and don't have an expiration for it
        delete providerToken.refreshTokenExpires;
      }
    } else {
      const newToken = {
        kind: providerName,
        accessToken,
        ...(accessTokenExpiration && {
          accessTokenExpires: moment().add(accessTokenExpiration, 'seconds').format(),
        }),
        ...(refreshToken && { refreshToken }),
        ...(refreshTokenExpiration && {
          refreshTokenExpires: moment().add(refreshTokenExpiration, 'seconds').format(),
        }),
      };
      user.tokens.push(newToken);
    }

    if (tokenConfig) {
      Object.assign(user, tokenConfig);
    }

    user.markModified('tokens');
    await user.save();
    return user;
  } catch (err) {
    throw new Error(err);
  }
}
Common function to handle OAuth2 token processing and saving user data.

This function is to handle various senarious that we would run into when it comes to
processing the OAuth2 tokens and saving the user data.

If we have an existing tokens:
   - Updates the access token
   - Updates access token expiration if provided
   - Updates refresh token if provided
   - Updates refresh token expiration if provided
   - Removes expiration dates if new tokens don't have them

If no tokens exists:
   - Creates new token entry with provided tokens and expirations