mirror of
https://github.com/movixcorp/MovixOpenSource.git
synced 2026-08-09 17:07:35 +00:00
- corrige l’extraction Fsvid/Vidzy dans proxiesembed, les extensions et le userscript avec un décodage XOR/P.A.C.K.E.R plus robuste - rejette les URL « troll » et supprime les résultats Fsvid/Vidzy contaminés des caches - ajoute KissKH pour les films et séries avec matching TMDB, catalogue, cache distribué, verrouillage, rotation des proxys et fallback sécurisé - ajoute le relais KissKH HLS/MP4 dans proxiesembed, avec retry SOCKS5 sur les erreurs 403 et streaming des segments BYTERANGE - prend en charge les sous-titres KissKH SRT/TXT/TXT2, leur déchiffrement AES et leur conversion en WebVTT - intègre KissKH au lecteur, aux priorités de sources, aux extensions Chrome/Firefox et au userscript - améliore la sélection, le formatage sécurisé, la traduction et l’affichage Picture-in-Picture des sous-titres - corrige le Cast web et Android pour transmettre les sous-titres internes, externes, KissKH et traduits - ajoute le support des pistes WebVTT inline via le relais LAN Android et améliore le suivi des sessions Cast - protège les liens jouables des caches Cpasmal et Coflix contre les rafraîchissements vides ou concurrents - fiabilise la sélection des saisons FStream et améliore le matching DarkiWorld par TMDB, titre et année - simplifie les nouvelles URL TMDB tout en conservant le décodage des anciens identifiants encodés - corrige l’opacité des icônes SVG dans toute l’interface en séparant la couleur de leur niveau d’opacité - met à jour le Dockerfile vers Node.js 22 et installe uniquement les dépendances runtime du workspace Hono - ajoute le workspace server avec ses dépendances dédiées et un arrêt gracieux sur SIGTERM/SIGINT - accélère le healthcheck Docker et évite de recopier tous les node_modules du builder dans l’image finale - retire les migrations et créations de tables automatiques au démarrage de la Main API au profit de db:init - attribue un port CycleTLS distinct à chaque worker pour éviter les conflits en mode cluster - ajoute des tests de non-régression pour KissKH, les caches de sources, CycleTLS et le Cast Android - publie Android 2.5.8 build 17 avec le nouvel APK - met à jour les extensions Chrome 1.3.13 et Firefox 1.5.10 Co-authored-by: GPT-5.6 Sol <noreply@openai.com>
88 lines
3.2 KiB
JavaScript
88 lines
3.2 KiB
JavaScript
const crypto = require('node:crypto');
|
|
|
|
const APPROVED_FIXED_MARKER = 'mg3c3b04ba';
|
|
|
|
function jsHashCode(value) {
|
|
const input = String(value);
|
|
let hash = 0;
|
|
for (let index = 0; index < input.length; index += 1) {
|
|
hash = (hash << 5) - hash + input.charCodeAt(index);
|
|
}
|
|
return hash;
|
|
}
|
|
|
|
function canonicalPayload({ episodeId, contextId, fixedMarker, appVersion, platformVersion, environmentFields }) {
|
|
if (fixedMarker !== APPROVED_FIXED_MARKER) {
|
|
throw new TypeError('fixedMarker kkey invalide');
|
|
}
|
|
if (!Array.isArray(environmentFields) || environmentFields.length !== 6) {
|
|
throw new TypeError('environmentFields invalides');
|
|
}
|
|
if (environmentFields.some((field) => typeof field !== 'string')) {
|
|
throw new TypeError('environmentFields invalides');
|
|
}
|
|
const normalize = (part) => part == null ? '' : String(part);
|
|
const truncate48 = (part) => String(part || '').substr(0, 48);
|
|
const fields = [
|
|
'',
|
|
episodeId,
|
|
null,
|
|
fixedMarker,
|
|
appVersion,
|
|
contextId,
|
|
platformVersion,
|
|
truncate48(environmentFields[0]),
|
|
truncate48(String(environmentFields[1]).toLowerCase()),
|
|
truncate48(environmentFields[2]),
|
|
environmentFields[3],
|
|
environmentFields[4],
|
|
environmentFields[5],
|
|
'00',
|
|
'',
|
|
];
|
|
const seed = fields.map(normalize).join('|');
|
|
fields.splice(1, 0, jsHashCode(seed));
|
|
return fields.map(normalize).join('|');
|
|
}
|
|
|
|
function decodeAes128Hex(value, label) {
|
|
if (typeof value !== 'string' || !/^[0-9a-f]{32}$/i.test(value)) {
|
|
throw new TypeError(`${label} AES-128 invalide`);
|
|
}
|
|
return Buffer.from(value, 'hex');
|
|
}
|
|
|
|
function computeKkey({ context, episodeId, algorithm }) {
|
|
if (!Number.isSafeInteger(episodeId) || episodeId <= 0) throw new TypeError('episodeId invalide');
|
|
if (!['episode', 'sub'].includes(context)) throw new TypeError('context invalide');
|
|
const key = decodeAes128Hex(algorithm?.keyHex, 'key');
|
|
const iv = decodeAes128Hex(algorithm?.ivHex, 'iv');
|
|
const contextSpec = algorithm?.contexts?.[context];
|
|
if (!contextSpec || typeof contextSpec.contextId !== 'string' || !contextSpec.contextId) {
|
|
throw new TypeError('contexte kkey absent');
|
|
}
|
|
if (!Number.isSafeInteger(contextSpec.expectedLength) || contextSpec.expectedLength <= 0) {
|
|
throw new TypeError('longueur kkey invalide');
|
|
}
|
|
if (typeof algorithm.appVersion !== 'string' || !algorithm.appVersion
|
|
|| !Number.isSafeInteger(algorithm.platformVersion) || algorithm.platformVersion <= 0) {
|
|
throw new TypeError('version kkey invalide');
|
|
}
|
|
const payload = canonicalPayload({
|
|
episodeId,
|
|
contextId: contextSpec.contextId,
|
|
fixedMarker: algorithm.fixedMarker,
|
|
appVersion: algorithm.appVersion,
|
|
platformVersion: algorithm.platformVersion,
|
|
environmentFields: algorithm.environmentFields,
|
|
});
|
|
const cipher = crypto.createCipheriv('aes-128-cbc', key, iv);
|
|
cipher.setAutoPadding(true);
|
|
const output = Buffer.concat([cipher.update(payload, 'utf8'), cipher.final()]).toString('hex').toUpperCase();
|
|
if (!/^[0-9A-F]+$/.test(output) || output.length !== contextSpec.expectedLength) {
|
|
throw new TypeError('sortie kkey invalide');
|
|
}
|
|
return output;
|
|
}
|
|
|
|
module.exports = { canonicalPayload, computeKkey, jsHashCode };
|