super-fit-web-app / src / utils / planetscale / login.ts
login.ts
Raw
import { db } from "@/db/PrismaClient";
import { TRPCError } from "@trpc/server";
import argon2 from "argon2";
import { cookieFunctions } from "../cookies";
import { NextApiRequest, NextApiResponse } from "next";
import { User } from "@prisma/client";

export const login = async (email: string, password: string, req: NextApiRequest, res: NextApiResponse) => {
  const user = await db.user.findUnique({
    where: {
      email: email,
    }
  }).catch((error) => {
    console.log(error);
    throw new TRPCError({
      code: 'UNAUTHORIZED',
      message: `This user does not exist`,
      cause: error
    });
  })

  if (!user) {
    throw new TRPCError({
      code: 'UNAUTHORIZED',
      message: 'Invalid email or password',
    });
  }

  const salted_password = password + user.salt;

  const valid = await argon2.verify(user.hash, salted_password);

  if (!valid) {
    throw new TRPCError({
      code: 'UNAUTHORIZED',
      message: 'Invalid email or password',
    });
  }

  const session_token = crypto.randomUUID();
  const userId = user.userId;
  const expires = new Date(Date.now() + 1000 * 60 * 60 * 24 * 14); // 14 days
  const userIP = req.headers['x-real-ip'] as string|| req.socket.remoteAddress;
  const userAgent = req.headers['user-agent'] as string;

  const existingSession = await db.session.findUnique({
    where: {
      userId: userId,
    }
  }).catch((error) => {
    console.log(error);
    throw new TRPCError({
      code: 'INTERNAL_SERVER_ERROR',
      message: `Error: there was an issue finding an existing session. ${(error as Error).message}`,
      cause: error
    });
  })

  if (existingSession) {
    await db.session.update({
      where: {
        userId: userId,
      },
      data: {
        expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 14),
        session_token: session_token,
      }
    })
  } else {
    await db.session.create({
      data: {
        session_token,
        userId,
        expires,
      }
    })
  }

  await cookieFunctions.saveCookie(req, res, session_token);

  const { hash, salt, ...userWithoutPassword } = user;

  return {
    user: userWithoutPassword as User,
    login_success: true,
    email_verified: user.emailVerified,
  };
}