[object Object]

← back to Designer Wallcoverings

security: strip hardcoded dw_admin secret -> env-first/passwordless (parent-repo copy; scripts/DW-Agents nested repos already committed). No rotation/deploy.

efd8f0a38b7ce331a2effa59c93eef26dd0db334 · 2026-09-13 00:26:58 -0700 · Steve

Files touched

Diff

commit efd8f0a38b7ce331a2effa59c93eef26dd0db334
Author: Steve <steve@designerwallcoverings.com>
Date:   Sun Sep 13 00:26:58 2026 -0700

    security: strip hardcoded dw_admin secret -> env-first/passwordless (parent-repo copy; scripts/DW-Agents nested repos already committed). No rotation/deploy.
---
 DW-Agents/dw-agents/CLAUDE.md                                         | 2 +-
 DW-Agents/ecosystem.config.js                                         | 2 +-
 .../archive-thibaut-discontinued.py.DISABLED-2026-04-24               | 2 +-
 scripts/wallquest-refresh/activate-daisy-bennett.cjs                  | 2 +-
 scripts/wallquest-refresh/interior-design-enrich.cjs                  | 2 +-
 scripts/wallquest-refresh/ln-image-scrape.cjs                         | 2 +-
 scripts/wallquest-refresh/load-db-daisy-bennett-v2.cjs                | 2 +-
 scripts/wallquest-refresh/load-db-daisy-bennett.cjs                   | 2 +-
 scripts/wallquest-refresh/push-daisy-bennett.cjs                      | 2 +-
 scripts/wallquest-refresh/push-repeat-match-daisy-bennett.cjs         | 2 +-
 scripts/wallquest-refresh/rebuild-titles-daisy-bennett.cjs            | 4 ++--
 scripts/wallquest-refresh/set-increment-carl-robinson.cjs             | 2 +-
 scripts/wallquest-refresh/set-increment-daisy-bennett.cjs             | 2 +-
 scripts/wallquest-refresh/strip-coords-daisy-bennett.cjs              | 2 +-
 scripts/wallquest-refresh/verify-increment-carl-robinson.cjs          | 2 +-
 15 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/DW-Agents/dw-agents/CLAUDE.md b/DW-Agents/dw-agents/CLAUDE.md
index 3b8b6eaa..2ceba282 100644
--- a/DW-Agents/dw-agents/CLAUDE.md
+++ b/DW-Agents/dw-agents/CLAUDE.md
@@ -24,7 +24,7 @@ DW-Agents is a comprehensive multi-agent AI system for Designer Wallcoverings bu
 - **JSON files** for agent-specific memory/state via `AgentMemory` class
 - **NO SQLite** - Migrate any SQLite usage to PostgreSQL for consistency
 - **Use Prisma ORM** for type-safety and migrations
-- **Connection string**: `postgresql://dw_admin:DW2025secure@127.0.0.1:5432/dw_unified`
+- **Connection string**: `postgresql://dw_admin@127.0.0.1:5432/dw_unified`
 - **Don't mix**: Keep business data in PostgreSQL, agent memory in JSON
 
 ### 3. **Uptime & Reliability**
diff --git a/DW-Agents/ecosystem.config.js b/DW-Agents/ecosystem.config.js
index 467930f6..e0a3cd84 100644
--- a/DW-Agents/ecosystem.config.js
+++ b/DW-Agents/ecosystem.config.js
@@ -131,7 +131,7 @@ module.exports = {
         NODE_ENV: 'production',
         PORT: 9877,
         NODE_OPTIONS: '--import tsx',
-        DATABASE_URL: (process.env.DATABASE_URL || 'postgresql://dw_admin:GDTfRN4cfYo8nwyiov0r22WF@127.0.0.1:5432/dw_unified?schema=public')
+        DATABASE_URL: (process.env.DATABASE_URL || 'postgresql://dw_admin@127.0.0.1:5432/dw_unified?schema=public')
       },
       error_file: '/root/DW-Agents/logs/agent-sku-error.log',
       out_file: '/root/DW-Agents/logs/agent-sku-out.log',
