This commit is contained in:
@@ -72,6 +72,9 @@ class DoodstreamUploader {
|
||||
}
|
||||
|
||||
async _fetch(url, opts = {}, _redirectCount = 0) {
|
||||
if (opts.allowedOrigin && new URL(url).origin !== opts.allowedOrigin) {
|
||||
throw new Error('Doodstream Login: Unerwartetes Weiterleitungsziel');
|
||||
}
|
||||
const MAX_REDIRECTS = 10;
|
||||
const headers = {
|
||||
'User-Agent': USER_AGENT,
|
||||
@@ -98,7 +101,7 @@ class DoodstreamUploader {
|
||||
} catch (err) {
|
||||
if (opts.signal && opts.signal.aborted) throw err; // caller abort: don't retry
|
||||
if (attempt >= 3) throw err;
|
||||
_debugLog(`_fetch transient (${attempt}/3) ${url}: ${err && err.message}; retry`);
|
||||
_debugLog(`_fetch transient (${attempt}/3) ${new URL(url).origin}: retry`);
|
||||
await new Promise(r => setTimeout(r, 400 * attempt));
|
||||
}
|
||||
}
|
||||
@@ -147,22 +150,24 @@ class DoodstreamUploader {
|
||||
const res = await fetch(`${BASE_URL}/?op=login_ajax&${loginData.toString()}`, {
|
||||
method: 'GET',
|
||||
headers,
|
||||
redirect: 'manual'
|
||||
redirect: 'manual',
|
||||
signal: AbortSignal.timeout(20000)
|
||||
});
|
||||
|
||||
this._parseCookiesFromHeaders(res.headers);
|
||||
let loginRedirect = '';
|
||||
|
||||
// On successful login, server may redirect (3xx) to dashboard
|
||||
if ([301, 302, 303, 307, 308].includes(res.status)) {
|
||||
try { await res.text(); } catch {}
|
||||
// Redirect means login succeeded
|
||||
loginRedirect = res.headers.get('location') || '';
|
||||
} else {
|
||||
const body = await res.text();
|
||||
let json;
|
||||
try { json = JSON.parse(body); } catch { json = null; }
|
||||
|
||||
if (json && ['success', 'redirect'].includes(json.status)) {
|
||||
// Explicit success response
|
||||
if (json.status === 'redirect') loginRedirect = json.message || '';
|
||||
} else if (json && (json.status === 'otp_sent' || (json.message && /otp|verification code/i.test(json.message)))) {
|
||||
// OTP required — signal caller to collect OTP from user
|
||||
const err = new Error(`Doodstream Login: ${json.message || 'OTP erforderlich'}`);
|
||||
@@ -178,7 +183,20 @@ class DoodstreamUploader {
|
||||
}
|
||||
}
|
||||
|
||||
// Extract sess_id from the upload page
|
||||
if (loginRedirect) {
|
||||
const target = new URL(loginRedirect, BASE_URL);
|
||||
if (target.origin !== BASE_URL || target.username || target.password) {
|
||||
throw new Error('Doodstream Login: Unerwartetes Weiterleitungsziel');
|
||||
}
|
||||
const landing = await this._fetch(target.href, { allowedOrigin: BASE_URL });
|
||||
const landingHtml = await landing.text();
|
||||
const sessId = this._findSessId(landingHtml);
|
||||
if (landing.status === 200 && sessId) {
|
||||
this.sessId = sessId;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
await this._extractSessId();
|
||||
}
|
||||
|
||||
@@ -186,13 +204,13 @@ class DoodstreamUploader {
|
||||
const res = await this._fetch(BASE_URL + '/?op=upload');
|
||||
const html = await res.text();
|
||||
const sessId = this._findSessId(html);
|
||||
|
||||
if (sessId) {
|
||||
if (res.status === 200 && sessId) {
|
||||
this.sessId = sessId;
|
||||
return;
|
||||
}
|
||||
|
||||
throw new Error('Doodstream: sess_id nicht gefunden nach Login');
|
||||
this.sessId = '';
|
||||
const guest = /utype\s*:\s*['"]anon['"]/.test(html);
|
||||
throw new Error(`Doodstream: sess_id nicht gefunden nach Login (HTTP ${res.status}; guest=${guest}; sessionField=${/sess_id/.test(html)}; cookies=${this.cookies.size})`);
|
||||
}
|
||||
|
||||
_findSessId(html) {
|
||||
|
||||
Reference in New Issue
Block a user