diff --git a/app.js b/app.js index 690d528..9893b4d 100644 --- a/app.js +++ b/app.js @@ -3,6 +3,8 @@ const fetch = require('node-fetch'); const cookieParser = require('cookie-parser'); const path = require('path'); const fs = require('fs'); +const captcha = require('trek-captcha'); +const JSZip = require('jszip'); const app = express(); const PORT = process.env.PORT || 3000; @@ -53,6 +55,91 @@ app.get('/:pasteId', async (req, res) => { } }); +let lastDownloadTime = {}; // To track cooldowns for each user + +// Function to check cooldown +const checkCooldown = (userId) => { + const now = Date.now(); + if (lastDownloadTime[userId] && now - lastDownloadTime[userId] < 180000) { // 3-minute cooldown + return false; + } + lastDownloadTime[userId] = now; + return true; +}; + +// Function to fetch paste data from Pastebin +const fetchPasteData = async (pasteId) => { + const rawUrl = `https://pastebin.com/raw/${pasteId}`; + const response = await fetch(rawUrl); + if (!response.ok) { + throw new Error('Failed to fetch paste data'); + } + return response.text(); +}; + +// Function to generate Trek-Captcha +const generateCaptcha = async () => { + const { token, buffer } = await captcha(); + return { token, buffer }; +}; + +// Bulk download route +app.post('/bulk-download', async (req, res) => { + const { userId, pasteIds, captchaToken } = req.body; + + if (!checkCooldown(userId)) { + return res.status(429).json({ message: 'Please wait 3 minutes before making another bulk download request.' }); + } + + // Validate CAPTCHA + const isCaptchaValid = await validateCaptcha(captchaToken); + if (!isCaptchaValid) { + return res.status(400).json({ message: 'Invalid CAPTCHA.' }); + } + + if (pasteIds.length > 64) { + return res.status(400).json({ message: 'You can only request up to 64 pastes at a time.' }); + } + + try { + // Create a new ZIP file + const zip = new JSZip(); + + for (const pasteId of pasteIds) { + const pasteData = await fetchPasteData(pasteId); + zip.file(`${pasteId}.txt`, pasteData); // Save each paste as a text file in the ZIP + } + + // Generate the ZIP file + const zipBuffer = await zip.generateAsync({ type: 'nodebuffer' }); + + // Send the ZIP file as a response + res.set('Content-Type', 'application/zip'); + res.set('Content-Disposition', 'attachment; filename=pastes.zip'); + res.send(zipBuffer); + } catch (error) { + console.error(error); + res.status(500).json({ message: 'Failed to generate the ZIP file.' }); + } +}); + +// Function to validate the CAPTCHA token (you'll need to implement this on your server) +const validateCaptcha = async (captchaToken) => { + // This is where you would validate the token against Trek-Captcha's verification endpoint. + // For now, assuming a mock validation function that always returns true. + return true; +}; + +// Route to show CAPTCHA for bulk download +app.get('/captcha', async (req, res) => { + try { + const { token, buffer } = await generateCaptcha(); + res.status(200).json({ token, image: buffer.toString('base64') }); + } catch (error) { + res.status(500).json({ message: 'Failed to generate CAPTCHA.' }); + } +}); + // Start the server app.listen(PORT, () => { console.log(`Server is running on http://localhost:${PORT}`);