WIP changes
This commit is contained in:
parent
b1b0d98eb2
commit
b458fad567
|
@ -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;
|
||||||
|
}
|
|
@ -40,6 +40,7 @@
|
||||||
"eslint-config-next": "13.4.9",
|
"eslint-config-next": "13.4.9",
|
||||||
"framer-motion": "^10.16.4",
|
"framer-motion": "^10.16.4",
|
||||||
"jsdom": "^22.1.0",
|
"jsdom": "^22.1.0",
|
||||||
|
"micro": "^10.0.1",
|
||||||
"next": "13.4.12",
|
"next": "13.4.12",
|
||||||
"next-auth": "^4.22.1",
|
"next-auth": "^4.22.1",
|
||||||
"next-themes": "^0.2.1",
|
"next-themes": "^0.2.1",
|
||||||
|
|
|
@ -16,7 +16,7 @@ export default async function Index(req: NextApiRequest, res: NextApiResponse) {
|
||||||
if (!session?.user?.username)
|
if (!session?.user?.username)
|
||||||
return res.status(401).json({ response: "You must be logged in." });
|
return res.status(401).json({ response: "You must be logged in." });
|
||||||
else if (session?.user?.isSubscriber === false)
|
else if (session?.user?.isSubscriber === false)
|
||||||
res.status(401).json({
|
return res.status(401).json({
|
||||||
response:
|
response:
|
||||||
"You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.",
|
"You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.",
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
import { prisma } from "@/lib/api/db";
|
import { prisma } from "@/lib/api/db";
|
||||||
import NextAuth from "next-auth/next";
|
import NextAuth from "next-auth/next";
|
||||||
import CredentialsProvider from "next-auth/providers/credentials";
|
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 bcrypt from "bcrypt";
|
||||||
import EmailProvider from "next-auth/providers/email";
|
import EmailProvider from "next-auth/providers/email";
|
||||||
import { JWT } from "next-auth/jwt";
|
|
||||||
import { PrismaAdapter } from "@auth/prisma-adapter";
|
import { PrismaAdapter } from "@auth/prisma-adapter";
|
||||||
import { Adapter } from "next-auth/adapters";
|
import { Adapter } from "next-auth/adapters";
|
||||||
import sendVerificationRequest from "@/lib/api/sendVerificationRequest";
|
import sendVerificationRequest from "@/lib/api/sendVerificationRequest";
|
||||||
|
@ -19,6 +18,7 @@ const providers: Provider[] = [
|
||||||
type: "credentials",
|
type: "credentials",
|
||||||
credentials: {},
|
credentials: {},
|
||||||
async authorize(credentials, req) {
|
async authorize(credentials, req) {
|
||||||
|
console.log("User logged in...");
|
||||||
if (!credentials) return null;
|
if (!credentials) return null;
|
||||||
|
|
||||||
const { username, password } = credentials as {
|
const { username, password } = credentials as {
|
||||||
|
@ -81,13 +81,6 @@ export const authOptions: AuthOptions = {
|
||||||
verifyRequest: "/confirmation",
|
verifyRequest: "/confirmation",
|
||||||
},
|
},
|
||||||
callbacks: {
|
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 }) {
|
async jwt({ token, trigger, user }) {
|
||||||
const STRIPE_SECRET_KEY = process.env.STRIPE_SECRET_KEY;
|
const STRIPE_SECRET_KEY = process.env.STRIPE_SECRET_KEY;
|
||||||
|
|
||||||
|
@ -121,7 +114,7 @@ export const authOptions: AuthOptions = {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trigger === "signIn") {
|
if (trigger === "signIn") {
|
||||||
token.id = user.id;
|
token.id = user.id as number;
|
||||||
token.username = (user as any).username;
|
token.username = (user as any).username;
|
||||||
} else if (trigger === "update" && token.id) {
|
} else if (trigger === "update" && token.id) {
|
||||||
console.log(token);
|
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.name = user.name;
|
||||||
token.username = user.username?.toLowerCase();
|
token.username = user.username?.toLowerCase();
|
||||||
token.email = user.email?.toLowerCase();
|
token.email = user.email?.toLowerCase();
|
||||||
|
@ -140,6 +133,13 @@ export const authOptions: AuthOptions = {
|
||||||
}
|
}
|
||||||
return token;
|
return token;
|
||||||
},
|
},
|
||||||
|
async session({ session, token }) {
|
||||||
|
session.user.id = token.id;
|
||||||
|
session.user.username = token.username;
|
||||||
|
session.user.isSubscriber = token.isSubscriber;
|
||||||
|
|
||||||
|
return session;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ export default async function Index(req: NextApiRequest, res: NextApiResponse) {
|
||||||
.status(401)
|
.status(401)
|
||||||
.send("You must be logged in.");
|
.send("You must be logged in.");
|
||||||
else if (session?.user?.isSubscriber === false)
|
else if (session?.user?.isSubscriber === false)
|
||||||
res.status(401).json({
|
return res.status(401).json({
|
||||||
response:
|
response:
|
||||||
"You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.",
|
"You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.",
|
||||||
});
|
});
|
||||||
|
|
|
@ -13,7 +13,7 @@ export default async function collections(
|
||||||
if (!session?.user?.id) {
|
if (!session?.user?.id) {
|
||||||
return res.status(401).json({ response: "You must be logged in." });
|
return res.status(401).json({ response: "You must be logged in." });
|
||||||
} else if (session?.user?.isSubscriber === false)
|
} else if (session?.user?.isSubscriber === false)
|
||||||
res.status(401).json({
|
return res.status(401).json({
|
||||||
response:
|
response:
|
||||||
"You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.",
|
"You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.",
|
||||||
});
|
});
|
||||||
|
|
|
@ -13,7 +13,7 @@ export default async function collections(
|
||||||
if (!session?.user?.id) {
|
if (!session?.user?.id) {
|
||||||
return res.status(401).json({ response: "You must be logged in." });
|
return res.status(401).json({ response: "You must be logged in." });
|
||||||
} else if (session?.user?.isSubscriber === false)
|
} else if (session?.user?.isSubscriber === false)
|
||||||
res.status(401).json({
|
return res.status(401).json({
|
||||||
response:
|
response:
|
||||||
"You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.",
|
"You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.",
|
||||||
});
|
});
|
||||||
|
|
|
@ -10,7 +10,7 @@ export default async function links(req: NextApiRequest, res: NextApiResponse) {
|
||||||
if (!session?.user?.id) {
|
if (!session?.user?.id) {
|
||||||
return res.status(401).json({ response: "You must be logged in." });
|
return res.status(401).json({ response: "You must be logged in." });
|
||||||
} else if (session?.user?.isSubscriber === false)
|
} else if (session?.user?.isSubscriber === false)
|
||||||
res.status(401).json({
|
return res.status(401).json({
|
||||||
response:
|
response:
|
||||||
"You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.",
|
"You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.",
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,18 +1,10 @@
|
||||||
// For future...
|
import { NextApiRequest, NextApiResponse } from "next";
|
||||||
// import { getToken } from "next-auth/jwt";
|
import { getToken } from "next-auth/jwt";
|
||||||
|
|
||||||
// export default async (req, res) => {
|
export default async (req: NextApiRequest, res: NextApiResponse) => {
|
||||||
// // If you don't have NEXTAUTH_SECRET set, you will have to pass your secret as `secret` to `getToken`
|
// if using `NEXTAUTH_SECRET` env variable, we detect it, and you won't actually need to `secret`
|
||||||
// console.log({ req });
|
// const token = await getToken({ req })
|
||||||
// const token = await getToken({ req, raw: true });
|
const token = await getToken({ req });
|
||||||
// if (token) {
|
console.log("JSON Web Token", token);
|
||||||
// // Signed in
|
res.end();
|
||||||
// console.log("JSON Web Token", JSON.stringify(token, null, 2));
|
};
|
||||||
// } else {
|
|
||||||
// // Not Signed in
|
|
||||||
// res.status(401);
|
|
||||||
// }
|
|
||||||
// res.end();
|
|
||||||
// };
|
|
||||||
|
|
||||||
export {};
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ export default async function links(req: NextApiRequest, res: NextApiResponse) {
|
||||||
if (!session?.user?.id) {
|
if (!session?.user?.id) {
|
||||||
return res.status(401).json({ response: "You must be logged in." });
|
return res.status(401).json({ response: "You must be logged in." });
|
||||||
} else if (session?.user?.isSubscriber === false)
|
} else if (session?.user?.isSubscriber === false)
|
||||||
res.status(401).json({
|
return res.status(401).json({
|
||||||
response:
|
response:
|
||||||
"You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.",
|
"You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.",
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,7 +11,7 @@ export default async function links(req: NextApiRequest, res: NextApiResponse) {
|
||||||
if (!session?.user?.id) {
|
if (!session?.user?.id) {
|
||||||
return res.status(401).json({ response: "You must be logged in." });
|
return res.status(401).json({ response: "You must be logged in." });
|
||||||
} else if (session?.user?.isSubscriber === false)
|
} else if (session?.user?.isSubscriber === false)
|
||||||
res.status(401).json({
|
return res.status(401).json({
|
||||||
response:
|
response:
|
||||||
"You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.",
|
"You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.",
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,14 +4,19 @@ import { authOptions } from "@/pages/api/v1/auth/[...nextauth]";
|
||||||
import getLinks from "@/lib/api/controllers/links/getLinks";
|
import getLinks from "@/lib/api/controllers/links/getLinks";
|
||||||
import postLink from "@/lib/api/controllers/links/postLink";
|
import postLink from "@/lib/api/controllers/links/postLink";
|
||||||
import { LinkRequestQuery } from "@/types/global";
|
import { LinkRequestQuery } from "@/types/global";
|
||||||
|
import { getToken } from "next-auth/jwt";
|
||||||
|
|
||||||
export default async function links(req: NextApiRequest, res: NextApiResponse) {
|
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) {
|
if (!session?.user?.id) {
|
||||||
return res.status(401).json({ response: "You must be logged in." });
|
return res.status(401).json({ response: "You must be logged in." });
|
||||||
} else if (session?.user?.isSubscriber === false)
|
} else if (session?.user?.isSubscriber === false)
|
||||||
res.status(401).json({
|
return res.status(401).json({
|
||||||
response:
|
response:
|
||||||
"You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.",
|
"You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.",
|
||||||
});
|
});
|
||||||
|
|
|
@ -20,7 +20,7 @@ export default async function users(req: NextApiRequest, res: NextApiResponse) {
|
||||||
if (!session?.user.id) {
|
if (!session?.user.id) {
|
||||||
return res.status(401).json({ response: "You must be logged in." });
|
return res.status(401).json({ response: "You must be logged in." });
|
||||||
} else if (session?.user?.isSubscriber === false)
|
} else if (session?.user?.isSubscriber === false)
|
||||||
res.status(401).json({
|
return res.status(401).json({
|
||||||
response:
|
response:
|
||||||
"You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.",
|
"You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.",
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,7 +9,7 @@ export default async function tags(req: NextApiRequest, res: NextApiResponse) {
|
||||||
if (!session?.user?.username) {
|
if (!session?.user?.username) {
|
||||||
return res.status(401).json({ response: "You must be logged in." });
|
return res.status(401).json({ response: "You must be logged in." });
|
||||||
} else if (session?.user?.isSubscriber === false)
|
} else if (session?.user?.isSubscriber === false)
|
||||||
res.status(401).json({
|
return res.status(401).json({
|
||||||
response:
|
response:
|
||||||
"You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.",
|
"You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.",
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,7 +9,7 @@ export default async function tags(req: NextApiRequest, res: NextApiResponse) {
|
||||||
if (!session?.user?.username) {
|
if (!session?.user?.username) {
|
||||||
return res.status(401).json({ response: "You must be logged in." });
|
return res.status(401).json({ response: "You must be logged in." });
|
||||||
} else if (session?.user?.isSubscriber === false)
|
} else if (session?.user?.isSubscriber === false)
|
||||||
res.status(401).json({
|
return res.status(401).json({
|
||||||
response:
|
response:
|
||||||
"You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.",
|
"You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.",
|
||||||
});
|
});
|
||||||
|
|
|
@ -26,7 +26,7 @@ export default async function users(req: NextApiRequest, res: NextApiResponse) {
|
||||||
if (!userId) {
|
if (!userId) {
|
||||||
return res.status(401).json({ response: "You must be logged in." });
|
return res.status(401).json({ response: "You must be logged in." });
|
||||||
} else if (session?.user?.isSubscriber === false)
|
} else if (session?.user?.isSubscriber === false)
|
||||||
res.status(401).json({
|
return res.status(401).json({
|
||||||
response:
|
response:
|
||||||
"You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.",
|
"You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.",
|
||||||
});
|
});
|
||||||
|
|
|
@ -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!" });
|
||||||
|
// }
|
||||||
|
// }
|
|
@ -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<FormData>({
|
||||||
|
username: "",
|
||||||
|
password: "",
|
||||||
|
});
|
||||||
|
|
||||||
|
async function loginUser(event: FormEvent<HTMLFormElement>) {
|
||||||
|
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 (
|
||||||
|
<CenteredForm text="Sign in to your account">
|
||||||
|
<form onSubmit={loginUser}>
|
||||||
|
<div className="p-4 mx-auto flex flex-col gap-3 justify-between max-w-[30rem] min-w-80 w-full bg-slate-50 dark:bg-neutral-800 rounded-2xl shadow-md border border-sky-100 dark:border-neutral-700">
|
||||||
|
<p className="text-3xl text-black dark:text-white text-center font-extralight">
|
||||||
|
Enter your credentials
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<hr className="border-1 border-sky-100 dark:border-neutral-700" />
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<p className="text-sm text-black dark:text-white w-fit font-semibold mb-1">
|
||||||
|
Username
|
||||||
|
{emailEnabled ? " or Email" : undefined}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<TextInput
|
||||||
|
autoFocus={true}
|
||||||
|
placeholder="johnny"
|
||||||
|
value={form.username}
|
||||||
|
className="bg-white"
|
||||||
|
onChange={(e) => setForm({ ...form, username: e.target.value })}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="w-full">
|
||||||
|
<p className="text-sm text-black dark:text-white w-fit font-semibold mb-1">
|
||||||
|
Password
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<TextInput
|
||||||
|
type="password"
|
||||||
|
placeholder="••••••••••••••"
|
||||||
|
value={form.password}
|
||||||
|
className="bg-white"
|
||||||
|
onChange={(e) => setForm({ ...form, password: e.target.value })}
|
||||||
|
/>
|
||||||
|
{emailEnabled && (
|
||||||
|
<div className="w-fit ml-auto mt-1">
|
||||||
|
<Link
|
||||||
|
href={"/forgot"}
|
||||||
|
className="text-gray-500 dark:text-gray-400 font-semibold"
|
||||||
|
>
|
||||||
|
Forgot Password?
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<SubmitButton
|
||||||
|
type="submit"
|
||||||
|
label="Login"
|
||||||
|
className=" w-full text-center"
|
||||||
|
loading={submitLoader}
|
||||||
|
/>
|
||||||
|
{process.env.NEXT_PUBLIC_DISABLE_REGISTRATION ===
|
||||||
|
"true" ? undefined : (
|
||||||
|
<div className="flex items-baseline gap-1 justify-center">
|
||||||
|
<p className="w-fit text-gray-500 dark:text-gray-400">
|
||||||
|
New here?
|
||||||
|
</p>
|
||||||
|
<Link
|
||||||
|
href={"/register"}
|
||||||
|
className="block text-black dark:text-white font-semibold"
|
||||||
|
>
|
||||||
|
Sign Up
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</CenteredForm>
|
||||||
|
);
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
import NextAuth from "next-auth";
|
import NextAuth from "next-auth";
|
||||||
|
import { JWT } from "next-auth/jwt";
|
||||||
|
|
||||||
declare module "next-auth" {
|
declare module "next-auth" {
|
||||||
interface Session {
|
interface Session {
|
||||||
|
@ -9,4 +10,35 @@ declare module "next-auth" {
|
||||||
isSubscriber: boolean;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
81
yarn.lock
81
yarn.lock
|
@ -1702,6 +1702,11 @@ are-we-there-yet@^2.0.0:
|
||||||
delegates "^1.0.0"
|
delegates "^1.0.0"
|
||||||
readable-stream "^3.6.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:
|
arg@^5.0.2:
|
||||||
version "5.0.2"
|
version "5.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c"
|
resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c"
|
||||||
|
@ -1929,6 +1934,11 @@ busboy@1.6.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
streamsearch "^1.1.0"
|
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:
|
call-bind@^1.0.0, call-bind@^1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c"
|
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"
|
resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e"
|
||||||
integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==
|
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:
|
convert-source-map@^1.5.0:
|
||||||
version "1.9.0"
|
version "1.9.0"
|
||||||
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f"
|
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"
|
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
|
||||||
integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==
|
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:
|
detect-libc@^2.0.0, detect-libc@^2.0.1:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.1.tgz#e1897aa88fa6ad197862937fbc0441ef352ee0cd"
|
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:
|
dependencies:
|
||||||
whatwg-encoding "^2.0.0"
|
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:
|
http-proxy-agent@^5.0.0:
|
||||||
version "5.0.0"
|
version "5.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43"
|
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"
|
agent-base "6"
|
||||||
debug "4"
|
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:
|
iconv-lite@0.6.3:
|
||||||
version "0.6.3"
|
version "0.6.3"
|
||||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501"
|
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"
|
once "^1.3.0"
|
||||||
wrappy "1"
|
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"
|
version "2.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
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"
|
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
|
||||||
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
|
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:
|
micromatch@^4.0.4, micromatch@^4.0.5:
|
||||||
version "4.0.5"
|
version "4.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6"
|
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"
|
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
|
||||||
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
|
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:
|
rc@^1.2.7:
|
||||||
version "1.2.8"
|
version "1.2.8"
|
||||||
resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
|
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"
|
get-intrinsic "^1.1.3"
|
||||||
is-regex "^1.1.4"
|
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"
|
version "2.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
||||||
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
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"
|
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
|
||||||
integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==
|
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:
|
sharp@^0.32.1:
|
||||||
version "0.32.1"
|
version "0.32.1"
|
||||||
resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.32.1.tgz#41aa0d0b2048b2e0ee453d9fcb14ec1f408390fe"
|
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"
|
safer-buffer "^2.0.2"
|
||||||
tweetnacl "~0.14.0"
|
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:
|
stop-iteration-iterator@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz#6a60be0b4ee757d1ed5254858ec66b10c49285e4"
|
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:
|
dependencies:
|
||||||
is-number "^7.0.0"
|
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:
|
tough-cookie@^4.1.2:
|
||||||
version "4.1.3"
|
version "4.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.3.tgz#97b9adb0728b42280aa3d814b6b999b2ff0318bf"
|
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"
|
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0"
|
||||||
integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==
|
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:
|
update-browserslist-db@^1.0.11:
|
||||||
version "1.0.11"
|
version "1.0.11"
|
||||||
resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940"
|
resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940"
|
||||||
|
|
Ŝarĝante…
Reference in New Issue