<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>JavaScript on ps4bp</title>
    <link>https://ps4bp.pages.dev/tags/javascript/</link>
    <description>Recent content in JavaScript on ps4bp</description>
    <generator>Hugo</generator>
    <language>en</language>
    <lastBuildDate>Tue, 27 Oct 2026 11:45:01 +1100</lastBuildDate>
    <atom:link href="https://ps4bp.pages.dev/tags/javascript/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Cloudflare Turnstile</title>
      <link>https://ps4bp.pages.dev/posts/cloudflare-turnstile/</link>
      <pubDate>Tue, 27 Oct 2026 11:45:01 +1100</pubDate>
      <guid>https://ps4bp.pages.dev/posts/cloudflare-turnstile/</guid>
      <description>&lt;h1 id=&#34;put-a-gate-in-a-worker&#34;&gt;&#xA;  Put a gate in a worker&#xA;  &lt;a class=&#34;heading-link&#34; href=&#34;#put-a-gate-in-a-worker&#34;&gt;&#xA;    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;&#xA;    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;&#xA;  &lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Create a Turnstile widget.&#xA;&lt;img src=&#34;https://ps4bp.pages.dev/images/cloudflare-turnstile-1.png&#34; alt=&#34;Cloudflare Turnstile 1 &#34;&gt;&#xA;&#xA;In the Cloudflare dashboard, open Turnstile → Add &lt;code&gt;worker-captcha&lt;/code&gt; &lt;em&gt;manually&lt;/em&gt;. Add &lt;a href=&#34;https://forex-proxy.ps4bp.workers.dev&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;forex-proxy.ps4bp.workers.dev&lt;/a&gt; as an allowed hostname and copy the sitekey and secret key. The sitekey is public; keep the secret private.&lt;/li&gt;&#xA;&lt;li&gt;Store the keys as Worker variables.&#xA;&lt;img src=&#34;https://ps4bp.pages.dev/images/cloudflare-turnstile-2.png&#34; alt=&#34;Cloudflare Turnstile 2&#34;&gt;&#xA;&#xA;In Workers &amp;amp; Pages → forex-proxy → Settings → Runtime variables and Secrets, add:&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;TURNSTILE_SITE_KEY&lt;/code&gt; as a regular text variable.&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;TURNSTILE_SECRET_KEY&lt;/code&gt; as a secret.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;Make the Worker handle requests before serving the page.&#xA;Have it:&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Check for a valid pass cookie on each page request.&lt;/li&gt;&#xA;&lt;li&gt;If there isn’t one, return a small HTML verification page containing the Turnstile widget.&lt;/li&gt;&#xA;&lt;li&gt;Accept the widget token at a verification endpoint and send it to &lt;a href=&#34;https://challenges.cloudflare.com/turnstile/v0/siteverify&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;https://challenges.cloudflare.com/turnstile/v0/siteverify&lt;/a&gt;.&lt;/li&gt;&#xA;&lt;li&gt;Only after Siteverify returns success: true, issue a short-lived, signed pass cookie and redirect back to /.&lt;/li&gt;&#xA;&lt;li&gt;Serve index.html when the cookie is valid.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;Protect every route that should be gated.&#xA;If only the landing page needs protection, gate /. If API routes also need protection, gate those separately so the verification endpoint stays reachable.&lt;/li&gt;&#xA;&lt;li&gt;Deploy and check both paths.&#xA;Test that a fresh browser sees the challenge, a successful verification reaches the page, and a request without a valid cookie cannot fetch the protected content directly.&lt;/li&gt;&#xA;&lt;/ol&gt;</description>
    </item>
  </channel>
</rss>
