🔒 feat: Implement Granular File Storage Strategies and Access Control Middleware

This commit is contained in:
“Praneeth 2025-07-25 16:50:18 +02:00 committed by Danny Avila
parent 74e029e78f
commit ff54cbffd9
No known key found for this signature in database
GPG key ID: BF31EEB2C5CA0956
13 changed files with 269 additions and 210 deletions

View file

@ -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}
/>
);
}

View file

@ -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>