diff --git a/backend/src/controllers/postController.ts b/backend/src/controllers/postController.ts index d54aed8..870dc45 100644 --- a/backend/src/controllers/postController.ts +++ b/backend/src/controllers/postController.ts @@ -109,7 +109,7 @@ const fetchPosts = asyncHandler(async (req: Request, res: Response) => { const { page } = req.body; const pageNumber = page; - const postsPerPage = 3; + const postsPerPage = 4; const offset = (pageNumber - 1) * postsPerPage; const posts = await prisma.post.findMany({ diff --git a/backend/src/controllers/userControllers.ts b/backend/src/controllers/userControllers.ts index 7bd7f66..2196ee6 100644 --- a/backend/src/controllers/userControllers.ts +++ b/backend/src/controllers/userControllers.ts @@ -7,51 +7,99 @@ import sendMail from "../mail/sendMail"; import { Verifier } from "academic-email-verifier"; import checkCollegeEmail from "../mail/checkAcademic"; - -//@ts-ignore -const googleSignInOrSignUp = asyncHandler(async (req: Request, res: Response) => { - const{email,displayName}=req.body; - const user = await prisma.user.findUnique({ - where: { - email, - }, - }); - if (!user) { - const user = await prisma.user.create({ - // @ts-ignore - data: { +const googleSignInOrSignUp = asyncHandler( + //@ts-ignore + async (req: Request, res: Response) => { + const { email, displayName } = req.body; + if (!process.env.SECRET) { + throw new Error("Secret not found"); + } + const user = await prisma.user.findUnique({ + where: { email, - name:displayName, - collegeEmailVerified: false, - emailVerified:true, }, }); - const exp = Date.now() + 1000 * 60 *60*24*30; - // @ts-ignore + if (!user) { + const user = await prisma.user.create({ + data: { + email, + name: displayName, + collegeEmailVerified: false, + emailVerified: true, + }, + }); + const exp = Date.now() + 1000 * 60 * 60 * 24 * 30; + const token = jwt.sign({ sub: user.user_id, exp }, process.env.SECRET); + res.cookie("Authorization", token, { + httpOnly: true, + secure: false, + sameSite: "lax", + }); + return res.status(201).json({ message: "User created" }); + } + const exp = Date.now() + 1000 * 60 * 60 * 24 * 30; const token = jwt.sign({ sub: user.user_id, exp }, process.env.SECRET); res.cookie("Authorization", token, { httpOnly: true, secure: false, sameSite: "lax", }); - return res.status(201).json({ message: "User created" }); + res.status(200).json({ message: "User logged in" }); } - const exp = Date.now() + 1000 * 60 * 60 * 24 * 30; - // @ts-ignore - const token = jwt.sign({ sub: user.user_id, exp }, process.env.SECRET); - res.cookie("Authorization", token, { - httpOnly: true, - secure: false, - sameSite: "lax", - }); - res.status(200).json({ message: "User logged in" }); -}); +); + +const githubSignInOrSignUp = asyncHandler( + //@ts-ignore + async (req: Request, res: Response) => { + let { email, displayName } = req.body; + if (!process.env.SECRET) { + throw new Error("Secret not found"); + } + const user = await prisma.user.findUnique({ + where: { + email, + }, + }); + if (!displayName) { + displayName = email.split("@")[0]; + } + if (!user) { + const user = await prisma.user.create({ + data: { + email, + name: displayName, + collegeEmailVerified: false, + emailVerified: true, + }, + }); + const exp = Date.now() + 1000 * 60 * 60 * 24 * 30; + const token = jwt.sign({ sub: user.user_id, exp }, process.env.SECRET); + res.cookie("Authorization", token, { + httpOnly: true, + secure: false, + sameSite: "lax", + }); + return res.status(201).json({ message: "User created" }); + } + const exp = Date.now() + 1000 * 60 * 60 * 24 * 30; + const token = jwt.sign({ sub: user.user_id, exp }, process.env.SECRET); + res.cookie("Authorization", token, { + httpOnly: true, + secure: false, + sameSite: "lax", + }); + res.status(200).json({ message: "User logged in" }); + } +); // @ts-ignore const registerUser = asyncHandler(async (req: Request, res: Response) => { const { email, name, password, collegeName, courseName, isOnline, location } = req.body; + if (!process.env.SECRET) { + throw new Error("Secret not found"); + } const hashedPassword = await bcrypt.hash(password, 8); if (!email || !name || !password) { res.status(400).json({ message: "Please provide all fields" }); @@ -128,11 +176,9 @@ const registerUser = asyncHandler(async (req: Request, res: Response) => { }, }); const exp = Date.now() + 1000 * 60 * 5; - // @ts-ignore const token = jwt.sign({ sub: user.user_id, exp }, process.env.SECRET); const url = `${process.env.BACKEND_URL}/api/user/verify/${token}`; const htmlContent = `Verify using this link`; - // @ts-ignore sendMail(htmlContent, email); res.status(201).json({ message: "User created" }); } else { @@ -145,11 +191,9 @@ const registerUser = asyncHandler(async (req: Request, res: Response) => { }, }); const exp = Date.now() + 1000 * 60 * 5; - // @ts-ignore const token = jwt.sign({ sub: user.user_id, exp }, process.env.SECRET); const url = `${process.env.BACKEND_URL}/api/user/verify/${token}`; const htmlContent = `Verify using this link`; - // @ts-ignore sendMail(htmlContent, email); res.status(201).json({ message: "User created" }); } @@ -194,6 +238,9 @@ const verifyUser = asyncHandler(async (req: Request, res: Response) => { const loginUser = asyncHandler(async (req: Request, res: Response) => { const { email, password } = req.body; + if (!process.env.SECRET) { + throw new Error("Secret not found"); + } if (!email || !password) { res.status(400).json({ message: "Please provide all fields" }); return; @@ -207,7 +254,7 @@ const loginUser = asyncHandler(async (req: Request, res: Response) => { res.status(404).json({ message: "User not found" }); return; } - if(!user.password){ + if (!user.password) { res.status(401).json({ message: "Logged in with Google Or Github" }); return; } @@ -217,7 +264,6 @@ const loginUser = asyncHandler(async (req: Request, res: Response) => { return; } const exp = Date.now() + 1000 * 60 * 60 * 24 * 30; - // @ts-ignore const token = jwt.sign({ sub: user.user_id, exp }, process.env.SECRET); res.cookie("Authorization", token, { httpOnly: true, @@ -356,4 +402,5 @@ export { getUserDetailsById, addCourseToUser, googleSignInOrSignUp, + githubSignInOrSignUp, }; diff --git a/backend/src/routes/userRoutes.ts b/backend/src/routes/userRoutes.ts index 3c1eb5d..b3c5226 100644 --- a/backend/src/routes/userRoutes.ts +++ b/backend/src/routes/userRoutes.ts @@ -7,7 +7,8 @@ import { getCurrentUserDetails, getUserDetailsById, addCourseToUser, - googleSignInOrSignUp + googleSignInOrSignUp, + githubSignInOrSignUp, } from "../controllers/userControllers"; import checkAuth from "../middleware/checkAuth"; @@ -20,5 +21,6 @@ router.get("/me", checkAuth, getCurrentUserDetails); // get the user details of router.get("/get/:userId", checkAuth, getUserDetailsById); // get the user details of a specific user router.post("/addcourse", checkAuth, addCourseToUser); // add a course to the current user router.post("/google", googleSignInOrSignUp); // sign in or sign up using google +router.post("/github", githubSignInOrSignUp); // sign in or sign up using github export default router; diff --git a/frontend/src/components/Login.jsx b/frontend/src/components/Login.jsx index 4bcc5f9..d6d2c68 100644 --- a/frontend/src/components/Login.jsx +++ b/frontend/src/components/Login.jsx @@ -11,9 +11,11 @@ import { Stack, useToast, } from "@chakra-ui/react"; +import { FcGoogle } from "react-icons/fc"; // Google icon +import { FaGithub } from "react-icons/fa"; // GitHub icon import axios from "axios"; import { useNavigate } from "react-router-dom"; -import { auth, googleProvider } from "../firebase.js"; +import { auth, googleProvider, githubProvider } from "../firebase.js"; import { signInWithPopup } from "firebase/auth"; const LoginPage = () => { @@ -27,11 +29,14 @@ const LoginPage = () => { try { const result = await signInWithPopup(auth, googleProvider); const user = result.user; - console.log("Google login result: "); - await axios.post("/user/google", { - email:user.email, - displayName:user.displayName - }, { withCredentials: true }); + await axios.post( + "/user/google", + { + email: user.email, + displayName: user.displayName, + }, + { withCredentials: true } + ); toast({ title: "Login successful.", description: "You are being redirected to the posts page.", @@ -52,6 +57,38 @@ const LoginPage = () => { } }; + const handleGithubLogin = async () => { + try { + const result = await signInWithPopup(auth, githubProvider); + const user = result.user; + await axios.post( + "/user/github", + { + email: user.email, + displayName: user.displayName, + }, + { withCredentials: true } + ); + toast({ + title: "Login successful.", + description: "You are being redirected to the posts page.", + status: "success", + duration: 3000, + isClosable: true, + }); + navigate("/posts"); + } catch (error) { + console.error("Github login error: ", error); + toast({ + title: "Login failed.", + description: error.message || "An error occurred.", + status: "error", + duration: 3000, + isClosable: true, + }); + } + }; + const handleLogin = async () => { setLoading(true); try { @@ -82,10 +119,17 @@ const LoginPage = () => { }; return ( - - + + - + Login @@ -95,6 +139,8 @@ const LoginPage = () => { value={email} onChange={(e) => setEmail(e.target.value)} required + bg="gray.700" + color="white" /> @@ -104,14 +150,38 @@ const LoginPage = () => { value={password} onChange={(e) => setPassword(e.target.value)} required + bg="gray.700" + color="white" /> - - + diff --git a/frontend/src/components/Posts.jsx b/frontend/src/components/Posts.jsx index 4c3b13d..618cd82 100644 --- a/frontend/src/components/Posts.jsx +++ b/frontend/src/components/Posts.jsx @@ -114,10 +114,10 @@ const Posts = () => { return ( - {communities.length>0 && ( + {communities && ( )} - + { - {suggestion} + + {" "} + {suggestion} + diff --git a/frontend/src/components/data/collegeNames.jsx b/frontend/src/components/data/collegeNames.jsx index ed2c9a5..b4e15d2 100644 --- a/frontend/src/components/data/collegeNames.jsx +++ b/frontend/src/components/data/collegeNames.jsx @@ -40,4 +40,6 @@ export const collegeNames = [ "Shiv Nadar University", "Jawaharlal Nehru Technological University", "IIT Patna", + "Indraprastha Institute of Information Technology", + "Netaji Subhas University of Technology", ]; diff --git a/frontend/src/components/routes/mainroute.jsx b/frontend/src/components/routes/mainroute.jsx index ae826c1..4d69778 100644 --- a/frontend/src/components/routes/mainroute.jsx +++ b/frontend/src/components/routes/mainroute.jsx @@ -62,7 +62,7 @@ const Mainrouter = createBrowserRouter([ element: , }, { - path: "/register", + path: "/signup", element: , }, {