diff --git a/.vscode/settings.json b/.vscode/settings.json index 171b326..f7d700f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,8 @@ { "conventionalCommits.scopes": [ "homepage", - "repo" + "repo", + "auth", + "perms" ] } \ No newline at end of file diff --git a/src/app/api/participants/route.ts b/src/app/api/participants/route.ts index 8cfe3aa..43c4285 100644 --- a/src/app/api/participants/route.ts +++ b/src/app/api/participants/route.ts @@ -2,7 +2,7 @@ import { eq } from "drizzle-orm"; import { NextResponse } from "next/server"; import { auth } from "@clerk/nextjs/server"; import { db } from "~/db"; -import { participants } from "~/db/schema"; +import { participantsTable } from "~/db/schema"; export async function GET(request: Request) { const { userId } = await auth(); @@ -20,8 +20,8 @@ export async function GET(request: Request) { const participantList = await db .select() - .from(participants) - .where(eq(participants.studyId, parseInt(studyId))); + .from(participantsTable) + .where(eq(participantsTable.studyId, parseInt(studyId))); return NextResponse.json(participantList); } @@ -37,7 +37,7 @@ export async function POST(request: Request) { try { const participant = await db - .insert(participants) + .insert(participantsTable) .values({ name, studyId, diff --git a/src/app/api/permissions/route.ts b/src/app/api/permissions/route.ts index 48fe8cf..c14011c 100644 --- a/src/app/api/permissions/route.ts +++ b/src/app/api/permissions/route.ts @@ -9,6 +9,11 @@ export async function GET() { return new NextResponse("Unauthorized", { status: 401 }); } - const permissions = await getUserPermissions(userId); - return NextResponse.json(Array.from(permissions)); + try { + const permissions = await getUserPermissions(userId); + return NextResponse.json(permissions); + } catch (error) { + console.error("Error fetching permissions:", error); + return new NextResponse("Internal Server Error", { status: 500 }); + } } diff --git a/src/lib/permissions.ts b/src/lib/permissions.ts index f772615..a784b1a 100644 --- a/src/lib/permissions.ts +++ b/src/lib/permissions.ts @@ -1,48 +1,63 @@ +import { eq, and } from "drizzle-orm"; import { db } from "~/db"; -import { permissions, rolePermissions, userRoles } from "~/db/schema"; -import { eq } from "drizzle-orm"; +import { + permissionsTable, + userRolesTable, + rolePermissionsTable +} from "~/db/schema"; -// Define permission codes export const PERMISSIONS = { - VIEW_PARTICIPANT_NAMES: 'view_participant_names', - CREATE_PARTICIPANT: 'create_participant', - DELETE_PARTICIPANT: 'delete_participant', - CREATE_STUDY: 'create_study', - DELETE_STUDY: 'delete_study', - MANAGE_ROLES: 'manage_roles', + VIEW_PARTICIPANT_NAMES: "view_participant_names", + CREATE_PARTICIPANT: "create_participant", + DELETE_PARTICIPANT: "delete_participant", + CREATE_STUDY: "create_study", + DELETE_STUDY: "delete_study", + MANAGE_ROLES: "manage_roles", } as const; export type PermissionCode = keyof typeof PERMISSIONS; -// Cache user permissions -const userPermissionsCache = new Map>(); - -export async function getUserPermissions(userId: string): Promise> { - // Check cache first - const cached = userPermissionsCache.get(userId); - if (cached) return cached; - - // Query permissions from database - const userPerms = await db +export async function getUserPermissions(userId: string) { + // Get all permissions for the user through their roles + const userPermissions = await db .select({ - permissionCode: permissions.code, + permissionCode: permissionsTable.code, }) - .from(userRoles) - .leftJoin(rolePermissions, eq(userRoles.roleId, rolePermissions.roleId)) - .leftJoin(permissions, eq(rolePermissions.permissionId, permissions.id)) - .where(eq(userRoles.userId, userId)); - const permSet = new Set(userPerms.map(p => p.permissionCode).filter((code): code is string => code !== null)); - userPermissionsCache.set(userId, permSet); - - return permSet; + .from(userRolesTable) + .innerJoin( + rolePermissionsTable, + eq(userRolesTable.roleId, rolePermissionsTable.roleId) + ) + .innerJoin( + permissionsTable, + eq(rolePermissionsTable.permissionId, permissionsTable.id) + ) + .where(eq(userRolesTable.userId, userId)); + + return userPermissions.map(p => p.permissionCode); } -export async function hasPermission(userId: string, permissionCode: string): Promise { - const userPerms = await getUserPermissions(userId); - return userPerms.has(permissionCode); -} +export async function hasPermission(userId: string, permissionCode: string) { + const result = await db + .select({ + id: permissionsTable.id, + }) + .from(userRolesTable) + .innerJoin( + rolePermissionsTable, + eq(userRolesTable.roleId, rolePermissionsTable.roleId) + ) + .innerJoin( + permissionsTable, + eq(rolePermissionsTable.permissionId, permissionsTable.id) + ) + .where( + and( + eq(userRolesTable.userId, userId), + eq(permissionsTable.code, permissionCode) + ) + ) + .limit(1); -// Clear cache for user -export function clearUserPermissionsCache(userId: string) { - userPermissionsCache.delete(userId); + return result.length > 0; }