@@ -394,6 +394,36 @@ async function getPodUrl(webId, fetch) {
394394 }
395395}
396396
397+ /**
398+ * Get authenticated fetch and Pod URL for the current Solid user, with session cache.
399+ * Pod URL is fetched once per session (e.g. at first use after login) to avoid repeated profile requests.
400+ *
401+ * @param {Object } req - Express request (must have req.user.openidId and session)
402+ * @returns {Promise<{ authenticatedFetch: Function, podUrl: string }> }
403+ */
404+ async function getSolidFetchAndPodUrl ( req ) {
405+ const openidId = req ?. user ?. openidId ;
406+ if ( ! openidId ) {
407+ throw new Error ( 'User not authenticated with Solid/OpenID' ) ;
408+ }
409+
410+ const cached =
411+ req . session ?. solidCachedPodUrlWebId === openidId && req . session ?. solidCachedPodUrl ;
412+ if ( cached ) {
413+ const authenticatedFetch = await getSolidFetch ( req ) ;
414+ logger . debug ( '[SolidStorage] Using cached Pod URL from session' , { openidId } ) ;
415+ return { authenticatedFetch, podUrl : req . session . solidCachedPodUrl } ;
416+ }
417+
418+ const authenticatedFetch = await getSolidFetch ( req ) ;
419+ const podUrl = await getPodUrl ( openidId , authenticatedFetch ) ;
420+ if ( req . session ) {
421+ req . session . solidCachedPodUrl = podUrl ;
422+ req . session . solidCachedPodUrlWebId = openidId ;
423+ }
424+ return { authenticatedFetch, podUrl } ;
425+ }
426+
397427/**
398428 * Get base storage path for LibreChat data in Pod
399429 *
@@ -574,8 +604,7 @@ async function ensureBaseStructureReady(req) {
574604 }
575605 let promise = baseStructureBatonMap . get ( openidId ) ;
576606 if ( ! promise ) {
577- const authenticatedFetch = await getSolidFetch ( req ) ;
578- const podUrl = await getPodUrl ( openidId , authenticatedFetch ) ;
607+ const { authenticatedFetch, podUrl } = await getSolidFetchAndPodUrl ( req ) ;
579608 promise = ensureBaseStructure ( podUrl , authenticatedFetch ) . catch ( ( err ) => {
580609 baseStructureBatonMap . delete ( openidId ) ;
581610 throw err ;
@@ -600,8 +629,7 @@ function startBaseStructureAfterLogin(req) {
600629
601630 const promise = ( async ( ) => {
602631 try {
603- const authenticatedFetch = await getSolidFetch ( req ) ;
604- const podUrl = await getPodUrl ( openidId , authenticatedFetch ) ;
632+ const { authenticatedFetch, podUrl } = await getSolidFetchAndPodUrl ( req ) ;
605633 await ensureBaseStructure ( podUrl , authenticatedFetch ) ;
606634 logger . debug ( '[SolidStorage] Base structure ready after login' , { openidId } ) ;
607635 } catch ( err ) {
@@ -645,8 +673,7 @@ async function saveMessageToSolid(req, messageDocument, metadata) {
645673 }
646674
647675 await ensureBaseStructureReady ( req ) ;
648- const authenticatedFetch = await getSolidFetch ( req ) ;
649- const podUrl = await getPodUrl ( req . user . openidId , authenticatedFetch ) ;
676+ const { authenticatedFetch, podUrl } = await getSolidFetchAndPodUrl ( req ) ;
650677
651678 const messagesContainerPath = getMessagesContainerPath ( podUrl , messageDocument . conversationId ) ;
652679 await ensureContainerExists ( messagesContainerPath , authenticatedFetch ) ;
@@ -743,8 +770,7 @@ async function getMessagesFromSolid(req, conversationId) {
743770 }
744771
745772 // Get authenticated fetch and Pod URL
746- const authenticatedFetch = await getSolidFetch ( req ) ;
747- const podUrl = await getPodUrl ( req . user . openidId , authenticatedFetch ) ;
773+ const { authenticatedFetch, podUrl } = await getSolidFetchAndPodUrl ( req ) ;
748774
749775 // Get messages container path
750776 const messagesContainerPath = getMessagesContainerPath ( podUrl , conversationId ) ;
@@ -919,8 +945,7 @@ async function updateMessageInSolid(req, messageData, metadata) {
919945 }
920946
921947 // Get authenticated fetch and Pod URL
922- const authenticatedFetch = await getSolidFetch ( req ) ;
923- const podUrl = await getPodUrl ( req . user . openidId , authenticatedFetch ) ;
948+ const { authenticatedFetch, podUrl } = await getSolidFetchAndPodUrl ( req ) ;
924949
925950 // First, try to get the existing message to merge updates
926951 let existingMessage = null ;
@@ -1124,8 +1149,7 @@ async function deleteMessagesFromSolid(req, params) {
11241149 }
11251150
11261151 // Get authenticated fetch and Pod URL
1127- const authenticatedFetch = await getSolidFetch ( req ) ;
1128- const podUrl = await getPodUrl ( req . user . openidId , authenticatedFetch ) ;
1152+ const { authenticatedFetch, podUrl } = await getSolidFetchAndPodUrl ( req ) ;
11291153
11301154 // Get messages container path
11311155 const _messagesContainerPath = getMessagesContainerPath ( podUrl , params . conversationId ) ;
@@ -1271,8 +1295,7 @@ async function saveConvoToSolid(req, convoDocument, metadata) {
12711295 }
12721296
12731297 await ensureBaseStructureReady ( req ) ;
1274- const authenticatedFetch = await getSolidFetch ( req ) ;
1275- const podUrl = await getPodUrl ( req . user . openidId , authenticatedFetch ) ;
1298+ const { authenticatedFetch, podUrl } = await getSolidFetchAndPodUrl ( req ) ;
12761299
12771300 const conversationPath = getConversationPath ( podUrl , finalConversationId ) ;
12781301
@@ -1421,8 +1444,7 @@ async function getConvoFromSolid(req, conversationId) {
14211444 }
14221445
14231446 // Get authenticated fetch and Pod URL
1424- const authenticatedFetch = await getSolidFetch ( req ) ;
1425- const podUrl = await getPodUrl ( req . user . openidId , authenticatedFetch ) ;
1447+ const { authenticatedFetch, podUrl } = await getSolidFetchAndPodUrl ( req ) ;
14261448
14271449 // Get conversation file path
14281450 const conversationPath = getConversationPath ( podUrl , conversationId ) ;
@@ -1640,9 +1662,8 @@ async function getConvosByCursorFromSolid(req, options = {}) {
16401662 const finalSortDirection = sortDirection === 'asc' ? 'asc' : 'desc' ;
16411663
16421664 // Get authenticated fetch and Pod URL
1643- const authenticatedFetch = await getSolidFetch ( req ) ;
1665+ const { authenticatedFetch, podUrl } = await getSolidFetchAndPodUrl ( req ) ;
16441666 // TODO: Allow user to select their storage (can happen after the initial PR).
1645- const podUrl = await getPodUrl ( req . user . openidId , authenticatedFetch ) ;
16461667
16471668 // Get conversations container path
16481669 const conversationsContainerPath = `${ getBaseStoragePath ( podUrl ) } conversations/` ;
@@ -1967,8 +1988,7 @@ async function deleteConvosFromSolid(req, conversationIds) {
19671988 }
19681989
19691990 // Get authenticated fetch and Pod URL
1970- const authenticatedFetch = await getSolidFetch ( req ) ;
1971- const podUrl = await getPodUrl ( req . user . openidId , authenticatedFetch ) ;
1991+ const { authenticatedFetch, podUrl } = await getSolidFetchAndPodUrl ( req ) ;
19721992
19731993 let deletedCount = 0 ;
19741994
@@ -2548,8 +2568,7 @@ async function setPublicAccessForShare(req, conversationId) {
25482568 }
25492569
25502570 // Get authenticated fetch and Pod URL
2551- const authenticatedFetch = await getSolidFetch ( req ) ;
2552- const podUrl = await getPodUrl ( req . user . openidId , authenticatedFetch ) ;
2571+ const { authenticatedFetch, podUrl } = await getSolidFetchAndPodUrl ( req ) ;
25532572
25542573 // Get conversation file path
25552574 const conversationPath = getConversationPath ( podUrl , conversationId ) ;
@@ -2717,8 +2736,7 @@ async function removePublicAccessForShare(req, conversationId) {
27172736 }
27182737
27192738 // Get authenticated fetch and Pod URL
2720- const authenticatedFetch = await getSolidFetch ( req ) ;
2721- const podUrl = await getPodUrl ( req . user . openidId , authenticatedFetch ) ;
2739+ const { authenticatedFetch, podUrl } = await getSolidFetchAndPodUrl ( req ) ;
27222740
27232741 // Get conversation file path
27242742 const conversationPath = getConversationPath ( podUrl , conversationId ) ;
0 commit comments