Skip to content

Commit b9c6b66

Browse files
committed
Deployment
0 parents  commit b9c6b66

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+8880
-0
lines changed

.gitignore

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
pnpm-debug.log*
8+
lerna-debug.log*
9+
10+
node_modules
11+
dist
12+
dist-ssr
13+
*.local
14+
15+
.env
16+
17+
# Editor directories and files
18+
.vscode/*
19+
!.vscode/extensions.json
20+
.idea
21+
.DS_Store
22+
*.suo
23+
*.ntvs*
24+
*.njsproj
25+
*.sln
26+
*.sw?
+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import bcrypt from "bcryptjs";
2+
import User from "../models/user.model.js";
3+
import generateTokenAndSetCookie from "../utils/generateToken.js";
4+
5+
export const signup = async (req, res) => {
6+
try {
7+
const { fullName, username, password, confirmPassword, gender } = req.body;
8+
9+
if (password !== confirmPassword) {
10+
return res.status(400).json({ error: "Passwords don't match" });
11+
}
12+
13+
const user = await User.findOne({ username });
14+
15+
if (user) {
16+
return res.status(400).json({ error: "Username already exists" });
17+
}
18+
19+
// HASH PASSWORD HERE
20+
const salt = await bcrypt.genSalt(10);
21+
const hashedPassword = await bcrypt.hash(password, salt);
22+
23+
// https://avatar-placeholder.iran.liara.run/
24+
25+
const boyProfilePic = `https://avatar.iran.liara.run/public/boy?username=${username}`;
26+
const girlProfilePic = `https://avatar.iran.liara.run/public/girl?username=${username}`;
27+
28+
const newUser = new User({
29+
fullName,
30+
username,
31+
password: hashedPassword,
32+
gender,
33+
profilePic: gender === "male" ? boyProfilePic : girlProfilePic,
34+
});
35+
36+
if (newUser) {
37+
// Generate JWT token here
38+
generateTokenAndSetCookie(newUser._id, res);
39+
await newUser.save();
40+
41+
res.status(201).json({
42+
_id: newUser._id,
43+
fullName: newUser.fullName,
44+
username: newUser.username,
45+
profilePic: newUser.profilePic,
46+
});
47+
} else {
48+
res.status(400).json({ error: "Invalid user data" });
49+
}
50+
} catch (error) {
51+
console.log("Error in signup controller", error.message);
52+
res.status(500).json({ error: "Internal Server Error" });
53+
}
54+
};
55+
56+
export const login = async (req, res) => {
57+
try {
58+
const { username, password } = req.body;
59+
const user = await User.findOne({ username });
60+
const isPasswordCorrect = await bcrypt.compare(password, user?.password || "");
61+
62+
if (!user || !isPasswordCorrect) {
63+
return res.status(400).json({ error: "Invalid username or password" });
64+
}
65+
66+
generateTokenAndSetCookie(user._id, res);
67+
68+
res.status(200).json({
69+
_id: user._id,
70+
fullName: user.fullName,
71+
username: user.username,
72+
profilePic: user.profilePic,
73+
});
74+
} catch (error) {
75+
console.log("Error in login controller", error.message);
76+
res.status(500).json({ error: "Internal Server Error" });
77+
}
78+
};
79+
80+
export const logout = (req, res) => {
81+
try {
82+
res.cookie("jwt", "", { maxAge: 0 });
83+
res.status(200).json({ message: "Logged out successfully" });
84+
} catch (error) {
85+
console.log("Error in logout controller", error.message);
86+
res.status(500).json({ error: "Internal Server Error" });
87+
}
88+
};
+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import bcryptjs from 'bcryptjs'
2+
import User from "../models/user.model.js"
3+
import generateJWT from '../utils/generateJWT.js';
4+
5+
6+
export const signup = async (req,res) => {
7+
try {
8+
const { fullName, username, password, confirmPassword, gender } = req.body
9+
10+
if (password !== confirmPassword) {
11+
return res.status(400).json({ error: "Passwords don't match" });
12+
}
13+
14+
const user = await User.findOne({ username });
15+
16+
if (user) {
17+
return res.status(400).json({ error: "Username already exists" });
18+
}
19+
20+
// HASH PASSWORD HERE
21+
const salt = await bcryptjs.genSalt(9)
22+
const hashedPasswd = await bcryptjs.hash(password,salt)
23+
24+
// https://avatar-placeholder.iran.liara.run/
25+
26+
const boyProfilePic = `https://avatar.iran.liara.run/public/boy?username=${username}`;
27+
const girlProfilePic = `https://avatar.iran.liara.run/public/girl?username=${username}`;
28+
29+
const newUser = new User({
30+
fullName,
31+
username,
32+
gender,
33+
password : hashedPasswd,
34+
profilePic: gender === "male" ? boyProfilePic : girlProfilePic,
35+
});
36+
37+
if (newUser) {
38+
// generate JWT token
39+
generateJWT(newUser._id,res)
40+
await newUser.save()
41+
res.status(201).json({
42+
_id: newUser._id,
43+
fullName: newUser.fullName,
44+
username: newUser.username,
45+
profilePic: newUser.profilePic,
46+
});
47+
48+
} else {
49+
res.status(400).json({ error: "Invalid user data" });
50+
}
51+
} catch (error) {
52+
console.log("Error in signup controller", error.message);
53+
res.status(500).json({ error: "Internal Server Error" });
54+
}
55+
};
56+
57+
58+
export const login = async (req,res) => {
59+
try {
60+
const {username,password} = req.body
61+
const user = await User.findOne({username})
62+
const isPass = await bcryptjs.compare(password,user?user.password:"")
63+
if (!user || !isPass){
64+
return res.status(400).json({ error: "Invalid credentials" });
65+
}
66+
generateJWT(user._id,res)
67+
res.status(201).json({
68+
_id: user._id,
69+
fullName: user.fullName,
70+
username: user.username,
71+
profilePic: user.profilePic,
72+
})
73+
} catch (error) {
74+
console.log("Error in login controller", error.message,req.body);
75+
res.status(500).json({ error: "Internal Server Error" });
76+
}
77+
}
78+
export const logout = (req,res) => {
79+
try {
80+
res.cookie('jwt','',{maxAge : 0})
81+
res.status(200).json({message : 'Logged out successfully'})
82+
} catch (error) {
83+
console.log("Error in logout controller", error.message);
84+
res.status(500).json({ error: "Internal Server Error" });
85+
}
86+
87+
}
+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import Conversation from "../models/conversation.model.js";
2+
import Message from "../models/message.model.js";
3+
import { getReceiverSocketId, io } from "../socket/socket.js";
4+
5+
export const sendMessage = async (req, res) => {
6+
try {
7+
const { message } = req.body;
8+
const { id: receiverId } = req.params;
9+
const senderId = req.user._id;
10+
11+
let conversation = await Conversation.findOne({
12+
participants: { $all: [senderId, receiverId] },
13+
});
14+
15+
if (!conversation) {
16+
conversation = await Conversation.create({
17+
participants: [senderId, receiverId],
18+
});
19+
}
20+
21+
const newMessage = new Message({
22+
senderId,
23+
receiverId,
24+
message,
25+
});
26+
27+
if (newMessage) {
28+
conversation.messages.push(newMessage._id);
29+
}
30+
31+
// await conversation.save();
32+
// await newMessage.save();
33+
34+
// this will run in parallel
35+
await Promise.all([conversation.save(), newMessage.save()]);
36+
37+
// SOCKET IO FUNCTIONALITY WILL GO HERE
38+
const receiverSocketId = getReceiverSocketId(receiverId);
39+
if (receiverSocketId) {
40+
// io.to(<socket_id>).emit() used to send events to specific client
41+
io.to(receiverSocketId).emit("newMessage", newMessage);
42+
}
43+
44+
res.status(201).json(newMessage);
45+
} catch (error) {
46+
console.log("Error in sendMessage controller: ", error.message);
47+
res.status(500).json({ error: "Internal server error" });
48+
}
49+
};
50+
51+
export const getMessages = async (req, res) => {
52+
try {
53+
const { id: userToChatId } = req.params;
54+
const senderId = req.user._id;
55+
56+
const conversation = await Conversation.findOne({
57+
participants: { $all: [senderId, userToChatId] },
58+
}).populate("messages"); // NOT REFERENCE BUT ACTUAL MESSAGES
59+
60+
if (!conversation) return res.status(200).json([]);
61+
62+
const messages = conversation.messages;
63+
64+
res.status(200).json(messages);
65+
} catch (error) {
66+
console.log("Error in getMessages controller: ", error.message);
67+
res.status(500).json({ error: "Internal server error" });
68+
}
69+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import Message from '../models/messages.model.js'
2+
import Convo from '../models/conversations.model.js'
3+
import { io ,getSocket} from '../socket/socket.js';
4+
import mongoose from 'mongoose';
5+
process.on('uncaughtException', function (err) {
6+
console.log("Node NOT Exiting...");
7+
});
8+
9+
10+
11+
export const sendMessage = async (req, res) => {
12+
try {
13+
const { message } = req.body;
14+
const senderID = req.user._id;
15+
const { id: receiverID } = req.params
16+
17+
let convo = await Convo.findOne({ participants: { $all: [senderID, receiverID] } });
18+
19+
// Check if conversation exists, if not, create a new one
20+
if (!convo) {
21+
convo = await Convo.create({
22+
participants: [senderID, receiverID],
23+
messages: [] // Initialize messages array
24+
});
25+
}
26+
27+
const newMessage = new Message({
28+
senderID,
29+
receiverID,
30+
message
31+
});
32+
33+
// Check if newMessage is successfully created
34+
if (newMessage) {
35+
// Ensure convo.messages is initialized as an array
36+
if (!convo.messages) {
37+
convo.messages = [];
38+
}
39+
// Push the new message ID to convo.messages
40+
convo.messages.push(newMessage._id);
41+
}
42+
43+
// Save both conversation and message
44+
await Promise.all([convo.save(), newMessage.save()]);
45+
const receiverSocket = getMessages(receiverID)
46+
if (receiverSocket){
47+
io.to(receiverSocket).emit("newMessage",newMessage)
48+
}
49+
res.status(200).json(newMessage);
50+
} catch (error) {
51+
console.log("Error in sendMessage controller", error.message, req.body);
52+
res.status(500).json({ error: "Internal Server Error" });
53+
}
54+
};
55+
export const getMessages = async (req, res) => {
56+
try {
57+
const { id: userToChatId } = req.params;
58+
const senderId = req.user._id;
59+
60+
const conversation = await Convo.findOne({
61+
participants: { $all: [senderId, userToChatId] },
62+
}).populate("messages"); // NOT REFERENCE BUT ACTUAL MESSAGES
63+
64+
if (!conversation) return res.status(200).json([]);
65+
66+
const messages = conversation.messages;
67+
68+
res.status(200).json(messages);
69+
} catch (error) {
70+
console.log("Error in getMessages controller: ", error.message);
71+
res.status(500).json({ error: "Internal server error" });
72+
}
73+
};
74+
75+
// export const getMessages = async (req, res) => {
76+
// try {
77+
// // Perform null checks for req and req.params
78+
// const receiverID = req && req.params ? req.params.id : null;
79+
// const senderID = req && req.user ? req.user._id : null;
80+
81+
// // Check if receiverID is missing
82+
// if (!receiverID) {
83+
// return res.status(400).json({ error: "Receiver ID is missing or invalid" });
84+
// }
85+
86+
// // Check if senderID is missing
87+
// if (!senderID) {
88+
// return res.status(400).json({ error: "Sender ID is missing or invalid" });
89+
// }
90+
91+
// // Verify if both sender and receiver IDs are valid ObjectId strings
92+
// if (!mongoose.Types.ObjectId.isValid(senderID) || !mongoose.Types.ObjectId.isValid(receiverID)) {
93+
// return res.status(400).json({ error: "Sender ID or Receiver ID is invalid" });
94+
// }
95+
96+
// // Find the conversation between sender and receiver
97+
// const conversation = await Convo.findOne({ participants: { $all: [senderID, receiverID] } }).populate("messages");
98+
99+
// if (!conversation) {
100+
// // If conversation is not found, return an empty array
101+
// return res.status(200).json([]);
102+
// }
103+
104+
// // Return the conversation messages
105+
// return res.status(200).json(conversation.messages);
106+
// } catch (error) {
107+
// // Log the error for debugging
108+
// console.error("Error in getMessages controller:", error);
109+
110+
// // Return a generic error response to the client
111+
// return res.status(500).json({ error: "Internal Server Error" });
112+
// }
113+
// };

0 commit comments

Comments
 (0)