Plugin: Legal Consent
Relevant source files
The following files were used as context for generating this wiki page:The Legal Consent plugin for Better Auth Kit is designed to enforce application compliance by requiring users to provide various legal consents during the sign-up process. It intercepts sign-up requests to validate that the user has accepted required policies such as Terms of Service (TOS), Privacy Policy, and age verification.
When enabled, the plugin dynamically extends the user database schema to store the consent information. This ensures that a record of the user's consent is persisted. The plugin is highly configurable, allowing developers to specify which consents are mandatory and to customize the database field names where this information is stored.
Sources: packages/plugins/legal-consent/README.md, packages/plugins/legal-consent/src/index.ts
Architecture and Flow
The plugin integrates into the Better Auth system using a before hook. This hook registers a middleware that specifically targets sign-up routes. When a user attempts to sign up, this middleware intercepts the request to perform validation before the core sign-up logic is executed.
Sign-up Request Flow
The following diagram illustrates the sequence of events when a user signs up with the Legal Consent plugin enabled.
This diagram shows how the middleware acts as a gatekeeper for sign-up requests, ensuring compliance before any user data is created.
Sources: packages/plugins/legal-consent/src/index.ts:186-259, packages/plugins/legal-consent/tests/legal-consent.test.ts:11-21
Configuration
The plugin is initialized by calling the legalConsent function and passing a configuration object. This object allows developers to enable specific consent requirements and customize schema field names.
Sources: packages/plugins/legal-consent/src/index.ts:91-92, packages/plugins/legal-consent/README.md:19-29
Main Options (LegalConsentOptions)
These are the primary options to control which consents are required.
| Option | Type | Description | Default |
|---|---|---|---|
requireTOS | boolean | If true, the user must accept the Terms of Service. | false |
TosVersion | string | Optional version string for the TOS. If provided, the version is saved instead of true. | undefined |
requirePrivacyPolicy | boolean | If true, the user must accept the Privacy Policy. | false |
PrivacyPolicyVersion | string | Optional version string for the Privacy Policy. | undefined |
requireAgeVerification | boolean | If true, the user must verify their age. | false |
AgeVerificationVersion | string | Optional version string for the age verification. | undefined |
requireMarketingConsent | boolean | If true, the user must consent to marketing communications. | false |
MarketingConsentVersion | string | Optional version string for marketing consent. | undefined |
requireCookieConsent | boolean | If true, the user must consent to cookies. | false |
CookieConsentVersion | string | Optional version string for cookie consent. | undefined |
schema | object | An object to customize the database schema field names. See Schema Configuration. | {...} |
Sources: packages/plugins/legal-consent/src/index.ts:5-76
Schema Configuration
The schema option allows for customizing the names of the fields that the plugin adds to the user model.
| Property | Type | Description | Default |
|---|---|---|---|
userModelName | string | The name of the user model. | "user" |
tosAccepted | string | The field name for TOS consent. | "tosAccepted" |
privacyPolicyAccepted | string | The field name for Privacy Policy consent. | "privacyPolicyAccepted" |
ageVerified | string | The field name for age verification. | "ageVerified" |
marketingConsentAccepted | string | The field name for marketing consent. | "marketingConsentAccepted" |
cookieConsentAccepted | string | The field name for cookie consent. | "cookieConsentAccepted" |
Sources: packages/plugins/legal-consent/src/index.ts:58-76, packages/plugins/legal-consent/README.md:61-71
Database Schema Extension
The plugin automatically extends the user database table with new fields based on the enabled consent options. For each required consent, a corresponding field is added to the user schema.
User Table Schema
The diagram below shows how the user table is extended with fields from the Legal Consent plugin.
This ER diagram illustrates the standard user fields alongside the optional fields managed by the Legal Consent plugin.
Sources: packages/plugins/legal-consent/src/index.ts:131-183, packages/cli/src/commands/db/database-explorer-plugin.ts:251-255
Field Attributes
The type of the added schema field is dynamic. It will be a boolean by default. However, if a version string (e.g., TosVersion) is provided in the configuration, the field type will be string to store that version.
| Property | Value | Description |
|---|---|---|
type | boolean or string | string if a version is provided, otherwise boolean. |
input | true | Indicates the field is expected as input during sign-up. |
required | true | The field is mandatory in the database schema. |
fieldName | Customizable via schema options | The actual column name in the database. |
defaultValue | false | The default value for the database column before consent is given. |
Sources: packages/plugins/legal-consent/src/index.ts:134-182
Error Handling
If a required consent is not provided in the sign-up request body, the plugin's middleware throws an APIError with a BAD_REQUEST status. The error message clearly indicates which consent is missing.
| Error Code | Message | Trigger |
|---|---|---|
TOS_NOT_ACCEPTED | "TOS must be accepted" | requireTOS is true and tosAccepted is falsy. |
PRIVACY_NOT_ACCEPTED | "Privacy must be accepted" | requirePrivacyPolicy is true and consent is missing. |
AGE_NOT_ACCEPTED | "Age must be accepted" | requireAgeVerification is true and consent is missing. |
MARKETING_NOT_ACCEPTED | "Marketing must be accepted" | requireMarketingConsent is true and consent is missing. |
COOKIE_NOT_ACCEPTED | "Cookie must be accepted" | requireCookieConsent is true and consent is missing. |
Sources: packages/plugins/legal-consent/src/index.ts:78-84, packages/plugins/legal-consent/tests/legal-consent.test.ts:11-21
Example Usage
Here is a minimal example of how to initialize betterAuth with the Legal Consent plugin.
import { betterAuth } from "better-auth";
import database from "better-sqlite3";
import { legalConsent } from "@better-auth-kit/legal-consent";
export const auth = betterAuth({
database: database("test.db"),
plugins: [
legalConsent({
requireTOS: true,
}),
],
emailAndPassword: {
enabled: true,
},
});
In this configuration, any call to the sign-up endpoint must include tosAccepted: true in the request body.
Sources: packages/plugins/legal-consent/tests/auth.ts:1-12, packages/plugins/legal-consent/README.md:19-29