mirror of
https://github.com/soconnor0919/hristudio.git
synced 2026-03-23 19:27:51 -04:00
114 lines
2.8 KiB
TypeScript
Executable File
114 lines
2.8 KiB
TypeScript
Executable File
import { TRPCError } from "@trpc/server";
|
|
import bcrypt from "bcryptjs";
|
|
import { eq } from "drizzle-orm";
|
|
import { z } from "zod";
|
|
|
|
import {
|
|
createTRPCRouter, protectedProcedure, publicProcedure
|
|
} from "~/server/api/trpc";
|
|
import { users } from "~/server/db/schema";
|
|
|
|
export const authRouter = createTRPCRouter({
|
|
register: publicProcedure
|
|
.input(
|
|
z.object({
|
|
name: z.string().min(1, "Name is required"),
|
|
email: z.string().email("Invalid email address"),
|
|
password: z.string().min(6, "Password must be at least 6 characters"),
|
|
}),
|
|
)
|
|
.mutation(async ({ ctx, input }) => {
|
|
const { name, email, password } = input;
|
|
|
|
// Check if user already exists
|
|
const existingUser = await ctx.db.query.users.findFirst({
|
|
where: eq(users.email, email),
|
|
});
|
|
|
|
if (existingUser) {
|
|
throw new TRPCError({
|
|
code: "CONFLICT",
|
|
message: "User with this email already exists",
|
|
});
|
|
}
|
|
|
|
// Hash password
|
|
const hashedPassword = await bcrypt.hash(password, 12);
|
|
|
|
try {
|
|
// Create user
|
|
const newUsers = await ctx.db
|
|
.insert(users)
|
|
.values({
|
|
name,
|
|
email,
|
|
password: hashedPassword,
|
|
})
|
|
.returning({
|
|
id: users.id,
|
|
name: users.name,
|
|
email: users.email,
|
|
createdAt: users.createdAt,
|
|
});
|
|
|
|
const newUser = newUsers[0];
|
|
if (!newUser) {
|
|
throw new TRPCError({
|
|
code: "INTERNAL_SERVER_ERROR",
|
|
message: "Failed to create user",
|
|
});
|
|
}
|
|
|
|
return newUser;
|
|
} catch (error: unknown) {
|
|
throw new TRPCError({
|
|
code: "INTERNAL_SERVER_ERROR",
|
|
message:
|
|
error instanceof Error ? error.message : "Failed to create user",
|
|
});
|
|
}
|
|
}),
|
|
|
|
logout: protectedProcedure.mutation(async ({ ctx: _ctx }) => {
|
|
// Note: Actual logout is handled by NextAuth.js
|
|
// This endpoint is for any additional cleanup if needed
|
|
return { success: true };
|
|
}),
|
|
|
|
me: protectedProcedure.query(async ({ ctx }) => {
|
|
const userId = ctx.session.user.id;
|
|
|
|
const user = await ctx.db.query.users.findFirst({
|
|
where: eq(users.id, userId),
|
|
with: {
|
|
systemRoles: {
|
|
with: {
|
|
grantedByUser: {
|
|
columns: {
|
|
id: true,
|
|
name: true,
|
|
email: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
columns: {
|
|
password: false, // Exclude password from response
|
|
},
|
|
});
|
|
|
|
if (!user) {
|
|
throw new TRPCError({
|
|
code: "NOT_FOUND",
|
|
message: "User not found",
|
|
});
|
|
}
|
|
|
|
return {
|
|
...user,
|
|
roles: user.systemRoles.map((sr) => sr.role),
|
|
};
|
|
}),
|
|
});
|