UNPKG

better-auth

Version:

The most comprehensive authentication framework for TypeScript.

616 lines (614 loc) • 15.7 kB
import { getDate } from "../../utils/date.mjs"; import { parseJSON } from "../../client/parser.mjs"; import { getCurrentAdapter } from "@better-auth/core/context"; import { BetterAuthError } from "@better-auth/core/error"; //#region src/plugins/organization/adapter.ts const getOrgAdapter = (context, options) => { const baseAdapter = context.adapter; return { findOrganizationBySlug: async (slug) => { return await (await getCurrentAdapter(baseAdapter)).findOne({ model: "organization", where: [{ field: "slug", value: slug }] }); }, createOrganization: async (data) => { const organization = await (await getCurrentAdapter(baseAdapter)).create({ model: "organization", data: { ...data.organization, metadata: data.organization.metadata ? JSON.stringify(data.organization.metadata) : void 0 }, forceAllowId: true }); return { ...organization, metadata: organization.metadata && typeof organization.metadata === "string" ? JSON.parse(organization.metadata) : void 0 }; }, findMemberByEmail: async (data) => { const adapter = await getCurrentAdapter(baseAdapter); const user = await adapter.findOne({ model: "user", where: [{ field: "email", value: data.email.toLowerCase() }] }); if (!user) return null; const member = await adapter.findOne({ model: "member", where: [{ field: "organizationId", value: data.organizationId }, { field: "userId", value: user.id }] }); if (!member) return null; return { ...member, user: { id: user.id, name: user.name, email: user.email, image: user.image } }; }, listMembers: async (data) => { const adapter = await getCurrentAdapter(baseAdapter); const members = await Promise.all([adapter.findMany({ model: "member", where: [{ field: "organizationId", value: data.organizationId }, ...data.filter?.field ? [{ field: data.filter?.field, value: data.filter?.value, ...data.filter.operator ? { operator: data.filter.operator } : {} }] : []], limit: data.limit || options?.membershipLimit || 100, offset: data.offset || 0, sortBy: data.sortBy ? { field: data.sortBy, direction: data.sortOrder || "asc" } : void 0 }), adapter.count({ model: "member", where: [{ field: "organizationId", value: data.organizationId }, ...data.filter?.field ? [{ field: data.filter?.field, value: data.filter?.value, ...data.filter.operator ? { operator: data.filter.operator } : {} }] : []] })]); const users = await adapter.findMany({ model: "user", where: [{ field: "id", value: members[0].map((member) => member.userId), operator: "in" }] }); return { members: members[0].map((member) => { const user = users.find((user$1) => user$1.id === member.userId); if (!user) throw new BetterAuthError("Unexpected error: User not found for member"); return { ...member, user: { id: user.id, name: user.name, email: user.email, image: user.image } }; }), total: members[1] }; }, findMemberByOrgId: async (data) => { const result = await (await getCurrentAdapter(baseAdapter)).findOne({ model: "member", where: [{ field: "userId", value: data.userId }, { field: "organizationId", value: data.organizationId }], join: { user: true } }); if (!result || !result.user) return null; const { user, ...member } = result; return { ...member, user: { id: user.id, name: user.name, email: user.email, image: user.image } }; }, findMemberById: async (memberId) => { const result = await (await getCurrentAdapter(baseAdapter)).findOne({ model: "member", where: [{ field: "id", value: memberId }], join: { user: true } }); if (!result) return null; const { user, ...member } = result; return { ...member, user: { id: user.id, name: user.name, email: user.email, image: user.image } }; }, createMember: async (data) => { return await (await getCurrentAdapter(baseAdapter)).create({ model: "member", data: { ...data, createdAt: /* @__PURE__ */ new Date() } }); }, updateMember: async (memberId, role) => { return await (await getCurrentAdapter(baseAdapter)).update({ model: "member", where: [{ field: "id", value: memberId }], update: { role } }); }, deleteMember: async ({ memberId, organizationId, userId: _userId }) => { const adapter = await getCurrentAdapter(baseAdapter); let userId; if (!_userId) { const member$1 = await adapter.findOne({ model: "member", where: [{ field: "id", value: memberId }] }); if (!member$1) throw new BetterAuthError("Member not found"); userId = member$1.userId; } else userId = _userId; const member = await adapter.delete({ model: "member", where: [{ field: "id", value: memberId }] }); if (options?.teams?.enabled) { const teams = await adapter.findMany({ model: "team", where: [{ field: "organizationId", value: organizationId }] }); await Promise.all(teams.map((team) => adapter.deleteMany({ model: "teamMember", where: [{ field: "teamId", value: team.id }, { field: "userId", value: userId }] }))); } return member; }, updateOrganization: async (organizationId, data) => { const organization = await (await getCurrentAdapter(baseAdapter)).update({ model: "organization", where: [{ field: "id", value: organizationId }], update: { ...data, metadata: typeof data.metadata === "object" ? JSON.stringify(data.metadata) : data.metadata } }); if (!organization) return null; return { ...organization, metadata: organization.metadata ? parseJSON(organization.metadata) : void 0 }; }, deleteOrganization: async (organizationId) => { const adapter = await getCurrentAdapter(baseAdapter); await adapter.deleteMany({ model: "member", where: [{ field: "organizationId", value: organizationId }] }); await adapter.deleteMany({ model: "invitation", where: [{ field: "organizationId", value: organizationId }] }); await adapter.delete({ model: "organization", where: [{ field: "id", value: organizationId }] }); return organizationId; }, setActiveOrganization: async (sessionToken, organizationId, ctx) => { return await context.internalAdapter.updateSession(sessionToken, { activeOrganizationId: organizationId }); }, findOrganizationById: async (organizationId) => { return await (await getCurrentAdapter(baseAdapter)).findOne({ model: "organization", where: [{ field: "id", value: organizationId }] }); }, checkMembership: async ({ userId, organizationId }) => { return await (await getCurrentAdapter(baseAdapter)).findOne({ model: "member", where: [{ field: "userId", value: userId }, { field: "organizationId", value: organizationId }] }); }, findFullOrganization: async ({ organizationId, isSlug, includeTeams, membersLimit }) => { const adapter = await getCurrentAdapter(baseAdapter); const result = await adapter.findOne({ model: "organization", where: [{ field: isSlug ? "slug" : "id", value: organizationId }], join: { invitation: true, member: membersLimit ? { limit: membersLimit } : true, ...includeTeams ? { team: true } : {} } }); if (!result) return null; const { invitation: invitations, member: members, team: teams, ...org } = result; const userIds = members.map((member) => member.userId); const users = userIds.length > 0 ? await adapter.findMany({ model: "user", where: [{ field: "id", value: userIds, operator: "in" }], limit: options?.membershipLimit || 100 }) : []; const userMap = new Map(users.map((user) => [user.id, user])); const membersWithUsers = members.map((member) => { const user = userMap.get(member.userId); if (!user) throw new BetterAuthError("Unexpected error: User not found for member"); return { ...member, user: { id: user.id, name: user.name, email: user.email, image: user.image } }; }); return { ...org, invitations, members: membersWithUsers, teams }; }, listOrganizations: async (userId) => { const result = await (await getCurrentAdapter(baseAdapter)).findMany({ model: "member", where: [{ field: "userId", value: userId }], join: { organization: true } }); if (!result || result.length === 0) return []; return result.map((member) => member.organization); }, createTeam: async (data) => { return await (await getCurrentAdapter(baseAdapter)).create({ model: "team", data }); }, findTeamById: async ({ teamId, organizationId, includeTeamMembers }) => { const result = await (await getCurrentAdapter(baseAdapter)).findOne({ model: "team", where: [{ field: "id", value: teamId }, ...organizationId ? [{ field: "organizationId", value: organizationId }] : []], join: { ...includeTeamMembers ? { teamMember: true } : {} } }); if (!result) return null; const { teamMember, ...team } = result; return { ...team, ...includeTeamMembers ? { members: teamMember } : {} }; }, updateTeam: async (teamId, data) => { const adapter = await getCurrentAdapter(baseAdapter); if ("id" in data) data.id = void 0; return await adapter.update({ model: "team", where: [{ field: "id", value: teamId }], update: { ...data } }); }, deleteTeam: async (teamId) => { const adapter = await getCurrentAdapter(baseAdapter); await adapter.deleteMany({ model: "teamMember", where: [{ field: "teamId", value: teamId }] }); return await adapter.delete({ model: "team", where: [{ field: "id", value: teamId }] }); }, listTeams: async (organizationId) => { return await (await getCurrentAdapter(baseAdapter)).findMany({ model: "team", where: [{ field: "organizationId", value: organizationId }] }); }, createTeamInvitation: async ({ email, role, teamId, organizationId, inviterId, expiresIn = 1e3 * 60 * 60 * 48 }) => { const adapter = await getCurrentAdapter(baseAdapter); const expiresAt = getDate(expiresIn); return await adapter.create({ model: "invitation", data: { email, role, organizationId, teamId, inviterId, status: "pending", expiresAt } }); }, setActiveTeam: async (sessionToken, teamId, ctx) => { return await context.internalAdapter.updateSession(sessionToken, { activeTeamId: teamId }); }, listTeamMembers: async (data) => { return await (await getCurrentAdapter(baseAdapter)).findMany({ model: "teamMember", where: [{ field: "teamId", value: data.teamId }] }); }, countTeamMembers: async (data) => { return await (await getCurrentAdapter(baseAdapter)).count({ model: "teamMember", where: [{ field: "teamId", value: data.teamId }] }); }, countMembers: async (data) => { return await (await getCurrentAdapter(baseAdapter)).count({ model: "member", where: [{ field: "organizationId", value: data.organizationId }] }); }, listTeamsByUser: async (data) => { return (await (await getCurrentAdapter(baseAdapter)).findMany({ model: "teamMember", where: [{ field: "userId", value: data.userId }], join: { team: true } })).map((result) => result.team); }, findTeamMember: async (data) => { return await (await getCurrentAdapter(baseAdapter)).findOne({ model: "teamMember", where: [{ field: "teamId", value: data.teamId }, { field: "userId", value: data.userId }] }); }, findOrCreateTeamMember: async (data) => { const adapter = await getCurrentAdapter(baseAdapter); const member = await adapter.findOne({ model: "teamMember", where: [{ field: "teamId", value: data.teamId }, { field: "userId", value: data.userId }] }); if (member) return member; return await adapter.create({ model: "teamMember", data: { teamId: data.teamId, userId: data.userId, createdAt: /* @__PURE__ */ new Date() } }); }, removeTeamMember: async (data) => { await (await getCurrentAdapter(baseAdapter)).deleteMany({ model: "teamMember", where: [{ field: "teamId", value: data.teamId }, { field: "userId", value: data.userId }] }); }, findInvitationsByTeamId: async (teamId) => { return await (await getCurrentAdapter(baseAdapter)).findMany({ model: "invitation", where: [{ field: "teamId", value: teamId }] }); }, listUserInvitations: async (email) => { return (await (await getCurrentAdapter(baseAdapter)).findMany({ model: "invitation", where: [{ field: "email", value: email.toLowerCase() }], join: { organization: true } })).map(({ organization, ...inv }) => ({ ...inv, organizationName: organization.name })); }, createInvitation: async ({ invitation, user }) => { const adapter = await getCurrentAdapter(baseAdapter); const expiresAt = getDate(options?.invitationExpiresIn || 3600 * 48, "sec"); return await adapter.create({ model: "invitation", data: { status: "pending", expiresAt, createdAt: /* @__PURE__ */ new Date(), inviterId: user.id, ...invitation, teamId: invitation.teamIds.length > 0 ? invitation.teamIds.join(",") : null } }); }, findInvitationById: async (id) => { return await (await getCurrentAdapter(baseAdapter)).findOne({ model: "invitation", where: [{ field: "id", value: id }] }); }, findPendingInvitation: async (data) => { return (await (await getCurrentAdapter(baseAdapter)).findMany({ model: "invitation", where: [ { field: "email", value: data.email.toLowerCase() }, { field: "organizationId", value: data.organizationId }, { field: "status", value: "pending" } ] })).filter((invite) => new Date(invite.expiresAt) > /* @__PURE__ */ new Date()); }, findPendingInvitations: async (data) => { return (await (await getCurrentAdapter(baseAdapter)).findMany({ model: "invitation", where: [{ field: "organizationId", value: data.organizationId }, { field: "status", value: "pending" }] })).filter((invite) => new Date(invite.expiresAt) > /* @__PURE__ */ new Date()); }, listInvitations: async (data) => { return await (await getCurrentAdapter(baseAdapter)).findMany({ model: "invitation", where: [{ field: "organizationId", value: data.organizationId }] }); }, updateInvitation: async (data) => { return await (await getCurrentAdapter(baseAdapter)).update({ model: "invitation", where: [{ field: "id", value: data.invitationId }], update: { status: data.status } }); } }; }; //#endregion export { getOrgAdapter }; //# sourceMappingURL=adapter.mjs.map