From b458fad567f4f9ae05015fe0aaf9aefb4ed54199 Mon Sep 17 00:00:00 2001 From: daniel31x13 Date: Thu, 2 Nov 2023 01:52:49 -0400 Subject: [PATCH] WIP changes --- lib/api/authenticateUser.ts | 21 ++++ package.json | 1 + pages/api/v1/archives/[...params].ts | 2 +- pages/api/v1/auth/[...nextauth].ts | 22 ++-- pages/api/v1/avatar/[id].ts | 2 +- pages/api/v1/collections/[id].ts | 2 +- pages/api/v1/collections/index.ts | 2 +- pages/api/v1/dashboard/index.ts | 2 +- pages/api/v1/getToken.ts | 26 ++--- pages/api/v1/links/[id]/archive/index.ts | 2 +- pages/api/v1/links/[id]/index.ts | 2 +- pages/api/v1/links/index.ts | 9 +- pages/api/v1/migration/index.ts | 2 +- pages/api/v1/tags/[id].ts | 2 +- pages/api/v1/tags/index.ts | 2 +- pages/api/v1/users/[id].ts | 2 +- pages/api/v1/webhooks/stripe/index.ts | 62 +++++++++++ pages/test.tsx | 125 +++++++++++++++++++++++ types/next-auth.d.ts | 32 ++++++ yarn.lock | 81 ++++++++++++++- 20 files changed, 358 insertions(+), 43 deletions(-) create mode 100644 lib/api/authenticateUser.ts create mode 100644 pages/api/v1/webhooks/stripe/index.ts create mode 100644 pages/test.tsx diff --git a/lib/api/authenticateUser.ts b/lib/api/authenticateUser.ts new file mode 100644 index 0000000..6ef51b6 --- /dev/null +++ b/lib/api/authenticateUser.ts @@ -0,0 +1,21 @@ +import { NextApiRequest } from "next"; +import { getToken } from "next-auth/jwt"; + +type Props = { + req: NextApiRequest; +}; + +export default async function authenticateUser({ req }: Props) { + const token = await getToken({ req }); + + if (!token?.id) { + return { response: "You must be logged in.", status: 401 }; + } else if (token.isSubscriber === false) + return { + response: + "You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.", + status: 401, + }; + + return token; +} diff --git a/package.json b/package.json index 39ae11f..5f53bc2 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "eslint-config-next": "13.4.9", "framer-motion": "^10.16.4", "jsdom": "^22.1.0", + "micro": "^10.0.1", "next": "13.4.12", "next-auth": "^4.22.1", "next-themes": "^0.2.1", diff --git a/pages/api/v1/archives/[...params].ts b/pages/api/v1/archives/[...params].ts index 814e5ee..d29099e 100644 --- a/pages/api/v1/archives/[...params].ts +++ b/pages/api/v1/archives/[...params].ts @@ -16,7 +16,7 @@ export default async function Index(req: NextApiRequest, res: NextApiResponse) { if (!session?.user?.username) return res.status(401).json({ response: "You must be logged in." }); else if (session?.user?.isSubscriber === false) - res.status(401).json({ + return res.status(401).json({ response: "You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.", }); diff --git a/pages/api/v1/auth/[...nextauth].ts b/pages/api/v1/auth/[...nextauth].ts index 1bde92d..67b01f7 100644 --- a/pages/api/v1/auth/[...nextauth].ts +++ b/pages/api/v1/auth/[...nextauth].ts @@ -1,10 +1,9 @@ import { prisma } from "@/lib/api/db"; import NextAuth from "next-auth/next"; import CredentialsProvider from "next-auth/providers/credentials"; -import { AuthOptions, Session } from "next-auth"; +import { AuthOptions, Session, User } from "next-auth"; import bcrypt from "bcrypt"; import EmailProvider from "next-auth/providers/email"; -import { JWT } from "next-auth/jwt"; import { PrismaAdapter } from "@auth/prisma-adapter"; import { Adapter } from "next-auth/adapters"; import sendVerificationRequest from "@/lib/api/sendVerificationRequest"; @@ -19,6 +18,7 @@ const providers: Provider[] = [ type: "credentials", credentials: {}, async authorize(credentials, req) { + console.log("User logged in..."); if (!credentials) return null; const { username, password } = credentials as { @@ -81,13 +81,6 @@ export const authOptions: AuthOptions = { verifyRequest: "/confirmation", }, callbacks: { - session: async ({ session, token }: { session: Session; token: JWT }) => { - session.user.id = parseInt(token.id as string); - session.user.username = token.username as string; - session.user.isSubscriber = token.isSubscriber as boolean; - - return session; - }, async jwt({ token, trigger, user }) { const STRIPE_SECRET_KEY = process.env.STRIPE_SECRET_KEY; @@ -121,7 +114,7 @@ export const authOptions: AuthOptions = { } if (trigger === "signIn") { - token.id = user.id; + token.id = user.id as number; token.username = (user as any).username; } else if (trigger === "update" && token.id) { console.log(token); @@ -132,7 +125,7 @@ export const authOptions: AuthOptions = { }, }); - if (user) { + if (user?.name && user.username && user.email) { token.name = user.name; token.username = user.username?.toLowerCase(); token.email = user.email?.toLowerCase(); @@ -140,6 +133,13 @@ export const authOptions: AuthOptions = { } return token; }, + async session({ session, token }) { + session.user.id = token.id; + session.user.username = token.username; + session.user.isSubscriber = token.isSubscriber; + + return session; + }, }, }; diff --git a/pages/api/v1/avatar/[id].ts b/pages/api/v1/avatar/[id].ts index 97eeb91..0a379fc 100644 --- a/pages/api/v1/avatar/[id].ts +++ b/pages/api/v1/avatar/[id].ts @@ -17,7 +17,7 @@ export default async function Index(req: NextApiRequest, res: NextApiResponse) { .status(401) .send("You must be logged in."); else if (session?.user?.isSubscriber === false) - res.status(401).json({ + return res.status(401).json({ response: "You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.", }); diff --git a/pages/api/v1/collections/[id].ts b/pages/api/v1/collections/[id].ts index 3ac289c..4f888d9 100644 --- a/pages/api/v1/collections/[id].ts +++ b/pages/api/v1/collections/[id].ts @@ -13,7 +13,7 @@ export default async function collections( if (!session?.user?.id) { return res.status(401).json({ response: "You must be logged in." }); } else if (session?.user?.isSubscriber === false) - res.status(401).json({ + return res.status(401).json({ response: "You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.", }); diff --git a/pages/api/v1/collections/index.ts b/pages/api/v1/collections/index.ts index 73cb45e..f5f00ae 100644 --- a/pages/api/v1/collections/index.ts +++ b/pages/api/v1/collections/index.ts @@ -13,7 +13,7 @@ export default async function collections( if (!session?.user?.id) { return res.status(401).json({ response: "You must be logged in." }); } else if (session?.user?.isSubscriber === false) - res.status(401).json({ + return res.status(401).json({ response: "You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.", }); diff --git a/pages/api/v1/dashboard/index.ts b/pages/api/v1/dashboard/index.ts index 5c92e00..af98b4b 100644 --- a/pages/api/v1/dashboard/index.ts +++ b/pages/api/v1/dashboard/index.ts @@ -10,7 +10,7 @@ export default async function links(req: NextApiRequest, res: NextApiResponse) { if (!session?.user?.id) { return res.status(401).json({ response: "You must be logged in." }); } else if (session?.user?.isSubscriber === false) - res.status(401).json({ + return res.status(401).json({ response: "You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.", }); diff --git a/pages/api/v1/getToken.ts b/pages/api/v1/getToken.ts index e51c4bb..84114d2 100644 --- a/pages/api/v1/getToken.ts +++ b/pages/api/v1/getToken.ts @@ -1,18 +1,10 @@ -// For future... -// import { getToken } from "next-auth/jwt"; +import { NextApiRequest, NextApiResponse } from "next"; +import { getToken } from "next-auth/jwt"; -// export default async (req, res) => { -// // If you don't have NEXTAUTH_SECRET set, you will have to pass your secret as `secret` to `getToken` -// console.log({ req }); -// const token = await getToken({ req, raw: true }); -// if (token) { -// // Signed in -// console.log("JSON Web Token", JSON.stringify(token, null, 2)); -// } else { -// // Not Signed in -// res.status(401); -// } -// res.end(); -// }; - -export {}; +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/links/[id]/archive/index.ts b/pages/api/v1/links/[id]/archive/index.ts index c1c38b0..750d440 100644 --- a/pages/api/v1/links/[id]/archive/index.ts +++ b/pages/api/v1/links/[id]/archive/index.ts @@ -12,7 +12,7 @@ export default async function links(req: NextApiRequest, res: NextApiResponse) { if (!session?.user?.id) { return res.status(401).json({ response: "You must be logged in." }); } else if (session?.user?.isSubscriber === false) - res.status(401).json({ + return res.status(401).json({ response: "You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.", }); diff --git a/pages/api/v1/links/[id]/index.ts b/pages/api/v1/links/[id]/index.ts index 748e009..28defa4 100644 --- a/pages/api/v1/links/[id]/index.ts +++ b/pages/api/v1/links/[id]/index.ts @@ -11,7 +11,7 @@ export default async function links(req: NextApiRequest, res: NextApiResponse) { if (!session?.user?.id) { return res.status(401).json({ response: "You must be logged in." }); } else if (session?.user?.isSubscriber === false) - res.status(401).json({ + return res.status(401).json({ response: "You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.", }); diff --git a/pages/api/v1/links/index.ts b/pages/api/v1/links/index.ts index e882c15..7fe25c9 100644 --- a/pages/api/v1/links/index.ts +++ b/pages/api/v1/links/index.ts @@ -4,14 +4,19 @@ import { authOptions } from "@/pages/api/v1/auth/[...nextauth]"; import getLinks from "@/lib/api/controllers/links/getLinks"; import postLink from "@/lib/api/controllers/links/postLink"; import { LinkRequestQuery } from "@/types/global"; +import { getToken } from "next-auth/jwt"; export default async function links(req: NextApiRequest, res: NextApiResponse) { - const session = await getServerSession(req, res, authOptions); + const token = await getToken({ req }); + + // const session = await getServerSession(req, res, authOptions); + + return res.status(200).json(token); if (!session?.user?.id) { return res.status(401).json({ response: "You must be logged in." }); } else if (session?.user?.isSubscriber === false) - res.status(401).json({ + return res.status(401).json({ response: "You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.", }); diff --git a/pages/api/v1/migration/index.ts b/pages/api/v1/migration/index.ts index 628a0d2..08d8336 100644 --- a/pages/api/v1/migration/index.ts +++ b/pages/api/v1/migration/index.ts @@ -20,7 +20,7 @@ export default async function users(req: NextApiRequest, res: NextApiResponse) { if (!session?.user.id) { return res.status(401).json({ response: "You must be logged in." }); } else if (session?.user?.isSubscriber === false) - res.status(401).json({ + return res.status(401).json({ response: "You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.", }); diff --git a/pages/api/v1/tags/[id].ts b/pages/api/v1/tags/[id].ts index 22b355f..eb6a1b5 100644 --- a/pages/api/v1/tags/[id].ts +++ b/pages/api/v1/tags/[id].ts @@ -9,7 +9,7 @@ export default async function tags(req: NextApiRequest, res: NextApiResponse) { if (!session?.user?.username) { return res.status(401).json({ response: "You must be logged in." }); } else if (session?.user?.isSubscriber === false) - res.status(401).json({ + return res.status(401).json({ response: "You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.", }); diff --git a/pages/api/v1/tags/index.ts b/pages/api/v1/tags/index.ts index efaf7b2..a516123 100644 --- a/pages/api/v1/tags/index.ts +++ b/pages/api/v1/tags/index.ts @@ -9,7 +9,7 @@ export default async function tags(req: NextApiRequest, res: NextApiResponse) { if (!session?.user?.username) { return res.status(401).json({ response: "You must be logged in." }); } else if (session?.user?.isSubscriber === false) - res.status(401).json({ + return res.status(401).json({ response: "You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.", }); diff --git a/pages/api/v1/users/[id].ts b/pages/api/v1/users/[id].ts index 20b3551..2eff580 100644 --- a/pages/api/v1/users/[id].ts +++ b/pages/api/v1/users/[id].ts @@ -26,7 +26,7 @@ export default async function users(req: NextApiRequest, res: NextApiResponse) { if (!userId) { return res.status(401).json({ response: "You must be logged in." }); } else if (session?.user?.isSubscriber === false) - res.status(401).json({ + return res.status(401).json({ response: "You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.", }); diff --git a/pages/api/v1/webhooks/stripe/index.ts b/pages/api/v1/webhooks/stripe/index.ts new file mode 100644 index 0000000..a1df0ea --- /dev/null +++ b/pages/api/v1/webhooks/stripe/index.ts @@ -0,0 +1,62 @@ +// TODO - Stripe webhooks for user cancellation... + +// import { NextApiRequest, NextApiResponse } from "next"; +// import Stripe from "stripe"; +// import { buffer } from "micro"; +// import { prisma } from "@/lib/api/db"; + +// const stripe = new Stripe(process.env.STRIPE_SECRET_KEY as string, { +// apiVersion: "2022-11-15", +// }); + +// const endpointSecret = +// "whsec_7c144bcd924041257e3d83eac1e2fba9c8a938b240fd8adb1c902f079e0cdee0"; + +// export const config = { +// api: { +// bodyParser: false, +// }, +// }; + +// export default async function handler( +// req: NextApiRequest, +// res: NextApiResponse +// ) { +// if (req.method === "POST") { +// const buf = await buffer(req); +// const sig = req.headers["stripe-signature"]; + +// let event: Stripe.Event; + +// try { +// if (!sig) throw new Error("Stripe Signature is not defined."); +// event = stripe.webhooks.constructEvent(buf, sig, endpointSecret); +// } catch (err) { +// console.log(err); +// return res.status(400).send({ response: "Error..." }); +// } + +// // Handle the event +// switch (event.type) { +// case "customer.subscription.deleted": +// const customerSubscriptionDeleted = event.data.object as any; + +// // Revoke all the token under the customers email... + +// const customer = (await stripe.customers.retrieve( +// customerSubscriptionDeleted.customer +// )) as any; + +// if (customer?.email) { +// // Revoke tokens inside the database +// } + +// break; +// // ... handle other event types +// default: +// console.log(`Unhandled event type ${event.type}`); +// } + +// return res.status(200).send({ response: "Done!" }); +// } +// } diff --git a/pages/test.tsx b/pages/test.tsx new file mode 100644 index 0000000..beae84f --- /dev/null +++ b/pages/test.tsx @@ -0,0 +1,125 @@ +import SubmitButton from "@/components/SubmitButton"; +import TextInput from "@/components/TextInput"; +import CenteredForm from "@/layouts/CenteredForm"; +import { signIn } from "next-auth/react"; +import Link from "next/link"; +import { useState, FormEvent } from "react"; +import { toast } from "react-hot-toast"; + +interface FormData { + username: string; + password: string; +} + +const emailEnabled = process.env.NEXT_PUBLIC_EMAIL_PROVIDER; + +export default function Login() { + const [submitLoader, setSubmitLoader] = useState(false); + + const [form, setForm] = useState({ + username: "", + password: "", + }); + + async function loginUser(event: FormEvent) { + event.preventDefault(); + + if (form.username !== "" && form.password !== "") { + setSubmitLoader(true); + + const load = toast.loading("Authenticating..."); + + const res = await signIn("credentials", { + username: form.username, + password: form.password, + redirect: false, + }); + + console.log(res); + + toast.dismiss(load); + + setSubmitLoader(false); + + if (!res?.ok) { + toast.error("Invalid login."); + } + } else { + toast.error("Please fill out all the fields."); + } + } + + return ( + +
+
+

+ Enter your credentials +

+ +
+ +
+

+ Username + {emailEnabled ? " or Email" : undefined} +

+ + setForm({ ...form, username: e.target.value })} + /> +
+ +
+

+ Password +

+ + setForm({ ...form, password: e.target.value })} + /> + {emailEnabled && ( +
+ + Forgot Password? + +
+ )} +
+ + + {process.env.NEXT_PUBLIC_DISABLE_REGISTRATION === + "true" ? undefined : ( +
+

+ New here? +

+ + Sign Up + +
+ )} +
+
+
+ ); +} diff --git a/types/next-auth.d.ts b/types/next-auth.d.ts index 6df7f6c..d78b116 100644 --- a/types/next-auth.d.ts +++ b/types/next-auth.d.ts @@ -1,4 +1,5 @@ import NextAuth from "next-auth"; +import { JWT } from "next-auth/jwt"; declare module "next-auth" { interface Session { @@ -9,4 +10,35 @@ declare module "next-auth" { isSubscriber: boolean; }; } + + interface User { + id: number; + name: string; + username: string; + email: string; + emailVerified: Date; + image: string; + password: string; + archiveAsScreenshot: boolean; + archiveAsPDF: boolean; + archiveAsWaybackMachine: boolean; + isPrivate: boolean; + createdAt: Date; + updatedAt: Date; + } +} + +declare module "next-auth/jwt" { + interface JWT { + name: string; + email: string; + picture: string; + sub: string; + isSubscriber: boolean; + id: number; + username: string; + iat: number; + exp: number; + jti: string; + } } diff --git a/yarn.lock b/yarn.lock index bd41d88..024191a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1702,6 +1702,11 @@ are-we-there-yet@^2.0.0: delegates "^1.0.0" readable-stream "^3.6.0" +arg@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.0.tgz#583c518199419e0037abb74062c37f8519e575f0" + integrity sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg== + arg@^5.0.2: version "5.0.2" resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c" @@ -1929,6 +1934,11 @@ busboy@1.6.0: dependencies: streamsearch "^1.1.0" +bytes@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" + integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== + 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" @@ -2079,6 +2089,11 @@ console-control-strings@^1.0.0, console-control-strings@^1.1.0: resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== +content-type@1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + convert-source-map@^1.5.0: version "1.9.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" @@ -2256,6 +2271,11 @@ delegates@^1.0.0: resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== + detect-libc@^2.0.0, detect-libc@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.1.tgz#e1897aa88fa6ad197862937fbc0441ef352ee0cd" @@ -3122,6 +3142,17 @@ html-encoding-sniffer@^3.0.0: dependencies: whatwg-encoding "^2.0.0" +http-errors@1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" + integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + http-proxy-agent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" @@ -3148,6 +3179,13 @@ https-proxy-agent@^5.0.0, https-proxy-agent@^5.0.1: agent-base "6" debug "4" +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + iconv-lite@0.6.3: version "0.6.3" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" @@ -3186,7 +3224,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.4, inherits@^2.0.3, inherits@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -3613,6 +3651,15 @@ merge2@^1.3.0, merge2@^1.4.1: resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== +micro@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/micro/-/micro-10.0.1.tgz#2601e02b0dacd2eaee77e9de18f12b2e595c5951" + integrity sha512-9uwZSsUrqf6+4FLLpiPj5TRWQv5w5uJrJwsx1LR/TjqvQmKC1XnGQ9OHrFwR3cbZ46YqPqxO/XJCOpWnqMPw2Q== + dependencies: + arg "4.1.0" + content-type "1.0.4" + raw-body "2.4.1" + micromatch@^4.0.4, micromatch@^4.0.5: version "4.0.5" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" @@ -4273,6 +4320,16 @@ queue-microtask@^1.2.2: resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== +raw-body@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.1.tgz#30ac82f98bb5ae8c152e67149dac8d55153b168c" + integrity sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA== + dependencies: + bytes "3.1.0" + http-errors "1.7.3" + iconv-lite "0.4.24" + unpipe "1.0.0" + rc@^1.2.7: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" @@ -4483,7 +4540,7 @@ safe-regex-test@^1.0.0: get-intrinsic "^1.1.3" is-regex "^1.1.4" -"safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -4519,6 +4576,11 @@ set-blocking@^2.0.0: resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== +setprototypeof@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" + integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== + sharp@^0.32.1: version "0.32.1" resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.32.1.tgz#41aa0d0b2048b2e0ee453d9fcb14ec1f408390fe" @@ -4615,6 +4677,11 @@ sshpk@^1.7.0: safer-buffer "^2.0.2" tweetnacl "~0.14.0" +"statuses@>= 1.5.0 < 2": + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== + stop-iteration-iterator@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz#6a60be0b4ee757d1ed5254858ec66b10c49285e4" @@ -4877,6 +4944,11 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" +toidentifier@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" + integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== + tough-cookie@^4.1.2: version "4.1.3" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.3.tgz#97b9adb0728b42280aa3d814b6b999b2ff0318bf" @@ -4997,6 +5069,11 @@ universalify@^0.2.0: resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0" integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg== +unpipe@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + update-browserslist-db@^1.0.11: version "1.0.11" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940"