diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..6d413b9 --- /dev/null +++ b/.env.example @@ -0,0 +1,4 @@ +MONGO_URI= +JWT_SECRET= +NODE_ENV= +PORT=mongodb+srv://mukeshdhadhariya1_db_user:sKk4J4Rsmt1MzOEL@cluster0.fc8cebb.mongodb.net/ \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index a6815ee..bdbaa8e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "cookie-parser": "^1.4.7", "cors": "^2.8.5", "date-fns": "^4.1.0", + "dotenv": "^17.2.3", "express": "^5.1.0", "express-async-handler": "^1.2.0", "framer-motion": "^12.23.22", @@ -3038,6 +3039,18 @@ "node": ">=8" } }, + "node_modules/dotenv": { + "version": "17.2.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz", + "integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", diff --git a/package.json b/package.json index cbfe266..de922f3 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "cookie-parser": "^1.4.7", "cors": "^2.8.5", "date-fns": "^4.1.0", + "dotenv": "^17.2.3", "express": "^5.1.0", "express-async-handler": "^1.2.0", "framer-motion": "^12.23.22", diff --git a/server/.env.example b/server/.env.example deleted file mode 100644 index 9e220fe..0000000 --- a/server/.env.example +++ /dev/null @@ -1,4 +0,0 @@ -MONGO_URI= -JWT_SECRET= -NODE_ENV= -PORT= \ No newline at end of file diff --git a/server/controller/user.controller.js b/server/controller/user.controller.js index e60eb95..c4619d6 100644 --- a/server/controller/user.controller.js +++ b/server/controller/user.controller.js @@ -36,6 +36,7 @@ export const registerUser = asyncHandler(async (req, res) => { }); export const loginUser = asyncHandler(async (req, res) => { + const { email, password } = req.body; if (!email || !password) { @@ -57,11 +58,12 @@ export const loginUser = asyncHandler(async (req, res) => { // Set token in HTTP-only cookie res.cookie("token", token, { httpOnly: true, - secure: process.env.NODE_ENV === "production", - sameSite: "strict", + secure: false, // β localhost uses HTTP, not HTTPS + sameSite: "lax", maxAge: 24 * 60 * 60 * 1000, }); + return res.status(200).json({ success: true, message: "Login successful", @@ -78,8 +80,8 @@ export const loginUser = asyncHandler(async (req, res) => { export const logoutUser = asyncHandler(async (req, res) => { res.clearCookie("token", { httpOnly: true, - secure: process.env.NODE_ENV === "production", - sameSite: "strict", + secure: false, + sameSite: "lax", }); return res.status(200).json({ diff --git a/server/middleware/auth.middleware.js b/server/middleware/auth.middleware.js index 933964f..681414f 100644 --- a/server/middleware/auth.middleware.js +++ b/server/middleware/auth.middleware.js @@ -4,11 +4,10 @@ import { User } from "../models/user.model.js"; export const authMiddleware = async (req, res, next) => { try { - const token = req.headers.authorization?.split(" ")[1]; + const token = req.cookies?.token || req.headers.authorization?.split(" ")[1]; if (!token) { return res.status(401).json({ success: false, message: "No token provided" }); } - const decoded = jwt.verify(token, process.env.JWT_SECRET); const user = await User.findById(decoded.id); diff --git a/server/mock-socket-server.js b/server/mock-socket-server.js index f7b9e71..8512172 100644 --- a/server/mock-socket-server.js +++ b/server/mock-socket-server.js @@ -6,10 +6,21 @@ import http from 'http'; import { Server } from 'socket.io'; import cors from 'cors'; import cookieParser from "cookie-parser"; +import userrouter from "./routes/user.route.js" +import dotenv from "dotenv"; +import connectDB from "./utils/connect-db.js" + +dotenv.config(); const app = express(); -app.use(cors()); +app.use(cors({ + origin: ["http://localhost:5173"], // π your React app + credentials: true, // π allow cookies +})); +app.use(express.json()); app.use(cookieParser()); +app.use("/api",userrouter) + const server = http.createServer(app); const io = new Server(server, { @@ -257,30 +268,30 @@ app.get('/info', (req, res) => { }); const PORT = process.env.PORT || 3001; -dotenv.config(); -// connectDB().then( -// server.listen(PORT, () => { -// console.log(`π InvertorGuard Mock Socket.IO server running on port ${PORT}`); -// console.log(`π Health check: http://localhost:${PORT}/health`); -// console.log(`π Server info: http://localhost:${PORT}/info`); -// console.log(`π Connect your React app to: http://localhost:${PORT}`); -// console.log(`π₯ Ready for client connections...`); -// }) -// ).catch((err)=> -// { -// console.log('database connection faield',err); -// }); - - -server.listen(PORT, () => { - console.log(`π InvertorGuard Mock Socket.IO server running on port ${PORT}`); - console.log(`π Health check: http://localhost:${PORT}/health`); - console.log(`π Server info: http://localhost:${PORT}/info`); - console.log(`π Connect your React app to: http://localhost:${PORT}`); - console.log(`π₯ Ready for client connections...`); -}) +connectDB() + .then(() => { + server.listen(PORT, () => { + console.log(`π InvertorGuard Mock Socket.IO server running on port ${PORT}`); + console.log(`π Health check: http://localhost:${PORT}/health`); + console.log(`π Server info: http://localhost:${PORT}/info`); + console.log(`π Connect your React app to: http://localhost:${PORT}`); + console.log(`π₯ Ready for client connections...`); + }) + }) + .catch((err) => { + console.error("β Database connection failed:", err); + }); + + +// server.listen(PORT, () => { +// console.log(`π InvertorGuard Mock Socket.IO server running on port ${PORT}`); +// console.log(`π Health check: http://localhost:${PORT}/health`); +// console.log(`π Server info: http://localhost:${PORT}/info`); +// console.log(`π Connect your React app to: http://localhost:${PORT}`); +// console.log(`π₯ Ready for client connections...`); +// }) // Graceful shutdown process.on('SIGINT', () => { diff --git a/server/routes/user.route.js b/server/routes/user.route.js index 61e0a8d..b31db9e 100644 --- a/server/routes/user.route.js +++ b/server/routes/user.route.js @@ -4,7 +4,7 @@ import { authMiddleware } from "../middleware/auth.middleware.js"; const router = express.Router(); -router.post("/register", registerUser); +router.post("/register", authMiddleware, registerUser); router.post("/login", loginUser); router.post("/logout", authMiddleware, logoutUser); diff --git a/server/utils/connect-db.js b/server/utils/connect-db.js index 100359a..a47fb92 100644 --- a/server/utils/connect-db.js +++ b/server/utils/connect-db.js @@ -1,22 +1,22 @@ import mongoose from "mongoose"; +import dotenv from "dotenv"; +dotenv.config(); -const connectDB=async ()=>{ - try { - - if(!process.env.MONGO_URI){ - console.warn('MONGO_URI not found in .env - database features will be unavailable'); - return; - } - - await mongoose.connect(`${process.env.MONGO_URI}`) +const connectDB = async () => { + try { + + if (!process.env.MONGO_URI) { + throw new Error("β Missing MONGO_URI in .env file!"); + } - console.log(`\n mongodb connected`); + await mongoose.connect(process.env.MONGO_URI); - } catch (error) { + console.log(`β MongoDB connected successfully`); + } catch (error) { + console.error("β MongoDB connection error:", error.message); - console.warn("Mongodb connection error - database features will be unavailable:",error.message); - - } -} + throw error; + } +}; -export default connectDB; \ No newline at end of file +export default connectDB; diff --git a/src/App.jsx b/src/App.jsx index fc14d96..6d7bc73 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,40 +1,3 @@ -// import { useState } from 'react' -// import reactLogo from './assets/react.svg' -// import viteLogo from '/vite.svg' -// import './App.css' - -// function App() { -// const [count, setCount] = useState(0) - -// return ( -// <> -//
-//
-// Edit src/App.jsx and save to test HMR
-//
-// Click on the Vite and React logos to learn more -//
-// > -// ) -// } - -// export default App - - import React from 'react'; import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom'; import { ToastContainer } from 'react-toastify'; @@ -42,40 +5,66 @@ import 'react-toastify/dist/ReactToastify.css'; import { AppProvider, useApp } from './context/AppContext'; import { SocketProvider } from './context/SocketContext'; import { NotificationProvider } from './context/NotificationContext'; +import { AuthProvider, useAuth } from './context/AuthContext'; import Dashboard from './pages/Dashboard'; import Logs from './pages/Logs'; import Settings from './pages/Settings'; import Navigation from './components/Navigation'; +import Login from './pages/Login'; +import Register from './pages/Register'; function App() { return ( -+ Monitor your inverter & energy usage with ease. +
+ + + ++ Donβt have an account?{" "} + + Register + +
++ Join Smart Energy Tracker and monitor power like never before. +
+ + + ++ Already have an account?{" "} + + Login + +
+