From 3934fe0d1751dbbacac4b19710a12751b62f2899 Mon Sep 17 00:00:00 2001 From: rajdip-b Date: Fri, 24 May 2024 10:28:58 +0530 Subject: [PATCH 1/2] feat: Emails are stored in lowercase --- src/auth/dto/signin.dto.ts | 2 ++ src/auth/dto/signup.dto.ts | 2 ++ src/auth/service/auth.service.ts | 9 ++++++++- src/user/service/user.service.ts | 2 +- 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/auth/dto/signin.dto.ts b/src/auth/dto/signin.dto.ts index da1a652..20d4d6e 100644 --- a/src/auth/dto/signin.dto.ts +++ b/src/auth/dto/signin.dto.ts @@ -1,8 +1,10 @@ import { ApiProperty } from '@nestjs/swagger'; +import { Transform } from 'class-transformer'; import { IsEmail } from 'class-validator'; export class SigninDto { @IsEmail() + @Transform(({ value }) => value.toLowerCase()) @ApiProperty({ name: 'email', description: 'User email. Must be a valid email address.', diff --git a/src/auth/dto/signup.dto.ts b/src/auth/dto/signup.dto.ts index ea04a40..0c7e4db 100644 --- a/src/auth/dto/signup.dto.ts +++ b/src/auth/dto/signup.dto.ts @@ -1,8 +1,10 @@ import { ApiProperty } from '@nestjs/swagger'; +import { Transform } from 'class-transformer'; import { IsEmail } from 'class-validator'; export class SignupDto { @IsEmail() + @Transform(({ value }) => value.toLowerCase()) @ApiProperty({ name: 'email', description: 'User email. Must be a valid email address.', diff --git a/src/auth/service/auth.service.ts b/src/auth/service/auth.service.ts index 3ba523c..a5dc8a8 100644 --- a/src/auth/service/auth.service.ts +++ b/src/auth/service/auth.service.ts @@ -131,6 +131,7 @@ export class AuthService { } async resendEmailVerificationCode(email: string) { + email = email.toLowerCase(); const user = await this.findUserByEmail(email); if (!user) { throw new NotFoundException('User not found'); @@ -143,6 +144,8 @@ export class AuthService { } async verifyEmail(email: string, code: string) { + email = email.toLowerCase(); + const verificationCode = await this.prisma.verificationCode.findUnique({ where: { email, @@ -201,6 +204,7 @@ export class AuthService { profilePictureUrl?: string, throwErrorIfUserExists?: boolean, ) { + email = email.toLowerCase(); let user = await this.findUserByEmail(email); if (user && throwErrorIfUserExists) { throw new ConflictException('User already exists'); @@ -209,7 +213,7 @@ export class AuthService { if (!user) { user = await this.prisma.user.create({ data: { - email: email, + email, name: name, profilePictureUrl: profilePictureUrl, authType, @@ -241,6 +245,7 @@ export class AuthService { } private async findUserByEmail(email: string) { + email = email.toLowerCase(); return await this.prisma.user.findUnique({ where: { email, @@ -257,6 +262,8 @@ export class AuthService { } private async sendEmailVerificationCode(email: string) { + email = email.toLowerCase(); + // Generate the code let code: string; diff --git a/src/user/service/user.service.ts b/src/user/service/user.service.ts index ef729d0..17ecf5e 100644 --- a/src/user/service/user.service.ts +++ b/src/user/service/user.service.ts @@ -177,7 +177,7 @@ export class UserService { */ async linkSocialAccount(req: any, socialAccountType: SocialAccountType) { const { emails, profileUrl } = req.user; - const email = emails[0].value; + const email = emails[0].value.toLowerCase(); // Check if the user exists const currentUser = await this.prisma.user.findUniqueOrThrow({ From a65b7de06d9157ac5cdac5ae356e42c0c7a31a89 Mon Sep 17 00:00:00 2001 From: rajdip-b Date: Fri, 24 May 2024 11:31:03 +0530 Subject: [PATCH 2/2] organized code --- src/app/app.module.ts | 2 ++ src/auth/controller/auth.controller.ts | 5 ++++- src/auth/dto/email-verification.dto.ts | 2 ++ src/auth/service/auth.service.ts | 5 ----- src/common/common.module.ts | 5 +++++ src/common/pipes/lowercase.pipe.ts | 8 ++++++++ 6 files changed, 21 insertions(+), 6 deletions(-) create mode 100644 src/common/common.module.ts create mode 100644 src/common/pipes/lowercase.pipe.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index ea4e5d4..469523b 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -9,12 +9,14 @@ import { AuthGuard } from '../auth/guard/auth/auth.guard'; import { PrismaModule } from '../prisma/prisma.module'; import { MailModule } from '../mail/mail.module'; import { ProviderModule } from '../provider/provider.module'; +import { CommonModule } from '../common/common.module'; @Module({ imports: [ ConfigModule.forRoot({ isGlobal: true, }), + CommonModule, AuthModule, UserModule, OauthModule, diff --git a/src/auth/controller/auth.controller.ts b/src/auth/controller/auth.controller.ts index 3cd3932..13d1480 100644 --- a/src/auth/controller/auth.controller.ts +++ b/src/auth/controller/auth.controller.ts @@ -32,6 +32,7 @@ import { ApiTags, } from '@nestjs/swagger'; import { userProperties } from '../../schemas/user.properties'; +import { LowercasePipe } from '../../common/pipes/lowercase.pipe'; @Controller('auth') @ApiTags('Auth Controller') @@ -195,7 +196,9 @@ export class AuthController { description: 'User not found', }) @HttpCode(HttpStatus.NO_CONTENT) - async resendEmailVerificationCode(@Param('email') email: string) { + async resendEmailVerificationCode( + @Param('email', LowercasePipe) email: string, + ) { return await this.authService.resendEmailVerificationCode(email); } diff --git a/src/auth/dto/email-verification.dto.ts b/src/auth/dto/email-verification.dto.ts index d76f80d..561e663 100644 --- a/src/auth/dto/email-verification.dto.ts +++ b/src/auth/dto/email-verification.dto.ts @@ -1,4 +1,5 @@ import { ApiProperty } from '@nestjs/swagger'; +import { Transform } from 'class-transformer'; import { IsEmail, Matches } from 'class-validator'; export class EmailVerificationDto { @@ -10,6 +11,7 @@ export class EmailVerificationDto { type: String, example: 'johndoe@example.com', }) + @Transform(({ value }) => value.toLowerCase()) email: string; @Matches(/^[0-9]{6}$/, { message: 'Code must be a 6 digit number', diff --git a/src/auth/service/auth.service.ts b/src/auth/service/auth.service.ts index a5dc8a8..8275fb2 100644 --- a/src/auth/service/auth.service.ts +++ b/src/auth/service/auth.service.ts @@ -131,7 +131,6 @@ export class AuthService { } async resendEmailVerificationCode(email: string) { - email = email.toLowerCase(); const user = await this.findUserByEmail(email); if (!user) { throw new NotFoundException('User not found'); @@ -144,8 +143,6 @@ export class AuthService { } async verifyEmail(email: string, code: string) { - email = email.toLowerCase(); - const verificationCode = await this.prisma.verificationCode.findUnique({ where: { email, @@ -262,8 +259,6 @@ export class AuthService { } private async sendEmailVerificationCode(email: string) { - email = email.toLowerCase(); - // Generate the code let code: string; diff --git a/src/common/common.module.ts b/src/common/common.module.ts new file mode 100644 index 0000000..b7bd955 --- /dev/null +++ b/src/common/common.module.ts @@ -0,0 +1,5 @@ +import { Global, Module } from '@nestjs/common'; + +@Global() +@Module({}) +export class CommonModule {} diff --git a/src/common/pipes/lowercase.pipe.ts b/src/common/pipes/lowercase.pipe.ts new file mode 100644 index 0000000..317bd0b --- /dev/null +++ b/src/common/pipes/lowercase.pipe.ts @@ -0,0 +1,8 @@ +import { PipeTransform, Injectable } from '@nestjs/common'; + +@Injectable() +export class LowercasePipe implements PipeTransform { + transform(value: string) { + return value.toLowerCase(); + } +}