From ae79b5c95fbef6665b91b1728f47155f48799f65 Mon Sep 17 00:00:00 2001 From: disvid Date: Fri, 10 Jan 2025 23:54:23 +0530 Subject: [PATCH 1/6] added google oauth --- SAMPLE.env.local | 1 - app/(components)/Nav.jsx | 54 +++- app/api/Tickets/[id]/route.js | 51 +++- app/api/auth/[...nextauth]/route.js | 21 ++ app/auth/signin/page.jsx | 32 +++ app/layout.jsx | 21 +- app/metadate.js | 6 + app/page.jsx | 20 +- package-lock.json | 409 +++++++++++++++++++++------- package.json | 7 +- public/googlelogo.png | Bin 0 -> 2420 bytes 11 files changed, 490 insertions(+), 132 deletions(-) delete mode 100644 SAMPLE.env.local create mode 100644 app/api/auth/[...nextauth]/route.js create mode 100644 app/auth/signin/page.jsx create mode 100644 app/metadate.js create mode 100644 public/googlelogo.png diff --git a/SAMPLE.env.local b/SAMPLE.env.local deleted file mode 100644 index 062362e..0000000 --- a/SAMPLE.env.local +++ /dev/null @@ -1 +0,0 @@ -MONGODB_URI=mongodb+srv://yourUSER:yourPASSWORD@cluster0.ukunedo.mongodb.net/MondayClone \ No newline at end of file diff --git a/app/(components)/Nav.jsx b/app/(components)/Nav.jsx index b303519..aa35d85 100644 --- a/app/(components)/Nav.jsx +++ b/app/(components)/Nav.jsx @@ -1,12 +1,15 @@ -"use client" +"use client"; + import { faHome, faTicket } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import Link from "next/link"; -import React, { useState } from 'react'; +import React, { useState } from "react"; import { usePathname } from "next/navigation"; +import { useSession, signOut } from "next-auth/react"; const Nav = () => { - const currentPath = usePathname() + const currentPath = usePathname(); + const { data: session } = useSession(); const isActive = (href) => currentPath === href; @@ -14,18 +17,31 @@ const Nav = () => { const showTooltip = (content) => setTooltip(content); const hideTooltip = () => setTooltip(null); + return ( ); diff --git a/app/api/Tickets/[id]/route.js b/app/api/Tickets/[id]/route.js index c1e47e3..dea2a76 100644 --- a/app/api/Tickets/[id]/route.js +++ b/app/api/Tickets/[id]/route.js @@ -1,14 +1,36 @@ import Ticket from "@/app/models/Ticket"; import { NextResponse } from "next/server"; +import { getServerSession } from "next-auth/next"; +import { authOptions } from "@/app/api/auth/[...nextauth]/route"; export async function GET(request, { params }) { - const { id } = params; + const session = await getServerSession(authOptions); + if (!session) { + return NextResponse.json( + { message: "Unauthorized access" }, + { status: 401 } + ); + } - const foundTicket = await Ticket.findOne({ _id: id }); - return NextResponse.json({ foundTicket }, { status: 200 }); + const { id } = params; + try { + const foundTicket = await Ticket.findOne({ _id: id }); + return NextResponse.json({ foundTicket }, { status: 200 }); + } catch (error) { + console.error(error); + return NextResponse.json({ message: "Error", error }, { status: 500 }); + } } export async function PUT(req, { params }) { + const session = await getServerSession(authOptions); + if (!session) { + return NextResponse.json( + { message: "Unauthorized access" }, + { status: 401 } + ); + } + try { const { id } = params; @@ -16,13 +38,15 @@ export async function PUT(req, { params }) { const ticketData = body.formData; const existingTicket = await Ticket.findById(id); - const updateTicketData = await Ticket.findByIdAndUpdate(id, { - ...ticketData, - }); if (existingTicket.status !== "not started") { const { title, description, category, priority } = ticketData; - if (title !== existingTicket.title || description !== existingTicket.description || category !== existingTicket.category || priority !== existingTicket.priority) { + if ( + title !== existingTicket.title || + description !== existingTicket.description || + category !== existingTicket.category || + priority !== existingTicket.priority + ) { return NextResponse.json( { message: "Cannot edit fields once the status is not 'not started'" }, { status: 400 } @@ -30,21 +54,30 @@ export async function PUT(req, { params }) { } } + await Ticket.findByIdAndUpdate(id, { ...ticketData }); return NextResponse.json({ message: "Ticket updated" }, { status: 200 }); } catch (error) { - console.log(error); + console.error(error); return NextResponse.json({ message: "Error", error }, { status: 500 }); } } export async function DELETE(req, { params }) { + const session = await getServerSession(authOptions); + if (!session) { + return NextResponse.json( + { message: "Unauthorized access" }, + { status: 401 } + ); + } + try { const { id } = params; await Ticket.findByIdAndDelete(id); return NextResponse.json({ message: "Ticket Deleted" }, { status: 200 }); } catch (error) { - console.log(error); + console.error(error); return NextResponse.json({ message: "Error", error }, { status: 500 }); } } diff --git a/app/api/auth/[...nextauth]/route.js b/app/api/auth/[...nextauth]/route.js new file mode 100644 index 0000000..5949e2d --- /dev/null +++ b/app/api/auth/[...nextauth]/route.js @@ -0,0 +1,21 @@ +import NextAuth from "next-auth"; +import GoogleProvider from "next-auth/providers/google"; + +export const authOptions = { + providers: [ + GoogleProvider({ + clientId: process.env.GOOGLE_CLIENT_ID, + clientSecret: process.env.GOOGLE_CLIENT_SECRET, + }), + ], + callbacks: { + async session({ session, token }) { + session.user.id = token.sub; // Attach user ID to the session + return session; + }, + }, + secret: process.env.NEXTAUTH_SECRET, +}; + +const handler = NextAuth(authOptions); +export { handler as GET, handler as POST }; diff --git a/app/auth/signin/page.jsx b/app/auth/signin/page.jsx new file mode 100644 index 0000000..b71b14e --- /dev/null +++ b/app/auth/signin/page.jsx @@ -0,0 +1,32 @@ +"use client"; + +import React from "react"; +import { signIn } from "next-auth/react"; // Import the signIn function from next-auth + +const SignInPage = () => { + // Trigger Google OAuth sign-in + const handleGoogleSignIn = () => { + signIn("google", { callbackUrl: "/" }); // Redirect to home page after successful sign-in + }; + + return ( +
+
+

