Harden cross-auth recovery and upload admission

Use stable Doodstream API identities across separate Web and API profiles, serialize ambiguous VOE and Doodstream mixed-auth recovery paths, and fail closed after uncertain post-upload response failures. Enforce host upload intervals only after recovery and concurrency admission, and clear batch-scoped recovery caches when the batch settles.
This commit is contained in:
Sucukdeluxe
2026-08-13 23:59:00 +02:00
parent cfa138198f
commit 21840cef94
5 changed files with 350 additions and 21 deletions
+61
View File
@@ -1,5 +1,8 @@
const { test } = require('node:test');
const assert = require('node:assert');
const fs = require('node:fs');
const os = require('node:os');
const path = require('node:path');
const DoodstreamUploader = require('../lib/doodstream-upload');
// The CDN hands back an XFileSharing form. `fn` is the filecode, `st` is the
@@ -268,3 +271,61 @@ test('getUploadServer: failures expose safe structured diagnostics without respo
}
);
});
test('upload response read failure is marked as an uncertain remote commit', async () => {
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'mhu-dood-response-'));
const file = path.join(root, 'episode.mkv');
fs.writeFileSync(file, Buffer.alloc(16, 1));
const up = new DoodstreamUploader();
up.sessId = 'SESSION';
up._getUploadServer = async () => 'https://node.example/upload/01';
up._requestUpload = async () => ({
statusCode: 200,
headers: {},
body: { text: async () => { throw new Error('socket closed'); } }
});
try {
await assert.rejects(
() => up.upload(file),
(err) => {
assert.equal(err.remoteCommitUncertain, true);
assert.equal(err.diagnostic.phase, 'upload-response-read');
return true;
}
);
} finally {
fs.rmSync(root, { recursive: true, force: true });
}
});
test('redirect fetch failure after upload is marked as an uncertain remote commit', async () => {
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'mhu-dood-redirect-'));
const file = path.join(root, 'episode.mkv');
fs.writeFileSync(file, Buffer.alloc(16, 1));
const up = new DoodstreamUploader();
up.sessId = 'SESSION';
up._getUploadServer = async () => 'https://node.example/upload/01';
up._requestUpload = async () => ({
statusCode: 302,
headers: { location: 'https://doodstream.com/upload-result' },
body: { text: async () => '' }
});
up._fetch = async () => {
const error = new Error('redirect fetch failed');
error.diagnostic = { phase: 'web-request' };
error.transientNetwork = true;
throw error;
};
try {
await assert.rejects(
() => up.upload(file),
(err) => {
assert.equal(err.remoteCommitUncertain, true);
assert.equal(err.diagnostic.phase, 'web-request');
return true;
}
);
} finally {
fs.rmSync(root, { recursive: true, force: true });
}
});