From 56b50d8c3242adf07d6f9cf3f80330af08e4ce08 Mon Sep 17 00:00:00 2001 From: matin jamshidi Date: Mon, 20 Jan 2025 10:19:06 +0330 Subject: [PATCH] feat: auth module --- package.json | 1 + pnpm-lock.yaml | 11 +++++++++ src/common/enums/message.enum.ts | 9 +++++++- src/modules/auth/DTOs/loginPassword.dto.ts | 14 +++++++++++ src/modules/auth/auth.controller.ts | 4 ++++ src/modules/auth/auth.module.ts | 12 ++++++++++ src/modules/auth/auth.service.ts | 23 +++++++++++++++++++ .../users/providers/users.repository.ts | 6 +++++ src/modules/users/providers/users.service.ts | 14 ++++++++--- 9 files changed, 90 insertions(+), 4 deletions(-) create mode 100644 src/modules/auth/DTOs/loginPassword.dto.ts create mode 100644 src/modules/auth/auth.controller.ts create mode 100644 src/modules/auth/auth.module.ts create mode 100644 src/modules/auth/auth.service.ts diff --git a/package.json b/package.json index a5db3d3..5478613 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "@keyv/redis": "^4.2.0", "@nestjs-modules/mailer": "^2.0.2", "@nestjs/cache-manager": "^3.0.0", + "@nestjs/class-validator": "^0.13.4", "@nestjs/common": "^10.4.15", "@nestjs/config": "^4.0.0", "@nestjs/core": "^10.4.15", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 18bf7a6..7fb7b67 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,6 +20,9 @@ importers: '@nestjs/cache-manager': specifier: ^3.0.0 version: 3.0.0(@nestjs/common@10.4.15(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(reflect-metadata@0.2.2)(rxjs@7.8.1))(cache-manager@6.3.2)(rxjs@7.8.1) + '@nestjs/class-validator': + specifier: ^0.13.4 + version: 0.13.4 '@nestjs/common': specifier: ^10.4.15 version: 10.4.15(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) @@ -710,6 +713,9 @@ packages: cache-manager: '>=6' rxjs: ^7.8.1 + '@nestjs/class-validator@0.13.4': + resolution: {integrity: sha512-/mqZL36LJ5uV5WDhi87Cd52IssuO+SStaOr2+6sBsvCCGUWkoJes4Wwzmm3m/gdHH+tsNxX60sVSzYcU6hAy9Q==} + '@nestjs/cli@10.4.9': resolution: {integrity: sha512-s8qYd97bggqeK7Op3iD49X2MpFtW4LVNLAwXFkfbRxKME6IYT7X0muNTJ2+QfI8hpbNx9isWkrLWIp+g5FOhiA==} engines: {node: '>= 16.14'} @@ -5453,6 +5459,11 @@ snapshots: cache-manager: 6.3.2 rxjs: 7.8.1 + '@nestjs/class-validator@0.13.4': + dependencies: + libphonenumber-js: 1.11.18 + validator: 13.12.0 + '@nestjs/cli@10.4.9': dependencies: '@angular-devkit/core': 17.3.11(chokidar@3.6.0) diff --git a/src/common/enums/message.enum.ts b/src/common/enums/message.enum.ts index 21e0cb2..354333d 100644 --- a/src/common/enums/message.enum.ts +++ b/src/common/enums/message.enum.ts @@ -12,7 +12,10 @@ export const enum AuthMessage { PASSWORD_UPDATE_SUCCESS = "رمز عبور شما تغییر کرد", INVALID_OTP = "کد صحیح نمی‌باشد", PASSWORD_MISMATCH = "رمز عبور یکسان نیست", - INVALID_PASSWORD = "رمز عبور اشتباه است", + INVALID_PASSWORD = "ایمیل یا رمز عبور اشتباه است", + EmailNotEmpty = "ایمیل نمیتواند خالی باشد.", + IncorrectEmail = "ایمیل صحیح نیست", + PasswordNotEmpty = "پسورد نمیتواند خالی باشد.", USER_NOT_FOUND = "کاربری با این شماره وجود ندارد", USER_EXISTS = "با این شماره قبلا ثبت نام شده است", USER_REGISTER_SUCCESS = "ثبت نام موفقیت آمیز بود", @@ -26,3 +29,7 @@ export const enum AuthMessage { Permission_NOT_FOUND = "دسترسی یافت نشد", ADMIN_NOT_FOUND = "ادمین یافت نشد", } + +export const enum UserMessage { + USER_NOT_FOUND = "کاربری با این مشخصات یافت نشد", +} diff --git a/src/modules/auth/DTOs/loginPassword.dto.ts b/src/modules/auth/DTOs/loginPassword.dto.ts new file mode 100644 index 0000000..4de197b --- /dev/null +++ b/src/modules/auth/DTOs/loginPassword.dto.ts @@ -0,0 +1,14 @@ +import { IsEmail, IsNotEmpty } from "@nestjs/class-validator"; +import { AuthMessage } from "../../../common/enums/message.enum"; +import { ApiProperty } from "@nestjs/swagger"; + +export class LoginPasswordDTO { + @IsNotEmpty({ message: AuthMessage.EmailNotEmpty }) + @IsEmail(undefined, { message: AuthMessage.IncorrectEmail }) + @ApiProperty({ description: "email of user", default: "user@abrclick.ir" }) + email: string; + + @IsNotEmpty({ message: AuthMessage.PasswordNotEmpty }) + @ApiProperty({ type: "string", description: "password user", example: "@1234" }) + password: string; +} diff --git a/src/modules/auth/auth.controller.ts b/src/modules/auth/auth.controller.ts new file mode 100644 index 0000000..438edde --- /dev/null +++ b/src/modules/auth/auth.controller.ts @@ -0,0 +1,4 @@ +import { Controller } from "@nestjs/common"; + +@Controller("auth") +export class AuthController {} diff --git a/src/modules/auth/auth.module.ts b/src/modules/auth/auth.module.ts new file mode 100644 index 0000000..3730dd1 --- /dev/null +++ b/src/modules/auth/auth.module.ts @@ -0,0 +1,12 @@ +import { Module } from "@nestjs/common"; + +import { AuthController } from "./auth.controller"; +import { AuthService } from "./auth.service"; +import { UtilsModule } from "../utils/utils.module"; + +@Module({ + imports: [UtilsModule], + controllers: [AuthController], + providers: [AuthService], +}) +export class AuthModule {} diff --git a/src/modules/auth/auth.service.ts b/src/modules/auth/auth.service.ts new file mode 100644 index 0000000..b901453 --- /dev/null +++ b/src/modules/auth/auth.service.ts @@ -0,0 +1,23 @@ +import { BadRequestException, Injectable } from "@nestjs/common"; +import { UsersService } from "../users/providers/users.service"; +import { LoginPasswordDTO } from "./DTOs/loginPassword.dto"; +import { PasswordService } from "../utils/providers/password.service"; +import { AuthMessage, UserMessage } from "../../common/enums/message.enum"; + +@Injectable() +export class AuthService { + constructor( + private readonly userSerivce: UsersService, + private readonly passwordService: PasswordService, + ) {} + + async loginWithPassword(loginDto: LoginPasswordDTO) { + const { email, password } = loginDto; + + const user = await this.userSerivce.findOneWithEmail(email); + if (!user) throw new BadRequestException(UserMessage.USER_NOT_FOUND); + + const passCompare = await this.passwordService.comparePassword(password, user.password); + if (!passCompare) throw new BadRequestException(AuthMessage.INVALID_PASSWORD); + } +} diff --git a/src/modules/users/providers/users.repository.ts b/src/modules/users/providers/users.repository.ts index 058aca8..7918c72 100644 --- a/src/modules/users/providers/users.repository.ts +++ b/src/modules/users/providers/users.repository.ts @@ -9,4 +9,10 @@ export class UserRepository extends Repository { constructor(@InjectRepository(User) userRepository: Repository) { super(userRepository.target, userRepository.manager, userRepository.queryRunner); } + + async findOneWithEmail(email: string): Promise { + return await this.findOneBy({ + email, + }); + } } diff --git a/src/modules/users/providers/users.service.ts b/src/modules/users/providers/users.service.ts index a7a6e12..a1efb05 100644 --- a/src/modules/users/providers/users.service.ts +++ b/src/modules/users/providers/users.service.ts @@ -1,8 +1,16 @@ -import { Injectable } from "@nestjs/common"; +import { BadRequestException, Injectable } from "@nestjs/common"; -// import { UserRepository } from "./users.repository"; +import { UserRepository } from "./users.repository"; +import { User } from "../entities/user.entity"; +import { UserMessage } from "../../../common/enums/message.enum"; @Injectable() export class UsersService { - // constructor(private userRepository: UserRepository) {} + constructor(private userRepository: UserRepository) {} + + async findOneWithEmail(email: string): Promise { + const user = await this.userRepository.findOneWithEmail(email); + if (!user) throw new BadRequestException(UserMessage.USER_NOT_FOUND); + return user; + } }