diff --git a/src/modules/account/account.controller.ts b/src/modules/account/account.controller.ts new file mode 100644 index 0000000..f182ccc --- /dev/null +++ b/src/modules/account/account.controller.ts @@ -0,0 +1,77 @@ +import { Body, Controller, HttpCode, HttpStatus, Post } from '@nestjs/common' +import { ApiBearerAuth, ApiOperation } from '@nestjs/swagger' + +import { CurrentUser, Protected } from '../../shared/decorators' + +import { AccountClientGrpc } from './account.grpc' +import { + ConfirmEmailChangeRequestDto, + ConfirmPhoneChangeRequestDto, + InitEmailChangeRequestDto, + InitPhoneChangeRequestDto +} from './dto' + +@Controller('account') +export class AccountController { + constructor(private readonly client: AccountClientGrpc) {} + + @ApiOperation({ + summary: 'Init email change', + description: 'Send confirmation code to change email' + }) + @ApiBearerAuth() + @Protected() + @Post('email/init') + @HttpCode(HttpStatus.OK) + public initEmailChange( + @Body() dto: InitEmailChangeRequestDto, + @CurrentUser() userId: string + ) { + return this.client.initEmailChange({ ...dto, userId }) + } + + @ApiOperation({ + summary: 'Confirm email change', + description: 'Verify confirmation code to change email' + }) + @Protected() + @ApiBearerAuth() + @Post('email/confirm') + @HttpCode(HttpStatus.OK) + public confirmEmailChange( + @Body() dto: ConfirmEmailChangeRequestDto, + @CurrentUser() userId: string + ) { + return this.client.confirmEmailChange({ ...dto, userId }) + } + + @ApiOperation({ + summary: 'Init phone change', + description: 'Send confirmation code to change phone' + }) + @ApiBearerAuth() + @Protected() + @Post('phone/init') + @HttpCode(HttpStatus.OK) + public initPhoneChange( + @Body() dto: InitPhoneChangeRequestDto, + @CurrentUser() userId: string + ) { + return this.client.initPhoneChange({ ...dto, userId }) + } + + @ApiOperation({ + summary: 'Confirm phone change', + description: 'Verify confirmation code to change phone' + }) + @Protected() + @ApiBearerAuth() + @Post('phone/confirm') + @HttpCode(HttpStatus.OK) + public confirmPhoneChange( + @Body() dto: ConfirmPhoneChangeRequestDto, + @CurrentUser() userId: string + ) { + return this.client.confirmPhoneChange({ ...dto, userId }) + } +} diff --git a/src/modules/account/account.grpc.ts b/src/modules/account/account.grpc.ts index a0b2437..e02266e 100644 --- a/src/modules/account/account.grpc.ts +++ b/src/modules/account/account.grpc.ts @@ -2,7 +2,11 @@ import { Inject, Injectable, OnModuleInit } from '@nestjs/common' import type { ClientGrpc } from '@nestjs/microservices' import { AccountServiceClient, - GetAccountRequest + ConfirmEmailChangeRequest, + ConfirmPhoneChangeRequest, + GetAccountRequest, + InitEmailChangeRequest, + InitPhoneChangeRequest, } from '@teacinema/contracts/gen/account' @Injectable() @@ -19,4 +23,20 @@ export class AccountClientGrpc implements OnModuleInit { public getAccount(request: GetAccountRequest) { return this.accountService.getAccount(request) } + + public initEmailChange(request: InitEmailChangeRequest) { + return this.accountService.initEmailChange(request) + } + + public initPhoneChange(request: InitPhoneChangeRequest) { + return this.accountService.initPhoneChange(request) + } + + public confirmEmailChange(request: ConfirmEmailChangeRequest) { + return this.accountService.confirmEmailChange(request) + } + + public confirmPhoneChange(request: ConfirmPhoneChangeRequest) { + return this.accountService.confirmPhoneChange(request) + } } diff --git a/src/modules/account/account.module.ts b/src/modules/account/account.module.ts index 5fd3054..040e978 100644 --- a/src/modules/account/account.module.ts +++ b/src/modules/account/account.module.ts @@ -3,6 +3,7 @@ import { ConfigService } from '@nestjs/config' import { ClientsModule, Transport } from '@nestjs/microservices' import { PROTO_PATHS } from '@teacinema/contracts' +import { AccountController } from './account.controller' import { AccountClientGrpc } from './account.grpc' @Module({ @@ -22,6 +23,7 @@ import { AccountClientGrpc } from './account.grpc' } ]) ], + controllers: [AccountController], providers: [AccountClientGrpc], exports: [AccountClientGrpc] }) diff --git a/src/modules/account/dto/index.ts b/src/modules/account/dto/index.ts new file mode 100644 index 0000000..66d0236 --- /dev/null +++ b/src/modules/account/dto/index.ts @@ -0,0 +1 @@ +export * from './rq' diff --git a/src/modules/account/dto/rq/confirm-email-change.request.dto.ts b/src/modules/account/dto/rq/confirm-email-change.request.dto.ts new file mode 100644 index 0000000..e726f15 --- /dev/null +++ b/src/modules/account/dto/rq/confirm-email-change.request.dto.ts @@ -0,0 +1,19 @@ +import { ApiProperty } from '@nestjs/swagger' +import { IsEmail, IsNotEmpty, IsNumberString, Length } from 'class-validator' + +export class ConfirmEmailChangeRequestDto { + @ApiProperty({ + example: 'mail@mail.ru' + }) + @IsNotEmpty() + @IsEmail() + email: string + + @ApiProperty({ + example: '123456' + }) + @Length(6, 6) + @IsNotEmpty() + @IsNumberString() + code: string +} diff --git a/src/modules/account/dto/rq/confirm-phone-change.request.dto.ts b/src/modules/account/dto/rq/confirm-phone-change.request.dto.ts new file mode 100644 index 0000000..a0b5fb7 --- /dev/null +++ b/src/modules/account/dto/rq/confirm-phone-change.request.dto.ts @@ -0,0 +1,24 @@ +import { ApiProperty } from '@nestjs/swagger' +import { + IsNotEmpty, + IsNumberString, + IsPhoneNumber, + Length +} from 'class-validator' + +export class ConfirmPhoneChangeRequestDto { + @ApiProperty({ + example: '+79123456789' + }) + @IsNotEmpty() + @IsPhoneNumber() + phone: string + + @ApiProperty({ + example: '123456' + }) + @Length(6, 6) + @IsNotEmpty() + @IsNumberString() + code: string +} diff --git a/src/modules/account/dto/rq/index.ts b/src/modules/account/dto/rq/index.ts new file mode 100644 index 0000000..44bb401 --- /dev/null +++ b/src/modules/account/dto/rq/index.ts @@ -0,0 +1,4 @@ +export * from './init-email-change.request.dto' +export * from './confirm-email-change.request.dto' +export * from './init-phone-change.request.dto' +export * from './confirm-phone-change.request.dto' diff --git a/src/modules/account/dto/rq/init-email-change.request.dto.ts b/src/modules/account/dto/rq/init-email-change.request.dto.ts new file mode 100644 index 0000000..8399a43 --- /dev/null +++ b/src/modules/account/dto/rq/init-email-change.request.dto.ts @@ -0,0 +1,11 @@ +import { ApiProperty } from '@nestjs/swagger' +import { IsEmail, IsNotEmpty } from 'class-validator' + +export class InitEmailChangeRequestDto { + @ApiProperty({ + example: 'mail@mail.ru' + }) + @IsNotEmpty() + @IsEmail() + email: string +} diff --git a/src/modules/account/dto/rq/init-phone-change.request.dto.ts b/src/modules/account/dto/rq/init-phone-change.request.dto.ts new file mode 100644 index 0000000..29c85bf --- /dev/null +++ b/src/modules/account/dto/rq/init-phone-change.request.dto.ts @@ -0,0 +1,11 @@ +import { ApiProperty } from '@nestjs/swagger' +import { IsNotEmpty, IsPhoneNumber } from 'class-validator' + +export class InitPhoneChangeRequestDto { + @ApiProperty({ + example: '+79123456789' + }) + @IsNotEmpty() + @IsPhoneNumber() + phone: string +} diff --git a/yarn.lock b/yarn.lock index 560f0a3..f1a335b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1216,14 +1216,14 @@ "@sinonjs/commons" "^3.0.1" "@teacinema/common@^1.0.0": - version "1.0.0" - resolved "https://git.ksv741.keenetic.pro/api/packages/teacinema/npm/%40teacinema%2Fcommon/-/1.0.0/common-1.0.0.tgz#3b79ae6eb46352ed1544535be094fe0ead244c36" - integrity sha512-L006mySvhRpUlRHf3ONbXA0RG42gbQ9QAnmQuZx4zejHEsWB9702xe18MSYcBilv+lmYkQpiX/g3p8P7suLfqQ== + version "1.0.1" + resolved "https://git.ksv741.keenetic.pro/api/packages/teacinema/npm/%40teacinema%2Fcommon/-/1.0.1/common-1.0.1.tgz#40ad9ced1522b53fa6e46d7f6797cc03193705ab" + integrity sha512-q3DURJbSk3k8MNWFIYaSM4LEcBgPbWa+HJmBz/nzYT4kuYitJVSXxpZ97kr0Ea+81AZwAU3JhQKlkK0SBWUi0A== "@teacinema/contracts@^1.0.0": - version "1.0.6" - resolved "https://git.ksv741.keenetic.pro/api/packages/teacinema/npm/%40teacinema%2Fcontracts/-/1.0.6/contracts-1.0.6.tgz#7aa97d4c3081b791908c90d2a12d771b5fb79bd5" - integrity sha512-2IU2S9hWtKeMpn4zRS9pJAaSryIODrRjS1q9QezQOXF6554vtQlMVr0fLVTGhNmXlbRfuje0f6HggApqPDFMaA== + version "1.0.7" + resolved "https://git.ksv741.keenetic.pro/api/packages/teacinema/npm/%40teacinema%2Fcontracts/-/1.0.7/contracts-1.0.7.tgz#2c75a3118e4126d30f5c8193c4518bac3f1812ff" + integrity sha512-lE14PO/yBphYCu0BGFGyGAyvJ74v+ACz34MXA3fFo/PwThPVpudBReSG6oRyUACRybkN882GKXFU6LrJXvGbrQ== dependencies: "@nestjs/microservices" "^11.1.12" protoc "33.4.0"