[PR #2409] [CLOSED] feat: support matcher functions for captcha validation endpoints #12550

Closed
opened 2026-04-13 08:27:39 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/better-auth/better-auth/pull/2409
Author: @EugeneDraitsev
Created: 4/23/2025
Status: Closed

Base: mainHead: captcha-matcher-fn


📝 Commits (2)

  • e4d4e63 feat: support custom matcher functions for captcha validation endpoints
  • fca08ac fix: update endpoints type to use array syntax in BaseCaptchaOptions

📊 Changes

4 files changed (+51 additions, -4 deletions)

View changed files

📝 docs/content/docs/plugins/captcha.mdx (+4 -2)
📝 packages/better-auth/src/plugins/captcha/captcha.test.ts (+35 -0)
📝 packages/better-auth/src/plugins/captcha/index.ts (+9 -1)
📝 packages/better-auth/src/plugins/captcha/types.ts (+3 -1)

📄 Description

What’s the problem?

Right now, the captcha plugin checks each request by seeing if the URL string includes any entry in the endpoints array. For example:

endpoints: ["/magic-link"]

Because the plugin does a simple substring check, a request to /magic-link/verify also matches. This means CAPTCHA is added to the verify route even when it shouldn’t be.

Why is this bad?

  • Over‑protection: Users must solve CAPTCHA on verify routes that don’t need it.
  • Confusion: Developers expect /magic-link to protect only that exact path, not its sub‑paths.
  • Potential breakage: Integrations for /magic-link/verify may fail unexpectedly.

What does this PR do?

What does this PR do?

This PR changes the endpoints option so it can accept both plain strings and custom matcher functions (EndpointMatcherFn).

  • String matchers: default check if URL includes path.
  • Custom matcher functions: any function that takes the full URL and returns true when the route should be protected.

Example usage:

captcha({
  secretKey: process.env.TURNSTILE_SECRET_KEY!,
  endpoints: [
    "/sign-up/email",  // prefix matches /sign-up/email and subpaths
    (url) => new URL(url).pathname === "/api/auth/sign-in/magic-link" // exact match only
  ],
});

Let me know if you’d like additional tests or examples added to the docs!


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/better-auth/better-auth/pull/2409 **Author:** [@EugeneDraitsev](https://github.com/EugeneDraitsev) **Created:** 4/23/2025 **Status:** ❌ Closed **Base:** `main` ← **Head:** `captcha-matcher-fn` --- ### 📝 Commits (2) - [`e4d4e63`](https://github.com/better-auth/better-auth/commit/e4d4e630398a1d160463dfe396cf10232d090e5b) feat: support custom matcher functions for captcha validation endpoints - [`fca08ac`](https://github.com/better-auth/better-auth/commit/fca08ac74c53afdc563c7d73d401b86bf84c22a1) fix: update endpoints type to use array syntax in BaseCaptchaOptions ### 📊 Changes **4 files changed** (+51 additions, -4 deletions) <details> <summary>View changed files</summary> 📝 `docs/content/docs/plugins/captcha.mdx` (+4 -2) 📝 `packages/better-auth/src/plugins/captcha/captcha.test.ts` (+35 -0) 📝 `packages/better-auth/src/plugins/captcha/index.ts` (+9 -1) 📝 `packages/better-auth/src/plugins/captcha/types.ts` (+3 -1) </details> ### 📄 Description ## What’s the problem? Right now, the captcha plugin checks each request by seeing if the URL string includes any entry in the `endpoints` array. For example: ```ts endpoints: ["/magic-link"] ``` Because the plugin does a simple substring check, a request to `/magic-link/verify` also matches. This means CAPTCHA is added to the verify route even when it shouldn’t be. ## Why is this bad? - **Over‑protection**: Users must solve CAPTCHA on verify routes that don’t need it. - **Confusion**: Developers expect `/magic-link` to protect only that exact path, not its sub‑paths. - **Potential breakage**: Integrations for `/magic-link/verify` may fail unexpectedly. ## What does this PR do? What does this PR do? This PR changes the `endpoints` option so it can accept both plain strings and custom matcher functions (`EndpointMatcherFn`). - **String matchers**: default check if URL includes path. - **Custom matcher functions**: any function that takes the full URL and returns `true` when the route should be protected. Example usage: ```ts captcha({ secretKey: process.env.TURNSTILE_SECRET_KEY!, endpoints: [ "/sign-up/email", // prefix matches /sign-up/email and subpaths (url) => new URL(url).pathname === "/api/auth/sign-in/magic-link" // exact match only ], }); ``` Let me know if you’d like additional tests or examples added to the docs! --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-04-13 08:27:39 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#12550