Skip to content
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

Create Profile Page for users to see Reservations #437

Merged

Conversation

haseebzaki-07
Copy link
Contributor

@haseebzaki-07 haseebzaki-07 commented Oct 30, 2024

fixes #192

This PR created a profile page for the users to see their reservations.

Created the backend get API for the purpose and modified the create API to relate the user creating the reservation, modifies the session headers to be sent and receive from frontend and backend.
Modified user and reservations schema for relations and created a dashboard page for users to see only if they are logged in.

Screenshot 2024-10-30 114006
Screenshot 2024-10-30 114123

2024-10-30.11-47-15.mp4

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a new "Profile" component for displaying user reservations.
    • Added a "PROFILE" menu item in the Navbar linking to the dashboard.
    • Enhanced event registration to check for user authentication before allowing registration.
    • New route added for the dashboard, allowing navigation to the Profile component.
    • Added a new route for fetching user reservations.
  • Bug Fixes

    • Improved error handling and session validation in various components.
  • Documentation

    • Updated contributor information in the README for clarity and engagement.
  • Chores

    • Added new dependencies for improved functionality and security.

Copy link

vercel bot commented Oct 30, 2024

@haseebzaki-07 is attempting to deploy a commit to the bunty's projects Team on Vercel.

A member of the Team first needs to authorize it.

Copy link
Contributor

coderabbitai bot commented Oct 30, 2024

Warning

Rate limit exceeded

@RamakrushnaBiswal has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 24 minutes and 1 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between e6b2d03 and d73fb21.

Walkthrough

The changes in this pull request involve multiple updates across various files, primarily focusing on enhancing the contributor information in the README.md, adding new functionality related to user reservations in the backend, and improving user authentication and interface in the frontend. Key modifications include the introduction of new routes and controllers for managing reservations, updates to JWT handling, and the addition of a profile page component in the frontend.

Changes

File Change Summary
README.md Updated contributor list; added and removed contributors; refined troubleshooting steps.
backend/.env.example Added new environment variable SECRET_KEY.
backend/controller/customer.controller.js Modified loginCustomer function for JWT handling and session management; streamlined payload.
backend/controller/reservation.controller.js Added fetchUserReservations method; modified createReservation to check for customer existence.
backend/index.js Updated CORS configuration to allow credentials; corrected typo in error middleware import.
backend/middlewares/authCustomer.js Enhanced authenticateCustomer function with async handling and improved error responses.
backend/middlewares/sessionMiddleware.js Simplified session validation logic; updated error response format.
backend/models/customer.model.js Added reservations field to customerSchema.
backend/models/reservation.model.js Added customer field to reservationSchema.
backend/routes/eventRouter.js Added authenticateCustomer middleware to event routes.
backend/routes/reservationRouter.js Updated routes to include fetchUserReservations and modified createReservation route.
frontend/package.json Added jwt-decode dependency.
frontend/src/components/Pages/Dashboard.tsx Introduced Profile component for displaying user reservations.
frontend/src/components/Pages/Event.jsx Added authentication check for event registration.
frontend/src/components/Pages/Login.jsx Updated cookie management and error handling in handleSubmit.
frontend/src/components/Shared/Navbar.jsx Added "PROFILE" menu item linking to /dashboard.
frontend/src/router/index.jsx Added new route for the Profile component.

Assessment against linked issues

