组织
组织插件简化了用户访问和权限管理。分配角色和权限以简化项目管理、团队协作和合作伙伴关系。
安装
使用方法
安装插件后,您可以开始使用组织插件来管理组织的成员和团队。客户端插件将在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。您可以将其设置为任何数字或返回布尔值的函数。