mirror of
https://github.com/Leado123/sharesyllabus-server.git
synced 2025-12-13 22:57:28 +00:00
changed
This commit is contained in:
@@ -6,83 +6,89 @@ import { prisma } from "..";
|
|||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
router.get("/", async (req, res) => {
|
router.get("/", async (req, res) => {
|
||||||
if (req.files === null || req.files === undefined)
|
if (req.files === null || req.files === undefined)
|
||||||
return res.status(400).json({ msg: "No file uploaded" });
|
return res.status(400).json({ msg: "No file uploaded" });
|
||||||
if (req.files.upload === null)
|
if (req.files.upload === null)
|
||||||
return res.status(400).json({ msg: "No file uploaded" });
|
return res.status(400).json({ msg: "No file uploaded" });
|
||||||
if (Array.isArray(req.files.upload))
|
if (Array.isArray(req.files.upload))
|
||||||
return res.status(400).json({ msg: "Multiple files uploaded" });
|
return res.status(400).json({ msg: "Multiple files uploaded" });
|
||||||
const file = req.files.upload as fileUpload.UploadedFile;
|
const file = req.files.upload as fileUpload.UploadedFile;
|
||||||
|
|
||||||
if (![mime.lookup(".pdf"), mime.lookup(".docx")].includes(file.mimetype)) return res.status(400).json({ msg: "Invalid file type" });
|
if (![mime.lookup(".pdf"), mime.lookup(".docx")].includes(file.mimetype))
|
||||||
if (file.size > 5_000_000) {
|
return res.status(400).json({ msg: "Invalid file type" });
|
||||||
return res.status(400).json({ msg: "File too large (max 5MB)" });
|
if (file.size > 5_000_000) {
|
||||||
|
return res.status(400).json({ msg: "File too large (max 5MB)" });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add error handling for missing required fields
|
||||||
|
if (!req.body.schoolName || !req.body.className || !req.body.professor) {
|
||||||
|
return res.status(400).json({ msg: "Missing required fields" });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add proper error handling for file operations
|
||||||
|
try {
|
||||||
|
let school = await prisma.school.findUnique({
|
||||||
|
where: { name: req.body.schoolName },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!school) {
|
||||||
|
return res.status(404).json({ msg: "School not found" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let classRecord = await prisma.class.findFirst({
|
||||||
|
// Change findUnique to findFirst
|
||||||
|
where: {
|
||||||
|
className: req.body.className,
|
||||||
|
schoolId: school.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
// Add error handling for missing required fields
|
if (!classRecord) {
|
||||||
if (!req.body.schoolName || !req.body.className || !req.body.professor) {
|
return res.status(404).json({ msg: "Class not found" });
|
||||||
return res.status(400).json({ msg: "Missing required fields" });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add proper error handling for file operations
|
let professorObject = await prisma.professor.findUnique({
|
||||||
try {
|
where: { name: req.body.professor },
|
||||||
let school = await prisma.school.findUnique({
|
});
|
||||||
where: { name: req.body.schoolName },
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!school) {
|
if (!professorObject) {
|
||||||
return res.status(404).json({ msg: "School not found" });
|
professorObject = await prisma.professor.create({
|
||||||
}
|
data: {
|
||||||
|
name: req.body.professor,
|
||||||
let classRecord = await prisma.class.findFirst({ // Change findUnique to findFirst
|
schoolId: school.id,
|
||||||
where: {
|
},
|
||||||
className: req.body.className,
|
});
|
||||||
schoolId: school.id,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!classRecord) {
|
|
||||||
return res.status(404).json({ msg: "Class not found" });
|
|
||||||
}
|
|
||||||
|
|
||||||
let professorObject = await prisma.professor.findUnique({
|
|
||||||
where: { name: req.body.professor },
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!professorObject) {
|
|
||||||
professorObject = await prisma.professor.create({
|
|
||||||
data: {
|
|
||||||
name: req.body.professor,
|
|
||||||
schoolId: school.id,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
let { id } = await prisma.syllabus.create({
|
|
||||||
data: {
|
|
||||||
mimeType: file.mimetype,
|
|
||||||
createdByName: req.body.name || undefined,
|
|
||||||
createdByEmail: req.body.email || undefined,
|
|
||||||
fullClassName: req.body.fullClassName || undefined,
|
|
||||||
classLength: req.body.classLength ? parseInt(req.body.classLength, 10) : undefined,
|
|
||||||
textbookCost: req.body.textbookCost || undefined,
|
|
||||||
description: req.body.description || undefined,
|
|
||||||
content: "", // Add the content property
|
|
||||||
class: { connect: { id: classRecord.id } },
|
|
||||||
professorObject: { connect: { id: professorObject.id } },
|
|
||||||
school: { connect: { id: school.id } },
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
await file.mv(`./syllabi/${id}.${mime.extension(file.mimetype)}`);
|
|
||||||
return res.status(200).json({ id });
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error creating syllabus:', error);
|
|
||||||
if (error instanceof Error) {
|
|
||||||
return res.status(500).json({ msg: "Internal server error", error: error.message });
|
|
||||||
}
|
|
||||||
return res.status(500).json({ msg: "Internal server error" });
|
|
||||||
}
|
}
|
||||||
|
let { id } = await prisma.syllabus.create({
|
||||||
|
data: {
|
||||||
|
mimeType: file.mimetype,
|
||||||
|
professor: req.body.professor, // Required string field
|
||||||
|
createdByName: req.body.name || undefined,
|
||||||
|
createdByEmail: req.body.email || undefined,
|
||||||
|
fullClassName: req.body.fullClassName || undefined,
|
||||||
|
classLength: req.body.classLength
|
||||||
|
? parseInt(req.body.classLength, 10)
|
||||||
|
: undefined,
|
||||||
|
textbookCost: req.body.textbookCost || undefined,
|
||||||
|
description: req.body.description || undefined,
|
||||||
|
content: "", // Add the content property
|
||||||
|
class: { connect: { id: classRecord.id } },
|
||||||
|
Professor: { connect: { id: professorObject.id } },
|
||||||
|
school: { connect: { id: school.id } },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await file.mv(`./syllabi/${id}.${mime.extension(file.mimetype)}`);
|
||||||
|
return res.status(200).json({ id });
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error creating syllabus:", error);
|
||||||
|
if (error instanceof Error) {
|
||||||
|
return res
|
||||||
|
.status(500)
|
||||||
|
.json({ msg: "Internal server error", error: error.message });
|
||||||
|
}
|
||||||
|
return res.status(500).json({ msg: "Internal server error" });
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
|||||||
591
src/index.ts
591
src/index.ts
@@ -5,356 +5,395 @@ import fileUpload from "express-fileupload";
|
|||||||
import http from "node:http";
|
import http from "node:http";
|
||||||
import fuzzysort from "fuzzysort";
|
import fuzzysort from "fuzzysort";
|
||||||
import mime from "mime-types";
|
import mime from "mime-types";
|
||||||
import jwt from 'jsonwebtoken';
|
import jwt from "jsonwebtoken";
|
||||||
import argon2 from 'argon2';
|
import argon2 from "argon2";
|
||||||
import { idText } from "typescript";
|
import { idText } from "typescript";
|
||||||
import 'dotenv/config';
|
import "dotenv/config";
|
||||||
import { jwtMiddleware } from "./authMiddleware";
|
import { jwtMiddleware } from "./authMiddleware";
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
const httpServer = http.createServer(app);
|
const httpServer = http.createServer(app);
|
||||||
|
|
||||||
const prisma = new PrismaClient();
|
export const prisma = new PrismaClient();
|
||||||
|
|
||||||
app.use(cors({
|
app.use(
|
||||||
|
cors({
|
||||||
origin: "*", // TODO change this to the actual domain
|
origin: "*", // TODO change this to the actual domain
|
||||||
}))
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
app.use(express.json());
|
app.use(express.json());
|
||||||
|
|
||||||
app.use(fileUpload());
|
app.use(fileUpload());
|
||||||
|
|
||||||
app.use('/files', express.static('syllabi'));
|
app.use("/files", express.static("syllabi"));
|
||||||
|
|
||||||
app.post("/create", async (req, res) => {
|
app.post("/create", async (req, res) => {
|
||||||
console.debug(req.body);
|
console.debug(req.body);
|
||||||
if (req.files === null || req.files === undefined)
|
if (req.files === null || req.files === undefined)
|
||||||
return res.status(400).json({ msg: "No file uploaded" });
|
return res.status(400).json({ msg: "No file uploaded" });
|
||||||
if (req.files.upload === null)
|
if (req.files.upload === null)
|
||||||
return res.status(400).json({ msg: "No file uploaded" });
|
return res.status(400).json({ msg: "No file uploaded" });
|
||||||
if (Array.isArray(req.files.upload))
|
if (Array.isArray(req.files.upload))
|
||||||
return res.status(400).json({ msg: "Multiple files uploaded" });
|
return res.status(400).json({ msg: "Multiple files uploaded" });
|
||||||
const file = req.files.upload as fileUpload.UploadedFile;
|
const file = req.files.upload as fileUpload.UploadedFile;
|
||||||
|
|
||||||
if (![mime.lookup(".pdf"), mime.lookup(".docx")].includes(file.mimetype)) return res.status(400).json({ msg: "Invalid file type" });
|
if (![mime.lookup(".pdf"), mime.lookup(".docx")].includes(file.mimetype))
|
||||||
if (file.size > 5_000_000) {
|
return res.status(400).json({ msg: "Invalid file type" });
|
||||||
return res.status(400).json({ msg: "File too large (max 5MB)" });
|
if (file.size > 5_000_000) {
|
||||||
|
return res.status(400).json({ msg: "File too large (max 5MB)" });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add error handling for missing required fields
|
||||||
|
if (!req.body.schoolName || !req.body.className || !req.body.professor) {
|
||||||
|
return res.status(400).json({ msg: "Missing required fields" });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add proper error handling for file operations
|
||||||
|
try {
|
||||||
|
let school = await prisma.school.findUnique({
|
||||||
|
where: { name: req.body.schoolName },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!school) {
|
||||||
|
return res.status(404).json({ msg: "School not found" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let classRecord = await prisma.class.findFirst({
|
||||||
|
// Change findUnique to findFirst
|
||||||
|
where: {
|
||||||
|
className: req.body.className,
|
||||||
|
schoolId: school.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
// Add error handling for missing required fields
|
if (!classRecord) {
|
||||||
if (!req.body.schoolName || !req.body.className || !req.body.professor) {
|
return res.status(404).json({ msg: "Class not found" });
|
||||||
return res.status(400).json({ msg: "Missing required fields" });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add proper error handling for file operations
|
let professorObject = await prisma.professor.findUnique({
|
||||||
try {
|
where: { name: req.body.professor },
|
||||||
let school = await prisma.school.findUnique({
|
});
|
||||||
where: { name: req.body.schoolName },
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!school) {
|
if (!professorObject) {
|
||||||
return res.status(404).json({ msg: "School not found" });
|
professorObject = await prisma.professor.create({
|
||||||
}
|
data: {
|
||||||
|
name: req.body.professor,
|
||||||
let classRecord = await prisma.class.findFirst({ // Change findUnique to findFirst
|
schoolId: school.id,
|
||||||
where: {
|
},
|
||||||
className: req.body.className,
|
});
|
||||||
schoolId: school.id,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!classRecord) {
|
|
||||||
return res.status(404).json({ msg: "Class not found" });
|
|
||||||
}
|
|
||||||
|
|
||||||
let professorObject = await prisma.professor.findUnique({
|
|
||||||
where: { name: req.body.professor },
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!professorObject) {
|
|
||||||
professorObject = await prisma.professor.create({
|
|
||||||
data: {
|
|
||||||
name: req.body.professor,
|
|
||||||
schoolId: school.id,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
let { id } = await prisma.syllabus.create({
|
|
||||||
data: {
|
|
||||||
mimeType: file.mimetype,
|
|
||||||
createdByName: req.body.name || undefined,
|
|
||||||
createdByEmail: req.body.email || undefined,
|
|
||||||
fullClassName: req.body.fullClassName || undefined,
|
|
||||||
classLength: req.body.classLength ? parseInt(req.body.classLength, 10) : undefined,
|
|
||||||
textbookCost: req.body.textbookCost || undefined,
|
|
||||||
description: req.body.description || undefined,
|
|
||||||
content: "", // Add the content property
|
|
||||||
class: { connect: { id: classRecord.id } },
|
|
||||||
professorObject: { connect: { id: professorObject.id } },
|
|
||||||
school: { connect: { id: school.id } },
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
await file.mv(`./syllabi/${id}.${mime.extension(file.mimetype)}`);
|
|
||||||
return res.status(200).json({ id });
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error creating syllabus:', error);
|
|
||||||
if (error instanceof Error) {
|
|
||||||
return res.status(500).json({ msg: "Internal server error", error: error.message });
|
|
||||||
}
|
|
||||||
return res.status(500).json({ msg: "Internal server error" });
|
|
||||||
}
|
}
|
||||||
|
let { id } = await prisma.syllabus.create({
|
||||||
|
data: {
|
||||||
|
mimeType: file.mimetype,
|
||||||
|
professor: req.body.professor, // Required string field
|
||||||
|
createdByName: req.body.name || undefined,
|
||||||
|
createdByEmail: req.body.email || undefined,
|
||||||
|
fullClassName: req.body.fullClassName || undefined,
|
||||||
|
classLength: req.body.classLength
|
||||||
|
? parseInt(req.body.classLength, 10)
|
||||||
|
: undefined,
|
||||||
|
textbookCost: req.body.textbookCost || undefined,
|
||||||
|
description: req.body.description || undefined,
|
||||||
|
content: "", // Add the content property
|
||||||
|
class: { connect: { id: classRecord.id } },
|
||||||
|
Professor: { connect: { id: professorObject.id } },
|
||||||
|
school: { connect: { id: school.id } },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await file.mv(`./syllabi/${id}.${mime.extension(file.mimetype)}`);
|
||||||
|
return res.status(200).json({ id });
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error creating syllabus:", error);
|
||||||
|
if (error instanceof Error) {
|
||||||
|
return res
|
||||||
|
.status(500)
|
||||||
|
.json({ msg: "Internal server error", error: error.message });
|
||||||
|
}
|
||||||
|
return res.status(500).json({ msg: "Internal server error" });
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get("/schools", async (req, res) => {
|
app.get("/schools", async (req, res) => {
|
||||||
let colleges = await prisma.school.findMany({});
|
let colleges = await prisma.school.findMany({});
|
||||||
res.json(colleges);
|
res.json(colleges);
|
||||||
})
|
});
|
||||||
|
|
||||||
app.post("/search/class/", async (req, res) => {
|
app.post("/search/class/", async (req, res) => {
|
||||||
let take = req.body.take || 10;
|
let take = req.body.take || 10;
|
||||||
let skip = req.body.skip || 0;
|
let skip = req.body.skip || 0;
|
||||||
|
|
||||||
if (await prisma.school.findUnique({ where: { name: req.query.s as string } }) === null) return res.status(404).json({ msg: "School not found" });
|
if (
|
||||||
|
(await prisma.school.findUnique({
|
||||||
|
where: { name: req.query.s as string },
|
||||||
|
})) === null
|
||||||
|
)
|
||||||
|
return res.status(404).json({ msg: "School not found" });
|
||||||
|
|
||||||
let classes = await prisma.class.findMany({
|
let classes = await prisma.class.findMany({
|
||||||
where: {
|
where: {
|
||||||
school: {
|
school: {
|
||||||
name: req.query.s as string,
|
name: req.query.s as string,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let results = classes;
|
||||||
|
|
||||||
let results = classes;
|
if (req.query.q) {
|
||||||
|
results = fuzzysort
|
||||||
|
.go(req.query.q as string, classes, {
|
||||||
|
keys: ["className", "fullClassName"],
|
||||||
|
})
|
||||||
|
.map((i) => i.obj);
|
||||||
|
}
|
||||||
|
|
||||||
if (req.query.q) {
|
res.json(results.slice(skip, skip + take));
|
||||||
results = fuzzysort.go(req.query.q as string, classes, { keys: ["className", "fullClassName"] }).map(i => i.obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
res.json(results.slice(skip, skip + take));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
app.post("/search/professor/", async (req, res) => {
|
app.post("/search/professor/", async (req, res) => {
|
||||||
let take = req.body.take || 10;
|
let take = req.body.take || 10;
|
||||||
let skip = req.body.skip || 0;
|
let skip = req.body.skip || 0;
|
||||||
|
|
||||||
if (await prisma.school.findUnique({ where: { name: req.query.s as string } }) === null) return res.status(404).json({ msg: "School not found" });
|
if (
|
||||||
|
(await prisma.school.findUnique({
|
||||||
|
where: { name: req.query.s as string },
|
||||||
|
})) === null
|
||||||
|
)
|
||||||
|
return res.status(404).json({ msg: "School not found" });
|
||||||
|
|
||||||
let professors = await prisma.professor.findMany({
|
let professors = await prisma.professor.findMany({
|
||||||
where: {
|
where: {
|
||||||
school: {
|
school: {
|
||||||
name: req.query.s as string,
|
name: req.query.s as string,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
let results = professors;
|
let results = professors;
|
||||||
|
|
||||||
if (req.query.q) {
|
if (req.query.q) {
|
||||||
results = fuzzysort.go(req.query.q as string, professors, { keys: ["name"] }).map(i => i.obj);
|
results = fuzzysort
|
||||||
}
|
.go(req.query.q as string, professors, { keys: ["name"] })
|
||||||
|
.map((i) => i.obj);
|
||||||
|
}
|
||||||
|
|
||||||
res.json(results.slice(skip, skip + take));
|
res.json(results.slice(skip, skip + take));
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get("/professor/:id", async (req, res) => {
|
app.get("/professor/:id", async (req, res) => {
|
||||||
let professor = await prisma.professor.findUnique({
|
let professor = await prisma.professor.findUnique({
|
||||||
where: { id: req.params.id },
|
where: { id: req.params.id },
|
||||||
|
include: {
|
||||||
|
school: true,
|
||||||
|
syllabi: {
|
||||||
include: {
|
include: {
|
||||||
school: true,
|
class: true,
|
||||||
syllabi: {
|
|
||||||
include: {
|
|
||||||
class: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
});
|
},
|
||||||
if (professor === null) return res.status(404).json({ msg: "Professor not found" });
|
},
|
||||||
return res.json({
|
});
|
||||||
name: professor.name,
|
if (professor === null)
|
||||||
school: professor.school?.name,
|
return res.status(404).json({ msg: "Professor not found" });
|
||||||
syllabi: professor.syllabi.map(i => {
|
return res.json({
|
||||||
return {
|
name: professor.name,
|
||||||
id: i.id,
|
school: professor.school?.name,
|
||||||
className: i.class?.className,
|
syllabi: professor.syllabi.map((i) => {
|
||||||
fullClassName: i.fullClassName,
|
return {
|
||||||
textbookCost: i.textbookCost,
|
id: i.id,
|
||||||
classLength: i.classLength,
|
className: i.class?.className,
|
||||||
description: i.description,
|
fullClassName: i.fullClassName,
|
||||||
dateCreated: i.dateCreated.toISOString(),
|
textbookCost: i.textbookCost,
|
||||||
fileName: `${i.id}.${mime.extension(i.mimeType)}`,
|
classLength: i.classLength,
|
||||||
};
|
description: i.description,
|
||||||
}),
|
dateCreated: i.dateCreated.toISOString(),
|
||||||
});
|
fileName: `${i.id}.${mime.extension(i.mimeType)}`,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get("/syllabus/:id", async (req, res) => {
|
app.get("/syllabus/:id", async (req, res) => {
|
||||||
let syllabus = await prisma.syllabus.findUnique({
|
let syllabus = await prisma.syllabus.findUnique({
|
||||||
where: { id: req.params.id},
|
where: { id: req.params.id },
|
||||||
|
include: {
|
||||||
|
class: {
|
||||||
include: {
|
include: {
|
||||||
class: {
|
discipline: true,
|
||||||
include: {
|
|
||||||
discipline: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
professorObject: true,
|
|
||||||
},
|
},
|
||||||
});
|
},
|
||||||
if (syllabus === null) return res.status(404).json({ msg: "Syllabus not found" });
|
Professor: true,
|
||||||
return res.json({
|
},
|
||||||
className: syllabus.class?.className,
|
});
|
||||||
description: syllabus.description,
|
if (syllabus === null)
|
||||||
fullClassName: syllabus.fullClassName,
|
return res.status(404).json({ msg: "Syllabus not found" });
|
||||||
textbookCost: syllabus.textbookCost,
|
return res.json({
|
||||||
content: syllabus.content,
|
className: syllabus.class?.className,
|
||||||
classLength: syllabus.classLength,
|
description: syllabus.description,
|
||||||
professor: syllabus.professorObject?.name,
|
fullClassName: syllabus.fullClassName,
|
||||||
dateCreated: syllabus.dateCreated.toISOString(),
|
textbookCost: syllabus.textbookCost,
|
||||||
fileName: `${syllabus.id}.${mime.extension(syllabus.mimeType)}`,
|
content: syllabus.content,
|
||||||
class: {
|
classLength: syllabus.classLength,
|
||||||
className: syllabus.class?.className ?? '',
|
professor: syllabus.Professor?.[0]?.name,
|
||||||
fullClassName: syllabus.class?.fullClassName ?? '',
|
dateCreated: syllabus.dateCreated.toISOString(),
|
||||||
discipline: syllabus.class?.discipline?.name ?? '',
|
fileName: `${syllabus.id}.${mime.extension(syllabus.mimeType)}`,
|
||||||
},
|
class: {
|
||||||
});
|
className: syllabus.class?.className ?? "",
|
||||||
|
fullClassName: syllabus.class?.fullClassName ?? "",
|
||||||
|
discipline: syllabus.class?.discipline?.name ?? "",
|
||||||
|
},
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get("/syllabus/:id/download", async (req, res) => {
|
app.get("/syllabus/:id/download", async (req, res) => {
|
||||||
let syllabus = await prisma.syllabus.findUnique({
|
let syllabus = await prisma.syllabus.findUnique({
|
||||||
where: { id: req.params.id, reviewed: true },
|
where: { id: req.params.id, reviewed: true },
|
||||||
include: {
|
include: {
|
||||||
class: true,
|
class: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (syllabus === null) return res.status(404).json({ msg: "Syllabus not found" });
|
if (syllabus === null)
|
||||||
res.download(`./syllabi/${syllabus.id}.${mime.extension(syllabus.mimeType)}`);
|
return res.status(404).json({ msg: "Syllabus not found" });
|
||||||
|
res.download(`./syllabi/${syllabus.id}.${mime.extension(syllabus.mimeType)}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get("/search/", async (req, res) => {
|
app.get("/search/", async (req, res) => {
|
||||||
try {
|
try {
|
||||||
let syllabi = await prisma.syllabus.findMany({
|
let syllabi = await prisma.syllabus.findMany({
|
||||||
include: {
|
include: {
|
||||||
class: {
|
class: {
|
||||||
include: {
|
include: {
|
||||||
discipline: true,
|
discipline: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
professorObject: true,
|
Professor: true,
|
||||||
school: true,
|
school: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
let results = syllabi;
|
let results = syllabi;
|
||||||
|
|
||||||
if (req.query.s) {
|
if (req.query.s) {
|
||||||
results = results.filter(i => i.school?.name === req.query.s);
|
results = results.filter((i) => i.school?.name === req.query.s);
|
||||||
}
|
|
||||||
|
|
||||||
if (req.query.c) {
|
|
||||||
results = results.filter(i => i.class?.className === req.query.c);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (req.query.p) {
|
|
||||||
results = results.filter(i => i.professorObject?.name === req.query.p);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (req.query.q) {
|
|
||||||
results = fuzzysort.go(req.query.q as string, results, { keys: ["class.className", "professorObject.name", "class.fullClassName"] }).map(i => i.obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
let take = req.query.take as unknown as number || 10;
|
|
||||||
let skip = req.query.skip as unknown as number || 0;
|
|
||||||
|
|
||||||
res.json(results.map(i => {
|
|
||||||
return {
|
|
||||||
id: i.id,
|
|
||||||
className: i.class?.className,
|
|
||||||
professor: i.professorObject?.name ?? '',
|
|
||||||
fullClassName: i.fullClassName,
|
|
||||||
textbookCost: i.textbookCost,
|
|
||||||
description: i.description,
|
|
||||||
classLength: i.classLength,
|
|
||||||
dateCreated: i.dateCreated.toISOString(),
|
|
||||||
fileName: `${i.id}.${mime.extension(i.mimeType)}`,
|
|
||||||
class: {
|
|
||||||
className: i.class?.className ?? '',
|
|
||||||
fullClassName: i.class?.fullClassName ?? '',
|
|
||||||
discipline: i.class?.discipline?.name ?? '',
|
|
||||||
},
|
|
||||||
professorId: i.professorObject?.id ?? '',
|
|
||||||
school: {
|
|
||||||
name: i.school?.name ?? '',
|
|
||||||
id: i.school?.id ?? '',
|
|
||||||
fullName: i.school?.fullName ?? '',
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}).slice(skip).slice(0, take));
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
res.status(500).json({ msg: "Internal server error" });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (req.query.c) {
|
||||||
|
results = results.filter((i) => i.class?.className === req.query.c);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req.query.p) {
|
||||||
|
results = results.filter((i) => i.Professor?.[0]?.name === req.query.p);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req.query.q) {
|
||||||
|
results = fuzzysort
|
||||||
|
.go(req.query.q as string, results, {
|
||||||
|
keys: ["class.className", "Professor.0.name", "class.fullClassName"],
|
||||||
|
})
|
||||||
|
.map((i) => i.obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
let take = (req.query.take as unknown as number) || 10;
|
||||||
|
let skip = (req.query.skip as unknown as number) || 0;
|
||||||
|
|
||||||
|
res.json(
|
||||||
|
results
|
||||||
|
.map((i) => {
|
||||||
|
return {
|
||||||
|
id: i.id,
|
||||||
|
className: i.class?.className,
|
||||||
|
professor: i.Professor?.[0]?.name ?? "",
|
||||||
|
fullClassName: i.fullClassName,
|
||||||
|
textbookCost: i.textbookCost,
|
||||||
|
description: i.description,
|
||||||
|
classLength: i.classLength,
|
||||||
|
dateCreated: i.dateCreated.toISOString(),
|
||||||
|
fileName: `${i.id}.${mime.extension(i.mimeType)}`,
|
||||||
|
class: {
|
||||||
|
className: i.class?.className ?? "",
|
||||||
|
fullClassName: i.class?.fullClassName ?? "",
|
||||||
|
discipline: i.class?.discipline?.name ?? "",
|
||||||
|
},
|
||||||
|
professorId: i.Professor?.[0]?.id ?? "",
|
||||||
|
school: {
|
||||||
|
name: i.school?.name ?? "",
|
||||||
|
id: i.school?.id ?? "",
|
||||||
|
fullName: i.school?.fullName ?? "",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.slice(skip)
|
||||||
|
.slice(0, take),
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
res.status(500).json({ msg: "Internal server error" });
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
app.post("/report/:id", async (req, res) => {
|
app.post("/report/:id", async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const { reportType, reportTitle, reportBody, reportBy } = req.body;
|
const { reportType, reportTitle, reportBody, reportBy } = req.body;
|
||||||
const syllabusId = req.params.id;
|
const syllabusId = req.params.id;
|
||||||
|
|
||||||
// Check if the syllabus exists
|
// Check if the syllabus exists
|
||||||
const syllabus = await prisma.syllabus.findUnique({ where: { id: syllabusId } });
|
const syllabus = await prisma.syllabus.findUnique({
|
||||||
if (!syllabus) {
|
where: { id: syllabusId },
|
||||||
return res.status(404).json({ msg: "Syllabus not found" });
|
});
|
||||||
}
|
if (!syllabus) {
|
||||||
|
return res.status(404).json({ msg: "Syllabus not found" });
|
||||||
// Create the report
|
|
||||||
const report = await prisma.report.create({
|
|
||||||
data: {
|
|
||||||
reportType,
|
|
||||||
reportTitle,
|
|
||||||
reportBody,
|
|
||||||
reportBy,
|
|
||||||
syllabusId,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
res.json(report);
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
res.status(500).json({ msg: `Internal Server Error ${e}` });
|
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
// Create the report
|
||||||
|
const report = await prisma.report.create({
|
||||||
|
data: {
|
||||||
|
reportType,
|
||||||
|
reportTitle,
|
||||||
|
reportBody,
|
||||||
|
reportBy,
|
||||||
|
syllabusId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
res.json(report);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
res.status(500).json({ msg: `Internal Server Error ${e}` });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
app.post("/moderator/login", async (req, res) => {
|
app.post("/moderator/login", async (req, res) => {
|
||||||
const { username, password } = req.body;
|
const { username, password } = req.body;
|
||||||
|
|
||||||
if (!username || !password) {
|
|
||||||
return res.status(400).json({ msg: "Missing username or password" });
|
|
||||||
}
|
|
||||||
|
|
||||||
const moderator = await prisma.moderator.findUnique({ where: { username } });
|
if (!username || !password) {
|
||||||
if (!moderator) {
|
return res.status(400).json({ msg: "Missing username or password" });
|
||||||
return res.status(401).json({ msg: "Invalid username or password" });
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const valid = await argon2.verify(moderator.password, password);
|
const moderator = await prisma.moderator.findUnique({ where: { username } });
|
||||||
if (!valid) {
|
if (!moderator) {
|
||||||
return res.status(401).json({ msg: "Invalid username or password" });
|
return res.status(401).json({ msg: "Invalid username or password" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const token = jwt.sign({ id: moderator.id }, process.env.SECRET_KEY as string, { expiresIn: '2h' });
|
const valid = await argon2.verify(moderator.password, password);
|
||||||
|
if (!valid) {
|
||||||
res.json({ token });
|
return res.status(401).json({ msg: "Invalid username or password" });
|
||||||
return;
|
}
|
||||||
|
|
||||||
|
const token = jwt.sign(
|
||||||
|
{ id: moderator.id },
|
||||||
|
process.env.SECRET_KEY as string,
|
||||||
|
{ expiresIn: "2h" },
|
||||||
|
);
|
||||||
|
|
||||||
|
res.json({ token });
|
||||||
|
return;
|
||||||
});
|
});
|
||||||
|
|
||||||
app.post("/moderator/flag", jwtMiddleware, async (req, res) => {
|
app.post("/moderator/flag", jwtMiddleware, async (req, res) => {
|
||||||
res.json(req.body);
|
res.json(req.body);
|
||||||
});
|
});
|
||||||
|
|
||||||
await new Promise<void>((resolve) =>
|
await new Promise<void>((resolve) =>
|
||||||
httpServer.listen({ port: 4000, host: "0.0.0.0" }, resolve)
|
httpServer.listen({ port: 4000, host: "0.0.0.0" }, resolve),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user