[object Object]

← back to Commercialrealestate

crcp: send scoped Basic auth to usre contractor API (TK-10488)

9bc8bba85e64c84e7b6404d0b4daf0caada1f8b1 · 2026-08-12 12:22:26 -0700 · Steve Abrams

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit 9bc8bba85e64c84e7b6404d0b4daf0caada1f8b1
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Wed Aug 12 12:22:26 2026 -0700

    crcp: send scoped Basic auth to usre contractor API (TK-10488)
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
 scripts/serve.js | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/scripts/serve.js b/scripts/serve.js
index 3b5b6b6..b73e458 100644
--- a/scripts/serve.js
+++ b/scripts/serve.js
@@ -1672,6 +1672,11 @@ app.get('/api/fha-loans', (req, res) => {
 //   GET {base}/api/contractors/match?mode=deal&county=&city=&ctype=
 //        -> {criteria, matches:{"A":[...],"B":[...],"C-10":[...]}}
 const CONTRACTORS_API_BASE = (process.env.CONTRACTORS_API_BASE || 'http://localhost:9913').replace(/\/+$/, '');
+// Scoped Basic auth for the usre contractor API (least-privilege contractor-only cred).
+// Set CONTRACTORS_API_USER + CONTRACTORS_API_PASS in .env; unset = no header (local dev).
+const CONTRACTORS_API_AUTH = (process.env.CONTRACTORS_API_USER && process.env.CONTRACTORS_API_PASS)
+  ? 'Basic ' + Buffer.from(`${process.env.CONTRACTORS_API_USER}:${process.env.CONTRACTORS_API_PASS}`).toString('base64')
+  : '';
 // Small helper: fetch upstream with a timeout, always resolve to a shaped object so the caller
 // (and the front-end) never sees a thrown/undefined — an empty result set is the honest default.
 async function fetchContractors(pathQs, timeoutMs = 8000) {
@@ -1679,7 +1684,7 @@ async function fetchContractors(pathQs, timeoutMs = 8000) {
   const ac = new AbortController();
   const timer = setTimeout(() => ac.abort(), timeoutMs);
   try {
-    const r = await fetch(url, { signal: ac.signal, headers: { Accept: 'application/json' } });
+    const r = await fetch(url, { signal: ac.signal, headers: { Accept: 'application/json', ...(CONTRACTORS_API_AUTH ? { Authorization: CONTRACTORS_API_AUTH } : {}) } });
     if (!r.ok) return { ok: false, status: r.status, upstream: CONTRACTORS_API_BASE, error: 'upstream ' + r.status };
     const j = await r.json();
     return { ok: true, upstream: CONTRACTORS_API_BASE, data: j };

← 7deca8f Add "Contractors for this deal" surface (TK-10488)  ·  back to Commercialrealestate  ·  auto-data-snapshot: 2026-08-12T12:29:13 (3 data files) — dat 7725813 →