fix: harden upload cancellation and audit logging
Preserve pre-start and batch cancellation requests, reject late upload success after cancellation, and wait for cancellation acknowledgements before removing queue entries. Separate formatted link logs from privacy-safe source cleanup and upload plan audits, persist audit fallback paths, redact support bundles, and expose audit diagnostics safely. Improve queue selection and destructive-action clarity, show the Settings save action only while changes are pending, and add regression coverage for all updated behavior.
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { getRotatedLogPath } = require('./log-rotation');
|
||||
|
||||
const READABLE_LOGS = {
|
||||
debug: 'debug',
|
||||
fileuploader: 'fileuploader',
|
||||
uploadAudit: 'uploadAudit',
|
||||
accountRotation: 'accountRotation',
|
||||
crash: 'crashLog'
|
||||
};
|
||||
@@ -38,7 +40,7 @@ function createCollectors(deps) {
|
||||
const paths = getAllLogPaths();
|
||||
let p = paths[key];
|
||||
if (!p) return null;
|
||||
if (backup === 1 || backup === 2) p = `${p}.${backup}`;
|
||||
if (backup === 1 || backup === 2) p = getRotatedLogPath(p, backup);
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -67,15 +69,17 @@ function createCollectors(deps) {
|
||||
const paths = getAllLogPaths();
|
||||
const dir = paths.logDir;
|
||||
const files = [];
|
||||
const readableNames = new Set();
|
||||
for (const [name, key] of Object.entries(READABLE_LOGS)) {
|
||||
const base = paths[key];
|
||||
if (!base) continue;
|
||||
const variants = [];
|
||||
for (const suffix of ['', '.1', '.2']) {
|
||||
const fp = base + suffix;
|
||||
for (const backup of [0, 1, 2]) {
|
||||
const fp = backup === 0 ? base : getRotatedLogPath(base, backup);
|
||||
readableNames.add(path.basename(fp));
|
||||
try {
|
||||
const st = fs.statSync(fp);
|
||||
variants.push({ backup: suffix === '' ? 0 : Number(suffix.slice(1)), sizeBytes: st.size, mtime: st.mtime.toISOString() });
|
||||
variants.push({ backup, sizeBytes: st.size, mtime: st.mtime.toISOString() });
|
||||
} catch {}
|
||||
}
|
||||
files.push({ name, path: base, readable: true, present: variants.length > 0, variants });
|
||||
@@ -84,7 +88,7 @@ function createCollectors(deps) {
|
||||
try {
|
||||
siblings = fs.readdirSync(dir)
|
||||
.filter(f => /\.log(\.\d+)?$/i.test(f))
|
||||
.filter(f => !files.some(x => path.basename(x.path) === f || f.startsWith(path.basename(x.path))));
|
||||
.filter(f => !readableNames.has(f));
|
||||
siblings = siblings.map(f => {
|
||||
let size = 0, mtime = null;
|
||||
try { const st = fs.statSync(path.join(dir, f)); size = st.size; mtime = st.mtime.toISOString(); } catch {}
|
||||
|
||||
Reference in New Issue
Block a user