Skip to content

Conversation

@Blaumaus
Copy link
Member

@Blaumaus Blaumaus commented Dec 6, 2025

Depends on:

Summary by CodeRabbit

  • New Features

    • Automatic Proof-of-Work captcha verification with background solving and real-time progress updates.
  • Refactor

    • Replaced manual captcha workflow with an automated, resilient solving flow (includes fallback and timeout handling).
  • UI Updates

    • Removed manual captcha input and submit controls.
    • Added a computing state and progress indicator; reduced status text size for readability.

✏️ Tip: You can customize this high-level summary in your review settings.

@Blaumaus Blaumaus self-assigned this Dec 6, 2025
@coderabbitai
Copy link

coderabbitai bot commented Dec 6, 2025

Walkthrough

Replaces manual CAPTCHA with a PoW-based flow: adds a PoW web worker, updates build to bundle the worker, simplifies iframe height handling, refactors captcha logic to request challenges, solve via worker (with main-thread fallback), report progress, verify solutions, and update UI for a computing state.

Changes

Cohort / File(s) Change Summary
Build Configuration
rollup.config.js
Adds new POW_WORKER_PATH and a Rollup output entry to bundle src/pow-worker.ts -> dist/pow-worker.js (IIFE, minified)
Web Worker Implementation
src/pow-worker.ts
New worker implementing PoW solver: SubtleCrypto SHA-256, nonce iteration, difficulty validation, periodic progress posts, timeout/error messages
Core Captcha Logic
src/captcha.ts
Replaces manual flow with challenge→solve→verify workflow; integrates worker + main-thread fallback, progress updates, computing state UI, token lifetime handling, and error paths
Frame Height Handling
src/captcha-loader.ts
Removes FRAME_HEIGHT_MAPPING; introduces single FRAME_HEIGHT = '66px' and removes manualStarted/manualFinished handling
UI & Styling
src/pages/dark.html, src/pages/light.html
Removes manual CAPTCHA UI block; reduces status font-size (16px → 14px); adds #status-computing and #pow-progress elements/styles for progress display

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Main as Main Thread (captcha.ts)
    participant Worker as PoW Worker (pow-worker.js)
    participant API as Backend API

    User->>Main: request CAPTCHA / open frame
    Main->>API: POST /generateChallenge
    API-->>Main: { challenge, difficulty, maxIterations? }
    Main->>Main: show "Computing..." UI
    Main->>Worker: postMessage(PowChallenge)
    Worker->>Worker: solveChallenge loop (sha256 + check prefix)
    alt every 10k attempts
        Worker-->>Main: { type: "progress", attempts, hashRate }
        Main->>Main: update `#pow-progress`
    end
    Worker-->>Main: { type: "result", nonce, solution }
    Main->>Worker: terminate
    Main->>API: POST /verifySolution { nonce, solution }
    API-->>Main: { token, lifetime } or error
    Main->>Main: update UI -> success or error
    Main-->>User: reveal token / success state
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Files needing careful review:
    • src/captcha.ts — worker lifecycle, fallback solver, state transitions, token lifetime handling, and error paths.
    • src/pow-worker.ts — SHA‑256 correctness, difficulty/prefix validation, progress frequency, and performance bounds.
    • rollup.config.js — ensure worker bundle path and IIFE/global name align with runtime worker URL.
    • src/pages/* and src/captcha-loader.ts — UI wiring and iframe sizing consistency after removing manual flow.

Poem

🐇 I count nonces in the midnight hum,

stamping hashes till the victor's come.
A tiny worker, steady and bright,
finds the proof and ends the fight.
Hop, hop—captcha solved by moonlit light ✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main objective of the pull request, which is to replace the existing CAPTCHA mechanism with a proof-of-work (PoW) based system across multiple files.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch captcha-pow

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (2)
src/captcha-loader.ts (1)

70-72: Consider addressing the TODO for origin validation.

The postMessage callback lacks origin validation, which could allow malicious iframes to spoof messages. While not a regression from this PR, it's worth addressing as part of this security-sensitive captcha flow.

 const postMessageCallback = (pmEvent: MessageEvent) => {
-  // TODO: Validate origin
+  const allowedOrigins = isDevelopment 
+    ? ['http://localhost:5005'] 
+    : ['https://cap.swetrix.com']
+  if (!allowedOrigins.includes(pmEvent.origin)) {
+    return
+  }

   const { data } = pmEvent
src/pow-worker.ts (1)

5-22: Consider sharing types between worker and main thread.

The PowChallenge, PowResult, and PowProgress interfaces are duplicated in both pow-worker.ts and captcha.ts. Extract these to a shared types file to prevent drift.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5fb0b69 and 2825a07.

📒 Files selected for processing (6)
  • rollup.config.js (2 hunks)
  • src/captcha-loader.ts (2 hunks)
  • src/captcha.ts (5 hunks)
  • src/pages/dark.html (2 hunks)
  • src/pages/light.html (2 hunks)
  • src/pow-worker.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/captcha-loader.ts (1)
dist/esnext/captcha-loader.js (1)
  • captchaFrame (123-123)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (9)
src/captcha-loader.ts (1)

24-24: LGTM! Frame height simplification aligns with the new PoW flow.

The removal of height mapping for manual states and use of a single constant is appropriate since the PoW mechanism no longer requires expandable manual input UI.

Also applies to: 142-142

rollup.config.js (1)

53-66: LGTM! Worker build configuration is appropriate.

The IIFE format is correct for web workers. Consider adding sourceMaps() plugin for easier debugging in development, similar to the captcha-loader build.

src/captcha.ts (2)

117-139: LGTM! Challenge generation with proper error handling.

The function correctly handles failures by notifying the loader and updating the UI state. The error handling pattern is consistent.


176-230: Worker lifecycle management looks correct.

Good pattern: terminating existing workers before creating new ones, proper cleanup on success/error, and fallback to main thread when workers aren't available.

src/pages/light.html (2)

74-83: LGTM! Clean UI implementation for the computing state.

The new #status-computing element with progress indicator provides good user feedback during PoW computation. The flex column layout and smaller progress text create a nice visual hierarchy.

Also applies to: 190-193


70-72: No changes needed — dark.html already has the matching style changes with appropriate theme adjustments. The #status font-size is consistently set to 14px in both files, and the #status-computing and #pow-progress rules are properly mirrored in dark.html with theme-appropriate color values.

Likely an incorrect or invalid review comment.

src/pages/dark.html (3)

68-70: Verify font size reduction aligns with new UI layout.

The #status font size is reduced from 16px to 14px. While this is a minor change, please confirm this sizing works well with the new computing state UI and the nested progress indicator below it.


72-81: CSS styling for computing state is appropriate.

The flex-based layout correctly positions the "Verifying..." label and progress text vertically, with appropriate color (#9ca3af) and spacing (2px margin-top) to differentiate the progress indicator from the main status text.


185-192: HTML structure for PoW computing state is well-formed.

The status state machine is correctly implemented with three mutually exclusive spans (status-default, status-failure, status-computing). The nested structure inside #status-computing provides clear visual hierarchy: "Verifying..." label with an empty #pow-progress container for dynamic progress updates from the worker. This aligns well with the worker-based PoW mechanism described in the PR.

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Dec 6, 2025

Deploying captchacdn with  Cloudflare Pages  Cloudflare Pages

Latest commit: a69aea8
Status: ✅  Deploy successful!
Preview URL: https://560bb71c.captchacdn.pages.dev
Branch Preview URL: https://captcha-pow.captchacdn.pages.dev

View logs

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
src/captcha.ts (2)

121-144: Consider adding a timeout to the fetch request.

The fetch call has no timeout mechanism. If the server is slow or unresponsive, the request could hang indefinitely, leaving users stuck on the loading state.

 const generateChallenge = async (): Promise<PowChallenge | null> => {
   try {
+    const controller = new AbortController()
+    const timeoutId = setTimeout(() => controller.abort(), 10000) // 10s timeout
+
     const response = await fetch(`${API_URL}${ENDPOINTS.GENERATE}`, {
       method: 'POST',
       headers: {
         'Content-Type': 'application/json',
       },
       body: JSON.stringify({
         // @ts-ignore
         pid: window.__SWETRIX_PROJECT_ID,
       }),
+      signal: controller.signal,
     })
+
+    clearTimeout(timeoutId)

     if (!response.ok) {
       throw new Error('Failed to generate challenge')
     }

     return await response.json()
   } catch (e) {
     sendMessageToLoader(IFRAME_MESSAGE_TYPES.FAILURE)
     activateAction(ACTION.failure)
     return null
   }
 }

146-178: Same timeout concern applies here.

Similar to generateChallenge, this fetch call could hang indefinitely. Consider adding an AbortController timeout for consistency and resilience.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2825a07 and a69aea8.

📒 Files selected for processing (2)
  • src/captcha.ts (5 hunks)
  • src/pow-worker.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/pow-worker.ts
🧰 Additional context used
🧬 Code graph analysis (1)
src/captcha.ts (1)
dist/esnext/captcha.js (11)
  • isDevelopment (3-3)
  • API_URL (4-4)
  • CAPTCHA_TOKEN_LIFETIME (7-7)
  • setLifetimeTimeout (70-75)
  • sendMessageToLoader (30-38)
  • activateAction (43-69)
  • response (106-117)
  • ENDPOINTS (10-13)
  • data (121-121)
  • captchaComponent (131-131)
  • branding (132-132)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (7)
src/captcha.ts (7)

1-18: LGTM!

The configuration setup with environment-based URLs and reasonable iteration/timeout limits for PoW is well-structured.


33-51: LGTM!

Well-defined TypeScript interfaces for PoW communication types and proper state management for the worker.


70-105: LGTM!

The UI state management correctly integrates the new statusComputing element for the PoW loading state.


107-119: LGTM!

Progress display and token lifetime management are implemented correctly.


180-270: LGTM!

The worker lifecycle management is well-implemented with:

  • Proper cleanup of existing workers before creating new ones
  • Comprehensive handling of all message types (progress, timeout, result, error, and unknown)
  • Graceful fallback to main thread on worker errors
  • Consistent termination and state cleanup in all code paths

The previous review concerns about handling unexpected message types have been addressed.


272-334: LGTM!

The main-thread fallback correctly implements:

  • Iteration limit (MAX_ITERATIONS) and timeout (TIMEOUT_MS) as requested in previous reviews
  • Progress updates every 10k iterations with event loop yielding
  • Proper failure handling when limits are exceeded

Note: crypto.subtle requires a secure context (HTTPS), which should be satisfied by the captcha iframe deployment.


336-363: LGTM!

The event handler correctly:

  • Prevents duplicate submissions during loading/completed states
  • Allows users to retry after failure
  • Chains the challenge generation and solving flow properly

@Blaumaus Blaumaus mentioned this pull request Dec 6, 2025
9 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants