diff --git a/src/auth/auth.service.ts b/src/auth/auth.service.ts index 92d4a2f..725b4db 100644 --- a/src/auth/auth.service.ts +++ b/src/auth/auth.service.ts @@ -1,5 +1,7 @@ import {Injectable, UnauthorizedException, HttpService} from '@nestjs/common'; import {Request} from 'express'; +import * as jwt from 'jsonwebtoken'; +import {Token} from 'src/users/types'; @Injectable() export class AuthService { @@ -7,7 +9,7 @@ export class AuthService { private http: HttpService ) {} - async checkRequest(request: Request): Promise { + async checkRequest(request: Request): Promise { const {data} = await this.http.post('http://api.auth.vigdorov.ru/auth/check', { access_token: request.headers.authorization, agent: request.headers['user-agent'] @@ -16,6 +18,7 @@ export class AuthService { if (!data) { throw new UnauthorizedException('Доступ запрещен'); } - return data; + + return jwt.decode(request.headers.authorization) as Token; } } diff --git a/src/users/types.ts b/src/users/types.ts new file mode 100644 index 0000000..35c6493 --- /dev/null +++ b/src/users/types.ts @@ -0,0 +1,6 @@ +export interface Token { + login: string; + agent: string; + iat: number; + exp: number; +} diff --git a/src/users/users.contoller.ts b/src/users/users.contoller.ts index fe23527..c21b1f0 100644 --- a/src/users/users.contoller.ts +++ b/src/users/users.contoller.ts @@ -102,9 +102,9 @@ export class UsersController { description: 'Объект для создания пользователя' }) async createUser(@Req() request: Request): Promise { - await this.authService.checkRequest(request); + const {login} = await this.authService.checkRequest(request); - return await this.userService.create(request.body); + return await this.userService.create(request.body, login); } @Put() @@ -117,9 +117,9 @@ export class UsersController { description: 'Объект обновления данных пользователя' }) async updateUser(@Req() request: Request): Promise { - await this.authService.checkRequest(request); + const {login} = await this.authService.checkRequest(request); - return await this.userService.update(request.body); + return await this.userService.updateUser(request.body, login); } @Delete(':login') @@ -131,9 +131,9 @@ export class UsersController { description: 'Логин пользователя', }) async removeUser(@Req() request: Request<{login: string}>): Promise { - await this.authService.checkRequest(request); + const {login} = await this.authService.checkRequest(request); - return await this.userService.removeOne(request.params.login); + return await this.userService.removeOne(request.params.login, login); } @Post('change-password') diff --git a/src/users/users.schema.ts b/src/users/users.schema.ts index ae4ad6c..d5a2c5f 100644 --- a/src/users/users.schema.ts +++ b/src/users/users.schema.ts @@ -19,6 +19,9 @@ export class UpdateUserRequest { @ApiProperty() avatar: string; + + @ApiProperty() + is_admin: boolean; } export class UpdateUserSelf { diff --git a/src/users/users.service.ts b/src/users/users.service.ts index 609c80f..eb3f4bf 100644 --- a/src/users/users.service.ts +++ b/src/users/users.service.ts @@ -1,17 +1,11 @@ import {Model, Connection, Document} from 'mongoose'; -import {Injectable, NotFoundException, BadGatewayException, ConflictException, BadRequestException} from '@nestjs/common'; +import {Injectable, NotFoundException, BadGatewayException, ConflictException, BadRequestException, NotAcceptableException} from '@nestjs/common'; import {InjectConnection} from '@nestjs/mongoose'; import {DB_NAME, USERS_CONTROLLER, SECRET_JWT_ACCESS_KEY, SECRET_JWT_REFRESH_KEY} from 'src/consts'; import {User, UserSchema, CreateUserRequest, UserResponse, UserModel, UpdateUserRequest, TokenResponse, UpdateUserSelf} from './users.schema'; import * as bcrypt from 'bcrypt'; import * as jwt from 'jsonwebtoken'; - -interface Token { - login: string; - agent: string; - iat: number; - exp: number; -} +import {Token} from './types'; const validateModel = async (user: Document) => { try { @@ -62,7 +56,13 @@ export class UserService { return users.map(prepareUserToUserResponse); } - async create(user: CreateUserRequest): Promise { + async create(user: CreateUserRequest, requesterLogin: string): Promise { + const requester = await this.findUser(requesterLogin); + + if (!requester.is_admin) { + throw new NotAcceptableException(`Действие запрещено`); + } + const searchUser = await this.findUser(user.login); if (searchUser) { @@ -122,15 +122,20 @@ export class UserService { } await searchUser.updateOne({ - ...{ - avatar: user.avatar, - }, + is_admin: user.is_admin, + avatar: user.avatar, }); return prepareUserToUserResponse(updateUser); } - async removeOne(login: string): Promise { + async removeOne(login: string, requesterLogin: string): Promise { + const requester = await this.findUser(requesterLogin); + + if (!requester.is_admin) { + throw new NotAcceptableException(`Действие запрещено`); + } + if (login === 'admin') { throw new BadRequestException('Запрещено удалять пользователя admin'); } @@ -217,11 +222,23 @@ export class UserService { return await this.findOne(token.login); } + async updateUser(user: UpdateUserRequest, requesterLogin: string): Promise { + const requester = await this.findUser(requesterLogin); + + if (!requester.is_admin) { + throw new NotAcceptableException(`Действие запрещено`); + } + + return await this.update(user); + } + async updateSelf(access_token: string, {avatar}: UpdateUserSelf): Promise { const {login} = jwt.decode(access_token) as Token; + const requester = await this.findUser(login); return await this.update({ avatar, login, + is_admin: requester.is_admin, }); }