diff --git a/api/report-error.js b/api/report-error.js index 19c4f8d..41da773 100644 --- a/api/report-error.js +++ b/api/report-error.js @@ -1,62 +1,62 @@ -const axios = require('axios'); +const axios = require('axios') // In-memory rate limiting for error reporting -const rateLimitMap = new Map(); -const RATE_LIMIT_WINDOW_MS = 60 * 1000; // 1 minute -const RATE_LIMIT_MAX_REQUESTS = 10; +const rateLimitMap = new Map() +const RATE_LIMIT_WINDOW_MS = 60 * 1000 // 1 minute +const RATE_LIMIT_MAX_REQUESTS = 10 function isRateLimited(ip) { - const now = Date.now(); - const record = rateLimitMap.get(ip); + const now = Date.now() + const record = rateLimitMap.get(ip) if (!record || now > record.resetTime) { - rateLimitMap.set(ip, { count: 1, resetTime: now + RATE_LIMIT_WINDOW_MS }); - return false; + rateLimitMap.set(ip, { count: 1, resetTime: now + RATE_LIMIT_WINDOW_MS }) + return false } if (record.count >= RATE_LIMIT_MAX_REQUESTS) { - return true; + return true } - record.count++; - return false; + record.count++ + return false } // Vercel serverless handler module.exports = async function handler(req, res) { // CORS headers - res.setHeader('Access-Control-Allow-Origin', '*'); - res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS'); - res.setHeader('Access-Control-Allow-Headers', 'Content-Type'); + res.setHeader('Access-Control-Allow-Origin', '*') + res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS') + res.setHeader('Access-Control-Allow-Headers', 'Content-Type') // Handle preflight if (req.method === 'OPTIONS') { - return res.status(200).end(); + return res.status(200).end() } // Only POST allowed if (req.method !== 'POST') { - return res.status(405).json({ error: 'Method not allowed' }); + return res.status(405).json({ error: 'Method not allowed' }) } try { // Rate limiting - const ip = req.headers['x-forwarded-for']?.split(',')[0]?.trim() || 'unknown'; + const ip = req.headers['x-forwarded-for']?.split(',')[0]?.trim() || 'unknown' if (isRateLimited(ip)) { - return res.status(429).json({ error: 'Rate limit exceeded' }); + return res.status(429).json({ error: 'Rate limit exceeded' }) } // Check Discord webhook URL - const webhookUrl = process.env.DISCORD_ERROR_WEBHOOK_URL; + const webhookUrl = process.env.DISCORD_ERROR_WEBHOOK_URL if (!webhookUrl) { - console.error('[ErrorReporting] DISCORD_ERROR_WEBHOOK_URL not configured'); - return res.status(503).json({ error: 'Error reporting service unavailable' }); + console.error('[ErrorReporting] DISCORD_ERROR_WEBHOOK_URL not configured') + return res.status(503).json({ error: 'Error reporting service unavailable' }) } // Validate payload - const payload = req.body; + const payload = req.body if (!payload?.error) { - return res.status(400).json({ error: 'Invalid payload: missing error field' }); + return res.status(400).json({ error: 'Invalid payload: missing error field' }) } // Build Discord embed @@ -71,15 +71,15 @@ module.exports = async function handler(req, res) { ], timestamp: new Date().toISOString(), footer: { text: 'Community Error Reporting' } - }; + } if (payload.stack) { - const stackLines = String(payload.stack).split('\n').slice(0, 15).join('\n'); - embed.fields.push({ - name: 'Stack Trace', - value: `\`\`\`\n${stackLines.slice(0, 1000)}\n\`\`\``, - inline: false - }); + const stackLines = String(payload.stack).split('\n').slice(0, 15).join('\n') + embed.fields.push({ + name: 'Stack Trace', + value: `\`\`\`\n${stackLines.slice(0, 1000)}\n\`\`\``, + inline: false + }) } // Send to Discord @@ -87,16 +87,16 @@ module.exports = async function handler(req, res) { username: 'Microsoft Rewards Bot', avatar_url: 'https://raw.githubusercontent.com/LightZirconite/Microsoft-Rewards-Bot/refs/heads/main/assets/logo.png', embeds: [embed] - }, { timeout: 10000 }); + }, { timeout: 10000 }) - console.log('[ErrorReporting] Report sent successfully'); - return res.json({ success: true, message: 'Error report received' }); + console.log('[ErrorReporting] Report sent successfully') + return res.json({ success: true, message: 'Error report received' }) } catch (error) { - console.error('[ErrorReporting] Failed:', error); - return res.status(500).json({ + console.error('[ErrorReporting] Failed:', error) + return res.status(500).json({ error: 'Failed to send error report', message: error.message || 'Unknown error' - }); + }) } -}; +}