Plugin: App Invite
Relevant source files
The following files were used as context for generating this wiki page:The App Invite plugin for Better Auth provides a complete system for managing user invitations. It allows existing, authorized users to invite new users to the application, who can then sign up. This facilitates controlled growth and invite-only access models. The plugin supports two primary types of invitations: "personal" invitations sent to a specific email address and "public" invitations, which are shareable links that can be restricted by email domain.
The plugin exposes a set of API endpoints to create, accept, reject, cancel, and list invitations. It is highly configurable, allowing developers to define permissions for creating invitations, set expiration times, and integrate custom email sending logic. All interactions are managed through a dedicated appInvitation database table.
Sources: packages/plugins/app-invite/README.md, packages/plugins/app-invite/src/index.ts:13-15, packages/plugins/app-invite/src/index.ts:199-202
Configuration
The plugin is initialized by passing an AppInviteOptions object. This object allows for customization of the invitation flow, permissions, and behavior.
Sources: packages/plugins/app-invite/src/index.ts:17-90
| Option | Type | Description | Default |
|---|---|---|---|
allowUserToCreateInvitation | boolean | (user, type) => Promise<boolean> | boolean | Determines if a logged-in user can create an invitation. Can be a static boolean or a function for dynamic permission checks. | true |
allowUserToCancelInvitation | ({ user, invitation }) => Promise<boolean> | boolean | Determines if a user can cancel a specific invitation. | Inviter only |
invitationExpiresIn | number | The expiration time for an invitation link in milliseconds. | 48 hours |
sendInvitationEmail | (data, request?) => Promise<void> | A function to send an invitation email. This is required for personal invitations. | undefined |
schema | object | Allows customization of the appInvitation model name and its field names in the database. | undefined |
autoSignIn | boolean | If true, automatically signs in the user and creates a session after they accept an invitation and sign up. | false |
rateLimit | { window: number; max: number; } | Configures rate limiting for the plugin's endpoints. window is in seconds. | { window: 60, max: 5 } |
$Infer | { AdditionalFields?: Record<string, any> } | Infers additional fields for the user model, allowing them to be passed during the invitation acceptance (sign-up) process. | undefined |
Sources: packages/plugins/app-invite/src/index.ts:17-90, packages/plugins/app-invite/tests/app-invite.test.ts:38-52
Data Schema
The plugin introduces a new table to the database, by default named appInvitation, to store and manage invitation records.
Sources: packages/plugins/app-invite/src/schema.ts, packages/plugins/app-invite/src/index.ts:1001-1043
ER Diagram
This diagram shows the relationship between the appInvitation table and the core user table.
appInvitation Table Schema
| Field | Type | Description | Constraints / Default |
|---|---|---|---|
id | string | Unique identifier for the invitation. | Primary Key, generateId() |
name | string | The name of the person being invited (optional). | Optional |
email | string | The email of the person being invited. Defines a "personal" invitation. | Optional |
status | string | The current status of the invitation. | pending, accepted, rejected, canceled. Default: pending |
inviterId | string | The ID of the user who created the invitation. | Foreign Key to user.id |
expiresAt | date | The date and time when the invitation expires. | Required |
domainWhitelist | string | A comma-separated list of domains allowed for "public" invitations. | Optional |
Sources: packages/plugins/app-invite/src/schema.ts:7-21, packages/plugins/app-invite/src/index.ts:1001-1043
API Endpoints & Flows
The plugin exposes several API endpoints to manage the full lifecycle of an invitation.
Sources: packages/plugins/app-invite/src/index.ts:109-898
Create Invitation Flow
A logged-in user can create either a personal (email-based) or public (link-based) invitation.
This diagram illustrates the sequence for creating a new invitation.
Accept Invitation Flow
A new user accepts an invitation by providing their details, which creates a new user account.
This diagram shows the process of a new user signing up via an invitation.
Endpoints Summary
| Endpoint | Method | Auth Required | Description |
|---|---|---|---|
/invite-user | POST | Yes | Creates a new personal or public invitation. |
/get-app-invitation | GET | No | Retrieves the details of a pending invitation by its ID. |
/accept-invitation | POST | No | Accepts an invitation, creating a new user account. |
/reject-invitation | POST | No | Rejects a personal invitation. Not applicable to public invitations. |
/cancel-invitation | POST | Yes | Cancels an invitation. By default, only the inviter can do this. |
/list-invitations | GET | Yes | Lists all invitations created by the currently logged-in user. Supports pagination, sorting, and filtering. |
Sources: packages/plugins/app-invite/src/index.ts:109-898
Client-Side Integration
The package includes a client-side helper, appInviteClient, to be used with better-auth/client. This provides typed methods for interacting with the App Invite API endpoints from a frontend application.
// Example of client-side plugin initialization
import { appInviteClient } from "@better-auth-kit/app-invite/client";
import { createAuthClient } from "better-auth/client";
const client = createAuthClient({
baseURL: "http://localhost:3000",
plugins: [appInviteClient()],
});
// Usage
// client.inviteUser({ email: "new@user.com" });
// client.acceptInvitation({ invitationId: "...", password: "..." });
This setup ensures type safety between the client and server for all App Invite operations.
Sources: packages/plugins/app-invite/src/client.ts, packages/plugins/app-invite/tests/app-invite.test.ts:58-79
Conclusion
The App Invite plugin is a powerful addition to the Better Auth ecosystem, offering a feature-rich, secure, and customizable solution for implementing invite-only user registration. It handles the entire lifecycle of an invitation, from creation by an existing user to the successful sign-up of a new user, while providing developers with fine-grained control over permissions and workflows.