praitv / api /proxy.js
itzraissc
oi
78c3e1e
const fetch = require('node-fetch');
const { encrypt } = require('../lib/crypto');
const KEY = "jb%!SZfM%AwwS7JmdM!";
const VERSION = "1.0.9";
const FLAVOUR = "neoRed";
// lupatre.cc: Standard Xtream reseller with all 43 live categories + VOD + Series.
// Master host (37.148.132.86:8080) only serves its internal curation panel, NOT Xtream API.
const TARGET_DOMAIN = "http://lupatre.cc";
const TARGET_USER = "Emersonadam";
const TARGET_PASS = "Em25804627";
module.exports = async (req, res) => {
// Enable CORS
res.setHeader('Access-Control-Allow-Origin', '*');
const { wifi, lan } = req.query;
if (!wifi || !lan) {
return res.status(400).json({ error: "Missing wifi or lan parameters" });
}
// Rebuild query using our known-good credentials, not the device's passed username/password.
// This allows Roku to use placeholder creds; the proxy substitutes they real ones.
// Build target URL by forwarding all parameters from the incoming request,
// but overriding username/password with our known-good ones.
const queryParams = new URLSearchParams(req.query);
queryParams.set('username', TARGET_USER);
queryParams.set('password', TARGET_PASS);
// Ensure action is present (it should be coming from Roku)
let targetUrl = `${TARGET_DOMAIN}/player_api.php?${queryParams.toString()}`;
try {
// Prepare Security Headers (Fingerprint)
const headers = {
"wifi": encrypt(wifi, KEY),
"lan": encrypt(lan, KEY),
"version": encrypt(VERSION, KEY),
"flavour": encrypt(FLAVOUR, KEY),
"User-Agent": "UniTV-Android/1.0"
};
// 8s timeout — Vercel serverless limit is 10s; leave 2s margin.
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 8000);
const response = await fetch(targetUrl, {
method: 'GET',
headers: headers,
signal: controller.signal
});
clearTimeout(timeoutId);
const data = await response.json();
return res.status(200).json(data);
} catch (error) {
console.error("Proxy Error:", error);
return res.status(500).json({ error: error.message });
}
};