feat: add desktop multipart API endpoints for Dragon Wind Desktop app

This commit is contained in:
Zac Gaetano 2026-04-08 22:05:53 -04:00
parent a3d1446060
commit 675ff9985f

View file

@ -918,3 +918,38 @@ server.timeout = 0;
server.keepAliveTimeout = 0;
server.headersTimeout = 0;
server.requestTimeout = 0;
const desktopSessions = new Map();
app.post("/api/desktop/multipart/init", requireAuth, async (req, res) => {
const { filename, size, prefix, totalParts } = req.body;
if (!filename || !size || !totalParts) return res.status(400).json({ error: "Missing fields" });
if (!s3Client) return res.status(503).json({ error: "S3 not configured" });
const s3cfg = db.s3Config || {};
const key = prefix ? prefix.replace(/\/+$/, "") + "/" + filename : filename;
try {
const cr = await s3Client.send(new CreateMultipartUploadCommand({ Bucket: s3cfg.bucket, Key: key }));
const uid = cr.UploadId;
const pp = await Promise.all(Array.from({ length: totalParts }, (_, i) =>
getSignedUrl(s3Client, new UploadPartCommand({ Bucket: s3cfg.bucket, Key: key, UploadId: uid, PartNumber: i+1 }), { expiresIn: 3600 })
));
desktopSessions.set(uid, { key, bucket: s3cfg.bucket });
console.log("[desktop] Init:", key, totalParts, "parts");
res.json({ uploadId: uid, key, bucket: s3cfg.bucket, presignedParts: pp });
} catch (err) { console.error("[desktop] Init error:", err.message); res.status(500).json({ error: err.message }); }
});
app.post("/api/desktop/multipart/complete", requireAuth, async (req, res) => {
const { uploadId, key, bucket, parts } = req.body;
if (!uploadId || !parts) return res.status(400).json({ error: "Missing fields" });
try {
await s3Client.send(new CompleteMultipartUploadCommand({ Bucket: bucket, Key: key, UploadId: uploadId, MultipartUpload: { Parts: parts.sort((a,b)=>a.PartNumber-b.PartNumber) } }));
desktopSessions.delete(uploadId);
console.log("[desktop] Complete:", key);
res.json({ success: true });
} catch (err) { console.error("[desktop] Complete error:", err.message); res.status(500).json({ error: err.message }); }
});
app.post("/api/desktop/multipart/abort", requireAuth, async (req, res) => {
const { uploadId, key, bucket } = req.body;
try { if (uploadId && key && bucket && s3Client) await s3Client.send(new AbortMultipartUploadCommand({ Bucket: bucket, Key: key, UploadId: uploadId })); } catch (_) {}
desktopSessions.delete(uploadId);
res.json({ success: true });
});