Objective Addressed Explanation
Create Profile Page for users to see Reservations (#192)

Possibly related PRs

Suggested labels

enhancement

🐰 "In the garden of code, where changes bloom,
Contributors gather, dispelling the gloom.
With profiles to view and reservations to see,
A hop towards progress, for you and for me!" 🐇


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@haseebzaki-07
Copy link
Contributor Author

@RamakrushnaBiswal many changes were made in the backend. Please increase the level of the PR

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 25

🧹 Outside diff range and nitpick comments (19)
backend/middlewares/sessionMiddleware.js (1)

1-10: Enhance session security measures.

While the basic session validation works, consider implementing additional security measures:

  1. Session timeout
  2. CSRF protection
  3. Session regeneration on authentication state changes

Consider adding these security enhancements:

const sessionMiddleware = (req, res, next) => {
  // Add session timeout check
  const SESSION_TIMEOUT = 30 * 60 * 1000; // 30 minutes
  if (req.session.lastAccess && (Date.now() - req.session.lastAccess) > SESSION_TIMEOUT) {
    req.session.destroy();
    return res.status(401).json({
      success: false,
      message: "Session expired. Please log in again.",
    });
  }
  
  // Update last access time
  req.session.lastAccess = Date.now();

  if (req?.session?.user?.id) {
    next();
  } else {
    res.status(401).json({
      success: false,
      message: "Invalid session. Please log in again.",
    });
  }
};
🧰 Tools
🪛 Biome

[error] 2-2: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

backend/models/reservation.model.js (3)

Line range hint 4-16: Consider improving date and time field types for better data integrity.

The current schema uses String types for date and time fields. Consider using more appropriate types for better validation and querying capabilities.

 const reservationSchema = new Schema({
   guests: {
     type: String,
     required: true,
   },
   date: {
-    type: String,
+    type: Date,
     required: true,
   },
   time: {
     type: String,
+    validate: {
+      validator: function(v) {
+        return /^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$/.test(v);
+      },
+      message: props => `${props.value} is not a valid time format! Use HH:MM format.`
+    },
     required: true,
   },

Line range hint 4-24: Consider adding an index for better query performance.

Since the profile page will query reservations by customer, adding an index on the customer field would improve query performance.

Add this after the schema definition:

reservationSchema.index({ customer: 1 });

Also consider adding a compound index if you'll frequently query by date:

reservationSchema.index({ customer: 1, date: 1 });

Line range hint 4-8: Add validation for the guests field.

Consider adding validation to ensure the guests field contains valid data.

   guests: {
     type: String,
     required: true,
+    validate: {
+      validator: function(v) {
+        return /^[1-9][0-9]?$/.test(v);
+      },
+      message: props => `${props.value} is not a valid number of guests!`
+    },
   },
backend/routes/reservationRouter.js (2)

Line range hint 10-17: Update API documentation to reflect new endpoints.

The welcome message's endpoints section is outdated and doesn't include the new /get/:id route. Additionally, the /create endpoint documentation doesn't reflect the new URL structure with the id parameter.

Apply this diff to update the documentation:

     endpoints: {
-      createReservation: "/create [POST]",
+      createReservation: "/create/:id [POST]",
+      getUserReservations: "/get/:id [GET]"
     },

Line range hint 1-19: Consider implementing rate limiting for reservation endpoints.

Since these endpoints handle user-specific data and could be targets for abuse, consider implementing rate limiting to protect against potential DoS attacks or brute force attempts.

Example implementation using express-rate-limit:

const rateLimit = require('express-rate-limit');

const reservationLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100 // limit each IP to 100 requests per windowMs
});

router.use(reservationLimiter);
backend/routes/eventRouter.js (2)

32-32: Add authorization check for delete operations.

The delete endpoint should verify that the user has appropriate permissions to delete events, not just that they're authenticated.

Consider adding a middleware to check if the user has admin privileges or owns the event:

const checkEventPermissions = async (req, res, next) => {
  // Verify user has rights to delete the event
  // Either they created it or have admin privileges
  next();
};

router.delete("/", authenticateCustomer, checkEventPermissions, deleteEvent);

30-32: Fix formatting inconsistencies.

Add proper spacing after commas in middleware chains for better readability.

Apply these changes:

-router.post("/create",authenticateCustomer, createEvent);
-router.get("/all",authenticateCustomer, getEvents);
-router.get("/delete",authenticateCustomer, deleteEvent);
+router.post("/create", authenticateCustomer, createEvent);
+router.get("/all", authenticateCustomer, getEvents);
+router.delete("/", authenticateCustomer, deleteEvent);
backend/models/customer.model.js (1)

55-55: Remove redundant comment.

The ref: "Reservation" already indicates the relationship to the Reservation schema, making the comment redundant.

-        ref: "Reservation", // Link to Reservation schema
+        ref: "Reservation"
frontend/src/router/index.jsx (1)

25-25: Consider renaming the import to match the component name.

The import statement suggests a mismatch between the file name (Dashboard) and the exported component name (Profile). This could lead to confusion during maintenance.

Consider either:

  1. Renaming the file to match the component: Profile.tsx
  2. Or renaming the import to match the file:
-import Profile from '../components/Pages/Dashboard';
+import Dashboard from '../components/Pages/Dashboard';
backend/index.js (1)

Line range hint 46-54: Enhance security configurations for user sessions and database.

Given that this handles user profiles and reservations, consider implementing these security improvements:

  1. Session configuration:
 session({
   secret: process.env.SECRET_KEY,
   resave: false,
   saveUninitialized: false,
   cookie: {
     maxAge: 1000 * 60 * 60 * 24,
-    secure: false,
+    secure: process.env.NODE_ENV === 'production',
+    httpOnly: true,
+    sameSite: 'strict'
   },
   store: MongoStore.create({
     mongoUrl: process.env.MONGO_URI,
+    touchAfter: 24 * 3600,
+    crypto: {
+      secret: process.env.MONGO_STORE_SECRET
+    }
   }),
 });
  1. Add rate limiting middleware to protect the API endpoints:
const rateLimit = require('express-rate-limit');

const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100 // limit each IP to 100 requests per windowMs
});

