Skip to content

feat: implement auth backend with EJS templates#256

Open
Nazarii-Lesniak wants to merge 15 commits intomate-academy:masterfrom
Nazarii-Lesniak:develop
Open

feat: implement auth backend with EJS templates#256
Nazarii-Lesniak wants to merge 15 commits intomate-academy:masterfrom
Nazarii-Lesniak:develop

Conversation

@Nazarii-Lesniak
Copy link
Copy Markdown

No description provided.

Copy link
Copy Markdown

@mateacademy-ai-mentor mateacademy-ai-mentor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

Great work on this project! The code is well-structured and you've successfully implemented most of the authentication features. However, a couple of critical issues are preventing approval.

First, the email change confirmation feature is broken. In src/services/userService.ts, the activation function only looks up users by their primary email. When confirming a new email address, the lookup fails because the new address is stored in the newEmail field. You'll need to adjust the logic to also check for a user with a matching newEmail.

Second, the logout endpoint is not secure. The task requires this feature to be available only to authenticated users, but the /logout route in src/routes/authRoutes.ts is missing the authMiddleware. Please add the middleware to protect this route.

Once these issues are addressed, your solution will be in great shape!


✨ 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

  1. Rate AI review example

  2. Re-request AI review example

  3. Add AI review comments example

authController.resetPasswordRequest,
);

authRouter.post('/logout', authController.logout);
Copy link
Copy Markdown

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, the logout feature should be available to authenticated users only. This route should be protected by the authMiddleware to enforce this requirement.

Comment on lines +72 to +76
const user = await getByEmail(email);

if (!user) {
throw new Error('User not found');
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current logic for finding a user in the activation function will fail when a user is trying to confirm a new email address. The getByEmail function searches for a user by their primary email, but during an email change, the email parameter here is the new email address, which is stored in the newEmail field. You should adjust the logic to also check for a user with a matching newEmail if no user is found by their primary email address.

Copy link
Copy Markdown

@mateacademy-ai-mentor mateacademy-ai-mentor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

Great job addressing the critical issues from the last review! Your project is very close to being complete. However, a couple of key requirements are not yet fully met, so I am requesting a few changes before approval.

  1. 404 Page Handling: The application needs to render a user-friendly HTML page for 404 errors. Currently, it sends a JSON response, which isn't suitable for a server-rendered application. Please update your errorMiddleware in src/middlewares/errorMiddleware.ts to check for a 404 status and render a dedicated 404 view.

  2. Email Change Notification Timing: The notification to the user's old email address is sent as soon as the change is requested, not when it's confirmed. This is misleading. This notification logic should be moved from the updateProfile function to the activation function in src/services/userService.ts, so it's sent only after the new email is successfully verified.

Once these two issues are resolved, your project will be ready for approval. Keep up the great work!


✨ 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

  1. Rate AI review example

  2. Re-request AI review example

  3. Add AI review comments example

await userService.updateProfile({ email, name });
response.redirect('/user/profile');
} catch (error) {
next(error);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error handling here is inconsistent with updatePassword and updateEmail. In those functions, if an error occurs, you fetch the user's data and re-render the profile page with a specific error message. Here, you're passing the error to the next middleware, which will likely result in a generic error page or a JSON response. For a better and more consistent user experience, consider adopting the same pattern you used for the other update functions.

await tokenService.removeToken(refreshToken);
response.clearCookie('refreshToken');

response.clearCookie('refreshToken');
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're calling response.clearCookie('refreshToken') twice. This line is redundant and can be removed.

Comment on lines +30 to +32
app.use((req, res, next) => {
next(ApiError.NotFound());
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The task requires a "404 for all the other pages". Since this is a server-side rendered application, sending a JSON error response is not the expected behavior. This should be handled by rendering a dedicated 404 page. You could add a check for error.status === 404 in your errorMiddleware to render a view.

Comment on lines +20 to +22
return response
.status(error.status)
.send({ message: error.message, errors: error.errors });
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The task requires a "404 for all the other pages". Since this is a server-rendered application, sending a JSON response for a 404 error is not ideal for the user experience. You should add a check for when error.status is 404 and render a dedicated 404 page instead.

Comment on lines +88 to +98
if (user.newEmail === email) {
await prisma.user.update({
where: {
id: user.id,
},
data: {
email: user.newEmail,
newEmail: null,
activationToken: null,
},
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When a user confirms their new email address, you update the user record here. This is the correct place to send the notification to the user's old email address, informing them that the change has been completed. You can capture the old email from the user.email property before this update query runs.

throw new Error('Invalid credentials');
}

await emailService.sendMessageToChangeEmail(user.email);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This notification is being sent to the user's old email address as soon as they request a change, not when they confirm it. The requirement is to "notify the old email about the change," which implies the change has already been successfully confirmed. Please move this email sending logic to the activation function, where the new email address is actually confirmed and set.

Comment on lines +39 to +40
const html = `
<h1>Email has been changed</h1>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The content of this email, 'Email has been changed,' is misleading. Based on the logic in userService.ts, this email is sent to the old address as soon as the change is requested, not after it's confirmed. A more accurate message would be something like, 'A request has been made to change the email address for your account.' This would prevent user confusion if they don't complete the confirmation process.

Copy link
Copy Markdown

@mateacademy-ai-mentor mateacademy-ai-mentor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

Excellent work on this project! You've successfully implemented all the features and addressed the feedback from the previous review perfectly. The application's logic for authentication, user management, and error handling is solid.

I am approving your solution as an educational override so you can move forward, but there's one small configuration issue causing the build to fail. Your package.json is set to "type": "module", which tells Node.js to treat .js files as ES modules. However, your .eslintrc.js file uses CommonJS syntax (module.exports), causing a conflict.

To fix this, you just need to rename the file to explicitly mark it as a CommonJS module:
mv .eslintrc.js .eslintrc.cjs

This is a common configuration detail when mixing module types. Once you make that change, your project will be perfect. Great job overall!


✨ 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

  1. Rate AI review example

  2. Re-request AI review example

  3. Add AI review comments example

Copy link
Copy Markdown

@2pasha 2pasha left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm 🔥

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants