-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #22 from kovarike/website-feature
set api
- Loading branch information
Showing
18 changed files
with
800 additions
and
102 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
// "use setver" | ||
// import { IncomingMessage } from 'http'; | ||
// import { NextApiRequest, NextApiResponse } from 'next'; | ||
// import cookies from 'next-cookies'; | ||
// import jwt, { JwtPayload } from 'jsonwebtoken'; | ||
// import { v4 as uuidv4 } from 'uuid'; | ||
|
||
// const secret = process.env.JWT_SECRET || uuidv4(); // Gerando UUID se não houver segredo no .env | ||
|
||
// interface AuthPayload extends JwtPayload { | ||
// userId: string; | ||
// email: string; | ||
// } | ||
|
||
|
||
// export const isAuthenticated = (req: IncomingMessage): AuthPayload | null => { | ||
// const allCookies = cookies({ req }); // Usa next-cookies para obter todos os cookies | ||
// const token = allCookies['auth-token'] | ||
|
||
// if (!token) return null; | ||
|
||
// try { | ||
// return jwt.verify(token, secret) as AuthPayload; | ||
// } catch (error) { | ||
// console.error('JWT verification failed:', error); | ||
// return null; | ||
// } | ||
// }; | ||
|
||
|
||
|
||
|
||
import { NextApiRequest, NextApiResponse } from 'next'; | ||
import jwt from 'jsonwebtoken'; | ||
import { v4 as uuidv4 } from 'uuid'; | ||
|
||
const secret = process.env.JWT_SECRET || uuidv4(); | ||
|
||
interface AuthPayload { | ||
userId: string; | ||
email: string; | ||
} | ||
|
||
export const login = async (req: NextApiRequest, res: NextApiResponse) => { | ||
const { email, password } = req.body; | ||
|
||
if (email === '[email protected]' && password === 'password123') { | ||
const token = jwt.sign({ email, userId: '1' }, secret, { expiresIn: '1h' }); | ||
res.setHeader('Set-Cookie', `auth-token=${token}; Path=/; HttpOnly`); | ||
return res.status(200).json({ success: true }); | ||
} else { | ||
return res.status(401).json({ success: false, message: 'Invalid credentials' }); | ||
} | ||
}; | ||
|
||
export const isAuthenticated = (req: NextApiRequest): AuthPayload | null => { | ||
const token = req.cookies['auth-token']; | ||
if (!token) return null; | ||
|
||
try { | ||
return jwt.verify(token, secret) as AuthPayload; | ||
} catch (error) { | ||
console.error('Invalid token:', error); | ||
return null; | ||
} | ||
}; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// middleware.ts | ||
import { NextResponse } from 'next/server'; | ||
import type { NextRequest } from 'next/server'; | ||
import jwt from 'jsonwebtoken'; | ||
import { v4 as uuidv4 } from 'uuid'; | ||
|
||
const secret = process.env.JWT_SECRET || uuidv4(); // Gera um UUID se o segredo não for definido | ||
|
||
export function middleware(req: NextRequest) { | ||
const token = req.cookies.get('auth-token')?.value; | ||
|
||
if (!token) { | ||
return NextResponse.redirect(new URL('/login', req.url)); | ||
} | ||
|
||
try { | ||
jwt.verify(token, secret); | ||
return NextResponse.next(); // Usuário autenticado, permite continuar | ||
} catch (error) { | ||
return NextResponse.redirect(new URL('/login', req.url)); // Redireciona se o JWT for inválido | ||
} | ||
} | ||
|
||
export const config = { | ||
matcher: '/admin/:path*', // Aplica a middleware apenas em rotas que começam com /admin | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// pages/api/login.ts | ||
import { NextApiRequest, NextApiResponse } from 'next'; | ||
import jwt from 'jsonwebtoken'; | ||
import cookie from 'cookie'; | ||
|
||
const secret = process.env.JWT_SECRET || 'seu-segredo-super-seguro'; | ||
|
||
export default function handler(req: NextApiRequest, res: NextApiResponse) { | ||
if (req.method === 'POST') { | ||
const { id, password } = req.body; | ||
|
||
// Validação simples (substitua com sua lógica de autenticação) | ||
if (id === '[email protected]' && password === '123456') { | ||
// Gerar um token JWT | ||
const token = jwt.sign({ id }, secret, { expiresIn: '1h' }); | ||
|
||
// Configurar o token nos cookies | ||
res.setHeader( | ||
'Set-Cookie', | ||
cookie.serialize('auth-token', token, { | ||
httpOnly: true, | ||
secure: process.env.NODE_ENV === 'production', | ||
maxAge: 3600, | ||
sameSite: 'strict', | ||
path: '/', | ||
}) | ||
); | ||
|
||
return res.status(200).json({ message: 'Login successful' }); | ||
} | ||
|
||
return res.status(401).json({ message: 'Invalid credentials' }); | ||
} | ||
|
||
return res.status(405).json({ message: 'Method not allowed' }); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,86 @@ | ||
import { Container } from "@/components/container"; | ||
import { ContainerFull } from "@/components/containerfull"; | ||
import { Doilog } from "@/components/dailog"; | ||
import { Footer } from "@/components/footer"; | ||
import { Header } from "@/components/header"; | ||
import { Login } from "@/components/login"; | ||
// import { GetServerSideProps } from 'next'; | ||
|
||
// import { Container } from "@/components/container"; | ||
// import { ContainerFull } from "@/components/containerfull"; | ||
// import { Footer } from "@/components/footer"; | ||
// import { Header } from "@/components/header"; | ||
// import { isAuthenticated } from '@/api/lib/alth'; | ||
|
||
|
||
|
||
// export default function PageAdmin() { | ||
// return ( | ||
// <> | ||
// <ContainerFull> | ||
// <Header /> | ||
// <Container> | ||
// <h2 className="text-center">Administração</h2> | ||
// <form action="#" className="mx-auto flex items-center flex-col"> | ||
// <input className="w-60 p-2 my-2 mx-0 rounded-md border-[1px] border-[#ccc]" type="text" name="postTitle" placeholder="Título do Post" required /> | ||
// <textarea className="w-full p-2 my-2 mx-0 rounded-md border-[1px] border-[#ccc] resize-none" name="postContent" rows={10} placeholder="Conteúdo do Post" required></textarea> | ||
// <button className="w-20 p-2 text-gray-600 bg-algorithms-color/20 hover:bg-algorithms-color/45 rounded-md text-center cursor-pointer" type="submit">Publicar</button> | ||
// </form> | ||
|
||
// </Container> | ||
// <Footer /> | ||
// </ContainerFull> | ||
// </> | ||
// ); | ||
// } | ||
|
||
// export const getServerSideProps: GetServerSideProps = async (context) => { | ||
// const user = isAuthenticated(context.req); | ||
|
||
// if (!user) { | ||
// return { | ||
// redirect: { | ||
// destination: '/login', | ||
// permanent: false, | ||
// }, | ||
// }; | ||
// } | ||
|
||
// return { | ||
// props: {}, | ||
// }; | ||
// }; | ||
|
||
|
||
// src/app/admin/page.tsx | ||
'use client'; | ||
|
||
import { useEffect } from 'react'; | ||
import { useRouter } from 'next/navigation'; // Para redirecionar no App Router | ||
import cookies from 'js-cookie'; | ||
import jwt from 'jsonwebtoken'; | ||
|
||
export default function PageAdmin() { | ||
const router = useRouter(); | ||
|
||
useEffect(() => { | ||
const token = String(cookies.get('auth-token')); | ||
const secret = process.env.NEXT_PUBLIC_JWT_SECRET || 'default-secret'; | ||
|
||
if (!token) { | ||
router.push('/login'); | ||
} | ||
|
||
try { | ||
jwt.verify(token, secret); | ||
} catch (error) { | ||
console.error('Invalid token, redirecting...'); | ||
router.push('/login'); | ||
} | ||
}, [router]); | ||
|
||
return ( | ||
<> | ||
<ContainerFull> | ||
<Header /> | ||
<Container> | ||
<h2 className="text-center">Administração</h2> | ||
<form action="#" className="mx-auto flex items-center flex-col"> | ||
<input className="w-60 p-2 my-2 mx-0 rounded-md border-[1px] border-[#ccc]" type="text" name="postTitle" placeholder="Título do Post" required /> | ||
<textarea className="w-full p-2 my-2 mx-0 rounded-md border-[1px] border-[#ccc] resize-none" name="postContent" rows={10} placeholder="Conteúdo do Post" required></textarea> | ||
<button className="w-20 p-2 text-gray-600 bg-algorithms-color/20 hover:bg-algorithms-color/45 rounded-md text-center cursor-pointer" type="submit">Publicar</button> | ||
</form> | ||
|
||
</Container> | ||
<Doilog> | ||
<Login /> | ||
</Doilog> | ||
<Footer /> | ||
</ContainerFull> | ||
<h2 className="text-center">Administração</h2> | ||
<form action="#" className="mx-auto flex items-center flex-col"> | ||
<input className="w-60 p-2 my-2 mx-0 rounded-md border-[1px] border-[#ccc]" type="text" name="postTitle" placeholder="Título do Post" required /> | ||
<textarea className="w-full p-2 my-2 mx-0 rounded-md border-[1px] border-[#ccc] resize-none" name="postContent" rows={10} placeholder="Conteúdo do Post" required></textarea> | ||
<button className="w-20 p-2 text-gray-600 bg-algorithms-color/20 hover:bg-algorithms-color/45 rounded-md text-center cursor-pointer" type="submit">Publicar</button> | ||
</form> | ||
</> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
// pages/api/login.ts | ||
import type { NextApiRequest, NextApiResponse } from 'next'; | ||
import { login } from '@/api/lib/alth'; | ||
|
||
export default async function handler(req: NextApiRequest, res: NextApiResponse) { | ||
if (req.method === 'POST') { | ||
return await login(req, res); | ||
} else { | ||
return res.status(405).json({ message: 'Method not allowed' }); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import type { NextApiRequest, NextApiResponse } from 'next'; | ||
import { isAuthenticated } from '@/api/lib/alth'; | ||
|
||
export default function handler(req: NextApiRequest, res: NextApiResponse) { | ||
const user = isAuthenticated(req); | ||
|
||
if (!user) { | ||
return res.status(401).json({ message: 'Unauthorized' }); | ||
} | ||
|
||
return res.status(200).json({ user }); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
"use client" | ||
|
||
import { useState } from "react"; | ||
import { useRouter } from "next/navigation"; | ||
import { Doilog } from "@/components/dailog"; | ||
import { Container } from "@/components/container"; | ||
|
||
interface DataProps extends FormData { | ||
id: string, | ||
password: string | ||
} | ||
|
||
|
||
export default function Home() { | ||
const [id, setId] = useState(''); | ||
const [password, setPassword] = useState(''); | ||
const router = useRouter(); | ||
|
||
const handleLogin = async (data: DataProps) => { | ||
setId(data.id) | ||
setPassword(data.password) | ||
|
||
const response = await fetch('/api/routers/login', { | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
}, | ||
body: JSON.stringify({ id, password }), | ||
}); | ||
|
||
if (response.ok) { | ||
router.push('/admin'); // Redireciona para a página de admin após o login bem-sucedido. | ||
} else { | ||
alert('Invalid credentials'); | ||
} | ||
}; | ||
|
||
return ( | ||
<Doilog> | ||
<Container> | ||
<div className="flex flex-col items-center space-y-5 mx-auto" > | ||
<h2 className="text-center font-algorithms-font font-semibold text-lg">Login</h2> | ||
<form action="#" className="mx-auto flex items-center flex-col space-y-5" > | ||
<input className="w-60 p-2 my-2 mx-0 rounded-md border-[1px] border-[#ccc]" type="text" name="id" placeholder="Id" required /> | ||
<input className="w-60 p-2 my-2 mx-0 rounded-md border-[1px] border-[#ccc]" type="password" name="password" placeholder="Password" required /> | ||
<button className="w-20 p-2 text-gray-600 bg-algorithms-color/20 hover:bg-algorithms-color/45 rounded-md text-center cursor-pointer" type="submit">Entrar</button> | ||
</form> | ||
</div> | ||
</Container> | ||
</Doilog> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
"use server" | ||
import { v4 as uuidv4 } from "uuid"; | ||
export const id = uuidv4(); |
Oops, something went wrong.