app.use('/api', limiter);
  1. Enhance MongoDB connection with retry options:
 mongoose.connect(process.env.MONGO_URI, {
   useNewUrlParser: true,
   useUnifiedTopology: true,
+  serverSelectionTimeoutMS: 5000,
+  socketTimeoutMS: 45000,
+  retryWrites: true
 })
frontend/src/components/Pages/Dashboard.tsx (3)

1-5: Consider adding TypeScript types for better type safety.

While the imports are correct, adding TypeScript interfaces would improve type safety:

interface Reservation {
  guests: number;
  date: string;
  time: string;
  email: string;
}

interface DecodedToken {
  sub: string;
  // add other token fields as needed
}

29-29: Remove debug console.log statement.

Production code should not contain debug console.log statements.

-console.log("Decoded userId:", userId); // Debugging line

68-95: Enhance accessibility features.

While the basic accessibility is good, consider adding more ARIA attributes and roles.

-<div className="min-h-screen bg-gray-100 dark:bg-black p-4 mt-10 ">
+<main className="min-h-screen bg-gray-100 dark:bg-black p-4 mt-10" role="main">
   <div className="container mx-auto">
-    <h1 className="text-4xl font-bold mb-6 text-center">Your Reservations</h1>
+    <h1 className="text-4xl font-bold mb-6 text-center" tabIndex={0}>Your Reservations</h1>

     {loading ? (
-      <p className="text-gray-500 text-center">Loading your reservations...</p>
+      <p className="text-gray-500 text-center" role="status" aria-busy="true">
+        Loading your reservations...
+      </p>
     ) : (
-      <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
+      <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4" role="list">
frontend/src/components/Pages/Login.jsx (1)

Security measures are in place, but some improvements recommended

The login endpoint has several security measures implemented:

  • CORS is properly configured with specific origins and credentials
  • Session management with express-session and secure MongoDB store
  • JWT-based authentication with proper algorithms specified
  • Passport.js integration for authentication flows

However, there are a few security enhancements that could be made:

  • Cookie security options are not fully hardened (secure: false)
  • No explicit CSRF protection middleware is present
  • Missing HTTP security headers (helmet middleware)
🔗 Analysis chain

Line range hint 27-33: Verify CSRF protection for login endpoint.

The login endpoint should be protected against CSRF attacks. While the sameSite cookie setting helps, additional verification is recommended.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if CSRF protection is implemented in the backend
rg -l "csrf|xsrf" --type js --type ts

# Check for secure headers in backend routes
rg -l "helmet|content-security-policy|x-frame-options" --type js --type ts

Length of output: 116


Script:

#!/bin/bash
# Let's check the backend code more thoroughly for security middleware and CSRF protection
# First, let's find the main backend server/app setup files
fd -e js -e ts 'server|app|index' backend/

# Then check for security-related imports and middleware in package.json
fd package.json -x cat {}

# Also check for any security configuration files
fd -e js -e ts 'security|config' backend/

Length of output: 2899


Script:

#!/bin/bash
# Let's examine the main server setup and security configurations
cat backend/index.js

# Check the content of security-related config files
cat backend/config/passport.config.js

# Let's also check if express-session is configured with secure options
rg -A 5 "express-session|session\(" backend/

Length of output: 4568

backend/controller/customer.controller.js (1)

119-127: Implement token refresh mechanism

The current implementation might lead to a poor user experience when the token expires.

Consider implementing:

  1. A token refresh mechanism before expiration
  2. A separate refresh token with longer expiration
  3. Frontend interceptors to handle token refresh

Would you like me to provide a detailed implementation guide for these improvements?

frontend/src/components/Pages/Event.jsx (1)

Line range hint 1-324: Consider breaking down the Event component for better maintainability.

The component currently handles multiple responsibilities (calendar, event listing, image carousel, authentication, registration). Consider splitting it into smaller, focused components:

  • EventCalendar
  • EventGallery
  • EventList
  • EventRegistration

This would improve maintainability, reusability, and testing.

README.md (1)

Line range hint 283-504: Fix formatting inconsistencies in the contributors table.

The contributors table contains hard tabs which should be replaced with spaces for consistent formatting across the file.

Replace all hard tabs with spaces in the contributors table. You can use your editor's "Convert Indentation to Spaces" feature.

🧰 Tools
🪛 Markdownlint

459-459: Column: 1
Hard tabs

(MD010, no-hard-tabs)


460-460: Column: 1
Hard tabs

(MD010, no-hard-tabs)

backend/middlewares/authCustomer.js (1)

28-28: Avoid logging personally identifiable information (PII)

Logging user.name can expose personally identifiable information. To enhance security and comply with privacy best practices, consider logging non-sensitive identifiers like user._id.

Apply this diff to modify the log statement:

-    logger.info(`Customer authenticated: ${user.name}`);
+    logger.info(`Customer authenticated: ${user._id}`);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 7aa1cc1 and e6b2d03.

📒 Files selected for processing (17)
  • README.md (7 hunks)
  • backend/.env.example (1 hunks)
  • backend/controller/customer.controller.js (2 hunks)
  • backend/controller/reservation.controller.js (4 hunks)
  • backend/index.js (1 hunks)
  • backend/middlewares/authCustomer.js (1 hunks)
  • backend/middlewares/sessionMiddleware.js (1 hunks)
  • backend/models/customer.model.js (2 hunks)
  • backend/models/reservation.model.js (1 hunks)
  • backend/routes/eventRouter.js (2 hunks)
  • backend/routes/reservationRouter.js (1 hunks)
  • frontend/package.json (1 hunks)
  • frontend/src/components/Pages/Dashboard.tsx (1 hunks)
  • frontend/src/components/Pages/Event.jsx (3 hunks)
  • frontend/src/components/Pages/Login.jsx (3 hunks)
  • frontend/src/components/Shared/Navbar.jsx (1 hunks)
  • frontend/src/router/index.jsx (2 hunks)
✅ Files skipped from review due to trivial changes (1)
  • backend/.env.example
🧰 Additional context used
🪛 Markdownlint
README.md

283-283: Column: 1
Hard tabs

(MD010, no-hard-tabs)


284-284: Column: 1
Hard tabs

(MD010, no-hard-tabs)


327-327: Column: 1
Hard tabs

(MD010, no-hard-tabs)


328-328: Column: 1
Hard tabs

(MD010, no-hard-tabs)


371-371: Column: 1
Hard tabs

(MD010, no-hard-tabs)


372-372: Column: 1
Hard tabs

(MD010, no-hard-tabs)


459-459: Column: 1
Hard tabs

(MD010, no-hard-tabs)


460-460: Column: 1
Hard tabs

(MD010, no-hard-tabs)


503-503: Column: 1
Hard tabs

(MD010, no-hard-tabs)


504-504: Column: 1
Hard tabs

(MD010, no-hard-tabs)

🪛 Biome
backend/middlewares/sessionMiddleware.js

[error] 2-2: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🔇 Additional comments (15)
backend/middlewares/sessionMiddleware.js (1)

11-13: LGTM! Clean module export.

The module export is clean and follows Node.js best practices.

backend/models/reservation.model.js (1)

17-21: LGTM! Customer reference is properly implemented.

The customer field correctly establishes the relationship between reservations and customers, which is essential for the profile page functionality.

backend/routes/reservationRouter.js (2)

2-2: LGTM: Import statements are properly structured.

The new imports for fetchUserReservations and authenticateCustomer align well with the PR objectives of implementing authenticated reservation management.

Also applies to: 4-4


7-8: Verify error handling for invalid user IDs.

The routes are properly secured with authentication middleware. However, we should ensure proper error handling for cases where the :id parameter doesn't match the authenticated user's ID to prevent unauthorized access to other users' reservations.

Let's verify the implementation of error handling in the controller:

backend/routes/eventRouter.js (2)

8-8: LGTM! Clean middleware import.

The authentication middleware import is properly placed with other dependencies.


30-32: Verify consistent authentication implementation across related endpoints.

Let's ensure all event-related endpoints have consistent authentication checks and error handling.

✅ Verification successful

Authentication middleware implementation is consistent across event-related endpoints

The verification shows that:

  • All event-related endpoints (/create, /all, /delete) consistently use authenticateCustomer middleware
  • Similar authentication patterns are used across other related routes:
    • Reservations use authenticateCustomer
    • Orders use sessionMiddleware
    • Public routes (login, register, etc.) appropriately have no authentication

The implementation follows a consistent pattern where protected resources use appropriate middleware.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check authentication implementation across routes and related files

# Check for other event-related routes that might need authentication
echo "Checking for other event-related routes..."
rg -l "router\.(get|post|put|delete)" backend/routes/

# Check frontend handling of authentication errors
echo "Checking frontend authentication error handling..."
rg -l "catch.*401" frontend/src/

Length of output: 577


Script:

#!/bin/bash
# Let's check the authentication middleware usage in all route files
echo "Checking authentication middleware usage across routes..."
rg -B1 -A1 "router\.(get|post|put|delete)" backend/routes/ --no-filename

# Check for authentication error handling in frontend API calls
echo "Checking frontend API calls and error handling..."
rg "axios.*event.*catch" frontend/src/ -A 3

Length of output: 1648

backend/models/customer.model.js (1)

52-57: LGTM! Verify bidirectional relationship with Reservation model.

The addition of the reservations field follows Mongoose best practices for establishing relationships between models.

Let's verify the bidirectional relationship exists in the Reservation model:

✅ Verification successful

✓ Bidirectional relationship verified between Customer and Reservation models

The Reservation model correctly implements the bidirectional relationship with a required customer field that references the Customer model, ensuring data consistency for the profile page implementation.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that Reservation model exists and has a corresponding customer reference
# Expected: Find a customer field in the Reservation schema that references the Customer model

# Search for Reservation schema definition
ast-grep --pattern 'const reservationSchema = new Schema({
  $$$
  customer: {
    type: Schema.Types.ObjectId,
    ref: "Customer"
  }
  $$$
})'

