Skip to content

Commit 9a1b505

Browse files
committed
Add vault ZIP download
1 parent 0e676c2 commit 9a1b505

7 files changed

Lines changed: 433 additions & 9 deletions

File tree

Cargo.lock

Lines changed: 147 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ resolver = "2"
1111
# The workspace doesn't have its own dependencies
1212
[workspace.package]
1313
edition = "2021"
14-
version = "0.1.5"
14+
version = "0.1.6"
1515
authors = ["Sarav"]
1616
license = "AGPL-3.0-or-later"
1717
homepage = "https://github.com/srv1n/kurpod"

encryption_core/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "encryption_core"
3-
version = "0.1.5"
3+
version = "0.1.6"
44
edition = "2021"
55
description = "Core encryption and blob storage logic"
66

frontend/src/App.jsx

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import UploadManager from './components/UploadManager';
1212
import MobileSidebar from './components/MobileSidebar';
1313
import { MobileBreadcrumb } from './components/MobileBreadcrumb';
1414
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator } from '@/components/ui/dropdown-menu';
15-
import { ArrowUpTrayIcon, FolderPlusIcon, Cog6ToothIcon, WrenchScrewdriverIcon } from '@heroicons/react/24/outline';
15+
import { ArrowDownTrayIcon, ArrowUpTrayIcon, FolderPlusIcon, Cog6ToothIcon, WrenchScrewdriverIcon } from '@heroicons/react/24/outline';
1616
import apiService from './services/api.js';
1717

1818
function UnlockScreen() {
@@ -192,6 +192,7 @@ function Dashboard() {
192192
const [showUploadManager, setShowUploadManager] = useState(false);
193193
const [uploadType, setUploadType] = useState('single');
194194
const [refreshTrigger, setRefreshTrigger] = useState(0);
195+
const [downloadingVault, setDownloadingVault] = useState(false);
195196
const { logout, volumeType, apiCall } = useAuth();
196197

197198
// Handle file preview
@@ -221,6 +222,35 @@ function Dashboard() {
221222
toast.success('Upload completed successfully!');
222223
}, []);
223224

225+
// Download the complete unlocked volume as a ZIP archive
226+
const handleDownloadVault = useCallback(async () => {
227+
if (downloadingVault) return;
228+
229+
setDownloadingVault(true);
230+
try {
231+
const response = await apiCall('/api/download-vault');
232+
if (!response.ok) {
233+
const data = await response.json().catch(() => null);
234+
throw new Error(data?.message || 'Failed to download vault');
235+
}
236+
237+
const archive = await response.blob();
238+
const downloadUrl = URL.createObjectURL(archive);
239+
const anchor = document.createElement('a');
240+
anchor.href = downloadUrl;
241+
anchor.download = 'kurpod-vault.zip';
242+
document.body.appendChild(anchor);
243+
anchor.click();
244+
anchor.remove();
245+
window.setTimeout(() => URL.revokeObjectURL(downloadUrl), 0);
246+
toast.success('Vault download started');
247+
} catch (error) {
248+
toast.error(error.message || 'Failed to download vault');
249+
} finally {
250+
setDownloadingVault(false);
251+
}
252+
}, [apiCall, downloadingVault]);
253+
224254
// Handle file delete
225255
const handleFileDelete = useCallback(async (file) => {
226256
const encodedPath = file.path.split('/').map(segment => encodeURIComponent(segment)).join('/');
@@ -306,6 +336,7 @@ function Dashboard() {
306336
currentPath={currentPath}
307337
onNavigate={handleNavigate}
308338
onUploadStart={handleUploadStart}
339+
onDownloadVault={handleDownloadVault}
309340
onCompactStorage={handleCompaction}
310341
/>
311342

@@ -359,6 +390,14 @@ function Dashboard() {
359390
<FolderPlusIcon className="w-4 h-4 mr-2" />
360391
<span>Folder</span>
361392
</button>
393+
<button
394+
onClick={handleDownloadVault}
395+
disabled={downloadingVault}
396+
className="inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 hover:bg-accent hover:text-accent-foreground h-9 px-4 py-2"
397+
>
398+
<ArrowDownTrayIcon className="w-4 h-4 mr-2" />
399+
<span>{downloadingVault ? 'Preparing...' : 'Download Vault'}</span>
400+
</button>
362401
</div>
363402

364403
{/* Storage Management Dropdown */}

0 commit comments

Comments
 (0)