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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions