import React, { useMemo } from 'react'; import DOMPurify from 'dompurify'; import { useForm, Controller } from 'react-hook-form'; import { Input, Label, Button } from '@librechat/client'; import { useMCPAuthValuesQuery } from '~/data-provider/Tools/queries'; import { useLocalize } from '~/hooks'; export interface CustomUserVarConfig { title: string; description?: string; } interface CustomUserVarsSectionProps { serverName: string; fields: Record; onSave: (authData: Record) => void; onRevoke: () => void; isSubmitting?: boolean; } interface AuthFieldProps { name: string; config: CustomUserVarConfig; hasValue: boolean; control: any; errors: any; } function AuthField({ name, config, hasValue, control, errors }: AuthFieldProps) { const localize = useLocalize(); const sanitizer = useMemo(() => { const instance = DOMPurify(); instance.addHook('afterSanitizeAttributes', (node) => { if (node.tagName && node.tagName === 'A') { node.setAttribute('target', '_blank'); node.setAttribute('rel', 'noopener noreferrer'); } }); return instance; }, []); const sanitizedDescription = useMemo(() => { if (!config.description) { return ''; } try { return sanitizer.sanitize(config.description, { ALLOWED_TAGS: ['a', 'strong', 'b', 'em', 'i', 'br', 'code'], ALLOWED_ATTR: ['href', 'class', 'target', 'rel'], ALLOW_DATA_ATTR: false, ALLOW_ARIA_ATTR: false, }); } catch (error) { console.error('Sanitization failed', error); return config.description; } }, [config.description, sanitizer]); return (
{hasValue ? (
{localize('com_ui_set')}
) : (
{localize('com_ui_unset')}
)}
( )} /> {sanitizedDescription && (

)} {errors[name] &&

{errors[name]?.message}

}
); } export default function CustomUserVarsSection({ fields, onSave, onRevoke, serverName, isSubmitting = false, }: CustomUserVarsSectionProps) { const localize = useLocalize(); const { data: authValuesData } = useMCPAuthValuesQuery(serverName, { enabled: !!serverName, }); const { reset, control, handleSubmit, formState: { errors }, } = useForm>({ defaultValues: useMemo(() => { const initial: Record = {}; Object.keys(fields).forEach((key) => { initial[key] = ''; }); return initial; }, [fields]), }); const onFormSubmit = (data: Record) => { onSave(data); }; const handleRevokeClick = () => { onRevoke(); reset(); }; if (!fields || Object.keys(fields).length === 0) { return null; } return (
{Object.entries(fields).map(([key, config]) => { const hasValue = authValuesData?.authValueFlags?.[key] || false; return ( ); })}
); }