mirror of
https://github.com/gethomepage/homepage.git
synced 2026-01-10 18:52:07 +08:00
Run pre-commit hooks over existing codebase
Co-Authored-By: Ben Phelps <ben@phelps.io>
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
/* eslint-disable no-underscore-dangle */
|
||||
import crypto from 'crypto';
|
||||
import querystring from 'querystring';
|
||||
import crypto from "crypto";
|
||||
import querystring from "querystring";
|
||||
|
||||
import { sha256, uniqueRid, validateRid, createEncryptionToken, decrypt, encrypt } from "./tools"
|
||||
import { sha256, uniqueRid, validateRid, createEncryptionToken, decrypt, encrypt } from "./tools";
|
||||
|
||||
import getServiceWidget from "utils/config/service-helpers";
|
||||
import { httpProxy } from "utils/proxy/http";
|
||||
@@ -12,183 +12,173 @@ 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;
|
||||
}
|
||||
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;
|
||||
return widget;
|
||||
}
|
||||
|
||||
async function login(loginSecret, deviceSecret, params) {
|
||||
const rid = uniqueRid();
|
||||
const path = `/my/connect?${querystring.stringify({ ...params, rid })}`;
|
||||
const rid = uniqueRid();
|
||||
const path = `/my/connect?${querystring.stringify({ ...params, rid })}`;
|
||||
|
||||
const signature = crypto
|
||||
.createHmac('sha256', loginSecret)
|
||||
.update(path)
|
||||
.digest('hex');
|
||||
const url = `${new URL(`https://api.jdownloader.org${path}&signature=${signature}`)}`
|
||||
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',
|
||||
},
|
||||
});
|
||||
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];
|
||||
}
|
||||
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];
|
||||
}
|
||||
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({ ...params, rid })}`;
|
||||
const signature = crypto
|
||||
.createHmac('sha256', serverEncryptionToken)
|
||||
.update(path)
|
||||
.digest('hex');
|
||||
const url = `${new URL(`https://api.jdownloader.org${path}&signature=${signature}`)}`
|
||||
const rid = uniqueRid();
|
||||
const path = `/my/listdevices?${querystring.stringify({ ...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, , data] = await httpProxy(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
const [status, , 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(device => device.name === deviceName);
|
||||
return [status, filteredDevice[0].id];
|
||||
} catch (e) {
|
||||
logger.error("Error decoding jdownloader API data. Data: %s", data.toString());
|
||||
return [status, null];
|
||||
}
|
||||
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((device) => device.name === deviceName);
|
||||
return [status, filteredDevice[0].id];
|
||||
} catch (e) {
|
||||
logger.error("Error decoding jdownloader API data. Data: %s", data.toString());
|
||||
return [status, null];
|
||||
}
|
||||
}
|
||||
|
||||
function createBody(rid, query, params) {
|
||||
const baseBody = {
|
||||
apiVer: 1,
|
||||
rid,
|
||||
url: query
|
||||
};
|
||||
return params ? { ...baseBody, params: [JSON.stringify(params)] } : baseBody;
|
||||
const baseBody = {
|
||||
apiVer: 1,
|
||||
rid,
|
||||
url: query,
|
||||
};
|
||||
return params ? { ...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, , data] = await httpProxy(url, {
|
||||
method: 'POST',
|
||||
body,
|
||||
});
|
||||
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, , 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, null];
|
||||
}
|
||||
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, null];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default async function jdownloaderProxyHandler(req, res) {
|
||||
const widget = await getWidget(req);
|
||||
const widget = await getWidget(req);
|
||||
|
||||
if (!widget) {
|
||||
return res.status(400).json({ error: "Invalid proxy service type" });
|
||||
if (!widget) {
|
||||
return res.status(400).json({ error: "Invalid proxy service type" });
|
||||
}
|
||||
logger.debug("Getting data from JDRss API");
|
||||
const { username } = widget;
|
||||
const { password } = widget;
|
||||
|
||||
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: true,
|
||||
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 totalLoaded = 0;
|
||||
let totalBytes = 0;
|
||||
let totalSpeed = 0;
|
||||
packageStatus.forEach((file) => {
|
||||
totalBytes += file.bytesTotal;
|
||||
totalLoaded += file.bytesLoaded;
|
||||
if (file.finished !== true && file.speed) {
|
||||
totalSpeed += file.speed;
|
||||
}
|
||||
logger.debug("Getting data from JDRss API");
|
||||
const { username } = widget
|
||||
const { password } = widget
|
||||
});
|
||||
|
||||
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": true,
|
||||
"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 totalLoaded = 0;
|
||||
let totalBytes = 0;
|
||||
let totalSpeed = 0;
|
||||
packageStatus.forEach(file => {
|
||||
totalBytes += file.bytesTotal;
|
||||
totalLoaded += file.bytesLoaded;
|
||||
if (file.finished !== true && file.speed) {
|
||||
totalSpeed += file.speed;
|
||||
}
|
||||
});
|
||||
|
||||
const data = {
|
||||
downloadCount: packageStatus.length,
|
||||
bytesRemaining: totalBytes - totalLoaded,
|
||||
totalBytes,
|
||||
totalSpeed
|
||||
};
|
||||
|
||||
return res.send(data);
|
||||
const data = {
|
||||
downloadCount: packageStatus.length,
|
||||
bytesRemaining: totalBytes - totalLoaded,
|
||||
totalBytes,
|
||||
totalSpeed,
|
||||
};
|
||||
|
||||
return res.send(data);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user