Sign In

+ +
+
+ ); +}; + +export default SignInPage; diff --git a/app/layout.jsx b/app/layout.jsx index 3e36824..e313844 100644 --- a/app/layout.jsx +++ b/app/layout.jsx @@ -1,6 +1,9 @@ +"use client"; // Mark this as a Client Component + import Nav from "./(components)/Nav"; import "./globals.css"; import { Inter } from "next/font/google"; +import { SessionProvider } from "next-auth/react"; import { config } from "@fortawesome/fontawesome-svg-core"; import "@fortawesome/fontawesome-svg-core/styles.css"; @@ -9,22 +12,18 @@ config.autoAddCss = false; const inter = Inter({ subsets: ["latin"] }); -export const metadata = { - title: "Ticket System", - description: "Creating a functional ticketing system.", -}; - export default function RootLayout({ children }) { return ( -
- ); diff --git a/app/api/Tickets/[id]/route.js b/app/api/Tickets/[id]/route.js index 2fdfbd8..c1e47e3 100644 --- a/app/api/Tickets/[id]/route.js +++ b/app/api/Tickets/[id]/route.js @@ -47,4 +47,4 @@ export async function DELETE(req, { params }) { console.log(error); return NextResponse.json({ message: "Error", error }, { status: 500 }); } -} \ No newline at end of file +} diff --git a/app/layout.jsx b/app/layout.jsx index e148785..af8b013 100644 --- a/app/layout.jsx +++ b/app/layout.jsx @@ -1,5 +1,4 @@ "use client"; - import Nav from "./(components)/Nav"; import "./globals.css"; import { Inter } from "next/font/google"; @@ -11,6 +10,11 @@ config.autoAddCss = false; const inter = Inter({ subsets: ["latin"] }); +const metadata = { + title: "Ticket System", + description: "Creating a functional ticketing system.", +}; + export default function RootLayout({ children }) { return ( @@ -18,7 +22,7 @@ export default function RootLayout({ children }) {