From 353213c6bdfc8b0b25e04acacd02c4ee697ccfdf Mon Sep 17 00:00:00 2001 From: Sergey Krylov Date: Sat, 24 Jan 2026 15:34:09 +0300 Subject: [PATCH] feat: add otp code verification --- src/modules/auth/auth.controller.ts | 12 +++++- src/modules/auth/auth.grpc.ts | 7 +++- src/modules/auth/dto/rq/index.ts | 1 + .../auth/dto/rq/verify-otp.request.dto.ts | 38 +++++++++++++++++++ yarn.lock | 6 +-- 5 files changed, 59 insertions(+), 5 deletions(-) create mode 100644 src/modules/auth/dto/rq/verify-otp.request.dto.ts diff --git a/src/modules/auth/auth.controller.ts b/src/modules/auth/auth.controller.ts index ad52293..a14f01d 100644 --- a/src/modules/auth/auth.controller.ts +++ b/src/modules/auth/auth.controller.ts @@ -2,7 +2,7 @@ import { Body, Controller, HttpCode, HttpStatus, Post } from '@nestjs/common' import { ApiOperation } from '@nestjs/swagger' import { AuthClientGrpc } from './auth.grpc' -import { SendOtpRequestDto } from './dto' +import { SendOtpRequestDto, VerifyOtpRequestDto } from './dto' @Controller('auth') export class AuthController { @@ -17,4 +17,14 @@ export class AuthController { public sendOtp(@Body() dto: SendOtpRequestDto) { return this.client.sendOtp(dto) } + + @ApiOperation({ + summary: 'Verify OTP', + description: 'Verify code to the user phone or email' + }) + @Post('otp/verify') + @HttpCode(HttpStatus.OK) + public verifyOtp(@Body() dto: VerifyOtpRequestDto) { + return this.client.verifyOtp(dto) + } } diff --git a/src/modules/auth/auth.grpc.ts b/src/modules/auth/auth.grpc.ts index e2b6400..750ad05 100644 --- a/src/modules/auth/auth.grpc.ts +++ b/src/modules/auth/auth.grpc.ts @@ -2,7 +2,8 @@ import { Inject, Injectable, OnModuleInit } from '@nestjs/common' import type { ClientGrpc } from '@nestjs/microservices' import { AuthServiceClient, - SendOtpRequest + SendOtpRequest, + VerifyOtpRequest } from '@teacinema/contracts/gen/auth' @Injectable() @@ -18,4 +19,8 @@ export class AuthClientGrpc implements OnModuleInit { public sendOtp(request: SendOtpRequest) { return this.authService.sendOtp(request) } + + public verifyOtp(request: VerifyOtpRequest) { + return this.authService.verifyOtp(request) + } } diff --git a/src/modules/auth/dto/rq/index.ts b/src/modules/auth/dto/rq/index.ts index 060b2b8..7acab38 100644 --- a/src/modules/auth/dto/rq/index.ts +++ b/src/modules/auth/dto/rq/index.ts @@ -1 +1,2 @@ export * from './send-otp.request.dto' +export * from './verify-otp.request.dto' diff --git a/src/modules/auth/dto/rq/verify-otp.request.dto.ts b/src/modules/auth/dto/rq/verify-otp.request.dto.ts new file mode 100644 index 0000000..ce942d1 --- /dev/null +++ b/src/modules/auth/dto/rq/verify-otp.request.dto.ts @@ -0,0 +1,38 @@ +import { ApiProperty } from '@nestjs/swagger' +import { + IsEnum, + IsNotEmpty, + IsNumberString, + IsString, + Length, + Validate +} from 'class-validator' + +import { IdentifierValidator } from '../../../../shared/validators' + +export class VerifyOtpRequestDto { + @ApiProperty({ + description: 'User phone or email', + example: '+791234567890' + }) + @Validate(IdentifierValidator) + @IsString() + public identifier: string + + @ApiProperty({ + description: 'Otp code', + example: '123456' + }) + @IsNumberString() + @IsNotEmpty() + @Length(6, 6) + public code: string + + @ApiProperty({ + description: 'Type of identifier', + example: 'phone', + enum: ['phone', 'email'] + }) + @IsEnum(['phone', 'email']) + public type: 'phone' | 'email' +} diff --git a/yarn.lock b/yarn.lock index cbf01a0..81166af 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1193,9 +1193,9 @@ "@sinonjs/commons" "^3.0.1" "@teacinema/contracts@^1.0.0": - version "1.0.0" - resolved "https://git.ksv741.keenetic.pro/api/packages/teacinema/npm/%40teacinema%2Fcontracts/-/1.0.0/contracts-1.0.0.tgz#9395c331ec94b604d1946d26b683dd93e04a6225" - integrity sha512-zhYE0SIWjJl+ujp+yf0dT3ua4hWpR19gy//CwVcLO9bvfh+bZRYttlXE6XXWGucHv6208+sNNdkpwSwVyKyqNg== + version "1.0.1" + resolved "https://git.ksv741.keenetic.pro/api/packages/teacinema/npm/%40teacinema%2Fcontracts/-/1.0.1/contracts-1.0.1.tgz#25021fecb1d33d0505fd11ca3d8201660cb1bcbe" + integrity sha512-gvdbQ3Xowr4/h9Kq2P+pO2lr9vyWvIvRoU74mG3LSq2IiKKuwQUTxRaJnzI5MdtNqiq0WIUMo30cfqnBzNAJ1A== dependencies: "@nestjs/microservices" "^11.1.12" protoc "33.4.0"