diff --git a/backend/index.js b/backend/index.js index 0050490..e2fe922 100644 --- a/backend/index.js +++ b/backend/index.js @@ -1,9 +1,14 @@ import express from 'express'; +import cookieParser from 'cookie-parser'; import cors from 'cors'; import { router } from './routes/routes.mjs'; const app = express(); -app.use(cors()); +app.use(cookieParser()); +app.use(cors({ + origin: 'http://localhost:3000', // replace with your React app origin + credentials: true, + })); const PORT = process.env.PORT || 6541; app.use(express.json()); diff --git a/backend/logics/Login/login.mjs b/backend/logics/Login/login.mjs new file mode 100644 index 0000000..3f7612e --- /dev/null +++ b/backend/logics/Login/login.mjs @@ -0,0 +1,59 @@ +import { GraphQLClient} from 'graphql-request'; +import { LoginQuery } from './query.mjs'; +import jwt from 'jsonwebtoken'; +// import bodyParser from "body-parser"; + +const login = new LoginQuery(); + +const hasuraEndpoint = 'http://localhost:8080/v1/graphql'; +const adminSecret = '123'; + +const generateJwtToken = () => { + const claims = { + "sub": "1234567890", + "name": "Debesh Pramanick", + "https://hasura.io/jwt/claims": { + "x-hasura-allowed-roles": [ + "admin", + "user" + ], + "x-hasura-default-role": "admin" + // "x-hasura-default-role": "user" + } + } + + return jwt.sign(claims, '5kOnr5vYmLggihää0X9TGrQBC4PoFPgt', { expiresIn: '1h' }); +}; + +const client = new GraphQLClient(hasuraEndpoint, { + headers: { + 'x-hasura-admin-secret': adminSecret + // 'Authorization': `Bearer ${generateJwtToken()}` + }, +}); + + + +export class LoginUser{ + async login(req, res){ + try{ + // console.log(req.body) + const {email, password} = req.body; + const data = await client.request(login.loginUser(email, password),{}); + const token = generateJwtToken(); + // console.log(data); + // res.json(data); + res.status(200).json( + { + "message":"Welcome User", + "uuid":data.kalenview_by_pk.uuid, + "first_name":data.kalenview_by_pk.first_name, + "last_name":data.kalenview_by_pk.last_name, + "token": token // Include the JWT in the response + }); + }catch (error) { + console.error('Error fetching data:', error); + res.status(500).json({error: 'Kindly Sign Up or Check email and password'}); + } + } +} \ No newline at end of file diff --git a/backend/logics/Login/query.mjs b/backend/logics/Login/query.mjs new file mode 100644 index 0000000..514a05e --- /dev/null +++ b/backend/logics/Login/query.mjs @@ -0,0 +1,13 @@ +export class LoginQuery { + loginUser(email, password){ + return ` + query MyQuery { + kalenview_by_pk(email: "${email}", password: "${password}") { + uuid + first_name + last_name + } + } + ` + }; +} \ No newline at end of file diff --git a/backend/logics/VerifyJWT/verifyJWT.mjs b/backend/logics/VerifyJWT/verifyJWT.mjs new file mode 100644 index 0000000..a8cb22d --- /dev/null +++ b/backend/logics/VerifyJWT/verifyJWT.mjs @@ -0,0 +1,34 @@ +const secretKey = '5kOnr5vYmLggihää0X9TGrQBC4PoFPgt'; +import jwt from 'jsonwebtoken'; + +export class VerifyJWToken{ + verifyJWT(req, res){ + const token = req.headers.authorization; + // console.log(token) + // const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkRlYmVzaCBQcmFtYW5pY2siLCJodHRwczovL2hhc3VyYS5pby9qd3QvY2xhaW1zIjp7IngtaGFzdXJhLWFsbG93ZWQtcm9sZXMiOlsiYWRtaW4iLCJ1c2VyIl0sIngtaGFzdXJhLWRlZmF1bHQtcm9sZSI6ImFkbWluIn0sImlhdCI6MTcxNTg1NjgyOCwiZXhwIjoxNzE1ODYwNDI4fQ.MGQvAwpkbJlfmOZh9ki8ML2U0kJo69ijsFvn834dwb8'; + try{ + if (!token) { + console.log("No jwt"); + return res.status(401).json({ success: false }); + + } + + jwt.verify(token, secretKey, (err, decoded) => { + if (err) { + console.log("Invalid jwt"); + return res.status(401).json({ success: false }); + // return res.redirect('/login'); + } + + else{ + console.log("Valid jwt"); + return res.status(200).json({success:true}); + } + + }); + } + catch(error){ + res.json({message:error}) + } + } +} \ No newline at end of file diff --git a/backend/package-lock.json b/backend/package-lock.json index 08ce24a..7ae8270 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -9,9 +9,11 @@ "version": "1.0.0", "license": "ISC", "dependencies": { + "cookie-parser": "^1.4.6", "cors": "^2.8.5", "express": "^4.19.2", - "graphql-request": "^7.0.1" + "graphql-request": "^7.0.1", + "jsonwebtoken": "^9.0.2" } }, "node_modules/@dprint/darwin-arm64": { @@ -204,6 +206,11 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -268,6 +275,26 @@ "node": ">= 0.6" } }, + "node_modules/cookie-parser": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz", + "integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==", + "dependencies": { + "cookie": "0.4.1", + "cookie-signature": "1.0.6" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/cookie-parser/node_modules/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", @@ -344,6 +371,14 @@ "@dprint/win32-x64": "0.45.1" } }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -611,16 +646,96 @@ "node": ">= 0.10" } }, + "node_modules/jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jsonwebtoken/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, "node_modules/lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, "node_modules/lodash.ismatch": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==" }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + }, "node_modules/lodash.snakecase": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", @@ -815,6 +930,17 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/send": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", diff --git a/backend/package.json b/backend/package.json index 0f3595d..a21fc5b 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,8 +1,10 @@ { "dependencies": { + "cookie-parser": "^1.4.6", "cors": "^2.8.5", "express": "^4.19.2", - "graphql-request": "^7.0.1" + "graphql-request": "^7.0.1", + "jsonwebtoken": "^9.0.2" }, "name": "backend", "version": "1.0.0", diff --git a/backend/routes/routes.mjs b/backend/routes/routes.mjs index cc23075..165d244 100644 --- a/backend/routes/routes.mjs +++ b/backend/routes/routes.mjs @@ -5,6 +5,8 @@ import express from 'express'; import { CreateEvent } from '../logics/CreateEvent/createEvent.mjs'; import { GetEvent } from '../logics/GetEvents/getEvents.mjs'; +import { LoginUser } from '../logics/Login/login.mjs'; +import { VerifyJWToken } from '../logics/VerifyJWT/verifyJWT.mjs'; // const auth_logic = new AuthLogic(); // const norm_routes = new NormRoutes(); @@ -12,16 +14,18 @@ import { GetEvent } from '../logics/GetEvents/getEvents.mjs'; const new_event = new CreateEvent(); const get_event = new GetEvent(); +const login_user = new LoginUser(); +const jwt_verify = new VerifyJWToken(); const router = express.Router(); // // For signup // router.post('/signup', auth_logic.insertSignupUser); -// // For login -// router.post('/login', auth_logic.login); +// For login +router.post('/login', login_user.login); -// // For JWT Verification -// router.post('/verify', verify_jwt.verifyJwt); +// For JWT Verification +router.post('/verify', jwt_verify.verifyJWT); // // For Home // router.get('/', norm_routes.linkpage); diff --git a/frontend/frontend/package-lock.json b/frontend/frontend/package-lock.json index 80e35ab..6d24149 100644 --- a/frontend/frontend/package-lock.json +++ b/frontend/frontend/package-lock.json @@ -12,6 +12,7 @@ "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "axios": "^1.6.8", + "js-cookie": "^3.0.5", "react": "^18.3.1", "react-dom": "^18.3.1", "react-icons": "^5.2.1", @@ -12189,6 +12190,14 @@ "jiti": "bin/jiti.js" } }, + "node_modules/js-cookie": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", + "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==", + "engines": { + "node": ">=14" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", diff --git a/frontend/frontend/package.json b/frontend/frontend/package.json index 9e41e50..b681c32 100644 --- a/frontend/frontend/package.json +++ b/frontend/frontend/package.json @@ -7,6 +7,7 @@ "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "axios": "^1.6.8", + "js-cookie": "^3.0.5", "react": "^18.3.1", "react-dom": "^18.3.1", "react-icons": "^5.2.1", diff --git a/frontend/frontend/src/App.css b/frontend/frontend/src/App.css index 65011f5..5f34fbd 100644 --- a/frontend/frontend/src/App.css +++ b/frontend/frontend/src/App.css @@ -1,24 +1,3 @@ .App { text-align: center; -} - -/* .App-logo { - height: 40vmin; - pointer-events: none; -} */ - -.create-event-button { - display: inline-block; - padding: 10px 20px; - margin: 20px 0; - background-color: #007BFF; - color: white; - text-decoration: none; - border-radius: 5px; - font-size: 16px; - transition: background-color 0.3s ease; -} - -.create-event-button:hover { - background-color: #0056b3; -} +} \ No newline at end of file diff --git a/frontend/frontend/src/App.js b/frontend/frontend/src/App.js index 9e2a8f1..bddb779 100644 --- a/frontend/frontend/src/App.js +++ b/frontend/frontend/src/App.js @@ -1,9 +1,10 @@ import React from "react"; -import { BrowserRouter as Router, Routes, Route, Link } from "react-router-dom"; +import { BrowserRouter as Router, Routes, Route} from "react-router-dom"; import CreateEvent from "./components/CreateEvent/CreateEvent.js"; import EventList from "./components/EventList/EventList.js"; +import Login from "./components/login/Login.js"; -import "./App.css" +import "./App.css"; function App() { return ( @@ -14,10 +15,10 @@ function App() {
- Create New Event } /> - } /> + } /> + }/>
diff --git a/frontend/frontend/src/components/CreateEvent/CreateEvent.js b/frontend/frontend/src/components/CreateEvent/CreateEvent.js index c329108..cb03e4e 100644 --- a/frontend/frontend/src/components/CreateEvent/CreateEvent.js +++ b/frontend/frontend/src/components/CreateEvent/CreateEvent.js @@ -1,7 +1,8 @@ -import React, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import { FaPhone, FaVideo, FaMapMarkerAlt } from 'react-icons/fa'; import { useNavigate } from 'react-router-dom'; import axios from 'axios'; +import Cookies from 'js-cookie'; import './CreateEvent.css'; const CreateEvent = () => { @@ -9,6 +10,7 @@ const CreateEvent = () => { const [duration, setDuration] = useState(''); const [locationType, setLocationType] = useState(''); const [locationDetail, setLocationDetail] = useState(''); + const [JWTverify, setJWTverify] = useState(false); const navigate = useNavigate(); const handleLocationTypeChange = (newLocationType)=>{ @@ -33,7 +35,7 @@ const CreateEvent = () => { if (response.data.success) { alert('Event created successfully!'); - navigate('/'); + navigate('/event_list'); } else { alert('Failed to create event.'); } @@ -42,68 +44,102 @@ const CreateEvent = () => { } } + useEffect(()=>{ + const JWTVERIFY = async()=>{ + const jwt = Cookies.get('jwt'); + const data ={}; + try { + const verification = await axios.post('http://localhost:6541/verify',data,{ + headers: { + Authorization: `${jwt}` + } + }); + // console.log(verification) + if(verification.data.success === true){ + return setJWTverify(true); + } + else{ + return setJWTverify(false); + } + } catch (error) { + console.error('Failed to verify JWT:', error); + } + }; + JWTVERIFY() + },[]); - return ( -
-
-

Create Event

- - -