Description:
While working on the login functionality for my Express app, I encountered a 500 error response while running the following body in the Postman test:
{
"name": "test",
"password": "test123"
}
The structure of the request body, in this case, was absolutely correct. The error message in the console was:
Login Error Details: TypeError: Cannot set properties of undefined (setting 'user')
This error occurred in the login route when I tried to assign a user object to req.session.user
. The session object was either not initialized or not accessible when I attempted to store the user in the session.
Troubleshooting:
Upon inspecting the code, I noticed that the req.session
object was undefined before assigning req.session.user
. This issue indicated that the session middleware was not properly initialized or not functioning as expected.
I checked the order of middleware and route definitions. The session middleware needed to be initialized before any route handlers that accessed the session.
Solution:
Correct Session Middleware Order:
I ensured that the session middleware was initialized at the beginning of the middleware stack before handling any routes that required session access.
const express = require("express");
const path = require("path");
const dotenv = require("dotenv");
const session = require("express-session"); // Import express-session
const { UserCollection } = require("./mongo");
const bcrypt = require("bcrypt");
const MongoStore = require("connect-mongo");
const crypto = require("crypto"); // For generating random tokens
const nodemailer = require("nodemailer"); // For sending emails
dotenv.config();
const app = express();
const PORT = 5002;
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
// Set up express-session middleware
app.use(
session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: true,
store: MongoStore.create({
mongoUrl: process.env.DATABASE_URL,
collectionName: "sessions",
}),
})
);
// Connecting the api.js file
const apiRoutes = require('./api'); // Path to your api.js file
app.use('/api', apiRoutes); // Mount the API routes under /api
// Generate a reset token with expiration
const token = crypto.randomBytes(20).toString('hex');
const expiryDate = Date.now() + 3600000; // 1 hour from now
// Get the absolute path to your project's root directory. Adjust as necessary.
const projectRoot = path.join(__dirname, '..'); // Assuming 'src' is directly under the project root.
//If your folder is directly under the project root use:
//const projectRoot = __dirname;
const successfulRegistrationPath = path.join(projectRoot, 'tempelates', 'successfulRegistration.html');
const passwordResetEmailSent = path.join(projectRoot, 'tempelates', 'passwordResetEmailSent.html');
const passwordResetSuccessful = path.join(projectRoot, 'tempelates', 'passwordResetSuccessful.html');
// Wrap the await code inside an async function
(async function updateUserToken() {
const userEmail = '[email protected]'; // Make sure this value is dynamically provided
const token = crypto.randomBytes(20).toString('hex');
const expiryDate = Date.now() + 3600000; // 1 hour from now
// Store the token and expiry in the user record
await UserCollection.updateOne(
{ email: userEmail },
{
$set: { resetToken: token, resetTokenExpiry: expiryDate }
}
);
// Handle password reset after token validation
await UserCollection.updateOne(
{ resetToken: token, resetTokenExpiry: { $gt: Date.now() } },
{
$set: { password: "hashedPassword" }, // Example hashed password, make sure to hash it first
$unset: { resetToken: 1, resetTokenExpiry: 1 }
}
);
})();