HM-109. Добавлена ручка для смены пароля

This commit is contained in:
vigdorov
2020-08-08 16:14:05 +03:00
parent 96d3232f9f
commit d4f6032232
5 changed files with 104 additions and 32 deletions

View File

@ -1,36 +1,39 @@
import {Controller, Get, Req, Post, Options, Header, Delete, HttpCode, Put} from '@nestjs/common'; 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 { import {
ALLOW_ORIGIN_ALL, ALLOW_ORIGIN_ALL,
ALLOW_METHOD, ALLOW_METHOD,
ALLOW_CREDENTIALS, ALLOW_CREDENTIALS,
CONTENT_LENGTH, CONTENT_LENGTH,
ALLOW_HEADERS, ALLOW_HEADERS,
USERS_CONTROLLER, USERS_CONTROLLER,
} from '../consts'; } from '../consts';
import { UserService } from './users.service'; import {UserService} from './users.service';
import { import {
UserResponse, UserResponse,
CreateUserRequest, CreateUserRequest,
UpdateUserRequest, UpdateUserRequest,
UpdateUserSelf, UpdateUserSelf,
ChangePasswordRequest,
} from './users.schema'; } from './users.schema';
import { Request } from 'express'; import {Request} from 'express';
import { import {
FIND_ALL_SUCCESS, FIND_ALL_SUCCESS,
FIND_ONE_SUCCESS, FIND_ONE_SUCCESS,
FIND_ONE_NOT_FOUND, FIND_ONE_NOT_FOUND,
CREATE_SUCCESS, CREATE_SUCCESS,
CREATE_CONFLICT, CREATE_CONFLICT,
CREATE_NOT_VALID, CREATE_NOT_VALID,
UPDATE_SUCCESS, UPDATE_SUCCESS,
UPDATE_NOT_FOUND, UPDATE_NOT_FOUND,
UPDATE_NOT_VALID, UPDATE_NOT_VALID,
REMOVE_SUCCESS, REMOVE_SUCCESS,
REMOVE_NOT_FOUND, REMOVE_NOT_FOUND,
EDIT_ME_SUCCESS, EDIT_ME_SUCCESS,
EDIT_ME_NOT_VALID, EDIT_ME_NOT_VALID,
CHANGE_PASSWORD_SUCCESS,
CHANGE_PASSWORD_NOT_VALID,
} from './users.responses'; } from './users.responses';
import {AuthService} from 'src/auth/auth.service'; import {AuthService} from 'src/auth/auth.service';
@ -78,6 +81,10 @@ export class UsersController {
@Header(...ALLOW_ORIGIN_ALL) @Header(...ALLOW_ORIGIN_ALL)
@ApiResponse(EDIT_ME_SUCCESS) @ApiResponse(EDIT_ME_SUCCESS)
@ApiResponse(EDIT_ME_NOT_VALID) @ApiResponse(EDIT_ME_NOT_VALID)
@ApiBody({
type: UpdateUserSelf,
description: 'Объект обновления пользователя',
})
async findEdit(@Req() request: Request<null, UpdateUserSelf>): Promise<UserResponse> { async findEdit(@Req() request: Request<null, UpdateUserSelf>): Promise<UserResponse> {
await this.authService.checkRequest(request); await this.authService.checkRequest(request);
@ -128,6 +135,21 @@ export class UsersController {
return await this.userService.removeOne(request.params.login); 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<null, {old_password: string, new_password: string}>): Promise<string> {
await this.authService.checkRequest(request);
const {headers, body} = request;
return await this.userService.changePassword(headers.authorization, body.old_password, body.new_password);
}
@Options([ @Options([
'', 'search/:login', ':login', 'me', 'edit-me' '', 'search/:login', ':login', 'me', 'edit-me'
]) ])

View File

@ -96,3 +96,15 @@ export const EDIT_ME_NOT_VALID: ApiResponseOptions = {
description: 'Ошибка при попытке обновить пользователя с невалидными полями', description: 'Ошибка при попытке обновить пользователя с невалидными полями',
type: Error, 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,
};

View File

@ -1,6 +1,6 @@
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; import {Prop, Schema, SchemaFactory} from '@nestjs/mongoose';
import {ApiProperty} from '@nestjs/swagger'; import {ApiProperty} from '@nestjs/swagger';
import { Document } from 'mongoose'; import {Document} from 'mongoose';
export class CreateUserRequest { export class CreateUserRequest {
@ApiProperty() @ApiProperty()
@ -67,6 +67,14 @@ export class CheckAuthTokenRequest {
agent: string; agent: string;
} }
export class ChangePasswordRequest {
@ApiProperty()
old_password: string;
@ApiProperty()
new_password: string;
}
export class RefreshAuthRequest { export class RefreshAuthRequest {
@ApiProperty() @ApiProperty()
refresh_token: string; refresh_token: string;
@ -107,6 +115,11 @@ export class User extends Document {
type: Boolean, type: Boolean,
}) })
is_admin: boolean; is_admin: boolean;
@Prop({
type: String,
})
salt: string;
} }
@Schema() @Schema()

View File

@ -198,7 +198,7 @@ export class UserService {
} catch (e) { } catch (e) {
return false; return false;
} }
const token = jwt.decode(access_token) as Token; const token = jwt.decode(access_token) as Token;
const searchUser = await this.findUser(token.login); const searchUser = await this.findUser(token.login);
return searchUser && this.checkToken(token, agent); return searchUser && this.checkToken(token, agent);
@ -216,4 +216,19 @@ export class UserService {
login, login,
}); });
} }
}
async changePassword(access_token: string, old_password: string, new_password: string): Promise<string> {
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');
}
}

View File

@ -9,7 +9,7 @@ POST http://localhost:4002/users HTTP/1.1
content-type: application/json content-type: application/json
{ {
"login": "gfhHfgDHDU89", "login": "string",
"avatar": "string", "avatar": "string",
"password": "string" "password": "string"
} }
@ -62,4 +62,14 @@ Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsb2dpbiI6InN0cmluZyIsImFn
{ {
"avatar": "hui" "avatar": "hui"
} }
###
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"
}