From b81e102d39942609ed07e94f7d8aa7c7987ba5df Mon Sep 17 00:00:00 2001 From: justin Date: Fri, 22 May 2026 01:08:51 -0500 Subject: [PATCH] Validate allowed_emails on discount code lookup The /api/v1/discount/:code endpoint now checks allowed_emails when an email is provided. If the email isn't in the allowed list, returns valid:false so the frontend doesn't show a fake discount. The promo field is cleared and unlocked if validation fails. Co-Authored-By: Claude Opus 4.6 (1M context) --- api/src/routes/discounts.ts | 19 +++++++++++++++++++ site/public/order/fcc-compliance/index.html | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/api/src/routes/discounts.ts b/api/src/routes/discounts.ts index 9343166..07d10fa 100644 --- a/api/src/routes/discounts.ts +++ b/api/src/routes/discounts.ts @@ -81,6 +81,25 @@ router.get("/api/v1/discount/:code", async (req, res) => { return; } + // Check allowed_emails restriction + if (dc.allowed_emails && dc.allowed_emails.length > 0) { + if (!email) { + res.status(400).json({ + valid: false, + error: "This code requires an email address to validate.", + }); + return; + } + const allowed = dc.allowed_emails.map((e: string) => e.toLowerCase()); + if (!allowed.includes(email.toLowerCase().trim())) { + res.status(403).json({ + valid: false, + error: "This discount code is not valid for your email address.", + }); + return; + } + } + // Check per-email limit if (email && dc.max_uses_per_email > 0) { const emailUsage = await pool.query( diff --git a/site/public/order/fcc-compliance/index.html b/site/public/order/fcc-compliance/index.html index 91ffcf6..4c06e13 100644 --- a/site/public/order/fcc-compliance/index.html +++ b/site/public/order/fcc-compliance/index.html @@ -195,7 +195,7 @@ var entityBar=document.getElementById("pw-entity-bar"); var bundleTip=document.getElementById("pw-bundle-tip"); // Fetch promo code info from API if present -if(promoFromUrl){fetch(API+"/api/v1/discount/"+encodeURIComponent(promoFromUrl)).then(function(r){return r.json()}).then(function(d){if(d.valid){window._promoInfo=d;var cb=document.querySelector(".svc-cb:checked");if(cb)cb.dispatchEvent(new Event("change",{bubbles:true}));}}).catch(function(){});} +if(promoFromUrl){var discUrl=API+"/api/v1/discount/"+encodeURIComponent(promoFromUrl)+(emailFromUrl?"?email="+encodeURIComponent(emailFromUrl):"");fetch(discUrl).then(function(r){return r.json()}).then(function(d){if(d.valid){window._promoInfo=d;var cb=document.querySelector(".svc-cb:checked");if(cb)cb.dispatchEvent(new Event("change",{bubbles:true}));}else{window._promoInfo=null;promoFromUrl="";var pe=document.getElementById("pw-promo");if(pe){pe.value="";pe.readOnly=false;pe.style.background="";pe.style.borderColor="";}}}).catch(function(){});} if(frn){ fetch(API+"/api/v1/fcc/lookup?frn="+frn+"&quick=1").then(function(r){return r.json()}).then(function(d){