From 0ce97f0b6406fddc946f910760892356a0a0f47b Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 20 May 2023 22:55:00 +0330 Subject: [PATCH] added update account functionality --- components/Modal/UserSettings.tsx | 91 +++++--- components/Navbar.tsx | 8 +- lib/api/controllers/links/postLink.ts | 7 + lib/api/controllers/users/getUsers.ts | 22 +- lib/api/controllers/users/updateUser.ts | 31 +++ package.json | 2 + pages/api/routes/users/index.ts | 5 +- .../migration.sql | 4 - .../migration.sql | 3 + prisma/schema.prisma | 2 +- store/account.ts | 18 ++ types/global.ts | 7 + yarn.lock | 206 +++++++++++++++++- 13 files changed, 345 insertions(+), 61 deletions(-) create mode 100644 lib/api/controllers/users/updateUser.ts delete mode 100644 prisma/migrations/20230518175141_updated_user_model/migration.sql rename prisma/migrations/{20230427184353_init => 20230520142249_init}/migration.sql (95%) diff --git a/components/Modal/UserSettings.tsx b/components/Modal/UserSettings.tsx index 4dfe16f..323ea77 100644 --- a/components/Modal/UserSettings.tsx +++ b/components/Modal/UserSettings.tsx @@ -8,27 +8,43 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faCircleUser, faClose } from "@fortawesome/free-solid-svg-icons"; import Checkbox from "../Checkbox"; import useAccountStore from "@/store/account"; +import { AccountSettings } from "@/types/global"; type Props = { toggleSettingsModal: Function; }; export default function UserSettings({ toggleSettingsModal }: Props) { - const { account } = useAccountStore(); - const [collectionProtection, setCollectionProtection] = useState(false); + const { account, updateAccount } = useAccountStore(); + + let initialUser = { + name: account.name, + email: account.email, + collectionProtection: account.collectionProtection, + whitelistedUsers: account.whitelistedUsers, + }; + + const [user, setUser] = useState(initialUser); - const [name, setName] = useState(account.name); - const [email, setEmail] = useState(account.email); const [selectedFile, setSelectedFile] = useState(null); - const handleFileChange = async (e) => { - const file = e.target.files[0]; - setSelectedFile(file); + const handleFileChange = (e: any) => { + setSelectedFile(e.target.files[0]); + }; + + const stateIsTampered = () => { + return JSON.stringify(user) !== JSON.stringify(initialUser); }; const submit = async () => { - // const response = await addLink(newLink as NewLink); - // if (response) toggleSettingsModal(); + updateAccount(user); + + initialUser = { + name: account.name, + email: account.email, + collectionProtection: account.collectionProtection, + whitelistedUsers: account.whitelistedUsers, + }; }; return ( @@ -43,8 +59,8 @@ export default function UserSettings({ toggleSettingsModal }: Props) {

Display Name

setName(e.target.value)} + value={user.name} + onChange={(e) => setUser({ ...user, name: e.target.value })} className="w-full rounded-md p-2 border-sky-100 border-solid border outline-none focus:border-sky-500 duration-100" /> @@ -53,8 +69,8 @@ export default function UserSettings({ toggleSettingsModal }: Props) {

Email

setEmail(e.target.value)} + value={user.email} + onChange={(e) => setUser({ ...user, email: e.target.value })} className="w-full rounded-md p-2 border-sky-100 border-solid border outline-none focus:border-sky-500 duration-100" /> @@ -70,12 +86,12 @@ export default function UserSettings({ toggleSettingsModal }: Props) { -
+ {/*

Profile Photo

- {/* Image goes here */} + // Image goes here
-
+ */}
@@ -119,30 +135,35 @@ export default function UserSettings({ toggleSettingsModal }: Props) {

Privacy Settings

setCollectionProtection(!collectionProtection)} + onClick={() => + setUser({ ...user, collectionProtection: !user.collectionProtection }) + } /> -
-
- Manage Allowed Users + {user.collectionProtection ? ( +
+

+ Please enter the email addresses of the users who are allowed to add + you to additional collections in the box below, separated by spaces. +

+
-
+ ) : null} -
- Apply Settings -
+ {stateIsTampered() ? ( +
+ Apply Settings +
+ ) : null}
); } diff --git a/components/Navbar.tsx b/components/Navbar.tsx index 4238318..0787e58 100644 --- a/components/Navbar.tsx +++ b/components/Navbar.tsx @@ -5,7 +5,6 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { signOut } from "next-auth/react"; -import { useSession } from "next-auth/react"; import { faPlus, faCircleUser, @@ -23,14 +22,13 @@ import Sidebar from "@/components/Sidebar"; import { useRouter } from "next/router"; import Search from "@/components/Search"; import UserSettings from "./Modal/UserSettings"; +import useAccountStore from "@/store/account"; export default function () { - const { data: session } = useSession(); + const { account } = useAccountStore(); const [profileDropdown, setProfileDropdown] = useState(false); - const user = session?.user; - const [linkModal, setLinkModal] = useState(false); const [settingsModal, setSettingsModal] = useState(false); const [sidebar, setSidebar] = useState(false); @@ -86,7 +84,7 @@ export default function () { />

- {user?.name} + {account.name}

diff --git a/lib/api/controllers/links/postLink.ts b/lib/api/controllers/links/postLink.ts index 26eb2dc..331ddac 100644 --- a/lib/api/controllers/links/postLink.ts +++ b/lib/api/controllers/links/postLink.ts @@ -10,6 +10,7 @@ import archive from "../../archive"; import { Link, UsersAndCollections } from "@prisma/client"; import AES from "crypto-js/aes"; import getPermission from "@/lib/api/getPermission"; +import { existsSync, mkdirSync } from "fs"; export default async function (link: ExtendedLink, userId: number) { link.collection.name = link.collection.name.trim(); @@ -100,6 +101,12 @@ export default async function (link: ExtendedLink, userId: number) { include: { tags: true, collection: true }, }); + const collectionPath = `data/archives/${updatedLink.collection.id}`; + if (!existsSync(collectionPath)) + mkdirSync(collectionPath, { recursive: true }); + + console.log(updatedLink); + archive(updatedLink.url, updatedLink.collectionId, updatedLink.id); return { response: updatedLink, status: 200 }; diff --git a/lib/api/controllers/users/getUsers.ts b/lib/api/controllers/users/getUsers.ts index 1c4f622..4237b18 100644 --- a/lib/api/controllers/users/getUsers.ts +++ b/lib/api/controllers/users/getUsers.ts @@ -12,21 +12,19 @@ export default async function (lookupEmail: string, isSelf: boolean) { }, }); + if (!user) return { response: "User not found." || null, status: 404 }; + + const { password, ...unsensitiveInfo } = user; + const data = isSelf - ? { - // If user is requesting its data - id: user?.id, - name: user?.name, - email: user?.email, - } + ? // If user is requesting its own data + unsensitiveInfo : { // If user is requesting someone elses data - id: user?.id, - name: user?.name, - email: user?.email, + id: unsensitiveInfo.id, + name: unsensitiveInfo.name, + email: unsensitiveInfo.email, }; - const statusCode = user?.id ? 200 : 404; - - return { response: data || null, status: statusCode }; + return { response: data || null, status: 200 }; } diff --git a/lib/api/controllers/users/updateUser.ts b/lib/api/controllers/users/updateUser.ts new file mode 100644 index 0000000..b075afc --- /dev/null +++ b/lib/api/controllers/users/updateUser.ts @@ -0,0 +1,31 @@ +// Copyright (C) 2022-present Daniel31x13 +// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3. +// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// You should have received a copy of the GNU General Public License along with this program. If not, see . + +import { prisma } from "@/lib/api/db"; +import { AccountSettings } from "@/types/global"; + +export default async function (user: AccountSettings, userId: number) { + console.log(typeof user); + + const updatedUser = await prisma.user.update({ + where: { + id: userId, + }, + data: { + name: user.name, + email: user.email, + collectionProtection: user.collectionProtection, + whitelistedUsers: user.whitelistedUsers, + }, + select: { + name: true, + email: true, + collectionProtection: true, + whitelistedUsers: true, + }, + }); + + return { response: updatedUser, status: 200 }; +} diff --git a/package.json b/package.json index f35dbbf..7eaa53d 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "crypto-js": "^4.1.1", "eslint": "8.33.0", "eslint-config-next": "13.1.6", + "multer": "^1.4.5-lts.1", "next": "13.1.6", "next-auth": "^4.19.1", "puppeteer": "^19.8.0", @@ -41,6 +42,7 @@ }, "devDependencies": { "@types/bcrypt": "^5.0.0", + "@types/multer": "^1.4.7", "autoprefixer": "^10.4.13", "postcss": "^8.4.21", "prisma": "^4.9.0", diff --git a/pages/api/routes/users/index.ts b/pages/api/routes/users/index.ts index df060c0..75ca851 100644 --- a/pages/api/routes/users/index.ts +++ b/pages/api/routes/users/index.ts @@ -7,6 +7,7 @@ import type { NextApiRequest, NextApiResponse } from "next"; import { getServerSession } from "next-auth/next"; import { authOptions } from "pages/api/auth/[...nextauth]"; import getUsers from "@/lib/api/controllers/users/getUsers"; +import updateUser from "@/lib/api/controllers/users/updateUser"; export default async function (req: NextApiRequest, res: NextApiResponse) { const session = await getServerSession(req, res, authOptions); @@ -18,9 +19,11 @@ export default async function (req: NextApiRequest, res: NextApiResponse) { const lookupEmail = req.query.email as string; const isSelf = session.user.email === lookupEmail ? true : false; - // get unsensitive user info by email if (req.method === "GET") { const users = await getUsers(lookupEmail, isSelf); return res.status(users.status).json({ response: users.response }); + } else if (req.method === "PUT" && !req.body.password) { + const updated = await updateUser(req.body, session.user.id); + return res.status(updated.status).json({ response: updated.response }); } } diff --git a/prisma/migrations/20230518175141_updated_user_model/migration.sql b/prisma/migrations/20230518175141_updated_user_model/migration.sql deleted file mode 100644 index 23d2cf5..0000000 --- a/prisma/migrations/20230518175141_updated_user_model/migration.sql +++ /dev/null @@ -1,4 +0,0 @@ --- AlterTable -ALTER TABLE "User" ADD COLUMN "collectionProtection" BOOLEAN NOT NULL DEFAULT true, -ADD COLUMN "profilePhotoPath" TEXT NOT NULL DEFAULT '', -ADD COLUMN "whitelistedUsers" TEXT[] DEFAULT ARRAY[]::TEXT[]; diff --git a/prisma/migrations/20230427184353_init/migration.sql b/prisma/migrations/20230520142249_init/migration.sql similarity index 95% rename from prisma/migrations/20230427184353_init/migration.sql rename to prisma/migrations/20230520142249_init/migration.sql index 03e3bce..6cb80d7 100644 --- a/prisma/migrations/20230427184353_init/migration.sql +++ b/prisma/migrations/20230520142249_init/migration.sql @@ -4,6 +4,9 @@ CREATE TABLE "User" ( "name" TEXT NOT NULL, "email" TEXT NOT NULL, "password" TEXT NOT NULL, + "collectionProtection" BOOLEAN NOT NULL DEFAULT false, + "whitelistedUsers" TEXT[] DEFAULT ARRAY[]::TEXT[], + "profilePhotoPath" TEXT NOT NULL DEFAULT '', "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT "User_pkey" PRIMARY KEY ("id") diff --git a/prisma/schema.prisma b/prisma/schema.prisma index f6ab35f..e1c7e7f 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -20,7 +20,7 @@ model User { collections Collection[] tags Tag[] collectionsJoined UsersAndCollections[] - collectionProtection Boolean @default(true) + collectionProtection Boolean @default(false) whitelistedUsers String[] @default([]) profilePhotoPath String @default("") createdAt DateTime @default(now()) diff --git a/store/account.ts b/store/account.ts index cf31150..03f3139 100644 --- a/store/account.ts +++ b/store/account.ts @@ -5,10 +5,13 @@ import { create } from "zustand"; import { User } from "@prisma/client"; +import { AccountSettings } from "@/types/global"; +import { useSession } from "next-auth/react"; type AccountStore = { account: User; setAccount: (email: string) => void; + updateAccount: (user: AccountSettings) => void; }; const useAccountStore = create()((set) => ({ @@ -20,6 +23,21 @@ const useAccountStore = create()((set) => ({ console.log(data); + if (response.ok) set({ account: data.response }); + }, + updateAccount: async (user) => { + const response = await fetch("/api/routes/users", { + method: "PUT", + body: JSON.stringify(user), + headers: { + "Content-Type": "application/json", + }, + }); + + const data = await response.json(); + + console.log(data); + if (response.ok) set({ account: data.response }); }, })); diff --git a/types/global.ts b/types/global.ts index c9ec1ac..1200961 100644 --- a/types/global.ts +++ b/types/global.ts @@ -57,3 +57,10 @@ export type SearchSettings = { tags: boolean; }; }; + +export type AccountSettings = { + name: string; + email: string; + collectionProtection: boolean; + whitelistedUsers: string[]; +}; diff --git a/yarn.lock b/yarn.lock index ff456d5..b05ad33 100644 --- a/yarn.lock +++ b/yarn.lock @@ -466,6 +466,14 @@ dependencies: "@types/node" "*" +"@types/body-parser@*": + version "1.19.2" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" + integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== + dependencies: + "@types/connect" "*" + "@types/node" "*" + "@types/chrome@^0.0.224": version "0.0.224" resolved "https://registry.yarnpkg.com/@types/chrome/-/chrome-0.0.224.tgz#0138497299eaaf261d61ece62d7d6af3868ce856" @@ -474,6 +482,13 @@ "@types/filesystem" "*" "@types/har-format" "*" +"@types/connect@*": + version "3.4.35" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" + integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== + dependencies: + "@types/node" "*" + "@types/crypto-js@^4.1.1": version "4.1.1" resolved "https://registry.yarnpkg.com/@types/crypto-js/-/crypto-js-4.1.1.tgz#602859584cecc91894eb23a4892f38cfa927890d" @@ -486,6 +501,26 @@ dependencies: "@types/ms" "*" +"@types/express-serve-static-core@^4.17.33": + version "4.17.35" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.35.tgz#c95dd4424f0d32e525d23812aa8ab8e4d3906c4f" + integrity sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + "@types/send" "*" + +"@types/express@*": + version "4.17.17" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.17.tgz#01d5437f6ef9cfa8668e616e13c2f2ac9a491ae4" + integrity sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.33" + "@types/qs" "*" + "@types/serve-static" "*" + "@types/filesystem@*": version "0.0.32" resolved "https://registry.yarnpkg.com/@types/filesystem/-/filesystem-0.0.32.tgz#307df7cc084a2293c3c1a31151b178063e0a8edf" @@ -513,11 +548,28 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== +"@types/mime@*": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10" + integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA== + +"@types/mime@^1": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" + integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== + "@types/ms@*": version "0.7.31" resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197" integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== +"@types/multer@^1.4.7": + version "1.4.7" + resolved "https://registry.yarnpkg.com/@types/multer/-/multer-1.4.7.tgz#89cf03547c28c7bbcc726f029e2a76a7232cc79e" + integrity sha512-/SNsDidUFCvqqcWDwxv2feww/yqhNeTRL5CVoL3jU4Goc4kKEL10T7Eye65ZqPNi4HRx8sAEX59pV1aEH7drNA== + dependencies: + "@types/express" "*" + "@types/node@*": version "18.11.19" resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.19.tgz#35e26df9ec441ab99d73e99e9aca82935eea216d" @@ -538,6 +590,16 @@ resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf" integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== +"@types/qs@*": + version "6.9.7" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" + integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== + +"@types/range-parser@*": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" + integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== + "@types/react-dom@18.0.10": version "18.0.10" resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.10.tgz#3b66dec56aa0f16a6cc26da9e9ca96c35c0b4352" @@ -566,6 +628,22 @@ resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39" integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== +"@types/send@*": + version "0.17.1" + resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.1.tgz#ed4932b8a2a805f1fe362a70f4e62d0ac994e301" + integrity sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + +"@types/serve-static@*": + version "1.15.1" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.1.tgz#86b1753f0be4f9a1bee68d459fcda5be4ea52b5d" + integrity sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ== + dependencies: + "@types/mime" "*" + "@types/node" "*" + "@types/yauzl@^2.9.1": version "2.10.0" resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.10.0.tgz#b3248295276cf8c6f153ebe6a9aba0c988cb2599" @@ -695,6 +773,11 @@ anymatch@~3.1.2: normalize-path "^3.0.0" picomatch "^2.0.4" +append-field@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/append-field/-/append-field-1.0.0.tgz#1e3440e915f0b1203d23748e78edd7b9b5b43e56" + integrity sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw== + "aproba@^1.0.3 || ^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" @@ -882,6 +965,11 @@ buffer-crc32@~0.2.3: resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + buffer@^5.2.1, buffer@^5.5.0: version "5.7.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" @@ -890,6 +978,13 @@ buffer@^5.2.1, buffer@^5.5.0: base64-js "^1.3.1" ieee754 "^1.1.13" +busboy@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" + integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== + dependencies: + streamsearch "^1.1.0" + call-bind@^1.0.0, call-bind@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" @@ -1012,6 +1107,16 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== +concat-stream@^1.5.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + console-control-strings@^1.0.0, console-control-strings@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" @@ -1027,6 +1132,11 @@ cookie@^0.5.0: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + cosmiconfig@8.1.3: version "8.1.3" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.1.3.tgz#0e614a118fcc2d9e5afc2f87d53cd09931015689" @@ -1978,7 +2088,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.3, inherits@^2.0.4: +inherits@2, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -2198,6 +2308,11 @@ isarray@^2.0.5: resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -2356,6 +2471,11 @@ make-dir@^3.1.0: dependencies: semver "^6.0.0" +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + memoize-one@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-6.0.0.tgz#b2591b871ed82948aee4727dc6abceeeac8c1045" @@ -2383,6 +2503,18 @@ micromatch@^4.0.4, micromatch@^4.0.5: braces "^3.0.2" picomatch "^2.3.1" +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@~2.1.24: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" @@ -2433,6 +2565,13 @@ mkdirp-classic@^0.5.2: resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== +mkdirp@^0.5.4: + version "0.5.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + mkdirp@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" @@ -2448,6 +2587,19 @@ ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +multer@^1.4.5-lts.1: + version "1.4.5-lts.1" + resolved "https://registry.yarnpkg.com/multer/-/multer-1.4.5-lts.1.tgz#803e24ad1984f58edffbc79f56e305aec5cfd1ac" + integrity sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ== + dependencies: + append-field "^1.0.0" + busboy "^1.0.0" + concat-stream "^1.5.2" + mkdirp "^0.5.4" + object-assign "^4.1.1" + type-is "^1.6.4" + xtend "^4.0.0" + nanoid@^3.3.4: version "3.3.4" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" @@ -2842,6 +2994,11 @@ prisma@^4.9.0: dependencies: "@prisma/engines" "4.9.0" +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + progress@2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" @@ -3020,6 +3177,19 @@ read-cache@^1.0.0: dependencies: pify "^2.3.0" +readable-stream@^2.2.2: + version "2.3.8" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + readable-stream@^3.1.1, readable-stream@^3.4.0: version "3.6.2" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" @@ -3106,6 +3276,11 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" @@ -3207,6 +3382,11 @@ stop-iteration-iterator@^1.0.0: dependencies: internal-slot "^1.0.4" +streamsearch@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" + integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== + "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" @@ -3255,6 +3435,13 @@ string_decoder@^1.1.1: dependencies: safe-buffer "~5.2.0" +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" @@ -3464,6 +3651,14 @@ type-fest@^0.20.2: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== +type-is@^1.6.4: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + typed-array-length@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" @@ -3473,6 +3668,11 @@ typed-array-length@^1.0.4: for-each "^0.3.3" is-typed-array "^1.1.9" +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== + typescript@4.9.4: version "4.9.4" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.4.tgz#a2a3d2756c079abda241d75f149df9d561091e78" @@ -3526,7 +3726,7 @@ use-sync-external-store@1.2.0: resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== -util-deprecate@^1.0.1, util-deprecate@^1.0.2: +util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== @@ -3611,7 +3811,7 @@ ws@8.13.0: resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== -xtend@^4.0.2: +xtend@^4.0.0, xtend@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==