| const client = require('openid-client'); |
| const { logger } = require('@librechat/data-schemas'); |
| const { CacheKeys } = require('librechat-data-provider'); |
| const { getOpenIdConfig } = require('~/strategies/openidStrategy'); |
| const getLogStores = require('~/cache/getLogStores'); |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| async function getGraphApiToken(user, accessToken, scopes, fromCache = true) { |
| try { |
| if (!user.openidId) { |
| throw new Error('User must be authenticated via Entra ID to access Microsoft Graph'); |
| } |
|
|
| if (!accessToken) { |
| throw new Error('Access token is required for token exchange'); |
| } |
|
|
| if (!scopes) { |
| throw new Error('Graph API scopes are required for token exchange'); |
| } |
|
|
| const config = getOpenIdConfig(); |
| if (!config) { |
| throw new Error('OpenID configuration not available'); |
| } |
|
|
| const cacheKey = `${user.openidId}:${scopes}`; |
| const tokensCache = getLogStores(CacheKeys.OPENID_EXCHANGED_TOKENS); |
|
|
| if (fromCache) { |
| const cachedToken = await tokensCache.get(cacheKey); |
| if (cachedToken) { |
| logger.debug(`[GraphTokenService] Using cached Graph API token for user: ${user.openidId}`); |
| return cachedToken; |
| } |
| } |
|
|
| logger.debug(`[GraphTokenService] Requesting new Graph API token for user: ${user.openidId}`); |
| logger.debug(`[GraphTokenService] Requested scopes: ${scopes}`); |
|
|
| const grantResponse = await client.genericGrantRequest( |
| config, |
| 'urn:ietf:params:oauth:grant-type:jwt-bearer', |
| { |
| scope: scopes, |
| assertion: accessToken, |
| requested_token_use: 'on_behalf_of', |
| }, |
| ); |
|
|
| const tokenResponse = { |
| access_token: grantResponse.access_token, |
| token_type: 'Bearer', |
| expires_in: grantResponse.expires_in || 3600, |
| scope: scopes, |
| }; |
|
|
| await tokensCache.set( |
| cacheKey, |
| tokenResponse, |
| (grantResponse.expires_in || 3600) * 1000, |
| ); |
|
|
| logger.debug( |
| `[GraphTokenService] Successfully obtained and cached Graph API token for user: ${user.openidId}`, |
| ); |
| return tokenResponse; |
| } catch (error) { |
| logger.error( |
| `[GraphTokenService] Failed to acquire Graph API token for user ${user.openidId}:`, |
| error, |
| ); |
| throw new Error(`Graph token acquisition failed: ${error.message}`); |
| } |
| } |
|
|
| module.exports = { |
| getGraphApiToken, |
| }; |
|
|