refactored/cleaned up API + added support for renaming tags
This commit is contained in:
@@ -1,79 +0,0 @@
|
||||
import { prisma } from "@/lib/api/db";
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import bcrypt from "bcrypt";
|
||||
|
||||
const emailEnabled =
|
||||
process.env.EMAIL_FROM && process.env.EMAIL_SERVER ? true : false;
|
||||
|
||||
interface Data {
|
||||
response: string | object;
|
||||
}
|
||||
|
||||
interface User {
|
||||
name: string;
|
||||
username?: string;
|
||||
email?: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
export default async function Index(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse<Data>
|
||||
) {
|
||||
if (process.env.NEXT_PUBLIC_DISABLE_REGISTRATION === "true") {
|
||||
return res.status(400).json({ response: "Registration is disabled." });
|
||||
}
|
||||
|
||||
const body: User = req.body;
|
||||
|
||||
const checkHasEmptyFields = emailEnabled
|
||||
? !body.password || !body.name || !body.email
|
||||
: !body.username || !body.password || !body.name;
|
||||
|
||||
if (checkHasEmptyFields)
|
||||
return res
|
||||
.status(400)
|
||||
.json({ response: "Please fill out all the fields." });
|
||||
|
||||
const checkUsername = RegExp("^[a-z0-9_-]{3,31}$");
|
||||
|
||||
if (!emailEnabled && !checkUsername.test(body.username?.toLowerCase() || ""))
|
||||
return res.status(400).json({
|
||||
response:
|
||||
"Username has to be between 3-30 characters, no spaces and special characters are allowed.",
|
||||
});
|
||||
|
||||
const checkIfUserExists = await prisma.user.findFirst({
|
||||
where: emailEnabled
|
||||
? {
|
||||
email: body.email?.toLowerCase(),
|
||||
emailVerified: { not: null },
|
||||
}
|
||||
: {
|
||||
username: (body.username as string).toLowerCase(),
|
||||
},
|
||||
});
|
||||
|
||||
if (!checkIfUserExists) {
|
||||
const saltRounds = 10;
|
||||
|
||||
const hashedPassword = bcrypt.hashSync(body.password, saltRounds);
|
||||
|
||||
await prisma.user.create({
|
||||
data: {
|
||||
name: body.name,
|
||||
username: emailEnabled
|
||||
? undefined
|
||||
: (body.username as string).toLowerCase(),
|
||||
email: emailEnabled ? body.email?.toLowerCase() : undefined,
|
||||
password: hashedPassword,
|
||||
},
|
||||
});
|
||||
|
||||
return res.status(201).json({ response: "User successfully created." });
|
||||
} else if (checkIfUserExists) {
|
||||
return res
|
||||
.status(400)
|
||||
.json({ response: "Username and/or Email already exists." });
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
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 users(req: NextApiRequest, res: NextApiResponse) {
|
||||
const session = await getServerSession(req, res, authOptions);
|
||||
|
||||
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({
|
||||
response:
|
||||
"You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.",
|
||||
});
|
||||
|
||||
const lookupUsername = (req.query.username as string) || undefined;
|
||||
const lookupId = Number(req.query.id) || undefined;
|
||||
const isSelf =
|
||||
session.user.username === lookupUsername || session.user.id === lookupId
|
||||
? true
|
||||
: false;
|
||||
|
||||
if (req.method === "GET") {
|
||||
const users = await getUsers({
|
||||
params: {
|
||||
lookupUsername,
|
||||
lookupId,
|
||||
},
|
||||
isSelf,
|
||||
username: session.user.username,
|
||||
});
|
||||
return res.status(users.status).json({ response: users.response });
|
||||
} else if (req.method === "PUT") {
|
||||
const updated = await updateUser(req.body, session.user);
|
||||
return res.status(updated.status).json({ response: updated.response });
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import { getServerSession } from "next-auth/next";
|
||||
import { authOptions } from "pages/api/auth/[...nextauth]";
|
||||
import { authOptions } from "@/pages/api/v1/auth/[...nextauth]";
|
||||
import getPermission from "@/lib/api/getPermission";
|
||||
import readFile from "@/lib/api/storage/readFile";
|
||||
|
||||
@@ -21,10 +21,10 @@ export default async function Index(req: NextApiRequest, res: NextApiResponse) {
|
||||
"You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.",
|
||||
});
|
||||
|
||||
const collectionIsAccessible = await getPermission(
|
||||
session.user.id,
|
||||
Number(collectionId)
|
||||
);
|
||||
const collectionIsAccessible = await getPermission({
|
||||
userId: session.user.id,
|
||||
collectionId: Number(collectionId),
|
||||
});
|
||||
|
||||
if (!collectionIsAccessible)
|
||||
return res
|
||||
@@ -88,8 +88,7 @@ export const authOptions: AuthOptions = {
|
||||
|
||||
return session;
|
||||
},
|
||||
// Using the `...rest` parameter to be able to narrow down the type based on `trigger`
|
||||
async jwt({ token, trigger, session, user }) {
|
||||
async jwt({ token, trigger, user }) {
|
||||
const STRIPE_SECRET_KEY = process.env.STRIPE_SECRET_KEY;
|
||||
|
||||
const NEXT_PUBLIC_TRIAL_PERIOD_DAYS =
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import { getServerSession } from "next-auth/next";
|
||||
import { authOptions } from "pages/api/auth/[...nextauth]";
|
||||
import { authOptions } from "@/pages/api/v1/auth/[...nextauth]";
|
||||
import { prisma } from "@/lib/api/db";
|
||||
import readFile from "@/lib/api/storage/readFile";
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import { getServerSession } from "next-auth/next";
|
||||
import { authOptions } from "@/pages/api/v1/auth/[...nextauth]";
|
||||
import updateCollectionById from "@/lib/api/controllers/collections/collectionId/updateCollectionById";
|
||||
import deleteCollectionById from "@/lib/api/controllers/collections/collectionId/deleteCollectionById";
|
||||
|
||||
export default async function collections(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse
|
||||
) {
|
||||
const session = await getServerSession(req, res, authOptions);
|
||||
|
||||
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({
|
||||
response:
|
||||
"You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.",
|
||||
});
|
||||
|
||||
if (req.method === "PUT") {
|
||||
const updated = await updateCollectionById(
|
||||
session.user.id,
|
||||
Number(req.query.id) as number,
|
||||
req.body
|
||||
);
|
||||
return res.status(updated.status).json({ response: updated.response });
|
||||
} else if (req.method === "DELETE") {
|
||||
const deleted = await deleteCollectionById(
|
||||
session.user.id,
|
||||
Number(req.query.id) as number
|
||||
);
|
||||
return res.status(deleted.status).json({ response: deleted.response });
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,8 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import { getServerSession } from "next-auth/next";
|
||||
import { authOptions } from "@/pages/api/auth/[...nextauth]";
|
||||
import { authOptions } from "@/pages/api/v1/auth/[...nextauth]";
|
||||
import getCollections from "@/lib/api/controllers/collections/getCollections";
|
||||
import postCollection from "@/lib/api/controllers/collections/postCollection";
|
||||
import updateCollection from "@/lib/api/controllers/collections/updateCollection";
|
||||
import deleteCollection from "@/lib/api/controllers/collections/deleteCollection";
|
||||
|
||||
export default async function collections(
|
||||
req: NextApiRequest,
|
||||
@@ -30,11 +28,5 @@ export default async function collections(
|
||||
return res
|
||||
.status(newCollection.status)
|
||||
.json({ response: newCollection.response });
|
||||
} else if (req.method === "PUT") {
|
||||
const updated = await updateCollection(req.body, session.user.id);
|
||||
return res.status(updated.status).json({ response: updated.response });
|
||||
} else if (req.method === "DELETE") {
|
||||
const deleted = await deleteCollection(req.body, session.user.id);
|
||||
return res.status(deleted.status).json({ response: deleted.response });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// For future...
|
||||
// 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();
|
||||
// };
|
||||
@@ -0,0 +1,33 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import { getServerSession } from "next-auth/next";
|
||||
import { authOptions } from "@/pages/api/v1/auth/[...nextauth]";
|
||||
import deleteLinkById from "@/lib/api/controllers/links/linkId/deleteLinkById";
|
||||
import updateLinkById from "@/lib/api/controllers/links/linkId/updateLinkById";
|
||||
|
||||
export default async function links(req: NextApiRequest, res: NextApiResponse) {
|
||||
const session = await getServerSession(req, res, authOptions);
|
||||
|
||||
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({
|
||||
response:
|
||||
"You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.",
|
||||
});
|
||||
|
||||
if (req.method === "PUT") {
|
||||
const updated = await updateLinkById(
|
||||
session.user.id,
|
||||
Number(req.query.id),
|
||||
req.body
|
||||
);
|
||||
return res.status(updated.status).json({
|
||||
response: updated.response,
|
||||
});
|
||||
} else if (req.method === "DELETE") {
|
||||
const deleted = await deleteLinkById(session.user.id, Number(req.query.id));
|
||||
return res.status(deleted.status).json({
|
||||
response: deleted.response,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,8 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import { getServerSession } from "next-auth/next";
|
||||
import { authOptions } from "@/pages/api/auth/[...nextauth]";
|
||||
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 deleteLink from "@/lib/api/controllers/links/deleteLink";
|
||||
import updateLink from "@/lib/api/controllers/links/updateLink";
|
||||
|
||||
export default async function links(req: NextApiRequest, res: NextApiResponse) {
|
||||
const session = await getServerSession(req, res, authOptions);
|
||||
@@ -25,15 +23,5 @@ export default async function links(req: NextApiRequest, res: NextApiResponse) {
|
||||
return res.status(newlink.status).json({
|
||||
response: newlink.response,
|
||||
});
|
||||
} else if (req.method === "PUT") {
|
||||
const updated = await updateLink(req.body, session.user.id);
|
||||
return res.status(updated.status).json({
|
||||
response: updated.response,
|
||||
});
|
||||
} else if (req.method === "DELETE") {
|
||||
const deleted = await deleteLink(req.body, session.user.id);
|
||||
return res.status(deleted.status).json({
|
||||
response: deleted.response,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import { getServerSession } from "next-auth/next";
|
||||
import { authOptions } from "@/pages/api/auth/[...nextauth]";
|
||||
import { authOptions } from "@/pages/api/v1/auth/[...nextauth]";
|
||||
import exportData from "@/lib/api/controllers/migration/exportData";
|
||||
import importFromHTMLFile from "@/lib/api/controllers/migration/importFromHTMLFile";
|
||||
import importFromLinkwarden from "@/lib/api/controllers/migration/importFromLinkwarden";
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import { getServerSession } from "next-auth/next";
|
||||
import { authOptions } from "@/pages/api/auth/[...nextauth]";
|
||||
import { authOptions } from "@/pages/api/v1/auth/[...nextauth]";
|
||||
import paymentCheckout from "@/lib/api/paymentCheckout";
|
||||
import { Plan } from "@/types/global";
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import { getServerSession } from "next-auth/next";
|
||||
import { authOptions } from "@/pages/api/v1/auth/[...nextauth]";
|
||||
import updateTag from "@/lib/api/controllers/tags/tagId/updeteTagById";
|
||||
|
||||
export default async function tags(req: NextApiRequest, res: NextApiResponse) {
|
||||
const session = await getServerSession(req, res, authOptions);
|
||||
|
||||
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({
|
||||
response:
|
||||
"You are not a subscriber, feel free to reach out to us at support@linkwarden.app in case of any issues.",
|
||||
});
|
||||
|
||||
const tagId = Number(req.query.id);
|
||||
|
||||
if (req.method === "PUT") {
|
||||
const tags = await updateTag(session.user.id, tagId, req.body);
|
||||
return res.status(tags.status).json({ response: tags.response });
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import { getServerSession } from "next-auth/next";
|
||||
import { authOptions } from "@/pages/api/auth/[...nextauth]";
|
||||
import { authOptions } from "@/pages/api/v1/auth/[...nextauth]";
|
||||
import getTags from "@/lib/api/controllers/tags/getTags";
|
||||
|
||||
export default async function tags(req: NextApiRequest, res: NextApiResponse) {
|
||||
@@ -0,0 +1,40 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import { getServerSession } from "next-auth/next";
|
||||
import { authOptions } from "@/pages/api/v1/auth/[...nextauth]";
|
||||
import getUserById from "@/lib/api/controllers/users/userId/getUserById";
|
||||
import getPublicUserById from "@/lib/api/controllers/users/userId/getPublicUserById";
|
||||
import updateUserById from "@/lib/api/controllers/users/userId/updateUserById";
|
||||
|
||||
export default async function users(req: NextApiRequest, res: NextApiResponse) {
|
||||
const session = await getServerSession(req, res, authOptions);
|
||||
const userId = session?.user.id;
|
||||
const username = session?.user.username;
|
||||
|
||||
const lookupId = req.query.id as string;
|
||||
const isSelf =
|
||||
userId === Number(lookupId) || username === lookupId ? true : false;
|
||||
|
||||
// Check if "lookupId" is the user "id" or their "username"
|
||||
const isId = lookupId.split("").every((e) => Number.isInteger(parseInt(e)));
|
||||
|
||||
if (req.method === "GET" && !isSelf) {
|
||||
const users = await getPublicUserById(lookupId, isId, username);
|
||||
return res.status(users.status).json({ response: users.response });
|
||||
}
|
||||
|
||||
if (!userId) {
|
||||
return res.status(401).json({ response: "You must be logged in." });
|
||||
} else if (session?.user?.isSubscriber === false)
|
||||
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.",
|
||||
});
|
||||
|
||||
if (req.method === "GET") {
|
||||
const users = await getUserById(session.user.id);
|
||||
return res.status(users.status).json({ response: users.response });
|
||||
} else if (req.method === "PUT") {
|
||||
const updated = await updateUserById(session.user, req.body);
|
||||
return res.status(updated.status).json({ response: updated.response });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import postUser from "@/lib/api/controllers/users/postUser";
|
||||
|
||||
export default async function users(req: NextApiRequest, res: NextApiResponse) {
|
||||
if (req.method === "POST") {
|
||||
const response = await postUser(req, res);
|
||||
return response;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user