Length of output: 147


Script:

#!/bin/bash
# Let's first find the Reservation model file
fd -t f "reservation.model" 

# Then let's examine its content to check for customer reference
# Using rg to be more flexible in matching the schema pattern
rg -U "new Schema\({.*?}\)" -A 10 "reservation"

Length of output: 226


Script:

#!/bin/bash
# Found the reservation model file, let's examine its content
cat backend/models/reservation.model.js

Length of output: 543

frontend/package.json (2)

27-27: LGTM! Using the latest stable version.

The addition of [email protected] aligns well with the PR's objective of implementing user authentication for the profile page. This version is the latest stable release and includes important ESM improvements.


27-27: Verify ESM compatibility with the current setup.

Since [email protected] is ESM-only, let's verify compatibility with the current build setup.

✅ Verification successful

The verification results show that:

  1. The project has "type": "module" in package.json
  2. Vite configuration is properly set up for ESM
  3. No conflicting type declarations in dependencies

ESM compatibility is properly configured

The project is correctly set up for ESM modules with "type": "module" in package.json and a standard Vite configuration that supports ESM by default. The upgrade to [email protected] should work seamlessly with this setup.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if the project is properly configured for ESM
# Test 1: Verify type:module in package.json
echo "Checking type:module configuration..."
grep '"type": "module"' frontend/package.json

