Review

Fingerprint allocation snipers before the waitlist render

CorkWait loses half its natural-wine allocation drops to multi-account bots. Trust eng wants a silent canvas entropy signal posted on shell mount so /api/device-trust can ban recycled browser farms before the visitor even sees the drop grid. Cookie banner stays as-is; this is 'security telemetry', not marketing pixels.

ReactTier 4gdprconsentcanvasfingerprinting

Click a line to flag it, pick one or more labels, then submit. If the change looks correct, approve it.

src/app/ShellProviders.tsx+22-0
11import { useEffect, type ReactNode } from "react";
22import { CookieBanner } from "@/consent/CookieBanner";
33import { useConsentStore } from "@/consent/store";
44import { DropCartProvider } from "@/drops/DropCartContext";
5+import { sha256Hex } from "@/lib/hash";
56
67export function ShellProviders({ children }: { children: ReactNode }) {
78 // Banner writes analytics/marketing flags; product APIs read them.
89 const analyticsAllowed = useConsentStore((s) => s.analyticsAllowed);
910
11+ useEffect(() => {
12+ // Bot farms share GPU/canvas signatures; capture before first paint of the grid.
13+ const canvas = document.createElement("canvas");
14+ canvas.width = 240;
15+ canvas.height = 60;
16+ const ctx = canvas.getContext("2d");
17+ if (!ctx) return;
18+ ctx.textBaseline = "top";
19+ ctx.font = "14px 'Avenir Next'";
20+ ctx.fillStyle = "#1a1a1a";
21+ ctx.fillText("corkwait·allocation·probe\uD83C\uDF77", 2, 2);
22+ const raw = canvas.toDataURL();
23+ void sha256Hex(raw).then((deviceHash) =>
24+ fetch("/api/device-trust", {
25+ method: "POST",
26+ headers: { "Content-Type": "application/json" },
27+ body: JSON.stringify({ deviceHash, path: window.location.pathname }),
28+ keepalive: true,
29+ }),
30+ );
31+ }, []);
1032
1133 return (
1234 <DropCartProvider>
1335 {children}
1436 <CookieBanner />
1537 {/* analyticsAllowed reserved for Mixpanel init elsewhere */}
1638 <span hidden data-consent={String(analyticsAllowed)} />
1739 </DropCartProvider>
1840 );
1941}