v0.3.49: Dedup validation — validate cached link before returning to avoid showing invalid links

This commit is contained in:
2026-05-18 01:06:28 +08:00
parent e4e3884ffc
commit 7f4ab50557
13 changed files with 1635 additions and 37 deletions

View File

@@ -58,35 +58,51 @@ async function doSaveFromShare(shareUrl: string, cloudType: string, sourceTitle?
dedupCutoff = recentCutoff.cutoff;
const recentRecord = db.prepare(
`SELECT share_url, share_pwd, status, error_message, folder_name, original_folder_name FROM save_records
`SELECT share_url, share_pwd, status, file_size, error_message, folder_name, original_folder_name FROM save_records
WHERE source_url = ? AND created_at >= ?
ORDER BY created_at DESC LIMIT 1`
).get(shareUrl, dedupCutoff) as {
share_url: string | null; share_pwd: string | null; status: string;
share_url: string | null; share_pwd: string | null; status: string; file_size: string | null;
error_message: string | null; folder_name: string | null; original_folder_name: string | null;
} | undefined;
if (recentRecord) {
const alreadySaved = recentRecord.status === 'success' || recentRecord.status === 'reused';
if (alreadySaved && recentRecord.share_url) {
console.log(`[Share] 🛡️ Dedup: ${shareUrl} was saved ${DEDUP_WINDOW_SEC}s ago (status=${recentRecord.status}), returning existing share link`);
db.prepare(
`INSERT INTO save_records (source_type, source_title, source_url, target_cloud, share_url, share_pwd, file_size, file_count, folder_count, duration_ms, status, error_message, folder_name, original_folder_name, ip_address, ip_location, created_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
).run(
cloudType, sourceTitle || null, shareUrl, cloudType,
recentRecord.share_url, recentRecord.share_pwd || null,
null, 0, 0, 0, 'reused', null,
recentRecord.folder_name || null, recentRecord.original_folder_name || null,
ipAddress || null, ipLocation, localTimestamp(),
);
return {
success: true,
message: `🛡️ 此资源刚在 ${DEDUP_WINDOW_SEC} 秒内转存过,直接返回已有分享链接`,
share_url: recentRecord.share_url, shareUrl: recentRecord.share_url,
sharePwd: recentRecord.share_pwd || '', folderName: '',
file_count: 0, folder_count: 0, duration_ms: 0,
};
// Validate the cached link before returning — avoid returning an invalid link
let dedupLinkInvalid = false;
try {
const { LinkValidator: DedupLinkValidator } = await import('../validation/link-validator.service');
const dedupValidator = new DedupLinkValidator();
const dedupValidation = await dedupValidator.validate(recentRecord.share_url, 'quark');
if (dedupValidation.status !== 'valid') {
dedupLinkInvalid = true;
console.log(`[Share] 🛡️ Dedup link invalid (${dedupValidation.message}), falling through to normal save`);
}
} catch (err: any) {
console.log(`[Share] 🛡️ Dedup validation error: ${err.message}, falling through`);
dedupLinkInvalid = true;
}
if (!dedupLinkInvalid) {
console.log(`[Share] 🛡️ Dedup: ${shareUrl} was saved ${DEDUP_WINDOW_SEC}s ago (status=${recentRecord.status}), returning existing share link`);
db.prepare(
`INSERT INTO save_records (source_type, source_title, source_url, target_cloud, share_url, share_pwd, file_size, file_count, folder_count, duration_ms, status, error_message, folder_name, original_folder_name, ip_address, ip_location, created_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
).run(
cloudType, sourceTitle || null, shareUrl, cloudType,
recentRecord.share_url, recentRecord.share_pwd || null,
recentRecord.file_size || null, 0, 0, 0, 'reused', null,
recentRecord.folder_name || null, recentRecord.original_folder_name || null,
ipAddress || null, ipLocation, localTimestamp(),
);
return {
success: true,
message: `🛡️ 此资源刚在 ${DEDUP_WINDOW_SEC} 秒内转存过,直接返回已有分享链接`,
share_url: recentRecord.share_url, shareUrl: recentRecord.share_url,
sharePwd: recentRecord.share_pwd || '', folderName: '',
file_count: 0, folder_count: 0, duration_ms: 0,
};
}
}
}
} catch (err: any) {
@@ -98,10 +114,10 @@ async function doSaveFromShare(shareUrl: string, cloudType: string, sourceTitle?
if (reuseEnabled !== 'false') {
try {
const existing = db.prepare(
`SELECT share_url, share_pwd, folder_name, original_folder_name FROM save_records
`SELECT share_url, share_pwd, file_size, folder_name, original_folder_name FROM save_records
WHERE source_url = ? AND status IN ('success', 'reused') AND share_url IS NOT NULL AND share_url != ''
ORDER BY created_at DESC LIMIT 1`
).get(shareUrl) as { share_url: string; share_pwd: string; folder_name: string | null; original_folder_name: string | null } | undefined;
).get(shareUrl) as { share_url: string; share_pwd: string; file_size: string | null; folder_name: string | null; original_folder_name: string | null } | undefined;
if (existing?.share_url) {
const { LinkValidator } = await import('../validation/link-validator.service');
@@ -123,7 +139,7 @@ async function doSaveFromShare(shareUrl: string, cloudType: string, sourceTitle?
).run(
cloudType, sourceTitle || null, shareUrl, cloudType,
existing.share_url, existing.share_pwd || null,
null, 0, 0, 0, reuseStatus, null,
existing.file_size || null, 0, 0, 0, reuseStatus, null,
existing.folder_name || null, existing.original_folder_name || null,
ipAddress || null, ipLocation, localTimestamp(),
);
@@ -220,7 +236,7 @@ async function doSaveFromShare(shareUrl: string, cloudType: string, sourceTitle?
).run(
cloudType, sourceTitle || driverResult.folderName || null, shareUrl, cloudType, config.id, config.promotion_account || null,
driverResult.shareUrl || null, driverResult.sharePwd || null,
null, driverResult.fileCount || 0, driverResult.folderCount || 0,
(driverResult as any).fileSize || null, driverResult.fileCount || 0, driverResult.folderCount || 0,
durationMs, driverResult.success ? 'success' : 'failed',
driverResult.success ? null : driverResult.message,
driverResult.folderName || null, driverResult.originalFolderName || null,