Skip to content
VSathveekPublic

About

A full-stack ed-tech platform featuring seamless course management for instructors, an interactive catalog for students, secure OTP authentication, and integrated Razorpay payments.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

BrainWave

A full-stack MERN ed-tech platform where instructors build and sell video courses and students buy, watch and review them.

What it does

Students

  • Sign up with email OTP verification, log in, reset a forgotten password by email link
  • Browse a catalog by category (with a "top selling" list and courses from another category), view course details and reviews
  • Add courses to a cart and check out with Razorpay, or use the "Buy for free" demo path
  • Watch lectures in a course player with a section/lecture sidebar, mark lectures complete and see progress percentages on the enrolled-courses page
  • Rate and review courses they are enrolled in

Instructors

  • Multi-step course builder: course info (thumbnail, price, category, tags, instructions), sections and lecture videos, then publish or keep as draft
  • Edit course content (sections and lectures), publish or unpublish, and delete courses
  • Dashboard with per-course enrolled students and income, plus a Chart.js pie chart

Everyone

  • Profile, display picture and password settings; account deletion
  • Contact form that sends a confirmation email
  • Transactional emails: OTP, enrollment, payment received, password updated

How it works

flowchart LR
  C["React SPA<br/>Redux Toolkit"] -->|"axios + Bearer JWT"| API["Express API"]
  API --> MW["auth middleware<br/>JWT verify + role check"]
  MW --> CT["Controllers"]
  CT --> DB[("MongoDB<br/>Mongoose")]
  CT -->|"thumbnails, videos, avatars"| CL["Cloudinary"]
  CT -->|"OTP, receipts, resets"| ML["Nodemailer"]
  CT -->|"create order"| RZ["Razorpay"]
  C -->|"checkout.js"| RZ
Loading

Authentication. Signup is gated by a 6-digit OTP. The OTP model has a Mongoose pre("save") hook that emails the code, and a TTL index (5 minutes) that expires it. Passwords are hashed with bcrypt. Login issues a JWT (email, id, accountType, 2 h expiry), returned in the response and set as an httpOnly cookie. The auth middleware accepts the token from the cookie, the body or an Authorization: Bearer header. Password reset uses a random crypto token stored on the user with a 5-minute expiry.

Role-based access control. Users are Student, Instructor or Admin. Routes chain auth with isStudent, isInstructor or isAdmin, which look the user up in MongoDB and check accountType. For example, only instructors can create courses and sections, only students can buy courses or post reviews, and only admins can create categories. Reviews are also checked against the course's enrolled students.

Payments. capturePayment totals the cart server-side from course prices (it does not trust a client amount), rejects courses the student already owns, and creates a Razorpay order in INR. After checkout, verifyPayment recomputes HMAC-SHA256(order_id + "|" + payment_id) with the Razorpay secret and only enrolls the student (course studentsEnrolled, user courses, a new CourseProgress record, enrollment email) if it matches the returned signature.

Media. express-fileupload writes uploads to temp files, and uploadImage sends them to Cloudinary (resource_type: "auto", so it handles both images and lecture videos) under FOLDER_NAME.

Data model. User, Profile, OTP, Category, Course, Section, SubSection (lecture video), CourseProgress, RatingAndReview, Tag.

Tech stack

Layer Tools
Frontend React 18 (Create React App), Redux Toolkit, React Router 6, Tailwind CSS 3, react-hook-form, Swiper, Chart.js, video-react, react-hot-toast
Backend Node.js, Express 4, Mongoose 7, JSON Web Tokens, bcrypt, otp-generator, cookie-parser, express-fileupload
Services MongoDB, Cloudinary, Razorpay, Nodemailer

Project structure

BrainWave/
├── src/                  React app
│   ├── pages/            Home, Catalog, CourseDetails, Dashboard, auth pages
│   ├── components/       Dashboard (AddCourse builder, Cart, InstructorDashboard), ViewCourse player, Commons
│   ├── services/         APIs.js (endpoint map), APIconnector.js, operations/ (API calls per feature)
│   └── reducer/          Redux slices (auth, profile, cart, course, courseDetails)
└── BackEnd/
    ├── index.js          Express app and route mounting
    ├── routes/           User (auth), Profile, Course, Payment, Contact
    ├── controllers/      business logic per resource
    ├── middlewares/      auth.js (JWT + role guards)
    ├── models/           Mongoose schemas
    ├── config/           database, cloudinary, razorpay
    ├── mailTemplates/    HTML email templates
    └── utilities/        ImageUploader (Cloudinary), MailSender, convertTimeFormat

