el.xwx.moe/lib/api/controllers/links/linkId/updateLinkById.ts

176 lines
5.0 KiB
TypeScript
Raw Normal View History

2023-03-28 10:11:34 -05:00
import { prisma } from "@/lib/api/db";
import { LinkIncludingShortenedCollectionAndTags } from "@/types/global";
import { UsersAndCollections } from "@prisma/client";
import getPermission from "@/lib/api/getPermission";
2024-09-12 14:03:14 -05:00
import { moveFiles, removeFiles } from "@/lib/api/manageLinkFiles";
import isValidUrl from "@/lib/shared/isValidUrl";
2023-03-28 10:11:34 -05:00
2023-10-28 23:57:24 -05:00
export default async function updateLinkById(
userId: number,
linkId: number,
data: LinkIncludingShortenedCollectionAndTags
2023-05-27 11:29:39 -05:00
) {
if (!data || !data.collection.id)
2023-06-24 16:54:35 -05:00
return {
response: "Please choose a valid link and collection.",
status: 401,
};
2023-03-28 10:11:34 -05:00
2023-11-19 15:22:27 -06:00
const collectionIsAccessible = await getPermission({ userId, linkId });
2023-05-01 05:07:01 -05:00
2023-06-24 16:54:35 -05:00
const isCollectionOwner =
collectionIsAccessible?.ownerId === data.collection.ownerId &&
data.collection.ownerId === userId;
2023-05-01 05:07:01 -05:00
2024-02-07 08:48:40 -06:00
const canPinPermission = collectionIsAccessible?.members.some(
(e: UsersAndCollections) => e.userId === userId
);
2024-09-04 21:19:40 -05:00
// If the user is part of a collection, they can pin it to their dashboard
if (canPinPermission && data.pinnedBy && data.pinnedBy[0]) {
const updatedLink = await prisma.link.update({
where: {
id: linkId,
},
data: {
2024-02-07 08:48:40 -06:00
pinnedBy:
2024-09-04 21:19:40 -05:00
data?.pinnedBy && data.pinnedBy[0].id === userId
2024-02-07 08:48:40 -06:00
? { connect: { id: userId } }
: { disconnect: { id: userId } },
},
include: {
collection: true,
pinnedBy: isCollectionOwner
? {
2024-02-10 18:34:25 -06:00
where: { id: userId },
select: { id: true },
}
: undefined,
},
});
2024-09-04 21:19:40 -05:00
return { response: updatedLink, status: 200 };
}
2024-03-05 11:11:40 -06:00
const targetCollectionIsAccessible = await getPermission({
userId,
collectionId: data.collection.id,
});
const memberHasAccess = collectionIsAccessible?.members.some(
(e: UsersAndCollections) => e.userId === userId && e.canUpdate
);
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;
2024-07-18 09:46:21 -05:00
if (!targetCollectionMatchesData)
2024-03-05 11:11:40 -06:00
return {
response: "Target collection does not match the data.",
status: 401,
};
const unauthorizedSwitchCollection =
!isCollectionOwner && collectionIsAccessible?.id !== data.collection.id;
2024-02-07 08:48:40 -06:00
// 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)
2023-06-24 16:54:35 -05:00
return {
response: "Collection is not accessible.",
status: 401,
};
else {
2024-09-12 14:03:14 -05:00
const oldLink = await prisma.link.findUnique({
where: {
id: linkId,
},
});
if (
data.url &&
oldLink &&
oldLink?.url !== data.url &&
isValidUrl(data.url)
) {
2024-09-12 14:03:14 -05:00
await removeFiles(oldLink.id, oldLink.collectionId);
} else
return {
response: "Invalid URL.",
status: 401,
};
2024-09-12 14:03:14 -05:00
2023-06-24 16:54:35 -05:00
const updatedLink = await prisma.link.update({
where: {
id: linkId,
2023-03-28 10:11:34 -05:00
},
2023-06-24 16:54:35 -05:00
data: {
name: data.name,
2024-09-12 14:03:14 -05:00
url: data.url,
description: data.description,
2024-08-24 14:50:29 -05:00
icon: data.icon,
iconWeight: data.iconWeight,
color: data.color,
2024-09-12 14:03:14 -05:00
image: oldLink?.url !== data.url ? null : undefined,
pdf: oldLink?.url !== data.url ? null : undefined,
readable: oldLink?.url !== data.url ? null : undefined,
monolith: oldLink?.url !== data.url ? null : undefined,
preview: oldLink?.url !== data.url ? null : undefined,
collection: {
connect: {
id: data.collection.id,
},
},
2023-06-24 16:54:35 -05:00
tags: {
set: [],
connectOrCreate: data.tags.map((tag) => ({
2023-06-24 16:54:35 -05:00
where: {
name_ownerId: {
name: tag.name,
ownerId: data.collection.ownerId,
2023-06-24 16:54:35 -05:00
},
2023-03-28 10:11:34 -05:00
},
2023-06-24 16:54:35 -05:00
create: {
name: tag.name,
owner: {
connect: {
id: data.collection.ownerId,
2023-06-24 16:54:35 -05:00
},
2023-03-28 10:11:34 -05:00
},
},
2023-06-24 16:54:35 -05:00
})),
},
pinnedBy:
2024-09-11 01:29:50 -05:00
data?.pinnedBy && data.pinnedBy[0]?.id === userId
2023-06-24 16:54:35 -05:00
? { connect: { id: userId } }
: { disconnect: { id: userId } },
2023-03-28 10:11:34 -05:00
},
2023-06-24 16:54:35 -05:00
include: {
tags: true,
collection: true,
pinnedBy: isCollectionOwner
? {
2024-02-10 18:34:25 -06:00
where: { id: userId },
select: { id: true },
}
2023-06-24 16:54:35 -05:00
: undefined,
2023-06-13 14:19:37 -05:00
},
2023-06-24 16:54:35 -05:00
});
2023-03-28 10:11:34 -05:00
if (collectionIsAccessible?.id !== data.collection.id) {
2024-04-08 18:35:06 -05:00
await moveFiles(linkId, collectionIsAccessible?.id, data.collection.id);
2023-08-05 23:58:18 -05:00
}
2023-06-24 16:54:35 -05:00
return { response: updatedLink, status: 200 };
}
2023-03-28 10:11:34 -05:00
}