super-fit-web-app / src / utils / planetscale / signup.ts
signup.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 { z } from "zod";
import { generateSalt } from "../functions/generateSalt";
import { nanoid } from "nanoid";
import { User } from "@prisma/client";
import crypto from 'crypto'
import { Client } from 'postmark';
import Stripe from 'stripe'

export const signup = async (
  firstName: string,
  lastName: string,
  email: string,
  age: string,
  height: string,
  weight: string,
  gender: string,
  password: string,
  req: NextApiRequest, 
  res: NextApiResponse
) => {
  const existingUser = await db.user.findUnique({
    where: {
      email: email,
    }
  });

  if (existingUser) {
    throw new TRPCError({
      code: 'CONFLICT',
      message: 'User already exists'
    })
  }

  const stripe = new Stripe(process.env.STRIPE_SECRET_TEST_KEY, {
    apiVersion: '2022-11-15'
  })

  const salt: string = crypto.randomBytes(16).toString('hex');
  const hash: string = await argon2.hash(password + salt);

  const userData = {
    userId: nanoid(32),
    firstName: firstName,
    lastName: lastName,
    email: email,
    age: age,
    height: height,
    weight: weight,
    gender: gender,
    isAdmin: false,
    hash: hash,
    salt: salt,
  };

  await db.user.create({
    data: userData,
  });

  const plus24Hr = new Date(Date.now() + 86400000)

  const userEmailData = {
    expiry: plus24Hr,
    token: nanoid(36),
    email: email
  }

  await db.emailVerificationToken.create({
    data: userEmailData
  })

  const session_token = crypto.randomUUID();
  const userId = userData.userId;
  const expires = new Date(Date.now() + 1000 * 60 * 60 * 24 * 14); // 14 days

  await db.session.create({
    data: {
      session_token,
      userId,
      expires,
    }
  })
  .then(async () => {
    await cookieFunctions.saveCookie(req, res, session_token);
  })
  .catch((error) => {
    console.log(error);
    throw new TRPCError({
      code: 'INTERNAL_SERVER_ERROR',
      message: `Error: there was an issue creating a new session. ${(error as Error).message}`,
      cause: error
    });
  });

  /*const templateID = process.env.VERIFY_EMAIL_TEMPLATE_ID;

  const postmarkClient = new Client(process.env.POSTMARK_API_TOKEN)

  const postmarkResult = await postmarkClient.sendEmailWithTemplate({
    TemplateId: parseInt(templateID),
    To: input.email,
    From: 'liam@squashdev.com',
    TemplateModel: {
      action_url: `http://localhost:3000/account/verify-email?token=${userEmailData.token}`,
      name: input.firstName
    },
    Headers: [
      {
        // Set this to prevent Gmail from threading emails.
        // See https://stackoverflow.com/questions/23434110/force-emails-not-to-be-grouped-into-conversations/25435722.
        Name: "X-Entity-Ref-ID",
        Value: new Date().getTime() + "",
      },
    ],
  })

  if (postmarkResult.ErrorCode) {
    throw new TRPCError({
      code: 'INTERNAL_SERVER_ERROR',
      message: postmarkResult.Message
    })
  }*/

  //Make stripe account and then update stipe ID on DB
  await stripe.customers.create({
    email: email,
    name: firstName + ' ' + lastName,
  })
  .then(async (customer) => {
    return db.user.update({
      where: { email: userData.email },
      data: {
        stripeCustomerId: customer.id,
      }
    })
  })


  return {
    signup_success: true,
  };
}