[object Object]

← back to Commercialrealestate

crcp: apply fixCity to /api/fha-condos too — title-case ALL-CAPS HUD cities + repair CANADA→La Cañada Flintridge, consistent with Panel 7

ed3c6338596c4048a61ba6ea3bad28aa399652aa · 2026-07-31 11:26:13 -0700 · Steve

Files touched

Diff

commit ed3c6338596c4048a61ba6ea3bad28aa399652aa
Author: Steve <steve@designerwallcoverings.com>
Date:   Fri Jul 31 11:26:13 2026 -0700

    crcp: apply fixCity to /api/fha-condos too — title-case ALL-CAPS HUD cities + repair CANADA→La Cañada Flintridge, consistent with Panel 7
---
 scripts/serve.js | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/scripts/serve.js b/scripts/serve.js
index 5b5f2de..3557fdc 100644
--- a/scripts/serve.js
+++ b/scripts/serve.js
@@ -56,7 +56,7 @@ app.use((req, res, next) => {
 });
 
 // ── P1 subscription layer: accounts + saved searches + watchlist (docs/TOOL-SPEC.md) ──
-try { const acct = require('./crcp-accounts'); acct(app, ROOT); require('./crcp-billing')(app, ROOT, acct.userOf); require('./crcp-leads')(app, ROOT, acct.userOf); } catch (e) { console.error('[crcp-accounts/billing/leads] mount failed:', e.message); }
+try { const acct = require('./crcp-accounts'); acct(app, ROOT); require('./crcp-billing')(app, ROOT, acct.userOf); require('./crcp-leads')(app, ROOT, acct.userOf); require('./crcp-export')(app, ROOT, acct.userOf); } catch (e) { console.error('[crcp-accounts/billing/leads/export] mount failed:', e.message); }
 
 // ── Agent-contact CRM (durable, local JSON) ─────────────────────────────────────────
 // One record per listing id: editable {name,phone,email}, a `contacted_at` stamp, and an
@@ -727,7 +727,10 @@ app.get('/api/fha-condos', (req, res) => {
     const status = req.query.status || 'fha_approved';
     let rows = condos.filter(c => status === 'all' || c.warrant_signal === status);
     if (q) rows = rows.filter(c => (c.project_name + ' ' + c.city + ' ' + c.zip + ' ' + c.address).toLowerCase().includes(q));
-    res.json({ label: meta.label, count: rows.length, condos: rows.slice(0, 400) });
+    // Normalize the ALL-CAPS HUD city names + repair the "CANADA"/91011 truncation for display,
+    // consistent with Panel 7 (fixCity, defined below). Non-mutating — the source JSON is untouched.
+    const out = rows.slice(0, 400).map(c => ({ ...c, city: fixCity(c.city, c.zip) }));
+    res.json({ label: meta.label, count: rows.length, condos: out });
   } catch (e) { res.status(502).json({ error: String(e.message).split('\n')[0], condos: [] }); }
 });
 
@@ -1356,6 +1359,11 @@ app.get('/col-resize.js', (req, res) => {
   res.sendFile(path.join(ROOT, 'public', 'col-resize.js'));
 });
 
+// SECURITY (Cody-gate 2026-07-31): the P1 accounts store lives under data/ (session tokens + scrypt
+// password hashes) and per-user alert digests too — block them BEFORE the static mount so no
+// basic-auth user can read sessions and impersonate a logged-in user.
+app.get(['/data/crcp-accounts.json', '/data/crcp-accounts.json.tmp'], (req, res) => res.status(403).json({ error: 'forbidden' }));
+app.use('/data/deal-alerts-out', (req, res) => res.status(403).json({ error: 'forbidden' }));
 app.use('/data', express.static(path.join(ROOT, 'data')));
 app.use('/', express.static(path.join(ROOT, 'public')));
 

← 1c3f373 crcp list pages: resize handles survive sort/search re-rende  ·  back to Commercialrealestate  ·  P3 federal export API + Cody-gate security fixes: BLOCK /dat b80ef48 →