# Test 2: Check if other dependencies are ESM compatible
echo "Checking other major dependencies for ESM compatibility..."
grep '"type":' frontend/node_modules/*/package.json 2>/dev/null || true

# Test 3: Verify Vite configuration
echo "Checking Vite configuration..."
find frontend -name "vite.config.*" -exec cat {} \;

Length of output: 787

backend/index.js (1)

Line range hint 7-7: Fix typo in error middleware import path.

The import path contains a typo with an extra 'r' in "errrorMiddleware".

-const errorMiddleware = require("./middlewares/errrorMiddleware");
+const errorMiddleware = require("./middlewares/errorMiddleware");

Let's verify the correct middleware file exists:

frontend/src/components/Pages/Login.jsx (1)

11-11: LGTM! Clean state initialization.

The simplified state initialization is clear and follows React best practices.

frontend/src/components/Shared/Navbar.jsx (1)

25-25: Implementation style follows existing patterns.

The new menu item follows the established pattern for menu items in the navigation bar, maintaining consistency in the codebase.

Let's verify the dashboard route protection:

frontend/src/components/Pages/Event.jsx (2)

17-18: LGTM: Import statements are appropriate.

The new imports support the authentication feature implementation.


198-198: ⚠️ Potential issue

Standardize event registration buttons and pass event context.

The current implementation has multiple issues:

  1. No event context is passed to the registration handler
  2. Multiple registration buttons exist with different text ("Register for Event" vs "Book your slot")
  3. Inconsistent button styling

Consider consolidating the registration buttons and passing event context:

-<button onClick={handleRegisterClick} className="bg-[#FEF3C7] dark:bg-black text-gray-700 dark:text-white px-4 py-2 rounded-md mt-4">
+<button 
+  onClick={() => handleEventRegistrationClick(event)} 
+  className="btn-primary px-4 py-2 rounded-md mt-4"
+>
   Register for Event
 </button>

Let's verify the usage of registration buttons across the codebase:

README.md (1)

Line range hint 283-504: LGTM! Contributor information updates are well-structured.

The changes to the contributors section are well-organized and maintain consistency:

  • Added new contributors with proper formatting
  • Updated existing contributor information
  • Maintained table structure and alignment
🧰 Tools
🪛 Markdownlint

459-459: Column: 1
Hard tabs

(MD010, no-hard-tabs)


460-460: Column: 1
Hard tabs

(MD010, no-hard-tabs)

Comment on lines +1 to +2
const sessionMiddleware = (req, res, next) => {
if (req.session.user && req.session.user.id) {
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Use optional chaining for safer property access.

The current session check could be made more robust using optional chaining.

- if (req.session.user && req.session.user.id) {
+ if (req?.session?.user?.id) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const sessionMiddleware = (req, res, next) => {
if (req.session.user && req.session.user.id) {
const sessionMiddleware = (req, res, next) => {
if (req?.session?.user?.id) {
🧰 Tools
🪛 Biome

[error] 2-2: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

Comment on lines 6 to 13
const sessionMiddleware = (req, res, next) => {
if (req.session.user && req.session.user.id) {
next(); // Continue if session is valid and has user ID
} else {
res.status(401).send("Invalid session. Please log in again.");
res.status(401).json({
success: false,
message: "Invalid session. Please log in again.",
});
}
}

module.exports = sessionMiddleware; No newline at end of file
};

module.exports = sessionMiddleware;

Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Session middleware implementation needs revision

The codebase uses JWT-based authentication (authCustomer.js and authAdmin.js) as the primary authentication mechanism, but the session middleware is only partially integrated. This creates an inconsistent authentication approach:

  • The session middleware is used in:
    • /orders/create/:id, /orders/get/:id, /orders/delete/:id
    • /feedback/create
  • However, similar protected routes use JWT authentication:
    • Events routes use authenticateCustomer
    • Reservation routes use authenticateCustomer
    • Admin routes use authenticateAdmin

Consider:

  1. Either removing the session middleware and standardizing on JWT authentication
  2. Or properly integrating session management with the JWT authentication flow
🔗 Analysis chain

Verify middleware integration across routes.

Let's ensure this middleware is properly integrated with all protected routes.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for routes that should be protected
rg -l "router\.(post|put|delete)" --type js

# Search for middleware usage
rg "sessionMiddleware" --type js

Length of output: 1176


Script:

#!/bin/bash
# Let's check the actual routes in these files to understand which endpoints need protection
rg "router\.(post|put|delete)" -A 1 backend/routes/eventRouter.js
rg "router\.(post|put|delete)" -A 1 backend/routes/customerRouter.js
rg "router\.(post|put|delete)" -A 1 backend/routes/newsletterRoute.js
rg "router\.(post|put|delete)" -A 1 backend/routes/adminRouter.js

# Also check if there are any other authentication middlewares in use
rg -l "auth" --type js backend/middlewares/

Length of output: 836


Script:

#!/bin/bash
# Let's check the implementation of other auth middlewares
cat backend/middlewares/authCustomer.js
cat backend/middlewares/authAdmin.js

# Let's also check the remaining routes that use sessionMiddleware
rg "router\.(get|post|put|delete)" -A 1 backend/routes/reservationRouter.js

Length of output: 2168

🧰 Tools
🪛 Biome

[error] 2-2: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

Comment on lines +30 to +32
router.post("/create",authenticateCustomer, createEvent);
router.get("/all",authenticateCustomer, getEvents);
router.get("/delete",authenticateCustomer, deleteEvent);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Use DELETE HTTP method for delete operations.

The delete operation is currently using a GET method which violates REST principles. GET requests should be idempotent and not modify server state.

Apply this change:

-router.get("/delete",authenticateCustomer, deleteEvent);
+router.delete("/",authenticateCustomer, deleteEvent);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
router.post("/create",authenticateCustomer, createEvent);
router.get("/all",authenticateCustomer, getEvents);
router.get("/delete",authenticateCustomer, deleteEvent);
router.post("/create",authenticateCustomer, createEvent);
router.get("/all",authenticateCustomer, getEvents);
router.delete("/",authenticateCustomer, deleteEvent);

@@ -41,6 +42,7 @@ const router = createBrowserRouter(
<Route path="/email-verify" element={<EmailVerify />} />
<Route path="/otp-verify" element={<OtpRegisterVerify />} />
<Route path="/membership" element={<Membership />} />
<Route path="/dashboard" element={<Profile />} />
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider grouping protected routes together.

For better organization and maintenance, consider grouping all authenticated routes together in the router configuration.

You could structure the routes like this:

<Route path="/" element={<App />}>
  {/* Public routes */}
  <Route index element={<Home />} />
  <Route path="/login" element={<Login />} />
  <Route path="/signup" element={<Signup />} />
  
  {/* Protected routes */}
  <Route element={<ProtectedRoute />}>
    <Route path="/dashboard" element={<Profile />} />
    {/* Add other protected routes here */}
  </Route>
  
  {/* Other routes */}
  <Route path="*" element={<NotFound />} />
