-
Notifications
You must be signed in to change notification settings - Fork 299
Solution #229
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
base: master
Are you sure you want to change the base?
Solution #229
Conversation
mateacademy-ai-mentor
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review Summary
Changes are needed as several core requirements have not been met. You have a good start with the PostgreSQL setup and JWT middleware, but there are critical blockers to address. The application is missing required features like a logout endpoint and a 404 handler for undefined routes. Several validation flows are also incomplete: registration is missing the name field and password rules, while the password reset/change flows lack the required confirmation field. Finally, there's a significant database conflict, as Mongoose/MongoDB files (src/models/user.js) are present in a PostgreSQL project, which will cause errors. Please address these issues to complete the task.
✨ Please rate this review in the Platform's notification center1. I will be grateful for your feedback! ✨
Important
Fix the issues, commit the changes, and then re-request my review using the Re-request review button2 in the Reviewers tab.
Tip
If you have any comments about this review, please leave a message in the Add a comment section below and mention me with the @mateacademy-ai-mentor tag3.
I will read your message during my next review of your pull request. Please do not reply directly to my comments, as that feature is not supported yet.
Caution
Do not close the pull request until the review is complete. Closing it early can lead to unexpected behavior and disrupt the review process.
Footnotes
src/index.js
Outdated
|
|
||
| app.use(express.json()); | ||
|
|
||
| app.use("/api/auth", authRoutes); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The application is missing a handler for routes that are not defined. The requirements state that you must "Show a 404 for all the other pages". You should add a catch-all middleware after your defined routes to handle any requests that don't match.
src/controllers/auth.controller.js
Outdated
| @@ -0,0 +1,22 @@ | |||
| // ./auth.controller.js | |||
| import { user } from "../models/user.js"; | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file is importing and using a Mongoose model, which is for MongoDB. However, the rest of your application is configured to use PostgreSQL (see src/db.js and the implementation in src/routes/auth.js). This code is incompatible with the project's database and will not work. It appears the correct activation logic is already present in src/routes/auth.js.
| userToActivate.activationToken = null; | ||
| await userToActivate.save(); | ||
|
|
||
| res.redirect(process.env.CLIENT_HOST); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to the task requirements, the user should be redirected to their profile page after successful activation. Redirecting to the base CLIENT_HOST will likely land them on the homepage. You should redirect to a more specific path, for example, ${process.env.CLIENT_HOST}/profile.
src/models/user.js
Outdated
| import mongoose from "mongoose"; | ||
|
|
||
| const userSchema = new mongoose.Schema({ | ||
| email: { type: String, required: true, unique: true }, | ||
| password: { type: String, required: true }, | ||
|
|
||
| isActivated: { type: Boolean, default: false }, | ||
| activationToken: { type: String }, | ||
| }); | ||
|
|
||
| export const user = mongoose.model("User", userSchema); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file defines a user model using Mongoose, which is an ODM for MongoDB. However, your application is configured to use PostgreSQL (via the pg library). This model is incompatible with your database setup and appears to be unused by the active routes in src/routes/auth.js.
| }); | ||
| }; | ||
|
|
||
| export const sendChangeEmailEmail = async (email, token) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The task requires that when a user changes their email, the old email address should be notified of this change. This file implements sending a confirmation to the new email address but lacks a corresponding function to send a notification to the old one. You'll need to add a new function for this purpose and call it from your email change route.
src/routes/auth.js
Outdated
| [token], | ||
| ); | ||
|
|
||
| res.json({ message: "Account activated" }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to the requirements, the user should be redirected to their profile page after successful activation. This endpoint currently returns a JSON response. You should use res.redirect() to send the user to the profile page.
| router.post("/reset-password/:token", async (req, res) => { | ||
| try { | ||
| const { token } = req.params; | ||
| const { password } = req.body; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The requirements for the password reset flow specify that the confirmation page must have password and confirmation fields that are equal. This endpoint only accepts a password field and lacks the necessary validation against a confirmation field.
| ========================= */ | ||
| router.post("/request-change-password", authMiddleware, async (req, res) => { | ||
| try { | ||
| const { oldPassword, newPassword } = req.body; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When a user changes their password from the profile page, the requirements specify that it should require an old password, a new password, and a confirmation field. This endpoint is missing the logic to validate that newPassword matches a confirmation field from the request body.
| await sendChangeEmailEmail(newEmail, token); | ||
| // 🔔 (опціонально, але дуже рекомендую) | ||
| // Надіслати лист на СТАРУ пошту, що хтось намагається змінити email | ||
| // await sendOldEmailNotification(user.email); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One of the requirements for changing an email is to notify the old email address about the change. The line of code to handle this functionality is commented out and thus not implemented.
| } | ||
| }); | ||
|
|
||
| export default router; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The application is missing the logout functionality entirely. The task requirements specify that there should be an endpoint for authenticated users to log out, which should then redirect them to the login page.
mateacademy-ai-mentor
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review Summary
This submission requires changes. While you've done a great job migrating to PostgreSQL, several critical features are missing or incomplete, and there's an issue that will cause a runtime crash.
Here are the main points to address:
- Runtime Error: The
cryptomodule is used insrc/routes/auth.jswithout being imported. This will cause aReferenceErrorand crash the application. Please add the necessary import statement. - Missing Core Features: The application is missing a
/logoutendpoint and a catch-all route insrc/index.jsto handle 404 errors for undefined pages. - Incomplete Functionality:
- The
/signuproute needs to accept anamefield and validate the password against complexity rules. - The password reset and change password routes are missing the
confirmationfield and the logic to ensure it matches the new password.
- The
- Project Cleanup: Please remove the leftover MongoDB files:
src/models/user.jsandsrc/controllers/auth.controller.js, as they are not compatible with the project's PostgreSQL setup.
Addressing these issues will bring the project in line with the requirements.
✨ Please rate this review in the Platform's notification center1. I will be grateful for your feedback! ✨
Important
Fix the issues, commit the changes, and then re-request my review using the Re-request review button2 in the Reviewers tab.
Tip
If you have any comments about this review, please leave a message in the Add a comment section below and mention me with the @mateacademy-ai-mentor tag3.
I will read your message during my next review of your pull request. Please do not reply directly to my comments, as that feature is not supported yet.
Caution
Do not close the pull request until the review is complete. Closing it early can lead to unexpected behavior and disrupt the review process.
Footnotes
| import { user } from '../models/user.js'; | ||
|
|
||
| export const activate = async (req, res) => { | ||
| try { | ||
| const { token } = req.params; | ||
|
|
||
| const userToActivate = await user.findOne({ activationToken: token }); | ||
|
|
||
| if (!userToActivate) { | ||
| return res.status(400).json({ message: 'Invalid token' }); | ||
| } | ||
|
|
||
| userToActivate.isActivated = true; | ||
| userToActivate.activationToken = null; | ||
| await userToActivate.save(); | ||
|
|
||
| res.redirect(process.env.CLIENT_HOST); | ||
| } catch (e) { | ||
| res.status(400).json({ message: 'Activation failed' }); | ||
| } | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This controller imports and uses a Mongoose model (user.findOne, userToActivate.save). However, the project has been migrated to PostgreSQL. This file seems to be a leftover and is not used anywhere in the application. The activation logic is handled directly in src/routes/auth.js. This file should be removed.
| app.use(express.json()); | ||
|
|
||
| app.use('/api/auth', authRoutes); | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The application is still missing a handler for undefined routes. According to the requirements, you need to show a 404 page for any route that doesn't match. You should add a catch-all middleware here, after all other routes have been defined, to handle this.
| // users.js // | ||
|
|
||
| import mongoose from 'mongoose'; | ||
|
|
||
| const userSchema = new mongoose.Schema({ | ||
| email: { type: String, required: true, unique: true }, | ||
| password: { type: String, required: true }, | ||
|
|
||
| isActivated: { type: Boolean, default: false }, | ||
| activationToken: { type: String }, | ||
| }); | ||
|
|
||
| export const user = mongoose.model('User', userSchema); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This project uses PostgreSQL, but this file defines a Mongoose schema for MongoDB. This was a critical issue identified in the previous review. Please remove this file as it is not compatible with the project's database setup.
| </div> | ||
| `, | ||
| }); | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The requirements state that when a user requests to change their email, a notification should be sent to the old email address about this change. You've correctly implemented sending a confirmation to the new email, but you're missing a function to notify the old one. Please add a new function for this purpose.
| ========================= */ | ||
| router.post('/signup', async (req, res) => { | ||
| try { | ||
| const { email, password } = req.body; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The registration requirement specifies that a user should register using name, email, and password. This endpoint is missing the name field from the request body. The username is currently derived from the email, which may not be the user's actual name.
| } | ||
|
|
||
| const hashedPassword = await bcrypt.hash(password, 10); | ||
| const activationToken = crypto.randomUUID(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The crypto module is used here to generate a token, but it hasn't been imported at the top of the file. This will cause a ReferenceError at runtime. You need to add import crypto from 'crypto'; to resolve this.
| [token], | ||
| ); | ||
|
|
||
| res.json({ message: 'Account activated' }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to the task requirements, the application should "redirect to Profile after the activation". This endpoint currently returns a JSON response. It should perform a redirect, for example, to a success page on your client application that then navigates the user to their profile.
| router.post('/reset-password/:token', async (req, res) => { | ||
| try { | ||
| const { token } = req.params; | ||
| const { password } = req.body; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The requirements for the password reset page specify it should have password and confirmation fields that must be equal. This endpoint only accepts the password field and doesn't validate it against a confirmation field.
| ========================= */ | ||
| router.post('/request-change-password', authMiddleware, async (req, res) => { | ||
| try { | ||
| const { oldPassword, newPassword } = req.body; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to the password reset flow, the profile page's change password feature requires new password and confirmation fields. This endpoint is missing the confirmation field and the check to ensure it matches the newPassword.
| await sendChangeEmailEmail(newEmail, token); | ||
| // 🔔 (опціонально, але дуже рекомендую) | ||
| // Надіслати лист на СТАРУ пошту, що хтось намагається змінити email | ||
| // await sendOldEmailNotification(user.email); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The requirement to "notify the old email about the change" when a user changes their email address has not been implemented. I see a commented-out line that suggests this was planned but not completed.
mateacademy-ai-mentor
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review Summary
I am approving this submission as an educational override to help you progress, but several critical issues from the previous review remain.
Excellent work on migrating the database logic to PostgreSQL! That's a significant accomplishment. However, the application currently has a runtime error because the crypto module is not imported in src/routes/auth.js.
Before moving on, please focus on implementing the missing core features, such as the /logout endpoint, the 404 catch-all route, and adding the required name field for registration. Also, remember to implement the password confirmation logic and remove the unused MongoDB files. Keep up the great effort!
✨ Please rate this review in the Platform's notification center1. I will be grateful for your feedback! ✨
Footnotes
| app.use(express.json()); | ||
|
|
||
| app.use('/api/auth', authRoutes); | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to the requirements, you need to implement a 404 handler for all undefined routes. You should add a catch-all route here, after all other routes have been defined, to handle any requests that don't match an existing endpoint.
| // ./auth.controller.js | ||
| import { user } from '../models/user.js'; | ||
|
|
||
| export const activate = async (req, res) => { | ||
| try { | ||
| const { token } = req.params; | ||
|
|
||
| const userToActivate = await user.findOne({ activationToken: token }); | ||
|
|
||
| if (!userToActivate) { | ||
| return res.status(400).json({ message: 'Invalid token' }); | ||
| } | ||
|
|
||
| userToActivate.isActivated = true; | ||
| userToActivate.activationToken = null; | ||
| await userToActivate.save(); | ||
|
|
||
| res.redirect(process.env.CLIENT_HOST); | ||
| } catch (e) { | ||
| res.status(400).json({ message: 'Activation failed' }); | ||
| } | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This controller file seems to be a leftover from a previous MongoDB setup and is no longer used in the current PostgreSQL implementation. It should be removed from the project.
| // users.js // | ||
|
|
||
| import mongoose from 'mongoose'; | ||
|
|
||
| const userSchema = new mongoose.Schema({ | ||
| email: { type: String, required: true, unique: true }, | ||
| password: { type: String, required: true }, | ||
|
|
||
| isActivated: { type: Boolean, default: false }, | ||
| activationToken: { type: String }, | ||
| }); | ||
|
|
||
| export const user = mongoose.model('User', userSchema); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This Mongoose model is a remnant from the previous MongoDB implementation. Since the application now uses PostgreSQL, this file is no longer necessary and should be removed from the project.
| </div> | ||
| `, | ||
| }); | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to the task description, when a user requests to change their email, their old email address must be notified of the change. You've implemented sending a confirmation to the new email, but a function to send a notification to the old email address is missing.
| ========================= */ | ||
| router.post('/signup', async (req, res) => { | ||
| try { | ||
| const { email, password } = req.body; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The registration endpoint must accept a name field from the request body as per the requirements. Currently, you're only destructuring email and password.
| } | ||
|
|
||
| const hashedPassword = await bcrypt.hash(password, 10); | ||
| const activationToken = crypto.randomUUID(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The crypto module is used here to generate a token, but it hasn't been imported at the top of the file. This will cause a ReferenceError and crash the application. Please add import crypto from 'crypto';.
| router.post('/reset-password/:token', async (req, res) => { | ||
| try { | ||
| const { token } = req.params; | ||
| const { password } = req.body; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to the requirements, the password reset functionality must include a confirmation field that matches the password. This endpoint should receive and validate this field.
| ========================= */ | ||
| router.post('/request-change-password', authMiddleware, async (req, res) => { | ||
| try { | ||
| const { oldPassword, newPassword } = req.body; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The change password functionality requires a confirmation field for the new password, which should be validated to ensure it matches newPassword.
| await sendChangeEmailEmail(newEmail, token); | ||
| // 🔔 (опціонально, але дуже рекомендую) | ||
| // Надіслати лист на СТАРУ пошту, що хтось намагається змінити email | ||
| // await sendOldEmailNotification(user.email); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The requirement to notify the old email address about the change has not been implemented. This line is commented out and needs to be implemented to fulfill the task requirements.
| } | ||
| }); | ||
|
|
||
| export default router; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The application is still missing the /logout endpoint, which is a core requirement for authenticated users. Please implement this feature.
No description provided.