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

Portal: Added HCaptcha element to signup/signin pages #22009

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

sam-lord
Copy link
Contributor

@sam-lord sam-lord commented Jan 15, 2025

ref BAE-371

Added the HCaptcha react component & related utils to enable it / disable it based on the Captcha labs flag. At the moment this does not include the same functionality on forms using the data-attributes.

Testing AI code review:
@coderabbitai

Summary by CodeRabbit

Release Notes

  • New Features

    • Added hCaptcha integration for enhanced security during sign-in and sign-up processes
    • Implemented optional CAPTCHA verification for user authentication
  • Dependencies

    • Added @hcaptcha/react-hcaptcha package (version 1.11.0)
  • Improvements

    • Enhanced sign-in and sign-up pages with CAPTCHA support
    • Added utility functions to manage CAPTCHA configuration

ref BAE-371

Added the HCaptcha react component & related utils to enable it /
disable it based on the Captcha labs flag. At the moment this does not
include the same functionality on forms using the data-attributes.
@sam-lord sam-lord self-assigned this Jan 15, 2025
@sam-lord sam-lord requested a review from aileen January 15, 2025 14:35
Copy link

coderabbitai bot commented Jan 15, 2025

Warning

There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure.

🔧 eslint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

apps/portal/src/components/pages/SigninPage.js

