Merge branch 'dev' of https://github.com/linkwarden/linkwarden into feat/single-file
This commit is contained in:
@@ -9,6 +9,8 @@ import formidable from "formidable";
|
||||
import createFile from "@/lib/api/storage/createFile";
|
||||
import fs from "fs";
|
||||
import verifyToken from "@/lib/api/verifyToken";
|
||||
import generatePreview from "@/lib/api/generatePreview";
|
||||
import createFolder from "@/lib/api/storage/createFolder";
|
||||
|
||||
export const config = {
|
||||
api: {
|
||||
@@ -74,83 +76,97 @@ export default async function Index(req: NextApiRequest, res: NextApiResponse) {
|
||||
|
||||
return res.send(file);
|
||||
}
|
||||
} else if (req.method === "POST") {
|
||||
const user = await verifyUser({ req, res });
|
||||
if (!user) return;
|
||||
|
||||
const collectionPermissions = await getPermission({
|
||||
userId: user.id,
|
||||
linkId,
|
||||
});
|
||||
|
||||
const memberHasAccess = collectionPermissions?.members.some(
|
||||
(e: UsersAndCollections) => e.userId === user.id && e.canCreate
|
||||
);
|
||||
|
||||
if (!(collectionPermissions?.ownerId === user.id || memberHasAccess))
|
||||
return { response: "Collection is not accessible.", status: 401 };
|
||||
|
||||
// await uploadHandler(linkId, )
|
||||
|
||||
const MAX_UPLOAD_SIZE = Number(process.env.NEXT_PUBLIC_MAX_FILE_SIZE);
|
||||
|
||||
const form = formidable({
|
||||
maxFields: 1,
|
||||
maxFiles: 1,
|
||||
maxFileSize: MAX_UPLOAD_SIZE || 30 * 1048576,
|
||||
});
|
||||
|
||||
form.parse(req, async (err, fields, files) => {
|
||||
const allowedMIMETypes = [
|
||||
"application/pdf",
|
||||
"image/png",
|
||||
"image/jpg",
|
||||
"image/jpeg",
|
||||
];
|
||||
|
||||
if (
|
||||
err ||
|
||||
!files.file ||
|
||||
!files.file[0] ||
|
||||
!allowedMIMETypes.includes(files.file[0].mimetype || "")
|
||||
) {
|
||||
// Handle parsing error
|
||||
return res.status(500).json({
|
||||
response: `Sorry, we couldn't process your file. Please ensure it's a PDF, PNG, or JPG format and doesn't exceed ${MAX_UPLOAD_SIZE}MB.`,
|
||||
});
|
||||
} else {
|
||||
const fileBuffer = fs.readFileSync(files.file[0].filepath);
|
||||
|
||||
const linkStillExists = await prisma.link.findUnique({
|
||||
where: { id: linkId },
|
||||
});
|
||||
|
||||
if (linkStillExists && files.file[0].mimetype?.includes("image")) {
|
||||
const collectionId = collectionPermissions?.id as number;
|
||||
createFolder({
|
||||
filePath: `archives/preview/${collectionId}`,
|
||||
});
|
||||
|
||||
generatePreview(fileBuffer, collectionId, linkId);
|
||||
}
|
||||
|
||||
if (linkStillExists) {
|
||||
await createFile({
|
||||
filePath: `archives/${collectionPermissions?.id}/${
|
||||
linkId + suffix
|
||||
}`,
|
||||
data: fileBuffer,
|
||||
});
|
||||
|
||||
await prisma.link.update({
|
||||
where: { id: linkId },
|
||||
data: {
|
||||
preview: files.file[0].mimetype?.includes("pdf")
|
||||
? "unavailable"
|
||||
: undefined,
|
||||
image: files.file[0].mimetype?.includes("image")
|
||||
? `archives/${collectionPermissions?.id}/${linkId + suffix}`
|
||||
: null,
|
||||
pdf: files.file[0].mimetype?.includes("pdf")
|
||||
? `archives/${collectionPermissions?.id}/${linkId + suffix}`
|
||||
: null,
|
||||
lastPreserved: new Date().toISOString(),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
fs.unlinkSync(files.file[0].filepath);
|
||||
}
|
||||
|
||||
return res.status(200).json({
|
||||
response: files,
|
||||
});
|
||||
});
|
||||
}
|
||||
// else if (req.method === "POST") {
|
||||
// const user = await verifyUser({ req, res });
|
||||
// if (!user) return;
|
||||
|
||||
// const collectionPermissions = await getPermission({
|
||||
// userId: user.id,
|
||||
// linkId,
|
||||
// });
|
||||
|
||||
// const memberHasAccess = collectionPermissions?.members.some(
|
||||
// (e: UsersAndCollections) => e.userId === user.id && e.canCreate
|
||||
// );
|
||||
|
||||
// if (!(collectionPermissions?.ownerId === user.id || memberHasAccess))
|
||||
// return { response: "Collection is not accessible.", status: 401 };
|
||||
|
||||
// // await uploadHandler(linkId, )
|
||||
|
||||
// const MAX_UPLOAD_SIZE = Number(process.env.NEXT_PUBLIC_MAX_FILE_SIZE);
|
||||
|
||||
// const form = formidable({
|
||||
// maxFields: 1,
|
||||
// maxFiles: 1,
|
||||
// maxFileSize: MAX_UPLOAD_SIZE || 30 * 1048576,
|
||||
// });
|
||||
|
||||
// form.parse(req, async (err, fields, files) => {
|
||||
// const allowedMIMETypes = [
|
||||
// "application/pdf",
|
||||
// "image/png",
|
||||
// "image/jpg",
|
||||
// "image/jpeg",
|
||||
// ];
|
||||
|
||||
// if (
|
||||
// err ||
|
||||
// !files.file ||
|
||||
// !files.file[0] ||
|
||||
// !allowedMIMETypes.includes(files.file[0].mimetype || "")
|
||||
// ) {
|
||||
// // Handle parsing error
|
||||
// return res.status(500).json({
|
||||
// response: `Sorry, we couldn't process your file. Please ensure it's a PDF, PNG, or JPG format and doesn't exceed ${MAX_UPLOAD_SIZE}MB.`,
|
||||
// });
|
||||
// } else {
|
||||
// const fileBuffer = fs.readFileSync(files.file[0].filepath);
|
||||
|
||||
// const linkStillExists = await prisma.link.findUnique({
|
||||
// where: { id: linkId },
|
||||
// });
|
||||
|
||||
// if (linkStillExists) {
|
||||
// await createFile({
|
||||
// filePath: `archives/${collectionPermissions?.id}/${
|
||||
// linkId + suffix
|
||||
// }`,
|
||||
// data: fileBuffer,
|
||||
// });
|
||||
|
||||
// await prisma.link.update({
|
||||
// where: { id: linkId },
|
||||
// data: {
|
||||
// image: `archives/${collectionPermissions?.id}/${
|
||||
// linkId + suffix
|
||||
// }`,
|
||||
// lastPreserved: new Date().toISOString(),
|
||||
// },
|
||||
// });
|
||||
// }
|
||||
|
||||
// fs.unlinkSync(files.file[0].filepath);
|
||||
// }
|
||||
|
||||
// return res.status(200).json({
|
||||
// response: files,
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { prisma } from "@/lib/api/db";
|
||||
import NextAuth from "next-auth/next";
|
||||
import CredentialsProvider from "next-auth/providers/credentials";
|
||||
import { AuthOptions } from "next-auth";
|
||||
import bcrypt from "bcrypt";
|
||||
import EmailProvider from "next-auth/providers/email";
|
||||
import { PrismaAdapter } from "@auth/prisma-adapter";
|
||||
@@ -66,6 +65,7 @@ import ZohoProvider from "next-auth/providers/zoho";
|
||||
import ZoomProvider from "next-auth/providers/zoom";
|
||||
import * as process from "process";
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import { randomBytes } from "crypto";
|
||||
|
||||
const emailEnabled =
|
||||
process.env.EMAIL_FROM && process.env.EMAIL_SERVER ? true : false;
|
||||
@@ -106,22 +106,26 @@ if (
|
||||
email: username?.toLowerCase(),
|
||||
},
|
||||
],
|
||||
emailVerified: { not: null },
|
||||
}
|
||||
: {
|
||||
username: username.toLowerCase(),
|
||||
},
|
||||
});
|
||||
|
||||
if (!user) throw Error("Invalid credentials.");
|
||||
else if (!user?.emailVerified && emailEnabled) {
|
||||
throw Error("Email not verified.");
|
||||
}
|
||||
|
||||
let passwordMatches: boolean = false;
|
||||
|
||||
if (user?.password) {
|
||||
passwordMatches = bcrypt.compareSync(password, user.password);
|
||||
}
|
||||
|
||||
if (passwordMatches) {
|
||||
if (passwordMatches && user?.password) {
|
||||
return { id: user?.id };
|
||||
} else return null as any;
|
||||
} else throw Error("Invalid credentials.");
|
||||
},
|
||||
})
|
||||
);
|
||||
@@ -133,8 +137,26 @@ if (emailEnabled) {
|
||||
server: process.env.EMAIL_SERVER,
|
||||
from: process.env.EMAIL_FROM,
|
||||
maxAge: 1200,
|
||||
sendVerificationRequest(params) {
|
||||
sendVerificationRequest(params);
|
||||
async sendVerificationRequest({ identifier, url, provider, token }) {
|
||||
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.");
|
||||
|
||||
sendVerificationRequest({
|
||||
identifier,
|
||||
url,
|
||||
from: provider.from as string,
|
||||
token,
|
||||
});
|
||||
},
|
||||
})
|
||||
);
|
||||
@@ -240,6 +262,35 @@ if (process.env.NEXT_PUBLIC_AUTH0_ENABLED === "true") {
|
||||
};
|
||||
}
|
||||
|
||||
// Authelia
|
||||
if (process.env.NEXT_PUBLIC_AUTHELIA_ENABLED === "true") {
|
||||
providers.push({
|
||||
id: "authelia",
|
||||
name: "Authelia",
|
||||
type: "oauth",
|
||||
clientId: process.env.AUTHELIA_CLIENT_ID!,
|
||||
clientSecret: process.env.AUTHELIA_CLIENT_SECRET!,
|
||||
wellKnown: process.env.AUTHELIA_WELLKNOWN_URL!,
|
||||
authorization: { params: { scope: "openid email profile" } },
|
||||
idToken: true,
|
||||
checks: ["pkce", "state"],
|
||||
profile(profile) {
|
||||
return {
|
||||
id: profile.sub,
|
||||
name: profile.name,
|
||||
email: profile.email,
|
||||
username: profile.preferred_username,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
const _linkAccount = adapter.linkAccount;
|
||||
adapter.linkAccount = (account) => {
|
||||
const { "not-before-policy": _, refresh_expires_in, ...data } = account;
|
||||
return _linkAccount ? _linkAccount(data) : undefined;
|
||||
};
|
||||
}
|
||||
|
||||
// Authentik
|
||||
if (process.env.NEXT_PUBLIC_AUTHENTIK_ENABLED === "true") {
|
||||
providers.push(
|
||||
@@ -520,6 +571,9 @@ if (process.env.NEXT_PUBLIC_GOOGLE_ENABLED === "true") {
|
||||
GoogleProvider({
|
||||
clientId: process.env.GOOGLE_CLIENT_ID!,
|
||||
clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
|
||||
httpOptions: {
|
||||
timeout: 10000,
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
import { prisma } from "@/lib/api/db";
|
||||
import sendPasswordResetRequest from "@/lib/api/sendPasswordResetRequest";
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
export default async function forgotPassword(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse
|
||||
) {
|
||||
if (req.method === "POST") {
|
||||
const email = req.body.email;
|
||||
|
||||
if (!email) {
|
||||
return res.status(400).json({
|
||||
response: "Invalid email.",
|
||||
});
|
||||
}
|
||||
|
||||
const recentPasswordRequestsCount = await prisma.passwordResetToken.count({
|
||||
where: {
|
||||
identifier: email,
|
||||
createdAt: {
|
||||
gt: new Date(new Date().getTime() - 1000 * 60 * 5), // 5 minutes
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Rate limit password reset requests
|
||||
if (recentPasswordRequestsCount >= 3) {
|
||||
return res.status(400).json({
|
||||
response: "Too many requests. Please try again later.",
|
||||
});
|
||||
}
|
||||
|
||||
const user = await prisma.user.findFirst({
|
||||
where: {
|
||||
email,
|
||||
},
|
||||
});
|
||||
|
||||
if (!user || !user.email) {
|
||||
return res.status(400).json({
|
||||
response: "Invalid email.",
|
||||
});
|
||||
}
|
||||
|
||||
sendPasswordResetRequest(user.email, user.name);
|
||||
|
||||
return res.status(200).json({
|
||||
response: "Password reset email sent.",
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
import { prisma } from "@/lib/api/db";
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import bcrypt from "bcrypt";
|
||||
|
||||
export default async function resetPassword(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse
|
||||
) {
|
||||
if (req.method === "POST") {
|
||||
const token = req.body.token;
|
||||
const password = req.body.password;
|
||||
|
||||
if (!password || password.length < 8) {
|
||||
return res.status(400).json({
|
||||
response: "Password must be at least 8 characters.",
|
||||
});
|
||||
}
|
||||
|
||||
if (!token || typeof token !== "string") {
|
||||
return res.status(400).json({
|
||||
response: "Invalid token.",
|
||||
});
|
||||
}
|
||||
|
||||
// Hashed password
|
||||
const saltRounds = 10;
|
||||
const hashedPassword = await bcrypt.hash(password, saltRounds);
|
||||
|
||||
// Check token in db
|
||||
const verifyToken = await prisma.passwordResetToken.findFirst({
|
||||
where: {
|
||||
token,
|
||||
expires: {
|
||||
gt: new Date(),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (!verifyToken) {
|
||||
return res.status(400).json({
|
||||
response: "Invalid token.",
|
||||
});
|
||||
}
|
||||
|
||||
const email = verifyToken.identifier;
|
||||
|
||||
// Update password
|
||||
await prisma.user.update({
|
||||
where: {
|
||||
email,
|
||||
},
|
||||
data: {
|
||||
password: hashedPassword,
|
||||
},
|
||||
});
|
||||
|
||||
await prisma.passwordResetToken.update({
|
||||
where: {
|
||||
token,
|
||||
},
|
||||
data: {
|
||||
expires: new Date(),
|
||||
},
|
||||
});
|
||||
|
||||
// Delete tokens older than 5 minutes
|
||||
await prisma.passwordResetToken.deleteMany({
|
||||
where: {
|
||||
identifier: email,
|
||||
createdAt: {
|
||||
lt: new Date(new Date().getTime() - 1000 * 60 * 5), // 5 minutes
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return res.status(200).json({
|
||||
response: "Password has been reset successfully.",
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
import { prisma } from "@/lib/api/db";
|
||||
import updateCustomerEmail from "@/lib/api/updateCustomerEmail";
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
export default async function verifyEmail(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse
|
||||
) {
|
||||
if (req.method === "POST") {
|
||||
const token = req.query.token;
|
||||
|
||||
if (!token || typeof token !== "string") {
|
||||
return res.status(400).json({
|
||||
response: "Invalid token.",
|
||||
});
|
||||
}
|
||||
|
||||
// Check token in db
|
||||
const verifyToken = await prisma.verificationToken.findFirst({
|
||||
where: {
|
||||
token,
|
||||
expires: {
|
||||
gt: new Date(),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const oldEmail = verifyToken?.identifier;
|
||||
|
||||
if (!oldEmail) {
|
||||
return res.status(400).json({
|
||||
response: "Invalid token.",
|
||||
});
|
||||
}
|
||||
|
||||
// Ensure email isn't in use
|
||||
const findNewEmail = await prisma.user.findFirst({
|
||||
where: {
|
||||
email: oldEmail,
|
||||
},
|
||||
select: {
|
||||
unverifiedNewEmail: true,
|
||||
},
|
||||
});
|
||||
|
||||
const newEmail = findNewEmail?.unverifiedNewEmail;
|
||||
|
||||
if (!newEmail) {
|
||||
return res.status(400).json({
|
||||
response: "No unverified emails found.",
|
||||
});
|
||||
}
|
||||
|
||||
const emailInUse = await prisma.user.findFirst({
|
||||
where: {
|
||||
email: newEmail,
|
||||
},
|
||||
select: {
|
||||
email: true,
|
||||
},
|
||||
});
|
||||
|
||||
console.log(emailInUse);
|
||||
|
||||
if (emailInUse) {
|
||||
return res.status(400).json({
|
||||
response: "Email is already in use.",
|
||||
});
|
||||
}
|
||||
|
||||
// Remove SSO provider
|
||||
await prisma.account.deleteMany({
|
||||
where: {
|
||||
user: {
|
||||
email: oldEmail,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Update email in db
|
||||
await prisma.user.update({
|
||||
where: {
|
||||
email: oldEmail,
|
||||
},
|
||||
data: {
|
||||
email: newEmail.toLowerCase().trim(),
|
||||
unverifiedNewEmail: null,
|
||||
},
|
||||
});
|
||||
|
||||
// Apply to Stripe
|
||||
const STRIPE_SECRET_KEY = process.env.STRIPE_SECRET_KEY;
|
||||
|
||||
if (STRIPE_SECRET_KEY)
|
||||
await updateCustomerEmail(STRIPE_SECRET_KEY, oldEmail, newEmail);
|
||||
|
||||
// Clean up existing tokens
|
||||
await prisma.verificationToken.delete({
|
||||
where: {
|
||||
token,
|
||||
},
|
||||
});
|
||||
|
||||
await prisma.verificationToken.deleteMany({
|
||||
where: {
|
||||
identifier: oldEmail,
|
||||
},
|
||||
});
|
||||
|
||||
return res.status(200).json({
|
||||
response: token,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,8 @@ import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import { prisma } from "@/lib/api/db";
|
||||
import verifyUser from "@/lib/api/verifyUser";
|
||||
import isValidUrl from "@/lib/shared/isValidUrl";
|
||||
import removeFile from "@/lib/api/storage/removeFile";
|
||||
import { Collection, Link } from "@prisma/client";
|
||||
import { removeFiles } from "@/lib/api/manageLinkFiles";
|
||||
|
||||
const RE_ARCHIVE_LIMIT = Number(process.env.RE_ARCHIVE_LIMIT) || 5;
|
||||
|
||||
@@ -81,19 +81,5 @@ const deleteArchivedFiles = async (link: Link & { collection: Collection }) => {
|
||||
},
|
||||
});
|
||||
|
||||
await removeFile({
|
||||
filePath: `archives/${link.collection.id}/${link.id}.pdf`,
|
||||
});
|
||||
await removeFile({
|
||||
filePath: `archives/${link.collection.id}/${link.id}.png`,
|
||||
});
|
||||
await removeFile({
|
||||
filePath: `archives/${link.collection.id}/${link.id}_readability.json`,
|
||||
});
|
||||
await removeFile({
|
||||
filePath: `archives/${link.collection.id}/${link.id}.html`,
|
||||
});
|
||||
await removeFile({
|
||||
filePath: `archives/preview/${link.collection.id}/${link.id}.png`,
|
||||
});
|
||||
await removeFiles(link.id, link.collection.id);
|
||||
};
|
||||
|
||||
@@ -391,6 +391,13 @@ export function getLogins() {
|
||||
name: process.env.ZOOM_CUSTOM_NAME ?? "Zoom",
|
||||
});
|
||||
}
|
||||
// Authelia
|
||||
if (process.env.NEXT_PUBLIC_AUTHELIA_ENABLED === "true") {
|
||||
buttonAuths.push({
|
||||
method: "authelia",
|
||||
name: process.env.AUTHELIA_CUSTOM_NAME ?? "Authelia",
|
||||
});
|
||||
}
|
||||
return {
|
||||
credentialsEnabled:
|
||||
process.env.NEXT_PUBLIC_CREDENTIALS_ENABLED === "true" ||
|
||||
|
||||
@@ -4,6 +4,7 @@ import importFromHTMLFile from "@/lib/api/controllers/migration/importFromHTMLFi
|
||||
import importFromLinkwarden from "@/lib/api/controllers/migration/importFromLinkwarden";
|
||||
import { MigrationFormat, MigrationRequest } from "@/types/global";
|
||||
import verifyUser from "@/lib/api/verifyUser";
|
||||
import importFromWallabag from "@/lib/api/controllers/migration/importFromWallabag";
|
||||
|
||||
export const config = {
|
||||
api: {
|
||||
@@ -32,9 +33,10 @@ export default async function users(req: NextApiRequest, res: NextApiResponse) {
|
||||
let data;
|
||||
if (request.format === MigrationFormat.htmlFile)
|
||||
data = await importFromHTMLFile(user.id, request.data);
|
||||
|
||||
if (request.format === MigrationFormat.linkwarden)
|
||||
else if (request.format === MigrationFormat.linkwarden)
|
||||
data = await importFromLinkwarden(user.id, request.data);
|
||||
else if (request.format === MigrationFormat.wallabag)
|
||||
data = await importFromWallabag(user.id, request.data);
|
||||
|
||||
if (data) return res.status(data.status).json({ response: data.response });
|
||||
}
|
||||
|
||||
@@ -16,9 +16,17 @@ export default async function users(req: NextApiRequest, res: NextApiResponse) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const userId = token?.id;
|
||||
const user = await prisma.user.findUnique({
|
||||
where: {
|
||||
id: token?.id,
|
||||
},
|
||||
});
|
||||
|
||||
if (userId !== Number(req.query.id))
|
||||
const isServerAdmin = process.env.ADMINISTRATOR === user?.username;
|
||||
|
||||
const userId = isServerAdmin ? Number(req.query.id) : token.id;
|
||||
|
||||
if (userId !== Number(req.query.id) && !isServerAdmin)
|
||||
return res.status(401).json({ response: "Permission denied." });
|
||||
|
||||
if (req.method === "GET") {
|
||||
@@ -53,7 +61,7 @@ export default async function users(req: NextApiRequest, res: NextApiResponse) {
|
||||
const updated = await updateUserById(userId, req.body);
|
||||
return res.status(updated.status).json({ response: updated.response });
|
||||
} else if (req.method === "DELETE") {
|
||||
const updated = await deleteUserById(userId, req.body);
|
||||
const updated = await deleteUserById(userId, req.body, isServerAdmin);
|
||||
return res.status(updated.status).json({ response: updated.response });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,18 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import postUser from "@/lib/api/controllers/users/postUser";
|
||||
import getUsers from "@/lib/api/controllers/users/getUsers";
|
||||
import verifyUser from "@/lib/api/verifyUser";
|
||||
|
||||
export default async function users(req: NextApiRequest, res: NextApiResponse) {
|
||||
if (req.method === "POST") {
|
||||
const response = await postUser(req, res);
|
||||
return response;
|
||||
return res.status(response.status).json({ response: response.response });
|
||||
} else if (req.method === "GET") {
|
||||
const user = await verifyUser({ req, res });
|
||||
if (!user || process.env.ADMINISTRATOR !== user.username)
|
||||
return res.status(401).json({ response: "Unauthorized..." });
|
||||
|
||||
const response = await getUsers();
|
||||
return res.status(response.status).json({ response: response.response });
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user