- π Overview
- π οΈ Tech Stack
- ποΈ Architecture
- βοΈ Features
- π¦ Quick Start
- πΌοΈ Image Upload with Cloudinary
- π§ͺ Testing
- π Project Structure
- π‘οΈ Environment Configuration
- π¨ UI/UX
- π Tracking
- π€ Feedback and Community
- π Contribution Guidelines
- π Our Amazing Contributors
- π Deployment
- π License
- πββοΈ Contact
RIVETO is a modern, fullstack web application built for scalability, advanced analytics.
It features a robust admin panel for management, user tracking, advanced UI components, and secure file/image upload via Cloudinary.
- Frontend: React, Tailwind CSS
- Backend: Node.js, Express.js
- Database: MongoDB (Mongoose ODM)
- Tracking: Custom analytics & event tracking
- UI: Advanced, responsive design with Tailwind
- Image Uploads: Cloudinary for secure and performant media management
- π Admin Panel: Manage users, payments, analytics, and more
- π Advanced Tracking: User behavior, transactions, and event analytics
- π¨ Modern UI: Responsive, accessible, and beautiful interface (Tailwind)
- πΌοΈ Cloudinary Image Upload: Fast, secure, and optimized media storage
- π Authentication & Authorization: Secure user and admin access
- π RESTful API: Powerful backend for frontend and mobile clients
git clone https://github.com/Nsanjayboruds/RIVETO.git
cd RIVETO- Copy and edit environment files:
- For backend:
cp backend/.env.example backend/.env
- For frontend:
cp frontend/.env.example frontend/.env
- For backend:
- Fill in your MongoDB, Razorpay keys, Cloudinary credentials, JWT secrets, etc.
# In root
cd backend
npm install
cd ../frontend
npm installOpen two separate terminal windows to run the servers simultaneously:
Terminal 1 (Backend):
cd backend
npm run dev- Backend: http://localhost:5000
- Frontend: http://localhost:3000
- Uses the cloudinary npm package.
- Secure image upload endpoints with authentication/middleware.
- Stores Cloudinary URLs in MongoDB model fields.
Sample Endpoint (Express.js):
// /backend/routes/upload.js
const { CloudinaryStorage } = require("multer-storage-cloudinary");
const multer = require("multer");
const cloudinary = require("cloudinary").v2;
// Cloudinary config (use your .env)
cloudinary.config({
cloud_name: process.env.CLOUDINARY_CLOUD_NAME,
api_key: process.env.CLOUDINARY_API_KEY,
api_secret: process.env.CLOUDINARY_API_SECRET,
});
const storage = new CloudinaryStorage({
cloudinary,
params: {
folder: "riveto_uploads",
allowed_formats: ["jpg", "png", "jpeg", "svg", "webp"],
},
});
const upload = multer({ storage });
router.post("/upload", upload.single("image"), (req, res) => {
res.json({ url: req.file.path });
});- Use a file input and upload images using a form or fetch/Axios to the backend
/uploadendpoint. - Store the returned Cloudinary URL for use in UI or database.
Sample Usage:
const handleUpload = async (event) => {
const formData = new FormData();
formData.append("image", event.target.files[0]);
const response = await fetch("/api/upload", {
method: "POST",
body: formData,
});
const data = await response.json();
setImageUrl(data.url); // Save/display Cloudinary URL
};Run lint checks:
npm run lintRIVETO/
βββ backend/
β βββ controller/
β βββ model/
β βββ routes/
β βββ middleware/
β βββ services/
β βββ .env.example
β βββ ...
βββ frontend/
β βββ src/
β β βββ components/
β β βββ pages/
β β βββ hooks/
β β βββ utils/
β β βββ App.jsx
β βββ public/
β βββ .env.example
β βββ ...
βββ README.md
βββ ...
MONGODB_URI=
JWT_SECRET=
BASE_URL=http://localhost:5000
CLOUDINARY_CLOUD_NAME=
CLOUDINARY_API_KEY=
CLOUDINARY_API_SECRET=
REACT_APP_API_URL=http://localhost:5000/api
REACT_APP_RAZORPAY_KEY=
- Fully responsive admin panel
- Advanced dashboard with analytics charts
- Dark/light mode with Tailwind CSS
- Custom components for user and payment management
- Custom event logging and analytics
- Admin dashboard for real-time tracking
We welcome bug reports, feature requests, and community feedback.
If you find a bug or security issue, please open an issue on GitHub with:
- Steps to reproduce
- Expected behavior
- Screenshots/logs if applicable
GitHub Issues: https://github.com/Nsanjayboruds/RIVETO/issues
Have an idea for improving RIVETO? Open a feature request issue and describe your suggestion.
Use GitHub Discussions for:
- Questions
- Community help
- Project ideas
- Feedback
GitHub Discussions: https://github.com/Nsanjayboruds/RIVETO/discussions
Before contributing, please star the repository β
- Fork the project
- Create your feature branch (
git checkout -b feature/YourFeature) - Commit your changes (
git commit -m 'Add feature') - Push to the branch (
git push origin feature/YourFeature) - Open a Pull Request
Please review CONTRIBUTING.md for details.
Thank you to all contributors who have helped make RIVETO better! π
- π― First Contributor: Madhav Majumdar (@madhav2348) - For being the first to join and contribute to RIVETO!
- π‘ Most Innovative: Md Ashad (@asadanwarr0) - For enhancing the About, Contact, and Home sections.
- π¨ UI/UX Champion: Vedant (@vedantbudhabaware) - For fixing critical UI issues and optimizing the mobile experience.
Want to see your name here? Check out our Contributing Guide!
- Docker Compose and cloud deployment instructions coming soon!
- Easily deploy to Vercel (frontend) and Render or Heroku (backend).
MIT License. See LICENSE for details.
- Nishant Sanjay Borude β @Nsanjayboruds
Built with React, Tailwind, Node.js, Express, MongoDB, Razorpay, and Cloudinary
This project implements a secure JWT refresh token flow with rotation:
-
Login
Issues an access token (15 minutes expiry) and a refresh token (7 days expiry).
Refresh tokens are hashed and stored in MongoDB. -
Refresh
POST /api/auth/refreshrotates the refresh token on each use.
Old tokens are invalidated, new ones are stored. -
Logout
POST /api/auth/logoutclears both cookies and deletes the refresh token from DB.
This ensures sessions cannot be reused after logout. -
Google & Admin Login
Both flows now issue access + refresh tokens, aligned with the same rotation/invalidation logic.
- All cookies are
httpOnly,secure, andsameSiteaware. - Refresh tokens are hashed with bcrypt before storage.
- Expired or invalid tokens return
403 Forbidden.
Run the Jest test suite to validate login, refresh, and logout flows:
npm test