From 21070c24eb44d3014e0632733dfc646a26ad096d Mon Sep 17 00:00:00 2001 From: nghiavohuynhdai Date: Fri, 26 Jan 2024 09:33:44 +0700 Subject: [PATCH] [Implement][Provider] Login API for Provider --- src/app.module.ts | 4 +- src/auth/auth.module.ts | 7 +- ...h.controller.ts => customer.controller.ts} | 12 +-- src/auth/controllers/provider.controller.ts | 21 +++++ src/auth/services/auth.service.ts | 15 +++- src/staff/repositories/staff.repository.ts | 12 +++ src/staff/schemas/staff.schema.ts | 83 +++++++++++++++++++ src/staff/staff.module.ts | 12 +++ tsconfig.json | 1 + 9 files changed, 157 insertions(+), 10 deletions(-) rename src/auth/controllers/{auth.controller.ts => customer.controller.ts} (91%) create mode 100644 src/auth/controllers/provider.controller.ts create mode 100644 src/staff/repositories/staff.repository.ts create mode 100644 src/staff/schemas/staff.schema.ts create mode 100644 src/staff/staff.module.ts diff --git a/src/app.module.ts b/src/app.module.ts index 4292157..7bdf3bc 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -13,6 +13,7 @@ import { CustomerModule } from '@customer/customer.module' import { AuthModule } from '@auth/auth.module' import { ProductModule } from '@product/product.module' import { CartModule } from '@cart/cart.module' +import { StaffModule } from '@staff/staff.module' @Module({ imports: [ @@ -61,7 +62,8 @@ import { CartModule } from '@cart/cart.module' CustomerModule, AuthModule, ProductModule, - CartModule + CartModule, + StaffModule ], controllers: [AppController], providers: [AppService] diff --git a/src/auth/auth.module.ts b/src/auth/auth.module.ts index 55a818d..7698260 100644 --- a/src/auth/auth.module.ts +++ b/src/auth/auth.module.ts @@ -3,19 +3,22 @@ import { JwtAccessStrategy } from '@auth/strategies/jwt-access.strategy' import { PassportModule } from '@nestjs/passport' import { CustomerModule } from '@customer/customer.module' import { AuthService } from '@auth/services/auth.service' -import { AuthController } from '@auth/controllers/auth.controller' +import { AuthCustomerController } from '@auth/controllers/customer.controller' import { JwtModule } from '@nestjs/jwt' import { ConfigModule } from '@nestjs/config' import { JwtRefreshStrategy } from '@auth/strategies/jwt-refresh.strategy' +import { StaffModule } from '@staff/staff.module' +import { AuthProviderController } from '@auth/controllers/provider.controller' @Module({ imports: [ ConfigModule, CustomerModule, + StaffModule, PassportModule, JwtModule ], - controllers: [AuthController], + controllers: [AuthCustomerController, AuthProviderController], providers: [AuthService, JwtAccessStrategy, JwtRefreshStrategy], exports: [AuthService] }) diff --git a/src/auth/controllers/auth.controller.ts b/src/auth/controllers/customer.controller.ts similarity index 91% rename from src/auth/controllers/auth.controller.ts rename to src/auth/controllers/customer.controller.ts index b6c60e5..f319bcd 100644 --- a/src/auth/controllers/auth.controller.ts +++ b/src/auth/controllers/customer.controller.ts @@ -8,12 +8,12 @@ import { UserSide } from '@common/contracts/constant' import { JwtAuthGuard } from '@auth/guards/jwt-auth.guard' import { RegisterReqDto } from '@auth/dto/register.dto' -@ApiTags('Auth') -@Controller() -export class AuthController { +@ApiTags('Auth - Customer') +@Controller('customer') +export class AuthCustomerController { constructor(private readonly authService: AuthService) {} - @Post('customer/login') + @Post('login') @ApiBody({ type: LoginReqDto }) @ApiOkResponse({ type: ResponseTokenDto }) @ApiBadRequestResponse({ type: ErrorResponse }) @@ -23,7 +23,7 @@ export class AuthController { return res } - @Post('customer/register') + @Post('register') @ApiBody({ type: RegisterReqDto }) @ApiOkResponse({ type: ResponseSuccessDto }) @ApiBadRequestResponse({ type: ErrorResponse }) @@ -32,7 +32,7 @@ export class AuthController { } @UseGuards(JwtAuthGuard.REFRESH_TOKEN) - @Post('customer/refresh') + @Post('refresh') @ApiBearerAuth() @ApiOkResponse({ type: ResponseTokenDto }) @ApiBadRequestResponse({ type: ErrorResponse }) diff --git a/src/auth/controllers/provider.controller.ts b/src/auth/controllers/provider.controller.ts new file mode 100644 index 0000000..bddb799 --- /dev/null +++ b/src/auth/controllers/provider.controller.ts @@ -0,0 +1,21 @@ +import { Body, Controller, Post } from "@nestjs/common" +import { ApiBadRequestResponse, ApiBody, ApiOkResponse, ApiTags } from "@nestjs/swagger" +import { UserSide } from "@common/contracts/constant" +import { ErrorResponse } from "@common/contracts/dto" +import { LoginReqDto } from "@auth/dto/login.dto" +import { ResponseTokenDto, TokenResDto } from "@auth/dto/token.dto" +import { AuthService } from "@auth/services/auth.service" + +@ApiTags('Auth - Provider') +@Controller('provider') +export class AuthProviderController { + constructor(private readonly authService: AuthService) {} + + @Post('login') + @ApiBody({ type: LoginReqDto }) + @ApiOkResponse({ type: ResponseTokenDto }) + @ApiBadRequestResponse({ type: ErrorResponse }) + async login(@Body() loginReqDto: LoginReqDto): Promise { + return await this.authService.login(loginReqDto, UserSide.PROVIDER) + } +} \ No newline at end of file diff --git a/src/auth/services/auth.service.ts b/src/auth/services/auth.service.ts index 8508cb6..21f3a28 100644 --- a/src/auth/services/auth.service.ts +++ b/src/auth/services/auth.service.ts @@ -11,17 +11,20 @@ import { RefreshTokenPayload } from '@auth/strategies/jwt-refresh.strategy' import { TokenResDto } from '@auth/dto/token.dto' import { ConfigService } from '@nestjs/config' import { RegisterReqDto } from '@auth/dto/register.dto' +import { StaffRepository } from '@staff/repositories/staff.repository' +import { Staff } from '@staff/schemas/staff.schema' @Injectable() export class AuthService { constructor( private readonly customerRepository: CustomerRepository, + private readonly staffRepository: StaffRepository, private readonly jwtService: JwtService, private readonly configService: ConfigService ) {} public async login(loginReqDto: LoginReqDto, side: UserSide): Promise { - let user: Customer | null + let user: Customer | Staff let userRole: UserRole if (side === UserSide.CUSTOMER) { @@ -34,6 +37,16 @@ export class AuthService { userRole = UserRole.CUSTOMER } + if (side === UserSide.PROVIDER) { + user = (await this.staffRepository.findOne({ + conditions: { + email: loginReqDto.email + } + })) + + userRole = user?.role + } + if (!user) throw new BadRequestException(Errors.WRONG_EMAIL_OR_PASSWORD.message) const isPasswordMatch = await this.comparePassword(loginReqDto.password, user.password) diff --git a/src/staff/repositories/staff.repository.ts b/src/staff/repositories/staff.repository.ts new file mode 100644 index 0000000..a4ecbe6 --- /dev/null +++ b/src/staff/repositories/staff.repository.ts @@ -0,0 +1,12 @@ +import { PaginateModel } from 'mongoose' +import { Injectable } from '@nestjs/common' +import { InjectModel } from '@nestjs/mongoose' +import { AbstractRepository } from '@common/repositories' +import { Staff, StaffDocument } from '@staff/schemas/staff.schema' + +@Injectable() +export class StaffRepository extends AbstractRepository { + constructor(@InjectModel(Staff.name) model: PaginateModel) { + super(model) + } +} diff --git a/src/staff/schemas/staff.schema.ts b/src/staff/schemas/staff.schema.ts new file mode 100644 index 0000000..b3be957 --- /dev/null +++ b/src/staff/schemas/staff.schema.ts @@ -0,0 +1,83 @@ +import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose' +import { ApiProperty } from '@nestjs/swagger' +import { Status, UserRole } from '@src/common/contracts/constant' +import { Transform } from 'class-transformer' +import { HydratedDocument } from 'mongoose' +import * as paginate from 'mongoose-paginate-v2' + +export type StaffDocument = HydratedDocument + +@Schema({ + collection: 'staffs', + timestamps: { + createdAt: true, + updatedAt: true + }, + toJSON: { + transform(doc, ret) { + delete ret.__v + } + } +}) +export class Staff { + constructor(id?: string) { + this._id = id + } + + @ApiProperty() + @Transform(({ value }) => value?.toString()) + _id: string + + @ApiProperty() + @Prop({ type: String, maxlength: 30, required: true }) + firstName: string + + @ApiProperty() + @Prop({ type: String, maxlength: 30, required: true }) + lastName: string + + @ApiProperty() + @Prop({ + type: String, + required: true + }) + email: string + + @ApiProperty() + @Prop({ type: String, required: true }) + password: string + + @ApiProperty() + @Prop({ type: String, required: true }) + staffCode: string + + @ApiProperty() + @Prop({ + type: String, + required: true + }) + phone: string + + @ApiProperty() + @Prop({ + type: String + }) + avatar: string + + @ApiProperty() + @Prop({ + enum: UserRole, + default: UserRole.STAFF + }) + role: UserRole + + @Prop({ + enum: Status, + default: Status.ACTIVE + }) + status: Status +} + +export const StaffSchema = SchemaFactory.createForClass(Staff) + +StaffSchema.plugin(paginate) diff --git a/src/staff/staff.module.ts b/src/staff/staff.module.ts new file mode 100644 index 0000000..ec9d6dc --- /dev/null +++ b/src/staff/staff.module.ts @@ -0,0 +1,12 @@ +import { Module } from '@nestjs/common' +import { MongooseModule } from '@nestjs/mongoose' +import { StaffRepository } from '@staff/repositories/staff.repository' +import { Staff, StaffSchema } from '@staff/schemas/staff.schema' + +@Module({ + imports: [MongooseModule.forFeature([{ name: Staff.name, schema: StaffSchema }])], + controllers: [], + providers: [StaffRepository], + exports: [StaffRepository] +}) +export class StaffModule {} diff --git a/tsconfig.json b/tsconfig.json index 16a0733..3c08950 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -29,6 +29,7 @@ "@booking/*": ["src/booking/*"], "@product/*": ["src/product/*"], "@cart/*": ["src/cart/*"], + "@staff/*": ["src/staff/*"], } } }