From 1f5a14988162e69b07c68d5f6ca9940f5da1877e Mon Sep 17 00:00:00 2001 From: Karl Hudgell Date: Wed, 7 Jun 2023 12:47:49 +0100 Subject: [PATCH 1/8] initial working jdownloader widget --- package.json | 1 + pnpm-lock.yaml | 25 ++++++++++ src/widgets/components.js | 1 + src/widgets/jdownloader/component.jsx | 37 ++++++++++++++ src/widgets/jdownloader/proxy.js | 71 +++++++++++++++++++++++++++ src/widgets/jdownloader/widget.js | 14 ++++++ src/widgets/widgets.js | 2 + 7 files changed, 151 insertions(+) create mode 100644 src/widgets/jdownloader/component.jsx create mode 100644 src/widgets/jdownloader/proxy.js create mode 100644 src/widgets/jdownloader/widget.js diff --git a/package.json b/package.json index f4f46180..a08072df 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "dockerode": "^3.3.4", "follow-redirects": "^1.15.2", "i18next": "^21.9.2", + "jdownloader-client": "^1.0.0", "js-yaml": "^4.1.0", "json-rpc-2.0": "^1.4.1", "memory-cache": "^0.2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 86188aa5..8eec7883 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -22,6 +22,9 @@ dependencies: i18next: specifier: ^21.9.2 version: 21.10.0 + jdownloader-client: + specifier: ^1.0.0 + version: 1.0.0 js-yaml: specifier: ^4.1.0 version: 4.1.0 @@ -681,6 +684,16 @@ packages: engines: {node: '>=4'} dev: true + /axios@0.17.1: + resolution: {integrity: sha512-mZzWRyJeJ0rtK7e1/6iYBUzmeXjzei+1h1IvbedyU0sB52++tU5AU6r6TLXpwNVR0ebXIpvTVW+9CpWNyc1n8w==} + deprecated: Critical security vulnerability fixed in v0.21.1. For more information, see https://github.com/axios/axios/pull/3410 + dependencies: + follow-redirects: 1.15.2 + is-buffer: 1.1.6 + transitivePeerDependencies: + - debug + dev: false + /axobject-query@3.1.1: resolution: {integrity: sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg==} dependencies: @@ -1963,6 +1976,10 @@ packages: has-tostringtag: 1.0.0 dev: true + /is-buffer@1.1.6: + resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} + dev: false + /is-callable@1.2.7: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} @@ -2106,6 +2123,14 @@ packages: resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} dev: false + /jdownloader-client@1.0.0: + resolution: {integrity: sha512-3aksD+UE6xDXGmRIWUUVnVcJQBvNwff2HfrkBIo/Ptxaru4dDO5WCb93vP+wNrTVKdw8QQZ9sE4Y3jBvrKVaXQ==} + dependencies: + axios: 0.17.1 + transitivePeerDependencies: + - debug + dev: false + /jiti@1.18.2: resolution: {integrity: sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==} dev: true diff --git a/src/widgets/components.js b/src/widgets/components.js index bb8171d0..08345654 100644 --- a/src/widgets/components.js +++ b/src/widgets/components.js @@ -32,6 +32,7 @@ const components = { immich: dynamic(() => import("./immich/component")), jackett: dynamic(() => import("./jackett/component")), jdrssdownloader: dynamic(() => import("./jdrssdownloader/component")), + jdownloader: dynamic(() => import("./jdownloader/component")), jellyfin: dynamic(() => import("./emby/component")), jellyseerr: dynamic(() => import("./jellyseerr/component")), komga: dynamic(() => import("./komga/component")), diff --git a/src/widgets/jdownloader/component.jsx b/src/widgets/jdownloader/component.jsx new file mode 100644 index 00000000..d8fea9ca --- /dev/null +++ b/src/widgets/jdownloader/component.jsx @@ -0,0 +1,37 @@ +import { useTranslation } from "next-i18next"; + +import Block from "components/services/widget/block"; +import Container from "components/services/widget/container"; +import useWidgetAPI from "utils/proxy/use-widget-api"; + +export default function Component({ service }) { + const { t } = useTranslation(); + + const { widget } = service; + + const { data: jdownloaderData, error: jdownloaderAPIError } = useWidgetAPI(widget, "unified", { + refreshInterval: 30000, + }); + + if (jdownloaderAPIError) { + return ; + } + + if (!jdownloaderData) { + return ( + + + + + + ); + } + + return ( + + + + + + ); +} \ No newline at end of file diff --git a/src/widgets/jdownloader/proxy.js b/src/widgets/jdownloader/proxy.js new file mode 100644 index 00000000..3e6fcce2 --- /dev/null +++ b/src/widgets/jdownloader/proxy.js @@ -0,0 +1,71 @@ +/* eslint-disable no-underscore-dangle */ +import { JDownloaderClient } from 'jdownloader-client'; + +import getServiceWidget from "utils/config/service-helpers"; +import createLogger from "utils/logger"; + + +const proxyName = "jdownloaderProxyHandler"; + +const logger = createLogger(proxyName); + +async function getWidget(req) { + const { group, service } = req.query; + if (!group || !service) { + logger.debug("Invalid or missing service '%s' or group '%s'", service, group); + return null; + } + const widget = await getServiceWidget(group, service); + if (!widget) { + logger.debug("Invalid or missing widget for service '%s' in group '%s'", service, group); + return null; + } + + return widget; +} + +export default async function jdownloaderProxyHandler(req, res) { + const widget = await getWidget(req); + + if (!widget) { + return res.status(400).json({ error: "Invalid proxy service type" }); + } + logger.debug("Getting data from JDRss API"); + const client = new JDownloaderClient(widget.username, widget.password) + await client.connect() + const devices = await client.listDevices() + const packageStatus = await client.downloadsQueryPackages(devices[0].id, { + "bytesLoaded": false, + "bytesTotal": true, + "comment": false, + "enabled": true, + "eta": false, + "priority": false, + "finished": true, + "running": true, + "speed": true, + "status": true, + "childCount": false, + "hosts": false, + "saveTo": false, + "maxResults": -1, + "startAt": 0, + }) + let totalBytes = 0; + let totalSpeed = 0; + packageStatus.forEach(file => { + totalBytes += file.bytesTotal; + if (file.speed) { + totalSpeed += file.speed; + } + }); + + const data = { + downloadCount: packageStatus.length, + totalBytes, + totalSpeed + }; + + return res.send(data); + +} diff --git a/src/widgets/jdownloader/widget.js b/src/widgets/jdownloader/widget.js new file mode 100644 index 00000000..2685b571 --- /dev/null +++ b/src/widgets/jdownloader/widget.js @@ -0,0 +1,14 @@ +import jdownloaderProxyHandler from "./proxy"; + +const widget = { + api: "{url}/api/{endpoint}", + proxyHandler: jdownloaderProxyHandler, + + mappings: { + unified: { + endpoint: "/", + }, + }, +}; + +export default widget; diff --git a/src/widgets/widgets.js b/src/widgets/widgets.js index 36b06c2e..4642bb36 100644 --- a/src/widgets/widgets.js +++ b/src/widgets/widgets.js @@ -86,6 +86,7 @@ import whatsupdocker from "./whatsupdocker/widget"; import wgeasy from "./wgeasy/widget"; import xteve from "./xteve/widget"; import jdrssdownloader from "./jdrssdownloader/widget"; +import jdownloader from "./jdownloader/widget"; const widgets = { adguard, @@ -118,6 +119,7 @@ const widgets = { jackett, jellyfin: emby, jdrssdownloader, + jdownloader, jellyseerr, komga, kopia, From fc7f28467d87db8a1d8979588b8a0894a4efda5e Mon Sep 17 00:00:00 2001 From: Karl Hudgell Date: Wed, 7 Jun 2023 12:57:28 +0100 Subject: [PATCH 2/8] relint --- src/widgets/jdownloader/proxy.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/widgets/jdownloader/proxy.js b/src/widgets/jdownloader/proxy.js index 3e6fcce2..6410633c 100644 --- a/src/widgets/jdownloader/proxy.js +++ b/src/widgets/jdownloader/proxy.js @@ -1,12 +1,10 @@ /* eslint-disable no-underscore-dangle */ -import { JDownloaderClient } from 'jdownloader-client'; - import getServiceWidget from "utils/config/service-helpers"; import createLogger from "utils/logger"; +const { JDownloaderClient } = require('jdownloader-client') const proxyName = "jdownloaderProxyHandler"; - const logger = createLogger(proxyName); async function getWidget(req) { From dd6d910ded891c13a743ea19054d05796f438282 Mon Sep 17 00:00:00 2001 From: Karl Hudgell Date: Wed, 7 Jun 2023 12:57:37 +0100 Subject: [PATCH 3/8] missed common changes for lang --- public/locales/en/common.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/public/locales/en/common.json b/public/locales/en/common.json index 7a6034e2..d1b3ce33 100755 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -665,5 +665,10 @@ }, "wgeasy": { "clients": "Total Clients" + }, + "jdownloader": { + "downloadCount": "Queue Count", + "downloadQueueSize": "Queue Size", + "downloadSpeed": "Download Speed" } } \ No newline at end of file From c9258a08ae25880b99406c13aceac9fbce9d0033 Mon Sep 17 00:00:00 2001 From: Karl Hudgell Date: Tue, 13 Jun 2023 18:11:53 +0100 Subject: [PATCH 4/8] working commit with local code --- src/widgets/jdownloader/proxy.js | 138 ++++++++++++++++++++++++++++-- src/widgets/jdownloader/tools.js | 55 ++++++++++++ src/widgets/jdownloader/widget.js | 3 +- 3 files changed, 188 insertions(+), 8 deletions(-) create mode 100644 src/widgets/jdownloader/tools.js diff --git a/src/widgets/jdownloader/proxy.js b/src/widgets/jdownloader/proxy.js index 6410633c..cecf3af8 100644 --- a/src/widgets/jdownloader/proxy.js +++ b/src/widgets/jdownloader/proxy.js @@ -1,8 +1,10 @@ /* eslint-disable no-underscore-dangle */ +import crypto from 'crypto'; +import querystring from 'querystring'; import getServiceWidget from "utils/config/service-helpers"; +import { httpProxy } from "utils/proxy/http"; import createLogger from "utils/logger"; - -const { JDownloaderClient } = require('jdownloader-client') +import { sha256, uniqueRid, validateRid, createEncryptionToken, decrypt, encrypt } from "./tools" const proxyName = "jdownloaderProxyHandler"; const logger = createLogger(proxyName); @@ -22,6 +24,113 @@ async function getWidget(req) { return widget; } +async function login(loginSecret, deviceSecret, params) { + const rid = uniqueRid(); + const path = '/my/connect' + + '?' + + querystring.stringify(Object.assign({}, params, { rid })); + const signature = crypto + .createHmac('sha256', loginSecret) + .update(path) + .digest('hex'); + const url = `${new URL(`https://api.jdownloader.org${path}&signature=${signature}`)}` + + const [status, contentType, data] = await httpProxy(url, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + }); + + if (status !== 200) { + logger.error("HTTP %d communicating with jdownloader. Data: %s", status, data.toString()); + return [status, data]; + } + + try { + const decryptedData = JSON.parse(decrypt(data.toString(), loginSecret)) + const sessionToken = decryptedData.sessiontoken; + validateRid(decryptedData, rid); + const serverEncryptionToken = createEncryptionToken(loginSecret, sessionToken); + const deviceEncryptionToken = createEncryptionToken(deviceSecret, sessionToken); + return [status, decryptedData, contentType, serverEncryptionToken, deviceEncryptionToken, sessionToken]; + } catch (e) { + logger.error("Error decoding jdownloader API data. Data: %s", data.toString()); + return [status, null]; + } +} + + +async function getDevice(serverEncryptionToken, deviceName, params) { + const rid = uniqueRid(); + const path = '/my/listdevices' + + '?' + + querystring.stringify(Object.assign({}, params, { rid })); + const signature = crypto + .createHmac('sha256', serverEncryptionToken) + .update(path) + .digest('hex'); + const url = `${new URL(`https://api.jdownloader.org${path}&signature=${signature}`)}` + + const [status, contentType, data] = await httpProxy(url, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + }); + + if (status !== 200) { + logger.error("HTTP %d communicating with jdownloader. Data: %s", status, data.toString()); + return [status, data]; + } + + try { + const decryptedData = JSON.parse(decrypt(data.toString(), serverEncryptionToken)) + const filteredDevice = decryptedData.list.filter(function (device) { + return device.name == deviceName; + }); + return [status, filteredDevice[0].id]; + } catch (e) { + logger.error("Error decoding jdownloader API data. Data: %s", data.toString()); + return [status, None]; + } + +} + +function createBody(rid, query, params) { + const baseBody = { + apiVer: 1, + rid, + url: query + }; + return params ? Object.assign({}, baseBody, { params: [JSON.stringify(params)] }) : baseBody; +} + +async function queryPackages(deviceEncryptionToken, deviceId, sessionToken, params) { + const rid = uniqueRid(); + const body = encrypt(JSON.stringify(createBody(rid, '/downloadsV2/queryPackages', params)), deviceEncryptionToken); + const url = `${new URL('https://api.jdownloader.org/t_' + encodeURI(sessionToken) + '_' + encodeURI(deviceId) + '/downloadsV2/queryPackages')}` + const [status, contentType, data] = await httpProxy(url, { + method: 'POST', + body, + }); + + if (status !== 200) { + logger.error("HTTP %d communicating with jdownloader. Data: %s", status, data.toString()); + return [status, data]; + } + + try { + const decryptedData = JSON.parse(decrypt(data.toString(), deviceEncryptionToken)) + return decryptedData.data; + } catch (e) { + logger.error("Error decoding JDRss jdownloader data. Data: %s", data.toString()); + return [status, None]; + } + +} + + export default async function jdownloaderProxyHandler(req, res) { const widget = await getWidget(req); @@ -29,10 +138,23 @@ export default async function jdownloaderProxyHandler(req, res) { return res.status(400).json({ error: "Invalid proxy service type" }); } logger.debug("Getting data from JDRss API"); - const client = new JDownloaderClient(widget.username, widget.password) - await client.connect() - const devices = await client.listDevices() - const packageStatus = await client.downloadsQueryPackages(devices[0].id, { + const username = widget.username + const password = widget.password + const appKey = "homepage" + const loginSecret = sha256(username + password + 'server') + const deviceSecret = sha256(username + password + 'device') + const email = username; + + const loginData = await login(loginSecret, deviceSecret, { + appKey, + email + }) + + const deviceData = await getDevice(loginData[3], widget.client, { + sessiontoken: loginData[5] + }) + + const packageStatus = await queryPackages(loginData[4], deviceData[1], loginData[5], { "bytesLoaded": false, "bytesTotal": true, "comment": false, @@ -48,7 +170,9 @@ export default async function jdownloaderProxyHandler(req, res) { "saveTo": false, "maxResults": -1, "startAt": 0, - }) + } + ) + let totalBytes = 0; let totalSpeed = 0; packageStatus.forEach(file => { diff --git a/src/widgets/jdownloader/tools.js b/src/widgets/jdownloader/tools.js new file mode 100644 index 00000000..08bcdf1a --- /dev/null +++ b/src/widgets/jdownloader/tools.js @@ -0,0 +1,55 @@ +import crypto from 'crypto'; + +export function sha256(data) { + return crypto + .createHash('sha256') + .update(data) + .digest(); +} + +export function uniqueRid() { + return Math.floor(Math.random() * 10e12); +} + +export function validateRid(decryptedData, rid) { + if (decryptedData.rid !== rid) { + throw new Error('RequestID mismatch'); + } + return decryptedData; + +} + +export function decrypt(data, ivKey) { + const iv = ivKey.slice(0, ivKey.length / 2); + const key = ivKey.slice(ivKey.length / 2, ivKey.length); + const cipher = crypto.createDecipheriv('aes-128-cbc', key, iv); + return Buffer.concat([ + cipher.update(data, 'base64'), + cipher.final() + ]).toString(); +} + +export function createEncryptionToken(oldTokenBuff, updateToken) { + const updateTokenBuff = Buffer.from(updateToken, 'hex'); + const mergedBuffer = Buffer.concat([oldTokenBuff, updateTokenBuff], oldTokenBuff.length + updateTokenBuff.length); + return sha256(mergedBuffer); +} + +export function encrypt(data, ivKey) { + if (typeof data !== 'string') { + throw new Error('data no es un string'); + } + if (!(ivKey instanceof Buffer)) { + throw new Error('ivKey no es un buffer'); + } + if (ivKey.length !== 32) { + throw new Error('ivKey tiene que tener tamaƱo 32'); + } + const stringIVKey = ivKey.toString('hex'); + const stringIV = stringIVKey.substring(0, stringIVKey.length / 2); + const stringKey = stringIVKey.substring(stringIVKey.length / 2, stringIVKey.length); + const iv = new Buffer(stringIV, 'hex'); + const key = new Buffer(stringKey, 'hex'); + const cipher = crypto.createCipheriv('aes-128-cbc', key, iv); + return cipher.update(data, 'utf8', 'base64') + cipher.final('base64'); +} \ No newline at end of file diff --git a/src/widgets/jdownloader/widget.js b/src/widgets/jdownloader/widget.js index 2685b571..d3213740 100644 --- a/src/widgets/jdownloader/widget.js +++ b/src/widgets/jdownloader/widget.js @@ -1,12 +1,13 @@ import jdownloaderProxyHandler from "./proxy"; const widget = { - api: "{url}/api/{endpoint}", + api: "https://api.jdownloader.org/{endpoint}/&signature={signature}", proxyHandler: jdownloaderProxyHandler, mappings: { unified: { endpoint: "/", + signature: "", }, }, }; From 6a854ce66c25789697076490645fdb9de168196b Mon Sep 17 00:00:00 2001 From: Karl Hudgell Date: Tue, 13 Jun 2023 18:23:48 +0100 Subject: [PATCH 5/8] initial lint fixes --- src/widgets/jdownloader/proxy.js | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/src/widgets/jdownloader/proxy.js b/src/widgets/jdownloader/proxy.js index cecf3af8..445f1e2e 100644 --- a/src/widgets/jdownloader/proxy.js +++ b/src/widgets/jdownloader/proxy.js @@ -1,10 +1,12 @@ /* eslint-disable no-underscore-dangle */ import crypto from 'crypto'; import querystring from 'querystring'; +import { sha256, uniqueRid, validateRid, createEncryptionToken, decrypt, encrypt } from "./tools" + import getServiceWidget from "utils/config/service-helpers"; import { httpProxy } from "utils/proxy/http"; import createLogger from "utils/logger"; -import { sha256, uniqueRid, validateRid, createEncryptionToken, decrypt, encrypt } from "./tools" + const proxyName = "jdownloaderProxyHandler"; const logger = createLogger(proxyName); @@ -26,9 +28,7 @@ async function getWidget(req) { async function login(loginSecret, deviceSecret, params) { const rid = uniqueRid(); - const path = '/my/connect' + - '?' + - querystring.stringify(Object.assign({}, params, { rid })); + const path = `/my/connect?${querystring.stringify(Object.assign({}, params, { rid }))}`; const signature = crypto .createHmac('sha256', loginSecret) .update(path) @@ -63,16 +63,14 @@ async function login(loginSecret, deviceSecret, params) { async function getDevice(serverEncryptionToken, deviceName, params) { const rid = uniqueRid(); - const path = '/my/listdevices' + - '?' + - querystring.stringify(Object.assign({}, params, { rid })); + const path = `/my/listdevices?${querystring.stringify(Object.assign({}, params, { rid }))}`; const signature = crypto .createHmac('sha256', serverEncryptionToken) .update(path) .digest('hex'); const url = `${new URL(`https://api.jdownloader.org${path}&signature=${signature}`)}` - const [status, contentType, data] = await httpProxy(url, { + const [status, , data] = await httpProxy(url, { method: 'POST', headers: { 'Content-Type': 'application/json', @@ -86,13 +84,11 @@ async function getDevice(serverEncryptionToken, deviceName, params) { try { const decryptedData = JSON.parse(decrypt(data.toString(), serverEncryptionToken)) - const filteredDevice = decryptedData.list.filter(function (device) { - return device.name == deviceName; - }); + const filteredDevice = decryptedData.list.filter(device => device.name === deviceName); return [status, filteredDevice[0].id]; } catch (e) { logger.error("Error decoding jdownloader API data. Data: %s", data.toString()); - return [status, None]; + return [status, null]; } } @@ -109,8 +105,8 @@ function createBody(rid, query, params) { async function queryPackages(deviceEncryptionToken, deviceId, sessionToken, params) { const rid = uniqueRid(); const body = encrypt(JSON.stringify(createBody(rid, '/downloadsV2/queryPackages', params)), deviceEncryptionToken); - const url = `${new URL('https://api.jdownloader.org/t_' + encodeURI(sessionToken) + '_' + encodeURI(deviceId) + '/downloadsV2/queryPackages')}` - const [status, contentType, data] = await httpProxy(url, { + const url = `${new URL(`https://api.jdownloader.org/t_${encodeURI(sessionToken)}_${encodeURI(deviceId)}/downloadsV2/queryPackages`)}` + const [status, , data] = await httpProxy(url, { method: 'POST', body, }); @@ -125,7 +121,7 @@ async function queryPackages(deviceEncryptionToken, deviceId, sessionToken, para return decryptedData.data; } catch (e) { logger.error("Error decoding JDRss jdownloader data. Data: %s", data.toString()); - return [status, None]; + return [status, null]; } } @@ -141,8 +137,8 @@ export default async function jdownloaderProxyHandler(req, res) { const username = widget.username const password = widget.password const appKey = "homepage" - const loginSecret = sha256(username + password + 'server') - const deviceSecret = sha256(username + password + 'device') + const loginSecret = sha256(`${username}${password}server`) + const deviceSecret = sha256(`${username}${password}device`) const email = username; const loginData = await login(loginSecret, deviceSecret, { From c692eb700f280216069e32f7e28ad4155d64a4ac Mon Sep 17 00:00:00 2001 From: Karl Hudgell Date: Tue, 13 Jun 2023 19:41:37 +0100 Subject: [PATCH 6/8] more linting --- src/widgets/jdownloader/proxy.js | 5 +++-- src/widgets/jdownloader/tools.js | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/widgets/jdownloader/proxy.js b/src/widgets/jdownloader/proxy.js index 445f1e2e..40dba1ad 100644 --- a/src/widgets/jdownloader/proxy.js +++ b/src/widgets/jdownloader/proxy.js @@ -134,8 +134,9 @@ export default async function jdownloaderProxyHandler(req, res) { return res.status(400).json({ error: "Invalid proxy service type" }); } logger.debug("Getting data from JDRss API"); - const username = widget.username - const password = widget.password + const {username} = widget + const {password} = widget + const appKey = "homepage" const loginSecret = sha256(`${username}${password}server`) const deviceSecret = sha256(`${username}${password}device`) diff --git a/src/widgets/jdownloader/tools.js b/src/widgets/jdownloader/tools.js index 08bcdf1a..d678b072 100644 --- a/src/widgets/jdownloader/tools.js +++ b/src/widgets/jdownloader/tools.js @@ -48,8 +48,8 @@ export function encrypt(data, ivKey) { const stringIVKey = ivKey.toString('hex'); const stringIV = stringIVKey.substring(0, stringIVKey.length / 2); const stringKey = stringIVKey.substring(stringIVKey.length / 2, stringIVKey.length); - const iv = new Buffer(stringIV, 'hex'); - const key = new Buffer(stringKey, 'hex'); + const iv = Buffer.from(stringIV, 'hex'); + const key = Buffer.from(stringKey, 'hex'); const cipher = crypto.createCipheriv('aes-128-cbc', key, iv); return cipher.update(data, 'utf8', 'base64') + cipher.final('base64'); } \ No newline at end of file From 60dc38e6c4a4f63d6e227da6ae24e3a26327941c Mon Sep 17 00:00:00 2001 From: Karl Hudgell Date: Tue, 13 Jun 2023 20:01:25 +0100 Subject: [PATCH 7/8] finished linting --- src/widgets/jdownloader/proxy.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/widgets/jdownloader/proxy.js b/src/widgets/jdownloader/proxy.js index 40dba1ad..44eadcad 100644 --- a/src/widgets/jdownloader/proxy.js +++ b/src/widgets/jdownloader/proxy.js @@ -1,13 +1,13 @@ /* eslint-disable no-underscore-dangle */ import crypto from 'crypto'; import querystring from 'querystring'; + import { sha256, uniqueRid, validateRid, createEncryptionToken, decrypt, encrypt } from "./tools" import getServiceWidget from "utils/config/service-helpers"; import { httpProxy } from "utils/proxy/http"; import createLogger from "utils/logger"; - const proxyName = "jdownloaderProxyHandler"; const logger = createLogger(proxyName); @@ -28,7 +28,8 @@ async function getWidget(req) { async function login(loginSecret, deviceSecret, params) { const rid = uniqueRid(); - const path = `/my/connect?${querystring.stringify(Object.assign({}, params, { rid }))}`; + const path = `/my/connect?${querystring.stringify({...params, rid})}`; + const signature = crypto .createHmac('sha256', loginSecret) .update(path) @@ -63,7 +64,7 @@ async function login(loginSecret, deviceSecret, params) { async function getDevice(serverEncryptionToken, deviceName, params) { const rid = uniqueRid(); - const path = `/my/listdevices?${querystring.stringify(Object.assign({}, params, { rid }))}`; + const path = `/my/listdevices?${querystring.stringify({...params, rid})}`; const signature = crypto .createHmac('sha256', serverEncryptionToken) .update(path) @@ -99,7 +100,7 @@ function createBody(rid, query, params) { rid, url: query }; - return params ? Object.assign({}, baseBody, { params: [JSON.stringify(params)] }) : baseBody; + return params ? {...baseBody, params: [JSON.stringify(params)] } : baseBody; } async function queryPackages(deviceEncryptionToken, deviceId, sessionToken, params) { From 63e9287e0da29a85fa5b149edcdb254dcfcf759b Mon Sep 17 00:00:00 2001 From: Karl Hudgell Date: Tue, 13 Jun 2023 20:04:01 +0100 Subject: [PATCH 8/8] remove jdownloader-client --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index a08072df..5f486bf7 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "0.1.0", "private": true, "scripts": { - "dev": "next dev", + "dev": "next dev -p 8080", "build": "next build", "start": "next start", "lint": "next lint", @@ -17,7 +17,6 @@ "dockerode": "^3.3.4", "follow-redirects": "^1.15.2", "i18next": "^21.9.2", - "jdownloader-client": "^1.0.0", "js-yaml": "^4.1.0", "json-rpc-2.0": "^1.4.1", "memory-cache": "^0.2.0",