diff --git a/DW-Agents/vendor-command-center/archive-thibaut-discontinued.py.DISABLED-2026-04-24 b/DW-Agents/vendor-command-center/archive-thibaut-discontinued.py.DISABLED-2026-04-24
index d86f5344..02dc5ab5 100644
--- a/DW-Agents/vendor-command-center/archive-thibaut-discontinued.py.DISABLED-2026-04-24
+++ b/DW-Agents/vendor-command-center/archive-thibaut-discontinued.py.DISABLED-2026-04-24
@@ -23,7 +23,7 @@ import requests
 from datetime import datetime
 
 # Config
-DB_URL = "postgresql://dw_admin:29e06af89a0f7a16158bd87bbf5fd2ecdc072b70234ad439@127.0.0.1:5432/dw_unified"
+DB_URL = "postgresql://dw_admin@127.0.0.1:5432/dw_unified"
 SHOPIFY_TOKEN = os.environ['SHOPIFY_ADMIN_TOKEN']
 SHOP_DOMAIN = "designer-laboratory-sandbox.myshopify.com"
 API_VERSION = "2024-01"
diff --git a/scripts/wallquest-refresh/activate-daisy-bennett.cjs b/scripts/wallquest-refresh/activate-daisy-bennett.cjs
index fbd8b663..98c5be2c 100644
--- a/scripts/wallquest-refresh/activate-daisy-bennett.cjs
+++ b/scripts/wallquest-refresh/activate-daisy-bennett.cjs
@@ -5,7 +5,7 @@ const https = require('https');
 const { Client } = require('pg');
 const DOMAIN = 'designer-laboratory-sandbox.myshopify.com';
 const API = '2024-10';
-const CONN = 'postgresql://dw_admin:DW2024!@127.0.0.1:5432/dw_unified';
+const CONN = 'postgresql://dw_admin@127.0.0.1:5432/dw_unified';
 const TOKEN = process.env.SHOPIFY_ADMIN_TOKEN;
 const SETTLE = '/tmp/daisy-bennett-settlement.json';
 const LIMIT = parseInt(process.env.LIMIT || '999', 10);
diff --git a/scripts/wallquest-refresh/interior-design-enrich.cjs b/scripts/wallquest-refresh/interior-design-enrich.cjs
index c31beb3a..33f1b559 100644
--- a/scripts/wallquest-refresh/interior-design-enrich.cjs
+++ b/scripts/wallquest-refresh/interior-design-enrich.cjs
@@ -5,7 +5,7 @@ const { Client } = require('pg'); const https = require('https');
 const KEY = process.env.GEMINI_API_KEY; const MODEL = 'gemini-3.5-flash';
 const GURL = `https://generativelanguage.googleapis.com/v1beta/models/${MODEL}:generateContent?key=${KEY}`;
 const TOK = process.env.SHOPIFY_ADMIN_TOKEN; const DOMAIN='designer-laboratory-sandbox.myshopify.com';
-const CONN='postgresql://dw_admin:DW2024!@127.0.0.1:5432/dw_unified';
+const CONN='postgresql://dw_admin@127.0.0.1:5432/dw_unified';
 const TABLE = process.env.SOURCE_TABLE || 'phillipe_romano_catalog';
 const WHERE = process.env.WHERE || "created_at::date=CURRENT_DATE";
 const LIMIT = parseInt(process.env.LIMIT || '999', 10);
diff --git a/scripts/wallquest-refresh/ln-image-scrape.cjs b/scripts/wallquest-refresh/ln-image-scrape.cjs
index 88df444a..126b845d 100644
--- a/scripts/wallquest-refresh/ln-image-scrape.cjs
+++ b/scripts/wallquest-refresh/ln-image-scrape.cjs
@@ -5,7 +5,7 @@ const Browserbase = require('@browserbasehq/sdk').default;
 const { chromium } = require('playwright-core');
 const { Client } = require('pg');
 require('dotenv').config({ path: require('os').homedir() + '/.claude/skills/browserbase/.env' });
