-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix-#3: refactored-backend-with-typescript #408
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,17 @@ | ||
import User from '../models/user.js'; | ||
import User from '../models/user'; | ||
import jwt from 'jsonwebtoken'; | ||
import { HTTP_STATUS, RESPONSE_MESSAGES } from '../utils/constants.js'; | ||
import { cookieOptions } from '../utils/cookie_options.js'; | ||
import { JWT_SECRET } from '../config/utils.js'; | ||
import { ApiError } from '../utils/api-error.js'; | ||
import { ApiResponse } from '../utils/api-response.js'; | ||
import { asyncHandler } from '../utils/async-handler.js'; | ||
import { HTTP_STATUS, RESPONSE_MESSAGES } from '../utils/constants'; | ||
import { cookieOptions } from '../utils/cookie_options'; | ||
import { JWT_SECRET } from '../config/utils'; | ||
import { ApiError } from '../utils/api-error'; | ||
import { ApiResponse } from '../utils/api-response'; | ||
import { asyncHandler } from '../utils/async-handler'; | ||
import { Response, Request } from 'express'; | ||
import { RequestWithUserRole } from '../types/request-User-Type'; | ||
|
||
//REGULAR EMAIL PASSWORD STRATEGY | ||
//1.Sign Up | ||
export const signUpWithEmail = asyncHandler(async (req, res) => { | ||
export const signUpWithEmail = asyncHandler(async (req: Request, res: Response) => { | ||
const { userName, fullName, email, password } = req.body; | ||
if (!userName || !fullName || !email || !password) { | ||
throw new ApiError(HTTP_STATUS.BAD_REQUEST, RESPONSE_MESSAGES.COMMON.REQUIRED_FIELDS); | ||
|
@@ -38,20 +40,27 @@ export const signUpWithEmail = asyncHandler(async (req, res) => { | |
try { | ||
await user.validate(); | ||
} catch (error) { | ||
const validationErrors = []; | ||
for (const key in error.errors) { | ||
validationErrors.push(error.errors[key].message); | ||
if (error instanceof ApiError) { | ||
const validationErrors = []; | ||
for (const key in error.errors) { | ||
validationErrors.push(error.errors[key].message); | ||
} | ||
throw new ApiError(HTTP_STATUS.BAD_REQUEST, validationErrors.join(', ')); | ||
} else { | ||
throw new ApiError( | ||
HTTP_STATUS.INTERNAL_SERVER_ERROR, | ||
RESPONSE_MESSAGES.COMMON.INTERNAL_SERVER_ERROR | ||
); | ||
} | ||
throw new ApiError(HTTP_STATUS.BAD_REQUEST, validationErrors.join(', ')); | ||
} | ||
|
||
const accessToken = await user.generateAccessToken(); | ||
const refreshToken = await user.generateRefreshToken(); | ||
const accessToken: string = await user.generateAccessToken(); | ||
const refreshToken: string = await user.generateRefreshToken(); | ||
|
||
user.refreshToken = refreshToken; | ||
|
||
await user.save(); | ||
user.password = undefined; | ||
// user.password = undefined; | ||
|
||
res | ||
.status(HTTP_STATUS.OK) | ||
|
@@ -95,7 +104,6 @@ export const signInWithEmailOrUsername = asyncHandler(async (req, res) => { | |
|
||
user.refreshToken = refreshToken; | ||
await user.save(); | ||
user.password = undefined; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same, get it back |
||
res | ||
.status(HTTP_STATUS.OK) | ||
|
@@ -115,7 +123,7 @@ export const signInWithEmailOrUsername = asyncHandler(async (req, res) => { | |
}); | ||
|
||
//Sign Out | ||
export const signOutUser = asyncHandler(async (req, res) => { | ||
export const signOutUser = asyncHandler(async (req: RequestWithUserRole, res: Response) => { | ||
await User.findByIdAndUpdate( | ||
req.user?._id, | ||
{ | ||
|
@@ -141,9 +149,15 @@ export const isLoggedIn = asyncHandler(async (req, res) => { | |
let refresh_token = req.cookies?.refresh_token; | ||
const { _id } = req.params; | ||
|
||
const user = await User.findById(_id); | ||
if (!user) { | ||
return res | ||
.status(HTTP_STATUS.NOT_FOUND) | ||
.json(new ApiResponse(HTTP_STATUS.NOT_FOUND, '', RESPONSE_MESSAGES.USERS.USER_NOT_EXISTS)); | ||
} | ||
if (access_token) { | ||
try { | ||
await jwt.verify(access_token, JWT_SECRET); | ||
await jwt.verify(access_token, JWT_SECRET!); | ||
return res | ||
.status(HTTP_STATUS.OK) | ||
.json(new ApiResponse(HTTP_STATUS.OK, access_token, RESPONSE_MESSAGES.USERS.VALID_TOKEN)); | ||
|
@@ -153,7 +167,7 @@ export const isLoggedIn = asyncHandler(async (req, res) => { | |
} | ||
} else if (refresh_token) { | ||
try { | ||
await jwt.verify(refresh_token, JWT_SECRET); | ||
await jwt.verify(refresh_token, JWT_SECRET!); | ||
access_token = await user.generateAccessToken(); | ||
return res | ||
.status(HTTP_STATUS.OK) | ||
|
@@ -164,12 +178,6 @@ export const isLoggedIn = asyncHandler(async (req, res) => { | |
console.log(error); | ||
} | ||
} | ||
const user = await User.findById(_id); | ||
if (!user) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why have we tottally removed this? please don't remove some functionality just because it is giving error XD There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not remove d but declared on above |
||
return res | ||
.status(HTTP_STATUS.NOT_FOUND) | ||
.json(new ApiResponse(HTTP_STATUS.NOT_FOUND, '', RESPONSE_MESSAGES.USERS.USER_NOT_EXISTS)); | ||
} | ||
|
||
const { refreshToken } = user; | ||
|
||
|
@@ -180,7 +188,7 @@ export const isLoggedIn = asyncHandler(async (req, res) => { | |
} | ||
|
||
try { | ||
await jwt.verify(refreshToken, JWT_SECRET); | ||
await jwt.verify(refreshToken, JWT_SECRET!); | ||
access_token = await user.generateAccessToken(); | ||
refresh_token = await user.generateRefreshToken(); | ||
|
||
|
@@ -192,14 +200,18 @@ export const isLoggedIn = asyncHandler(async (req, res) => { | |
.cookie('refresh_token', refresh_token, cookieOptions) | ||
.json(new ApiResponse(HTTP_STATUS.OK, access_token, RESPONSE_MESSAGES.USERS.VALID_TOKEN)); | ||
} catch (error) { | ||
return res | ||
.status(HTTP_STATUS.UNAUTHORIZED) | ||
.json( | ||
new ApiResponse( | ||
HTTP_STATUS.UNAUTHORIZED, | ||
error.message, | ||
RESPONSE_MESSAGES.USERS.INVALID_TOKEN | ||
) | ||
); | ||
if (error instanceof Error) { | ||
return res | ||
.status(HTTP_STATUS.UNAUTHORIZED) | ||
.json( | ||
new ApiResponse<string>( | ||
HTTP_STATUS.UNAUTHORIZED, | ||
error.message, | ||
RESPONSE_MESSAGES.USERS.INVALID_TOKEN | ||
) | ||
); | ||
} else { | ||
res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({ message: error }); | ||
} | ||
} | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,11 @@ | ||
import Post from '../models/post.js'; | ||
import User from '../models/user.js'; | ||
import { deleteDataFromCache, storeDataInCache } from '../utils/cache-posts.js'; | ||
import { HTTP_STATUS, REDIS_KEYS, RESPONSE_MESSAGES, validCategories } from '../utils/constants.js'; | ||
export const createPostHandler = async (req, res) => { | ||
import { Request, Response } from 'express'; | ||
import Post from '../models/post'; | ||
import User from '../models/user'; | ||
import { deleteDataFromCache, storeDataInCache } from '../utils/cache-posts'; | ||
import { HTTP_STATUS, REDIS_KEYS, RESPONSE_MESSAGES, validCategories } from '../utils/constants'; | ||
import { RequestWithUserRole } from '../types/request-User-Type'; | ||
|
||
export const createPostHandler = async (req: RequestWithUserRole, res: Response) => { | ||
try { | ||
const { | ||
title, | ||
|
@@ -13,7 +16,7 @@ export const createPostHandler = async (req, res) => { | |
isFeaturedPost = false, | ||
} = req.body; | ||
|
||
const userId = req.user._id; | ||
const userId = req.user?._id; | ||
|
||
// Validation - check if all fields are filled | ||
if (!title || !authorName || !imageLink || !description || !categories) { | ||
|
@@ -44,7 +47,7 @@ export const createPostHandler = async (req, res) => { | |
description, | ||
categories, | ||
isFeaturedPost, | ||
authorId: req.user._id, | ||
authorId: req.user?._id, | ||
}); | ||
|
||
const [savedPost] = await Promise.all([ | ||
|
@@ -59,31 +62,43 @@ export const createPostHandler = async (req, res) => { | |
|
||
res.status(HTTP_STATUS.OK).json(savedPost); | ||
} catch (err) { | ||
res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({ message: err.message }); | ||
if (err instanceof Error) { | ||
res.status(HTTP_STATUS.BAD_REQUEST).json({ message: err.message }); | ||
} else { | ||
res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({ message: err }); | ||
} | ||
} | ||
}; | ||
|
||
export const getAllPostsHandler = async (req, res) => { | ||
export const getAllPostsHandler = async (req: Request, res: Response) => { | ||
try { | ||
const posts = await Post.find(); | ||
await storeDataInCache(REDIS_KEYS.ALL_POSTS, posts); | ||
return res.status(HTTP_STATUS.OK).json(posts); | ||
} catch (err) { | ||
res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({ message: err.message }); | ||
if (err instanceof Error) { | ||
res.status(HTTP_STATUS.BAD_REQUEST).json({ message: err.message }); | ||
} else { | ||
res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({ message: err }); | ||
} | ||
} | ||
}; | ||
|
||
export const getFeaturedPostsHandler = async (req, res) => { | ||
export const getFeaturedPostsHandler = async (req: Request, res: Response) => { | ||
try { | ||
const featuredPosts = await Post.find({ isFeaturedPost: true }); | ||
await storeDataInCache(REDIS_KEYS.FEATURED_POSTS, featuredPosts); | ||
res.status(HTTP_STATUS.OK).json(featuredPosts); | ||
} catch (err) { | ||
res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({ message: err.message }); | ||
if (err instanceof Error) { | ||
res.status(HTTP_STATUS.BAD_REQUEST).json({ message: err.message }); | ||
} else { | ||
res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({ message: err }); | ||
} | ||
} | ||
}; | ||
|
||
export const getPostByCategoryHandler = async (req, res) => { | ||
export const getPostByCategoryHandler = async (req: Request, res: Response) => { | ||
const category = req.params.category; | ||
try { | ||
// Validation - check if category is valid | ||
|
@@ -96,21 +111,29 @@ export const getPostByCategoryHandler = async (req, res) => { | |
const categoryPosts = await Post.find({ categories: category }); | ||
res.status(HTTP_STATUS.OK).json(categoryPosts); | ||
} catch (err) { | ||
res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({ message: err.message }); | ||
if (err instanceof Error) { | ||
res.status(HTTP_STATUS.BAD_REQUEST).json({ message: err.message }); | ||
} else { | ||
res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({ message: err }); | ||
} | ||
} | ||
}; | ||
|
||
export const getLatestPostsHandler = async (req, res) => { | ||
export const getLatestPostsHandler = async (req: Request, res: Response) => { | ||
try { | ||
const latestPosts = await Post.find().sort({ timeOfPost: -1 }); | ||
await storeDataInCache(REDIS_KEYS.LATEST_POSTS, latestPosts); | ||
res.status(HTTP_STATUS.OK).json(latestPosts); | ||
} catch (err) { | ||
res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({ message: err.message }); | ||
if (err instanceof Error) { | ||
res.status(HTTP_STATUS.BAD_REQUEST).json({ message: err.message }); | ||
} else { | ||
res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({ message: err }); | ||
} | ||
} | ||
}; | ||
|
||
export const getPostByIdHandler = async (req, res) => { | ||
export const getPostByIdHandler = async (req: Request, res: Response) => { | ||
try { | ||
const post = await Post.findById(req.params.id); | ||
|
||
|
@@ -121,11 +144,15 @@ export const getPostByIdHandler = async (req, res) => { | |
|
||
res.status(HTTP_STATUS.OK).json(post); | ||
} catch (err) { | ||
res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({ message: err.message }); | ||
if (err instanceof Error) { | ||
res.status(HTTP_STATUS.BAD_REQUEST).json({ message: err.message }); | ||
} else { | ||
res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({ message: err }); | ||
} | ||
} | ||
}; | ||
|
||
export const updatePostHandler = async (req, res) => { | ||
export const updatePostHandler = async (req: Request, res: Response) => { | ||
try { | ||
const updatedPost = await Post.findByIdAndUpdate(req.params.id, req.body, { | ||
new: true, | ||
|
@@ -138,11 +165,15 @@ export const updatePostHandler = async (req, res) => { | |
|
||
res.status(HTTP_STATUS.OK).json(updatedPost); | ||
} catch (err) { | ||
res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({ message: err.message }); | ||
if (err instanceof Error) { | ||
res.status(HTTP_STATUS.BAD_REQUEST).json({ message: err.message }); | ||
} else { | ||
res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({ message: err }); | ||
} | ||
} | ||
}; | ||
|
||
export const deletePostByIdHandler = async (req, res) => { | ||
export const deletePostByIdHandler = async (req: Request, res: Response) => { | ||
try { | ||
const post = await Post.findByIdAndDelete(req.params.id); | ||
|
||
|
@@ -154,23 +185,30 @@ export const deletePostByIdHandler = async (req, res) => { | |
|
||
res.status(HTTP_STATUS.OK).json({ message: RESPONSE_MESSAGES.POSTS.DELETED }); | ||
} catch (err) { | ||
res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({ message: err.message }); | ||
if (err instanceof Error) { | ||
res.status(HTTP_STATUS.BAD_REQUEST).json({ message: err.message }); | ||
} else { | ||
res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({ message: err }); | ||
} | ||
} | ||
}; | ||
|
||
export const getRelatedPostsByCategories = async (req, res) => { | ||
export const getRelatedPostsByCategories = async (req: Request, res: Response) => { | ||
const { categories } = req.query; | ||
if (!categories) { | ||
return res | ||
.status(HTTP_STATUS.NOT_FOUND) | ||
.json({ message: RESPONSE_MESSAGES.POSTS.CATEGORIES_NOTFOUND }); | ||
return res.status(HTTP_STATUS.NOT_FOUND).json({ message: 'Categories not Found' }); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please don't hard-code, or change any variables, keep it existing as whatever it was, just do the ts refactor without any changes to the actual functionality of the code |
||
|
||
try { | ||
const filteredCategoryPosts = await Post.find({ | ||
categories: { $in: categories }, | ||
}); | ||
res.status(HTTP_STATUS.OK).json(filteredCategoryPosts); | ||
} catch (err) { | ||
res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({ message: err.message }); | ||
if (err instanceof Error) { | ||
res.status(HTTP_STATUS.BAD_REQUEST).json({ message: err.message }); | ||
} else { | ||
res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({ message: err }); | ||
} | ||
} | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make the password field nullable in the type, so that you don't have to comment it for the ts error