feat(bestdebrid): add BestDebrid web-login provider

- New BestDebrid web-login option (BrowserWindow + session.fetch)
- Uses bestdebrid.com/api/v1/generateLink with browser session cookies
- Login via BestDebrid website in embedded browser window
- Toggle "BestDebrid per Web-Login statt API-Token verwenden"
- Provider label shows "BestDebrid (Web)" or "BestDebrid (API)"
- Session persistence respects "Token merken" setting

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Sucukdeluxe
2026-03-06 11:26:48 +01:00
co-authored by Claude Opus 4.6
parent 54e502b9af
commit 438a9f209e
12 changed files with 368 additions and 7 deletions
+18 -2
View File
@@ -34,11 +34,13 @@ interface ProviderUnrestrictedLink extends UnrestrictedLink {
export type MegaWebUnrestrictor = (link: string, signal?: AbortSignal) => Promise<UnrestrictedLink | null>;
export type AllDebridWebUnrestrictor = (link: string, signal?: AbortSignal) => Promise<UnrestrictedLink | null>;
export type RealDebridWebUnrestrictor = (link: string, signal?: AbortSignal) => Promise<UnrestrictedLink | null>;
export type BestDebridWebUnrestrictor = (link: string, signal?: AbortSignal) => Promise<UnrestrictedLink | null>;
interface DebridServiceOptions {
megaWebUnrestrict?: MegaWebUnrestrictor;
allDebridWebUnrestrict?: AllDebridWebUnrestrictor;
realDebridWebUnrestrict?: RealDebridWebUnrestrictor;
bestDebridWebUnrestrict?: BestDebridWebUnrestrictor;
}
function cloneSettings(settings: AppSettings): AppSettings {
@@ -1585,6 +1587,10 @@ export class DebridService {
return Boolean(settings.allDebridUseWebLogin && this.options.allDebridWebUnrestrict);
}
private shouldUseBestDebridWeb(settings: AppSettings): boolean {
return Boolean(settings.bestDebridUseWebLogin && this.options.bestDebridWebUnrestrict);
}
public async unrestrictLink(link: string, signal?: AbortSignal, settingsSnapshot?: AppSettings): Promise<ProviderUnrestrictedLink> {
const settings = settingsSnapshot ? cloneSettings(settingsSnapshot) : cloneSettings(this.settings);
@@ -1718,7 +1724,7 @@ export class DebridService {
if (provider === "onefichier") {
return Boolean(settings.oneFichierApiKey.trim());
}
return Boolean(settings.bestToken.trim());
return Boolean(this.shouldUseBestDebridWeb(settings) || settings.bestToken.trim());
}
private async unrestrictViaProvider(settings: AppSettings, provider: DebridProvider, link: string, signal?: AbortSignal): Promise<UnrestrictedLink> {
@@ -1757,6 +1763,16 @@ export class DebridService {
if (provider === "onefichier") {
return new OneFichierClient(settings.oneFichierApiKey).unrestrictLink(link, signal);
}
return new BestDebridClient(settings.bestToken).unrestrictLink(link, signal);
if (this.shouldUseBestDebridWeb(settings) && this.options.bestDebridWebUnrestrict) {
const bdResult = await this.options.bestDebridWebUnrestrict(link, signal);
if (!bdResult) {
throw new Error("BestDebrid-Web-Fallback nicht verfügbar");
}
bdResult.sourceLabel = "Web";
return bdResult;
}
const bdResult = await new BestDebridClient(settings.bestToken).unrestrictLink(link, signal);
bdResult.sourceLabel = "API";
return bdResult;
}
}