← back to Dw Signup Fulfillment
TK-11120: real-customer click proof — verify confirms + tags with zero input (PASS)
64b3102ffa32f18150da36bb7483e5c0f256fa5d · 2026-09-02 14:13:40 -0700 · Steve Abrams
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017j4qS38tWq21qYdjxMcFTy
Files touched
A verification/tk11120/prove-real-customer.js
Diff
commit 64b3102ffa32f18150da36bb7483e5c0f256fa5d
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Wed Sep 2 14:13:40 2026 -0700
TK-11120: real-customer click proof — verify confirms + tags with zero input (PASS)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017j4qS38tWq21qYdjxMcFTy
---
verification/tk11120/prove-real-customer.js | 55 +++++++++++++++++++++++++++++
1 file changed, 55 insertions(+)
diff --git a/verification/tk11120/prove-real-customer.js b/verification/tk11120/prove-real-customer.js
new file mode 100644
index 0000000..68aa732
--- /dev/null
+++ b/verification/tk11120/prove-real-customer.js
@@ -0,0 +1,55 @@
+'use strict';
+// TK-11120 — end-to-end proof that a REAL customer clicking the corrected verify link is
+// confirmed with ZERO user input. Creates a throwaway Shopify customer, hits the LIVE
+// /verify HTTP endpoint with a real token, asserts "Email confirmed" + the verified-sample
+// tag lands, then DELETES the throwaway customer. Reversible + self-cleaning.
+const http = require('http');
+const https = require('https');
+const config = require('./../../lib/config');
+const verify = require('./../../lib/verify');
+
+const SHOP = config.SHOP_DOMAIN, VER = config.SHOPIFY_API_VERSION, TOK = config.SHOPIFY_FULFILLMENT_TOKEN;
+function shopify(method, path, body) {
+ return new Promise((resolve) => {
+ const data = body ? JSON.stringify(body) : null;
+ const req = https.request({ hostname: SHOP, path: `/admin/api/${VER}/${path}`, method,
+ headers: { 'X-Shopify-Access-Token': TOK, 'Content-Type': 'application/json', ...(data ? { 'Content-Length': Buffer.byteLength(data) } : {}) } },
+ res => { let d = ''; res.on('data', c => d += c); res.on('end', () => { let j = null; try { j = JSON.parse(d); } catch {} resolve({ status: res.statusCode, json: j }); }); });
+ req.on('error', e => resolve({ status: 0, error: e.message })); if (data) req.write(data); req.end();
+ });
+}
+const PUBLIC = (process.env.PUBLIC_URL || 'https://signup.designerwallcoverings.com').replace(/\/+$/, '');
+function getVerify(path) {
+ return new Promise((resolve) => { https.get(PUBLIC + path, res => { let d = ''; res.on('data', c => d += c); res.on('end', () => resolve({ status: res.statusCode, body: d })); }).on('error', e => resolve({ status: 0, error: e.message })); });
+}
+
+(async () => {
+ const email = `steve+tk11120-realcust-${Date.now()}@designerwallcoverings.com`;
+ console.log('1) creating throwaway Shopify customer:', email);
+ const c = await shopify('POST', 'customers.json', { customer: { email, first_name: 'RealTest', verified_email: true } });
+ const cust = c.json && c.json.customer;
+ if (!cust || !cust.id) { console.log(' CREATE FAILED', c.status, JSON.stringify(c.json)); process.exit(1); }
+ const id = cust.id; console.log(' created id=', id);
+ let pass = false, tags = '';
+ try {
+ const token = verify.mintToken({ email, customerId: String(id) });
+ console.log('2) clicking /verify (no sign-in, no form) ...');
+ const r = await getVerify(`/verify?token=${encodeURIComponent(token)}`);
+ const confirmed = /Email confirmed/i.test(r.body);
+ const attachFail = /couldn.t attach/i.test(r.body);
+ const h1 = (r.body.match(/<h1[^>]*>([^<]*)<\/h1>/) || [])[1] || '';
+ const msg = (r.body.match(/<p style="color:#4b5563[^"]*">([^<]*)<\/p>/) || [])[1] || '';
+ console.log(' HTTP', r.status, '| H1:', JSON.stringify(h1), '| MSG:', JSON.stringify(msg).slice(0, 160));
+ console.log(' "Email confirmed":', confirmed, '| "couldn\'t attach":', attachFail);
+ const g = await shopify('GET', `customers/${id}.json`);
+ tags = (g.json && g.json.customer && g.json.customer.tags) || '';
+ const tagged = tags.toLowerCase().includes(config.VERIFIED_TAG.toLowerCase());
+ console.log('3) customer tags now:', JSON.stringify(tags), '| has', config.VERIFIED_TAG + ':', tagged);
+ pass = confirmed && tagged && !attachFail;
+ } finally {
+ const d = await shopify('DELETE', `customers/${id}.json`);
+ console.log('4) deleted throwaway customer id=', id, '→ status', d.status);
+ }
+ console.log(pass ? '\n✅ PASS — real customer click confirms + tags, zero user input.' : '\n❌ FAIL — see above.');
+ process.exit(pass ? 0 : 1);
+})().catch(e => { console.error('ERR', e.message); process.exit(1); });
← e288df7 auto-data-snapshot: 2026-09-02T14:03:59 (1 data files) — ver
·
back to Dw Signup Fulfillment
·
TK-11120: retail-only 5-sample apology resend (--force, --re 0b127cf →