- Created lib/permissions.ts with four utility functions: - canAccessList: Check if user can view a list - canEditList: Check if user can edit a list or its items - canDeleteList: Check if user can delete a list (owner only) - getPermission: Get user's permission level for a list - Added comprehensive unit tests in lib/__tests__/permissions.test.ts - All 24 tests passing - Validates Requirements 4.3, 6.2, 6.3
165 lines
3.4 KiB
TypeScript
165 lines
3.4 KiB
TypeScript
'use server'
|
|
|
|
import { prisma } from './db'
|
|
|
|
export type Permission = 'owner' | 'editor' | 'viewer'
|
|
|
|
/**
|
|
* Check if a user can access a list (view it)
|
|
* Users can access a list if they are the owner or a collaborator
|
|
*
|
|
* @param userId - The ID of the user
|
|
* @param listId - The ID of the list
|
|
* @returns true if the user can access the list, false otherwise
|
|
*/
|
|
export async function canAccessList(
|
|
userId: string,
|
|
listId: string
|
|
): Promise<boolean> {
|
|
try {
|
|
if (!userId || !listId) {
|
|
return false
|
|
}
|
|
|
|
const list = await prisma.list.findFirst({
|
|
where: {
|
|
id: listId,
|
|
OR: [
|
|
{ ownerId: userId },
|
|
{
|
|
collaborators: {
|
|
some: {
|
|
userId: userId,
|
|
},
|
|
},
|
|
},
|
|
],
|
|
},
|
|
})
|
|
|
|
return list !== null
|
|
} catch (error) {
|
|
console.error('Error checking list access:', error)
|
|
return false
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if a user can edit a list or its items
|
|
* Users can edit if they are the owner or have editor permission
|
|
*
|
|
* @param userId - The ID of the user
|
|
* @param listId - The ID of the list
|
|
* @returns true if the user can edit the list, false otherwise
|
|
*/
|
|
export async function canEditList(
|
|
userId: string,
|
|
listId: string
|
|
): Promise<boolean> {
|
|
try {
|
|
if (!userId || !listId) {
|
|
return false
|
|
}
|
|
|
|
const list = await prisma.list.findFirst({
|
|
where: {
|
|
id: listId,
|
|
OR: [
|
|
{ ownerId: userId },
|
|
{
|
|
collaborators: {
|
|
some: {
|
|
userId: userId,
|
|
permission: 'editor',
|
|
},
|
|
},
|
|
},
|
|
],
|
|
},
|
|
})
|
|
|
|
return list !== null
|
|
} catch (error) {
|
|
console.error('Error checking list edit permission:', error)
|
|
return false
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if a user can delete a list
|
|
* Only the owner can delete a list
|
|
*
|
|
* @param userId - The ID of the user
|
|
* @param listId - The ID of the list
|
|
* @returns true if the user can delete the list, false otherwise
|
|
*/
|
|
export async function canDeleteList(
|
|
userId: string,
|
|
listId: string
|
|
): Promise<boolean> {
|
|
try {
|
|
if (!userId || !listId) {
|
|
return false
|
|
}
|
|
|
|
const list = await prisma.list.findFirst({
|
|
where: {
|
|
id: listId,
|
|
ownerId: userId,
|
|
},
|
|
})
|
|
|
|
return list !== null
|
|
} catch (error) {
|
|
console.error('Error checking list delete permission:', error)
|
|
return false
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the permission level a user has for a list
|
|
*
|
|
* @param userId - The ID of the user
|
|
* @param listId - The ID of the list
|
|
* @returns The permission level ('owner', 'editor', 'viewer') or null if no access
|
|
*/
|
|
export async function getPermission(
|
|
userId: string,
|
|
listId: string
|
|
): Promise<Permission | null> {
|
|
try {
|
|
if (!userId || !listId) {
|
|
return null
|
|
}
|
|
|
|
// Check if user is the owner
|
|
const ownedList = await prisma.list.findFirst({
|
|
where: {
|
|
id: listId,
|
|
ownerId: userId,
|
|
},
|
|
})
|
|
|
|
if (ownedList) {
|
|
return 'owner'
|
|
}
|
|
|
|
// Check if user is a collaborator
|
|
const collaborator = await prisma.collaborator.findFirst({
|
|
where: {
|
|
userId: userId,
|
|
listId: listId,
|
|
},
|
|
})
|
|
|
|
if (collaborator) {
|
|
return collaborator.permission as Permission
|
|
}
|
|
|
|
return null
|
|
} catch (error) {
|
|
console.error('Error getting user permission:', error)
|
|
return null
|
|
}
|
|
}
|