Root cause of the recurring "kein Filecode — Server gab leeren Link zurueck": the web-session upload flow gets the filecode back inside an XFileSharing HTML form, and on long/large uploads that form comes back empty (no fn). Verified research: doodstream's server-side file-registration callback times out under large-file load, so the upload "succeeds" (bytes sent, HTTP 200) but no filecode is minted — and because registration failed, the file is NOT in the file list either, so polling can't recover it. The web path also rides a per-page-load sess_id token that ages over the multi-minute upload. The official doodapi.co JSON API has no such failure mode for result retrieval: the upload response returns result[0].filecode directly, and it authenticates with a persistent api_key (no aging sess_id). Git history confirms the API was doodstream's ORIGINAL upload path (initial commit); web login was added later only "as an alternative to API key" — so preferring the key restores the intended primary path rather than fighting a deliberate choice. - lib/account-auth.js (new, pure, unit-tested): selectUploadAuth() prefers the doodstream API key over username/password; all other hosters unchanged. - main.js buildTaskFromAccount delegates to it → a doodstream account with an apiKey now routes through hosters.uploadFile (doodapi API) instead of the web uploader; keyless accounts keep using web login. - hosters.js: drop the stale hardcoded fallback node from the doodstream API config (same dead tr1128ve host removed from the web path) so a failed server lookup throws cleanly instead of uploading into a dead end. - Tests: 8 routing cases (doodstream key-preference, keyless fallback, voe unaffected, authType=api, null-safety). Full suite 173/173. This eliminates the empty-form failure mode for result retrieval when a key is configured. It does NOT change doodstream's backend — whether the large-file timeout recurs (now as a structured JSON error, not a silent empty form) is for the server run to confirm. Requires a doodstream API key on the account. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
45 lines
2.0 KiB
JavaScript
45 lines
2.0 KiB
JavaScript
const { test } = require('node:test');
|
|
const assert = require('node:assert');
|
|
const { selectUploadAuth } = require('../lib/account-auth');
|
|
|
|
test('doodstream prefers the API key even when username/password are also set', () => {
|
|
const auth = selectUploadAuth('doodstream.com', {
|
|
apiKey: 'KEY123', username: 'u', password: 'p'
|
|
});
|
|
assert.deepEqual(auth, { apiKey: 'KEY123' }); // API path — no username leaks through
|
|
});
|
|
|
|
test('doodstream with only username/password uses web login (keyless fallback)', () => {
|
|
const auth = selectUploadAuth('doodstream.com', { username: 'u', password: 'p' });
|
|
assert.deepEqual(auth, { username: 'u', password: 'p' });
|
|
});
|
|
|
|
test('doodstream with empty apiKey + creds falls back to web login (no false API route)', () => {
|
|
const auth = selectUploadAuth('doodstream.com', { apiKey: '', username: 'u', password: 'p' });
|
|
assert.deepEqual(auth, { username: 'u', password: 'p' });
|
|
});
|
|
|
|
test('doodstream with nothing usable returns empty', () => {
|
|
assert.deepEqual(selectUploadAuth('doodstream.com', { apiKey: '', username: '', password: '' }), {});
|
|
});
|
|
|
|
test('voe.sx is unaffected by the doodstream special-case: username/password wins', () => {
|
|
// voe also supports both, but the empty-form bug is doodstream-specific; do
|
|
// not change voe routing.
|
|
const auth = selectUploadAuth('voe.sx', { apiKey: 'VKEY', username: 'u', password: 'p' });
|
|
assert.deepEqual(auth, { username: 'u', password: 'p' });
|
|
});
|
|
|
|
test('authType=api forces the API key for any hoster', () => {
|
|
assert.deepEqual(selectUploadAuth('voe.sx', { authType: 'api', apiKey: 'K', username: 'u', password: 'p' }), { apiKey: 'K' });
|
|
});
|
|
|
|
test('api-key-only account (no creds) uses the key', () => {
|
|
assert.deepEqual(selectUploadAuth('byse.sx', { apiKey: 'BKEY' }), { apiKey: 'BKEY' });
|
|
});
|
|
|
|
test('null / non-object account does not throw', () => {
|
|
assert.deepEqual(selectUploadAuth('doodstream.com', null), {});
|
|
assert.deepEqual(selectUploadAuth('doodstream.com', undefined), {});
|
|
});
|