Oops! Something went wrong! :(

ESLint: 8.44.0

ESLint couldn't find the plugin "eslint-plugin-i18next".

(The package "eslint-plugin-i18next" was not found when loaded as a Node module from the directory "/apps/portal".)

It's likely that the plugin isn't installed correctly. Try reinstalling by running the following:

npm install eslint-plugin-i18next@latest --save-dev

The plugin "eslint-plugin-i18next" was referenced from the config file in "apps/portal/package.json".

If you still can't figure out the problem, please stop by https://eslint.org/chat/help to chat with the team.

Walkthrough

The pull request introduces hCaptcha integration into the Ghost Portal application. The changes span multiple files to add captcha verification for signup and signin processes. A new dependency @hcaptcha/react-hcaptcha is added, and utility functions are created to check captcha settings. The implementation allows conditional rendering of hCaptcha based on site configuration, with new methods to handle captcha token verification during user authentication flows.

Changes

File Change Summary
apps/portal/package.json Added @hcaptcha/react-hcaptcha dependency (v1.11.0)
apps/portal/src/components/pages/SigninPage.js Added hCaptcha integration, new state variables captchaLoaded and token, modified handleSignin method
apps/portal/src/components/pages/SignupPage.js Added hCaptcha integration, new method doSignupWithChecks(), added captchaRef
apps/portal/src/components/pages/SignupPage.test.js Added test for hCaptcha rendering when enabled
apps/portal/src/utils/api.js Updated sendMagicLink method signature to include token parameter
apps/portal/src/utils/fixtures-generator.js Added captchaEnabled and captchaSiteKey parameters to getSiteData function
apps/portal/src/utils/helpers.js Added hasCaptchaEnabled and getCaptchaSitekey utility functions

Sequence Diagram

sequenceDiagram
    participant User
    participant SignupPage
    participant HCaptcha
    participant AuthService

    User->>SignupPage: Initiate Signup
    alt Captcha Enabled
        SignupPage->>HCaptcha: Execute Verification
        HCaptcha-->>SignupPage: Return Token
        SignupPage->>AuthService: Signup with Token
    else Captcha Disabled
        SignupPage->>AuthService: Direct Signup
    end
    AuthService-->>SignupPage: Signup Response
    SignupPage-->>User: Show Result
Loading

Poem

🐰 Hop, hop, a captcha's here to play,
Securing signup in a rabbity way!
With hCaptcha's magic, tokens so bright,
Keeping our portal safe and tight.
A bunny's shield against the spam, hurray! 🛡️

Finishing Touches

  • 📝 Generate Docstrings (Beta)

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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: 3

🧹 Nitpick comments (10)
apps/portal/src/utils/helpers.js (1)

518-520: Consider validating the sitekey format.

While the implementation is clean, consider adding validation for the sitekey format to prevent potential issues with invalid keys being passed to the HCaptcha component.

 export function getCaptchaSitekey({site}) {
-    return site?.captcha_sitekey || '';
+    const sitekey = site?.captcha_sitekey || '';
+    // HCaptcha sitekeys are typically 40 characters long
+    if (sitekey && !/^[0-9a-f]{40}$/i.test(sitekey)) {
+        console.warn('[Portal] Invalid HCaptcha sitekey format');
+    }
+    return sitekey;
 }
apps/portal/src/components/pages/SignupPage.test.js (2)

216-216: Document test environment limitations.

The comment about hCaptcha's test environment limitations should be expanded to provide more context for other developers.

-    // Cannot test using hCaptcha component, as it cannot run in a test environment
+    // Note: Limited testing scope due to hCaptcha's runtime requirements.
+    // The hCaptcha component requires a browser environment with full JavaScript execution.
+    // We can only verify the component's presence, not its functionality.

217-231: Enhance test coverage for captcha functionality.

While the current test verifies the presence of the hCaptcha element, consider adding more test cases:

  1. Verify captcha is not rendered when disabled
  2. Test error states and loading states
  3. Test the interaction between captcha state and form submission

Example implementation:

describe('when captcha is enabled', () => {
    const getById = queryByAttribute.bind(null, 'id');

    test('renders hCaptcha when enabled', () => {
        setup({
            site: getSiteData({
                captchaEnabled: true,
                captchaSiteKey: '20000000-ffff-ffff-ffff-000000000002'
            })
        });
        const hcaptchaElement = getById(document.body, 'hcaptcha-signup');
        expect(hcaptchaElement).toBeInTheDocument();
    });

    test('does not render hCaptcha when disabled', () => {
        setup({
            site: getSiteData({
                captchaEnabled: false
            })
        });
        const hcaptchaElement = getById(document.body, 'hcaptcha-signup');
        expect(hcaptchaElement).not.toBeInTheDocument();
    });

    test('submit button is disabled until captcha is verified', () => {
        const {submitButton} = setup({
            site: getSiteData({
                captchaEnabled: true,
                captchaSiteKey: '20000000-ffff-ffff-ffff-000000000002'
            })
        });
        expect(submitButton).toBeDisabled();
    });
});
apps/portal/src/utils/api.js (2)

273-275: Good security implementation with room for minor improvement.

The implementation combines multiple security measures:

  1. Honeypot field using a hidden phone number input
  2. HCaptcha token verification

Consider maintaining comment style consistency with the rest of the file.

-                // we don't actually use a phone #, this is from a hidden field to prevent bot activity
+                /* We don't actually use a phone #, this is from a hidden field to prevent bot activity */

Line range hint 261-275: Consider updating API documentation.

Since this is a significant security enhancement, consider:

  1. Adding JSDoc comments to document the new token parameter
  2. Updating any API documentation to reflect the captcha requirements
  3. Adding examples of error handling for captcha validation failures
+/**
+ * Sends a magic link for authentication
+ * @param {Object} options
+ * @param {string} options.email - User's email address
+ * @param {string} [options.token] - HCaptcha verification token (required when captcha is enabled)
+ * ...
+ * @throws {Error} When captcha validation fails
+ */
 async sendMagicLink({email, emailType, labels, name, oldEmail, newsletters, redirect, integrityToken, phonenumber, customUrlHistory, token, autoRedirect = true}) {
apps/portal/src/utils/fixtures-generator.js (1)

76-78: Consider adding JSDoc for the new captcha parameters.

While the implementation looks good and follows the existing property naming convention (snake_case), adding JSDoc comments would help document the purpose and expected values of these new captcha-related parameters.

 export function getSiteData({
+    /** @type {boolean} Whether captcha verification is enabled */
     captchaEnabled = false,
+    /** @type {string} The site key for HCaptcha integration */
     captchaSiteKey
apps/portal/src/components/pages/SignupPage.js (2)

747-756: Consider handling captcha loading state.

The captcha integration looks good, but the user experience could be improved by:

  • Disabling the submit button while captcha is loading
  • Showing a loading indicator during verification
 {(hasCaptchaEnabled({site}) &&
     <HCaptcha
         size="invisible"
         sitekey={getCaptchaSitekey({site})}
-        onLoad={() => this.setState({captchaLoaded: true})}
+        onLoad={() => {
+            this.setState({
+                captchaLoaded: true,
+                captchaError: null
+            });
+        }}
+        onError={(error) => {
+            this.setState({
+                captchaError: 'Captcha verification failed',
+                isSubmitting: false
+            });
+        }}
         onVerify={token => this.setState({token: token}, this.doSignup)}
         ref={this.captchaRef}
         id="hcaptcha-signup"
     />
 )}

Line range hint 391-392: Add captcha cleanup in componentWillUnmount.

To prevent potential memory leaks, consider resetting the captcha state when the component unmounts.

 componentWillUnmount() {
     clearTimeout(this.timeoutId);
+    if (this.captchaRef.current) {
+        this.captchaRef.current.resetCaptcha();
+    }
 }
apps/portal/src/components/pages/SigninPage.js (2)

18-23: Document the token state type.

Consider adding JSDoc comments to document the expected type and format of the token state, which would help with maintainability and type checking.

    constructor(props) {
        super(props);
+       /** @type {{
+           email: string,
+           captchaLoaded: boolean,
+           token: string | undefined
+       }} */
        this.state = {
            email: '',
            captchaLoaded: false,
            token: undefined
        };

        this.captchaRef = React.createRef();
    }

175-184: Enhance accessibility and loading state handling.

  1. Add aria-label for screen readers
  2. Handle loading state in the submit button
    {(hasCaptchaEnabled({site}) &&
        <HCaptcha
            size="invisible"
            sitekey={getCaptchaSitekey({site})}
            onLoad={() => this.setState({captchaLoaded: true})}
            onVerify={token => this.setState({token: token}, this.doSignin)}
            ref={this.captchaRef}
            id="hcaptcha-signin"
+           aria-label={t('Security verification')}
        />
    )}

Also, modify the renderSubmitButton method to handle the captcha loading state:

    renderSubmitButton() {
        const {action, t} = this.context;
-       const isRunning = (action === 'signin:running');
+       const isRunning = (action === 'signin:running' || 
+           (hasCaptchaEnabled({site}) && !this.state.captchaLoaded));
        let label = isRunning ? t('Sending login link...') : t('Continue');
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 73f8bcf and 7a86bd7.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (7)
  • apps/portal/package.json (1 hunks)
  • apps/portal/src/components/pages/SigninPage.js (3 hunks)
  • apps/portal/src/components/pages/SignupPage.js (6 hunks)
  • apps/portal/src/components/pages/SignupPage.test.js (2 hunks)
  • apps/portal/src/utils/api.js (2 hunks)
  • apps/portal/src/utils/fixtures-generator.js (2 hunks)
  • apps/portal/src/utils/helpers.js (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Setup
🔇 Additional comments (10)
apps/portal/src/utils/helpers.js (1)

514-516: Clean implementation of captcha check!

The function follows a consistent pattern with other utility functions and has a clear, focused responsibility.

apps/portal/src/components/pages/SignupPage.test.js (1)

3-3: LGTM!

The addition of queryByAttribute to the imports is appropriate for the new test functionality.

apps/portal/src/utils/api.js (1)

261-261: LGTM! Method signature updated to support captcha verification.

The addition of the optional token parameter aligns with the PR objectives for HCaptcha integration.

apps/portal/package.json (1)

101-102: LGTM! Package structure follows best practices.

The dependency is correctly placed under dependencies and the version is appropriately pinned for reproducible builds.

apps/portal/src/utils/fixtures-generator.js (2)

46-48: LGTM! Parameters follow existing conventions.

The new parameters recommendationsEnabled, captchaEnabled, and captchaSiteKey maintain consistency with the existing parameter naming convention (camelCase).


77-78: Verify captcha_sitekey handling.

The captcha_sitekey is assigned directly without validation or default value. Consider:

  1. Whether a default value should be provided for testing scenarios
  2. If validation is needed to ensure the key format is correct

Let's check how this key is used across the codebase:

✅ Verification successful

The current captcha_sitekey handling is appropriate

The implementation is correct because:

  • The getCaptchaSitekey helper provides an empty string fallback
  • Key validation is handled by the hCaptcha component
  • The optional nature of captcha (controlled by captcha_enabled) makes the current implementation sufficient
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for usages of captcha_sitekey to understand validation requirements
rg -A 3 "captcha_sitekey|captchaSiteKey" --type js

Length of output: 1063


Script:

#!/bin/bash
# Search for captcha component implementation
rg -A 5 "ReCAPTCHA|hCaptcha|Captcha" --type js

Length of output: 12465

apps/portal/src/components/pages/SignupPage.js (2)

10-10: LGTM! Clean integration of HCaptcha dependencies.

The imports and constructor changes are well-organized, with proper initialization of the captcha reference.

Also applies to: 13-13, 360-360


750-750: Verify captcha site key configuration.

Ensure that the getCaptchaSitekey utility is retrieving the correct site key for both development and production environments.

✅ Verification successful

Captcha implementation is properly configured ✓

The getCaptchaSitekey utility correctly retrieves the site key from the site configuration. The implementation includes proper feature flagging, error handling, and follows hCaptcha integration best practices.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for hardcoded site keys in the codebase
rg -g '!node_modules' -g '!dist' -i 'hcaptcha.*sitekey'

# Check for environment-specific configurations
rg -g '!node_modules' -g '!dist' 'HCAPTCHA_SITE_KEY'

Length of output: 110


Script:

#!/bin/bash
# Search for the getCaptchaSitekey implementation
ast-grep --pattern 'function getCaptchaSitekey'

# Look for any captcha-related files or configurations
rg -g '!node_modules' -g '!dist' -i 'captcha'

# Search for environment variable patterns in config files
fd -e js -e json -e env --exec grep -l -i "captcha" {} \;

Length of output: 10871

apps/portal/src/components/pages/SigninPage.js (2)

10-10: Verify the hCaptcha dependency version and security.

Let's ensure we're using a secure version of the hCaptcha React component.

✅ Verification successful

hCaptcha dependency is secure but could be updated

The current version (1.11.0) is secure with no known vulnerabilities. Consider updating to the latest version (1.11.1) in a future maintenance cycle for potential bug fixes.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for security advisories and latest versions
curl -s https://registry.npmjs.org/@hcaptcha/react-hcaptcha | jq '.["dist-tags"].latest'

# Check for known vulnerabilities
gh api graphql -f query='
{
  securityVulnerabilities(first: 5, ecosystem: NPM, package: "@hcaptcha/react-hcaptcha") {
    nodes {
      advisory {
        summary
        severity
        publishedAt
      }
      vulnerableVersionRange
      firstPatchedVersion {
        identifier
      }
    }
  }
}'

Length of output: 457


Script:

#!/bin/bash
# Check package.json for the actual version
fd package.json --type f --exec sh -c 'echo "=== {} ==="; cat {} | jq -r "select(.dependencies?.\"@hcaptcha/react-hcaptcha\" != null) | .dependencies?.\"@hcaptcha/react-hcaptcha\""'

# Check yarn.lock or package-lock.json for the resolved version
fd "yarn.lock|package-lock.json" --type f --exec sh -c 'echo "=== {} ==="; cat {}'

Length of output: 71002


179-180: Handle captcha token expiration.

The hCaptcha token can expire. Consider adding the onExpire callback to reset the token state and show an appropriate message to the user.

    <HCaptcha
        size="invisible"
        sitekey={getCaptchaSitekey({site})}
        onLoad={() => this.setState({captchaLoaded: true})}
        onVerify={token => this.setState({token: token}, this.doSignin)}
+       onExpire={() => {
+           this.setState({
+               token: undefined,
+               errors: {
+                   captcha: this.context.t('Security verification expired. Please try again.')
+               }
+           });
+       }}
        ref={this.captchaRef}
        id="hcaptcha-signin"
    />
✅ Verification successful

The concern about hCaptcha token expiration is valid.

The codebase currently lacks token expiration handling, which could lead to failed signin attempts if users take too long to complete the form. The suggested solution to add the onExpire callback with appropriate error messaging follows good practices for user experience and security.

🏁 Scripts executed

The following scripts were executed for the analysis:

Error: No shell scripts found


Script:

#!/bin/bash
# Find HCaptcha component usage patterns
echo "=== HCaptcha Component Usage ==="
ast-grep --pattern 'HCaptcha $$$'

echo -e "\n=== Token Expiration Handling ==="
rg -i "expire|token.*expire|captcha.*expire" -A 2

echo -e "\n=== Error Messages Related to Captcha ==="
rg -i "captcha.*error|security.*verification" -A 1

Length of output: 76425

Comment on lines +101 to +102
"dependencies": {
"@hcaptcha/react-hcaptcha": "1.11.0"
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

Update to latest patch version 1.11.1

The package is compatible with React 17 and has no security vulnerabilities, but there's a newer patch version available.

  • Update @hcaptcha/react-hcaptcha from 1.11.0 to 1.11.1 in apps/portal/package.json
🔗 Analysis chain

Verify HCaptcha package compatibility and security.

The addition of @hcaptcha/react-hcaptcha looks good, but let's verify a few important aspects:

Run this script to check compatibility with React 17 and latest versions:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify hcaptcha package compatibility and check for newer versions

# Check package.json from @hcaptcha/react-hcaptcha for peer dependencies
curl -s https://registry.npmjs.org/@hcaptcha/react-hcaptcha/1.11.0 | jq -r '.peerDependencies'

# Get latest version
curl -s https://registry.npmjs.org/@hcaptcha/react-hcaptcha/latest | jq -r '.version'

# Check for security advisories
gh api graphql -f query='
{
  securityVulnerabilities(first: 5, ecosystem: NPM, package: "@hcaptcha/react-hcaptcha") {
    nodes {
      advisory {
        summary
        severity
        publishedAt
      }
      vulnerableVersionRange
      firstPatchedVersion {
        identifier
      }
    }
  }
}'

Length of output: 600

Comment on lines +405 to +413
doSignupWithChecks() {
const {site} = this.context;
if (hasCaptchaEnabled({site})) {
// hCaptcha's callback will call doSignup
return this.captchaRef.current.execute();
} else {
this.doSignup();
}
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add error handling for captcha verification failures.

While the captcha integration looks good, consider handling potential failure scenarios:

  • Network errors during captcha verification
  • Invalid or expired captcha tokens
  • User cancellation of captcha
 doSignupWithChecks() {
     const {site} = this.context;
     if (hasCaptchaEnabled({site})) {
-        // hCaptcha's callback will call doSignup
-        return this.captchaRef.current.execute();
+        try {
+            return this.captchaRef.current.execute();
+        } catch (error) {
+            this.setState({
+                errors: {
+                    captcha: 'Failed to verify captcha. Please try again.'
+                }
+            });
+        }
     } else {
         this.doSignup();
     }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
doSignupWithChecks() {
const {site} = this.context;
if (hasCaptchaEnabled({site})) {
// hCaptcha's callback will call doSignup
return this.captchaRef.current.execute();
} else {
this.doSignup();
}
}
doSignupWithChecks() {
const {site} = this.context;
if (hasCaptchaEnabled({site})) {
try {
return this.captchaRef.current.execute();
} catch (error) {
this.setState({
errors: {
captcha: 'Failed to verify captcha. Please try again.'
}
});
}
} else {
this.doSignup();
}
}

Comment on lines +37 to +45

const {site} = this.context;
if (hasCaptchaEnabled({site})) {
// hCaptcha's callback will call doSignin
return this.captchaRef.current.execute();
} else {
this.doSignin();
}
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add error handling for captcha execution failures.

The captcha execution could fail for various reasons (network issues, timeouts, etc.). Consider adding try-catch block and error state handling.

    handleSignin(e) {
        e.preventDefault();

        const {site} = this.context;
        if (hasCaptchaEnabled({site})) {
-           // hCaptcha's callback will call doSignin
-           return this.captchaRef.current.execute();
+           try {
+               // hCaptcha's callback will call doSignin
+               return this.captchaRef.current.execute();
+           } catch (error) {
+               this.setState({
+                   errors: {
+                       captcha: this.context.t('Failed to load captcha. Please try again.')
+                   }
+               });
+           }
        } else {
            this.doSignin();
        }
    }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const {site} = this.context;
if (hasCaptchaEnabled({site})) {
// hCaptcha's callback will call doSignin
return this.captchaRef.current.execute();
} else {
this.doSignin();
}
}
handleSignin(e) {
e.preventDefault();
const {site} = this.context;
if (hasCaptchaEnabled({site})) {
try {
// hCaptcha's callback will call doSignin
return this.captchaRef.current.execute();
} catch (error) {
this.setState({
errors: {
captcha: this.context.t('Failed to load captcha. Please try again.')
}
});
}
} else {
this.doSignin();
}
}

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.

1 participant