mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-18 03:54:17 +02:00
fix(slicer): token-based auth for Open in Slicer downloads (#433)
Slicer protocol handlers (bambustudio://, orcaslicer://) launch the
slicer app which fetches files via HTTP but cannot send auth headers.
The global auth middleware returned 401, causing "importing failed."
Add short-lived, single-use download tokens: the frontend fetches a
token via authenticated POST, then builds a /dl/{token}/{filename} URL
the slicer can access without auth headers. Tokens are validated
server-side (5-min expiry, single-use). Applies to archive files,
source 3MFs, and library files.
Also fix platform-specific URL formats to match slicer source code:
- macOS: bambustudioopen:// with encodeURIComponent
- Windows/Linux: bambustudio://open?file= (was wrongly using macOS scheme on Linux)
- OrcaSlicer: orcaslicer://open?file=
This commit is contained in:
@@ -263,17 +263,29 @@ export function ModelViewerModal({ archiveId, libraryFileId, title, fileType, on
|
||||
|
||||
const canOpenInSlicer = isLibrary ? (fileType || '').toLowerCase() === '3mf' : true;
|
||||
|
||||
const handleOpenInSlicer = () => {
|
||||
const handleOpenInSlicer = async () => {
|
||||
if (!canOpenInSlicer) return;
|
||||
// URL must include .3mf filename for Bambu Studio to recognize the format
|
||||
const filename = title || 'model';
|
||||
if (isLibrary) {
|
||||
const downloadUrl = `${window.location.origin}${api.getLibraryFileDownloadUrl(libraryFileId!)}`;
|
||||
openInSlicer(downloadUrl, preferredSlicer);
|
||||
return;
|
||||
try {
|
||||
if (isLibrary) {
|
||||
const { token } = await api.createLibrarySlicerToken(libraryFileId!);
|
||||
const path = api.getLibrarySlicerDownloadUrl(libraryFileId!, token, filename);
|
||||
openInSlicer(`${window.location.origin}${path}`, preferredSlicer);
|
||||
} else {
|
||||
const { token } = await api.createArchiveSlicerToken(archiveId!);
|
||||
const path = api.getArchiveSlicerDownloadUrl(archiveId!, token, filename);
|
||||
openInSlicer(`${window.location.origin}${path}`, preferredSlicer);
|
||||
}
|
||||
} catch {
|
||||
// Fallback to direct URL (works when auth is disabled)
|
||||
if (isLibrary) {
|
||||
const downloadUrl = `${window.location.origin}${api.getLibraryFileDownloadUrl(libraryFileId!)}`;
|
||||
openInSlicer(downloadUrl, preferredSlicer);
|
||||
} else {
|
||||
const downloadUrl = `${window.location.origin}${api.getArchiveForSlicer(archiveId!, filename)}`;
|
||||
openInSlicer(downloadUrl, preferredSlicer);
|
||||
}
|
||||
}
|
||||
const downloadUrl = `${window.location.origin}${api.getArchiveForSlicer(archiveId!, filename)}`;
|
||||
openInSlicer(downloadUrl, preferredSlicer);
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user