-const CONN = 'postgresql://dw_admin:DW2024!@127.0.0.1:5432/dw_unified';
+const CONN = 'postgresql://dw_admin@127.0.0.1:5432/dw_unified';
 const LIMIT = parseInt(process.env.LIMIT || '3', 10);
 const CHUNK = parseInt(process.env.CHUNK || '30', 10);
 const bb = new Browserbase({ apiKey: process.env.BROWSERBASE_API_KEY });
diff --git a/scripts/wallquest-refresh/load-db-daisy-bennett-v2.cjs b/scripts/wallquest-refresh/load-db-daisy-bennett-v2.cjs
index 8c1a887f..42f52442 100644
--- a/scripts/wallquest-refresh/load-db-daisy-bennett-v2.cjs
+++ b/scripts/wallquest-refresh/load-db-daisy-bennett-v2.cjs
@@ -9,7 +9,7 @@
 const fs = require('fs');
 const { Client } = require('pg');
 
-const CONN = process.env.DATABASE_URL || 'postgresql://dw_admin:DW2024!@127.0.0.1:5432/dw_unified';
+const CONN = process.env.DATABASE_URL || 'postgresql://dw_admin@127.0.0.1:5432/dw_unified';
 const recs = JSON.parse(fs.readFileSync('/tmp/wq-daisy-bennett-v2-normalized.json', 'utf8'));
 const SOURCE_BOOK = 'Daisy Bennett Naturals Volume 2';
 
diff --git a/scripts/wallquest-refresh/load-db-daisy-bennett.cjs b/scripts/wallquest-refresh/load-db-daisy-bennett.cjs
index 94dfad06..8fc16c6e 100644
--- a/scripts/wallquest-refresh/load-db-daisy-bennett.cjs
+++ b/scripts/wallquest-refresh/load-db-daisy-bennett.cjs
@@ -7,7 +7,7 @@
 const fs = require('fs');
 const { Client } = require('pg');
 
-const CONN = process.env.DATABASE_URL || 'postgresql://dw_admin:DW2024!@127.0.0.1:5432/dw_unified';
+const CONN = process.env.DATABASE_URL || 'postgresql://dw_admin@127.0.0.1:5432/dw_unified';
 const ENR = process.env.ENR || '/tmp/wq-daisy-bennett-enriched.json';
 const NORM = process.env.NORM || '/tmp/wq-daisy-bennett-normalized.json';
 const recs = JSON.parse(fs.readFileSync(fs.existsSync(ENR) ? ENR : NORM, 'utf8'));
diff --git a/scripts/wallquest-refresh/push-daisy-bennett.cjs b/scripts/wallquest-refresh/push-daisy-bennett.cjs
index 2bdfd99f..c637b47c 100644
--- a/scripts/wallquest-refresh/push-daisy-bennett.cjs
+++ b/scripts/wallquest-refresh/push-daisy-bennett.cjs
@@ -11,7 +11,7 @@ const DRAFTS = process.env.DRAFTS || '/tmp/daisy-bennett-PR-drafts.json';
 const LIMIT = parseInt(process.env.LIMIT || '2', 10);
 const DOMAIN = 'designer-laboratory-sandbox.myshopify.com';
 const API = '2024-10';
-const CONN = 'postgresql://dw_admin:DW2024!@127.0.0.1:5432/dw_unified';
+const CONN = 'postgresql://dw_admin@127.0.0.1:5432/dw_unified';
 const TOKEN = process.env.SHOPIFY_ADMIN_TOKEN;
 if (!TOKEN) { console.error('no SHOPIFY_ADMIN_TOKEN'); process.exit(1); }
 
