Skip to content

feat: automatic bot protection#5

Merged
RobertBoes merged 18 commits intomainfrom
feature/auto-bot-protection
Apr 1, 2026
Merged

feat: automatic bot protection#5
RobertBoes merged 18 commits intomainfrom
feature/auto-bot-protection

Conversation

@RobertBoes
Copy link
Copy Markdown
Contributor

Summary

  • Adds botProtectionContainer option to useFormRelay — pass a template ref and the SDK handles widget loading, token acquisition, expiry renewal, reset re-initialization, and cleanup automatically
  • New @formrelay/core/bot-protection entrypoint with loadBotProtectionWidget (dynamic import switch by protection type) and runTokenLoop (infinite token acquisition loop with abort handle)
  • @formrelay/nuxt passes the new option through to the Vue composable

Test plan

  • Core: createCallbackWidget consuming getToken() — 8 tests passing
  • Core: loadBotProtectionWidget — 5 tests (turnstile, recaptcha v2/v3, return value, unknown type)
  • Core: runTokenLoop — 5 tests (initial token, subsequent tokens, stop, post-stop guard, rejection exit)
  • Vue: auto bot protection — 7 tests (load + loop, null container, no bot protection, reset delegation, unmount cleanup, container change reinit, backward compat)
  • All existing tests unaffected (core 72/72, vue 30/30)
  • All packages build successfully

Clear currentToken after returning it so subsequent calls wait for the
next token, preventing an infinite spin in the upcoming runTokenLoop.
- Fix onCleanup registered after early-return guard (widget leak on v-if cycle)
- Fix rejectAbort overwritten each loop iteration (promise leak)
- Add try/catch in async watch for widget loading failures
- Add onError callback to runTokenLoop to distinguish abort from real errors
- Import BotProtectionWidget from @formrelay/core/bot-protection (correct entrypoint)
- Wrap Nuxt composable in effectScope for proper watcher cleanup after await
- Add tests for onError callback and widget loading failure
- Add .catch() to fire-and-forget loop() call in runTokenLoop
- Fix unsafe error cast in fetchSchema — wrap non-FormRelayError in FormRelayError
- Add edge case tests: reset during active bot protection, runTokenLoop
  called twice on container reinit, botToken cleared on v-if container destroy
@RobertBoes RobertBoes merged commit 102e349 into main Apr 1, 2026
1 check failed
@RobertBoes RobertBoes deleted the feature/auto-bot-protection branch April 1, 2026 19:38
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