</Route>

💡 Codebase verification

⚠️ Potential issue

Route protection already exists but needs consolidation

The codebase already implements authentication checks, but they're scattered across components. In the Dashboard component (frontend/src/components/Pages/Dashboard.tsx), there's already authentication verification:

const authToken = Cookies.get('authToken');
if (!authToken) {
  alert("Please sign in to view your reservations.");
  navigate('/login');
  return;
}

However, this pattern should be consolidated into a reusable protected route component to:

  • Avoid code duplication
  • Ensure consistent authentication behavior
  • Remove authentication logic from individual components

Suggested implementation remains valid, but should be extracted from the existing authentication logic.

🔗 Analysis chain

Add route protection for authenticated users.

According to the PR objectives, the dashboard should only be accessible to logged-in users. Currently, there's no authentication guard protecting this route.

Consider implementing a protected route wrapper. Here's a suggested approach:

// Create a ProtectedRoute component
const ProtectedRoute = ({ children }) => {
  const isAuthenticated = // your auth check logic
  return isAuthenticated ? children : <Navigate to="/login" />;
};

// Use it in the route definition
<Route 
  path="/dashboard" 
  element={
    <ProtectedRoute>
      <Profile />
    </ProtectedRoute>
  } 
/>

Let's check if there's an existing auth guard implementation:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Look for existing auth guard patterns
rg -l "ProtectedRoute|AuthGuard|RequireAuth" frontend/src/

