diff --git a/frontend-next/src/app/api/login/route.js b/frontend-next/src/app/api/login/route.js index 8005225..55d9967 100644 --- a/frontend-next/src/app/api/login/route.js +++ b/frontend-next/src/app/api/login/route.js @@ -1,121 +1,63 @@ -// src/app/api/login/route.js -import { auth } from "firebase-admin"; import { cookies, headers } from "next/headers"; import { NextResponse } from "next/server"; -import { customInitApp } from "../../../lib/firebase-admin"; +// Firebase Imports +import { auth } from "firebase-admin"; import { signInWithEmailAndPassword } from "firebase/auth"; +// Lib Imports import { auth as authConfig } from "../../../lib/firebase-config"; +import { customInitApp } from "../../../lib/firebase-admin"; -// Init the Firebase SDK every time the server is called +// Needs to "init" on each call to the API customInitApp(); -async function handleBearerToken(authorization) { - if (authorization?.startsWith("Bearer ")) { - const idToken = authorization.split("Bearer ")[1]; - const decodedToken = await auth().verifyIdToken(idToken); - - if (decodedToken) { - const expiresIn = 5 * 60 * 1000; - const sessionCookie = await auth().createSessionCookie(idToken, { - expiresIn, - }); - const options = { - name: "session", - value: sessionCookie, - maxAge: expiresIn, - httpOnly: true, - secure: true, - }; - - cookies().set(options); - return NextResponse.json({}, { status: 200 }); - } - } -} - +// Login with Email/Password async function handleEmailAndPassword(email, password) { try { - const userCredential = await signInWithEmailAndPassword( - authConfig, - email, - password - ); - - const user = userCredential.user; - const authorization = user.accessToken; - - if (authorization) { - const idToken = authorization; - const decodedToken = await auth().verifyIdToken(idToken); - - if (decodedToken) { - const expiresIn = 5 * 60 * 1000; - const sessionCookie = await auth().createSessionCookie(idToken, { - expiresIn, - }); - const options = { + var userCredential = await signInWithEmailAndPassword(authConfig,email,password); + if (userCredential.user.accessToken) { + const token = await auth().verifyIdToken(userCredential.user.accessToken); + if (token) { + var expiresIn = 300000 + var sessionCookie = await auth().createSessionCookie(userCredential.user.accessToken, {expiresIn,}); + var options = { name: "session", value: sessionCookie, - maxAge: expiresIn, + maxAge: expiresIn, // 5 mins httpOnly: true, secure: true, }; - cookies().set(options); return NextResponse.json({ options }, { status: 200 }); } } } catch (error) { - console.error("Authentication error:", error); - - let errorMessage = "Authentication failed"; - - // Check Firebase authentication error codes and handle them accordingly - if (error.code === "auth/wrong-password") { - errorMessage = "Wrong password"; - } else if (error.code === "auth/user-not-found") { - errorMessage = "User not found"; - } else if (error.code === "auth/invalid-email") { - errorMessage = "Invalid email address"; - } - - return NextResponse.json({ error: errorMessage }, { status: 401 }); + return NextResponse.json({ error: error.code }, { status: 401 }); } } -export async function POST(request, response) { +// Handles POST requests (login requests) +export async function POST(req, res) { try { - const { email, password } = await request?.json(); - - if (!email || !password) { - const authorization = headers().get("Authorization"); - return await handleBearerToken(authorization); - } else { - return await handleEmailAndPassword(email, password); - } + var { email, password } = await req?.json() + return await handleEmailAndPassword(email, password); // need session token } catch (error) { - console.error(error); - return NextResponse.json( - { error: "Internal Server Error" }, - { status: 500 } - ); + return NextResponse.json({ error: "Internal Server Error" },{ status: 500 }); } } -export async function GET(request) { - const session = cookies().get("session")?.value || ""; - +// Handles GET requests (is session still valid requests) +export async function GET(req) { + var session = cookies().get("session")?.value || ""; //Validate if the cookie exist in the request if (!session) { return NextResponse.json({ isLogged: false }, { status: 401 }); - } - - //Use Firebase Admin to validate the session cookie - const decodedClaims = await auth().verifySessionCookie(session, true); - - if (!decodedClaims) { - return NextResponse.json({ isLogged: false }, { status: 401 }); - } - - return NextResponse.json({ isLogged: true }, { status: 200 }); + } else { + // Validate session cookie + var validation = await auth().verifySessionCookie(session, true); + if (!validation) { + return NextResponse.json({ isLogged: false }, { status: 401 }); + } else { + return NextResponse.json({ isLogged: true }, { status: 200 }); + } + } } \ No newline at end of file diff --git a/frontend-next/src/app/api/register/route.js b/frontend-next/src/app/api/register/route.js index 12d3c65..0dba943 100644 --- a/frontend-next/src/app/api/register/route.js +++ b/frontend-next/src/app/api/register/route.js @@ -6,31 +6,19 @@ import { NextResponse } from "next/server"; // Function to register a new user using Firebase Authentication export async function registerUser(email, password) { try { - const userCredential = await createUserWithEmailAndPassword( - auth, - email, - password - ); - - const user = userCredential.user; - console.log("User registered:", user); - + var userCredential = await createUserWithEmailAndPassword(auth,email,password); // You can perform additional actions after successful registration, if needed. - - return { success: true, user }; + return { success: true, userCredential }; } catch (error) { - console.error("Error during registration:", error); return { success: false, error: error.message }; } } // POST request handler -export async function POST(request, response) { +export async function POST(req, res) { try { // Extract email and password from the request body - const { email, password } = await request?.json(); - - console.log(email); + var { email, password } = await req?.json(); // Check if email and password are provided if (!email || !password) { return NextResponse.json( @@ -40,27 +28,15 @@ export async function POST(request, response) { } // Register the user - const registrationResult = await registerUser(email, password); - - if (registrationResult.success) { - // Registration successful - return NextResponse.json({ - message: "Registration successful.", - user: registrationResult.user, - }); - } else { - // Registration failed, return an error response - return NextResponse.json( - { error: registrationResult.error }, - { status: 500 } - ); + try { + var userCredential = await createUserWithEmailAndPassword(auth,email,password); + return NextResponse.json({message: "Registration successful.",user: userCredential.user,}); + } catch { + return NextResponse.json({ error: registrationResult.error },{ status: 500 }); } + } catch (error) { // Handle unexpected errors - console.error("Error during registration:", error); - return NextResponse.json( - { error: "Internal Server Error" }, - { status: 500 } - ); + return NextResponse.json({ error: "Internal Server Error" },{ status: 500 }); } } \ No newline at end of file diff --git a/frontend-next/src/app/api/signout/route.js b/frontend-next/src/app/api/signout/route.js new file mode 100644 index 0000000..333092a --- /dev/null +++ b/frontend-next/src/app/api/signout/route.js @@ -0,0 +1,11 @@ +import { cookies } from "next/headers"; +import { NextResponse } from "next/server"; + +export async function POST(req) { + cookies().set({ + name: "session", + value: "", + maxAge: -1, + }); + return NextResponse.json({}, { status: 200 }); +} \ No newline at end of file diff --git a/frontend-next/src/app/login/page.js b/frontend-next/src/app/login/page.js index 443cb0a..5844183 100644 --- a/frontend-next/src/app/login/page.js +++ b/frontend-next/src/app/login/page.js @@ -6,32 +6,20 @@ import { useForm } from "react-hook-form"; import { useRouter } from "next/navigation"; import "../globals.css" -function Home() { - const router = useRouter(); - const { register, handleSubmit } = useForm(); - const Login = async (data) => { - try { - const res = await fetch("/api/login", { - method: "POST", - body: JSON.stringify(data ? data : {}), - }); +function Login() { + var router = useRouter(); + var { register, handleSubmit } = useForm(); + async function Login(data) { + const res = await fetch("/api/login", { + method: "POST", + body: JSON.stringify(data ? data : {}), + }); - if (res.ok) { - const result = await res.json(); - console.log("Logged In"); - router.push("/room/success"); - } else { - const errorResponse = await res.json(); - console.error(errorResponse); - } - } catch (error) { - console.error("Error during login:", error); + if (res.ok) { + router.push("/room/success"); } - }; - const onSubmit = (data) => { - //setError(""); // Clear the error state on successful registration - Login(data); - }; + } + return (
@@ -42,7 +30,7 @@ function Home() {

Login

-
+

@@ -54,4 +42,4 @@ function Home() { ) } -export default Home; \ No newline at end of file +export default Login; \ No newline at end of file diff --git a/frontend-next/src/app/page.js b/frontend-next/src/app/page.js index 7b862e0..690a8ad 100644 --- a/frontend-next/src/app/page.js +++ b/frontend-next/src/app/page.js @@ -1,4 +1,5 @@ -function Home() { +async function Home() { + return (
@@ -11,8 +12,8 @@ function Home() { Chat with friends!
- - + +
diff --git a/frontend-next/src/app/register/page.js b/frontend-next/src/app/register/page.js index d7184d7..14e72e7 100644 --- a/frontend-next/src/app/register/page.js +++ b/frontend-next/src/app/register/page.js @@ -3,34 +3,20 @@ import { useRouter } from "next/navigation"; import { useForm } from "react-hook-form"; import "../globals.css" -function Home() { - const {register, handleSubmit } = useForm() - const router = useRouter(); - const onSubmit = (data) => { - //setError(""); // Clear the error state on successful registration - RegisterWithEmail(data); - }; - - const RegisterWithEmail = async (data) => { - try { - const res = await fetch("/api/register", { - method: "POST", - body: JSON.stringify(data ? data : {}), - }); - - if (res.ok) { - const result = await res.json(); - console.log("Created"); - router.push("/login"); - } else { - const errorResponse = await res.json(); - console.error(errorResponse); - } - } catch (error) { - console.error("Error during registration:", error); - //setError("An unexpected error occurred. Please try again."); // Set the error state +function Register() { + var {register, handleSubmit } = useForm() + var router = useRouter(); + + async function RegisterWithEmail(data) { + const res = await fetch("/api/register", { + method: "POST", + body: JSON.stringify(data ? data : {}), + }); + if (res.ok) { + router.push("/login"); } - }; + } + return (
@@ -41,7 +27,7 @@ function Home() {

Register

- +

@@ -53,4 +39,4 @@ function Home() { ) } -export default Home; \ No newline at end of file +export default Register; \ No newline at end of file diff --git a/frontend-next/src/lib/firebase-config.js b/frontend-next/src/lib/firebase-config.js index 6f053be..4a5abcf 100644 --- a/frontend-next/src/lib/firebase-config.js +++ b/frontend-next/src/lib/firebase-config.js @@ -1,19 +1,10 @@ -// lib/firebase-config.js -import { initializeApp } from "firebase/app"; -import { getApps, getApp } from "firebase/app"; -import { OAuthProvider, getAuth } from "firebase/auth"; -import { GoogleAuthProvider } from "firebase/auth"; +import { initializeApp, getApps, getApp } from "firebase/app"; +import { getAuth } from "firebase/auth"; import firebaseConfigFile from "../../../firebase-config" -const firebaseConfig = firebaseConfigFile; +var firebaseConfig = firebaseConfigFile; -const app = getApps().length > 0 ? getApp() : initializeApp(firebaseConfig); -const auth = getAuth(app); -const provider = new GoogleAuthProvider(); +var app = getApps().length > 0 ? getApp() : initializeApp(firebaseConfig); +var auth = getAuth(app); -// Prevent automatic account selection -provider.setCustomParameters({ - prompt: "select_account", -}); - -export { auth, provider }; \ No newline at end of file +export { auth }; \ No newline at end of file diff --git a/frontend-next/src/middleware.js b/frontend-next/src/middleware.js new file mode 100644 index 0000000..12d3e1e --- /dev/null +++ b/frontend-next/src/middleware.js @@ -0,0 +1,26 @@ +// src/middleware.js +import { NextResponse } from "next/server"; + +export async function middleware(req, res) { + const session = req.cookies.get("session"); + // Login if not logged in + if (!session) { + return NextResponse.redirect(new URL("/login", req.url)); + } + //Call the authentication endpoint + const responseAPI = await fetch("http://localhost:3000/api/login", { + headers: { + Cookie: `session=${session?.value}`, + }, + }); + // Login if unauthorized + if (responseAPI.status !== 200) { + return NextResponse.redirect(new URL("/login", req.url)); + } + return NextResponse.next(); +} + +//Add your protected routes +export const config = { + matcher: ["/room/:path*"], +}; \ No newline at end of file