import { prisma } from "@/lib/api/db"; import { LinkIncludingShortenedCollectionAndTags } from "@/types/global"; import { UsersAndCollections } from "@prisma/client"; import getPermission from "@/lib/api/getPermission"; import { moveFiles } from "@/lib/api/manageLinkFiles"; export default async function updateLinkById( userId: number, linkId: number, data: LinkIncludingShortenedCollectionAndTags ) { if (!data || !data.collection.id) return { response: "Please choose a valid link and collection.", status: 401, }; const collectionIsAccessible = await getPermission({ userId, linkId }); const isCollectionOwner = collectionIsAccessible?.ownerId === data.collection.ownerId && data.collection.ownerId === userId; const canPinPermission = collectionIsAccessible?.members.some( (e: UsersAndCollections) => e.userId === userId ); // If the user is able to create a link, they can pin it to their dashboard only. if (canPinPermission) { const updatedLink = await prisma.link.update({ where: { id: linkId, }, data: { pinnedBy: data?.pinnedBy && data.pinnedBy[0] ? { connect: { id: userId } } : { disconnect: { id: userId } }, }, include: { collection: true, pinnedBy: isCollectionOwner ? { where: { id: userId }, select: { id: true }, } : undefined, }, }); return { response: updatedLink, status: 200 }; } const targetCollectionIsAccessible = await getPermission({ userId, collectionId: data.collection.id, }); const memberHasAccess = collectionIsAccessible?.members.some( (e: UsersAndCollections) => e.userId === userId && e.canUpdate ); const targetCollectionsAccessible = targetCollectionIsAccessible?.ownerId === userId; const targetCollectionMatchesData = data.collection.id ? data.collection.id === targetCollectionIsAccessible?.id : true && data.collection.name ? data.collection.name === targetCollectionIsAccessible?.name : true && data.collection.ownerId ? data.collection.ownerId === targetCollectionIsAccessible?.ownerId : true; if (!targetCollectionsAccessible) return { response: "Target collection is not accessible.", status: 401, }; else if (!targetCollectionMatchesData) return { response: "Target collection does not match the data.", status: 401, }; const unauthorizedSwitchCollection = !isCollectionOwner && collectionIsAccessible?.id !== data.collection.id; // Makes sure collection members (non-owners) cannot move a link to/from a collection. if (unauthorizedSwitchCollection) return { response: "You can't move a link to/from a collection you don't own.", status: 401, }; else if (collectionIsAccessible?.ownerId !== userId && !memberHasAccess) return { response: "Collection is not accessible.", status: 401, }; else { const updatedLink = await prisma.link.update({ where: { id: linkId, }, data: { name: data.name, description: data.description, collection: { connect: { id: data.collection.id, }, }, tags: { set: [], connectOrCreate: data.tags.map((tag) => ({ where: { name_ownerId: { name: tag.name, ownerId: data.collection.ownerId, }, }, create: { name: tag.name, owner: { connect: { id: data.collection.ownerId, }, }, }, })), }, pinnedBy: data?.pinnedBy && data.pinnedBy[0] ? { connect: { id: userId } } : { disconnect: { id: userId } }, }, include: { tags: true, collection: true, pinnedBy: isCollectionOwner ? { where: { id: userId }, select: { id: true }, } : undefined, }, }); if (collectionIsAccessible?.id !== data.collection.id) { await moveFiles(linkId, collectionIsAccessible?.id, data.collection.id); } return { response: updatedLink, status: 200 }; } }