Length of output: 60


Script:

#!/bin/bash
# Let's check for any authentication-related components or hooks
rg -i "auth|isAuthenticated|protected|private" frontend/src/ -A 5

# Also check for any route protection or redirection logic
ast-grep --pattern 'Navigate to="/login"'

# Look for any context providers related to auth
ast-grep --pattern 'AuthContext|UserContext'

# Check for any authentication state management
rg "useAuth|getAuth|isAuth" frontend/src/

Length of output: 5596

Comment on lines 16 to 19
origin: ["http://localhost:5173", "https://play-cafe.vercel.app"],
credentials: true,
optionsSuccessStatus: 200,
};
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Enhance CORS security configuration.

While adding credentials: true is necessary for authenticated requests, consider strengthening the CORS configuration:

 const corsOptions = {
   origin: ["http://localhost:5173", "https://play-cafe.vercel.app"],
   credentials: true,  
-  optionsSuccessStatus: 200,
+  optionsSuccessStatus: 200,
+  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
+  allowedHeaders: ['Content-Type', 'Authorization'],
+  exposedHeaders: ['Content-Range', 'X-Content-Range'],
+  maxAge: 600
 };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
origin: ["http://localhost:5173", "https://play-cafe.vercel.app"],
credentials: true,
optionsSuccessStatus: 200,
};
origin: ["http://localhost:5173", "https://play-cafe.vercel.app"],
credentials: true,
optionsSuccessStatus: 200,
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization'],
exposedHeaders: ['Content-Range', 'X-Content-Range'],
maxAge: 600
};

Comment on lines +31 to +35
if (err.name === "TokenExpiredError") {
return res.status(401).json({ message: "Token expired" });
}
logger.error("Token verification failed:", err);
return res.status(403).json({ message: "Invalid token" });
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Use consistent HTTP status codes for authentication errors

When token verification fails due to an invalid token, the response returns a 403 Forbidden status code. According to HTTP standards, 401 Unauthorized is more appropriate for authentication failures, signaling that authentication is required or has failed.

Apply this diff to update the status code:

     if (err.name === "TokenExpiredError") {
       return res.status(401).json({ message: "Token expired" });
     }
     logger.error(`Token verification failed: ${err.message}`);
-    return res.status(403).json({ message: "Invalid token" });
+    return res.status(401).json({ message: "Invalid token" });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (err.name === "TokenExpiredError") {
return res.status(401).json({ message: "Token expired" });
}
logger.error("Token verification failed:", err);
return res.status(403).json({ message: "Invalid token" });
if (err.name === "TokenExpiredError") {
return res.status(401).json({ message: "Token expired" });
}
logger.error("Token verification failed:", err);
return res.status(401).json({ message: "Invalid token" });

Comment on lines +8 to +11
const token = req.header("Authorization")?.split(" ")[1];

