From d4f6032232383a6812ec5bcd856009868eec11c6 Mon Sep 17 00:00:00 2001 From: vigdorov Date: Sat, 8 Aug 2020 16:14:05 +0300 Subject: [PATCH] =?UTF-8?q?HM-109.=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B0=20=D1=80=D1=83=D1=87=D0=BA=D0=B0=20=D0=B4?= =?UTF-8?q?=D0=BB=D1=8F=20=D1=81=D0=BC=D0=B5=D0=BD=D1=8B=20=D0=BF=D0=B0?= =?UTF-8?q?=D1=80=D0=BE=D0=BB=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/users/users.contoller.ts | 74 +++++++++++++++++++++++------------- src/users/users.responses.ts | 12 ++++++ src/users/users.schema.ts | 17 ++++++++- src/users/users.service.ts | 19 ++++++++- users.http | 14 ++++++- 5 files changed, 104 insertions(+), 32 deletions(-) diff --git a/src/users/users.contoller.ts b/src/users/users.contoller.ts index 8c4050c..b8709ac 100644 --- a/src/users/users.contoller.ts +++ b/src/users/users.contoller.ts @@ -1,36 +1,39 @@ import {Controller, Get, Req, Post, Options, Header, Delete, HttpCode, Put} from '@nestjs/common'; -import { ApiResponse, ApiTags, ApiParam, ApiBody } from '@nestjs/swagger'; +import {ApiResponse, ApiTags, ApiParam, ApiBody} from '@nestjs/swagger'; import { - ALLOW_ORIGIN_ALL, - ALLOW_METHOD, - ALLOW_CREDENTIALS, - CONTENT_LENGTH, - ALLOW_HEADERS, - USERS_CONTROLLER, + ALLOW_ORIGIN_ALL, + ALLOW_METHOD, + ALLOW_CREDENTIALS, + CONTENT_LENGTH, + ALLOW_HEADERS, + USERS_CONTROLLER, } from '../consts'; -import { UserService } from './users.service'; +import {UserService} from './users.service'; import { - UserResponse, - CreateUserRequest, - UpdateUserRequest, - UpdateUserSelf, + UserResponse, + CreateUserRequest, + UpdateUserRequest, + UpdateUserSelf, + ChangePasswordRequest, } from './users.schema'; -import { Request } from 'express'; +import {Request} from 'express'; import { - FIND_ALL_SUCCESS, - FIND_ONE_SUCCESS, - FIND_ONE_NOT_FOUND, - CREATE_SUCCESS, - CREATE_CONFLICT, - CREATE_NOT_VALID, - UPDATE_SUCCESS, - UPDATE_NOT_FOUND, - UPDATE_NOT_VALID, - REMOVE_SUCCESS, - REMOVE_NOT_FOUND, - EDIT_ME_SUCCESS, - EDIT_ME_NOT_VALID, + FIND_ALL_SUCCESS, + FIND_ONE_SUCCESS, + FIND_ONE_NOT_FOUND, + CREATE_SUCCESS, + CREATE_CONFLICT, + CREATE_NOT_VALID, + UPDATE_SUCCESS, + UPDATE_NOT_FOUND, + UPDATE_NOT_VALID, + REMOVE_SUCCESS, + REMOVE_NOT_FOUND, + EDIT_ME_SUCCESS, + EDIT_ME_NOT_VALID, + CHANGE_PASSWORD_SUCCESS, + CHANGE_PASSWORD_NOT_VALID, } from './users.responses'; import {AuthService} from 'src/auth/auth.service'; @@ -78,6 +81,10 @@ export class UsersController { @Header(...ALLOW_ORIGIN_ALL) @ApiResponse(EDIT_ME_SUCCESS) @ApiResponse(EDIT_ME_NOT_VALID) + @ApiBody({ + type: UpdateUserSelf, + description: 'Объект обновления пользователя', + }) async findEdit(@Req() request: Request): Promise { await this.authService.checkRequest(request); @@ -128,6 +135,21 @@ export class UsersController { return await this.userService.removeOne(request.params.login); } + @Post('change-password') + @Header(...ALLOW_ORIGIN_ALL) + @ApiResponse(CHANGE_PASSWORD_SUCCESS) + @ApiResponse(CHANGE_PASSWORD_NOT_VALID) + @ApiBody({ + type: ChangePasswordRequest, + description: 'Объект изменения пароля', + }) + async changePassword(@Req() request: Request): Promise { + await this.authService.checkRequest(request); + + const {headers, body} = request; + return await this.userService.changePassword(headers.authorization, body.old_password, body.new_password); + } + @Options([ '', 'search/:login', ':login', 'me', 'edit-me' ]) diff --git a/src/users/users.responses.ts b/src/users/users.responses.ts index 68488e5..565905e 100644 --- a/src/users/users.responses.ts +++ b/src/users/users.responses.ts @@ -96,3 +96,15 @@ export const EDIT_ME_NOT_VALID: ApiResponseOptions = { description: 'Ошибка при попытке обновить пользователя с невалидными полями', type: Error, }; + +export const CHANGE_PASSWORD_SUCCESS: ApiResponseOptions = { + status: 200, + description: 'Возвращает "ok" при успешном изменении пароля', + type: String, +}; + +export const CHANGE_PASSWORD_NOT_VALID: ApiResponseOptions = { + status: 400, + description: 'Ошибка при не верном вводе старого пароля', + type: Error, +}; diff --git a/src/users/users.schema.ts b/src/users/users.schema.ts index 209134d..ae4ad6c 100644 --- a/src/users/users.schema.ts +++ b/src/users/users.schema.ts @@ -1,6 +1,6 @@ -import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; +import {Prop, Schema, SchemaFactory} from '@nestjs/mongoose'; import {ApiProperty} from '@nestjs/swagger'; -import { Document } from 'mongoose'; +import {Document} from 'mongoose'; export class CreateUserRequest { @ApiProperty() @@ -67,6 +67,14 @@ export class CheckAuthTokenRequest { agent: string; } +export class ChangePasswordRequest { + @ApiProperty() + old_password: string; + + @ApiProperty() + new_password: string; +} + export class RefreshAuthRequest { @ApiProperty() refresh_token: string; @@ -107,6 +115,11 @@ export class User extends Document { type: Boolean, }) is_admin: boolean; + + @Prop({ + type: String, + }) + salt: string; } @Schema() diff --git a/src/users/users.service.ts b/src/users/users.service.ts index 4ba7845..0bd97ae 100644 --- a/src/users/users.service.ts +++ b/src/users/users.service.ts @@ -198,7 +198,7 @@ export class UserService { } catch (e) { return false; } - + const token = jwt.decode(access_token) as Token; const searchUser = await this.findUser(token.login); return searchUser && this.checkToken(token, agent); @@ -216,4 +216,19 @@ export class UserService { login, }); } -} \ No newline at end of file + + async changePassword(access_token: string, old_password: string, new_password: string): Promise { + const {login} = jwt.decode(access_token) as Token; + const user = await this.userModel().findOne({login}); + if (user && await this.checkPassword(old_password, user.password)) { + const salt = user.salt; + const password = await bcrypt.hash(new_password, salt); + await user.updateOne({ + password, + }); + + return 'ok'; + } + throw new BadRequestException('Unauthorized request'); + } +} diff --git a/users.http b/users.http index 72e87a6..adcb4eb 100644 --- a/users.http +++ b/users.http @@ -9,7 +9,7 @@ POST http://localhost:4002/users HTTP/1.1 content-type: application/json { - "login": "gfhHfgDHDU89", + "login": "string", "avatar": "string", "password": "string" } @@ -62,4 +62,14 @@ Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsb2dpbiI6InN0cmluZyIsImFn { "avatar": "hui" -} \ No newline at end of file +} + +### +POST http://localhost:4002/users/change-password HTTP/1.1 +content-type: application/json +Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsb2dpbiI6InN0cmluZyIsImFnZW50IjoidnNjb2RlLXJlc3RjbGllbnQiLCJpYXQiOjE1OTY4OTE3NjIsImV4cCI6MTU5Njg5MTc4Mn0.u_sYoVdCPjioimDZ-m7j3wAvgvaiw-pAl-OL5ei87K8 + +{ + "old_password": "string32", + "new_password": "string" +}