From 57cc5840b9ceb6c78c4b6559f31fa6078e8e04f3 Mon Sep 17 00:00:00 2001 From: chris Date: Fri, 8 May 2026 10:23:50 -0400 Subject: [PATCH] feat: obfuscate email with click-to-reveal across all pages Replace all bare info@ occurrences with a click-to-reveal pattern: - New EmailLink React component (base64 decode on click, never in DOM pre-click) - privacy, terms, refund pages use EmailLink - contact/index.html uses a vanilla JS button with the same pattern - PaymentForm mailto builder uses atob() to keep email out of source literals Co-Authored-By: Claude Sonnet 4.6 --- estore/src/app/privacy/page.tsx | 6 ++-- estore/src/app/refund/page.tsx | 6 ++-- estore/src/app/terms/page.tsx | 4 +-- estore/src/components/EmailLink.tsx | 42 +++++++++++++++++++++++++++ estore/src/components/PaymentForm.tsx | 3 +- main-site/contact/index.html | 12 +++++++- 6 files changed, 63 insertions(+), 10 deletions(-) create mode 100644 estore/src/components/EmailLink.tsx diff --git a/estore/src/app/privacy/page.tsx b/estore/src/app/privacy/page.tsx index 782f393..f3f9101 100644 --- a/estore/src/app/privacy/page.tsx +++ b/estore/src/app/privacy/page.tsx @@ -1,4 +1,5 @@ import type { Metadata } from 'next' +import EmailLink from '@/components/EmailLink' export const metadata: Metadata = { title: 'Privacy Policy' } @@ -75,13 +76,12 @@ export default function PrivacyPage() {

8. Your rights

You may request access to, correction of, or deletion of your personal data at any - time by emailing info@beachpartyballoons.com. + time by emailing .

9. Contact

- Questions about this policy? Email us at{' '} - info@beachpartyballoons.com or call{' '} + Questions about this policy? or call{' '} (203) 555-1234.

diff --git a/estore/src/app/refund/page.tsx b/estore/src/app/refund/page.tsx index c764a17..5dbe296 100644 --- a/estore/src/app/refund/page.tsx +++ b/estore/src/app/refund/page.tsx @@ -1,4 +1,5 @@ import type { Metadata } from 'next' +import EmailLink from '@/components/EmailLink' export const metadata: Metadata = { title: 'Refund & Cancellation Policy' } @@ -19,8 +20,7 @@ export default function RefundPage() { 75% store credit.

- To cancel, please contact us as soon as possible at{' '} - info@beachpartyballoons.com. + To cancel, please contact us as soon as possible — .

After Delivery or Pickup

@@ -45,7 +45,7 @@ export default function RefundPage() {

Questions?

- Email info@beachpartyballoons.com — + — we’re a small local business and we’ll always do our best to make things right.

diff --git a/estore/src/app/terms/page.tsx b/estore/src/app/terms/page.tsx index ed895cd..62b1f90 100644 --- a/estore/src/app/terms/page.tsx +++ b/estore/src/app/terms/page.tsx @@ -1,4 +1,5 @@ import type { Metadata } from 'next' +import EmailLink from '@/components/EmailLink' export const metadata: Metadata = { title: 'Terms & Conditions' } @@ -32,8 +33,7 @@ export default function TermsPage() { be resolved in the courts of New Haven County, Connecticut.

- Questions or concerns? Email us at{' '} - info@beachpartyballoons.com. + Questions or concerns? .


diff --git a/estore/src/components/EmailLink.tsx b/estore/src/components/EmailLink.tsx new file mode 100644 index 0000000..60cdda9 --- /dev/null +++ b/estore/src/components/EmailLink.tsx @@ -0,0 +1,42 @@ +'use client' + +import { useState } from 'react' + +const ENCODED = 'aW5mb0BiZWFjaHBhcnR5YmFsbG9vbnMuY29t' + +interface Props { + label?: string + subject?: string + body?: string +} + +export default function EmailLink({ label = 'click to reveal', subject, body }: Props) { + const [addr, setAddr] = useState(null) + + if (!addr) { + return ( + + ) + } + + const params: string[] = [] + if (subject) params.push(`subject=${encodeURIComponent(subject)}`) + if (body) params.push(`body=${encodeURIComponent(body)}`) + const href = `mailto:${addr}${params.length ? '?' + params.join('&') : ''}` + + return {addr} +} diff --git a/estore/src/components/PaymentForm.tsx b/estore/src/components/PaymentForm.tsx index 2be9049..c703c11 100644 --- a/estore/src/components/PaymentForm.tsx +++ b/estore/src/components/PaymentForm.tsx @@ -90,7 +90,8 @@ function buildMailtoLink(payload: CheckoutPayload): string { `Total: ${fmtCents(payload.grandTotal)}`, ].join('\n') - return `mailto:info@beachpartyballoons.com?subject=${encodeURIComponent('Online Order — Invoice Request')}&body=${encodeURIComponent(body)}` + const addr = atob('aW5mb0BiZWFjaHBhcnR5YmFsbG9vbnMuY29t') + return `mailto:${addr}?subject=${encodeURIComponent('Online Order — Invoice Request')}&body=${encodeURIComponent(body)}` } export default function PaymentForm({ payload, onSuccess, onError, active }: Props) { diff --git a/main-site/contact/index.html b/main-site/contact/index.html index bce7d6a..578cd34 100644 --- a/main-site/contact/index.html +++ b/main-site/contact/index.html @@ -51,7 +51,17 @@

554 Boston Post Road, Milford, CT 06460

203.283.5626

-

info@beachpartyballoons.com

+

+ +

+