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 }); } };