import { z } from "zod"; import { procedure, router } from "../trpc"; import { db } from "@/db/PrismaClient"; import { TRPCError } from '@trpc/server'; import { login } from "@/utils/planetscale/login"; import { logout } from "@/utils/planetscale/logout"; import { getSession } from "@/utils/planetscale/session"; import { signup } from "@/utils/planetscale/signup"; import { changePassword } from "@/utils/planetscale/change-password"; export const authRouter = router({ //******************************************************* // log the user in from their provided email and password and set a session //******************************************************* login: procedure .input(z.object({ email: z.string(), password: z.string() })) .mutation(async ({ ctx, input }) => { try{ const loginResponse = await login(input.email, input.password, ctx.req, ctx.res) return loginResponse; } catch (error) { console.log(error) if (error instanceof TRPCError) throw error; throw new TRPCError({ code: 'INTERNAL_SERVER_ERROR', message: (error as Error).message, cause: error }); } }), signOut: procedure.mutation(async ({ ctx }) => { const {req, res} = ctx; const logoutResponse = await logout(req, res) return logoutResponse; }), //******************************************************* // Get session information, like if the user is logged in and data inline with the session //******************************************************* getSession: procedure.query(async ({ ctx }) => { const { req, res } = ctx; const sessionResponse = await getSession(req, res) return sessionResponse; }), //******************************************************* // Sign up a new user and set a session //******************************************************* signUp: procedure .input(z.object({ firstName: z.string(), lastName: z.string(), email: z.string(), age: z.string(), height: z.string(), weight: z.string(), gender: z.string(), password: z.string(), })) .mutation(async ({ ctx, input }) => { const { req, res } = ctx; const signupResponse = await signup(input.firstName, input.lastName, input.email, input.age, input.height, input.weight, input.gender, input.password, req, res) return signupResponse; }), verifyEmail: procedure .input(z.object({ token: z.string() })) .mutation(async ({ ctx, input}) => { const { token } = input; const userToken = await db.emailVerificationToken.findFirst({ where: { token: token }, }) if (!userToken) { throw new TRPCError({ code: 'FORBIDDEN', message: 'bad token' }) } if (token !== userToken.token) { throw new TRPCError({ code: 'FORBIDDEN', message: 'bad token' }) } const curDate = new Date if (userToken.expiry < curDate) { throw new TRPCError({ code: 'FORBIDDEN', message: 'Token is expired', }) } await db.user.update({ where: { email: userToken.email }, data: { emailVerified: curDate } }) await db.emailVerificationToken.delete({ where: { email: userToken.email } }) return { validated: true } }), //******************************************************* // Change the users password //******************************************************* changePassword: procedure .input(z.object({ oldPassword: z.string(), newPassword: z.string() })) .mutation(async ({ ctx, input }) => { const { req, res } = ctx; const { oldPassword, newPassword } = input; const result = await changePassword(oldPassword, newPassword, req, res); return result; }) })