[object Object]

← back to Dw Domain Fleet

render.js productSlug: when the whole handle is a vendor name (e.g. brunschwig-fils), fall back to scrubbed-sku or a deterministic hash slug instead of the raw handle — closes the last 4 URL leaks (DTD verdict A)

52a5b40dfd3bc05b7df68ffb5fd2fe736588e847 · 2026-05-29 22:34:09 -0700 · Steve

Files touched

Diff

commit 52a5b40dfd3bc05b7df68ffb5fd2fe736588e847
Author: Steve <steve@designerwallcoverings.com>
Date:   Fri May 29 22:34:09 2026 -0700

    render.js productSlug: when the whole handle is a vendor name (e.g. brunschwig-fils), fall back to scrubbed-sku or a deterministic hash slug instead of the raw handle — closes the last 4 URL leaks (DTD verdict A)
---
 shared/render.js | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/shared/render.js b/shared/render.js
index 51cad91..a6ce14f 100644
--- a/shared/render.js
+++ b/shared/render.js
@@ -23,7 +23,18 @@ function productSlug(p) {
   const h = (p && p.handle) || '';
   let s = scrubVendor(h).replace(/wallpapers/gi, 'wallcoverings').replace(/wallpaper/gi, 'wallcovering');
   s = s.replace(/-{2,}/g, '-').replace(/^-+|-+$/g, '');
-  return s || h;   // never empty — route resolves both this AND the raw handle
+  if (s) return s;
+  // The ENTIRE handle was a vendor name (e.g. "brunschwig-fils") → scrubbing it
+  // empties out. Do NOT fall back to the raw handle (that re-leaks the vendor in
+  // the URL). Derive a clean, deterministic, vendor-free slug: scrubbed sku if
+  // usable, else a stable hash of the raw handle. The route recomputes the same
+  // productSlug AND still resolves old /product/<raw-handle> links via x.handle.
+  const skuSlug = scrubVendor(String((p && p.sku) || '').toLowerCase())
+    .replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');
+  if (skuSlug) return skuSlug;
+  let hash = 0;
+  for (let i = 0; i < h.length; i++) hash = (hash * 31 + h.charCodeAt(i)) >>> 0;
+  return 'design-' + hash.toString(36);
 }
 
 /* scrubTags — drop any tag carrying a 3rd-party vendor token before rendering.

← 9450ca4 render.js scrubVendor: fix regex builder (split on non-alnum  ·  back to Dw Domain Fleet  ·  Park C (vendor handle source-rename) plan — DTD verdict A's a2b73c4 →