This website helps people quickly find, compare, and book rental cars online.
Customers can browse available cars, choose rental dates, complete checkout, and track booking status, while admins manage requests, inventory, and booking approvals.
A full-stack car rental platform built with Node.js, Express, MongoDB, and EJS. It includes customer flows (browse/search/book), admin workflows (requests/bookings management), authentication (email/password + Google OAuth), localization, and checkout status tracking.
- Features
- Tech Stack
- Project Structure
- Architecture Overview
- Getting Started
- Environment Variables
- Run the App
- Main Routes
- API Endpoints
- Data Models
- Authentication Flows
- Internationalization
- Static Assets & Views
- Security Notes
- Known Gaps / Next Improvements
- Contributing
- License
- User registration and login with session-based auth
- Google OAuth login via Passport
- Forgot password flow with email verification code
- Car catalog with category/search filters
- Date-based availability search
- Car details page with rental session context
- Booking checkout flow with status lifecycle (
pending,confirmed,cancelled,completed) - Admin panel for requests and bookings
- Booking status lookup endpoint
- Cookie consent endpoints
- English/French localization via
i18n
- Backend: Node.js, Express 5
- Database: MongoDB + Mongoose
- Views: EJS templates
- Auth: express-session, Passport (Google OAuth 2.0), bcrypt
- Email: Nodemailer (Gmail)
- Uploads: Multer
- Localization: i18n
- Utilities/Middleware: body-parser, morgan, cookie-parser, cors
Car_Rental/
|- app.js
|- package.json
|- config/
| \- passport.js
|- controllers/
| |- User.js
| |- Car.js
| \- admin.js
|- models/
| |- user.js
| |- car.js
| |- booking.js
| |- bookings.js
| |- rentRequest.js
| \- notification.js
|- routers/
| |- users.js
| |- cars.js
| |- bookingroute.js
| \- admins.js
|- views/
| |- Admin/
| \- partials/
|- public/
| |- css/
| |- JavaScript/
| \- images/
|- locales/
| |- en.json
| \- fr.json
\- Utils/
\- sendEmail.js
flowchart TD
A[Browser / Client] --> B[Express App app.js]
B --> C[Routers]
C --> D[Controllers]
D --> E[Mongoose Models]
E --> F[(MongoDB)]
B --> G[EJS Views]
B --> H[Public Assets]
B --> I[Passport Google OAuth]
B --> J[Nodemailer]
- Node.js 18+
- npm 9+
- MongoDB database (local or Atlas)
- Google OAuth credentials (for Google login)
- Gmail app password (for reset emails)
npm installCreate a .env file in project root.
Use this template:
API_URL=/api/v1
CONNECTION_STRING=mongodb+srv://<username>:<password>@<cluster>/<db_name>
EMAIL_USER=[email protected]
EMAIL_PASS=your_gmail_app_password
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
GOOGLE_CALLBACK_URL=http://localhost:3000/auth/google/callback| Variable | Required | Description |
|---|---|---|
API_URL |
Yes | API prefix mounted for cars/users/admin routes |
CONNECTION_STRING |
Yes | MongoDB connection URI |
EMAIL_USER |
Yes (for reset flow) | Sender Gmail address for password reset |
EMAIL_PASS |
Yes (for reset flow) | Gmail app password |
GOOGLE_CLIENT_ID |
Yes (for Google auth) | OAuth client ID |
GOOGLE_CLIENT_SECRET |
Yes (for Google auth) | OAuth client secret |
GOOGLE_CALLBACK_URL |
Yes (for Google auth) | OAuth callback URL |
npm run devOr production:
npm startDefault server URL: http://localhost:3000
| Route | Method | Description |
|---|---|---|
/ |
GET | Home page |
/explore |
GET | Car listing page |
/cars/:id |
GET | Car details fallback route |
/checkout |
GET | Checkout page |
/pending |
GET/POST | Pending page + booking creation |
/success |
GET | Booking success page |
/admin |
GET | Admin requests page |
/login |
GET | Login page |
/signup |
GET | Signup page |
/forgotpassword |
GET | Forgot password page |
/verify |
GET | Reset code verification page |
/resetpass |
GET | Password reset page |
/auth/google |
GET | Google auth entry |
/auth/google/callback |
GET | Google auth callback |
/lang/:locale |
GET | Language switch (en/fr) |
With API_URL=/api/v1:
/api/v1/cars-> cars router/api/v1/users-> users router/api/v1/admin-> admin router/api/booking-> booking router
POST /signup- Register userPOST /login- Login userPOST /forgot-password- Send reset codePOST /verify-code- Verify codePOST /reset-password- Set new passwordGET /logout- Destroy sessionGET /- List all usersGET /:userId/notifications- User notifications
GET /- List/search carsGET /inside/:id- Single car pageGET /featured- Featured cars JSONGET /search- Alias search routeGET /available- Date/city availability searchGET /store-dates- Store dates in sessionGET /AddCars- Add car form pagePOST /- Add carPUT /inside/:id- Edit car
GET /requests- All rent requestsGET /requests/details/:id- Request detailsPOST /requests/accept/:id- Approve requestPOST /requests/decline/:id- Decline requestGET /bookings- All bookingsGET /bookings/details/:id- Booking details
GET /api/booking/status/:bookingRef- Booking status lookupPOST /api/booking/upload- Upload identity imagePOST /process-payment- Update booking to processing statePOST /admin/booking/:id/status- Update booking status
- Profile: first/last name, email, phone, birthdate
- Auth: hashed password, role (
client/admin) - Password reset:
resetCode,resetCodeExpires
- Core details: name, brand, city, images, pricing, category
- Flags:
available,featured - Specs: seats, horsepower, cylinders, maxSpeed, model
- Customer contact and address data
- Payment method and summary fields
- Booking reference auto-generation (
NW-YYYY-XXXXXX) - Status lifecycle:
pending,confirmed,cancelled,completed
- Links
userIdandcarId - Rental window (
rentStart,rentEnd) - Booking status (
booked)
- Rental request from user to admin
- Request dates and entity references
- Notification content per user
- Timestamped entries
- User signs up (
bcrypthash stored) - User logs in (
express-sessionstores user) - Role-based redirect (
admin->/admin,client->/)
POST /api/v1/users/forgot-password- Code emailed via Nodemailer (Gmail)
POST /api/v1/users/verify-codePOST /api/v1/users/reset-password
GET /auth/google- Google callback to
/auth/google/callback - Passport profile saved to session
- Configured locales:
en,fr - Locale sources in
locales/en.jsonandlocales/fr.json - Query parameter supported:
?lang=enor?lang=fr - Cookie-based language persistence via
/lang/:locale
- Views under
views/(EJS) - Reusable parts in
views/partials/ - Admin templates in
views/Admin/ - Frontend assets in
public/css,public/JavaScript,public/images
- Do not commit real
.envsecrets to source control. - Rotate any exposed credentials immediately.
- For production, secure sessions (
cookie.secure: truebehind HTTPS). - Avoid storing full card/payment details server-side.
- Add request validation/sanitization for all write endpoints.
- Add automated tests (unit + integration)
- Add centralized input validation (e.g., Joi/Zod)
- Enforce auth/role middleware on admin routes
- Add CSRF protection and rate limiting
- Normalize model naming (
booking.jsvsbookings.js) - Add
.env.exampleand remove hardcoded/committed secrets - Add CI workflow for lint + tests
- Fork the repository
- Create a feature branch
- Commit your changes
- Open a pull request with a clear description