Skip to content

cancelBooking lacks transaction protection; User model has no unique indexes on email or user_id #244

@amaydixit11

Description

@amaydixit11

Issue Found

In backend/models/schema.js, there are no unique indexes defined on the RoomBooking collection for (room_id, date, startTime).

Why This matters

The bookRoom controller in backend/controllers/roomBookingController.js (line 407) does app-level clash detection inside a MongoDB transaction, which is good. However, the cancelBooking method (line 654) does NOT use a transaction — it's an unprotected findById + save operation.

Race condition in cancelBooking

exports.cancelBooking = async (req, res) => {
  const booking = await RoomBooking.findById(id);  // No session, no transaction
  // ...
  booking.status = "Cancelled";
  await booking.save();  // No unique index protects against concurrent modification
};

Two concurrent cancel requests could both read the booking before either updates it.

Missing unique constraint on users

The User model does not have unique indexes on user_id (ID number) or email. This means:

  • Duplicate users can be created with the same ID number
  • Duplicate users can be created with the same email
  • Onboarding could corrupt data if called twice

How to fix

1. Cancel booking should use a transaction:

exports.cancelBooking = async (req, res) => {
  const session = await mongoose.startSession();
  try {
    await session.withTransaction(async () => {
      const booking = await RoomBooking.findById(id).session(session);
      if (!booking) throw new Error("Booking not found");
      // ... validate ...
      booking.status = "Cancelled";
      await booking.save({ session });
    });
  } finally {
    session.endSession();
  }
};

2. Add unique indexes to schema:

userSchema.index({ user_id: 1 }, { unique: true, sparse: true });
userSchema.index({ email: 1 }, { unique: true });
roomBookingSchema.index({ room: 1, date: 1, startTime: 1 }, { unique: true });

Metadata

Metadata

Assignees

No one assigned

    Labels

    advancedComplex issues requiring experienced contributorsbugSomething isn't workingsecuritySecurity vulnerabilities

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions