docs: complete v3 migration guidance - #156
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Security Review — docs: complete v3 migration guidance
Scope: All 20 changed files are documentation-only (.md / .mdx). No source code, dependencies, CI configuration, or infrastructure files were modified. No injection, authz bypass, secrets leakage, or supply-chain risk is introduced by executable code.
🟡 Low — Migration Guide Omits Renamed Backend Hook (Fail-Open Risk for Consumers)
In form-builder.mdx, the documentation renames the backend lifecycle hook from onBeforeDeleteSubmission to onBeforeSubmissionDeleted. However, the migration checklist in breaking-changes.mdx only tells consumers to update the denial pattern (return false → throw new Error()); it does not list which hooks were renamed.
Risk: A consumer who follows the migration guide step-by-step will:
- Update the denial pattern in their existing
onBeforeDeleteSubmissionhook to throw. - Not realise the hook name itself changed.
- End up with authorization code that silently never runs — fail-open on Form Builder submission deletes after upgrading to v3.
Suggested fix: Add a "Renamed hooks" line or table to the migration checklist:
| v2 hook name | v3 hook name |
|-----------------------------|-------------------------------|
| onBeforeDeleteSubmission | onBeforeSubmissionDeleted |
This ensures consumers update both the name and the denial pattern together. See inline comment on breaking-changes.mdx.
ℹ️ Informational — better-auth-ui.mdx Auth Template Omits can()
The new StackAuthProvider example provides getIdentity and loginPath but no can() implementation. Without can(), client-side route guards and UI controls default to permissive — all authenticated users see and can activate every control.
This is acceptable when authorization is enforced entirely by backend hooks, but the template gives no signal that can() is needed for route-level or control-level client gating. See inline comment.
✅ No High-Confidence Code Vulnerabilities
The documentation consistently and correctly states that backend lifecycle hooks are the authoritative security boundary. The v3 pattern change (throwing instead of returning false) is a positive improvement — it eliminates a class of silent fail-open bugs in consumer code. No production-executable code was modified in this PR.
Sent by Cursor Automation: Find vulnerabilities


Summary
Validation
cd docs && pnpm buildpnpm lintquick_validate.pyCloses #152
Note
Low Risk
Documentation and agent-skill updates only; no runtime or API code changes.
Overview
Makes v3 the only documented integration path. Catch-all API/page routes now use framework entry factories (
toNextRouteHandlers/createNextPageand equivalents), andStackProviderownsrouter,api, andauthonce instead of per-plugin overrides.The v2→v3 breaking-changes guide is expanded into a full checklist: drop hand-written route glue, move shared services off plugin overrides, replace
onBefore*PageRenderedwithauth.can, stop passing identity/API props into Comments, switch parameterizedpageComponentsto{ params }, and deny backend hooks by throwing (including Form Builder’sonBeforeSubmissionDeleted).Installation, README, CLI, architecture, and plugin pages (blog, comments, form builder, kanban, media, UI builder, route-docs, better-auth-ui) plus the client-plugin/integration/build-config skills are aligned with that model. Hand-written route “escape hatch” examples are removed.
Reviewed by Cursor Bugbot for commit b72d7e6. Bugbot is set up for automated code reviews on this repo. Configure here.