diff --git a/src/app/api/auth/[...nextauth]/route.ts b/src/app/api/auth/[...nextauth]/route.ts index caeb954..5616d03 100644 --- a/src/app/api/auth/[...nextauth]/route.ts +++ b/src/app/api/auth/[...nextauth]/route.ts @@ -1,20 +1,18 @@ import NextAuth from "next-auth" -import { getAuthProviders } from "../../../helpers/providers"; +import { getAuthProviders } from "../../../helpers/providers" const handler = NextAuth({ providers: getAuthProviders(), - callbacks: { async jwt({ token, user, account }) { if (user && account) { - token.id = user.id; - token.provider = account.provider; - token.accessToken = account.access_token; + token.id = user.id + token.provider = account.provider + token.accessToken = account.access_token } - return token; + return token }, }, -}); - +}) export { handler as GET, handler as POST } diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 33f8d97..e651b45 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -12,29 +12,29 @@ const menuItems = ["Nivelamento", "Autoestudo"]; const inter = Inter({ subsets: ["latin"] }); -export const session = async () => await getServerSession() - export const metadata: Metadata = { title: "E-acelera - Plataforma de Estudo para Desenvolvedores", description: "O E-acelera é uma plataforma inovadora que faz parte do programa Aceleradora Ágil. A plataforma oferece nivelamentos e desafios para desenvolvedores aprimorarem suas habilidades em programação.", }; -export default function RootLayout({ +export default async function RootLayout({ children, }: Readonly<{ children: React.ReactNode; }>) { + const session = await getServerSession() + return ( - - - - - {children} - + + + + + {children} + diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx index 5e48848..1bd97c6 100644 --- a/src/app/login/page.tsx +++ b/src/app/login/page.tsx @@ -1,43 +1,13 @@ "use client" - import { CardLogin } from "@/components/CardLogin" import { LayoutPage } from "@/components/PageElements/LayoutPage" -import { useSession } from "next-auth/react" -import { useRouter, useSearchParams } from "next/navigation" -import { Suspense, useEffect } from "react" -import { Loading } from "@/components/Loading" - -function LoginContent() { - const { data: session, status } = useSession() - const router = useRouter() - const searchParams = useSearchParams() - const callbackUrl = searchParams?.get("callbackUrl") || "/" - - useEffect(() => { - if (status === "authenticated") { - router.push(callbackUrl) - } - }, [status, router, callbackUrl]) - - if (status === "loading") { - return - } +export default function LoginPage() { - if (status === "unauthenticated") { - return ( - - - - ) - } - - return null + return ( + + + + ) } -export default function Login() { - - return (}> - - ) -} diff --git a/src/components/NavBar/WebNavBar/index.test.tsx b/src/components/NavBar/WebNavBar/index.test.tsx index bd398c9..48a1474 100644 --- a/src/components/NavBar/WebNavBar/index.test.tsx +++ b/src/components/NavBar/WebNavBar/index.test.tsx @@ -1,6 +1,6 @@ import '@testing-library/jest-dom' import { render, screen } from '@testing-library/react' -import { WebMenu } from '@/components/NavBar/WebNavBar' +import { WebMenu } from '@/components/NavBar/WebNavBar' import { useSession } from 'next-auth/react' jest.mock('next/image', () => ({ @@ -27,9 +27,9 @@ describe('Testes do botão de Login do componente WebMenu', () => { it('Deve mostrar o botão de login quando não houver sessão', () => { (useSession as jest.Mock).mockReturnValue({ data: null }) - render() + render() - const loginButton = screen.queryByText('LOGIN') + const loginButton = screen.getByRole('button', { name: /login/i }) expect(loginButton).toBeInTheDocument() }) @@ -39,13 +39,17 @@ describe('Testes do botão de Login do componente WebMenu', () => { user: { image: 'url-da-imagem', name: 'Usuário Teste' - } + }, + expires: '2025-01-01T00:00:00Z' } }) - render() + render() - const loginButton = screen.queryByText('LOGIN') + const loginButton = screen.queryByRole('button', { name: /login/i }) expect(loginButton).not.toBeInTheDocument() }) -}) \ No newline at end of file +}) diff --git a/src/components/NavBar/WebNavBar/index.tsx b/src/components/NavBar/WebNavBar/index.tsx index 13ea543..298615b 100644 --- a/src/components/NavBar/WebNavBar/index.tsx +++ b/src/components/NavBar/WebNavBar/index.tsx @@ -17,15 +17,16 @@ import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown" import { useSession, signOut } from "next-auth/react" import { useState } from "react" import LogoutIcon from "@mui/icons-material/Logout" +import { Session } from "next-auth" interface WebMenuProps { list: string[] + session: Session | null } -export const WebMenu: React.FC = ({ list }) => { +export const WebMenu: React.FC = ({ list, session }) => { const router = useRouter() const pathname = usePathname() - const { data: session } = useSession() const [anchorEl, setAnchorEl] = useState(null) const handleOpenMenu = (event: React.MouseEvent) => { diff --git a/src/components/NavBar/index.tsx b/src/components/NavBar/index.tsx index 26b0b10..dc5d16e 100644 --- a/src/components/NavBar/index.tsx +++ b/src/components/NavBar/index.tsx @@ -1,37 +1,19 @@ -"use client"; -import React, { useState } from "react"; -import AppBar from "@mui/material/AppBar"; -import Toolbar from "@mui/material/Toolbar"; -import Container from "@mui/material/Container"; -import { Box, Avatar, Menu, MenuItem, Typography, IconButton, Tooltip } from "@mui/material"; -import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown"; -import { theme } from "../../app/config/theme"; -import { MobileMenu } from "./MobileNavBar"; -import { WebMenu } from "./WebNavBar"; -import { useSession, signOut } from "next-auth/react"; -import LogoutIcon from '@mui/icons-material/Logout'; -import Divider from '@mui/material/Divider'; - +"use client" +import AppBar from "@mui/material/AppBar" +import Toolbar from "@mui/material/Toolbar" +import Container from "@mui/material/Container" +import { Box } from "@mui/material" +import { theme } from "../../app/config/theme" +import { MobileMenu } from "./MobileNavBar" +import { WebMenu } from "./WebNavBar" +import { Session } from "next-auth" interface NavBarProps { - list: string[]; + list: string[] + session: Session | null } - -const ResponsiveAppBar: React.FC = ({ list }) => { - const { data: session } = useSession(); - const [anchorEl, setAnchorEl] = useState(null); - - - const handleOpenMenu = (event: React.MouseEvent) => { - setAnchorEl(event.currentTarget); - }; - - - const handleCloseMenu = () => { - setAnchorEl(null); - }; - +const ResponsiveAppBar: React.FC = ({ list, session }) => { return ( = ({ list }) => { disableGutters sx={{ display: "flex", alignItems: "center" }} > - - - + - ); -}; + ) +} -export default ResponsiveAppBar; \ No newline at end of file +export default ResponsiveAppBar \ No newline at end of file diff --git a/src/middleware.ts b/src/middleware.ts new file mode 100644 index 0000000..feb2167 --- /dev/null +++ b/src/middleware.ts @@ -0,0 +1,23 @@ +import { NextResponse } from "next/server" +import type { NextRequest } from "next/server" + +export async function middleware(request: NextRequest) { + const sessionToken = + request.cookies.get("next-auth.session-token") || + request.cookies.get("__Secure-next-auth.session-token") + + const callbackUrl = + new URLSearchParams(request.nextUrl.search).get("callbackUrl") || "/" + + const parsedUrl = new URL(callbackUrl, request.url) + + if (request.nextUrl.pathname.startsWith("/login") && sessionToken) { + return NextResponse.redirect(parsedUrl) + } + + return NextResponse.next() +} + +export const config = { + matcher: ["/login"], +} diff --git a/src/types/next-auth.d.ts b/src/types/next-auth.d.ts new file mode 100644 index 0000000..e763ca8 --- /dev/null +++ b/src/types/next-auth.d.ts @@ -0,0 +1,13 @@ +import NextAuth, { DefaultSession } from "next-auth"; + +declare module "next-auth" { + /** + * Returned by `useSession`, `getSession` and received as a prop on the `SessionProvider` React Context + */ + interface Session { + user: { + /** Oauth access token */ + token?: accessToken; + } & DefaultSession["user"]; + } +} \ No newline at end of file