组织
组织插件简化了用户访问和权限管理。分配角色和权限以简化项目管理、团队协作和合作伙伴关系。
安装
使用方法
安装插件后,您可以开始使用组织插件来管理组织的成员和团队。客户端插件将在organization
命名空间下提供方法。服务器api
将提供管理组织的必要端点,并为您提供更简便的方式在自己的后端调用这些函数。
组织
创建组织
要创建组织,您需要提供:
name
:组织的名称。slug
:组织的唯一标识符。logo
:组织的徽标。(可选)
限制谁可以创建组织
默认情况下,任何用户都可以创建组织。要限制这一点,将allowUserToCreateOrganization
选项设置为返回布尔值的函数,或直接设置为true
或false
。
检查组织标识符是否已被使用
要检查组织标识符是否已被使用,您可以使用客户端提供的checkSlug
函数。该函数接受一个具有以下属性的对象:
slug
:组织的标识符。
组织创建钩子
您可以使用在组织创建前后运行的钩子自定义组织创建过程。
beforeCreate
钩子在组织创建前运行。它接收:
organization
:组织数据(不包含ID)user
:创建组织的用户request
:HTTP请求对象(可选)
返回带有data
属性的对象来修改将要创建的组织数据。
afterCreate
钩子在组织成功创建后运行。它接收:
organization
:已创建的组织(包含ID)member
:创建者的成员记录user
:创建组织的用户request
:HTTP请求对象(可选)
列出用户的组织
要列出用户所属的组织,可以使用useListOrganizations
钩子。它以响应式方式获取用户所属的组织。
活跃组织
活跃组织是用户当前正在使用的工作区。默认情况下,当用户登录时,活跃组织设置为null
。您可以将活跃组织设置到用户会话中。
并非总是需要在会话中保存活跃组织。您可以只在客户端管理活跃组织。例如,多个标签页可以有不同的活跃组织。
设置活跃组织
您可以通过调用organization.setActive
函数来设置活跃组织。它将为用户会话设置活跃组织。
要在创建会话时设置活跃组织,可以使用数据库钩子。
使用活跃组织
要获取用户的活跃组织,可以调用useActiveOrganization
钩子。它返回用户的活跃组织。每当活跃组织变化时,该钩子将重新评估并返回新的活跃组织。
获取完整组织信息
要获取组织的完整详情,可以使用客户端提供的getFullOrganization
函数。该函数接受一个具有以下属性的对象:
organizationId
:组织的ID。(可选)– 默认情况下,它将使用活跃组织。organizationSlug
:组织的标识符。(可选)– 用于通过标识符获取组织。
更新组织
要更新组织信息,可以使用organization.update
删除组织
要删除用户拥有的组织,可以使用organization.delete
如果用户在指定组织中拥有必要的权限(默认情况下:角色为owner),所有成员、邀请和组织信息都将被删除。
您可以通过organizationDeletion
选项配置组织删除的处理方式:
邀请
要将成员添加到组织中,我们首先需要向用户发送邀请。用户将收到带有邀请链接的电子邮件/短信。一旦用户接受邀请,他们将被添加到组织中。
设置邀请电子邮件
为了使成员邀请功能正常工作,我们首先需要向better-auth
实例提供sendInvitationEmail
。这个函数负责向用户发送邀请电子邮件。
您需要构建并向用户发送邀请链接。链接应包含邀请ID,当用户点击链接时将与acceptInvitation函数一起使用。
发送邀请
要邀请用户加入组织,可以使用客户端提供的invite
函数。invite
函数接受一个具有以下属性的对象:
email
:用户的电子邮件地址。role
:用户在组织中的角色。可以是admin
、member
或guest
。organizationId
:组织的ID。这是可选的,默认情况下它将使用活跃组织。(可选)
- 如果用户已经是组织的成员,邀请将被取消。
- 如果用户已经被邀请到组织,除非
resend
设置为true
,否则不会再次发送邀请。 - 如果
cancelPendingInvitationsOnReInvite
设置为true
,如果用户已经被邀请到组织并发送了新邀请,原有邀请将被取消。
接受邀请
当用户收到邀请电子邮件时,他们可以点击邀请链接来接受邀请。邀请链接应包含邀请ID,用于接受邀请。
确保在用户登录后调用acceptInvitation
函数。
更新邀请状态
要更新邀请的状态,可以使用客户端提供的acceptInvitation
、cancelInvitation
、rejectInvitation
函数。这些函数接受邀请ID作为参数。
获取邀请
要获取邀请,可以使用客户端提供的getInvitation
函数。您需要提供邀请ID作为查询参数。
列出邀请
要列出所有邀请,可以使用客户端提供的listInvitations
函数。
Members
移除成员
要移除成员,可以使用organization.removeMember
更新成员角色
要更新组织中成员的角色,可以使用organization.updateMemberRole
。如果用户有更新成员角色的权限,角色将被更新。
获取活跃成员
要获取组织的当前成员,可以使用organization.getActiveMember
函数。此函数将返回当前活跃成员。
添加成员
如果您想直接将成员添加到组织而不发送邀请,可以使用只能在服务器上调用的addMember
函数。
退出组织
要退出组织,可以使用organization.leave
函数。此函数将从组织中移除当前用户。
访问控制
组织插件提供了非常灵活的访问控制系统。您可以根据用户在组织中的角色控制用户的访问权限。您可以根据用户的角色定义自己的权限集。
角色
默认情况下,组织中有三个角色:
owner
:默认情况下创建组织的用户。所有者对组织拥有完全控制权,可以执行任何操作。
admin
:拥有admin角色的用户对组织拥有完全控制权,但不能删除组织或更改所有者。
member
:拥有member角色的用户对组织有有限的控制权。他们可以创建项目、邀请用户和管理他们创建的项目。
用户可以拥有多个角色。多个角色存储为以逗号(",")分隔的字符串。
权限
默认情况下,有三个资源,这些资源有两到三个操作。
organization:
update
delete
member:
create
update
delete
invitation:
create
cancel
所有者对所有资源和操作有完全控制权。管理员对所有资源有完全控制权,但不能删除组织或更改所有者。成员除了读取数据外,对这些操作没有任何控制权。
自定义权限
该插件提供了一种简便的方法来为每个角色定义自己的权限集。
创建角色
一旦创建了访问控制器,您可以使用已定义的权限创建角色。
当您为现有角色创建自定义角色时,那些角色的预定义权限将被覆盖。要将现有权限添加到自定义角色,您需要导入defaultStatements
并将其与您的新语句合并,同时将角色的权限集与默认角色合并。
访问控制使用
检查权限:
您可以使用api
提供的hasPermission
操作来检查用户的权限。
如果您想从服务器检查客户端上的用户权限,可以使用客户端提供的hasPermission
函数。
检查角色权限:
一旦定义了角色和权限,为了避免从服务器检查权限,您可以使用客户端提供的checkRolePermission
函数。
团队
团队允许您在组织内分组成员。团队功能提供了额外的组织结构,可用于在更精细的级别管理权限。
启用团队
要启用团队,请将teams
配置选项传递给服务器和客户端插件:
管理团队
创建团队
在组织内创建新团队:
列出团队
获取组织中的所有团队:
更新团队
更新团队的详细信息:
移除团队
从组织中删除团队:
团队权限
团队遵循组织的权限系统。要管理团队,用户需要以下权限:
team:create
- 创建新团队team:update
- 更新团队详细信息team:delete
- 移除团队
默认情况下:
- 组织所有者和管理员可以管理团队
- 普通成员不能创建、更新或删除团队
团队配置选项
团队功能支持多种配置选项:
-
maximumTeams
:限制每个组织的团队数量 -
allowRemovingAllTeams
:控制是否可以移除最后一个团队
团队成员
在邀请成员加入组织时,您可以指定一个团队:
被邀请的成员在接受邀请后将被添加到指定的团队中。
数据库表
当启用团队功能时,会添加一个新的team
表,结构如下:
Field Name | Type | Key | Description |
---|---|---|---|
id | string | 每个团队的唯一标识符 | |
name | string | - | 团队名称 |
organizationId | string | 组织的ID | |
createdAt | Date | - | 团队创建时的时间戳 |
updatedAt | Date | - | 团队最后更新时的时间戳 |
Schema
组织插件向数据库添加以下表:
组织表
表名: organization
Field Name | Type | Key | Description |
---|---|---|---|
id | string | 每个组织的唯一标识符 | |
name | string | - | 组织名称 |
slug | string | - | 组织的唯一标识符 |
logo | string | 组织的logo | |
metadata | string | 组织的额外元数据 | |
createdAt | Date | - | 组织创建时的时间戳 |
成员表
表名: member
Field Name | Type | Key | Description |
---|---|---|---|
id | string | 每个成员的唯一标识符 | |
userId | string | 用户的ID | |
organizationId | string | 组织的ID | |
role | string | - | 用户在组织中的角色 |
createdAt | Date | - | 成员添加到组织时的时间戳 |
邀请表
表名: invitation
Field Name | Type | Key | Description |
---|---|---|---|
id | string | 每个邀请的唯一标识符 | |
string | - | 用户的电子邮件地址 | |
inviterId | string | 邀请者的ID | |
organizationId | string | 组织的ID | |
role | string | - | 用户在组织中的角色 |
status | string | - | 邀请的状态 |
expiresAt | Date | - | 邀请过期的时间戳 |
createdAt | Date | - | 邀请创建时的时间戳 |
会话表
表名: session
您需要在会话表中添加一个字段来存储活跃组织的ID。
Field Name | Type | Key | Description |
---|---|---|---|
activeOrganizationId | string | 活跃组织的ID |
团队表(可选)
表名: team
Field Name | Type | Key | Description |
---|---|---|---|
id | string | 每个团队的唯一标识符 | |
name | string | - | 团队名称 |
organizationId | string | 组织的ID | |
createdAt | Date | - | 团队创建时的时间戳 |
updatedAt | Date | 团队更新时的时间戳 |
表名: member
Field Name | Type | Key | Description |
---|---|---|---|
teamId | string | 团队的ID |
表名: invitation
Field Name | Type | Key | Description |
---|---|---|---|
teamId | string | 团队的ID |
自定义Schema
要更改表名或字段,您可以向组织插件传递schema
选项。
选项
allowUserToCreateOrganization: boolean
| ((user: User) => Promise<boolean> | boolean)
- 确定用户是否可以创建组织的函数。默认为true
。您可以将其设置为false
以限制用户创建组织。
organizationLimit: number
| ((user: User) => Promise<boolean> | boolean)
- 用户允许的最大组织数量。默认为5
。您可以将其设置为任何数字或返回布尔值的函数。
creatorRole: admin | owner
- 创建组织的用户的角色。默认为owner
。您可以将其设置为admin
。
membershipLimit: number
- 组织中允许的最大成员数量。默认为100
。您可以将其设置为任何数字。
sendInvitationEmail: async (data) => Promise<void>
- 向用户发送邀请电子邮件的函数。
invitationExpiresIn: number
- 邀请链接的有效期(秒)。默认为48小时(2天)。
cancelPendingInvitationsOnReInvite: boolean
- 如果用户已被邀请到组织,是否取消待处理的邀请。默认为true
。
invitationLimit: number
| ((user: User) => Promise<boolean> | boolean)
- 用户允许的最大邀请数量。默认为100
。您可以将其设置为任何数字或返回布尔值的函数。