142 lines
2.5 KiB
TypeScript
142 lines
2.5 KiB
TypeScript
"use server"
|
|
import prisma from 'app/lib/db';
|
|
import { jwtVerify, JWTPayload, decodeJwt, SignJWT } from 'jose';
|
|
import { cookies } from 'next/headers';
|
|
import { loginSchema, LoginSchema } from 'app/login/schema';
|
|
import { NextResponse } from 'next/server';
|
|
|
|
export async function getJWTSecretKey<Uint8Array>() {
|
|
const secret = process.env.JWT_SECRET
|
|
if (!secret) throw new Error("There is no JWT secret key")
|
|
try {
|
|
const enc: Uint8Array = new TextEncoder().encode(secret)
|
|
return enc
|
|
} catch (error) {
|
|
throw new Error("failed to getJWTSecretKey", error.message)
|
|
}
|
|
}
|
|
|
|
export async function verifyJwt(token: string): Promise<JWTPayload | null> {
|
|
try {
|
|
const key = await getJWTSecretKey()
|
|
const { payload } = await jwtVerify(token, key)
|
|
return payload
|
|
} catch {
|
|
return null
|
|
}
|
|
}
|
|
|
|
export async function getJwt() {
|
|
const cookieStore = cookies()
|
|
const token = cookieStore.get("token")
|
|
|
|
if (token) {
|
|
try {
|
|
const payload = await verifyJwt(token.value)
|
|
if (payload) {
|
|
const authPayload = {
|
|
email: payload.email as string,
|
|
iat: payload.iat as number,
|
|
exp: payload.exp as number
|
|
}
|
|
return authPayload
|
|
}
|
|
} catch (error) {
|
|
|
|
return null
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
|
|
export async function logout() {
|
|
const cookieStore = cookies()
|
|
const token = cookieStore.get('token')
|
|
|
|
if (token) {
|
|
//empty catch swallows errors
|
|
try {
|
|
cookieStore.delete('token')
|
|
} catch { }
|
|
}
|
|
|
|
const userData = cookieStore.get("userData")
|
|
if (userData) {
|
|
try {
|
|
cookieStore.delete('userData')
|
|
return true
|
|
} catch (_) { }
|
|
}
|
|
//return false if there is no userdata
|
|
return null
|
|
}
|
|
|
|
export async function setUserDataCookie(userData) {
|
|
const cookieStore = cookies();
|
|
cookieStore.set({
|
|
name: 'userData',
|
|
value: JSON.stringify(userData),
|
|
path: '/',
|
|
maxAge: 3600,
|
|
sameSite: 'strict'
|
|
})
|
|
}
|
|
|
|
|
|
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")
|
|
const bcrypt = require("bcrypt");
|
|
const passwordIsValid = await bcrypt.compare(userLogin.password, user.password)
|
|
if (!passwordIsValid) throw new Error("password is not valid")
|
|
return { email: userLogin.email }
|
|
} catch (error) {
|
|
console.error("WHOOPS", error)
|
|
throw new Error('login failed')
|
|
}
|
|
}
|
|
|
|
export async function jwtExpires() {
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|