-
-
Notifications
You must be signed in to change notification settings - Fork 101
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
Create Profile Page for users to see Reservations #437
Conversation
@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. |
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 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. WalkthroughThe changes in this pull request involve multiple updates across various files, primarily focusing on enhancing the contributor information in the Changes
Assessment against linked issues
Possibly related PRs
Suggested labels
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? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
@RamakrushnaBiswal many changes were made in the backend. Please increase the level of the PR |
There was a problem hiding this 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:
- Session timeout
- CSRF protection
- 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:
- Renaming the file to match the component:
Profile.tsx
- 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:
- 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
+ }
}),
});
- 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);
- 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:
- A token refresh mechanism before expiration
- A separate refresh token with longer expiration
- 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
📒 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 useauthenticateCustomer
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
- Reservations use
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:
- The project has
"type": "module"
in package.json - Vite configuration is properly set up for ESM
- 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
:
Standardize event registration buttons and pass event context.
The current implementation has multiple issues:
- No event context is passed to the registration handler
- Multiple registration buttons exist with different text ("Register for Event" vs "Book your slot")
- 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)
const sessionMiddleware = (req, res, next) => { | ||
if (req.session.user && req.session.user.id) { |
There was a problem hiding this comment.
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.
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)
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; | ||
|
There was a problem hiding this comment.
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
- Events routes use
Consider:
- Either removing the session middleware and standardizing on JWT authentication
- 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)
router.post("/create",authenticateCustomer, createEvent); | ||
router.get("/all",authenticateCustomer, getEvents); | ||
router.get("/delete",authenticateCustomer, deleteEvent); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
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 />} /> |
There was a problem hiding this comment.
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
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
origin: ["http://localhost:5173", "https://play-cafe.vercel.app"], | ||
credentials: true, | ||
optionsSuccessStatus: 200, | ||
}; |
There was a problem hiding this comment.
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.
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 | |
}; |
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" }); |
There was a problem hiding this comment.
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.
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" }); |
const token = req.header("Authorization")?.split(" ")[1]; | ||
|
||
if (!token) { | ||
return res.status(401).json({ message: "Authorization token is missing" }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
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" }); |
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.", | ||
}); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 |
There was a problem hiding this comment.
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
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.", | ||
}); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
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: [], | |
}); | |
} |
solve the conflicts @haseebzaki-07 |
@RamakrushnaBiswal done |
8b20043
into
RamakrushnaBiswal:main
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.
2024-10-30.11-47-15.mp4
Summary by CodeRabbit
Release Notes
New Features
Bug Fixes
Documentation
Chores