nestjs_auth ...
This commit is contained in:
parent
64cd01b669
commit
a1be293719
2
.env
2
.env
@ -4,7 +4,7 @@
|
||||
# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB.
|
||||
# See the documentation for all the connection string options: https://pris.ly/d/connection-strings
|
||||
|
||||
DATABASE_URL="mysql://root:@localhost:3306/test"
|
||||
DATABASE_URL="mysql://root:@localhost:3306/test_user"
|
||||
CORS_ALLOW_ORIGINS = ['http://localhost:8080']
|
||||
CORS_ALLOW_METHOD = "GET,PUT,POST,DELETE,PATCH,OPTIONS"
|
||||
|
||||
|
||||
40
package-lock.json
generated
40
package-lock.json
generated
@ -14,7 +14,7 @@
|
||||
"@nestjs/jwt": "^9.0.0",
|
||||
"@nestjs/passport": "^9.0.0",
|
||||
"@nestjs/platform-express": "^9.0.0",
|
||||
"@prisma/client": "^4.3.0",
|
||||
"@prisma/client": "^4.3.1",
|
||||
"cors": "^2.8.5",
|
||||
"passport": "^0.6.0",
|
||||
"passport-jwt": "^4.0.0",
|
||||
@ -37,7 +37,7 @@
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"jest": "28.1.2",
|
||||
"prettier": "^2.3.2",
|
||||
"prisma": "^4.3.0",
|
||||
"prisma": "^4.3.1",
|
||||
"source-map-support": "^0.5.20",
|
||||
"supertest": "^6.1.3",
|
||||
"ts-jest": "28.0.5",
|
||||
@ -3053,9 +3053,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ci-info": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.2.tgz",
|
||||
"integrity": "sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg==",
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.4.0.tgz",
|
||||
"integrity": "sha512-t5QdPT5jq3o262DOQ8zA6E1tlH2upmUc4Hlvrbx1pGYJuiiHl7O7rvVNI+l8HTVhd/q3Qc9vqimkNk5yiXsAug==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/cjs-module-lexer": {
|
||||
@ -3469,9 +3469,9 @@
|
||||
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
|
||||
},
|
||||
"node_modules/electron-to-chromium": {
|
||||
"version": "1.4.246",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.246.tgz",
|
||||
"integrity": "sha512-/wFCHUE+Hocqr/LlVGsuKLIw4P2lBWwFIDcNMDpJGzyIysQV4aycpoOitAs32FT94EHKnNqDR/CVZJFbXEufJA==",
|
||||
"version": "1.4.247",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.247.tgz",
|
||||
"integrity": "sha512-FLs6R4FQE+1JHM0hh3sfdxnYjKvJpHZyhQDjc2qFq/xFvmmRt/TATNToZhrcGUFzpF2XjeiuozrA8lI0PZmYYw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/emittery": {
|
||||
@ -4014,9 +4014,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/fast-glob": {
|
||||
"version": "3.2.11",
|
||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz",
|
||||
"integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==",
|
||||
"version": "3.2.12",
|
||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz",
|
||||
"integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@nodelib/fs.stat": "^2.0.2",
|
||||
@ -10791,9 +10791,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"ci-info": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.2.tgz",
|
||||
"integrity": "sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg==",
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.4.0.tgz",
|
||||
"integrity": "sha512-t5QdPT5jq3o262DOQ8zA6E1tlH2upmUc4Hlvrbx1pGYJuiiHl7O7rvVNI+l8HTVhd/q3Qc9vqimkNk5yiXsAug==",
|
||||
"dev": true
|
||||
},
|
||||
"cjs-module-lexer": {
|
||||
@ -11119,9 +11119,9 @@
|
||||
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
|
||||
},
|
||||
"electron-to-chromium": {
|
||||
"version": "1.4.246",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.246.tgz",
|
||||
"integrity": "sha512-/wFCHUE+Hocqr/LlVGsuKLIw4P2lBWwFIDcNMDpJGzyIysQV4aycpoOitAs32FT94EHKnNqDR/CVZJFbXEufJA==",
|
||||
"version": "1.4.247",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.247.tgz",
|
||||
"integrity": "sha512-FLs6R4FQE+1JHM0hh3sfdxnYjKvJpHZyhQDjc2qFq/xFvmmRt/TATNToZhrcGUFzpF2XjeiuozrA8lI0PZmYYw==",
|
||||
"dev": true
|
||||
},
|
||||
"emittery": {
|
||||
@ -11535,9 +11535,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"fast-glob": {
|
||||
"version": "3.2.11",
|
||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz",
|
||||
"integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==",
|
||||
"version": "3.2.12",
|
||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz",
|
||||
"integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@nodelib/fs.stat": "^2.0.2",
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
"@nestjs/jwt": "^9.0.0",
|
||||
"@nestjs/passport": "^9.0.0",
|
||||
"@nestjs/platform-express": "^9.0.0",
|
||||
"@prisma/client": "^4.3.0",
|
||||
"@prisma/client": "^4.3.1",
|
||||
"cors": "^2.8.5",
|
||||
"passport": "^0.6.0",
|
||||
"passport-jwt": "^4.0.0",
|
||||
@ -49,7 +49,7 @@
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"jest": "28.1.2",
|
||||
"prettier": "^2.3.2",
|
||||
"prisma": "^4.3.0",
|
||||
"prisma": "^4.3.1",
|
||||
"source-map-support": "^0.5.20",
|
||||
"supertest": "^6.1.3",
|
||||
"ts-jest": "28.0.5",
|
||||
@ -74,5 +74,8 @@
|
||||
],
|
||||
"coverageDirectory": "../coverage",
|
||||
"testEnvironment": "node"
|
||||
},
|
||||
"prisma": {
|
||||
"seed": "ts-node prisma/seed.ts"
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,11 +4,12 @@ CREATE TABLE `User` (
|
||||
`email` VARCHAR(191) NOT NULL,
|
||||
`password` VARCHAR(191) NOT NULL,
|
||||
`name` VARCHAR(191) NOT NULL,
|
||||
`role` VARCHAR(191) NOT NULL DEFAULT 'USER',
|
||||
`role` ENUM('USER', 'ADMIN') NOT NULL DEFAULT 'USER',
|
||||
`is_done` BOOLEAN NULL DEFAULT false,
|
||||
`updatedAt` TIMESTAMP(0) NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
|
||||
UNIQUE INDEX `User_email_key`(`email`),
|
||||
INDEX `email`(`email`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
@ -1,6 +1,3 @@
|
||||
// This is your Prisma schema file,
|
||||
// learn more about it in the docs: https://pris.ly/d/prisma-schema
|
||||
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
}
|
||||
@ -10,14 +7,20 @@ datasource db {
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
//만들려는 모델
|
||||
model User {
|
||||
id Int @id @default(autoincrement())
|
||||
email String @unique
|
||||
password String
|
||||
name String
|
||||
role String @default("USER")
|
||||
is_done Boolean? @default(false)
|
||||
id Int @id @default(autoincrement())
|
||||
email String @unique(map: "User_email_key")
|
||||
password String
|
||||
name String
|
||||
role ROLE @default(USER)
|
||||
is_done Boolean? @default(false)
|
||||
updatedAt DateTime? @db.Timestamp(0)
|
||||
createdAt DateTime @default(now())
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@index([email], name: "email")
|
||||
}
|
||||
|
||||
enum ROLE {
|
||||
USER
|
||||
ADMIN
|
||||
}
|
||||
@ -1,5 +1,13 @@
|
||||
/* eslint-disable prettier/prettier */
|
||||
import { Body, Controller, Get, Post, Request, UseGuards } from '@nestjs/common'
|
||||
import {
|
||||
Body,
|
||||
Controller,
|
||||
Get,
|
||||
Param,
|
||||
Post,
|
||||
UseGuards,
|
||||
Request
|
||||
} from '@nestjs/common'
|
||||
import { User } from '@prisma/client'
|
||||
import { UserDTO } from 'src/user/dtos/user.dto'
|
||||
import { AuthService } from './auth.service'
|
||||
@ -13,9 +21,9 @@ export class AuthController {
|
||||
//Login용
|
||||
@UseGuards(LocalAuthGuard)
|
||||
@Post('login')
|
||||
login(@Request() req) {
|
||||
login(@Param('email') email: string, @Param('password') password: string) {
|
||||
//console.log(req)
|
||||
return this.authService.login(req.user)
|
||||
return this.authService.login(email, password)
|
||||
}
|
||||
|
||||
//Profile 여부 확인용
|
||||
|
||||
@ -6,7 +6,7 @@ import { Module } from '@nestjs/common'
|
||||
import { PassportModule } from '@nestjs/passport'
|
||||
import { AuthService } from './auth.service'
|
||||
import { JwtModule } from '@nestjs/jwt'
|
||||
import { jwtAcceesTokenTypes } from './guards/jwt.constants'
|
||||
import { jwtAcceesTokenOptions } from './guards/jwt.constants'
|
||||
import { AuthController } from './auth.controller'
|
||||
import { LocalStrategy } from './guards/local.strategy'
|
||||
import { JwtStrategy } from './guards/jwt.strategy'
|
||||
@ -17,8 +17,8 @@ import { UsersModule } from '../user/user.module'
|
||||
UsersModule,
|
||||
PassportModule,
|
||||
JwtModule.register({
|
||||
secret: jwtAcceesTokenTypes.secret,
|
||||
signOptions: { expiresIn: jwtAcceesTokenTypes.expiresIn }
|
||||
secret: jwtAcceesTokenOptions.secret,
|
||||
signOptions: { expiresIn: jwtAcceesTokenOptions.expiresIn }
|
||||
})
|
||||
],
|
||||
controllers: [AuthController],
|
||||
|
||||
@ -4,6 +4,10 @@ import { JwtService } from '@nestjs/jwt'
|
||||
import { User } from '@prisma/client'
|
||||
import { UserDTO } from 'src/user/dtos/user.dto'
|
||||
import { UserService } from '../user/user.service'
|
||||
import {
|
||||
jwtAcceesTokenOptions,
|
||||
jwtRefreshTokenTypes
|
||||
} from './guards/jwt.constants'
|
||||
|
||||
@Injectable()
|
||||
export class AuthService {
|
||||
@ -13,8 +17,8 @@ export class AuthService {
|
||||
) {}
|
||||
|
||||
//app.controller.ts에서 @UseGuards(AuthGuard('local'))용
|
||||
async validateUser(email: string, password: string): Promise<any> {
|
||||
const user = await this.userService.fetchOneByEmail(email)
|
||||
async validateUser(email: string, password: string): Promise<any> | null {
|
||||
const user = await this.userService.fetchOne({ email: email })
|
||||
if (user && user.password === password) {
|
||||
const { password, ...result } = user
|
||||
// result는 password 를 제외한 user의 모든 정보를 포함한다.
|
||||
@ -25,17 +29,37 @@ export class AuthService {
|
||||
return null
|
||||
}
|
||||
|
||||
async login(user: any) {
|
||||
async getTokens(user: User): Promise<any> {
|
||||
//console.log(user)
|
||||
const payload = {
|
||||
const access_token_payload = {
|
||||
email: user.email,
|
||||
name: user.name
|
||||
}
|
||||
const refresh_token_payload = {}
|
||||
// console.log(payload)
|
||||
return await { access_token: this.jwtService.sign(payload) }
|
||||
return {
|
||||
tokens: {
|
||||
access_token: this.jwtService.sign(
|
||||
access_token_payload,
|
||||
jwtAcceesTokenOptions
|
||||
),
|
||||
refresh_token: this.jwtService.sign(
|
||||
refresh_token_payload,
|
||||
jwtRefreshTokenTypes
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async register(data: UserDTO): Promise<User> {
|
||||
return await this.userService.add(data)
|
||||
async login(email: string, password: string): Promise<any> | null {
|
||||
const user = await this.validateUser(email, password)
|
||||
if (!user) return null
|
||||
return await this.getTokens(user)
|
||||
}
|
||||
|
||||
async register(data: UserDTO): Promise<any> | null {
|
||||
const user = await this.userService.add(data)
|
||||
if (!user) return null
|
||||
return await this.getTokens(user)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +0,0 @@
|
||||
export enum Role {
|
||||
USER = 'USER',
|
||||
ADMIN = 'ADMIN'
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
import { SetMetadata } from '@nestjs/common'
|
||||
import { Role } from './role.enum'
|
||||
import { ROLE } from '@prisma/client'
|
||||
|
||||
export const ROLES_KEY = 'roles'
|
||||
export const Roles = (...roles: Role[]) => SetMetadata(ROLES_KEY, roles)
|
||||
export const Roles = (...roles: ROLE[]) => SetMetadata(ROLES_KEY, roles)
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export const jwtAcceesTokenTypes = {
|
||||
export const jwtAcceesTokenOptions = {
|
||||
secret: process.env.JWT_ACCESS_TOKEN_SECRET,
|
||||
expiresIn: process.env.JWT_ACCESS_TOKEN_EXPIREIN,
|
||||
issuer: process.env.JWT_ACCESS_TOKEN_ISSUER
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { ExtractJwt, Strategy } from 'passport-jwt'
|
||||
import { PassportStrategy } from '@nestjs/passport'
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { jwtAcceesTokenTypes } from './jwt.constants'
|
||||
import { jwtAcceesTokenOptions } from './jwt.constants'
|
||||
|
||||
@Injectable()
|
||||
export class JwtStrategy extends PassportStrategy(Strategy) {
|
||||
@ -9,7 +9,7 @@ export class JwtStrategy extends PassportStrategy(Strategy) {
|
||||
super({
|
||||
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
|
||||
ignoreExpiration: false,
|
||||
secretOrKey: jwtAcceesTokenTypes.secret
|
||||
secretOrKey: jwtAcceesTokenOptions.secret
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common'
|
||||
import { Reflector } from '@nestjs/core'
|
||||
import { ROLE } from '@prisma/client'
|
||||
import { Observable } from 'rxjs'
|
||||
import { ROLES_KEY } from '../decorators/roles.decorator'
|
||||
import { Role } from '../decorators/role.enum'
|
||||
|
||||
//참고: https://shpota.com/2022/07/16/role-based-authorization-with-jwt-using-nestjs.html
|
||||
@Injectable()
|
||||
@ -12,7 +12,7 @@ export class RolesGuard implements CanActivate {
|
||||
canActivate(
|
||||
context: ExecutionContext
|
||||
): boolean | Promise<boolean> | Observable<boolean> {
|
||||
const requiredRoles = this.reflector.getAllAndOverride<Role[]>(ROLES_KEY, [
|
||||
const requiredRoles = this.reflector.getAllAndOverride<ROLE[]>(ROLES_KEY, [
|
||||
context.getHandler(),
|
||||
context.getClass()
|
||||
])
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
import { ROLE, User } from '@prisma/client'
|
||||
|
||||
export class UserDTO {
|
||||
email: string
|
||||
password: string
|
||||
name: string
|
||||
role?: string | 'USER'
|
||||
role?: ROLE | 'USER'
|
||||
is_done?: boolean | false
|
||||
updatedAt?: Date | null
|
||||
createdAt?: Date
|
||||
|
||||
@ -15,14 +15,14 @@ import { UserDTO } from './dtos/user.dto'
|
||||
import { UserService } from './user.service'
|
||||
import { Roles } from '../auth/decorators/roles.decorator'
|
||||
import { JwtAuthGuard } from '../auth/guards/jwt.auth.guard'
|
||||
import { Role } from '../auth/decorators/role.enum'
|
||||
import { RolesGuard } from '../auth/guards/roles.guard'
|
||||
import { ROLE } from '@prisma/client'
|
||||
|
||||
@Controller('user')
|
||||
export class UserController {
|
||||
constructor(private readonly userService: UserService) {}
|
||||
|
||||
@Roles(Role.ADMIN)
|
||||
@Roles(ROLE.ADMIN)
|
||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||
@Get()
|
||||
async fetchAll(@Query() query): Promise<any> {
|
||||
@ -129,21 +129,21 @@ export class UserController {
|
||||
return result
|
||||
}
|
||||
|
||||
@Roles(Role.ADMIN)
|
||||
@Roles(ROLE.ADMIN)
|
||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||
@Get(':id')
|
||||
async fetchOne(@Param('id') id: string): Promise<User | undefined> {
|
||||
return await this.userService.fetchOne({ id: Number(id) })
|
||||
}
|
||||
|
||||
@Roles(Role.ADMIN)
|
||||
@Roles(ROLE.ADMIN)
|
||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||
@Post('add')
|
||||
async add(@Body() data: UserDTO): Promise<User> {
|
||||
return await this.userService.add(data)
|
||||
}
|
||||
|
||||
@Roles(Role.ADMIN)
|
||||
@Roles(ROLE.ADMIN)
|
||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||
@Put(':id')
|
||||
async update(@Param('id') id: string, @Body() data: UserDTO): Promise<User> {
|
||||
@ -154,7 +154,7 @@ export class UserController {
|
||||
})
|
||||
}
|
||||
|
||||
@Roles(Role.ADMIN)
|
||||
@Roles(ROLE.ADMIN)
|
||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||
@Delete(':id')
|
||||
async delete(@Param('id') id: string): Promise<User | undefined> {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/* eslint-disable prettier/prettier */
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { Prisma, User } from '@prisma/client'
|
||||
import { PrismaService } from '../prisma.service'
|
||||
import { PrismaService } from 'src/prisma.service'
|
||||
|
||||
@Injectable()
|
||||
export class UserService {
|
||||
@ -12,18 +12,13 @@ export class UserService {
|
||||
})
|
||||
}
|
||||
|
||||
//단일 조회 ByEmail
|
||||
async fetchOneByEmail(email: string): Promise<User | undefined> {
|
||||
return this.prisma.user.findUnique({ where: { email: email } })
|
||||
}
|
||||
|
||||
//전체조회
|
||||
async count(params: {
|
||||
cursor?: Prisma.UserWhereUniqueInput
|
||||
where?: Prisma.UserWhereInput
|
||||
}): Promise<number> {
|
||||
const { cursor, where } = params
|
||||
return this.prisma.user.count({
|
||||
return await this.prisma.user.count({
|
||||
cursor,
|
||||
where
|
||||
})
|
||||
@ -38,7 +33,7 @@ export class UserService {
|
||||
orderBy?: Prisma.UserOrderByWithRelationInput
|
||||
}): Promise<User[]> {
|
||||
const { skip, take, cursor, where, orderBy } = params
|
||||
return this.prisma.user.findMany({
|
||||
return await this.prisma.user.findMany({
|
||||
skip,
|
||||
take,
|
||||
cursor,
|
||||
@ -49,12 +44,12 @@ export class UserService {
|
||||
|
||||
//단일 조회
|
||||
async fetchOne(where: Prisma.UserWhereUniqueInput): Promise<User | null> {
|
||||
return this.prisma.user.findUnique({ where })
|
||||
return await this.prisma.user.findUnique({ where })
|
||||
}
|
||||
|
||||
//단일 추가
|
||||
async add(data: Prisma.UserCreateInput): Promise<User> {
|
||||
return this.prisma.user.create({ data })
|
||||
return await this.prisma.user.create({ data })
|
||||
}
|
||||
|
||||
//단일 수정
|
||||
@ -63,7 +58,7 @@ export class UserService {
|
||||
data: Prisma.UserUpdateInput
|
||||
}): Promise<User | null> {
|
||||
const { where, data } = params
|
||||
return this.prisma.user.update({
|
||||
return await this.prisma.user.update({
|
||||
data,
|
||||
where
|
||||
})
|
||||
@ -71,6 +66,6 @@ export class UserService {
|
||||
|
||||
//단일 삭제
|
||||
async remove(where: Prisma.UserWhereUniqueInput): Promise<User | null> {
|
||||
return this.prisma.user.delete({ where })
|
||||
return await this.prisma.user.delete({ where })
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user