Skip to content
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

Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
10 changes: 5 additions & 5 deletions backend/app.js → backend/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import compression from 'compression';
import cookieParser from 'cookie-parser';
import cors from 'cors';
import express from 'express';
import { FRONTEND_URL } from './config/utils.js';
import authRouter from './routes/auth.js';
import postsRouter from './routes/posts.js';
import userRouter from './routes/user.js';
import errorMiddleware from './middlewares/error-middleware.js';
import { FRONTEND_URL } from './config/utils';
import authRouter from './routes/auth';
import postsRouter from './routes/posts';
import userRouter from './routes/user';
import errorMiddleware from './middlewares/error-middleware';

const app = express();

Expand Down
6 changes: 3 additions & 3 deletions backend/config/db.js → backend/config/db.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import mongoose from 'mongoose';
import { MONGODB_URI } from './utils.js';
import { MONGODB_URI } from './utils';

export default async function connectDB() {
try {
await mongoose.connect(MONGODB_URI, {
await mongoose.connect(MONGODB_URI!, {
dbName: 'wanderlust',
});
console.log(`Database connected: ${MONGODB_URI}`);
} catch (err) {
console.error(err.message);
console.error(err);
process.exit(1);
}

Expand Down
File renamed without changes.
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);
Expand Down Expand Up @@ -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;

Copy link
Owner

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

res
.status(HTTP_STATUS.OK)
Expand Down Expand Up @@ -95,7 +104,6 @@ export const signInWithEmailOrUsername = asyncHandler(async (req, res) => {

user.refreshToken = refreshToken;
await user.save();
user.password = undefined;

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same, get it back

res
.status(HTTP_STATUS.OK)
Expand All @@ -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,
{
Expand All @@ -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));
Expand All @@ -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)
Expand All @@ -164,12 +178,6 @@ export const isLoggedIn = asyncHandler(async (req, res) => {
console.log(error);
}
}
const user = await User.findById(_id);
if (!user) {
Copy link
Owner

Choose a reason for hiding this comment

The 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

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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;

Expand All @@ -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();

Expand All @@ -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,
Expand All @@ -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) {
Expand Down Expand Up @@ -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([
Expand 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
Expand All @@ -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);

Expand All @@ -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,
Expand All @@ -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);

Expand All @@ -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' });
}
Copy link
Owner

Choose a reason for hiding this comment

The 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 });
}
}
};
Loading