diff --git a/src/app.ts b/src/app.ts index cd934b9..64af9a5 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,8 +1,9 @@ import cookieParser from 'cookie-parser'; import cors from 'cors'; import express from 'express'; -import routes from './routes'; import passport from 'passport'; +import routes from './routes'; +import { NotFoundError, SuccessResponse } from './utils/apiResponse'; const app = express(); @@ -23,12 +24,12 @@ app.use('/quiz', routes.quizRoutes); // Home Route app.get('/', cors(), async (req, res) => { - res.status(200).json({ name: 'Interview Experience API' }); + return SuccessResponse(res, { name: 'Interview Experience API' }); }); // Not found route app.get('*', cors(), (req, res) => { - return res.status(404).json({ message: 'API URL is not valid' }); + return NotFoundError(res, { message: 'API URL is not valid' }); }); export default app; diff --git a/src/controller/comment.controller.ts b/src/controller/comment.controller.ts index 990ce7d..911bf13 100644 --- a/src/controller/comment.controller.ts +++ b/src/controller/comment.controller.ts @@ -4,6 +4,13 @@ import { Types } from 'mongoose'; import commentServices from '../services/comment.service'; import { TypeRequestBody } from '../types/request.types'; import { IAuthToken } from '../types/token.types'; +import { + BadRequestError, + InternalServerError, + NotFoundError, + SuccessResponse, + UnauthorizedError, +} from '../utils/apiResponse'; const commentController = { getComment: async ( @@ -12,7 +19,7 @@ const commentController = { ) => { const postId = req.params['postid']; if (!Types.ObjectId.isValid(postId)) { - return res.status(404).json({ message: 'No such post found...' }); + return NotFoundError(res, { message: 'No such post found...' }); } // query page = 0 for the backend that's why (-1) @@ -22,7 +29,7 @@ const commentController = { if (!limit || limit <= 0) limit = 10; if (limit > 100) { - return res.status(500).json({ message: 'Limit cannot exceed 100' }); + return InternalServerError(res, { message: 'Limit cannot exceed 100' }); } if (!page || page < 0) { @@ -35,7 +42,7 @@ const commentController = { const comments = await commentServices.getComment(postId, skip, limit); if (!comments || comments.length === 0) { - return res.status(200).json({ + return SuccessResponse(res, { message: 'No comments', data: [], page: { @@ -47,14 +54,14 @@ const commentController = { const previousPage = page === 0 ? undefined : page; const nextPage = page + 2; - return res.status(200).json({ + return SuccessResponse(res, { message: 'comments fetched successfully', data: comments, page: { nextPage, previousPage }, }); } catch (error) { console.log(error); - return res.status(500).json({ message: 'Something went wrong....' }); + return InternalServerError(res, { message: 'Something went wrong....' }); } }, createComment: async ( @@ -69,15 +76,15 @@ const commentController = { const postId = req.params['postid']; if (!Types.ObjectId.isValid(postId)) { - return res - .status(404) - .json({ message: 'Please provide a valid post to create comment' }); + return NotFoundError(res, { + message: 'Please provide a valid post to create comment', + }); } if (!content) { - return res - .status(401) - .json({ message: 'Comment is Empty, please provide content' }); + return UnauthorizedError(res, { + message: 'Comment is Empty, please provide content', + }); } try { @@ -88,18 +95,18 @@ const commentController = { ); if (!commentId) { - return res - .status(404) - .json({ message: 'Please provide a valid Post to Comment' }); + return NotFoundError(res, { + message: 'Please provide a valid Post to Comment', + }); } - return res.status(200).json({ + return SuccessResponse(res, { message: 'Comment Created Successfully', commentId: commentId, }); } catch (error) { console.log(error); - return res.status(500).json({ message: 'Something went wrong.....' }); + return InternalServerError(res, { message: 'Something went wrong.....' }); } }, deleteComment: async (req: Request, res: Response) => { @@ -109,9 +116,9 @@ const commentController = { const postId = req.params['postid']; const commentId = req.params['commentid']; if (!Types.ObjectId.isValid(postId) || !Types.ObjectId.isValid(commentId)) { - return res - .status(404) - .json({ message: 'Please provide a valid Comment to Delete' }); + return NotFoundError(res, { + message: 'Please provide a valid Comment to Delete', + }); } try { @@ -134,19 +141,17 @@ const commentController = { // Check the condition if the given comment was successfully deleted or not if (!commentDeleteResponse.acknowledged) { - return res.status(400).json({ message: 'Something went wrong...' }); + return BadRequestError(res, { message: 'Something went wrong...' }); } if (commentDeleteResponse.modifiedCount === 0) { - return res - .status(404) - .json({ message: 'Comment Could not be Deleted' }); + return NotFoundError(res, { message: 'Comment Could not be Deleted' }); } - return res.status(200).json({ message: 'Comment Deleted Successfully' }); + return SuccessResponse(res, { message: 'Comment Deleted Successfully' }); } catch (error) { console.log(error); - return res.status(500).json({ message: 'Something went wrong...' }); + return InternalServerError(res, { message: 'Something went wrong...' }); } }, getCommentReplies: async (req: Request, res: Response) => { @@ -154,9 +159,9 @@ const commentController = { const commentId = req.params['commentid']; if (!Types.ObjectId.isValid(postId) || !Types.ObjectId.isValid(commentId)) { - return res - .status(404) - .json({ message: 'Please provide a valid Post with Comment to reply' }); + return NotFoundError(res, { + message: 'Please provide a valid Post with Comment to reply', + }); } let page = parseInt(req.query['page'] as string) - 1; @@ -166,7 +171,7 @@ const commentController = { if (!limit || limit <= 0) limit = 10; if (limit > 100) { - return res.status(500).json({ message: 'Limit cannot exceed 100' }); + return InternalServerError(res, { message: 'Limit cannot exceed 100' }); } // default page @@ -186,7 +191,7 @@ const commentController = { ); if (!replies || replies.length === 0) { - return res.status(200).json({ + return SuccessResponse(res, { message: 'No replies to display', data: [], page: { @@ -202,14 +207,14 @@ const commentController = { // previous page is returned as page because for 1 based indexing page is the previous page as page-1 is done const previousPage = page === 0 ? undefined : page; - return res.status(200).json({ + return SuccessResponse(res, { message: 'Replies fetched successfully', data: replies, page: { nextPage, previousPage }, }); } catch (error) { console.log(error); - return res.status(500).json({ message: 'Something went wrong.....' }); + return InternalServerError(res, { message: 'Something went wrong.....' }); } }, createCommentReply: async ( @@ -225,15 +230,15 @@ const commentController = { const postId = req.params['postid']; const commentId = req.params['commentid']; if (!Types.ObjectId.isValid(postId) || !Types.ObjectId.isValid(commentId)) { - return res - .status(404) - .json({ message: 'Please provide a valid Post with Comment to reply' }); + return NotFoundError(res, { + message: 'Please provide a valid Post with Comment to reply', + }); } if (!content) { - return res - .status(401) - .json({ message: 'Reply is Empty, please provide content' }); + return UnauthorizedError(res, { + message: 'Reply is Empty, please provide content', + }); } try { @@ -245,18 +250,18 @@ const commentController = { ); if (!replyId) { - return res - .status(404) - .json({ message: 'Please provide a valid Comment to Reply' }); + return NotFoundError(res, { + message: 'Please provide a valid Comment to Reply', + }); } - return res.status(200).json({ + return SuccessResponse(res, { message: 'Replied to the Comment Successfully', replyId: replyId, }); } catch (error) { console.log(error); - return res.status(500).json({ message: 'Something went wrong.....' }); + return InternalServerError(res, { message: 'Something went wrong.....' }); } }, deleteCommentReply: async ( @@ -273,9 +278,9 @@ const commentController = { !Types.ObjectId.isValid(commentId) || !Types.ObjectId.isValid(replyId) ) { - return res - .status(404) - .json({ message: 'Please provide a valid Reply to be deleted....' }); + return NotFoundError(res, { + message: 'Please provide a valid Reply to be deleted....', + }); } try { @@ -297,17 +302,19 @@ const commentController = { } if (!response.acknowledged) { - return res.status(500).json({ message: 'something went wrong.....' }); + return InternalServerError(res, { + message: 'something went wrong.....', + }); } if (!response.modifiedCount) { - return res.status(404).json({ message: 'no such reply found' }); + return NotFoundError(res, { message: 'no such reply found' }); } - return res.status(200).json({ message: 'Reply deleted successfully' }); + return SuccessResponse(res, { message: 'Reply deleted successfully' }); } catch (error) { console.log(error); - return res.status(500).json({ message: 'Something went wrong...' }); + return InternalServerError(res, { message: 'Something went wrong...' }); } }, }; diff --git a/src/controller/post.controller.ts b/src/controller/post.controller.ts index 4176e5b..176b844 100644 --- a/src/controller/post.controller.ts +++ b/src/controller/post.controller.ts @@ -6,6 +6,13 @@ import userServices from '../services/user.service'; import { IPostFilter, IPostForm } from '../types/post.types'; import { TypeRequestBody } from '../types/request.types'; import { IAuthToken } from '../types/token.types'; +import { + BadRequestError, + InternalServerError, + NotFoundError, + SuccessResponse, + UnauthorizedError, +} from '../utils/apiResponse'; import generateSummaryFromHTMLContent from '../utils/generateSummaryFromHTMLContent'; const postController = { @@ -30,7 +37,7 @@ const postController = { if (!limit || limit <= 0) limit = 10; if (limit > 100) { - return res.status(500).json({ message: 'Limit cannot exceed 100' }); + return InternalServerError(res, { message: 'Limit cannot exceed 100' }); } // default page @@ -79,7 +86,7 @@ const postController = { const posts = await postServices.getAllPosts(filters, sort, limit, skip); if (posts.length === 0) { - return res.status(200).json({ + return SuccessResponse(res, { message: 'No posts to display', data: [], page: { previousPage: page === 0 ? undefined : page }, @@ -113,13 +120,13 @@ const postController = { const nextPage = page + 2; // previous page is returned as page because for 1 based indexing page is the previous page as page-1 is done const previousPage = page === 0 ? undefined : page; - return res.status(200).json({ + return SuccessResponse(res, { message: 'post fetched successfully', data: response, page: { nextPage, previousPage }, }); } catch (error) { - return res.status(500).json({ message: 'Something went wrong.....' }); + return InternalServerError(res, { message: 'Something went wrong.....' }); } }, @@ -131,13 +138,13 @@ const postController = { // check if the id is a valid mongodb id; if (!mongoose.Types.ObjectId.isValid(postId)) { - return res.status(404).json({ message: 'No such Post found' }); + return NotFoundError(res, { message: 'No such Post found' }); } try { // increment the value of views by 1 and return the post with populated user data const post = await postServices.getPost(postId); if (!post) { - return res.status(404).json({ message: 'No such Post found' }); + return NotFoundError(res, { message: 'No such Post found' }); } const postAuthor = post.userId.username; const postAuthorId = post.userId._id; @@ -157,7 +164,7 @@ const postController = { const isDownVoted = post.downVotes.includes(userId); const commentCount = post.comments.length; - return res.status(200).json({ + return SuccessResponse(res, { message: 'post fetched successfully', post: { title: post.title, @@ -182,7 +189,7 @@ const postController = { }, }); } catch (error) { - return res.status(500).json({ message: 'Something went wrong.....' }); + return InternalServerError(res, { message: 'Something went wrong.....' }); } }, @@ -196,7 +203,7 @@ const postController = { const paramUserId = req.params['userId']; if (!mongoose.Types.ObjectId.isValid(paramUserId)) { - return res.status(404).json({ message: 'No such User found' }); + return NotFoundError(res, { message: 'No such User found' }); } const userId = new Types.ObjectId(paramUserId); @@ -209,7 +216,7 @@ const postController = { if (!limit || limit <= 0) limit = 10; if (limit > 100) { - return res.status(500).json({ message: 'Limit cannot exceed 100' }); + return InternalServerError(res, { message: 'Limit cannot exceed 100' }); } // default page @@ -225,7 +232,7 @@ const postController = { skip, ); if (posts.length === 0) { - return res.status(200).json({ + return SuccessResponse(res, { message: 'No posts to display', data: [], page: { previousPage: page === 0 ? undefined : page }, @@ -260,7 +267,7 @@ const postController = { const nextPage = page + 2; // previous page is returned as page because for 1 based indexing page is the previous page as page-1 is done const previousPage = page === 0 ? undefined : page; - return res.status(200).json({ + return SuccessResponse(res, { message: 'bookmarked posts fetched successfully', data: response, page: { nextPage, previousPage }, @@ -268,7 +275,7 @@ const postController = { } catch (error) { console.log(error); - return res.status(500).json({ message: 'Something went wrong.....' }); + return InternalServerError(res, { message: 'Something went wrong.....' }); } }, @@ -278,24 +285,24 @@ const postController = { // check if the id is a valid mongodb id; if (!mongoose.Types.ObjectId.isValid(postId)) { - return res.status(404).json({ message: 'No such Post found' }); + return NotFoundError(res, { message: 'No such Post found' }); } if (!limit || limit <= 0) { - return res.status(400).json({ message: 'Please provide a valid limit' }); + return BadRequestError(res, { message: 'Please provide a valid limit' }); } try { // Get posts related to the given post const relatedPosts = await postServices.getRelatedPosts(postId, limit); - return res.status(200).json({ + return SuccessResponse(res, { message: 'post fetched successfully', relatedPosts, }); } catch (error) { console.log(error); - return res.status(500).json({ message: 'Something went wrong.....' }); + return InternalServerError(res, { message: 'Something went wrong.....' }); } }, @@ -308,7 +315,7 @@ const postController = { const paramUserId = req.params['userId']; if (!Types.ObjectId.isValid(paramUserId)) { - return res.status(404).json({ message: 'No such User found' }); + return NotFoundError(res, { message: 'No such User found' }); } // query page will start from 1; let page = parseInt(req.query['page'] as string) - 1; @@ -318,7 +325,7 @@ const postController = { if (!limit || limit <= 0) limit = 10; if (limit > 100) { - return res.status(500).json({ message: 'limit cannot exceed 100' }); + return InternalServerError(res, { message: 'limit cannot exceed 100' }); } if (!page || page < 0) { @@ -331,7 +338,7 @@ const postController = { const posts = await postServices.getUserPosts(userId, limit, skip); if (posts.length === 0) { - return res.status(200).json({ + return SuccessResponse(res, { message: 'No posts to display', data: [], page: { previousPage: page === 0 ? undefined : page }, @@ -362,14 +369,14 @@ const postController = { // previous page is returned as page because for 1 based indexing page is the previous page as page-1 is done const previousPage = page === 0 ? undefined : page; - return res.status(200).json({ + return SuccessResponse(res, { message: 'user posts', data: response, page: { nextPage, previousPage }, }); } catch (error) { console.log(error); - return res.status(500).json({ message: 'something went wrong....' }); + return InternalServerError(res, { message: 'something went wrong....' }); } }, @@ -414,9 +421,9 @@ const postController = { !status || !tags ) { - return res - .status(401) - .json({ message: 'Please enter all required fields ' }); + return UnauthorizedError(res, { + message: 'Please enter all required fields ', + }); } // Generating summary @@ -439,12 +446,13 @@ const postController = { // Create post using the post services try { const post = await postServices.createPost(postData); - return res - .status(200) - .json({ message: 'Post Created Successfully', postId: post._id }); + return SuccessResponse(res, { + message: 'Post Created Successfully', + postId: post._id, + }); } catch (error) { console.log(error); - return res.status(500).json({ message: 'Something went wrong.....' }); + return InternalServerError(res, { message: 'Something went wrong.....' }); } // TODO: save the post in the user model in the userPost section @@ -460,9 +468,9 @@ const postController = { const postId = req.params['id']; if (!Types.ObjectId.isValid(postId)) { - return res - .status(404) - .json({ message: 'Please provide a valid Post to Delete' }); + return NotFoundError(res, { + message: 'Please provide a valid Post to Delete', + }); } let postDeleteResponse: DeleteResult | null = null; @@ -479,19 +487,19 @@ const postController = { } } catch (error) { console.log(error); - return res.status(500).json({ message: 'Something went wrong...' }); + return InternalServerError(res, { message: 'Something went wrong...' }); } // Check the condition if the post is successfully deleted or not if (!postDeleteResponse.acknowledged) { - return res.status(400).json({ message: 'Something went wrong...' }); + return BadRequestError(res, { message: 'Something went wrong...' }); } if (postDeleteResponse.deletedCount === 0) { - return res.status(404).json({ message: 'Post Could not be Delete' }); + return NotFoundError(res, { message: 'Post Could not be Delete' }); } - return res.status(200).json({ message: 'Post Deleted Successfully' }); + return SuccessResponse(res, { message: 'Post Deleted Successfully' }); }, upVotePost: async ( req: TypeRequestBody<{ @@ -504,9 +512,9 @@ const postController = { const postId = req.params['id']; if (!Types.ObjectId.isValid(postId)) { - return res - .status(404) - .json({ message: 'Please provide a valid Post to Up-Vote' }); + return NotFoundError(res, { + message: 'Please provide a valid Post to Up-Vote', + }); } try { @@ -515,15 +523,15 @@ const postController = { // Check if user was already bookmarked if (updateDetail.matchedCount === 0) { await postServices.nullifyUserVote(postId, userId); - return res - .status(200) - .json({ message: 'Removed Up Vote Successfully' }); + return SuccessResponse(res, { + message: 'Removed Up Vote Successfully', + }); } - return res.status(200).json({ message: 'Post Up Voted Successfully' }); + return SuccessResponse(res, { message: 'Post Up Voted Successfully' }); } catch (error) { console.log(error); - return res.status(500).json({ message: 'Something went wrong...' }); + return InternalServerError(res, { message: 'Something went wrong...' }); } }, downVotePost: async ( @@ -537,9 +545,9 @@ const postController = { const postId = req.params['id']; if (!Types.ObjectId.isValid(postId)) { - return res - .status(404) - .json({ message: 'Please provide a valid Post to Down-Vote' }); + return NotFoundError(res, { + message: 'Please provide a valid Post to Down-Vote', + }); } try { @@ -548,15 +556,15 @@ const postController = { // Check if user was already bookmarked if (updateDetail.matchedCount === 0) { await postServices.nullifyUserVote(postId, userId); - return res - .status(200) - .json({ message: 'Removed Down Vote Successfully' }); + return SuccessResponse(res, { + message: 'Removed Down Vote Successfully', + }); } - return res.status(200).json({ message: 'Post Down Voted Successfully' }); + return SuccessResponse(res, { message: 'Post Down Voted Successfully' }); } catch (error) { console.log(error); - return res.status(500).json({ message: 'Something went wrong...' }); + return InternalServerError(res, { message: 'Something went wrong...' }); } }, addUserBookmark: async ( @@ -570,9 +578,9 @@ const postController = { const postId = req.params['id']; if (!Types.ObjectId.isValid(postId)) { - return res - .status(404) - .json({ message: 'Please provide a valid Post to Bookmark' }); + return NotFoundError(res, { + message: 'Please provide a valid Post to Bookmark', + }); } try { @@ -580,13 +588,15 @@ const postController = { // Check if user was already bookmarked if (updateDetail.matchedCount === 0) { - return res.status(500).json({ message: 'Post is already Bookmarked' }); + return InternalServerError(res, { + message: 'Post is already Bookmarked', + }); } - return res.status(200).json({ message: 'Post Bookmarked Successfully' }); + return SuccessResponse(res, { message: 'Post Bookmarked Successfully' }); } catch (error) { console.log(error); - return res.status(500).json({ message: 'Something went wrong...' }); + return InternalServerError(res, { message: 'Something went wrong...' }); } }, removeUserBookmark: async ( @@ -600,9 +610,9 @@ const postController = { const postId = req.params['id']; if (!Types.ObjectId.isValid(postId)) { - return res - .status(404) - .json({ message: 'Please provide a valid Post to Remove Bookmark' }); + return NotFoundError(res, { + message: 'Please provide a valid Post to Remove Bookmark', + }); } try { @@ -613,13 +623,13 @@ const postController = { // Check if user was already bookmarked if (updateDetail.matchedCount === 0) { - return res.status(500).json({ message: 'Post is not Bookmarked' }); + return InternalServerError(res, { message: 'Post is not Bookmarked' }); } - return res.status(200).json({ message: 'Post Removed From Bookmark' }); + return SuccessResponse(res, { message: 'Post Removed From Bookmark' }); } catch (error) { console.log(error); - return res.status(500).json({ message: 'Something went wrong...' }); + return InternalServerError(res, { message: 'Something went wrong...' }); } }, @@ -628,7 +638,7 @@ const postController = { try { const data = await postServices.getCompanyAndRole(); if (!data || data.length === 0) { - return res.status(200).json({ + return SuccessResponse(res, { message: 'Company and role fetched successfully', data: { company: [], @@ -637,7 +647,7 @@ const postController = { }); } - return res.status(200).json({ + return SuccessResponse(res, { message: 'Company and role fetched successfully', data: { company: data[0].company ? data[0].company : [], @@ -646,7 +656,7 @@ const postController = { }); } catch (error) { console.log(error); - return res.status(500).json({ message: 'Something went wrong.....' }); + return InternalServerError(res, { message: 'Something went wrong.....' }); } }, @@ -685,7 +695,7 @@ const postController = { // Check if user has passed all values if (!postId || !Types.ObjectId.isValid(postId)) { - return res.status(401).json({ message: 'NO such post found.... ' }); + return UnauthorizedError(res, { message: 'NO such post found.... ' }); } if ( @@ -700,9 +710,9 @@ const postController = { !status || !tags ) { - return res - .status(401) - .json({ message: 'Please enter all required fields ' }); + return UnauthorizedError(res, { + message: 'Please enter all required fields ', + }); } const userId = authTokenData.id; @@ -731,18 +741,19 @@ const postController = { if (!post) { console.log('Not acknowledged while editing the post'); - return res.status(400).json({ + return BadRequestError(res, { message: 'NO such post Found OR You do not have permission to edit this post.... ', }); } - return res - .status(200) - .json({ message: 'Post edited succesfully', data: post }); + return SuccessResponse(res, { + message: 'Post edited succesfully', + data: post, + }); } catch (error) { console.log(error); - return res.status(500).json({ message: 'Something went wrong.....' }); + return InternalServerError(res, { message: 'Something went wrong.....' }); } }, }; diff --git a/src/controller/quiz.controller.ts b/src/controller/quiz.controller.ts index 8a3f555..d73eaf3 100644 --- a/src/controller/quiz.controller.ts +++ b/src/controller/quiz.controller.ts @@ -1,9 +1,16 @@ import { Request, Response } from 'express'; +import { Types } from 'mongoose'; import quizServices from '../services/quiz.service'; import { IQuiz, IQuizHistorySubmit } from '../types/quiz.types'; import { TypeRequestBody } from '../types/request.types'; import { IAuthToken } from '../types/token.types'; -import { Types } from 'mongoose'; +import { + InternalServerError, + NotFoundError, + PreconditionFailedError, + SuccessResponse, + UnauthorizedError, +} from '../utils/apiResponse'; const quizController = { createQuestion: async ( @@ -40,15 +47,15 @@ const quizController = { !wrongOption3 || !detailedSolution ) { - return res - .status(401) - .json({ message: 'Please enter all required fields ' }); + return UnauthorizedError(res, { + message: 'Please enter all required fields ', + }); } if (!difficulty || difficulty <= 0 || difficulty > 10) { - return res - .status(401) - .json({ message: 'Please enter all required fields ' }); + return UnauthorizedError(res, { + message: 'Please enter all required fields ', + }); } const data: IQuiz = { @@ -64,12 +71,13 @@ const quizController = { try { const question = await quizServices.createQuizQuestion(data); - return res - .status(200) - .json({ message: 'Question created successfully', data: question._id }); + return SuccessResponse(res, { + message: 'Question created successfully', + data: question._id, + }); } catch (error) { console.log(error); - return res.status(500).json({ message: 'Something went wrong.....' }); + return InternalServerError(res, { message: 'Something went wrong.....' }); } }, @@ -83,22 +91,23 @@ const quizController = { } if (!topic) { - return res.status(404).json({ message: 'No such quiz found' }); + return NotFoundError(res, { message: 'No such quiz found' }); } try { const questions = await quizServices.getQuizQuestion(topic, count); if (questions.length == 0) { - return res.status(404).json({ message: 'No such quiz found' }); + return NotFoundError(res, { message: 'No such quiz found' }); } - return res - .status(200) - .json({ message: 'questions fetched successfully', data: questions }); + return SuccessResponse(res, { + message: 'questions fetched successfully', + data: questions, + }); } catch (error) { console.log(error); - return res.status(500).json({ message: 'Something went wrong.....' }); + return InternalServerError(res, { message: 'Something went wrong.....' }); } }, @@ -115,7 +124,7 @@ const quizController = { const userId = req.body.authTokenData.id; if (!topic) { - return res.status(401).json({ message: 'Not a valid test submission' }); + return UnauthorizedError(res, { message: 'Not a valid test submission' }); } // check if the totalQuestionsCount contains a valid value or not. @@ -124,7 +133,7 @@ const quizController = { totalQuestionsCount < 0 || totalQuestionsCount < correctAnswerCount ) { - return res.status(401).json({ message: 'Not a valid test submission' }); + return UnauthorizedError(res, { message: 'Not a valid test submission' }); } // check if the correctAnswerCount contains a valid value or not. @@ -132,15 +141,16 @@ const quizController = { correctAnswerCount < 0 || (!correctAnswerCount && correctAnswerCount != 0) ) { - return res.status(401).json({ message: 'Not a valid test submission' }); + return UnauthorizedError(res, { message: 'Not a valid test submission' }); } const result = correctAnswerCount / totalQuestionsCount; if (result < 0.6) { - return res - .status(412) - .json({ message: 'Score must me greater than 60%...' }); + return PreconditionFailedError(res, { + message: 'Score must me greater than 60%...', + }); } + const history: IQuizHistorySubmit = { topic, totalQuestionsCount, @@ -150,19 +160,20 @@ const quizController = { try { const response = await quizServices.submitQuiz(history); - return res - .status(200) - .json({ message: 'Quiz submitted successfully', data: response._id }); + return SuccessResponse(res, { + message: 'Quiz submitted successfully', + data: response._id, + }); } catch (error) { console.log(error); - return res.status(500).json({ message: 'Something went wrong.....' }); + return InternalServerError(res, { message: 'Something went wrong.....' }); } }, getStreak: async (req: Request, res: Response) => { const userId = req.query['userId'] as string; if (!userId || !Types.ObjectId.isValid(userId)) { - return res.status(401).json({ message: 'No such user found!!' }); + return UnauthorizedError(res, { message: 'No such user found!!' }); } let dailyQuizDone = false; @@ -170,7 +181,7 @@ const quizController = { const quizSubmitDates = await quizServices.getQuizHistoryDates(userId); if (quizSubmitDates.length === 0) { - return res.status(200).json({ + return SuccessResponse(res, { message: 'streak fetched successfully', streakCount: 0, dailyQuizDone, @@ -187,7 +198,7 @@ const quizController = { currentDate.getTime() - quizSubmitDates[0].getTime() >= 86400000 * 2 ) { - return res.status(200).json({ + return SuccessResponse(res, { message: 'streak fetched successfully', streakCount: 0, dailyQuizDone, @@ -210,14 +221,14 @@ const quizController = { streakCount++; } - return res.status(200).json({ + return SuccessResponse(res, { message: 'streak fetched successfully', streakCount, dailyQuizDone, }); } catch (error) { console.log(error); - return res.status(500).json({ message: 'Something went wrong.....' }); + return InternalServerError(res, { message: 'Something went wrong.....' }); } }, }; diff --git a/src/controller/user.controller.ts b/src/controller/user.controller.ts index 99e9ba6..fae0be9 100644 --- a/src/controller/user.controller.ts +++ b/src/controller/user.controller.ts @@ -11,6 +11,14 @@ import { IForgotPasswordToken, } from '../types/token.types'; import { IUser } from '../types/user.types'; +import { + BadRequestError, + ForbiddenError, + InternalServerError, + NotFoundError, + SuccessResponse, + UnauthorizedError, +} from '../utils/apiResponse'; import decodeToken from '../utils/token/decodeToken'; import generateAuthToken from '../utils/token/generateAuthToken'; import generateEmailVerificationToken from '../utils/token/generateEmailVerificationToken'; @@ -45,7 +53,7 @@ const userController = { // if email or password is undefined if (!email || !password) { - return res.status(401).json({ + return UnauthorizedError(res, { message: 'Incorrect Username or Password', }); } @@ -71,7 +79,7 @@ const userController = { // Check if email is verified or not if (!user.isEmailVerified) { - return res.status(401).json({ message: 'Email is not verified' }); + return UnauthorizedError(res, { message: 'Email is not verified' }); } // generate JWT token @@ -81,7 +89,7 @@ const userController = { res.cookie('token', token, cookieOptions); // Remove the password - return res.status(200).json({ + return SuccessResponse(res, { message: 'Login Successful', user: { id: user._id, @@ -99,7 +107,7 @@ const userController = { }); } catch (error) { console.log(error); - return res.status(500).json({ message: 'Something went wrong.....' }); + return InternalServerError(res, { message: 'Something went wrong.....' }); } }, @@ -153,7 +161,7 @@ const userController = { const oldUser = await userServices.findUser(email); if (oldUser && oldUser.isEmailVerified) { - return res.status(404).json({ message: 'Email already exists' }); + return NotFoundError(res, { message: 'Email already exists' }); } if (oldUser && !oldUser.isEmailVerified) { @@ -192,12 +200,12 @@ const userController = { // send email to the user for verification await sendEmailVerificationMail(email, token, user.username); - return res.status(200).json({ + return SuccessResponse(res, { message: 'Account created successfully, please verify your email....', }); } catch (error) { console.log(error); - return res.status(500).json({ message: 'Something went wrong.....' }); + return InternalServerError(res, { message: 'Something went wrong.....' }); } }, @@ -218,11 +226,11 @@ const userController = { // check if email is not-registered const user = await userServices.findUser(email); if (!user) { - return res.status(401).json({ message: 'No such email found' }); + return UnauthorizedError(res, { message: 'No such email found' }); } if (!user.isEmailVerified) { - return res.status(400).json({ message: 'Please Verify your Email' }); + return BadRequestError(res, { message: 'Please Verify your Email' }); } // Creating a jwt token and sending it to the user @@ -231,12 +239,14 @@ const userController = { // send email to the user sendForgotPasswordEmail(email, token, user.username); - return res - .status(200) - .json({ message: `A password reset link is sent to ${email}` }); + return SuccessResponse(res, { + message: `A password reset link is sent to ${email}`, + }); } catch (error) { console.log(error); - return res.status(500).json({ message: 'Error, Please try again later' }); + return InternalServerError(res, { + message: 'Error, Please try again later', + }); } }, @@ -249,25 +259,25 @@ const userController = { const resetPasswordToken = req.params['token']; if (!email) { - return res.status(401).json({ message: 'Please enter Email' }); + return UnauthorizedError(res, { message: 'Please enter Email' }); } if (!newPassword) { - return res.status(401).json({ message: 'Please enter new Password ' }); + return UnauthorizedError(res, { message: 'Please enter new Password ' }); } try { const tokenData = decodeToken(resetPasswordToken) as IForgotPasswordToken; if (email !== tokenData.email) { - return res.status(403).json({ message: 'Reset Link is not valid' }); + return ForbiddenError(res, { message: 'Reset Link is not valid' }); } const user = await userServices.findUser(tokenData.email); if (!user) { - return res - .status(401) - .json({ message: 'Please create a new Reset Password Link' }); + return UnauthorizedError(res, { + message: 'Please create a new Reset Password Link', + }); } // Hash the password @@ -275,17 +285,17 @@ const userController = { // Resetting the password await userServices.resetPassword(tokenData.email, hashedNewPassword); - return res.status(200).json({ message: 'Password changed successfully' }); + return SuccessResponse(res, { message: 'Password changed successfully' }); } catch (error) { console.log(error); - return res - .status(500) - .json({ message: 'Error, generate new password link' }); + return InternalServerError(res, { + message: 'Error, generate new password link', + }); } }, logoutUser: (req: Request, res: Response) => { res.clearCookie('token', cookieOptions); - return res.status(200).json({ message: 'User Logout successful' }); + return SuccessResponse(res, { message: 'User Logout successful' }); }, verifyEmail: async (req: Request, res: Response) => { const emailVerificationToken = req.params['token']; @@ -323,18 +333,18 @@ const userController = { const userData = req.body.authTokenData; if (!userData) { - return res.status(403).json({ message: 'User not logged in' }); + return ForbiddenError(res, { message: 'User not logged in' }); } try { // Delete the user Account await userServices.deleteUser(userData.id); - return res.status(200).json({ message: 'User Account deleted' }); + return SuccessResponse(res, { message: 'User Account deleted' }); } catch (error) { console.log(error); - return res - .status(500) - .json({ message: 'Error during Deletion, Please try again later' }); + return InternalServerError(res, { + message: 'Error during Deletion, Please try again later', + }); } }, getLoginStatus: async (req: Request, res: Response) => { @@ -355,7 +365,7 @@ const userController = { const user = await userServices.findUser(authTokenData.email); if (!user) { - return res.status(200).json({ + return SuccessResponse(res, { isLoggedIn: false, isAdmin: false, admin: null, @@ -377,7 +387,7 @@ const userController = { linkedin: user.linkedin, }; - return res.status(200).json({ + return SuccessResponse(res, { isLoggedIn: true, isAdmin: user.isAdmin, admin: null, @@ -418,7 +428,9 @@ const userController = { } = req.body; if (!username || !branch || !passingYear || !designation || !about) { - return res.status(401).json({ message: 'Please enter all the fields ' }); + return UnauthorizedError(res, { + message: 'Please enter all the fields ', + }); } const updatedProfile = { @@ -435,12 +447,15 @@ const userController = { const userId = req.body.authTokenData.id; try { const user = await userServices.editProfile(userId, updatedProfile); - return res - .status(200) - .json({ message: 'User Profile Edited Successfully', data: user }); + return SuccessResponse(res, { + message: 'User Profile Edited Successfully', + data: user, + }); } catch (error) { console.log(error); - return res.status(500).json({ message: 'something went wrong......' }); + return InternalServerError(res, { + message: 'something went wrong......', + }); } }, @@ -449,7 +464,7 @@ const userController = { // if not a valid user id if (!mongoose.Types.ObjectId.isValid(paramId)) { - return res.status(404).json({ message: 'No such user found' }); + return NotFoundError(res, { message: 'No such user found' }); } const userId = new Types.ObjectId(paramId); @@ -457,7 +472,7 @@ const userController = { const userProfile = await userServices.getUserProfile(userId); if (userProfile.length === 0) { - return res.status(404).json({ message: 'No such User found' }); + return NotFoundError(res, { message: 'No such User found' }); } // if no post @@ -469,10 +484,10 @@ const userController = { downVoteCount: 0, }); } - return res.status(200).json({ message: 'ok', data: userProfile }); + return SuccessResponse(res, { message: 'ok', data: userProfile }); } catch (error) { console.log(error); - return res.status(500).json({ message: 'something went wrong...' }); + return InternalServerError(res, { message: 'something went wrong...' }); } }, @@ -486,7 +501,7 @@ const userController = { if (!limit || limit <= 0) limit = 10; if (limit > 100) { - return res.status(500).json({ message: 'Limit cannot exceed 100' }); + return InternalServerError(res, { message: 'Limit cannot exceed 100' }); } const skip = limit * page; @@ -494,7 +509,7 @@ const userController = { const userList = await userServices.searchUser(search, limit, skip); if (userList.length === 0) { - return res.status(200).json({ + return SuccessResponse(res, { message: 'No posts to display', data: [], page: { previousPage: page === 0 ? undefined : page }, @@ -506,14 +521,14 @@ const userController = { // previous page is returned as page because for 1 based indexing page is the previous page as page-1 is done const previousPage = page === 0 ? undefined : page; - return res.status(200).json({ + return SuccessResponse(res, { message: 'Users fetched successfully', data: userList, page: { nextPage, previousPage }, }); } catch (error) { console.log(error); - return res.status(500).json({ message: 'something went wrong...' }); + return InternalServerError(res, { message: 'something went wrong...' }); } }, googleLogin: async (req: Request, res: Response) => { @@ -543,7 +558,7 @@ const userController = { const token = req.params['token']; res.cookie('token', token, cookieOptions); - return res.status(200).json({ message: 'Token set successfully' }); + return SuccessResponse(res, { message: 'Token set successfully' }); }, }; diff --git a/src/middleware/isAdminAuth.ts b/src/middleware/isAdminAuth.ts index f875998..b036913 100644 --- a/src/middleware/isAdminAuth.ts +++ b/src/middleware/isAdminAuth.ts @@ -1,5 +1,6 @@ import { NextFunction, Request, Response } from 'express'; import { IAuthToken } from '../types/token.types'; +import { UnauthorizedError } from '../utils/apiResponse'; import decodeToken from '../utils/token/decodeToken'; // A middleware to check if the user is authenticated or not, before any action @@ -7,7 +8,7 @@ const isAdminAuth = (req: Request, res: Response, next: NextFunction) => { const token = req.cookies['token']; if (!token) { - return res.status(401).json({ message: 'Not LoggedIn as Admin' }); + return UnauthorizedError(res, { message: 'Not LoggedIn as Admin' }); } // Verify the token @@ -17,7 +18,7 @@ const isAdminAuth = (req: Request, res: Response, next: NextFunction) => { // Check if data exits if (!authTokenData.isAdmin) { res.clearCookie('token'); - return res.status(401).json({ message: 'Not LoggedIn as Admin' }); + return UnauthorizedError(res, { message: 'Not LoggedIn as Admin' }); } // Adding token data to req @@ -25,7 +26,7 @@ const isAdminAuth = (req: Request, res: Response, next: NextFunction) => { return next(); } catch (err) { - return res.status(401).json({ message: 'Not LoggedIn as Admin' }); + return UnauthorizedError(res, { message: 'Not LoggedIn as Admin' }); } }; diff --git a/src/middleware/isUserAuth.ts b/src/middleware/isUserAuth.ts index 23a24c4..6b196fe 100644 --- a/src/middleware/isUserAuth.ts +++ b/src/middleware/isUserAuth.ts @@ -1,5 +1,6 @@ import { NextFunction, Request, Response } from 'express'; import { IAuthToken } from '../types/token.types'; +import { UnauthorizedError } from '../utils/apiResponse'; import decodeToken from '../utils/token/decodeToken'; // A middleware to check if the user is authenticated or not, before any action @@ -7,7 +8,7 @@ const isUserAuth = (req: Request, res: Response, next: NextFunction) => { const token = req.cookies['token']; if (!token) { - return res.status(401).json({ message: 'User not LoggedIn' }); + return UnauthorizedError(res, { message: 'User not LoggedIn' }); } try { @@ -19,7 +20,7 @@ const isUserAuth = (req: Request, res: Response, next: NextFunction) => { return next(); } catch (err) { - return res.status(401).json({ message: 'User not LoggedIn' }); + return UnauthorizedError(res, { message: 'User not LoggedIn' }); } }; diff --git a/src/routes/post.routes.ts b/src/routes/post.routes.ts index 89d47e1..31c5753 100644 --- a/src/routes/post.routes.ts +++ b/src/routes/post.routes.ts @@ -32,11 +32,11 @@ router.get( postController.getUserBookmarkedPost, ); -router.options('/related/:id', cors(corsOptionForCredentials)); +router.options('/related/:id', cors()); router.get( '/related/:id', - cors(corsOptionForCredentials), - isUserAuth, + cors(), + // isUserAuth, postController.getRelatedPosts, ); diff --git a/src/routes/user.routes.ts b/src/routes/user.routes.ts index 7c7fd44..141e525 100644 --- a/src/routes/user.routes.ts +++ b/src/routes/user.routes.ts @@ -4,6 +4,7 @@ import passport from 'passport'; import corsOptionForCredentials from '../config/cors'; import userController from '../controller/user.controller'; import isUserAuth from '../middleware/isUserAuth'; +import { UnauthorizedError } from '../utils/apiResponse'; const router = Router(); @@ -101,7 +102,7 @@ router.get( // Route to handle for google error router.options('/auth/google/failed', cors(corsOptionForCredentials)); router.get('/auth/google/failed', (req, res) => { - return res.status(401).json({ message: 'Login Failure' }); + return UnauthorizedError(res, { message: 'Login Failure' }); }); export default router; diff --git a/src/utils/apiResponse.ts b/src/utils/apiResponse.ts new file mode 100644 index 0000000..fed8efc --- /dev/null +++ b/src/utils/apiResponse.ts @@ -0,0 +1,29 @@ +import { Response } from 'express'; + +export const SuccessResponse = (res: Response, data: object) => { + return res.status(200).json(data); +}; + +export const BadRequestError = (res: Response, data: object) => { + return res.status(400).json(data); +}; + +export const UnauthorizedError = (res: Response, data: object) => { + return res.status(401).json(data); +}; + +export const ForbiddenError = (res: Response, data: object) => { + return res.status(403).json(data); +}; + +export const NotFoundError = (res: Response, data: object) => { + return res.status(404).json(data); +}; + +export const PreconditionFailedError = (res: Response, data: object) => { + return res.status(412).json(data); +}; + +export const InternalServerError = (res: Response, data: object) => { + return res.status(500).json(data); +};