Phase 3 server side configuration done

This commit is contained in:
Mosiur Rahman
2026-04-23 16:10:00 +06:00
parent bd2c58f9ef
commit ad313f3b21
8 changed files with 197 additions and 3 deletions

View File

@@ -41,7 +41,8 @@ export const login = async (req: Request, res: Response ): Promise<void> => {
} }
const user = await User.findOne({ email }); const user = await User.findOne({ email });
if (!user) { const isMatch = await user?.comparePassword(password)
if (!user || !isMatch) {
res.status(401).json({message:'Invalid Email or password'}) res.status(401).json({message:'Invalid Email or password'})
return; return;
} }
@@ -54,4 +55,19 @@ export const login = async (req: Request, res: Response ): Promise<void> => {
res.status(500).json({ message: 'Server error during login' }); res.status(500).json({ message: 'Server error during login' });
} }
}
export const getMe = async (req: Request, res: Response): Promise<void> => {
try {
const user = req.user;
if (!user) {
res.status(401).json({message:'Undefined User'})
return;
}
res.json({ user })
} catch (error) {
console.error(error)
res.status(500).json({ message: 'Server Error'})
}
} }

View File

@@ -0,0 +1,111 @@
import { Request, Response } from "express"
import { Todo } from "../models/Todo"
export const createTodo = async (req: Request, res: Response): Promise<void> => {
try {
const {title, description, priority, dueDate} = req.body
if (!title) {
res.status(400).json({message: "Please insert title"})
return
}
const todo = await Todo.create({
title,
description,
priority,
dueDate,
user: req.user._id
})
res.status(201).json({todo})
} catch (error) {
console.error('Create todo error:', error)
res.status(500).json({ message: 'Server error' }) }
}
export const getTodos = async (req: Request, res: Response): Promise<void> => {
try {
const todos = await Todo.find({ user: req.user?._id })
res.status(200).json({ todos })
} catch (error) {
console.error('Get todos error:', error)
res.status(500).json({ message: 'Server error' })
}
}
export const updateTodos = async (req: Request, res: Response): Promise<void> => {
try {
const id = req.params.id
const todo = await Todo.findById(id)
if (!todo) {
res.status(404).json({message: "Object Not Found"})
return;
}
if (todo.user.toString()!== req.user?._id.toString()){
res.status(403).json({ message: "Not authorized" })
return;
}
const updateTodo = await Todo.findByIdAndUpdate(
id,
req.body,
{new: true}
)
res.status(200).json({ todo: updateTodo })
} catch (error) {
console.error('Update todo error:', error)
res.status(500).json({ message: 'Server error' })
}
}
export const deleteTodo = async (req: Request, res: Response): Promise<void> => {
try{
const id = req.params.id
const deleteTodo = await Todo.findById(id)
if (!deleteTodo) {
res.status(404).json({ message: 'Todo not found' })
return;
}
if (deleteTodo.user.toString() !== req.user?._id.toString()) {
res.status(403).json({ message: 'Not authorized' })
return
}
await Todo.findByIdAndDelete(id)
res.status(200).json({ message: 'Todo deleted successfully' })
} catch (error) {
console.error(error)
res.status(500).json({message: "Server Error"})
}
}
export const toggleTodo = async (req: Request, res: Response): Promise<void> =>{
try {
const todo = await Todo.findById(req.params.id)
if (!todo) {
res.status(404).json({ message: 'Todo not found' })
return
}
// ownership check:
if (todo.user.toString() !== req.user?._id.toString()) {
res.status(403).json({ message: 'Not authorized' })
return
}
todo.completed = !todo.completed
await todo.save()
res.status(200).json({ todo })
} catch (error) {
console.error(error)
res.status(500).json({message: "Server Error"})
}
}

48
server/src/models/Todo.ts Normal file
View File

@@ -0,0 +1,48 @@
import { Document, model, Schema, Types } from "mongoose";
export interface ITodo {
title: string,
description?: string,
completed: boolean,
priority: 'low' | 'medium' | 'high'
dueDate?: Date,
user: Types.ObjectId
}
export interface ITodoDocument extends ITodo, Document {
_id: Types.ObjectId
}
const todoSchema = new Schema<ITodoDocument> ({
title: {
type: String,
required: [true, 'Title is required'],
trim: true,
},
description: {
type: String,
required: false
},
completed: {
type: Boolean,
default: false
},
priority: {
type: String,
enum: ['low', 'medium', 'high',],
default: 'medium'
},
dueDate:{
type: Date,
required: false
},
user: {
type: Schema.Types.ObjectId,
ref: 'User',
required: true
}
}, {timestamps: true}
)
export const Todo = model<ITodoDocument>('Todo', todoSchema)

View File

@@ -1,10 +1,12 @@
import { Router } from 'express'; import { Router } from 'express';
import { register, login } from '../controllers/authController'; import { register, login, getMe } from '../controllers/authController';
import { protect } from '../middleware/authMiddleware';
const router = Router(); const router = Router();
router.post('/register', register); router.post('/register', register);
router.post ('/login', login) router.post ('/login', login)
router.get('/me',protect, getMe)
export default router; export default router;

View File

@@ -0,0 +1,14 @@
import { Router } from "express";
import { createTodo, deleteTodo, getTodos, toggleTodo, updateTodos } from "../controllers/todoController";
import { protect } from "../middleware/authMiddleware";
const router = Router();
router.use(protect)
router.get("/", getTodos)
router.post("/", createTodo)
router.put("/:id", updateTodos)
router.delete("/:id", deleteTodo)
router.patch("/:id/toggle", toggleTodo)
export default router;

View File

View File

@@ -3,6 +3,7 @@ import cors from 'cors';
import {ENV} from './config/env'; import {ENV} from './config/env';
import {connectDB, readyState} from './config/db'; import {connectDB, readyState} from './config/db';
import authRoutes from './routes/authRoutes'; import authRoutes from './routes/authRoutes';
import todoRoutes from './routes/todoRoutes';
const app: Application = express() const app: Application = express()
@@ -19,7 +20,7 @@ app.get('/health', (_req: Request, res: Response)=> {
//for checking database connection //for checking database connection
app.get('/health/db', (req: Request, res: Response)=> { app.get('/health/db', (_req: Request, res: Response)=> {
res.json({ res.json({
db_status: readyState(), db_status: readyState(),
environment: ENV.NODE_ENV, environment: ENV.NODE_ENV,
@@ -30,6 +31,8 @@ app.get('/health/db', (req: Request, res: Response)=> {
//api routes //api routes
app.use('/api/auth', authRoutes); app.use('/api/auth', authRoutes);
app.use('/api/todos', todoRoutes);
//start Server //start Server