Plugin: Profile Image
Relevant source files
The following files were used as context for generating this wiki page:The Profile Image plugin for Better Auth Kit provides a comprehensive solution for users to upload, manage, and display custom profile images or avatars. It handles the entire lifecycle of a profile image, including API endpoints for uploading and deleting, validation of file types and sizes, and integration with a pluggable storage provider.
This plugin extends the core user model by managing the image field and ensures data integrity through database-level hooks that validate image URLs upon creation or update. It is designed to be flexible, allowing developers to configure constraints, permissions, and custom logic through a set of well-defined options.
Sources: packages/plugins/profile-image/README.md, packages/plugins/profile-image/src/index.ts
Core Functionality & Configuration
The plugin is initialized by calling the profileImage function and passing a configuration object. This function returns a BetterAuthPlugin object that integrates with the core auth system.
Sources: packages/plugins/profile-image/src/index.ts:42-55
Configuration Options
The behavior of the plugin is controlled through the ProfileImageOptions object.
| Option | Type | Description | Default |
|---|---|---|---|
storageProvider | StorageProvider | Required. An object with uploadImage and optional deleteImage methods to handle file storage. | N/A |
maxSize | number | The maximum allowed file size in bytes. | 5242880 (5MB) |
allowedTypes | string[] | ((session) => string[]) | An array of allowed MIME types (e.g., 'image/png') or a function that returns an array. | ['image/jpeg', 'image/png', 'image/webp'] |
canUploadImage | (session) => boolean | Promise<boolean> | A function to determine if the current user is permitted to upload an image. | undefined (all authenticated users allowed) |
onImageUploaded | (data) => void | Promise<void> | A callback function executed after an image is successfully uploaded and before the user record is updated. | undefined |
trustedImageOrigins | string[] | An array of trusted URL origins. If a user tries to update their image URL directly, the origin must be in this list. | undefined |
Sources: packages/plugins/profile-image/src/index.ts:44-53
API Endpoints
The plugin exposes two primary API endpoints to manage profile images. These endpoints are automatically created and secured.
| Endpoint | Method | Middleware | Description |
|---|---|---|---|
/profile-image/upload | POST | sessionMiddleware | Uploads a new profile image for the authenticated user. |
/profile-image/delete | POST | sessionMiddleware | Deletes the current profile image for the authenticated user. |
Sources: packages/plugins/profile-image/src/index.ts:59-182
Image Upload Flow
The following diagram illustrates the sequence of operations when a user uploads a profile image via the /profile-image/upload endpoint.
This diagram shows the image upload process, including all validation steps and interactions with the storage provider and database.
Sources: packages/plugins/profile-image/src/index.ts:62-154
Image Deletion Flow
The /profile-image/delete endpoint allows an authenticated user to remove their current profile picture.
This diagram shows the image deletion process, which involves removing the file from the storage provider and clearing the URL from the user's database record.
Sources: packages/plugins/profile-image/src/index.ts:155-182
Database Integration and Validation
The plugin integrates with the database by leveraging the core user table's image field and by adding validation hooks.
User Schema
The plugin relies on the standard image field within the user table schema defined by Better Auth. This field is an optional string.
// From packages/cli/src/commands/db/database-explorer-plugin.ts
// ...
user: {
modelName: options.user?.modelName || "user",
fields: {
// ... other fields
image: {
type: "string",
required: false,
fieldName: options.user?.fields?.image || "image",
plugin: "",
},
// ... other fields
},
},
// ...
Sources: packages/cli/src/commands/db/database-explorer-plugin.ts:326-331
This field is then processed by adapters like the Convex adapter, which converts the schema definition into a database-specific format.
Sources: packages/adapters/convex/src/generate-schema/generate-schema-builder.ts:90-104
Database Hooks
To prevent users from setting arbitrary or malicious image URLs directly through the database adapter, the plugin uses the init lifecycle method to register before hooks on the user model for create and update operations.
The following diagram illustrates the validation logic within these hooks.
This flow ensures that any non-null image URL is well-formed and, if configured, comes from a whitelisted domain.
Sources: packages/plugins/profile-image/src/index.ts:184-249
Error Handling
The plugin defines a set of specific error codes to provide clear feedback for failed operations.
| Code | Message |
|---|---|
FILE_TOO_LARGE | File is too large |
INVALID_FILE_TYPE | Invalid file type |
USER_NOT_LOGGED_IN | User must be logged in to upload a profile image |
USER_NOT_FOUND | User not found |
USER_NOT_ALLOWED | You are not allowed to upload a profile image |
INVALID_BLOB | Invalid blob image value. |
PROFILE_IMAGE_NOT_FOUND | Profile image not found |
MISSING_REQUEST_BODY | Missing request body. This is likely caused by the endpoint being called from auth.api. |
USER_DOES_NOT_OWN_IMAGE | You are not allowed to delete this image |
FAILED_TO_UPLOAD_IMAGE | Failed to upload image |
Sources: packages/plugins/profile-image/src/index.ts:14-26
Summary
The Profile Image plugin is a powerful and essential addition to the Better Auth Kit, offering a secure and configurable system for managing user avatars. By providing dedicated API endpoints, robust validation rules, and seamless integration with storage providers and the core database schema, it abstracts away the complexity of handling user-uploaded content. Its use of database hooks further enhances security by validating data at the source, making it a reliable solution for any application that requires user profile images.
Sources: packages/plugins/profile-image/src/index.ts, packages/plugins/profile-image/package.json