From 35567d551fcb1b2adacb409da13e5b80cf449998 Mon Sep 17 00:00:00 2001 From: huongnt3 Date: Wed, 25 Aug 2021 15:53:25 +0700 Subject: [PATCH] Authorization creating task for user --- package-lock.json | 12 +++++++++--- src/auth/user.entity.ts | 5 +++++ src/tasks/task.entity.ts | 15 ++++++++++++++- src/tasks/tasks.controller.ts | 33 +++++++++++++++++++++++---------- src/tasks/tasks.service.ts | 35 +++++++++++++++++++++++++---------- 5 files changed, 76 insertions(+), 24 deletions(-) diff --git a/package-lock.json b/package-lock.json index ca33629..cce1991 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3452,7 +3452,7 @@ "dev": true, "license": "MIT", "engines": { - "node": ">=10" + "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -5727,7 +5727,7 @@ "dev": true, "license": "Apache-2.0", "engines": { - "node": ">=8.12.0" + "node": ">=10.17.0" } }, "node_modules/iconv-lite": { @@ -5989,7 +5989,7 @@ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "license": "MIT", "engines": { - "node": ">=8" + "node": ">=4" } }, "node_modules/is-generator-fn": { @@ -7806,6 +7806,9 @@ }, "bin": { "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" } }, "node_modules/normalize-path": { @@ -8739,6 +8742,9 @@ "inherits": "~2.0.1", "isarray": "0.0.1", "string_decoder": "~0.10.x" + }, + "engines": { + "node": ">= 6" } }, "node_modules/readdirp": { diff --git a/src/auth/user.entity.ts b/src/auth/user.entity.ts index 3c41998..316bacb 100644 --- a/src/auth/user.entity.ts +++ b/src/auth/user.entity.ts @@ -2,11 +2,13 @@ import { BaseEntity, Column, Entity, + OneToMany, PrimaryGeneratedColumn, Unique, } from 'typeorm'; import * as bcrypt from 'bcrypt'; import { hashPassword } from '../utils/common'; +import { Task } from '../tasks/task.entity'; @Entity() @Unique(['username']) @@ -23,6 +25,9 @@ export class User extends BaseEntity { @Column() salt: string; + @OneToMany((type) => Task, (task) => task.user, { eager: true }) + tasks: Task[]; + async validatePassword(password: string): Promise { const hash = await bcrypt.hash(password, this.salt); diff --git a/src/tasks/task.entity.ts b/src/tasks/task.entity.ts index d58ba23..1720ace 100644 --- a/src/tasks/task.entity.ts +++ b/src/tasks/task.entity.ts @@ -1,4 +1,11 @@ -import { BaseEntity, Column, Entity, PrimaryGeneratedColumn } from 'typeorm'; +import { + BaseEntity, + Column, + Entity, + ManyToOne, + PrimaryGeneratedColumn, +} from 'typeorm'; +import { User } from '../auth/user.entity'; // import { TaskStatusValidationPipe } from './pipes/task-status-validation.pipe'; import { TaskStatus } from './task-status.enum'; @@ -15,4 +22,10 @@ export class Task extends BaseEntity { @Column() status: TaskStatus; + + @ManyToOne((type) => User, (user) => user.tasks, { eager: false }) + user: User; + + @Column() + userId: number; } diff --git a/src/tasks/tasks.controller.ts b/src/tasks/tasks.controller.ts index e53b337..460e012 100644 --- a/src/tasks/tasks.controller.ts +++ b/src/tasks/tasks.controller.ts @@ -13,7 +13,8 @@ import { ValidationPipe, } from '@nestjs/common'; import { AuthGuard } from '@nestjs/passport'; -import { filter } from 'rxjs'; +import { GetUser } from '../auth/get-user.decorator'; +import { User } from '../auth/user.entity'; import { CreateTaskDto } from './dto/create-task.dto'; import { GetTasksFilterDto } from './dto/get-tasks-filter.dto'; import { TaskStatusValidationPipe } from './pipes/task-status-validation.pipe'; @@ -29,40 +30,52 @@ export class TasksController { @Get() getTasks( @Query(ValidationPipe) filterTaskDto: GetTasksFilterDto, + @GetUser() user: User, ): Promise { - return this.tasksService.getTasks(filterTaskDto); + return this.tasksService.getTasks(filterTaskDto, user); } @Get('/:id') - getTaskById(@Param('id', ParseIntPipe) id: number): Promise { - return this.tasksService.getTaskById(id); + getTaskById( + @Param('id', ParseIntPipe) id: number, + @GetUser() user: User, + ): Promise { + return this.tasksService.getTaskById(id, user); } // Define parameter implicit @Post() @UsePipes(ValidationPipe) - createTask(@Body() createTaskDto: CreateTaskDto): Promise { - return this.tasksService.createTask(createTaskDto); + createTask( + @Body() createTaskDto: CreateTaskDto, + @GetUser() user: User, + ): Promise { + return this.tasksService.createTask(createTaskDto, user); } @Delete('/:id') - deleteTaskById(@Param('id', ParseIntPipe) id: number): Promise { - return this.tasksService.deleteTaskById(id); + deleteTaskById( + @Param('id', ParseIntPipe) id: number, + @GetUser() user: User, + ): Promise { + return this.tasksService.deleteTaskById(id, user); } @Patch('/:id/status') updateTaskStatus( @Param('id', ParseIntPipe) id: number, @Body('status', TaskStatusValidationPipe) taskStatus: TaskStatus, + @GetUser() user: User, ): Promise { - return this.tasksService.updateTaskStatus(id, taskStatus); + return this.tasksService.updateTaskStatus(id, taskStatus, user); } @Patch('/:id') updateTaskInfo( @Param('id', ParseIntPipe) id: number, @Body('title') createTaskDto: CreateTaskDto, + @GetUser() user: User, ): Promise { - return this.tasksService.updateTaskInfo(id, createTaskDto); + return this.tasksService.updateTaskInfo(id, createTaskDto, user); } } diff --git a/src/tasks/tasks.service.ts b/src/tasks/tasks.service.ts index 93d7b70..8b8c665 100644 --- a/src/tasks/tasks.service.ts +++ b/src/tasks/tasks.service.ts @@ -1,6 +1,7 @@ import { Inject, Injectable, NotFoundException } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Not, Repository } from 'typeorm'; +import { User } from '../auth/user.entity'; import { CreateTaskDto } from './dto/create-task.dto'; import { GetTasksFilterDto } from './dto/get-tasks-filter.dto'; import { TaskStatus } from './task-status.enum'; @@ -14,8 +15,10 @@ export class TasksService { ) {} // constructor(@InjectRepository(Task) private taskRepository: TaskRepository) {} - async getTaskById(id: number): Promise { - const task = await this.taskRepository.findOne(id); + async getTaskById(id: number, user: User): Promise { + const task = await this.taskRepository.findOne({ + where: { id, userId: user.id }, + }); if (!task) { throw new NotFoundException(`Task with ID "${id}" not found`); @@ -24,21 +27,28 @@ export class TasksService { return task; } - async createTask(createTaskDto: CreateTaskDto): Promise { + async createTask(createTaskDto: CreateTaskDto, user: User): Promise { const { title, description } = createTaskDto; const task = new Task(); task.title = title; task.description = description; task.status = TaskStatus.OPEN; + task.user = user; await task.save(); + delete task.user; return task; } - async getTasks(filterTaskDto: GetTasksFilterDto): Promise { + async getTasks( + filterTaskDto: GetTasksFilterDto, + user: User, + ): Promise { const { status, searchString } = filterTaskDto; const query = this.taskRepository.createQueryBuilder('task'); + query.andWhere('task.userId = :userId', { userId: user.id }); + if (status) { query.andWhere('task.status = :status', { status }); } @@ -54,19 +64,23 @@ export class TasksService { return tasks; } - async deleteTaskById(id: number): Promise { - const task: Task = await this.getTaskById(id); + async deleteTaskById(id: number, user: User): Promise { + const task: Task = await this.getTaskById(id, user); // const result = await this.taskRepository.remove(task); - const result = await this.taskRepository.delete(id); + const result = await this.taskRepository.delete({ id, userId: user.id }); if (result.affected == 0) { throw new NotFoundException('Something went wrong when delete task!'); } } - async updateTaskStatus(id: number, status: TaskStatus): Promise { - const task: Task = await this.getTaskById(id); + async updateTaskStatus( + id: number, + status: TaskStatus, + user: User, + ): Promise { + const task: Task = await this.getTaskById(id, user); task.status = status; task.save(); @@ -76,8 +90,9 @@ export class TasksService { async updateTaskInfo( id: number, createTaskDto: CreateTaskDto, + user: User, ): Promise { - const task = await this.getTaskById(id); + const task = await this.getTaskById(id, user); const { title, description } = createTaskDto; task.title = title; task.description = description;