Organization
Organizations simplifies user access and permissions management. Assign roles and permissions to streamline project management, team coordination, and partnerships.
Installation
Migrate the database
Run the migration or generate the schema to add the necessary fields and tables to the database.
See the Schema section to add the fields manually.
Usage
Once you've installed the plugin, you can start using the organization plugin to manage your organization's members and teams. The client plugin will provide you methods under the organization
namespace. And the server api
will provide you with the necessary endpoints to manage your organization and gives you easier way to call the functions on your own backend.
Organization
Create an organization
To create an organization, you need to provide:
name
: The name of the organization.slug
: The slug of the organization.logo
: The logo of the organization. (Optional)
Restrict who can create an organization
By default, any user can create an organization. To restrict this, set the allowUserToCreateOrganization
option to a function that returns a boolean, or directly to true
or false
.
List User's Organizations
To list the organizations that a user is a member of, you can use useListOrganizations
hook. It implments a reactive way to get the organizations that the user is a member of.
Active Organization
Active organization is the workspace the user is currently working on. By defualt when the user is signed in the active organization is set to null
.
Set Active Organization
You can set the active organization by calling the organization.setActive
function. It'll set the active organization for the user both on the client state and the session on the server.
Use Active Organization
To retrieve the active organization for the user, you can call the useActiveOrganization
hook. It returns the active organization for the user. Whenever the active organization changes, the hook will re-evaluate and return the new active organization.
Invitations
To add a member to an organization, we first need to send an invitation to the user. The user will receive an email/sms with the invitation link. Once the user accepts the invitation, they will be added to the organization.
Setup Invitation Email
For member invitation to work we first need to provider sendInvitationEmail
to the better-auth
instance. This function is responsible for sending the invitation email to the user.
You'll need to construct and send the invitation link to the user. The link should include the invitation ID, which will be used with the acceptInvitation function when the user clicks on it.
Send Invitation
To invite users to an organization, you can use the invite
function provided by the client. The invite
function takes an object with the following properties:
email
: The email address of the user.role
: The role of the user in the organization. It can beadmin
,member
, orguest
.organizationId
: The id of the organization. this is optional by default it will use the active organization. (Optional)
Accept Invitation
When a user receives an invitation email, they can click on the invitation link to accept the invitation. The invitation link should include the invitation ID, which will be used to accept the invitation.
Make sure to call the acceptInvitation
function after the user is logged in.
Update Invitation Status
To update the status of invitation you can use the acceptInvitation
, cancelInvitation
, rejectInvitation
functions provided by the client. The functions take the invitation id as an argument.
Get Invitation
To get an invitation you can use the getInvitation
function provided by the client. You need to provide the invitation id as a query parameter.
Remove Member
To remove you can use organization.removeMember
Update Member Role
To update the role of a member in an organization, you can use the organization.updateMemberRole
. If the user has the permission to update the role of the member, the role will be updated.
Access Control
The organization plugin providers a very flexible access control system. You can control the access of the user based on the role they have in the organization. You can define your own set of permissions based on the role of the user.
Roles
currently only three roles are supported:
owner
: The user who created the organization by default. The owner has full control over the organization and can perform any action.
admin
: Users with the admin role have full control over the organization except for deleting the organization or changing the owner.
member
: Users with the member role have limited control over the organization. They can create projects, invite users, and manage projects they have created.
Currently, you can't create custom roles
Permissons
By defualt there are 3 resources and they have 2 to 3 actions.
organization:
update
delete
member:
create
update
delete
invitation:
create
cancel
The owner have full control over all the resources and actions. The admin have full control over all the resources except for deleting the organization or changing the owner. The member have no control over any of those action other than reading the data.
Custom Permissions
the plugin providers easy way to define your own set of permission for each role.
Create Access Control
You first need to create access controller by calling createAccessControl
function and passing the statement object. The statement object should have the resource name as the key and the array of actions as the value.
Create Roles
Once you have created the access controller you can create roles with the permissions you have defined.
Pass Roles to the Plugin
Once you have created the roles you can pass them to the organization plugin both on the client and the server.
You also need to pass the access controller to the client plugin. This is useful for type checking and auto-completion.
Schema
The organization plugin adds the following tables to the database:
Organization
Table Name: organization
Field Name | Type | Key | Description |
---|---|---|---|
id | string | Unique identifier for each organization | |
name | string | - | The name of the organization |
slug | string | - | The slug of the organization |
logo | string | The logo of the organization | |
metadata | string | Additional metadata for the organization | |
createdAt | Date | - | Timestamp of when the organization was created |
Member
Table Name: member
Field Name | Type | Key | Description |
---|---|---|---|
id | string | Unique identifier for each member | |
userId | string | The id of the user | |
organizationId | string | The id of the organization | |
role | string | - | The role of the user in the organization |
createdAt | Date | - | Timestamp of when the member was added to the organization |
Invitation
Table Name: invitation
Field Name | Type | Key | Description |
---|---|---|---|
id | string | Unique identifier for each invitation | |
string | - | The email address of the user | |
organizationId | string | The id of the organization | |
role | string | - | The role of the user in the organization |
status | string | - | The status of the invitation |
expiresAt | Date | - | Timestamp of when the invitation expires |
createdAt | Date | - | Timestamp of when the invitation was created |
Options
allowUserToCreateOrganization: boolean
| ((user: User) => Promise<boolean> | boolean)
- A function that determines whether a user can create an organization. By default, it's true
. You can set it to false
to restrict users from creating organizations.
organizationLimit: numbe
| ((user: User) => Promise<boolean> | boolean)
- The maximum number of organizations allowed for a user. By default, it's 5
. You can set it to any number you want or a function that returns a boolean.
creatorRole: admin | owner
- The role of the user who creates the organization. By default, it's owner
. You can set it to admin
.
membershipLimit: number
- The maximum number of members allowed in an organization. By default, it's 100
. You can set it to any number you want.
sendInvitationEmail: async (data) => Promise<void>
- A function that sends an invitation email to the user.
invitationExpiresIn : number
- How long the invitation link is valid for in seconds. By default, it's 48 hours (2 days).