Local setup

Prerequisites: Node.js, a MongoDB connection string, and Cloudinary, Razorpay (test mode) and SMTP credentials.

npm install                    # frontend
cd BackEnd && npm install      # backend
cd .. && npm run dev           # runs the React app (port 3000) and the API (nodemon) together

Or run them separately with npm start (root) and npm run dev (in BackEnd/).

Create a .env file in both the project root and the BackEnd directory (see the .env.example files).

BackEnd/.env:

MONGO_URL=
PORT=4000
MAIL_HOST=          # Nodemailer "service" name, e.g. gmail
MAIL_USER=
MAIL_PASS=
JWT_SECRET=
FOLDER_NAME=        # Cloudinary folder for uploads
CLOUD_NAME=
API_KEY=            # Cloudinary
API_SECRET=         # Cloudinary
RAZORPAY_KEY=
RAZORPAY_SECRET=

Root .env:

REACT_APP_BASE_URL=http://localhost:4000

The API mounts its routers at the root (/auth, /course, ...), so the base URL should not include the /api/v1 suffix shown in BackEnd/.env.example.

API overview

A = requires a JWT. Role guards are noted where they apply.

Router Endpoints
/auth POST /sendOTP, POST /signup, POST /login, POST /changePassword (A), POST /resetPasswordToken, POST /resetPassword
/profile GET /getAllDetails (A), PUT /updateProfile (A), PUT /updateDisplayPicture (A), DELETE /deleteProfile (A), GET /getEnrolledCourses (A, Student), GET /instructorDashboard (A, Instructor)
/course (instructor) POST /createCourse, POST /addSection, PUT /updateSection, DELETE /deleteSection, POST /addSubSection, PUT /updateSubSection, DELETE /deleteSubSection, PUT /changeStatus, GET /getInstructorCourses, DELETE /deleteCourse (all A, Instructor)
/course (student) POST /getFullCourseDetails, POST /updateCourseProgress, POST /createRatingAndReview, POST /getStudentCourseRatingsAndReview (all A, Student)
/course (public) GET /getAllCourses, POST /getCourseDetails, GET /showAllCategory, POST /getCategoryPageDetails, POST /getAverageRating, GET /getReviews
/course (admin) POST /createCategory (A, Admin)
/payment POST /capturePayment, POST /verifyPayment, POST /sendPaymentSuccessEmail, POST /buyCoursesForFree (all A, Student)
/contact POST /contactUs

What I'd improve next

Known issues found while reviewing the code, roughly in priority order:

  • Payment verification: BackEnd/controllers/Payment.js uses crypto without requiring it, so /payment/verifyPayment throws. The frontend also reads process.env.RAZORPAY_KEY, which Create React App does not expose (it needs a REACT_APP_ prefix).
  • Security hardening:
    • /payment/buyCoursesForFree enrolls a student without checking the course price
    • sendOTP returns the OTP in its response
    • signup accepts any accountType from the client, including Admin
    • course update/delete routes check the Instructor role but not course ownership
  • Frontend/backend drift: the endpoint map calls /profile/getUserDetails and /course/editCourse, which do not exist on the server (the edit route is commented out), and the payment-success-email URL is missing a /.
  • Smaller bugs:
    • the OTP createdAt default is Date.now() (evaluated once at startup) instead of Date.now
    • a few typos (.josn, res.stauts) in error paths
    • sendPaymentSuccessEmail never sends a success response
    • the reset-password link is hardcoded to http://localhost:3000
  • Engineering: restrict CORS (currently *), add request validation, centralize error handling, and add tests (there are none yet).

About

A full-stack ed-tech platform featuring seamless course management for instructors, an interactive catalog for students, secure OTP authentication, and integrated Razorpay payments.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages