undo commit

This commit is contained in:
daniel31x13
2024-11-03 03:25:01 -05:00
parent aeafe6e15d
commit 9103f67db5
176 changed files with 9406 additions and 2367 deletions
+102 -4
View File
@@ -1,9 +1,11 @@
import { prisma } from "@/lib/api/db";
import sendInvitationRequest from "@/lib/api/sendInvitationRequest";
import sendVerificationRequest from "@/lib/api/sendVerificationRequest";
import verifySubscription from "@/lib/api/verifySubscription";
import updateSeats from "@/lib/api/stripe/updateSeats";
import verifySubscription from "@/lib/api/stripe/verifySubscription";
import { PrismaAdapter } from "@auth/prisma-adapter";
import { User } from "@prisma/client";
import bcrypt from "bcrypt";
import { randomBytes } from "crypto";
import type { NextApiRequest, NextApiResponse } from "next";
import { Adapter } from "next-auth/adapters";
import NextAuth from "next-auth/next";
@@ -133,6 +135,7 @@ if (process.env.NEXT_PUBLIC_CREDENTIALS_ENABLED !== "false") {
if (emailEnabled) {
providers.push(
EmailProvider({
id: "email",
server: process.env.EMAIL_SERVER,
from: process.env.EMAIL_FROM,
maxAge: 1200,
@@ -157,6 +160,56 @@ if (emailEnabled) {
token,
});
},
}),
EmailProvider({
id: "invite",
server: process.env.EMAIL_SERVER,
from: process.env.EMAIL_FROM,
maxAge: 1200,
async sendVerificationRequest({ identifier, url, provider, token }) {
const parentSubscriptionEmail = (
await prisma.user.findFirst({
where: {
email: identifier,
emailVerified: null,
},
include: {
parentSubscription: {
include: {
user: {
select: {
email: true,
},
},
},
},
},
})
)?.parentSubscription?.user.email;
if (!parentSubscriptionEmail) throw Error("Invalid email.");
const recentVerificationRequestsCount =
await prisma.verificationToken.count({
where: {
identifier,
createdAt: {
gt: new Date(new Date().getTime() - 1000 * 60 * 5), // 5 minutes
},
},
});
if (recentVerificationRequestsCount >= 4)
throw Error("Too many requests. Please try again later.");
sendInvitationRequest({
parentSubscriptionEmail,
identifier,
url,
from: provider.from as string,
token,
});
},
})
);
}
@@ -1179,6 +1232,52 @@ export default async function auth(req: NextApiRequest, res: NextApiResponse) {
},
callbacks: {
async signIn({ user, account, profile, email, credentials }) {
if (
!(user as User).emailVerified &&
!email?.verificationRequest
// && (account?.provider === "email" || account?.provider === "google")
) {
// Email is being verified for the first time...
console.log("Email is being verified for the first time...");
const parentSubscriptionId = (user as User).parentSubscriptionId;
if (parentSubscriptionId) {
// Add seat request to Stripe
const parentSubscription = await prisma.subscription.findFirst({
where: {
id: parentSubscriptionId,
},
});
// Count child users with verified email under a specific subscription, excluding the current user
const verifiedChildUsersCount = await prisma.user.count({
where: {
parentSubscriptionId: parentSubscriptionId,
id: {
not: user.id as number,
},
emailVerified: {
not: null,
},
},
});
if (
STRIPE_SECRET_KEY &&
parentSubscription?.quantity &&
verifiedChildUsersCount + 2 > // add current user and the admin
parentSubscription.quantity
) {
// Add seat if the user count exceeds the subscription limit
await updateSeats(
parentSubscription.stripeSubscriptionId,
verifiedChildUsersCount + 2
);
}
}
}
if (account?.provider !== "credentials") {
// registration via SSO can be separately disabled
const existingUser = await prisma.account.findFirst({
@@ -1287,8 +1386,6 @@ export default async function auth(req: NextApiRequest, res: NextApiResponse) {
async session({ session, token }) {
session.user.id = token.id;
console.log("session", session);
if (STRIPE_SECRET_KEY) {
const user = await prisma.user.findUnique({
where: {
@@ -1296,6 +1393,7 @@ export default async function auth(req: NextApiRequest, res: NextApiResponse) {
},
include: {
subscriptions: true,
parentSubscription: true,
},
});
+10 -5
View File
@@ -1,5 +1,6 @@
import { prisma } from "@/lib/api/db";
import sendPasswordResetRequest from "@/lib/api/sendPasswordResetRequest";
import { ForgotPasswordSchema } from "@/lib/shared/schemaValidation";
import type { NextApiRequest, NextApiResponse } from "next";
export default async function forgotPassword(
@@ -13,14 +14,18 @@ export default async function forgotPassword(
"This action is disabled because this is a read-only demo of Linkwarden.",
});
const email = req.body.email;
const dataValidation = ForgotPasswordSchema.safeParse(req.body);
if (!email) {
if (!dataValidation.success) {
return res.status(400).json({
response: "Invalid email.",
response: `Error: ${
dataValidation.error.issues[0].message
} [${dataValidation.error.issues[0].path.join(", ")}]`,
});
}
const { email } = dataValidation.data;
const recentPasswordRequestsCount = await prisma.passwordResetToken.count({
where: {
identifier: email,
@@ -45,11 +50,11 @@ export default async function forgotPassword(
if (!user || !user.email) {
return res.status(400).json({
response: "Invalid email.",
response: "No user found with that email.",
});
}
sendPasswordResetRequest(user.email, user.name);
sendPasswordResetRequest(user.email, user.name || "Linkwarden User");
return res.status(200).json({
response: "Password reset email sent.",
+7 -9
View File
@@ -1,6 +1,7 @@
import { prisma } from "@/lib/api/db";
import type { NextApiRequest, NextApiResponse } from "next";
import bcrypt from "bcrypt";
import { ResetPasswordSchema } from "@/lib/shared/schemaValidation";
export default async function resetPassword(
req: NextApiRequest,
@@ -13,20 +14,17 @@ export default async function resetPassword(
"This action is disabled because this is a read-only demo of Linkwarden.",
});
const token = req.body.token;
const password = req.body.password;
const dataValidation = ResetPasswordSchema.safeParse(req.body);
if (!password || password.length < 8) {
if (!dataValidation.success) {
return res.status(400).json({
response: "Password must be at least 8 characters.",
response: `Error: ${
dataValidation.error.issues[0].message
} [${dataValidation.error.issues[0].path.join(", ")}]`,
});
}
if (!token || typeof token !== "string") {
return res.status(400).json({
response: "Invalid token.",
});
}
const { token, password } = dataValidation.data;
// Hashed password
const saltRounds = 10;
+9 -4
View File
@@ -1,5 +1,6 @@
import { prisma } from "@/lib/api/db";
import updateCustomerEmail from "@/lib/api/updateCustomerEmail";
import updateCustomerEmail from "@/lib/api/stripe/updateCustomerEmail";
import { VerifyEmailSchema } from "@/lib/shared/schemaValidation";
import type { NextApiRequest, NextApiResponse } from "next";
export default async function verifyEmail(
@@ -13,14 +14,18 @@ export default async function verifyEmail(
"This action is disabled because this is a read-only demo of Linkwarden.",
});
const token = req.query.token;
const dataValidation = VerifyEmailSchema.safeParse(req.query);
if (!token || typeof token !== "string") {
if (!dataValidation.success) {
return res.status(400).json({
response: "Invalid token.",
response: `Error: ${
dataValidation.error.issues[0].message
} [${dataValidation.error.issues[0].path.join(", ")}]`,
});
}
const { token } = dataValidation.data;
// Check token in db
const verifyToken = await prisma.verificationToken.findFirst({
where: {