| | 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, |
| | }; |
| |
|