login endpoint authentication now working
This commit is contained in:
parent
fff780922d
commit
9c2148076b
|
@ -1,13 +1,16 @@
|
|||
"use server"
|
||||
import prisma from 'app/lib/db';
|
||||
import { jwtVerify, JWTPayload, decodeJwt } from 'jose';
|
||||
import { jwtVerify, JWTPayload, decodeJwt, SignJWT } from 'jose';
|
||||
import { cookies } from 'next/headers';
|
||||
|
||||
import { loginSchema, LoginSchema } from 'app/login/schema';
|
||||
import { NextResponse } from 'next/server';
|
||||
import { TextEncoder } from 'util';
|
||||
|
||||
export async function getJWTSecretKey() {
|
||||
const secret = process.env.JWT_SECRET
|
||||
if (!secret) throw new Error("There is no JWT secret key")
|
||||
return new TextEncoder().encode(secret)
|
||||
const enc: Uint8Array = new TextEncoder().encode(secret)
|
||||
return enc
|
||||
}
|
||||
|
||||
export async function verifyJwt(token: string): Promise<JWTPayload | null> {
|
||||
|
@ -76,25 +79,20 @@ export async function setUserDataCookie(userData) {
|
|||
})
|
||||
}
|
||||
|
||||
export type UserLogin = {
|
||||
email: string,
|
||||
password: string
|
||||
}
|
||||
|
||||
export async function login(userLogin: UserLogin) {
|
||||
export async function login(userLogin: LoginSchema) {
|
||||
const isSafe = loginSchema.safeParse(userLogin)
|
||||
try {
|
||||
|
||||
if (!isSafe.success) throw new Error("parse failed")
|
||||
const user = await prisma.user.findFirst({ where: { email: userLogin.email } })
|
||||
if (!user) { throw new Error('user does not exist') }
|
||||
if (!user) throw new Error("user does not exist")
|
||||
const bcrypt = require("bcrypt");
|
||||
console.log(`client user: ${JSON.stringify(userLogin)}
|
||||
db user: ${JSON.stringify(user)}`)
|
||||
const passwordIsValid = await bcrypt.compare(userLogin.password, user.password)
|
||||
if (!passwordIsValid) throw new Error('invalid password')
|
||||
//return the user object without the hashed password
|
||||
return { email: user.email, id: user.id }
|
||||
if (!passwordIsValid) throw new Error("password is not valid")
|
||||
return { email: userLogin.email }
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
throw new Error('invalid login or password')
|
||||
throw new Error('login failed')
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { NextResponse, NextRequest } from "next/server";
|
||||
import prisma from "app/lib/db";
|
||||
import { SignJWT } from "jose";
|
||||
|
||||
import { getJWTSecretKey, login, setUserDataCookie } from "../actions";
|
||||
|
@ -13,9 +14,9 @@ const dynamic = 'force-dynamic'
|
|||
|
||||
//POST endpoint
|
||||
export async function POST(request: NextRequest) {
|
||||
const { body } = await request.json()
|
||||
const { email, password } = body
|
||||
const body = await request.json()
|
||||
console.log(`body: ${JSON.stringify(body)}`)
|
||||
const { email, password } = body
|
||||
|
||||
if (!email || !password) {
|
||||
const res = {
|
||||
|
@ -37,7 +38,7 @@ export async function POST(request: NextRequest) {
|
|||
.setProtectedHeader({ alg: 'HS256' })
|
||||
.setIssuedAt()
|
||||
.setExpirationTime('1h')
|
||||
.sign(getJWTSecretKey())
|
||||
.sign(await getJWTSecretKey())
|
||||
|
||||
//make response
|
||||
const res = { success: true }
|
||||
|
|
|
@ -6,28 +6,44 @@ import { toast } from "@/components/ui/use-toast";
|
|||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { login } from "app/api/auth/actions";
|
||||
import { redirect } from "next/navigation";
|
||||
import { loginSchema } from "./schema";
|
||||
import { useRouter } from "next/navigation";
|
||||
|
||||
const formSchema = z.object({
|
||||
email: z.string().email(),
|
||||
password: z.string().min(6)
|
||||
})
|
||||
|
||||
export default function LoginForm() {
|
||||
const form = useForm<z.infer<typeof formSchema>>({
|
||||
resolver: zodResolver(formSchema),
|
||||
const router = useRouter()
|
||||
const form = useForm<z.infer<typeof loginSchema>>({
|
||||
resolver: zodResolver(loginSchema),
|
||||
})
|
||||
|
||||
function onErrors(errors) {
|
||||
toast({
|
||||
title: "WHOOPS",
|
||||
description: JSON.stringify(errors)
|
||||
const onSubmit = form.handleSubmit(async (data) => {
|
||||
// const res = await login(data)
|
||||
// if (res?.error) {
|
||||
// toast({ title: "Whoops!", description: res.error })
|
||||
// form.reset()
|
||||
// } else {
|
||||
// toast({ title: "login successful" })
|
||||
// }
|
||||
const res = await fetch('/api/auth/login', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
})
|
||||
if (res.status === 200) {
|
||||
toast({ title: "login successful!" })
|
||||
router.push('/submission')
|
||||
} else {
|
||||
toast({ title: "login failed!" })
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
return (
|
||||
<Form {...form}>
|
||||
<form action={login}>
|
||||
<form onSubmit={onSubmit}>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="email"
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
import { z } from "zod"
|
||||
export const loginSchema = z.object({
|
||||
email: z.string().email(),
|
||||
password: z.string().min(6)
|
||||
})
|
||||
|
||||
export type LoginSchema = z.infer<typeof loginSchema>
|
|
@ -17,10 +17,9 @@ export default async function(request: NextRequest) {
|
|||
// const url = `${process.env.NEXT_PUBLIC_BASE_URL}/login?redirect=${request.nextUrl.pathname + request.nextUrl.search}`
|
||||
const url = request.nextUrl.clone()
|
||||
url.pathname = "/login"
|
||||
|
||||
if (protectedRoutes.some(pattern => matchesWildcard(request.nextUrl.pathname, pattern))) {
|
||||
const token = request.cookies.get('token')
|
||||
|
||||
console.log(`token: ${JSON.stringify(token)}`)
|
||||
//NOTE - may need to add logic to return 401 for api routes
|
||||
|
||||
if (!token) {
|
||||
|
@ -30,9 +29,9 @@ export default async function(request: NextRequest) {
|
|||
try {
|
||||
//decode and verify jwt cookie
|
||||
const jwtIsVerified = await verifyJwt(token.value)
|
||||
|
||||
if (!jwtIsVerified) {
|
||||
//delete token
|
||||
console.log('could not verify jwt')
|
||||
request.cookies.delete('token')
|
||||
return NextResponse.redirect(url)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue