Skip to content

Commit ba55cb3

Browse files
committed
Release v1.0.0
Refactor backend and frontend structure - Deleted unused middleware and routes in the backend: - Removed: admin.js, auth.js, privateRoute.js, validObjectId.js - Removed routes: adminRoute.js, auth.js, comments.js, playlists.js, search.js, songs.js, users.js - Removed models: comment.js, playlist.js, song.js, user.js - Added new backend structure: - Added controllers, updated models with `.model.js` naming - Added new routes with `.route.js` naming - Added token generation utility and Gmail utility - Updated backend logic: - Refactored `server.js` and `helpers.js` - Modified frontend components and pages: - Refactored Navbar, Sidebar, PlaylistView, SingleSongCard, TrackList, and other components - Updated pages like HomePage, LoginPage, MySongPage, SignUpPage, and others - Deleted unused pages: FeedPage.jsx, LibraryPage.jsx, ResetPassword.jsx - Added new frontend features: - Added DashboardPage.jsx, EmailVerificationPage.jsx, ResetPasswordPage.jsx - Added new components: FloatingShape.jsx, Input.jsx, LoadingSpinner.jsx, PasswordStrengthMeter.jsx - Introduced state management in `frontend/src/store` - Updated utility files and configuration: - Updated `config.jsx`, `serverHelper.jsx`, and added `date.js` - Adjusted dependencies: - Updated `package.json` and `package-lock.json`
1 parent 1baffec commit ba55cb3

78 files changed

