Release v1.4.34 with DLC import package-name and 413 fixes

- Use DLC filename as package name in dcrypt fallback instead of
  inferring from individual URLs (fixes mangled package names)
- Add paste endpoint fallback when dcrypt upload returns 413
- Split decryptDlcViaDcrypt into tryDcryptUpload/tryDcryptPaste
- Add DCRYPT_PASTE_URL constant
- Expand container tests for 413 fallback and dual-failure scenarios

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Sucukdeluxe
2026-03-01 01:51:40 +01:00
co-authored by Claude Opus 4.6
parent edbfba6663
commit 778124312c
4 changed files with 127 additions and 30 deletions
+1
View File
@@ -8,6 +8,7 @@ export const APP_VERSION: string = packageJson.version;
export const API_BASE_URL = "https://api.real-debrid.com/rest/1.0";
export const DCRYPT_UPLOAD_URL = "https://dcrypt.it/decrypt/upload";
export const DCRYPT_PASTE_URL = "https://dcrypt.it/decrypt/paste";
export const DLC_SERVICE_URL = "https://service.jdownloader.org/dlcrypt/service.php?srcType=dlc&destType=pylo&data={KEY}";
export const DLC_AES_KEY = Buffer.from("cb99b5cbc24db398", "utf8");
export const DLC_AES_IV = Buffer.from("9bc24cb995cb8db3", "utf8");
+44 -14
View File
@@ -1,7 +1,7 @@
import fs from "node:fs";
import path from "node:path";
import crypto from "node:crypto";
import { DCRYPT_UPLOAD_URL, DLC_AES_IV, DLC_AES_KEY, DLC_SERVICE_URL } from "./constants";
import { DCRYPT_PASTE_URL, DCRYPT_UPLOAD_URL, DLC_AES_IV, DLC_AES_KEY, DLC_SERVICE_URL } from "./constants";
import { compactErrorText, inferPackageNameFromLinks, isHttpLink, sanitizeFilename, uniquePreserveOrder } from "./utils";
import { ParsedPackageInput } from "../shared/types";
@@ -162,9 +162,17 @@ async function decryptDlcLocal(filePath: string): Promise<ParsedPackageInput[]>
return parsePackagesFromDlcXml(xmlData);
}
async function decryptDlcViaDcrypt(filePath: string): Promise<ParsedPackageInput[]> {
const fileName = path.basename(filePath);
const blob = new Blob([new Uint8Array(readDlcFileWithLimit(filePath))]);
function extractLinksFromResponse(text: string): string[] {
const payload = decodeDcryptPayload(text);
let links = extractUrlsRecursive(payload);
if (links.length === 0) {
links = extractUrlsRecursive(text);
}
return uniquePreserveOrder(links.filter((l) => isHttpLink(l)));
}
async function tryDcryptUpload(fileContent: Buffer, fileName: string): Promise<string[] | null> {
const blob = new Blob([new Uint8Array(fileContent)]);
const form = new FormData();
form.set("dlcfile", blob, fileName);
@@ -172,22 +180,44 @@ async function decryptDlcViaDcrypt(filePath: string): Promise<ParsedPackageInput
method: "POST",
body: form
});
if (response.status === 413) {
return null;
}
const text = await response.text();
if (!response.ok) {
throw new Error(compactErrorText(text));
}
const payload = decodeDcryptPayload(text);
let packages = extractPackagesFromPayload(payload);
if (packages.length === 1) {
const regrouped = groupLinksByName(packages[0].links);
if (regrouped.length > 1) {
packages = regrouped;
}
return extractLinksFromResponse(text);
}
async function tryDcryptPaste(fileContent: Buffer): Promise<string[]> {
const form = new FormData();
form.set("content", fileContent.toString("ascii"));
const response = await fetch(DCRYPT_PASTE_URL, {
method: "POST",
body: form
});
const text = await response.text();
if (!response.ok) {
throw new Error(compactErrorText(text));
}
if (packages.length === 0) {
packages = groupLinksByName(extractUrlsRecursive(text));
return extractLinksFromResponse(text);
}
async function decryptDlcViaDcrypt(filePath: string): Promise<ParsedPackageInput[]> {
const fileContent = readDlcFileWithLimit(filePath);
const fileName = path.basename(filePath);
const packageName = sanitizeFilename(path.basename(filePath, ".dlc")) || "Paket";
let links = await tryDcryptUpload(fileContent, fileName);
if (links === null) {
links = await tryDcryptPaste(fileContent);
}
return packages;
if (links.length === 0) {
return [];
}
return [{ name: packageName, links }];
}
export async function importDlcContainers(filePaths: string[]): Promise<ParsedPackageInput[]> {