Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(auth): add a turnstile widget #631

Merged
merged 1 commit into from
Jan 15, 2025
Merged

feat(auth): add a turnstile widget #631

merged 1 commit into from
Jan 15, 2025

Conversation

ygrishajev
Copy link
Contributor

@ygrishajev ygrishajev commented Jan 14, 2025

This PR introduces a Turnstile React component that integrates Cloudflare's Turnstile widget for verifying human interaction. It provides an interactive challenge to users and handles various states such as initialization, success, expiration, errors, and dismissal.

Functionality

The Turnstile component serves the following purposes:

  1. Challenge Presentation:

    • Displays a challenge to verify the user's identity as a human.
    • The challenge is visible only when the required environment variable (NEXT_PUBLIC_TURNSTILE_SITE_KEY) is present and certain statuses ("uninitialized", "expired", "error") make it relevant.
  2. Challenge States:

    • uninitialized: Initial state before the Turnstile widget starts.
    • solved: When the challenge is successfully completed.
    • expired: When the challenge expires without completion.
    • error: When the Turnstile widget encounters an error.
    • dismissed: When the user opts to dismiss the challenge.
  3. Timeout for Actions:

    • Introduces a delay of 5 seconds (setTimeout) before enabling actions like retrying the challenge or dismissing it. This ensures the user has enough time to interact with the widget first.
  4. Action Handling:

    • Retry: Resets the Turnstile widget, allowing the user to retry the challenge if it expires or encounters an error.
    • Dismiss: Allows users to dismiss the challenge with a warning that some features might not work as expected.
  5. Error Handling:

    • If the widget encounters an error, the status is updated to "error", and a message is displayed.
  6. State-Based Rendering:

    • The challenge and actions are conditionally rendered based on the component's state (isVisible, hasActions).

Key Features

  • Dynamic Visibility: The widget only appears when required and hides gracefully when dismissed or solved.
  • Timeout-Based Actions: Introduces a delay for enabling retry or dismiss actions for better UX.
  • State Management: Handles complex states (uninitialized, solved, expired, error, dismissed) with clear transitions.
  • Error Resilience: Ensures the user can retry the challenge if errors occur.

Testing Instructions

  1. Test Cases:

    • Verify the widget displays correctly when the component initializes (status = "uninitialized").
    • Confirm smooth transitions when the status changes (e.g., expired to retry).
    • Test the retry functionality using the "Retry" button.
    • Test dismissal behavior using the "Dismiss" button.
    • Simulate errors (e.g., by invalidating the site key) to verify error handling.
    • Ensure timeout delays are correctly applied before enabling actions.
  2. Simulating States:

    • Use the test keys provided in Cloudflare's documentation to emulate different states:
      • Successful verification (solved).
      • Challenge expiration (expired).
      • Errors (error).

Some screenshots:

  1. "Always blocks" key. Note, action buttons appear instantly
image
  1. "Always passes" key in progress
image
  1. "Forces an interactive challenge" key. Note, action buttons appear after 5s
Screenshot 2025-01-15 at 13 12 30

Some testing would still be needed in staging, before deploying this to prod.

@ygrishajev ygrishajev requested a review from a team as a code owner January 14, 2025 09:43
@ygrishajev ygrishajev force-pushed the feature/turnstile branch 2 times, most recently from 5cf5dbc to 599e74e Compare January 15, 2025 11:57
@ygrishajev ygrishajev requested review from baktun14 and a team January 15, 2025 12:14
@ygrishajev ygrishajev force-pushed the feature/turnstile branch 2 times, most recently from 5c02c45 to 75c81b1 Compare January 15, 2025 12:17
@ygrishajev ygrishajev merged commit d485fbb into main Jan 15, 2025
5 checks passed
@ygrishajev ygrishajev deleted the feature/turnstile branch January 15, 2025 14:58
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