diff --git a/expressjs/src/server.js b/expressjs/src/server.js index e7f60a2..12b2609 100644 --- a/expressjs/src/server.js +++ b/expressjs/src/server.js @@ -19,6 +19,7 @@ const dataDir = process.env.DATA_DIR || path.join(__dirname, '..', 'data'); const dbPath = process.env.DB_PATH || path.join(__dirname, '..', 'data', 'uploads.sqlite'); const adminHash = process.env.MANAGEMENT_ADMIN_HASH || ''; const uploadTtlSeconds = parseInt(process.env.UPLOAD_TTL_SECONDS || '604800', 10); +const maxRetentionSeconds = 90 * 24 * 60 * 60; const maxUploadBytes = parseInt(process.env.UPLOAD_MAX_BYTES || '0', 10); const shareDir = path.join(dataDir, '_share'); @@ -1262,8 +1263,10 @@ app.post(`${basePath}/admin/files/:id/extend`, requireAdminPage, async (req, res ? Math.round(override * 3600) : uploadTtlSeconds; - const base = Math.max(uploadEntry.expires_at, Date.now()); - const nextExpiry = base + extensionSeconds * 1000; + const now = Date.now(); + const base = Math.max(uploadEntry.expires_at, now); + const maxExpiry = now + maxRetentionSeconds * 1000; + const nextExpiry = Math.min(base + extensionSeconds * 1000, maxExpiry); await run('UPDATE uploads SET expires_at = ? WHERE id = ?', [nextExpiry, uploadEntry.id]); await logEvent('extend', 'admin', { id: uploadEntry.id, expires_at: nextExpiry }); res.redirect(baseUrl('/admin/dashboard')); @@ -1431,6 +1434,7 @@ app.post(`${basePath}/api/upload`, requireAuthApi, upload.single('file'), async const retentionSeconds = Number.isFinite(retentionOverride) && retentionOverride > 0 ? Math.round(retentionOverride * 3600) : uploadTtlSeconds; + const cappedRetention = Math.min(retentionSeconds, maxRetentionSeconds); try { await fs.promises.rename(req.file.path, storedPath); @@ -1453,7 +1457,7 @@ app.post(`${basePath}/api/upload`, requireAuthApi, upload.single('file'), async storedPath, req.file.size, now, - now + retentionSeconds * 1000, + now + cappedRetention * 1000, ] ); await logEvent('upload', req.user.username, { name: storedName, size: req.file.size }); @@ -1495,8 +1499,10 @@ app.post(`${basePath}/files/:id/extend`, requireAuthPage, async (req, res) => { ? Math.round(override * 3600) : uploadTtlSeconds; - const base = Math.max(uploadEntry.expires_at, Date.now()); - const nextExpiry = base + extensionSeconds * 1000; + const now = Date.now(); + const base = Math.max(uploadEntry.expires_at, now); + const maxExpiry = now + maxRetentionSeconds * 1000; + const nextExpiry = Math.min(base + extensionSeconds * 1000, maxExpiry); await run('UPDATE uploads SET expires_at = ? WHERE id = ?', [nextExpiry, uploadEntry.id]); await logEvent('extend', req.user.username, { id: uploadEntry.id, expires_at: nextExpiry }); res.redirect(baseUrl('/dashboard'));