UNPKG

better-auth

Version:

The most comprehensive authentication framework for TypeScript.

730 lines (729 loc) • 21.2 kB
import { Session as Session$1, User as User$1 } from "../../types/models.mjs"; import "../../types/index.mjs"; import { AccessControl, Role } from "../access/types.mjs"; import "../access/index.mjs"; import { Invitation, Member, Organization, OrganizationRole, Team, TeamMember } from "./schema.mjs"; import { AuthContext, Awaitable, GenericEndpointContext } from "@better-auth/core"; import { DBFieldAttribute } from "@better-auth/core/db"; //#region src/plugins/organization/types.d.ts interface OrganizationOptions { /** * Configure whether new users are able to create new organizations. * You can also pass a function that returns a boolean. * * @example * ```ts * allowUserToCreateOrganization: async (user) => { * const plan = await getUserPlan(user); * return plan.name === "pro"; * } * ``` * @default true */ allowUserToCreateOrganization?: (boolean | ((user: User$1 & Record<string, any>) => Awaitable<boolean>)) | undefined; /** * The maximum number of organizations a user can create. * * You can also pass a function that returns a boolean. The function should return `true` if the user has reached their organization limit, and `false` otherwise. * * @default unlimited * @example * ```ts * organizationLimit: async (user) => { * const plan = await getUserPlan(user); * // Return true if the user has reached their organization limit, false otherwise * return plan.name === "pro"; * } * ``` */ organizationLimit?: (number | ((user: User$1 & Record<string, any>) => Awaitable<boolean>)) | undefined; /** * The role that is assigned to the creator of the * organization. * * @default "owner" */ creatorRole?: string | undefined; /** * The maximum number of members allowed in an organization. * * @default 100 */ membershipLimit?: number | undefined; /** * Configure the roles and permissions for the * organization plugin. */ ac?: AccessControl | undefined; /** * Custom permissions for roles. */ roles?: { [key in string]?: Role<any> } | undefined; /** * Dynamic access control for the organization plugin. */ dynamicAccessControl?: { /** * Whether to enable dynamic access control for the organization plugin. * * @default false */ enabled?: boolean; /** * The maximum number of roles that can be created for an organization. * * @default Infinite */ maximumRolesPerOrganization?: number | ((organizationId: string) => Awaitable<number>); } | undefined; /** * Support for team. */ teams?: { /** * Enable team features. */ enabled: boolean; /** * Default team configuration */ defaultTeam?: { /** * Enable creating a default team when an organization is created * * @default true */ enabled: boolean; /** * Pass a custom default team creator function */ customCreateDefaultTeam?: (organization: Organization & Record<string, any>, ctx?: GenericEndpointContext) => Promise<Team & Record<string, any>>; }; /** * Maximum number of teams an organization can have. * * You can pass a number or a function that returns a number * * @default "unlimited" * * @param organization * @param request * @returns */ maximumTeams?: ((data: { organizationId: string; session: { user: User$1; session: Session$1; } | null; }, ctx?: GenericEndpointContext) => Awaitable<number>) | number; /** * The maximum number of members per team. * * if `undefined`, there is no limit. * * @default undefined */ maximumMembersPerTeam?: number | ((data: { teamId: string; session: { user: User$1; session: Session$1; }; organizationId: string; }) => Awaitable<number>) | undefined; /** * By default, if an organization does only have one team, they'll not be able to remove it. * * You can disable this behavior by setting this to `false. * * @default false */ allowRemovingAllTeams?: boolean; }; /** * The expiration time for the invitation link. * * @default 48 hours */ invitationExpiresIn?: number | undefined; /** * The maximum invitation a user can send. * * @default 100 */ invitationLimit?: number | ((data: { user: User$1 & Record<string, any>; organization: Organization & Record<string, any>; member: Member & Record<string, any>; }, ctx: AuthContext) => Awaitable<number>) | undefined; /** * Cancel pending invitations on re-invite. * * @default false */ cancelPendingInvitationsOnReInvite?: boolean | undefined; /** * Require email verification on accepting or rejecting an invitation * * @default false */ requireEmailVerificationOnInvitation?: boolean | undefined; /** * Send an email with the * invitation link to the user. * * Note: Better Auth doesn't * generate invitation URLs. * You'll need to construct the * URL using the invitation ID * and pass it to the * acceptInvitation endpoint for * the user to accept the * invitation. * * @example * ```ts * sendInvitationEmail: async (data) => { * const url = `https://yourapp.com/organization/ * accept-invitation?id=${data.id}`; * sendEmail(data.email, "Invitation to join * organization", `Click the link to join the * organization: ${url}`); * } * ``` */ sendInvitationEmail?: ((data: { /** * the invitation id */ id: string; /** * the role of the user */ role: string; /** * the email of the user */ email: string; /** * the organization the user is invited to join */ organization: Organization; /** * the invitation object */ invitation: Invitation; /** * the member who is inviting the user */ inviter: Member & { user: User$1; }; }, /** * The request object */ request?: Request) => Promise<void>) | undefined; /** * The schema for the organization plugin. */ schema?: { session?: { fields?: { activeOrganizationId?: string; activeTeamId?: string; }; }; organization?: { modelName?: string; fields?: { [key in keyof Omit<Organization, "id">]?: string }; additionalFields?: { [key in string]: DBFieldAttribute }; }; member?: { modelName?: string; fields?: { [key in keyof Omit<Member, "id">]?: string }; additionalFields?: { [key in string]: DBFieldAttribute }; }; invitation?: { modelName?: string; fields?: { [key in keyof Omit<Invitation, "id">]?: string }; additionalFields?: { [key in string]: DBFieldAttribute }; }; team?: { modelName?: string; fields?: { [key in keyof Omit<Team, "id">]?: string }; additionalFields?: { [key in string]: DBFieldAttribute }; }; teamMember?: { modelName?: string; fields?: { [key in keyof Omit<TeamMember, "id">]?: string }; }; organizationRole?: { modelName?: string; fields?: { [key in keyof Omit<OrganizationRole, "id">]?: string }; additionalFields?: { [key in string]: DBFieldAttribute }; }; } | undefined; /** * Disable organization deletion * * @default false */ disableOrganizationDeletion?: boolean | undefined; /** * Configure how organization deletion is handled * * @deprecated Use `organizationHooks` instead */ organizationDeletion?: { /** * disable deleting organization * * @deprecated Use `disableOrganizationDeletion` instead */ disabled?: boolean; /** * A callback that runs before the organization is * deleted * * @deprecated Use `organizationHooks` instead * @param data - organization and user object * @param request - the request object * @returns */ beforeDelete?: (data: { organization: Organization; user: User$1; }, request?: Request) => Promise<void>; /** * A callback that runs after the organization is * deleted * * @deprecated Use `organizationHooks` instead * @param data - organization and user object * @param request - the request object * @returns */ afterDelete?: (data: { organization: Organization; user: User$1; }, request?: Request) => Promise<void>; } | undefined; /** * @deprecated Use `organizationHooks` instead */ organizationCreation?: { disabled?: boolean; beforeCreate?: (data: { organization: Omit<Organization, "id"> & Record<string, any>; user: User$1 & Record<string, any>; }, request?: Request) => Promise<void | { data: Record<string, any>; }>; afterCreate?: (data: { organization: Organization & Record<string, any>; member: Member & Record<string, any>; user: User$1 & Record<string, any>; }, request?: Request) => Promise<void>; } | undefined; /** * Hooks for organization */ organizationHooks?: { /** * A callback that runs before the organization is created * * You can return a `data` object to override the default data. * * @example * ```ts * beforeCreateOrganization: async (data) => { * return { * data: { * ...data.organization, * }, * }; * } * ``` * * You can also throw `new APIError` to stop the organization creation. * * @example * ```ts * beforeCreateOrganization: async (data) => { * throw new APIError("BAD_REQUEST", { * message: "Organization creation is disabled", * }); * } */ beforeCreateOrganization?: (data: { organization: { name?: string; slug?: string; logo?: string; metadata?: Record<string, any>; [key: string]: any; }; user: User$1 & Record<string, any>; }) => Promise<void | { data: Record<string, any>; }>; /** * A callback that runs after the organization is created */ afterCreateOrganization?: (data: { organization: Organization & Record<string, any>; member: Member & Record<string, any>; user: User$1 & Record<string, any>; }) => Promise<void>; /** * A callback that runs before the organization is updated * * You can return a `data` object to override the default data. * * @example * ```ts * beforeUpdateOrganization: async (data) => { * return { data: { ...data.organization } }; * } */ beforeUpdateOrganization?: (data: { organization: { name?: string; slug?: string; logo?: string; metadata?: Record<string, any>; [key: string]: any; }; user: User$1 & Record<string, any>; member: Member & Record<string, any>; }) => Promise<void | { data: { name?: string; slug?: string; logo?: string; metadata?: Record<string, any>; [key: string]: any; }; }>; /** * A callback that runs after the organization is updated * * @example * ```ts * afterUpdateOrganization: async (data) => { * console.log(data.organization); * } * ``` */ afterUpdateOrganization?: (data: { /** * Updated organization object * * This could be `null` if an adapter doesn't return updated organization. */ organization: (Organization & Record<string, any>) | null; user: User$1 & Record<string, any>; member: Member & Record<string, any>; }) => Promise<void>; /** * A callback that runs before the organization is deleted */ beforeDeleteOrganization?: (data: { organization: Organization & Record<string, any>; user: User$1 & Record<string, any>; }) => Promise<void>; /** * A callback that runs after the organization is deleted */ afterDeleteOrganization?: (data: { organization: Organization & Record<string, any>; user: User$1 & Record<string, any>; }) => Promise<void>; /** * Member hooks */ /** * A callback that runs before a member is added to an organization * * You can return a `data` object to override the default data. * * @example * ```ts * beforeAddMember: async (data) => { * return { * data: { * ...data.member, * role: "custom-role" * } * }; * } * ``` */ beforeAddMember?: (data: { member: { userId: string; organizationId: string; role: string; [key: string]: any; }; user: User$1 & Record<string, any>; organization: Organization & Record<string, any>; }) => Promise<void | { data: Record<string, any>; }>; /** * A callback that runs after a member is added to an organization */ afterAddMember?: (data: { member: Member & Record<string, any>; user: User$1 & Record<string, any>; organization: Organization & Record<string, any>; }) => Promise<void>; /** * A callback that runs before a member is removed from an organization */ beforeRemoveMember?: (data: { member: Member & Record<string, any>; user: User$1 & Record<string, any>; organization: Organization & Record<string, any>; }) => Promise<void>; /** * A callback that runs after a member is removed from an organization */ afterRemoveMember?: (data: { member: Member & Record<string, any>; user: User$1 & Record<string, any>; organization: Organization & Record<string, any>; }) => Promise<void>; /** * A callback that runs before a member's role is updated * * You can return a `data` object to override the default data. */ beforeUpdateMemberRole?: (data: { member: Member & Record<string, any>; newRole: string; user: User$1 & Record<string, any>; organization: Organization & Record<string, any>; }) => Promise<void | { data: { role: string; [key: string]: any; }; }>; /** * A callback that runs after a member's role is updated */ afterUpdateMemberRole?: (data: { member: Member & Record<string, any>; previousRole: string; user: User$1 & Record<string, any>; organization: Organization & Record<string, any>; }) => Promise<void>; /** * Invitation hooks */ /** * A callback that runs before an invitation is created * * You can return a `data` object to override the default data. * * @example * ```ts * beforeCreateInvitation: async (data) => { * return { * data: { * ...data.invitation, * expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 7) // 7 days * } * }; * } * ``` */ beforeCreateInvitation?: (data: { invitation: { email: string; role: string; organizationId: string; inviterId: string; teamId?: string; [key: string]: any; }; inviter: User$1 & Record<string, any>; organization: Organization & Record<string, any>; }) => Promise<void | { data: Record<string, any>; }>; /** * A callback that runs after an invitation is created */ afterCreateInvitation?: (data: { invitation: Invitation & Record<string, any>; inviter: User$1 & Record<string, any>; organization: Organization & Record<string, any>; }) => Promise<void>; /** * A callback that runs before an invitation is accepted */ beforeAcceptInvitation?: (data: { invitation: Invitation & Record<string, any>; user: User$1 & Record<string, any>; organization: Organization & Record<string, any>; }) => Promise<void>; /** * A callback that runs after an invitation is accepted */ afterAcceptInvitation?: (data: { invitation: Invitation & Record<string, any>; member: Member & Record<string, any>; user: User$1 & Record<string, any>; organization: Organization & Record<string, any>; }) => Promise<void>; /** * A callback that runs before an invitation is rejected */ beforeRejectInvitation?: (data: { invitation: Invitation & Record<string, any>; user: User$1 & Record<string, any>; organization: Organization & Record<string, any>; }) => Promise<void>; /** * A callback that runs after an invitation is rejected */ afterRejectInvitation?: (data: { invitation: Invitation & Record<string, any>; user: User$1 & Record<string, any>; organization: Organization & Record<string, any>; }) => Promise<void>; /** * A callback that runs before an invitation is cancelled */ beforeCancelInvitation?: (data: { invitation: Invitation & Record<string, any>; cancelledBy: User$1 & Record<string, any>; organization: Organization & Record<string, any>; }) => Promise<void>; /** * A callback that runs after an invitation is cancelled */ afterCancelInvitation?: (data: { invitation: Invitation & Record<string, any>; cancelledBy: User$1 & Record<string, any>; organization: Organization & Record<string, any>; }) => Promise<void>; /** * Team hooks (when teams are enabled) */ /** * A callback that runs before a team is created * * You can return a `data` object to override the default data. */ beforeCreateTeam?: (data: { team: { name: string; organizationId: string; [key: string]: any; }; user?: User$1 & Record<string, any>; organization: Organization & Record<string, any>; }) => Promise<void | { data: Record<string, any>; }>; /** * A callback that runs after a team is created */ afterCreateTeam?: (data: { team: Team & Record<string, any>; user?: User$1 & Record<string, any>; organization: Organization & Record<string, any>; }) => Promise<void>; /** * A callback that runs before a team is updated * * You can return a `data` object to override the default data. */ beforeUpdateTeam?: (data: { team: Team & Record<string, any>; updates: { name?: string; [key: string]: any; }; user: User$1 & Record<string, any>; organization: Organization & Record<string, any>; }) => Promise<void | { data: Record<string, any>; }>; /** * A callback that runs after a team is updated */ afterUpdateTeam?: (data: { team: (Team & Record<string, any>) | null; user: User$1 & Record<string, any>; organization: Organization & Record<string, any>; }) => Promise<void>; /** * A callback that runs before a team is deleted */ beforeDeleteTeam?: (data: { team: Team & Record<string, any>; user?: User$1 & Record<string, any>; organization: Organization & Record<string, any>; }) => Promise<void>; /** * A callback that runs after a team is deleted */ afterDeleteTeam?: (data: { team: Team & Record<string, any>; user?: User$1 & Record<string, any>; organization: Organization & Record<string, any>; }) => Promise<void>; /** * A callback that runs before a member is added to a team */ beforeAddTeamMember?: (data: { teamMember: { teamId: string; userId: string; [key: string]: any; }; team: Team & Record<string, any>; user: User$1 & Record<string, any>; organization: Organization & Record<string, any>; }) => Promise<void | { data: Record<string, any>; }>; /** * A callback that runs after a member is added to a team */ afterAddTeamMember?: (data: { teamMember: TeamMember & Record<string, any>; team: Team & Record<string, any>; user: User$1 & Record<string, any>; organization: Organization & Record<string, any>; }) => Promise<void>; /** * A callback that runs before a member is removed from a team */ beforeRemoveTeamMember?: (data: { teamMember: TeamMember & Record<string, any>; team: Team & Record<string, any>; user: User$1 & Record<string, any>; organization: Organization & Record<string, any>; }) => Promise<void>; /** * A callback that runs after a member is removed from a team */ afterRemoveTeamMember?: (data: { teamMember: TeamMember & Record<string, any>; team: Team & Record<string, any>; user: User$1 & Record<string, any>; organization: Organization & Record<string, any>; }) => Promise<void>; } | undefined; } //#endregion export { OrganizationOptions }; //# sourceMappingURL=types.d.mts.map