From cb5b1751c090d6b0eb80635b24ce3d510e739bbf Mon Sep 17 00:00:00 2001 From: daniel31x13 Date: Tue, 7 Nov 2023 08:03:35 -0500 Subject: [PATCH] bug fix --- components/Dropdown.tsx | 84 +++++----- .../migration/importFromHTMLFile.ts | 155 +++++++++--------- .../migration/importFromLinkwarden.ts | 151 ++++++++--------- .../users/userId/deleteUserById.ts | 87 +++++----- pages/api/v1/getToken.ts | 10 -- pages/api/v1/migration/index.ts | 2 +- types/global.ts | 2 +- 7 files changed, 243 insertions(+), 248 deletions(-) delete mode 100644 pages/api/v1/getToken.ts diff --git a/components/Dropdown.tsx b/components/Dropdown.tsx index 5ec8198..ac1ee59 100644 --- a/components/Dropdown.tsx +++ b/components/Dropdown.tsx @@ -60,51 +60,47 @@ export default function Dropdown({ } }, [points, dropdownHeight]); - return ( - (!points || pos) && ( - { - setDropdownHeight(e.height); - setDropdownWidth(e.width); - }} - style={ - points - ? { - position: "fixed", - top: `${pos?.y}px`, - left: `${pos?.x}px`, - } - : undefined - } - onClickOutside={onClickOutside} - className={`${ - className || "" - } py-1 shadow-md border border-sky-100 dark:border-neutral-700 bg-gray-50 dark:bg-neutral-800 rounded-md flex flex-col z-20`} - > - {items.map((e, i) => { - const inner = e && ( -
-
-

- {e.name} -

-
+ return !points || pos ? ( + { + setDropdownHeight(e.height); + setDropdownWidth(e.width); + }} + style={ + points + ? { + position: "fixed", + top: `${pos?.y}px`, + left: `${pos?.x}px`, + } + : undefined + } + onClickOutside={onClickOutside} + className={`${ + className || "" + } py-1 shadow-md border border-sky-100 dark:border-neutral-700 bg-gray-50 dark:bg-neutral-800 rounded-md flex flex-col z-20`} + > + {items.map((e, i) => { + const inner = e && ( +
+
+

{e.name}

- ); +
+ ); - return e && e.href ? ( - + return e && e.href ? ( + + {inner} + + ) : ( + e && ( +
{inner} - - ) : ( - e && ( -
- {inner} -
- ) - ); - })} - - ) - ); +
+ ) + ); + })} +
+ ) : null; } diff --git a/lib/api/controllers/migration/importFromHTMLFile.ts b/lib/api/controllers/migration/importFromHTMLFile.ts index 36c48c0..7791777 100644 --- a/lib/api/controllers/migration/importFromHTMLFile.ts +++ b/lib/api/controllers/migration/importFromHTMLFile.ts @@ -7,94 +7,97 @@ export default async function importFromHTMLFile( userId: number, rawData: string ) { - try { - const dom = new JSDOM(rawData); - const document = dom.window.document; + const dom = new JSDOM(rawData); + const document = dom.window.document; - const folders = document.querySelectorAll("H3"); + const folders = document.querySelectorAll("H3"); - // @ts-ignore - for (const folder of folders) { - const findCollection = await prisma.user.findUnique({ - where: { - id: userId, - }, - select: { - collections: { + await prisma + .$transaction( + async () => { + // @ts-ignore + for (const folder of folders) { + const findCollection = await prisma.user.findUnique({ where: { - name: folder.textContent.trim(), + id: userId, }, - }, - }, - }); + select: { + collections: { + where: { + name: folder.textContent.trim(), + }, + }, + }, + }); - const checkIfCollectionExists = findCollection?.collections[0]; + const checkIfCollectionExists = findCollection?.collections[0]; - let collectionId = findCollection?.collections[0]?.id; + let collectionId = findCollection?.collections[0]?.id; - if (!checkIfCollectionExists || !collectionId) { - const newCollection = await prisma.collection.create({ - data: { - name: folder.textContent.trim(), - description: "", - color: "#0ea5e9", - isPublic: false, - ownerId: userId, - }, - }); + if (!checkIfCollectionExists || !collectionId) { + const newCollection = await prisma.collection.create({ + data: { + name: folder.textContent.trim(), + description: "", + color: "#0ea5e9", + isPublic: false, + ownerId: userId, + }, + }); - createFolder({ filePath: `archives/${newCollection.id}` }); + createFolder({ filePath: `archives/${newCollection.id}` }); - collectionId = newCollection.id; - } + collectionId = newCollection.id; + } - createFolder({ filePath: `archives/${collectionId}` }); + createFolder({ filePath: `archives/${collectionId}` }); - const bookmarks = folder.nextElementSibling.querySelectorAll("A"); - for (const bookmark of bookmarks) { - await prisma.link.create({ - data: { - name: bookmark.textContent.trim(), - url: bookmark.getAttribute("HREF"), - tags: bookmark.getAttribute("TAGS") - ? { - connectOrCreate: bookmark - .getAttribute("TAGS") - .split(",") - .map((tag: string) => - tag - ? { - where: { - name_ownerId: { - name: tag.trim(), - ownerId: userId, - }, - }, - create: { - name: tag.trim(), - owner: { - connect: { - id: userId, + const bookmarks = folder.nextElementSibling.querySelectorAll("A"); + for (const bookmark of bookmarks) { + await prisma.link.create({ + data: { + name: bookmark.textContent.trim(), + url: bookmark.getAttribute("HREF"), + tags: bookmark.getAttribute("TAGS") + ? { + connectOrCreate: bookmark + .getAttribute("TAGS") + .split(",") + .map((tag: string) => + tag + ? { + where: { + name_ownerId: { + name: tag.trim(), + ownerId: userId, + }, }, - }, - }, - } - : undefined - ), - } - : undefined, - description: bookmark.getAttribute("DESCRIPTION") - ? bookmark.getAttribute("DESCRIPTION") - : "", - collectionId: collectionId, - createdAt: new Date(), - }, - }); - } - } - } catch (err) { - console.log(err); - } + create: { + name: tag.trim(), + owner: { + connect: { + id: userId, + }, + }, + }, + } + : undefined + ), + } + : undefined, + description: bookmark.getAttribute("DESCRIPTION") + ? bookmark.getAttribute("DESCRIPTION") + : "", + collectionId: collectionId, + createdAt: new Date(), + }, + }); + } + } + }, + { timeout: 30000 } + ) + .catch((err) => console.log(err)); return { response: "Success.", status: 200 }; } diff --git a/lib/api/controllers/migration/importFromLinkwarden.ts b/lib/api/controllers/migration/importFromLinkwarden.ts index eb68e7e..78af4e3 100644 --- a/lib/api/controllers/migration/importFromLinkwarden.ts +++ b/lib/api/controllers/migration/importFromLinkwarden.ts @@ -5,87 +5,88 @@ import createFolder from "@/lib/api/storage/createFolder"; export default async function getData(userId: number, rawData: string) { const data: Backup = JSON.parse(rawData); - console.log(typeof data); + await prisma + .$transaction( + async () => { + // Import collections + for (const e of data.collections) { + e.name = e.name.trim(); - // Import collections - try { - for (const e of data.collections) { - e.name = e.name.trim(); - - const findCollection = await prisma.user.findUnique({ - where: { - id: userId, - }, - select: { - collections: { + const findCollection = await prisma.user.findUnique({ where: { - name: e.name, + id: userId, }, - }, - }, - }); - - const checkIfCollectionExists = findCollection?.collections[0]; - - let collectionId = findCollection?.collections[0]?.id; - - if (!checkIfCollectionExists) { - const newCollection = await prisma.collection.create({ - data: { - owner: { - connect: { - id: userId, - }, - }, - name: e.name, - description: e.description, - color: e.color, - }, - }); - - createFolder({ filePath: `archives/${newCollection.id}` }); - - collectionId = newCollection.id; - } - - // Import Links - for (const link of e.links) { - const newLink = await prisma.link.create({ - data: { - url: link.url, - name: link.name, - description: link.description, - collection: { - connect: { - id: collectionId, - }, - }, - // Import Tags - tags: { - connectOrCreate: link.tags.map((tag) => ({ + select: { + collections: { where: { - name_ownerId: { - name: tag.name.trim(), - ownerId: userId, - }, + name: e.name, }, - create: { - name: tag.name.trim(), - owner: { - connect: { - id: userId, - }, - }, - }, - })), + }, }, - }, - }); - } - } - } catch (err) { - console.log(err); - } + }); + + const checkIfCollectionExists = findCollection?.collections[0]; + + let collectionId = findCollection?.collections[0]?.id; + + if (!checkIfCollectionExists) { + const newCollection = await prisma.collection.create({ + data: { + owner: { + connect: { + id: userId, + }, + }, + name: e.name, + description: e.description, + color: e.color, + }, + }); + + createFolder({ filePath: `archives/${newCollection.id}` }); + + collectionId = newCollection.id; + } + + // Import Links + for (const link of e.links) { + const newLink = await prisma.link.create({ + data: { + url: link.url, + name: link.name, + description: link.description, + collection: { + connect: { + id: collectionId, + }, + }, + // Import Tags + tags: { + connectOrCreate: link.tags.map((tag) => ({ + where: { + name_ownerId: { + name: tag.name.trim(), + ownerId: userId, + }, + }, + create: { + name: tag.name.trim(), + owner: { + connect: { + id: userId, + }, + }, + }, + })), + }, + }, + }); + } + } + }, + { timeout: 30000 } + ) + .catch((err) => console.log(err)); return { response: "Success.", status: 200 }; } diff --git a/lib/api/controllers/users/userId/deleteUserById.ts b/lib/api/controllers/users/userId/deleteUserById.ts index 28e43a1..f072e65 100644 --- a/lib/api/controllers/users/userId/deleteUserById.ts +++ b/lib/api/controllers/users/userId/deleteUserById.ts @@ -32,56 +32,61 @@ export default async function deleteUserById( } // Delete the user and all related data within a transaction - await prisma.$transaction(async (prisma) => { - // Delete whitelisted users - await prisma.whitelistedUser.deleteMany({ - where: { userId }, - }); + await prisma + .$transaction( + async (prisma) => { + // Delete whitelisted users + await prisma.whitelistedUser.deleteMany({ + where: { userId }, + }); - // Delete links - await prisma.link.deleteMany({ - where: { collection: { ownerId: userId } }, - }); + // Delete links + await prisma.link.deleteMany({ + where: { collection: { ownerId: userId } }, + }); - // Delete tags - await prisma.tag.deleteMany({ - where: { ownerId: userId }, - }); + // Delete tags + await prisma.tag.deleteMany({ + where: { ownerId: userId }, + }); - // Find collections that the user owns - const collections = await prisma.collection.findMany({ - where: { ownerId: userId }, - }); + // Find collections that the user owns + const collections = await prisma.collection.findMany({ + where: { ownerId: userId }, + }); - for (const collection of collections) { - // Delete related users and collections relations - await prisma.usersAndCollections.deleteMany({ - where: { collectionId: collection.id }, - }); + for (const collection of collections) { + // Delete related users and collections relations + await prisma.usersAndCollections.deleteMany({ + where: { collectionId: collection.id }, + }); - // Delete archive folders - await removeFolder({ filePath: `archives/${collection.id}` }); - } + // Delete archive folders + removeFolder({ filePath: `archives/${collection.id}` }); + } - // Delete collections after cleaning up related data - await prisma.collection.deleteMany({ - where: { ownerId: userId }, - }); + // Delete collections after cleaning up related data + await prisma.collection.deleteMany({ + where: { ownerId: userId }, + }); - // Delete subscription - if (process.env.STRIPE_SECRET_KEY) - await prisma.subscription.delete({ - where: { userId }, - }); + // Delete subscription + if (process.env.STRIPE_SECRET_KEY) + await prisma.subscription.delete({ + where: { userId }, + }); - // Delete user's avatar - await removeFile({ filePath: `uploads/avatar/${userId}.jpg` }); + // Delete user's avatar + await removeFile({ filePath: `uploads/avatar/${userId}.jpg` }); - // Finally, delete the user - await prisma.user.delete({ - where: { id: userId }, - }); - }); + // Finally, delete the user + await prisma.user.delete({ + where: { id: userId }, + }); + }, + { timeout: 20000 } + ) + .catch((err) => console.log(err)); if (process.env.STRIPE_SECRET_KEY) { const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, { diff --git a/pages/api/v1/getToken.ts b/pages/api/v1/getToken.ts deleted file mode 100644 index 0143d89..0000000 --- a/pages/api/v1/getToken.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { NextApiRequest, NextApiResponse } from "next"; -import { getToken } from "next-auth/jwt"; - -export default async (req: NextApiRequest, res: NextApiResponse) => { - // if using `NEXTAUTH_SECRET` env variable, we detect it, and you won't actually need to `secret` - // const token = await getToken({ req }) - // const token = await getToken({ req }); - // console.log("JSON Web Token", token); - // res.end(); -}; diff --git a/pages/api/v1/migration/index.ts b/pages/api/v1/migration/index.ts index 4afd7e7..e950563 100644 --- a/pages/api/v1/migration/index.ts +++ b/pages/api/v1/migration/index.ts @@ -8,7 +8,7 @@ import verifyUser from "@/lib/api/verifyUser"; export const config = { api: { bodyParser: { - sizeLimit: process.env.IMPORT_SIZE_LIMIT || "2mb", + sizeLimit: `${process.env.IMPORT_SIZE_LIMIT || "5"}mb`, }, }, }; diff --git a/types/global.ts b/types/global.ts index ce461e3..26058cf 100644 --- a/types/global.ts +++ b/types/global.ts @@ -29,7 +29,7 @@ export interface Member { } export interface CollectionIncludingMembersAndLinkCount - extends Omit { + extends Omit { id?: number; ownerId?: number; createdAt?: string;