mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-28 14:18:51 +01:00
🔒 feat: Implement Granular File Storage Strategies and Access Control Middleware
This commit is contained in:
parent
74e029e78f
commit
ff54cbffd9
13 changed files with 269 additions and 210 deletions
|
|
@ -130,9 +130,10 @@ export function Citation(props: CitationComponentProps) {
|
|||
|
||||
// Setup file download hook
|
||||
const isFileType = refData?.refType === 'file' && (refData as any)?.fileId;
|
||||
const isLocalFile = isFileType && (refData as any)?.metadata?.storageType === 'local';
|
||||
const { refetch: downloadFile } = useFileDownload(
|
||||
user?.id ?? '',
|
||||
isFileType ? (refData as any).fileId : '',
|
||||
isFileType && !isLocalFile ? (refData as any).fileId : '',
|
||||
);
|
||||
|
||||
const handleFileDownload = useCallback(
|
||||
|
|
@ -142,6 +143,15 @@ export function Citation(props: CitationComponentProps) {
|
|||
|
||||
if (!isFileType || !(refData as any)?.fileId) return;
|
||||
|
||||
// Don't allow download for local files
|
||||
if (isLocalFile) {
|
||||
showToast({
|
||||
status: 'error',
|
||||
message: localize('com_sources_download_local_unavailable'),
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const stream = await downloadFile();
|
||||
if (stream.data == null || stream.data === '') {
|
||||
|
|
@ -167,7 +177,7 @@ export function Citation(props: CitationComponentProps) {
|
|||
});
|
||||
}
|
||||
},
|
||||
[downloadFile, isFileType, refData, localize, showToast],
|
||||
[downloadFile, isFileType, isLocalFile, refData, localize, showToast],
|
||||
);
|
||||
|
||||
if (!refData) return null;
|
||||
|
|
@ -187,8 +197,9 @@ export function Citation(props: CitationComponentProps) {
|
|||
label={getCitationLabel()}
|
||||
onMouseEnter={() => setHoveredCitationId(citationId || null)}
|
||||
onMouseLeave={() => setHoveredCitationId(null)}
|
||||
onClick={isFileType ? handleFileDownload : undefined}
|
||||
onClick={isFileType && !isLocalFile ? handleFileDownload : undefined}
|
||||
isFile={isFileType}
|
||||
isLocalFile={isLocalFile}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ interface SourceHovercardProps {
|
|||
onMouseLeave?: () => void;
|
||||
onClick?: (e: React.MouseEvent) => void;
|
||||
isFile?: boolean;
|
||||
isLocalFile?: boolean;
|
||||
children?: ReactNode;
|
||||
}
|
||||
|
||||
|
|
@ -50,6 +51,7 @@ export function SourceHovercard({
|
|||
onMouseLeave,
|
||||
onClick,
|
||||
isFile = false,
|
||||
isLocalFile = false,
|
||||
children,
|
||||
}: SourceHovercardProps) {
|
||||
const localize = useLocalize();
|
||||
|
|
@ -64,9 +66,16 @@ export function SourceHovercard({
|
|||
isFile ? (
|
||||
<button
|
||||
onClick={onClick}
|
||||
className="ml-1 inline-block h-5 max-w-36 cursor-pointer items-center overflow-hidden text-ellipsis whitespace-nowrap rounded-xl border border-border-heavy bg-surface-secondary px-2 text-xs font-medium text-blue-600 no-underline transition-colors hover:bg-surface-hover dark:border-border-medium dark:text-blue-400 dark:hover:bg-surface-tertiary"
|
||||
className={`ml-1 inline-block h-5 max-w-36 items-center overflow-hidden text-ellipsis whitespace-nowrap rounded-xl border border-border-heavy bg-surface-secondary px-2 text-xs font-medium no-underline transition-colors ${
|
||||
isLocalFile
|
||||
? 'cursor-default text-text-tertiary opacity-60'
|
||||
: 'cursor-pointer text-blue-600 hover:bg-surface-hover dark:text-blue-400 dark:hover:bg-surface-tertiary'
|
||||
} dark:border-border-medium`}
|
||||
onMouseEnter={onMouseEnter}
|
||||
onMouseLeave={onMouseLeave}
|
||||
title={
|
||||
isLocalFile ? localize('com_sources_download_local_unavailable') : undefined
|
||||
}
|
||||
>
|
||||
{label}
|
||||
</button>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue