diff --git a/package.json b/package.json index 2895f20c..aa345de3 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "@vanilla-extract/recipes": "^0.5.2", "auto-launch": "^5.0.6", "axios": "^1.7.9", + "axios-cookiejar-support": "^5.0.5", "better-sqlite3": "^11.7.0", "classnames": "^2.5.1", "color": "^4.2.3", @@ -74,6 +75,7 @@ "sound-play": "^1.1.0", "sudo-prompt": "^9.2.1", "tar": "^7.4.3", + "tough-cookie": "^5.1.1", "typeorm": "^0.3.20", "user-agents": "^1.1.387", "yaml": "^2.6.1", diff --git a/src/main/services/hosters/datanodes.ts b/src/main/services/hosters/datanodes.ts index d77e7d51..256d4af0 100644 --- a/src/main/services/hosters/datanodes.ts +++ b/src/main/services/hosters/datanodes.ts @@ -1,46 +1,72 @@ import axios, { AxiosResponse } from "axios"; +import { wrapper } from "axios-cookiejar-support"; +import { CookieJar } from "tough-cookie"; export class DatanodesApi { - private static readonly session = axios.create({}); + private static readonly jar = new CookieJar(); + + private static readonly session = wrapper( + axios.create({ + jar: DatanodesApi.jar, + withCredentials: true, + }) + ); public static async getDownloadUrl(downloadUrl: string): Promise { - const parsedUrl = new URL(downloadUrl); - const pathSegments = parsedUrl.pathname.split("/"); + try { + const parsedUrl = new URL(downloadUrl); + const pathSegments = parsedUrl.pathname.split("/").filter(Boolean); + const fileCode = pathSegments[0]; - const fileCode = decodeURIComponent(pathSegments[1]); - const fileName = decodeURIComponent(pathSegments[pathSegments.length - 1]); + await this.jar.setCookie( + "lang=english; affiliate=xMMbODVvr8YJ2fSUcUnMp%2BGXrORHVW1k8r7y2EAcXokClQHfT29mJ1a8NtvhD7dfq%2BzAz0Sxmz5NoIEyvh32QE0nzx7KyKTspsroVhug2lkfAffiIqvzq52eJ2GGVY9jl9iVmw%3D%3D", + "https://datanodes.to" + ); - const payload = new URLSearchParams({ - op: "download2", - id: fileCode, - rand: "", - referer: "https://datanodes.to/download", - method_free: "Free Download >>", - method_premium: "", - adblock_detected: "", - }); + const payload = new URLSearchParams({ + op: "download2", + id: fileCode, + method_free: "Free Download >>", + dl: "1" + }); - const response: AxiosResponse = await this.session.post( - "https://datanodes.to/download", - payload, - { - headers: { - "Content-Type": "application/x-www-form-urlencoded", - Cookie: `lang=english; file_name=${fileName}; file_code=${fileCode};`, - Host: "datanodes.to", - Origin: "https://datanodes.to", - Referer: "https://datanodes.to/download", - "User-Agent": - "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36", - }, - maxRedirects: 0, validateStatus: (status: number) => status === 302 || status < 400, + const response: AxiosResponse = await this.session.post( + "https://datanodes.to/download", + payload, + { + headers: { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:135.0) Gecko/20100101 Firefox/135.0", + "Referer": "https://datanodes.to/download", + "Origin": "https://datanodes.to", + "Content-Type": "application/x-www-form-urlencoded" + }, + maxRedirects: 0, + validateStatus: (status: number) => status === 302 || status < 400, + } + ); + + if (response.status === 302) { + return response.headers["location"]; } - ); - if (response.status === 302) { - return response.headers["location"]; + if (typeof response.data === 'object' && response.data.url) { + return decodeURIComponent(response.data.url); + } + + const htmlContent = String(response.data); + if (!htmlContent) { + throw new Error("Empty response received"); + } + + const downloadLinkMatch = htmlContent.match(/href=["'](https:\/\/[^"']+)["']/); + if (downloadLinkMatch) { + return downloadLinkMatch[1]; + } + + throw new Error("Failed to get the download link"); + } catch (error) { + console.error("Error fetching download URL:", error); + throw error; } - - return ""; } } diff --git a/yarn.lock b/yarn.lock index 69ee75d8..5dbd98e0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3740,6 +3740,11 @@ agent-base@^7.0.2, agent-base@^7.1.0: dependencies: debug "^4.3.4" +agent-base@^7.1.3: + version "7.1.3" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.3.tgz#29435eb821bc4194633a5b89e5bc4703bafc25a1" + integrity sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw== + agentkeepalive@^4.2.1: version "4.5.0" resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.5.0.tgz#2673ad1389b3c418c5a20c5d7364f93ca04be923" @@ -4055,6 +4060,13 @@ axe-core@^4.10.0: resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.10.0.tgz#d9e56ab0147278272739a000880196cdfe113b59" integrity sha512-Mr2ZakwQ7XUAjp7pAwQWRhhK8mQQ6JAaNWSjmjxil0R8BPioMtQsTLOolGYkji1rcL++3dCqZA3zWqpT+9Ew6g== +axios-cookiejar-support@^5.0.5: + version "5.0.5" + resolved "https://registry.yarnpkg.com/axios-cookiejar-support/-/axios-cookiejar-support-5.0.5.tgz#6030e17b438a64e3967a5ca190ee4202481c0ecf" + integrity sha512-jJG+p7JnOYxkVrYkCDKBrLqUmcpwHZTNQrEcIEKr5qe7YVTyPAD9nCsi1cO5LDmQpQApfS430czO+oceI3g/3g== + dependencies: + http-cookie-agent "^6.0.8" + axios@^1.7.9: version "1.7.9" resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.9.tgz#d7d071380c132a24accda1b2cfc1535b79ec650a" @@ -6215,6 +6227,13 @@ http-cache-semantics@^4.0.0, http-cache-semantics@^4.1.0: resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== +http-cookie-agent@^6.0.8: + version "6.0.8" + resolved "https://registry.yarnpkg.com/http-cookie-agent/-/http-cookie-agent-6.0.8.tgz#f2635638f4172c7de0c482396ea7313e9731a62b" + integrity sha512-qnYh3yLSr2jBsTYkw11elq+T361uKAJaZ2dR4cfYZChw1dt9uL5t3zSUwehoqqVb4oldk1BpkXKm2oat8zV+oA== + dependencies: + agent-base "^7.1.3" + http-proxy-agent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" @@ -9073,6 +9092,18 @@ tinyexec@^0.3.0: resolved "https://registry.yarnpkg.com/tinyexec/-/tinyexec-0.3.1.tgz#0ab0daf93b43e2c211212396bdb836b468c97c98" integrity sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ== +tldts-core@^6.1.78: + version "6.1.78" + resolved "https://registry.yarnpkg.com/tldts-core/-/tldts-core-6.1.78.tgz#47b477d9742870daa01dbd5ff9a598a48379728c" + integrity sha512-jS0svNsB99jR6AJBmfmEWuKIgz91Haya91Z43PATaeHJ24BkMoNRb/jlaD37VYjb0mYf6gRL/HOnvS1zEnYBiw== + +tldts@^6.1.32: + version "6.1.78" + resolved "https://registry.yarnpkg.com/tldts/-/tldts-6.1.78.tgz#ee94576653a60d421ff94162c4e9060f2e62467b" + integrity sha512-fSgYrW0ITH0SR/CqKMXIruYIPpNu5aDgUp22UhYoSrnUQwc7SBqifEBFNce7AAcygUPBo6a/gbtcguWdmko4RQ== + dependencies: + tldts-core "^6.1.78" + tmp-promise@^3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/tmp-promise/-/tmp-promise-3.0.3.tgz#60a1a1cc98c988674fcbfd23b6e3367bdeac4ce7" @@ -9120,6 +9151,13 @@ tough-cookie@^4.1.4: universalify "^0.2.0" url-parse "^1.5.3" +tough-cookie@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-5.1.1.tgz#4641c1fdbf024927e29c5532edb7b6e5377ea1f2" + integrity sha512-Ek7HndSVkp10hmHP9V4qZO1u+pn1RU5sI0Fw+jCU3lyvuMZcgqsNgc6CmJJZyByK4Vm/qotGRJlfgAX8q+4JiA== + dependencies: + tldts "^6.1.32" + tr46@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/tr46/-/tr46-5.0.0.tgz#3b46d583613ec7283020d79019f1335723801cec"