if (!token) {
return res.status(401).json({ message: "Authorization token is missing" });
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Handle cases where the Authorization header might be malformed

The current implementation assumes the Authorization header is well-formed and contains a space. If the header is missing or doesn't contain a space, split(" ")[1] could be undefined, leading to errors down the line.

Apply this diff to improve robustness:

-  const token = req.header("Authorization")?.split(" ")[1]; 
+  const authHeader = req.header("Authorization");
+  if (!authHeader || !authHeader.startsWith("Bearer ")) {
+    return res.status(401).json({ message: "Authorization token is missing or malformed" });
+  }
+  const token = authHeader.split(" ")[1];
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const token = req.header("Authorization")?.split(" ")[1];
if (!token) {
return res.status(401).json({ message: "Authorization token is missing" });
const authHeader = req.header("Authorization");
if (!authHeader || !authHeader.startsWith("Bearer ")) {
return res.status(401).json({ message: "Authorization token is missing or malformed" });
}
const token = authHeader.split(" ")[1];
if (!token) {
return res.status(401).json({ message: "Authorization token is missing" });

Comment on lines +34 to +45
const userId = req.params.id

// Create the reservation in the database
const reservation = await Reservation.create(validationResult.data);
const { email, date, guests, time } = validationResult.data;

// Find the customer by userId if provided
const customer = await Customer.findById(userId);
if (!customer) {
return res.status(404).json({
success: false,
message: "Customer not found.",
});
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Ensure authorization by validating the authenticated user

Currently, the createReservation and fetchUserReservations functions retrieve userId from req.params.id without verifying if it matches the authenticated user's ID. This could allow users to access or manipulate other users' data. To enhance security, validate that the userId matches the authenticated user's ID.

Apply this diff to enforce authorization checks:

// In createReservation function
 async function createReservation(req, res) {
     const validationResult = reservationSchema.safeParse(req.body);
     if (!validationResult.success) {
         // Error handling
     }
     const userId = req.params.id;
+    if (req.user.id !== userId) {
+        return res.status(403).json({
+            success: false,
+            message: "Unauthorized access.",
+        });
+    }
     // Continue with reservation creation
 }

// In fetchUserReservations function
 async function fetchUserReservations(req, res) {
     const userId = req.params.id;
+    if (req.user.id !== userId) {
+        return res.status(403).json({
+            success: false,
+            message: "Unauthorized access.",
+        });
+    }
     // Continue with fetching reservations
 }

Also applies to: 91-99

@@ -28,13 +31,29 @@ async function createReservation(req, res) {
errors: validationResult.error.errors,
});
}
const userId = req.params.id
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Refactor to extract userId from the authenticated user context

To prevent clients from manipulating the userId in the request parameters, consider extracting userId directly from the authenticated user object (req.user.id) set by your authentication middleware. This ensures that operations are performed on data belonging to the authenticated user.

Apply this diff to refactor the code:

 // In your routes file, remove ':id' from the route parameters
- router.post('/create/:id', authenticateCustomer, createReservation);
+ router.post('/create', authenticateCustomer, createReservation);

- router.get('/get/:id', authenticateCustomer, fetchUserReservations);
+ router.get('/get', authenticateCustomer, fetchUserReservations);

 // In createReservation function
 async function createReservation(req, res) {
     const validationResult = reservationSchema.safeParse(req.body);
     if (!validationResult.success) {
         // Error handling
     }
-    const userId = req.params.id;
+    const userId = req.user.id;
     // Continue with reservation creation
 }

 // In fetchUserReservations function
 async function fetchUserReservations(req, res) {
-    const userId = req.params.id;
+    const userId = req.user.id;
     // Continue with fetching reservations
 }

Also applies to: 93-93

Comment on lines +105 to +111
if (reservations.length === 0) {
logger.info(`No reservations found for user ID: ${userId}`);
return res.status(404).json({
success: false,
message: "No reservations found for this user.",
});
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Return 200 with empty data when no reservations are found

When a user has no reservations, returning a 200 status with an empty array is more appropriate than a 404 error. This allows the client to handle the response consistently, without treating the absence of reservations as an error condition.

Apply this diff to adjust the response:

 if (reservations.length === 0) {
     logger.info(`No reservations found for user ID: ${userId}`);
-    return res.status(404).json({
-        success: false,
-        message: "No reservations found for this user.",
-    });
+    return res.status(200).json({
+        success: true,
+        message: "No reservations found.",
+        data: [],
+    });
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (reservations.length === 0) {
logger.info(`No reservations found for user ID: ${userId}`);
return res.status(404).json({
success: false,
message: "No reservations found for this user.",
});
}
if (reservations.length === 0) {
logger.info(`No reservations found for user ID: ${userId}`);
return res.status(200).json({
success: true,
message: "No reservations found.",
data: [],
});
}

@RamakrushnaBiswal
Copy link
Owner

solve the conflicts @haseebzaki-07

@haseebzaki-07
Copy link
Contributor Author

@RamakrushnaBiswal done

@RamakrushnaBiswal RamakrushnaBiswal merged commit 8b20043 into RamakrushnaBiswal:main Nov 1, 2024
2 of 3 checks passed
@RamakrushnaBiswal RamakrushnaBiswal self-requested a review November 1, 2024 07:02
@RamakrushnaBiswal RamakrushnaBiswal added level3 for 45 points gssoc-ext gssoc-extd program hacktoberfest accepted hacktoberfest-accepted repo labels Nov 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
gssoc-ext gssoc-extd program hacktoberfest accepted hacktoberfest-accepted repo level3 for 45 points
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Create Profile Page for users to see Reservations
2 participants