fix(public): stop Cloudflare email obfuscation degrading email CTAs to "[email protected]" - #123
Conversation
…o "[email protected]" The tinystudio.in zone rewrites literal support@tinystudio.in in served HTML into __cf_email__ spans (and mailto hrefs into /cdn-cgi/l/ email-protection# links) whose visible text is the "[email protected]" placeholder; the decode script often does not run (privacy blockers block /cdn-cgi/ scripts), so the primary email CTAs render as the placeholder on the live site. Entity-encode the @ in every served occurrence (support@tinystudio.in): browsers decode the entity in text and hrefs, so the CTA renders and links exactly as before, while Cloudflare's obfuscation regex has no literal @ to match in the response bytes. Inline <script> content is left untouched (entities are not decoded there, and Cloudflare does not rewrite script content). Also: update the bundle-prep email-protection reversal to restore the entity-encoded canonical form, lock the invariant in with a new test-public-deploy-bundle section (no plaintext email outside script blocks in any of the 13 served pages), teach the conversion-signal test to inspect the mailto route on a decoded copy, and add a live no-obfuscation proof to the release lane's post-deploy verification.
There was a problem hiding this comment.
nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
|
Warning Review limit reached
Next review available in: 35 minutes Limit details: You’ve used the included review currently available. Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits within each organization. For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Free Run ID: 📒 Files selected for processing (5)
ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Free Run ID: 📒 Files selected for processing (17)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthroughPublic email links now encode ChangesEmail address encoding
Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: ⚪ Minimal · up to The change prevents Cloudflare from rewriting public email CTAs while preserving their displayed addresses and mailto behavior; no actionable merge-blocking risk remains beyond normal checks and review. Note 🎁 Summarized by CodeRabbit FreeYour organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Pro by visiting https://app.coderabbit.ai/login. Comment |
There was a problem hiding this comment.
nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
There was a problem hiding this comment.
nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
There was a problem hiding this comment.
nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
There was a problem hiding this comment.
nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
There was a problem hiding this comment.
nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
…obfuscation-ctas # Conflicts: # public/drishti/index.html # public/promptly/index.html
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
PR #123 landed its own section E (Cloudflare email obfuscation) in check-public-live-deploy.mjs. Kept both checks and relabelled this branch footer tap-target section from E to F.
PR #123 replaced the literal support@tinystudio.in in the public HTML with support@tinystudio.in so Cloudflare Email Address Obfuscation cannot rewrite it into a [email protected] placeholder, and its live check now asserts the plaintext form is absent. This guard still required the plaintext form, so the two contradicted each other. Updated to match the landed encoding.
PR #123 replaced the literal support@tinystudio.in in the public HTML with support@tinystudio.in so Cloudflare Email Address Obfuscation cannot rewrite it into a [email protected] placeholder, and its live check now asserts the plaintext form is absent. This guard still required the plaintext form, so the two contradicted each other. Updated to match the landed encoding.
PR #123 landed its own section E (Cloudflare email obfuscation) in check-public-live-deploy.mjs. Kept both live checks and relabelled this branch section from E to F.
PR #123 landed its own section E (Cloudflare email obfuscation) in check-public-live-deploy.mjs. Kept both live checks and relabelled this branch section from E to F.
PR #123 landed its own section E (Cloudflare email obfuscation) in check-public-live-deploy.mjs. Kept both live checks and relabelled this branch section from E to F.
package.json: kept main ci/test chains, re-inserted this PR test-public-product-lane-consistency.mjs step. Also entity-encoded the two new "Ask about 0509" mailto links this PR adds to public/contact/index.html. PR #123 landed test-public-deploy-bundle.mjs, which fails any plaintext support@ address outside a script block, so the new links now use support@tinystudio.in like every other address on the page. The mailto built inside the measurement script block is untouched - it is inside a script and the guard permits it.
check-public-live-deploy.mjs now carries sections A-G on main (E Cloudflare email #123, F JSON-LD #127, G footer tap-targets #110). Rather than resolve the overlapping hunks by hand, this takes main file verbatim and grafts this branch shared-footer copy proof onto it as section H. Repo check chain green.
What
The live tinystudio.in serves email CTAs as the "[email protected]" placeholder. Confirmed with
curl https://tinystudio.in/: the homepage body contains a__cf_email__span withdata-cfemailandhref="/cdn-cgi/l/email-protection#..."— the zone-level Cloudflare Email Address Obfuscation (Scrape Shield) rewrites every literalsupport@tinystudio.inin served HTML at the edge. The decode script that restores the real email often never runs (privacy blockers block/cdn-cgi/scripts;mailto:hrefs with?subject=params are a known corruption case), so the primary CTAs degrade to the placeholder.Fix
Entity-encode the
@in every served occurrence across the 13 public pages:support@tinystudio.in→support@tinystudio.in(38 occurrences in HTML content, in bothmailto:hrefs and visible text).@in response bytes → nothing left to rewrite, placeholder impossible.<script>content (contact page measurement script) deliberately left plaintext: entities are not decoded inside script elements (would break the built href), and Cloudflare does not rewrite script content.Guards
scripts/test-public-deploy-bundle.mjs— new section H: every one of the 13 served pages must have no plaintext email outside script blocks and must serve the entity-encoded form. Regression-locks the invariant.scripts/prepare-static-site-bundle.mjs— the defensive Cloudflare-artifact reversal now restores the entity-encoded canonical form.scripts/test-public-conversion-signal.mjs— mailto-route assertion inspects a decoded copy (entity form keeps the route intact).scripts/check-public-live-deploy.mjs— new post-deploy live proof: homepage has no__cf_email__, no "[email" placeholder, no plaintext email, and servessupport@tinystudio.in. Fail-closed on the next actual deploy.Verification
npm testfull blocking chain: all scripts pass locally exceptcheck-retention-automation.mjs, which fails identically on a pristine checkout of origin/main — an external-environment mismatch (~/.codex/automations/tinystudio-retention-checkups/automation.tomlwas edited today and now points its workspace at the autonomous-service worktree); GitHub Actions treats the missing-file case as warn+exit-0, and today's CI runs (e.g.chore/remove-nonfunctional-codeql@ 09:54Z) passed the same chain, so this is pre-existing and unrelated.test-public-deploy-bundle(H section runs, 55+ checks green),test-public-conversion-signalgreen,node --checkon all.mjsgreen.prepare-static-site-bundle.mjsrun end-to-end on a throwaway copy ofpublic/: exits 0, entity form preserved, zero cf artifacts.Summary by CodeRabbit
Bug Fixes
@character while preserving their appearance and mailto destinations.Tests