mirror of
https://github.com/shafat-96/anicrush-api.git
synced 2026-04-17 15:51:44 +00:00
fix
This commit is contained in:
161
embedHandler.js
161
embedHandler.js
@@ -1,6 +1,5 @@
|
|||||||
const { spawn } = require('child_process');
|
const axios = require('axios');
|
||||||
const path = require('path');
|
const crypto = require('node:crypto');
|
||||||
const fs = require('fs').promises;
|
|
||||||
|
|
||||||
class EmbedSource {
|
class EmbedSource {
|
||||||
constructor(file, sourceType) {
|
constructor(file, sourceType) {
|
||||||
@@ -31,75 +30,113 @@ class EmbedSources {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const findRabbitScript = async () => {
|
// Constants for Megacloud
|
||||||
const possiblePaths = [
|
const MEGACLOUD_URL = 'https://megacloud.blog';
|
||||||
path.join(__dirname, 'sources', 'rabbit.ts'),
|
const KEY_URL = 'https://raw.githubusercontent.com/yogesh-hacker/MegacloudKeys/refs/heads/main/keys.json';
|
||||||
path.join(__dirname, 'sources', 'rabbit.js'),
|
|
||||||
path.join(__dirname, 'rabbit.js'),
|
|
||||||
path.join(process.cwd(), 'rabbit.js')
|
|
||||||
];
|
|
||||||
|
|
||||||
for (const p of possiblePaths) {
|
// --- OpenSSL-compatible key+IV derivation (same algorithm used by Megacloud)
|
||||||
try {
|
function opensslKeyIv(password, salt, keyLen = 32, ivLen = 16) {
|
||||||
await fs.access(p);
|
let d = Buffer.alloc(0);
|
||||||
return p;
|
let prev = Buffer.alloc(0);
|
||||||
} catch (error) {
|
|
||||||
continue;
|
while (d.length < keyLen + ivLen) {
|
||||||
}
|
const hash = crypto.createHash('md5');
|
||||||
|
hash.update(Buffer.concat([prev, password, salt]));
|
||||||
|
prev = hash.digest();
|
||||||
|
d = Buffer.concat([d, prev]);
|
||||||
}
|
}
|
||||||
throw new Error('rabbit.js not found in any expected locations');
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleEmbed = async (embedUrl, referrer) => {
|
return {
|
||||||
return new Promise(async (resolve, reject) => {
|
key: d.subarray(0, keyLen),
|
||||||
try {
|
iv: d.subarray(keyLen, keyLen + ivLen),
|
||||||
const rabbitPath = await findRabbitScript();
|
};
|
||||||
const childProcess = spawn('node', [
|
}
|
||||||
rabbitPath,
|
|
||||||
`--embed-url=${embedUrl}`,
|
|
||||||
`--referrer=${referrer}`
|
|
||||||
]);
|
|
||||||
|
|
||||||
let outputData = '';
|
// --- Decrypt OpenSSL AES-CBC encoded Base64 payloads
|
||||||
let errorData = '';
|
function decryptOpenSSL(encBase64, password) {
|
||||||
|
try {
|
||||||
|
const data = Buffer.from(encBase64, 'base64');
|
||||||
|
if (data.subarray(0, 8).toString() !== 'Salted__') return null;
|
||||||
|
|
||||||
childProcess.stdout.on('data', (data) => {
|
const salt = data.subarray(8, 16);
|
||||||
outputData += data.toString();
|
const { key, iv } = opensslKeyIv(Buffer.from(password, 'utf8'), salt);
|
||||||
});
|
const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
|
||||||
|
const decrypted = Buffer.concat([
|
||||||
|
decipher.update(data.subarray(16)),
|
||||||
|
decipher.final(),
|
||||||
|
]);
|
||||||
|
return decrypted.toString('utf-8');
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Decryption error:', err.message);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
childProcess.stderr.on('data', (data) => {
|
// --- Helpers
|
||||||
errorData += data.toString();
|
function extractId(url) {
|
||||||
});
|
return url.split('/').pop().split('?')[0];
|
||||||
|
}
|
||||||
|
|
||||||
childProcess.on('close', (code) => {
|
async function getDecryptionKey() {
|
||||||
if (code !== 0) {
|
try {
|
||||||
reject(new Error(`Process exited with code ${code}: ${errorData}`));
|
const res = await axios.get(KEY_URL);
|
||||||
return;
|
return typeof res.data === 'string' ? JSON.parse(res.data).mega : res.data?.mega;
|
||||||
}
|
} catch (e) {
|
||||||
|
console.error('Failed to fetch key:', e.message);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
const handleEmbed = async (embedUrl, referrer = 'https://megacloud.blog') => {
|
||||||
const parsedOutput = JSON.parse(outputData.trim());
|
try {
|
||||||
const embedSources = new EmbedSources(
|
if (!embedUrl) throw new Error('embedUrl is required');
|
||||||
parsedOutput.sources.map(s => new EmbedSource(s.file, s.type)),
|
|
||||||
parsedOutput.tracks.map(t => new Track(t.file, t.label, t.kind, t.default)),
|
|
||||||
parsedOutput.t,
|
|
||||||
parsedOutput.server,
|
|
||||||
parsedOutput.intro,
|
|
||||||
parsedOutput.outro
|
|
||||||
);
|
|
||||||
resolve(embedSources);
|
|
||||||
} catch (error) {
|
|
||||||
reject(error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
childProcess.on('error', (error) => {
|
const id = extractId(embedUrl);
|
||||||
reject(error);
|
const apiUrl = `${MEGACLOUD_URL}/embed-2/v2/e-1/getSources?id=${id}`;
|
||||||
});
|
|
||||||
} catch (error) {
|
const headers = {
|
||||||
reject(error);
|
Referer: referrer || embedUrl,
|
||||||
|
Origin: 'https://megacloud.blog/',
|
||||||
|
'User-Agent': 'Mozilla/5.0',
|
||||||
|
};
|
||||||
|
|
||||||
|
const { data } = await axios.get(apiUrl, { headers });
|
||||||
|
if (!data?.sources) throw new Error('No sources field in response');
|
||||||
|
|
||||||
|
// Parse/Decrypt sources array
|
||||||
|
let rawSources;
|
||||||
|
if (typeof data.sources === 'string') {
|
||||||
|
try {
|
||||||
|
rawSources = JSON.parse(data.sources);
|
||||||
|
} catch (_) {
|
||||||
|
const key = await getDecryptionKey();
|
||||||
|
if (!key) throw new Error('Failed to fetch decryption key');
|
||||||
|
const decrypted = decryptOpenSSL(data.sources, key);
|
||||||
|
if (!decrypted) throw new Error('Decryption failed');
|
||||||
|
rawSources = JSON.parse(decrypted);
|
||||||
|
}
|
||||||
|
} else if (Array.isArray(data.sources)) {
|
||||||
|
rawSources = data.sources;
|
||||||
|
} else {
|
||||||
|
throw new Error('Unexpected sources format');
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
if (!rawSources.length) throw new Error('No valid sources found');
|
||||||
|
|
||||||
|
const sources = rawSources.map((s) => new EmbedSource(s.file, s.type || s.quality || 'unknown'));
|
||||||
|
const tracks = (data.tracks || []).map((t) => new Track(t.file, t.label, t.kind, t.default));
|
||||||
|
|
||||||
|
return new EmbedSources(
|
||||||
|
sources,
|
||||||
|
tracks,
|
||||||
|
data.t ?? 0,
|
||||||
|
'megacloud',
|
||||||
|
data.intro ?? null,
|
||||||
|
data.outro ?? null
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|||||||
8
package-lock.json
generated
8
package-lock.json
generated
@@ -10,6 +10,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^1.6.2",
|
"axios": "^1.6.2",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
|
"crypto": "^1.0.1",
|
||||||
"dotenv": "^16.3.1",
|
"dotenv": "^16.3.1",
|
||||||
"express": "^4.18.2"
|
"express": "^4.18.2"
|
||||||
},
|
},
|
||||||
@@ -269,6 +270,13 @@
|
|||||||
"node": ">= 0.10"
|
"node": ">= 0.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/crypto": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==",
|
||||||
|
"deprecated": "This package is no longer supported. It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in.",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
"node_modules/debug": {
|
"node_modules/debug": {
|
||||||
"version": "2.6.9",
|
"version": "2.6.9",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||||
|
|||||||
@@ -12,10 +12,11 @@
|
|||||||
"vercel-build": "echo hello"
|
"vercel-build": "echo hello"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"express": "^4.18.2",
|
|
||||||
"axios": "^1.6.2",
|
"axios": "^1.6.2",
|
||||||
|
"cors": "^2.8.5",
|
||||||
|
"crypto": "^1.0.1",
|
||||||
"dotenv": "^16.3.1",
|
"dotenv": "^16.3.1",
|
||||||
"cors": "^2.8.5"
|
"express": "^4.18.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"nodemon": "^3.0.2"
|
"nodemon": "^3.0.2"
|
||||||
|
|||||||
58292
sources/rabbit.js
58292
sources/rabbit.js
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user