Skip to content

Commit 21d0afa

Browse files
committed
d
1 parent 39c5231 commit 21d0afa

File tree

12 files changed

+2172
-0
lines changed

12 files changed

+2172
-0
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
frontend/.env
2+
backend/.env
3+
frontend/node_modules/
4+
backend/node_modules/
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import bcrypt from "bcrypt";
2+
import jwt from "jsonwebtoken";
3+
import User from "../models/User.model.js";
4+
5+
let emailRegex = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
6+
7+
export const signup = async (req, res) => {
8+
const { fullname, email, password } = req.body;
9+
10+
if (fullname.length < 3) {
11+
return res
12+
.status(403)
13+
.json({ error: "Fullname must be at least 3 letters or more;" });
14+
}
15+
16+
if (!email.length) {
17+
return res.status(403).json({ error: "Enter Email" });
18+
}
19+
20+
if (!emailRegex.test(email)) {
21+
return res.status(403).json({ error: "Email is invalid!" });
22+
}
23+
24+
if (password.length < 6) {
25+
return res
26+
.status(403)
27+
.json({ error: "Password must be at least 6 letters or more" });
28+
}
29+
30+
try {
31+
const existingUser = await User.findOne({ email: email });
32+
33+
if (existingUser) {
34+
return res.status(500).json({ error: "Email already Exists" });
35+
}
36+
37+
const hashedPassword = await bcrypt.hash(password, 5);
38+
39+
const newUser = new User({ fullname, email, password: hashedPassword });
40+
41+
const user = await newUser.save();
42+
43+
const access_token = jwt.sign({ id: user._id }, process.env.JWT_SECRET);
44+
45+
return res.status(201).json({
46+
user: {
47+
fullname: user.fullname,
48+
email: user.email,
49+
},
50+
access_token,
51+
});
52+
} catch (error) {
53+
res
54+
.status(400)
55+
.json({ error: "User creation failed", message: error.message });
56+
}
57+
};
58+
59+
export const signin = async (req, res) => {
60+
try {
61+
const { email, password } = req.body;
62+
63+
// Find the user by email
64+
const existingUser = await User.findOne({ email: email });
65+
66+
if (!existingUser) {
67+
return res.status(404).json({ error: "User not found!" });
68+
}
69+
70+
// Compare passwords
71+
bcrypt.compare(password, existingUser.password, (err, result) => {
72+
if (err) {
73+
return res
74+
.status(500)
75+
.json({ error: "Error occured while login, Please try again!" });
76+
}
77+
if (!result) {
78+
return res.status(403).json({ error: "Incorrect password!" });
79+
}
80+
81+
const access_token = jwt.sign(
82+
{ id: existingUser._id },
83+
process.env.JWT_SECRET
84+
);
85+
86+
return res.status(201).json({
87+
user: {
88+
fullname: existingUser.fullname,
89+
email: existingUser.email,
90+
},
91+
access_token,
92+
});
93+
});
94+
} catch (error) {
95+
res
96+
.status(500)
97+
.json({ error: "Internal server error", message: error.message });
98+
}
99+
};
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import Todo from "../models/Todo.model.js";
2+
import User from "../models/User.model.js";
3+
4+
export const getAllTodos = async (req, res) => {
5+
try {
6+
const user = await User.findOne({ _id: req.id }).populate("todos");
7+
8+
if (!user) {
9+
return res.status(404).json({ message: "User not found" });
10+
}
11+
12+
const simplifiedTodos = user.todos.map((todo) => ({
13+
id: todo._id,
14+
title: todo.title,
15+
column: todo.column,
16+
}));
17+
18+
return res.status(200).json(simplifiedTodos);
19+
} catch (err) {
20+
return res.status(500).json({ error: err.message });
21+
}
22+
};
23+
24+
export const createTodo = async (req, res) => {
25+
try {
26+
const { title, column } = req.body;
27+
const newTodo = await Todo.create({ title, userId: req.id, column });
28+
await newTodo.save();
29+
30+
const currentUser = await User.findById(req.id);
31+
currentUser.todos.push(newTodo._id);
32+
await currentUser.save();
33+
res.status(201).json({ msg: "todo created", newTodo });
34+
} catch (err) {
35+
console.log(err);
36+
return res.status(500).json({ error: err });
37+
}
38+
};

backend/db/connection.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import mongoose from "mongoose";
2+
import "dotenv/config";
3+
4+
const connection = async () => {
5+
try {
6+
mongoose.connect(process.env.MONGO_DB_URI, {
7+
autoIndex: true,
8+
});
9+
} catch (err) {
10+
console.log(err);
11+
}
12+
};
13+
14+
export default connection;

backend/index.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import express from "express";
2+
import cors from "cors";
3+
import "dotenv/config";
4+
import connection from "./db/connection.js";
5+
import authRouter from "./routes/auth.routes.js";
6+
import { auth } from "./middleware/auth.js";
7+
import todoRouter from "./routes/todo.routes.js";
8+
9+
const server = express();
10+
const PORT = 3000;
11+
12+
server.use(express.json());
13+
server.use(cors());
14+
15+
server.use("/auth", authRouter);
16+
server.use("/todo", auth, todoRouter);
17+
18+
server.listen(PORT, () => {
19+
connection();
20+
console.log(`Listening on port ${PORT}`);
21+
});

backend/middleware/auth.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import jwt from "jsonwebtoken";
2+
3+
export const auth = (req, res, next) => {
4+
const authorization_header = req.headers.authorization;
5+
if (!authorization_header) {
6+
return res.status(400).send({ msg: "Authorization header is missing" });
7+
}
8+
const token = authorization_header.split(" ")[1];
9+
10+
jwt.verify(token, process.env.JWT_SECRET, async function (err, decoded) {
11+
if (decoded) {
12+
const id = decoded.id;
13+
req.id = id;
14+
next();
15+
} else {
16+
return res.status(400).send({ msg: "Login first" });
17+
}
18+
});
19+
};

backend/models/Todo.model.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import mongoose, { Schema } from "mongoose";
2+
3+
const todoSchema = mongoose.Schema(
4+
{
5+
title: { type: String, required: true },
6+
userId: { type: Schema.Types.ObjectId, ref: "user" },
7+
column: {
8+
type: String,
9+
},
10+
},
11+
12+
{
13+
timestamps: true,
14+
}
15+
);
16+
17+
export default mongoose.model("todo", todoSchema);

backend/models/User.model.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import mongoose, { Schema } from "mongoose";
2+
3+
const userSchema = mongoose.Schema(
4+
{
5+
fullname: {
6+
type: String,
7+
lowercase: true,
8+
required: true,
9+
minlength: [3, "fullname must be 3 letters long"],
10+
},
11+
email: {
12+
type: String,
13+
required: true,
14+
lowercase: true,
15+
unique: true,
16+
},
17+
password: String,
18+
todos: {
19+
type: [Schema.Types.ObjectId],
20+
ref: "todo",
21+
default: [],
22+
},
23+
},
24+
{
25+
timestamps: true,
26+
}
27+
);
28+
29+
export default mongoose.model("user", userSchema);

0 commit comments

Comments
 (0)