/** * Proxies Hail Recon API calls from the browser. * Solves CORS and keeps credentials server-side. * * Usage: GET /api/hail-proxy?endpoint=ImpactDatesForLatLong&Lat=33.055&Long=-96.752&Months=12 * POST /api/hail-proxy?endpoint=AddressMonitoringImport2g (body = JSON payload) */ const BASE_URL = 'https://maps.interactivehailmaps.com/ExternalApi'; const ALLOWED_ENDPOINTS = new Set([ 'ImpactDatesForLatLong', 'ImpactDatesForAddressMarker', 'AddressMonitoringImport2g', ]); export default async function handler(req, res) { res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); res.setHeader('Access-Control-Allow-Headers', 'Content-Type'); if (req.method === 'OPTIONS') { return res.status(200).end(); } const { endpoint, ...params } = req.query; if (!endpoint || !ALLOWED_ENDPOINTS.has(endpoint)) { return res.status(400).json({ error: 'Invalid or missing endpoint' }); } const accessKey = process.env.HAIL_RECON_ACCESS_KEY; const accessSecret = process.env.HAIL_RECON_ACCESS_SECRET; if (!accessKey || !accessSecret) { return res.status(500).json({ error: 'Hail Recon credentials not configured' }); } const credentials = Buffer.from(`${accessKey}:${accessSecret}`).toString('base64'); const authHeader = `Basic ${credentials}`; try { let response; if (req.method === 'POST') { response = await fetch(`${BASE_URL}/${endpoint}`, { method: 'POST', headers: { 'Authorization': authHeader, 'Content-Type': 'application/json', }, body: JSON.stringify(req.body), }); } else { const qs = new URLSearchParams(params).toString(); const url = `${BASE_URL}/${endpoint}${qs ? `?${qs}` : ''}`; response = await fetch(url, { headers: { 'Authorization': authHeader }, }); } const contentType = response.headers.get('content-type') || ''; const data = contentType.includes('application/json') ? await response.json() : await response.text(); return res.status(response.status).json(data); } catch (err) { return res.status(502).json({ error: 'Failed to reach Hail Recon API', detail: err.message }); } }