diff --git a/prisma/migrations/20241018233516_init/migration.sql b/prisma/migrations/20241027162231_init/migration.sql similarity index 99% rename from prisma/migrations/20241018233516_init/migration.sql rename to prisma/migrations/20241027162231_init/migration.sql index 4e7124f..60cc439 100644 --- a/prisma/migrations/20241018233516_init/migration.sql +++ b/prisma/migrations/20241027162231_init/migration.sql @@ -40,10 +40,12 @@ CREATE TABLE `SpriteAction` ( CREATE TABLE `User` ( `id` INTEGER NOT NULL AUTO_INCREMENT, `username` VARCHAR(191) NOT NULL, + `email` VARCHAR(191) NOT NULL, `password` VARCHAR(191) NOT NULL, `online` BOOLEAN NOT NULL DEFAULT false, UNIQUE INDEX `User_username_key`(`username`), + UNIQUE INDEX `User_email_key`(`email`), PRIMARY KEY (`id`) ) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; diff --git a/prisma/schema/user.prisma b/prisma/schema/user.prisma index 0259610..d67fc4b 100644 --- a/prisma/schema/user.prisma +++ b/prisma/schema/user.prisma @@ -1,6 +1,7 @@ model User { id Int @id @default(autoincrement()) username String @unique + email String @unique password String online Boolean @default(false) characters Character[] diff --git a/src/repositories/userRepository.ts b/src/repositories/userRepository.ts index 37dbf69..03b9faf 100644 --- a/src/repositories/userRepository.ts +++ b/src/repositories/userRepository.ts @@ -27,6 +27,19 @@ class UserRepository { throw new Error(`Failed to get user by username: ${error.message}`) } } + + async getByEmail(email: string): Promise { + try { + return await prisma.user.findUnique({ + where: { + email + } + }) + } catch (error: any) { + // Handle error + throw new Error(`Failed to get user by email: ${error.message}`) + } + } } export default new UserRepository() diff --git a/src/services/userService.ts b/src/services/userService.ts index 576fe05..285d08d 100644 --- a/src/services/userService.ts +++ b/src/services/userService.ts @@ -33,16 +33,22 @@ class UserService { * @param username * @param password */ - async register(username: string, password: string): Promise { + async register(username: string, email: string, password: string): Promise { const user = await UserRepository.getByUsername(username) if (user) { return false } + const userByEmail = await UserRepository.getByEmail(email) + if (userByEmail) { + return false + } + const hashedPassword = await bcrypt.hash(password, 10) return prisma.user.create({ data: { username, + email, password: hashedPassword } }) diff --git a/src/utilities/http.ts b/src/utilities/http.ts index b7dcd85..52cbd63 100644 --- a/src/utilities/http.ts +++ b/src/utilities/http.ts @@ -40,16 +40,16 @@ async function addHttpRoutes(app: Application) { * @param res */ app.post('/register', async (req: Request, res: Response) => { - const { username, password } = req.body + const { username, email, password } = req.body try { - registerAccountSchema.parse({ username, password }) + registerAccountSchema.parse({ username, email, password }) } catch (error: any) { return res.status(400).json({ message: error.errors[0]?.message }) } const userService = new UserService() - const user = await userService.register(username, password) + const user = await userService.register(username, email, password) if (user) { return res.status(200).json({ message: 'User registered' }) diff --git a/src/utilities/zodTypes.ts b/src/utilities/zodTypes.ts index 6203820..9c9489e 100644 --- a/src/utilities/zodTypes.ts +++ b/src/utilities/zodTypes.ts @@ -20,6 +20,11 @@ export const registerAccountSchema = z.object({ .min(3, { message: 'Name must be at least 3 characters long' }) .max(255, { message: 'Name must be at most 255 characters long' }) .regex(/^[A-Za-z][A-Za-z0-9_-]*$/, { message: 'Name must start with a letter and can only contain letters, numbers, underscores, or dashes' }), + email: z + .string() + .min(3, { message: 'Email must be at least 3 characters long' }) + .max(255, { message: 'Email must be at most 255 characters long' }) + .regex(/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/, { message: 'Email must be valid' }), password: z .string() .min(8, {