diff --git a/backend/.gitignore b/backend/.gitignore index c09b77d..39b82a9 100644 --- a/backend/.gitignore +++ b/backend/.gitignore @@ -1,5 +1,4 @@ node_modules # Keep environment variables out of version control .env -dist .DS_Store diff --git a/backend/dist/controllers/ratingController.js b/backend/dist/controllers/ratingController.js new file mode 100644 index 0000000..446caa0 --- /dev/null +++ b/backend/dist/controllers/ratingController.js @@ -0,0 +1,53 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.calAvgRating = void 0; +const express_async_handler_1 = __importDefault(require("express-async-handler")); +const prisma_1 = __importDefault(require("../lib/prisma")); +// @ts-ignore +const calAvgRating = (0, express_async_handler_1.default)((req, res) => __awaiter(void 0, void 0, void 0, function* () { + const { college } = req.body; + if (!college || typeof college !== "string") { + return res.status(400).json({ message: "Invalid request" }); + } + try { + const reviews = yield prisma_1.default.review.findMany({ + where: { + College: { + name: { + contains: college, + mode: "insensitive", + }, + }, + }, + select: { + rating: true, + review: true, + }, + }); + let avgRating = 0; + let count = 0; + for (const review of reviews) { + avgRating += review.rating; + count++; + } + avgRating /= count; + res.status(200).json({ avgRating }); + } + catch (error) { + console.error(error); + res.status(500).json({ message: "Internal server error" }); + } +})); +exports.calAvgRating = calAvgRating; diff --git a/backend/dist/controllers/reviewControllers.js b/backend/dist/controllers/reviewControllers.js new file mode 100644 index 0000000..8806366 --- /dev/null +++ b/backend/dist/controllers/reviewControllers.js @@ -0,0 +1,272 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.editReview = exports.deleteReview = exports.getFullReview = exports.getBulkReviews = exports.filterReviews = exports.postReview = void 0; +const express_async_handler_1 = __importDefault(require("express-async-handler")); +const prisma_1 = __importDefault(require("../lib/prisma")); +// @ts-ignore +const postReview = (0, express_async_handler_1.default)((req, res, next) => __awaiter(void 0, void 0, void 0, function* () { + var _a; + const { review, rating, college, course: Ucourse, reviewForCollege, } = req.body; + // @ts-ignore + const user_id = req.user.user_id; + if (!review || !rating || (!college && !Ucourse)) { + return res.status(400).json({ message: "Required fields are missing" }); + } + if (rating < 1 || rating > 5) { + return res.status(400).json({ message: "Rating must be between 1 and 5" }); + } + try { + const user = yield prisma_1.default.user.findFirst({ + where: { user_id }, + }); + if (!user) { + return res.status(404).json({ message: "User not found" }); + } + const { collegeEmailVerified, emailVerified } = user; + if (!collegeEmailVerified || !emailVerified) { + return res.status(403).json({ + message: "Please verify your college email to write a review", + }); + } + const courses = yield prisma_1.default.userCourse.findMany({ + select: { + Course: { + select: { + course_id: true, + name: true, + isOnline: true, + College: { + select: { + college_id: true, + name: true, + }, + }, + }, + }, + }, + where: { user_id }, + }); + const findCourse = (condition) => { + return courses.find(condition); + }; + const createReview = (reviewData) => __awaiter(void 0, void 0, void 0, function* () { + try { + yield prisma_1.default.review.create({ + data: reviewData, + }); + return res.status(201).json({ message: "Review written successfully" }); + } + catch (err) { + console.error("Error creating review:", err); + return res.status(500).json({ message: "Internal server error" }); + } + }); + if (reviewForCollege && college) { + const course = findCourse((course) => { var _a; return ((_a = course.Course.College) === null || _a === void 0 ? void 0 : _a.name.toLowerCase()) === college.toLowerCase(); }); + if (course) { + const courseCollegeId = (_a = course.Course.College) === null || _a === void 0 ? void 0 : _a.college_id; + yield createReview({ + user_id, + college_id: courseCollegeId, + rating, + review, + createdAt: new Date(), + }); + return res.status(201).json({ message: "Review written for college" }); + } + else { + return res + .status(404) + .json({ message: "You were never enrolled in this college" }); + } + } + else if (!reviewForCollege && Ucourse) { + const course = findCourse((course) => course.Course.name.toLowerCase() === Ucourse.toLowerCase()); + if (course) { + const courseId = course.Course.course_id; + yield createReview({ + user_id, + course_id: courseId, + rating, + review, + createdAt: new Date(), + }); + return res.status(201).json({ message: "Review written for course" }); + } + else { + return res + .status(404) + .json({ message: "You were never enrolled in this course" }); + } + } + else { + return res.status(400).json({ message: "Invalid request" }); + } + } + catch (error) { + console.error(error); + return res.status(500).json({ message: "Internal server error" }); + } +})); +exports.postReview = postReview; +// @ts-ignore +const getBulkReviews = (0, express_async_handler_1.default)((req, res) => __awaiter(void 0, void 0, void 0, function* () { + const { reviewIds } = req.body; + if (!reviewIds || typeof reviewIds !== "string") { + return res.status(400).json({ message: "Invalid request" }); + } + try { + const reviews = yield prisma_1.default.review.findMany({}); + return res.status(200).json(reviews); + } + catch (error) { + console.error(error); + return res.status(500).json({ message: "Internal server error" }); + } +})); +exports.getBulkReviews = getBulkReviews; +// @ts-ignore +const filterReviews = (0, express_async_handler_1.default)((req, res) => __awaiter(void 0, void 0, void 0, function* () { + const { keyword } = req.query; + if (!keyword || typeof keyword !== "string") { + return res + .status(400) + .send("Keyword query parameter is required and should be a string"); + } + try { + const reviews = yield prisma_1.default.review.findMany({ + where: { + OR: [ + { + College: { + name: { + contains: keyword, + mode: "insensitive", + }, + }, + }, + { + Course: { + name: { + contains: keyword, + mode: "insensitive", + }, + }, + }, + ], + }, + select: { + review_id: true, + review: true, + rating: true, + createdAt: true, + updatedAt: true, + College: true, + Course: true, + User: true, + }, + }); + res.json(reviews); + } + catch (error) { + console.error(error); + res.status(500).send("An error occurred while fetching reviews"); + } +})); +exports.filterReviews = filterReviews; +// @ts-ignore +const getFullReview = (0, express_async_handler_1.default)((req, res) => __awaiter(void 0, void 0, void 0, function* () { + const { reviewId } = req.params; + const review = yield prisma_1.default.review.findFirst({ + where: { + review_id: reviewId, + }, + }); + if (!review) { + return res.status(404).json({ message: "Review not found" }); + } + try { + return res.status(200).json(review); + } + catch (error) { + console.error(error); + return res.status(500).json({ message: "Internal server error" }); + } +})); +exports.getFullReview = getFullReview; +// @ts-ignore +const deleteReview = (0, express_async_handler_1.default)((req, res) => __awaiter(void 0, void 0, void 0, function* () { + const { reviewId } = req.params; + // @ts-ignore + const user_id = req.user.user_id; + const review = yield prisma_1.default.review.findFirst({ + where: { + review_id: reviewId, + user_id, + }, + }); + if (!review) { + return res.status(404).json({ message: "Review not found" }); + } + try { + yield prisma_1.default.review.delete({ + where: { + review_id: reviewId, + user_id, + }, + }); + return res.status(200).json({ message: "Review deleted" }); + } + catch (error) { + console.error(error); + return res.status(500).json({ message: "Internal server error" }); + } +})); +exports.deleteReview = deleteReview; +// @ts-ignore +const editReview = (0, express_async_handler_1.default)((req, res) => __awaiter(void 0, void 0, void 0, function* () { + const { reviewId } = req.params; + const { rating, updateReview } = req.body; + // @ts-ignore + const user_id = req.user.user_id; + const review = yield prisma_1.default.review.findFirst({ + where: { + review_id: reviewId, + user_id, + }, + }); + if (!review) { + return res.status(404).json({ message: "Review not found" }); + } + try { + yield prisma_1.default.review.update({ + where: { + review_id: reviewId, + user_id, + }, + data: { + rating, + review: updateReview, + updatedAt: new Date(), + }, + }); + return res.status(200).json({ message: "Review updated" }); + } + catch (error) { + console.error(error); + return res.status(500).json({ message: "Internal server error" }); + } +})); +exports.editReview = editReview; diff --git a/backend/dist/controllers/userControllers.js b/backend/dist/controllers/userControllers.js new file mode 100644 index 0000000..47192aa --- /dev/null +++ b/backend/dist/controllers/userControllers.js @@ -0,0 +1,200 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.verifyUser = exports.loginUser = exports.registerUser = void 0; +const express_async_handler_1 = __importDefault(require("express-async-handler")); +const prisma_1 = __importDefault(require("../lib/prisma")); +const jsonwebtoken_1 = __importDefault(require("jsonwebtoken")); +const bcrypt_1 = __importDefault(require("bcrypt")); +const sendMail_1 = __importDefault(require("../mail/sendMail")); +const academic_email_verifier_1 = require("academic-email-verifier"); +const checkAcademic_1 = __importDefault(require("../mail/checkAcademic")); +const registerUser = (0, express_async_handler_1.default)((req, res) => __awaiter(void 0, void 0, void 0, function* () { + let { email, name, password, collegeName, courseName, isOnline, location } = req.body; + const hashedPassword = yield bcrypt_1.default.hash(password, 8); + if (!email || !name || !password) { + res.status(400).json({ message: "Please provide all fields" }); + return; + } + const userExists = yield prisma_1.default.user.findUnique({ + where: { + email, + }, + }); + if (userExists) { + res.status(409).json({ message: "User already exists" }); + return; + } + let isCollegeEmail; + if ((0, checkAcademic_1.default)(email)) { + isCollegeEmail = true; + } + else { + isCollegeEmail = yield academic_email_verifier_1.Verifier.isAcademic(email); + } + if (isCollegeEmail == true) { + if (!collegeName || !courseName || !isOnline || !location) { + res.status(400).json({ message: "Please provide all fields" }); + return; + } + if (isOnline === "true") { + isOnline = true; + } + else { + isOnline = false; + } + let college = yield prisma_1.default.college.findFirst({ + where: { + name: collegeName, + }, + }); + if (!college) { + college = yield prisma_1.default.college.create({ + data: { + name: collegeName, + location, + }, + }); + } + const college_id = college.college_id; + let course = yield prisma_1.default.course.findFirst({ + where: { + name: courseName, + }, + }); + let course_id; + if (course) { + course_id = course.course_id; + } + else { + course = yield prisma_1.default.course.create({ + data: { + name: courseName, + college_id, + isOnline, + }, + }); + course_id = course.course_id; + } + const user = yield prisma_1.default.user.create({ + data: { + email, + password: hashedPassword, + name, + collegeEmailVerified: true, + }, + }); + const userCourse = yield prisma_1.default.userCourse.create({ + data: { + user_id: user.user_id, + course_id, + }, + }); + const exp = Date.now() + 1000 * 60 * 5; + // @ts-ignore + const token = jsonwebtoken_1.default.sign({ sub: user.user_id, exp }, process.env.SECRET); + const url = `https://localhost:3000/api/user/verify/${token}`; + const htmlContent = `Verify using this link`; + // @ts-ignore + yield (0, sendMail_1.default)(email, htmlContent); + res.status(201).json({ message: "User created" }); + } + else { + const user = yield prisma_1.default.user.create({ + data: { + email, + password: hashedPassword, + name, + collegeEmailVerified: false, + }, + }); + const exp = Date.now() + 1000 * 60 * 5; + // @ts-ignore + const token = jsonwebtoken_1.default.sign({ sub: user.user_id, exp }, process.env.SECRET); + const url = `http://localhost:3000/api/user/verify/${token}`; + const htmlContent = `Verify using this link`; + // @ts-ignore + yield (0, sendMail_1.default)(email, htmlContent); + res.status(201).json({ message: "User created" }); + } +})); +exports.registerUser = registerUser; +const verifyUser = (0, express_async_handler_1.default)((req, res) => __awaiter(void 0, void 0, void 0, function* () { + const token = req.params.token; + if (!token) { + res.status(400).json({ message: "Invalid token" }); + return; + } + // @ts-ignore + const { sub, exp } = jsonwebtoken_1.default.verify(token, process.env.SECRET); + // @ts-ignore + if (exp < Date.now()) { + res.status(400).json({ message: "Token expired" }); + return; + } + const user = yield prisma_1.default.user.findUnique({ + where: { + user_id: sub, + }, + }); + if (!user) { + res.status(404).json({ message: "User not found" }); + return; + } + if (user.emailVerified) { + res.status(400).json({ message: "User already verified" }); + return; + } + yield prisma_1.default.user.update({ + where: { + user_id: sub, + }, + data: { + emailVerified: true, + }, + }); + res.status(200).json({ message: "User verified" }); +})); +exports.verifyUser = verifyUser; +const loginUser = (0, express_async_handler_1.default)((req, res) => __awaiter(void 0, void 0, void 0, function* () { + const { email, password } = req.body; + if (!email || !password) { + res.status(400).json({ message: "Please provide all fields" }); + return; + } + const user = yield prisma_1.default.user.findUnique({ + where: { + email, + }, + }); + if (!user) { + res.status(404).json({ message: "User not found" }); + return; + } + const match = yield bcrypt_1.default.compare(password, user.password); + if (!match) { + res.status(401).json({ message: "Invalid credentials" }); + return; + } + const exp = Date.now() + 1000 * 60 * 60 * 24 * 30; + // @ts-ignore + const token = jsonwebtoken_1.default.sign({ sub: user.user_id, exp }, process.env.SECRET); + res.cookie("Authorization", token, { + httpOnly: true, + secure: false, + sameSite: "lax", + }); + res.status(200).json({ message: "User logged in" }); +})); +exports.loginUser = loginUser; diff --git a/backend/dist/index.js b/backend/dist/index.js new file mode 100644 index 0000000..8895eac --- /dev/null +++ b/backend/dist/index.js @@ -0,0 +1,30 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const express_1 = __importDefault(require("express")); +const cors_1 = __importDefault(require("cors")); +const cookie_parser_1 = __importDefault(require("cookie-parser")); +require("dotenv/config"); +const userRoutes_1 = __importDefault(require("./routes/userRoutes")); +const mRuote_1 = __importDefault(require("./routes/mRuote")); +const reviewRoutes_1 = __importDefault(require("./routes/reviewRoutes")); +const ratingRoute_1 = __importDefault(require("./routes/ratingRoute")); +const app = (0, express_1.default)(); +app.use(express_1.default.json()); +const corsOptions = { + origin: 'http://localhost:3001', + credentials: true, +}; +app.use((0, cors_1.default)(corsOptions)); +app.use((0, cookie_parser_1.default)()); +app.use("/api/user", userRoutes_1.default); +//actual path (/api/admin/reviews/approve) +// body :-> {"content":"....."} +app.use("/api/admin", mRuote_1.default); +app.use("/api/review", reviewRoutes_1.default); +app.use("/api/rating", ratingRoute_1.default); +app.listen(process.env.PORT, () => { + console.log(`Server is listening on port ${process.env.PORT}`); +}); diff --git a/backend/dist/lib/convertor.js b/backend/dist/lib/convertor.js new file mode 100644 index 0000000..97b95da --- /dev/null +++ b/backend/dist/lib/convertor.js @@ -0,0 +1,54 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const fs = __importStar(require("fs")); +function sortWordsInJson() { + // Read the content of the wordlist.json file + fs.readFile("wordlist.json", "utf-8", (err, data) => { + if (err) { + console.error("Error reading file:", err); + return; + } + // Parse the JSON content to get the array of words + let wordsArray = JSON.parse(data).words; + // Sort the array of words + wordsArray.sort(); + // Prepare the JSON object with the sorted words + const sortedWordsObject = { + words: wordsArray, + }; + // Stringify the JSON object + const sortedWordsString = JSON.stringify(sortedWordsObject, null, 2); + // Write the sorted array back to the wordlist.json file + fs.writeFile("wordlist.json", sortedWordsString, (err) => { + if (err) { + console.error("Error writing file:", err); + return; + } + console.log("Word list sorted and saved successfully."); + }); + }); +} +sortWordsInJson(); diff --git a/backend/dist/lib/prisma.js b/backend/dist/lib/prisma.js new file mode 100644 index 0000000..a3a3576 --- /dev/null +++ b/backend/dist/lib/prisma.js @@ -0,0 +1,5 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const client_1 = require("@prisma/client"); +const prisma = new client_1.PrismaClient(); +exports.default = prisma; diff --git a/backend/dist/mail/checkAcademic.js b/backend/dist/mail/checkAcademic.js new file mode 100644 index 0000000..fa19b3b --- /dev/null +++ b/backend/dist/mail/checkAcademic.js @@ -0,0 +1,38 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const fs_1 = __importDefault(require("fs")); +const path_1 = __importDefault(require("path")); +// Import the CommonJS module for __dirname and rename it +const currentDir = require("./dirNameHelper"); +// Function to check if an email has a valid college domain +function checkCollegeEmail(email) { + const filePath = path_1.default.join(currentDir, "emails.json"); + const domains = JSON.parse(fs_1.default.readFileSync(filePath, "utf8")); + // Extract the domain from the email + const emailDomain = email.split("@")[1]; + // Perform binary search + return binarySearch(domains, emailDomain); +} +// Function to perform binary search on a sorted array +function binarySearch(arr, target) { + let left = 0; + let right = arr.length - 1; + while (left <= right) { + const mid = Math.floor((left + right) / 2); + const midVal = arr[mid]; + if (midVal === target) { + return true; + } + else if (midVal < target) { + left = mid + 1; + } + else { + right = mid - 1; + } + } + return false; +} +exports.default = checkCollegeEmail; diff --git a/backend/dist/mail/dirNameHelper.js b/backend/dist/mail/dirNameHelper.js new file mode 100644 index 0000000..bf90db1 --- /dev/null +++ b/backend/dist/mail/dirNameHelper.js @@ -0,0 +1,2 @@ +// dirnameHelper.js +module.exports = __dirname; diff --git a/backend/dist/mail/emails.json b/backend/dist/mail/emails.json new file mode 100644 index 0000000..8ec52c5 --- /dev/null +++ b/backend/dist/mail/emails.json @@ -0,0 +1,8 @@ +[ + "aec.edu", + "anothercollege.edu", + "iitkgp.ac.in", + "jadavpuruniversity.in", + "taylorswift.com", + "techno.in" +] diff --git a/backend/dist/mail/sendMail.js b/backend/dist/mail/sendMail.js new file mode 100644 index 0000000..3d9ed1e --- /dev/null +++ b/backend/dist/mail/sendMail.js @@ -0,0 +1,38 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const nodemailer_1 = __importDefault(require("nodemailer")); +const express_async_handler_1 = __importDefault(require("express-async-handler")); +const transporter = nodemailer_1.default.createTransport({ + // @ts-ignore + host: process.env.BREVO_HOST, + port: process.env.BREVO_PORT, + secure: false, // Use `true` for port 465, `false` for all other ports + auth: { + user: process.env.BREVO_USER, + pass: process.env.BREVO_PASSWORD, + }, +}); +const sendMail = (0, express_async_handler_1.default)((email, url) => __awaiter(void 0, void 0, void 0, function* () { + yield transporter.sendMail({ + from: '"Review" ', + // @ts-ignore + to: email, + subject: "URL/OTP for verification", + text: "Single use URL/OTP", + // @ts-ignore + html: url, + }); +})); +exports.default = sendMail; diff --git a/backend/dist/middleware/checkAuth.js b/backend/dist/middleware/checkAuth.js new file mode 100644 index 0000000..81b6504 --- /dev/null +++ b/backend/dist/middleware/checkAuth.js @@ -0,0 +1,47 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const jsonwebtoken_1 = __importDefault(require("jsonwebtoken")); +const prisma_js_1 = __importDefault(require("../lib/prisma.js")); +// @ts-ignore +function requireAuth(req, res, next) { + return __awaiter(this, void 0, void 0, function* () { + try { + const token = req.cookies.Authorization; + // @ts-ignore + const decoded = jsonwebtoken_1.default.verify(token, process.env.SECRET); + // @ts-ignore + if (Date.now() >= decoded.exp) { + res.sendStatus(410); + return; + } + const user = yield prisma_js_1.default.user.findUnique({ + where: { + user_id: decoded.sub, + }, + }); + if (!user) { + res.sendStatus(401); + return; + } + req.user = user; + next(); + } + catch (err) { + res.sendStatus(401); + return; + } + }); +} +exports.default = requireAuth; diff --git a/backend/dist/middleware/moderation.js b/backend/dist/middleware/moderation.js new file mode 100644 index 0000000..f6c2fa1 --- /dev/null +++ b/backend/dist/middleware/moderation.js @@ -0,0 +1,81 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.checkModerationForString = checkModerationForString; +exports.checkModeration = checkModeration; +const promises_1 = __importDefault(require("fs/promises")); +function binarySearch(items, value) { + var startIndex = 0, stopIndex = items.length - 1, middle = Math.floor((stopIndex + startIndex) / 2); + while (items[middle] != value && startIndex < stopIndex) { + //adjust search area + if (value < items[middle]) { + stopIndex = middle - 1; + } + else if (value > items[middle]) { + startIndex = middle + 1; + } + //recalculate middle + middle = Math.floor((stopIndex + startIndex) / 2); + } + //make sure it's the right value + return items[middle] != value ? 0 : 1; +} +function checkModerationForString(content) { + return __awaiter(this, void 0, void 0, function* () { + try { + const data = yield promises_1.default.readFile("./src/lib/wordlist.json", "utf8"); + const wordList = JSON.parse(data).words; + const words = content.split(/\s+/); + let isClean = true; + for (let word of words) { + if (binarySearch(wordList.map((w) => w.toUpperCase()), word.toUpperCase())) { + isClean = false; + break; + } + } + return isClean; + } + catch (err) { + console.error("Error processing the word list:", err); + throw err; + } + }); +} +function checkModeration(req, res, next) { + const fs = require("fs"); + //for some reason it is taking backend folder as the root folder + fs.readFile("./src/lib/wordlist.json", (err, data) => { + if (!err) { + data = JSON.parse(data); + let contents = req.body.content; + let content = contents.split(" "); + var flag = true; + for (let i = 0; i < content.length; i++) { + // performing the binary searcing + if (binarySearch(data.words, content[i].toUpperCase())) { + flag = false; + break; + } + } + if (flag) { + res.status(200); + res.send("1"); + } + else { + res.status(401); + res.send("0"); + } + } + }); +} diff --git a/backend/dist/routes/mRuote.js b/backend/dist/routes/mRuote.js new file mode 100644 index 0000000..b06acb0 --- /dev/null +++ b/backend/dist/routes/mRuote.js @@ -0,0 +1,10 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const express_1 = __importDefault(require("express")); +const moderation_js_1 = require("../middleware/moderation.js"); +const router = express_1.default.Router(); +router.post("/reviews/approve", moderation_js_1.checkModeration); +exports.default = router; diff --git a/backend/dist/routes/ratingRoute.js b/backend/dist/routes/ratingRoute.js new file mode 100644 index 0000000..f54dff4 --- /dev/null +++ b/backend/dist/routes/ratingRoute.js @@ -0,0 +1,10 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const express_1 = __importDefault(require("express")); +const ratingController_1 = require("../controllers/ratingController"); +const router = express_1.default.Router(); +router.route("/rating").get(ratingController_1.calAvgRating); +exports.default = router; diff --git a/backend/dist/routes/reviewRoutes.js b/backend/dist/routes/reviewRoutes.js new file mode 100644 index 0000000..734cfe5 --- /dev/null +++ b/backend/dist/routes/reviewRoutes.js @@ -0,0 +1,16 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const express_1 = __importDefault(require("express")); +const reviewControllers_1 = require("../controllers/reviewControllers"); +const checkAuth_1 = __importDefault(require("../middleware/checkAuth")); +const reviewRoute = express_1.default.Router(); +reviewRoute.post("/", checkAuth_1.default, reviewControllers_1.postReview); +reviewRoute.get("/", reviewControllers_1.filterReviews); +reviewRoute.post("/bulk", reviewControllers_1.getBulkReviews); +reviewRoute.delete("/delete/:reviewId", checkAuth_1.default, reviewControllers_1.deleteReview); +reviewRoute.put("/edit/:reviewId", checkAuth_1.default, reviewControllers_1.editReview); +reviewRoute.get("/:reviewId", reviewControllers_1.getFullReview); +exports.default = reviewRoute; diff --git a/backend/dist/routes/userRoutes.js b/backend/dist/routes/userRoutes.js new file mode 100644 index 0000000..b30a574 --- /dev/null +++ b/backend/dist/routes/userRoutes.js @@ -0,0 +1,12 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const express_1 = __importDefault(require("express")); +const userControllers_1 = require("../controllers/userControllers"); +const router = express_1.default.Router(); +router.route("/register").post(userControllers_1.registerUser); +router.route("/login").post(userControllers_1.loginUser); +router.route("/verify/:token").get(userControllers_1.verifyUser); +exports.default = router; diff --git a/backend/dist/seed.js b/backend/dist/seed.js new file mode 100644 index 0000000..a59032a --- /dev/null +++ b/backend/dist/seed.js @@ -0,0 +1,28 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const prisma_1 = __importDefault(require("./lib/prisma")); +function main() { + return __awaiter(this, void 0, void 0, function* () { + const user = yield prisma_1.default.user.create({ + data: { + email: "xxx@gmail.com", + name: "Alice", + password: "123456", + }, + }); + console.log(user); + }); +} +main();