Lines changed: 3957 additions & 1634 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
import bcryptjs from "bcryptjs";
2+
import crypto from "crypto";
3+
4+
import { generateTokenAndSetCookie } from "../utils/generateTokenAndSetCookie.js";
5+
import {
6+
sendPasswordResetEmail,
7+
sendResetSuccessEmail,
8+
sendVerificationEmail,
9+
sendWelcomeEmail,
10+
} from "../gmail/emails.js";
11+
import { User } from "../model/user.model.js";
12+
import getToken from "../utils/helpers.js";
13+
14+
export const signup = async (req, res) => {
15+
const { email, password, username, avatar } = req.body;
16+
17+
try {
18+
if (!email || !password || !username) {
19+
throw new Error("All fields are required");
20+
}
21+
22+
const userAlreadyExists = await User.findOne({ email });
23+
console.log("userAlreadyExists", userAlreadyExists);
24+
25+
if (userAlreadyExists) {
26+
return res
27+
.status(400)
28+
.json({ success: false, message: "User already exists" });
29+
}
30+
31+
const hashedPassword = await bcryptjs.hash(password, 10);
32+
const verificationToken = Math.floor(
33+
100000 + Math.random() * 900000
34+
).toString();
35+
36+
const user = new User({
37+
email,
38+
password: hashedPassword,
39+
username,
40+
avatar,
41+
verificationToken,
42+
verificationTokenExpiresAt: Date.now() + 24 * 60 * 60 * 1000, // 24 hours
43+
});
44+
45+
await user.save();
46+
47+
// jwt
48+
generateTokenAndSetCookie(res, user._id);
49+
50+
await sendVerificationEmail(user.email, verificationToken);
51+
52+
res.status(201).json({
53+
success: true,
54+
message: "User created successfully",
55+
user: {
56+
...user._doc,
57+
password: undefined,
58+
},
59+
});
60+
} catch (error) {
61+
res.status(400).json({ success: false, message: error.message });
62+
}
63+
};
64+
65+
export const verifyEmail = async (req, res) => {
66+
const { code } = req.body;
67+
try {
68+
const user = await User.findOne({
69+
verificationToken: code,
70+
verificationTokenExpiresAt: { $gt: Date.now() },
71+
});
72+
73+
if (!user) {
74+
return res.status(400).json({
75+
success: false,
76+
message: "Invalid or expired verification code",
77+
});
78+
}
79+
80+
user.isVerified = true;
81+
user.verificationToken = undefined;
82+
user.verificationTokenExpiresAt = undefined;
83+
await user.save();
84+
85+
await sendWelcomeEmail(user.email, user.username);
86+
87+
res.status(200).json({
88+
success: true,
89+
message: "Email verified successfully",
90+
user: {
91+
...user._doc,
92+
password: undefined,
93+
},
94+
});
95+
} catch (error) {
96+
console.log("error in verifyEmail ", error);
97+
res.status(500).json({ success: false, message: "Server error" });
98+
}
99+
};
100+
101+
export const login = async (req, res) => {
102+
const { email, password } = req.body;
103+
104+
try {
105+
if (!email || !password) {
106+
return res.status(400).json({ error: "Email and password are required" });
107+
}
108+
109+
const user = await User.findOne({ email });
110+
if (!user) {
111+
return res.status(403).json({ error: "Invalid credentials" });
112+
}
113+
114+
const isPasswordValid = await bcryptjs.compare(password, user.password);
115+
if (!isPasswordValid) {
116+
return res.status(403).json({ error: "Invalid credentials" });
117+
}
118+
119+
// Create JWT token
120+
const token = getToken(user);
121+
122+
// Set token in cookie for same-origin access
123+
res.cookie("authToken", token, {
124+
httpOnly: true,
125+
secure: true,
126+
sameSite: "Strict",
127+
});
128+
129+
// Prepare response data
130+
const userToReturn = { ...user.toObject(), token };
131+
delete userToReturn.password;
132+
133+
return res.status(200).json(userToReturn);
134+
} catch (error) {
135+
console.error("Login Error:", error);
136+
return res.status(500).json({ error: "Internal server error" });
137+
}
138+
};
139+
140+
export const logout = async (req, res) => {
141+
res.clearCookie("token");
142+
res.status(200).json({ success: true, message: "Logged out successfully" });
143+
};
144+
145+
export const forgotPassword = async (req, res) => {
146+
const { email } = req.body;
147+
try {
148+
const user = await User.findOne({ email });
149+
150+
if (!user) {
151+
return res
152+
.status(400)
153+
.json({ success: false, message: "User not found" });
154+
}
155+
156+
// Generate reset token
157+
const resetToken = crypto.randomBytes(20).toString("hex");
158+
const resetTokenExpiresAt = Date.now() + 1 * 60 * 60 * 1000; // 1 hour
159+
160+
user.resetPasswordToken = resetToken;
161+
user.resetPasswordExpiresAt = resetTokenExpiresAt;
162+
163+
await user.save();
164+
165+
// send email
166+
await sendPasswordResetEmail(
167+
user.email,
168+
`${process.env.CLIENT_URL}/reset-password/${resetToken}`
169+
);
170+
171+
res.status(200).json({
172+
success: true,
173+
message: "Password reset link sent to your email",
174+
});
175+
} catch (error) {
176+
console.log("Error in forgotPassword ", error);
177+
res.status(400).json({ success: false, message: error.message });
178+
}
179+
};
180+
181+
export const resetPassword = async (req, res) => {
182+
try {
183+
const { token } = req.params;
184+
const { password } = req.body;
185+
186+
const user = await User.findOne({
187+
resetPasswordToken: token,
188+
resetPasswordExpiresAt: { $gt: Date.now() },
189+
});
190+
191+
if (!user) {
192+
return res
193+
.status(400)
194+
.json({ success: false, message: "Invalid or expired reset token" });
195+
}
196+
197+
// update password
198+
const hashedPassword = await bcryptjs.hash(password, 10);
199+
200+
user.password = hashedPassword;
201+
user.resetPasswordToken = undefined;
202+
user.resetPasswordExpiresAt = undefined;
203+
await user.save();
204+
205+
await sendResetSuccessEmail(user.email);
206+
207+
res
208+
.status(200)
209+
.json({ success: true, message: "Password reset successful" });
210+
} catch (error) {
211+
console.log("Error in resetPassword ", error);
212+
res.status(400).json({ success: false, message: error.message });
213+
}
214+
};
215+
216+
export const checkAuth = async (req, res) => {
217+
try {
218+
const user = await User.findById(req.userId).select("-password");
219+
if (!user) {
220+
return res
221+
.status(400)
222+
.json({ success: false, message: "User not found" });
223+
}
224+
225+
res.status(200).json({ success: true, user });
226+
} catch (error) {
227+
console.log("Error in checkAuth ", error);
228+
res.status(400).json({ success: false, message: error.message });
229+
}
230+
};
File renamed without changes.

0 commit comments

Comments
 (0)