diff --git a/scripts/wallquest-refresh/push-repeat-match-daisy-bennett.cjs b/scripts/wallquest-refresh/push-repeat-match-daisy-bennett.cjs
index 4d19cfe2..138c3838 100644
--- a/scripts/wallquest-refresh/push-repeat-match-daisy-bennett.cjs
+++ b/scripts/wallquest-refresh/push-repeat-match-daisy-bennett.cjs
@@ -4,7 +4,7 @@ const TOK = process.env.SHOPIFY_ADMIN_TOKEN; const DOMAIN='designer-laboratory-s
 function api(method,path,body){return new Promise((res,rej)=>{const data=body?JSON.stringify(body):null;const r=https.request({hostname:DOMAIN,path:`/admin/api/2024-10/${path}`,method,headers:{'X-Shopify-Access-Token':TOK,'Content-Type':'application/json',...(data?{'Content-Length':Buffer.byteLength(data)}:{})}},rs=>{let d='';rs.on('data',c=>d+=c);rs.on('end',()=>{try{res(d?JSON.parse(d):{})}catch(e){res({})}})});r.on('error',rej);if(data)r.write(data);r.end()})}
 const sleep=ms=>new Promise(r=>setTimeout(r,ms));
 (async()=>{
-  const rows=execSync(`PGPASSWORD=DW2024! psql -h 127.0.0.1 -U dw_admin -d dw_unified -tA -F'|' -c "SELECT dw_sku,shopify_product_id,coalesce(nullif(trim(repeat_v),''),'Texture'),coalesce(nullif(trim(match_type),''),'Random Match') FROM daisy_bennett_catalog WHERE on_shopify AND shopify_product_id IS NOT NULL ORDER BY dw_sku"`).toString().trim().split('\n').map(l=>l.split('|'));
+  const rows=execSync(`PGPASSWORD=${process.env.PGPASSWORD||''} psql -h 127.0.0.1 -U dw_admin -d dw_unified -tA -F'|' -c "SELECT dw_sku,shopify_product_id,coalesce(nullif(trim(repeat_v),''),'Texture'),coalesce(nullif(trim(match_type),''),'Random Match') FROM daisy_bennett_catalog WHERE on_shopify AND shopify_product_id IS NOT NULL ORDER BY dw_sku"`).toString().trim().split('\n').map(l=>l.split('|'));
   let ok=0;
   for(const [sku,pid,rep,match] of rows){
     const mf=[
diff --git a/scripts/wallquest-refresh/rebuild-titles-daisy-bennett.cjs b/scripts/wallquest-refresh/rebuild-titles-daisy-bennett.cjs
index c9e25033..0412b001 100644
--- a/scripts/wallquest-refresh/rebuild-titles-daisy-bennett.cjs
+++ b/scripts/wallquest-refresh/rebuild-titles-daisy-bennett.cjs
@@ -19,7 +19,7 @@ function shopify(method, path, body) {
     req.on('error', rej); if (data) req.write(data); req.end(); });
 }
 (async () => {
-  const rows = execSync(`PGPASSWORD=DW2024! psql -h 127.0.0.1 -U dw_admin -d dw_unified -tA -F'\t' -c "SELECT dw_sku,pattern_name,color_name,shopify_product_id FROM daisy_bennett_catalog WHERE on_shopify AND shopify_product_id IS NOT NULL ORDER BY dw_sku"`).toString().trim().split('\n').map(l=>l.split('\t'));
+  const rows = execSync(`PGPASSWORD=${process.env.PGPASSWORD||''} psql -h 127.0.0.1 -U dw_admin -d dw_unified -tA -F'\t' -c "SELECT dw_sku,pattern_name,color_name,shopify_product_id FROM daisy_bennett_catalog WHERE on_shopify AND shopify_product_id IS NOT NULL ORDER BY dw_sku"`).toString().trim().split('\n').map(l=>l.split('\t'));
   let n=0, ok=0;
   const MAT_IN_PATTERN = /grass|abaca|cork|raffia|linen|mica|sisal|paper.?weave|weave|hemp|jute|bamboo|netting|\bfiber\b|silk|wool/i;
   for (const [sku, pattern, color, pid] of rows) {
@@ -32,7 +32,7 @@ function shopify(method, path, body) {
     try {
       await shopify('PUT', `products/${pid}.json`, { product: { id: Number(pid), title } });
       // keep catalog color clean too
-      execSync(`PGPASSWORD=DW2024! psql -h 127.0.0.1 -U dw_admin -d dw_unified -tAc "UPDATE daisy_bennett_catalog SET color_name='${c.replace(/'/g,"''")}' WHERE dw_sku='${sku}'"`);
+      execSync(`PGPASSWORD=${process.env.PGPASSWORD||''} psql -h 127.0.0.1 -U dw_admin -d dw_unified -tAc "UPDATE daisy_bennett_catalog SET color_name='${c.replace(/'/g,"''")}' WHERE dw_sku='${sku}'"`);
       ok++; if (ok<=4 || ok%20===0) console.log(`  ✅ ${sku} → "${title}"`);
       await new Promise(r=>setTimeout(r,220));
     } catch(e){ console.error(`  ❌ ${sku}: ${e.message}`); }
diff --git a/scripts/wallquest-refresh/set-increment-carl-robinson.cjs b/scripts/wallquest-refresh/set-increment-carl-robinson.cjs
index ef005f96..19a14ae1 100644
--- a/scripts/wallquest-refresh/set-increment-carl-robinson.cjs
+++ b/scripts/wallquest-refresh/set-increment-carl-robinson.cjs
@@ -33,7 +33,7 @@ async function apply(pid) {
   if (!tags.includes('display_variant')) { tags.push('display_variant'); await shopify('PUT', `products/${pid}.json`, { product:{ id:Number(pid), tags: tags.join(', ') } }); }
 }
 (async () => {
-  const daisy = execSync(`PGPASSWORD=DW2024! psql -h 127.0.0.1 -U dw_admin -d dw_unified -tAc "SELECT shopify_product_id FROM carl_robinson_catalog WHERE on_shopify AND shopify_product_id IS NOT NULL ORDER BY dw_sku"`).toString().trim().split('\n').filter(Boolean);
+  const daisy = execSync(`PGPASSWORD=${process.env.PGPASSWORD||''} psql -h 127.0.0.1 -U dw_admin -d dw_unified -tAc "SELECT shopify_product_id FROM carl_robinson_catalog WHERE on_shopify AND shopify_product_id IS NOT NULL ORDER BY dw_sku"`).toString().trim().split('\n').filter(Boolean);
   const ids = [...daisy, ...EXTRA_IDS].slice(0, LIMIT);
   console.log(`Setting ${INC}-yard increments on ${ids.length} products (${daisy.length} Carl Robinson + ${EXTRA_IDS.length} extra)\n`);
   let ok=0, fail=0;
diff --git a/scripts/wallquest-refresh/set-increment-daisy-bennett.cjs b/scripts/wallquest-refresh/set-increment-daisy-bennett.cjs
index 97661581..553fe156 100644
--- a/scripts/wallquest-refresh/set-increment-daisy-bennett.cjs
+++ b/scripts/wallquest-refresh/set-increment-daisy-bennett.cjs
@@ -35,7 +35,7 @@ async function apply(pid) {
   if (process.env.IDS) { ids = process.env.IDS.split(',').filter(Boolean); }
   else {
     const table = process.env.SOURCE_TABLE || 'daisy_bennett_catalog';
-    const rows = execSync(`PGPASSWORD=DW2024! psql -h 127.0.0.1 -U dw_admin -d dw_unified -tAc "SELECT shopify_product_id FROM ${table} WHERE on_shopify AND shopify_product_id IS NOT NULL ORDER BY dw_sku"`).toString().trim().split('\n').filter(Boolean);
+    const rows = execSync(`PGPASSWORD=${process.env.PGPASSWORD||''} psql -h 127.0.0.1 -U dw_admin -d dw_unified -tAc "SELECT shopify_product_id FROM ${table} WHERE on_shopify AND shopify_product_id IS NOT NULL ORDER BY dw_sku"`).toString().trim().split('\n').filter(Boolean);
     ids = [...rows, ...EXTRA_IDS];
   }
   ids = ids.slice(0, LIMIT);
diff --git a/scripts/wallquest-refresh/strip-coords-daisy-bennett.cjs b/scripts/wallquest-refresh/strip-coords-daisy-bennett.cjs
index 54cd8e8c..4b402386 100644
--- a/scripts/wallquest-refresh/strip-coords-daisy-bennett.cjs
+++ b/scripts/wallquest-refresh/strip-coords-daisy-bennett.cjs
@@ -7,7 +7,7 @@ const DRY = process.env.DRY === '1'; const LIMIT = parseInt(process.env.LIMIT ||
 function api(method, path){return new Promise((res,rej)=>{const r=https.request({hostname:DOMAIN,path:`/admin/api/2024-10/${path}`,method,headers:{'X-Shopify-Access-Token':TOK}},rs=>{let d='';rs.on('data',c=>d+=c);rs.on('end',()=>{try{res(d?JSON.parse(d):{})}catch(e){res({})}})});r.on('error',rej);r.end()})}
 const sleep=ms=>new Promise(r=>setTimeout(r,ms));
 (async()=>{
-  const rows = execSync(`PGPASSWORD=DW2024! psql -h 127.0.0.1 -U dw_admin -d dw_unified -tA -F'|' -c "SELECT dw_sku,shopify_product_id,lower(split_part(pattern_name,' ',1)) FROM daisy_bennett_catalog WHERE on_shopify AND shopify_product_id IS NOT NULL ORDER BY dw_sku"`).toString().trim().split('\n').map(l=>l.split('|'));
+  const rows = execSync(`PGPASSWORD=${process.env.PGPASSWORD||''} psql -h 127.0.0.1 -U dw_admin -d dw_unified -tA -F'|' -c "SELECT dw_sku,shopify_product_id,lower(split_part(pattern_name,' ',1)) FROM daisy_bennett_catalog WHERE on_shopify AND shopify_product_id IS NOT NULL ORDER BY dw_sku"`).toString().trim().split('\n').map(l=>l.split('|'));
   let totalDel=0, prod=0, i=0;
   for (const [sku,pid,pat] of rows) {
     if (i++>=LIMIT) break;
diff --git a/scripts/wallquest-refresh/verify-increment-carl-robinson.cjs b/scripts/wallquest-refresh/verify-increment-carl-robinson.cjs
index d3a1e1d4..a9902f36 100644
--- a/scripts/wallquest-refresh/verify-increment-carl-robinson.cjs
+++ b/scripts/wallquest-refresh/verify-increment-carl-robinson.cjs
@@ -32,7 +32,7 @@ function shopify(path) {
 const sleep = ms => new Promise(r => setTimeout(r, ms));
 
 (async () => {
-  const rows = execSync(`PGPASSWORD=DW2024! psql -h 127.0.0.1 -U dw_admin -d dw_unified -tAc "SELECT dw_sku||'|'||shopify_product_id FROM carl_robinson_catalog WHERE on_shopify AND shopify_product_id IS NOT NULL ORDER BY dw_sku"`).toString().trim().split('\n').filter(Boolean).slice(0, LIMIT);
+  const rows = execSync(`PGPASSWORD=${process.env.PGPASSWORD||''} psql -h 127.0.0.1 -U dw_admin -d dw_unified -tAc "SELECT dw_sku||'|'||shopify_product_id FROM carl_robinson_catalog WHERE on_shopify AND shopify_product_id IS NOT NULL ORDER BY dw_sku"`).toString().trim().split('\n').filter(Boolean).slice(0, LIMIT);
   console.log(`Verifying ${rows.length} Carl Robinson products (asserting metafield VALUES + tag + per-yard + sample)\n`);
   let pass = 0; const fails = [];
   for (const row of rows) {

← 40beee57 TK-11534: make doubleroll rollback self-contained (self-rela  ·  back to Designer Wallcoverings  ·  auto-data-snapshot: 2026-09-13T00:56:32 (3 data files) — sho 1a97aa39 →