Member Management
Learn about managing workspace members, roles, and access control.
Member Schema
Database
The member management system uses a PostgreSQL table with the following structure:
Schema Definition
Database schema for workspace members:
export const workspaceMembers = pgTable(
"workspaceMembers",
{
// User reference
userId: text("user_id")
.notNull()
.references(() => users.id, { onDelete: "cascade" }),
// Workspace reference
workspaceId: text("workspace_id")
.notNull()
.references(() => workspaces.id, { onDelete: "cascade" }),
// Role assignment
roleId: text("role_id")
.notNull()
.references(() => roles.id),
// Timestamps
createdAt: timestamp("created_at").notNull().defaultNow(),
updatedAt: timestamp("updated_at"),
},
(t) => ({
pk: primaryKey({ columns: [t.userId, t.workspaceId] }),
})
)
Access Control
Authorization
The MemberProvider component handles workspace access control:
Member Provider
Authorization wrapper for workspace routes:
export async function MemberProvider({ children, slug }: MemberProviderProps) {
// 1. Check authentication
const { user } = await getCurrentUser()
if (!user) {
return redirect(createRoute("sign-in").href)
}
// 2. Verify workspace exists
const workspace = await db.query.workspaces.findFirst({
where: eq(workspaces.slug, slug),
with: {
members: {
columns: {
userId: true,
},
},
},
})
if (!workspace) {
return notFound()
}
// 3. Check membership
if (!workspace.members.some((member) => member.userId === user.id)) {
return (
<RestrictedContent
title="Unauthorized"
description="You are not authorized to access this workspace."
/>
)
}
return <>{children}</>
}
Member Operations
Update Member
Update member roles and permissions
const { server_updateMember } = useUpdateMember()
// Update member role
await server_updateMember({
role: "admin",
userId: member.id,
slug: workspace.slug,
})
Delete Member
Remove member from workspace
const { server_deleteMember } = useDeleteMember()
// Remove member
await server_deleteMember({
userId: member.id,
slug: workspace.slug,
})
Leave Workspace
Member leaves workspace voluntarily
const { server_leaveWorkspace } = useLeaveWorkspace()
// Leave workspace
await server_leaveWorkspace({
slug: workspace.slug,
})
Security Features
Access Control
- Role-based permissions
- Workspace membership verification
- Automatic cleanup on deletion
- Secure role updates
Protection
- Rate limiting on actions
- Input validation
- Permission checks
- Audit logging
Member management operations are protected by authentication, authorization, and rate limiting. Always verify permissions before performing sensitive actions.