feat(security): shorten download signed URLs to 30s and remove update polling
This commit is contained in:
@@ -97,6 +97,10 @@ const DOWNLOAD_RESERVATION_TTL_MS = Number(process.env.DOWNLOAD_RESERVATION_TTL_
|
||||
const DOWNLOAD_LOG_RECONCILE_INTERVAL_MS = Number(process.env.DOWNLOAD_LOG_RECONCILE_INTERVAL_MS || (5 * 60 * 1000)); // 5分钟
|
||||
const DOWNLOAD_LOG_MAX_FILES_PER_SWEEP = Number(process.env.DOWNLOAD_LOG_MAX_FILES_PER_SWEEP || 40);
|
||||
const DOWNLOAD_LOG_LIST_MAX_KEYS = Number(process.env.DOWNLOAD_LOG_LIST_MAX_KEYS || 200);
|
||||
const DOWNLOAD_SIGNED_URL_EXPIRES_SECONDS = Math.max(
|
||||
10,
|
||||
Math.min(3600, Number(process.env.DOWNLOAD_SIGNED_URL_EXPIRES_SECONDS || 30))
|
||||
);
|
||||
const DEFAULT_DESKTOP_VERSION = process.env.DESKTOP_LATEST_VERSION || '0.1.1';
|
||||
const DEFAULT_DESKTOP_INSTALLER_URL = process.env.DESKTOP_INSTALLER_URL || '';
|
||||
const DEFAULT_DESKTOP_RELEASE_NOTES = process.env.DESKTOP_RELEASE_NOTES || '';
|
||||
@@ -6433,8 +6437,10 @@ app.get('/api/files/download-url', authMiddleware, async (req, res) => {
|
||||
};
|
||||
const command = new GetObjectCommand(commandInput);
|
||||
|
||||
// 生成签名 URL(1小时有效)
|
||||
const signedUrl = await getSignedUrl(client, command, { expiresIn: 3600 });
|
||||
// 生成签名 URL(短时有效,默认30秒)
|
||||
const signedUrl = await getSignedUrl(client, command, {
|
||||
expiresIn: DOWNLOAD_SIGNED_URL_EXPIRES_SECONDS
|
||||
});
|
||||
|
||||
// 直连模式:先预扣保留额度(不写入已用),实际用量由 OSS 日志异步确认入账
|
||||
if (!trafficState.isUnlimited && fileSize > 0) {
|
||||
@@ -6454,7 +6460,7 @@ app.get('/api/files/download-url', authMiddleware, async (req, res) => {
|
||||
res.json({
|
||||
success: true,
|
||||
downloadUrl: signedUrl,
|
||||
expiresIn: 3600,
|
||||
expiresIn: DOWNLOAD_SIGNED_URL_EXPIRES_SECONDS,
|
||||
direct: true,
|
||||
quotaLimited: !trafficState.isUnlimited
|
||||
});
|
||||
@@ -8262,8 +8268,10 @@ app.post('/api/share/:code/download-url', shareRateLimitMiddleware, async (req,
|
||||
ResponseContentDisposition: `attachment; filename="${encodeURIComponent(normalizedFilePath.split('/').pop())}"`
|
||||
});
|
||||
|
||||
// 生成签名 URL(1小时有效)
|
||||
const signedUrl = await getSignedUrl(client, command, { expiresIn: 3600 });
|
||||
// 生成签名 URL(短时有效,默认30秒)
|
||||
const signedUrl = await getSignedUrl(client, command, {
|
||||
expiresIn: DOWNLOAD_SIGNED_URL_EXPIRES_SECONDS
|
||||
});
|
||||
|
||||
if (!ownerTrafficState.isUnlimited && fileSize > 0) {
|
||||
const reserveResult = reserveDirectDownloadTraffic(shareOwner.id, fileSize, {
|
||||
@@ -8284,7 +8292,7 @@ app.post('/api/share/:code/download-url', shareRateLimitMiddleware, async (req,
|
||||
downloadUrl: signedUrl,
|
||||
direct: true,
|
||||
quotaLimited: !ownerTrafficState.isUnlimited,
|
||||
expiresIn: 3600
|
||||
expiresIn: DOWNLOAD_SIGNED_URL_EXPIRES_SECONDS
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
@@ -10588,7 +10596,9 @@ app.get('/d/:code', async (req, res) => {
|
||||
ResponseContentDisposition: `attachment; filename*=UTF-8''${encodeURIComponent(directFileName)}`
|
||||
});
|
||||
|
||||
const signedUrl = await getSignedUrl(client, command, { expiresIn: 3600 });
|
||||
const signedUrl = await getSignedUrl(client, command, {
|
||||
expiresIn: DOWNLOAD_SIGNED_URL_EXPIRES_SECONDS
|
||||
});
|
||||
DirectLinkDB.incrementDownloadCount(code);
|
||||
|
||||
logShare(
|
||||
|
||||
Reference in New Issue
Block a user