fix(perms): Fix wrong table names in permissions scope

This commit is contained in:
2024-11-21 01:57:50 -05:00
parent 645b4b63aa
commit 07a04e9e8b
4 changed files with 64 additions and 42 deletions

View File

@@ -1,6 +1,8 @@
{ {
"conventionalCommits.scopes": [ "conventionalCommits.scopes": [
"homepage", "homepage",
"repo" "repo",
"auth",
"perms"
] ]
} }

View File

@@ -2,7 +2,7 @@ import { eq } from "drizzle-orm";
import { NextResponse } from "next/server"; import { NextResponse } from "next/server";
import { auth } from "@clerk/nextjs/server"; import { auth } from "@clerk/nextjs/server";
import { db } from "~/db"; import { db } from "~/db";
import { participants } from "~/db/schema"; import { participantsTable } from "~/db/schema";
export async function GET(request: Request) { export async function GET(request: Request) {
const { userId } = await auth(); const { userId } = await auth();
@@ -20,8 +20,8 @@ export async function GET(request: Request) {
const participantList = await db const participantList = await db
.select() .select()
.from(participants) .from(participantsTable)
.where(eq(participants.studyId, parseInt(studyId))); .where(eq(participantsTable.studyId, parseInt(studyId)));
return NextResponse.json(participantList); return NextResponse.json(participantList);
} }
@@ -37,7 +37,7 @@ export async function POST(request: Request) {
try { try {
const participant = await db const participant = await db
.insert(participants) .insert(participantsTable)
.values({ .values({
name, name,
studyId, studyId,

View File

@@ -9,6 +9,11 @@ export async function GET() {
return new NextResponse("Unauthorized", { status: 401 }); return new NextResponse("Unauthorized", { status: 401 });
} }
const permissions = await getUserPermissions(userId); try {
return NextResponse.json(Array.from(permissions)); 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 });
}
} }

View File

@@ -1,48 +1,63 @@
import { eq, and } from "drizzle-orm";
import { db } from "~/db"; import { db } from "~/db";
import { permissions, rolePermissions, userRoles } from "~/db/schema"; import {
import { eq } from "drizzle-orm"; permissionsTable,
userRolesTable,
rolePermissionsTable
} from "~/db/schema";
// Define permission codes
export const PERMISSIONS = { export const PERMISSIONS = {
VIEW_PARTICIPANT_NAMES: 'view_participant_names', VIEW_PARTICIPANT_NAMES: "view_participant_names",
CREATE_PARTICIPANT: 'create_participant', CREATE_PARTICIPANT: "create_participant",
DELETE_PARTICIPANT: 'delete_participant', DELETE_PARTICIPANT: "delete_participant",
CREATE_STUDY: 'create_study', CREATE_STUDY: "create_study",
DELETE_STUDY: 'delete_study', DELETE_STUDY: "delete_study",
MANAGE_ROLES: 'manage_roles', MANAGE_ROLES: "manage_roles",
} as const; } as const;
export type PermissionCode = keyof typeof PERMISSIONS; export type PermissionCode = keyof typeof PERMISSIONS;
// Cache user permissions export async function getUserPermissions(userId: string) {
const userPermissionsCache = new Map<string, Set<string>>(); // Get all permissions for the user through their roles
const userPermissions = await db
export async function getUserPermissions(userId: string): Promise<Set<string>> {
// Check cache first
const cached = userPermissionsCache.get(userId);
if (cached) return cached;
// Query permissions from database
const userPerms = await db
.select({ .select({
permissionCode: permissions.code, permissionCode: permissionsTable.code,
}) })
.from(userRoles) .from(userRolesTable)
.leftJoin(rolePermissions, eq(userRoles.roleId, rolePermissions.roleId)) .innerJoin(
.leftJoin(permissions, eq(rolePermissions.permissionId, permissions.id)) rolePermissionsTable,
.where(eq(userRoles.userId, userId)); eq(userRolesTable.roleId, rolePermissionsTable.roleId)
const permSet = new Set<string>(userPerms.map(p => p.permissionCode).filter((code): code is string => code !== null)); )
userPermissionsCache.set(userId, permSet); .innerJoin(
permissionsTable,
eq(rolePermissionsTable.permissionId, permissionsTable.id)
)
.where(eq(userRolesTable.userId, userId));
return permSet; return userPermissions.map(p => p.permissionCode);
} }
export async function hasPermission(userId: string, permissionCode: string): Promise<boolean> { export async function hasPermission(userId: string, permissionCode: string) {
const userPerms = await getUserPermissions(userId); const result = await db
return userPerms.has(permissionCode); .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 return result.length > 0;
export function clearUserPermissionsCache(userId: string) {
userPermissionsCache.delete(userId);
} }