const { logger } = require('@librechat/data-schemas'); const { encrypt, decrypt } = require('@librechat/api'); const { findOnePluginAuth, updatePluginAuth, deletePluginAuth } = require('~/models'); /** * Asynchronously retrieves and decrypts the authentication value for a user's plugin, based on a specified authentication field. * * @param {string} userId - The unique identifier of the user for whom the plugin authentication value is to be retrieved. * @param {string} authField - The specific authentication field (e.g., 'API_KEY', 'URL') whose value is to be retrieved and decrypted. * @param {boolean} throwError - Whether to throw an error if the authentication value does not exist. Defaults to `true`. * @param {string} [pluginKey] - Optional plugin key to make the lookup more specific to a particular plugin. * @returns {Promise} A promise that resolves to the decrypted authentication value if found, or `null` if no such authentication value exists for the given user and field. * * The function throws an error if it encounters any issue during the retrieval or decryption process, or if the authentication value does not exist. * * @example * // To get the decrypted value of the 'token' field for a user with userId '12345': * getUserPluginAuthValue('12345', 'token').then(value => { * console.log(value); * }).catch(err => { * console.error(err); * }); * * @example * // To get the decrypted value of the 'API_KEY' field for a specific plugin: * getUserPluginAuthValue('12345', 'API_KEY', true, 'mcp-server-name').then(value => { * console.log(value); * }).catch(err => { * console.error(err); * }); * * @throws {Error} Throws an error if there's an issue during the retrieval or decryption process, or if the authentication value does not exist. * @async */ const getUserPluginAuthValue = async (userId, authField, throwError = true, pluginKey) => { try { const searchParams = { userId, authField }; if (pluginKey) { searchParams.pluginKey = pluginKey; } const pluginAuth = await findOnePluginAuth(searchParams); if (!pluginAuth) { const pluginInfo = pluginKey ? ` for plugin ${pluginKey}` : ''; throw new Error(`No plugin auth ${authField} found for user ${userId}${pluginInfo}`); } const decryptedValue = await decrypt(pluginAuth.value); return decryptedValue; } catch (err) { if (!throwError) { return null; } logger.error('[getUserPluginAuthValue]', err); throw err; } }; // const updateUserPluginAuth = async (userId, authField, pluginKey, value) => { // try { // const encryptedValue = encrypt(value); // const pluginAuth = await PluginAuth.findOneAndUpdate( // { userId, authField }, // { // $set: { // value: encryptedValue, // pluginKey // } // }, // { // new: true, // upsert: true // } // ); // return pluginAuth; // } catch (err) { // logger.error('[getUserPluginAuthValue]', err); // return err; // } // }; /** * * @async * @param {string} userId * @param {string} authField * @param {string} pluginKey * @param {string} value * @returns {Promise} * @throws {Error} */ const updateUserPluginAuth = async (userId, authField, pluginKey, value) => { try { const encryptedValue = await encrypt(value); return await updatePluginAuth({ userId, authField, pluginKey, value: encryptedValue, }); } catch (err) { logger.error('[updateUserPluginAuth]', err); return err; } }; /** * @async * @param {string} userId * @param {string | null} authField - The specific authField to delete, or null if `all` is true. * @param {boolean} [all=false] - Whether to delete all auths for the user (or for a specific pluginKey if provided). * @param {string} [pluginKey] - Optional. If `all` is true and `pluginKey` is provided, delete all auths for this user and pluginKey. * @returns {Promise} * @throws {Error} */ const deleteUserPluginAuth = async (userId, authField, all = false, pluginKey) => { try { return await deletePluginAuth({ userId, authField, pluginKey, all, }); } catch (err) { logger.error( `[deleteUserPluginAuth] Error deleting ${all ? 'all' : 'single'} auth(s) for userId: ${userId}${pluginKey ? ` and pluginKey: ${pluginKey}` : ''}`, err, ); return err; } }; module.exports = { getUserPluginAuthValue, updateUserPluginAuth, deleteUserPluginAuth, };