diff --git a/backend/prisma/schema.prisma b/backend/prisma/schema.prisma index f0c93e4..3a524ab 100644 --- a/backend/prisma/schema.prisma +++ b/backend/prisma/schema.prisma @@ -11,7 +11,7 @@ model User { user_id String @id @default(cuid()) email String @unique name String? - password String + password String? createdAt DateTime @default(now()) emailVerified Boolean @default(false) collegeEmailVerified Boolean @default(false) diff --git a/backend/src/controllers/userControllers.ts b/backend/src/controllers/userControllers.ts index 1ef38f7..2765a54 100644 --- a/backend/src/controllers/userControllers.ts +++ b/backend/src/controllers/userControllers.ts @@ -7,6 +7,45 @@ 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({ + data: { + email, + name:displayName, + collegeEmailVerified: false, + emailVerified:true, + }, + }); + 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", + }); + return res.status(201).json({ message: "User created" }); + } + 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" }); +}); + + // @ts-ignore const registerUser = asyncHandler(async (req: Request, res: Response) => { const { email, name, password, collegeName, courseName, isOnline, location } = @@ -166,6 +205,10 @@ const loginUser = asyncHandler(async (req: Request, res: Response) => { res.status(404).json({ message: "User not found" }); return; } + if(!user.password){ + res.status(401).json({ message: "Logged in with Google Or Github" }); + return; + } const match = await bcrypt.compare(password, user.password); if (!match) { res.status(401).json({ message: "Invalid credentials" }); @@ -310,4 +353,5 @@ export { getCurrentUserDetails, getUserDetailsById, addCourseToUser, + googleSignInOrSignUp, }; diff --git a/backend/src/routes/userRoutes.ts b/backend/src/routes/userRoutes.ts index 8523ff6..3c1eb5d 100644 --- a/backend/src/routes/userRoutes.ts +++ b/backend/src/routes/userRoutes.ts @@ -6,7 +6,8 @@ import { verifyUser, getCurrentUserDetails, getUserDetailsById, - addCourseToUser + addCourseToUser, + googleSignInOrSignUp } from "../controllers/userControllers"; import checkAuth from "../middleware/checkAuth"; @@ -18,5 +19,6 @@ router.route("/verify/:token").get(verifyUser); router.get("/me", checkAuth, getCurrentUserDetails); // get the user details of the current user 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 export default router; diff --git a/frontend/package.json b/frontend/package.json index ee18568..f16f4d7 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -14,6 +14,8 @@ "@emotion/react": "^11.13.0", "@emotion/styled": "^11.13.0", "axios": "^1.7.2", + "dotenv": "^16.4.5", + "firebase": "^10.14.0", "framer-motion": "^11.3.19", "react": "^18.3.1", "react-autosuggest": "^10.1.0", diff --git a/frontend/src/components/Login.jsx b/frontend/src/components/Login.jsx index c8223b1..4bcc5f9 100644 --- a/frontend/src/components/Login.jsx +++ b/frontend/src/components/Login.jsx @@ -13,6 +13,8 @@ import { } from "@chakra-ui/react"; import axios from "axios"; import { useNavigate } from "react-router-dom"; +import { auth, googleProvider } from "../firebase.js"; +import { signInWithPopup } from "firebase/auth"; const LoginPage = () => { const [email, setEmail] = useState(""); @@ -21,6 +23,35 @@ const LoginPage = () => { const toast = useToast(); const navigate = useNavigate(); + const handleGoogleLogin = async () => { + 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 }); + 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("Google 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 { @@ -78,6 +109,9 @@ const LoginPage = () => { + diff --git a/frontend/src/components/Posts.jsx b/frontend/src/components/Posts.jsx index 32b9141..4c3b13d 100644 --- a/frontend/src/components/Posts.jsx +++ b/frontend/src/components/Posts.jsx @@ -53,10 +53,11 @@ const Posts = () => { withCredentials: true, }); setCommunities(response.data.college); + console.log(response.data.college); setLoading(false); } catch (err) { setLoading(false); - alert("Error fetching communities"); + console.error("Error fetching communities:", err); } }; // const fetchPosts = async () => { @@ -113,7 +114,10 @@ const Posts = () => { return ( - + {communities.length>0 && ( + + )} +