diff --git a/package-lock.json b/package-lock.json index 3c52d83..5fd4ebe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,6 +28,7 @@ "@nestjs/testing": "^9.0.0", "@types/express": "^4.17.13", "@types/jest": "28.1.4", + "@types/multer": "^1.4.9", "@types/node": "^16.0.0", "@types/supertest": "^2.0.11", "@typescript-eslint/eslint-plugin": "^5.0.0", @@ -2043,6 +2044,15 @@ "integrity": "sha512-1Gjee59G25MrQGk8bsNvC6fxNiRgUlGn2wlhGf95a59DrprnnHk80FIMMFG9XHMdrfsuA119ht06QPDXA1Z7tw==", "dev": true }, + "node_modules/@types/multer": { + "version": "1.4.9", + "resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.9.tgz", + "integrity": "sha512-9NSvPJ2E8bNTc8XtJq1Cimx2Wrn2Ah48F15B2Du/hM8a8CHLhVbJMlF3ZCqhvMdht7Sa+YdP0aKP7N4fxDcrrg==", + "dev": true, + "dependencies": { + "@types/express": "*" + } + }, "node_modules/@types/node": { "version": "16.18.60", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.60.tgz", @@ -10311,6 +10321,15 @@ "integrity": "sha512-1Gjee59G25MrQGk8bsNvC6fxNiRgUlGn2wlhGf95a59DrprnnHk80FIMMFG9XHMdrfsuA119ht06QPDXA1Z7tw==", "dev": true }, + "@types/multer": { + "version": "1.4.9", + "resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.9.tgz", + "integrity": "sha512-9NSvPJ2E8bNTc8XtJq1Cimx2Wrn2Ah48F15B2Du/hM8a8CHLhVbJMlF3ZCqhvMdht7Sa+YdP0aKP7N4fxDcrrg==", + "dev": true, + "requires": { + "@types/express": "*" + } + }, "@types/node": { "version": "16.18.60", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.60.tgz", diff --git a/package.json b/package.json index 7b1f592..c2def4b 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "@nestjs/testing": "^9.0.0", "@types/express": "^4.17.13", "@types/jest": "28.1.4", + "@types/multer": "^1.4.9", "@types/node": "^16.0.0", "@types/supertest": "^2.0.11", "@typescript-eslint/eslint-plugin": "^5.0.0", diff --git a/src/auth/auth.controller.ts b/src/auth/auth.controller.ts index 47b9da9..f96019a 100644 --- a/src/auth/auth.controller.ts +++ b/src/auth/auth.controller.ts @@ -1,7 +1,18 @@ -import { Controller, Get, Logger, Query, Res } from '@nestjs/common'; +import { + Body, + Controller, + Get, + Logger, + Patch, + Post, + Query, + Res, + UseInterceptors, +} from '@nestjs/common'; import { Auth42Service } from './auth-42.service'; import { AuthService } from './auth.service'; import { UserSigninResponseDto } from './dto/user-signin-response.dto'; +import { FileInterceptor } from '@nestjs/platform-express'; @Controller('auth') export class AuthController { @@ -11,8 +22,8 @@ export class AuthController { ) {} private readonly logger = new Logger(AuthController.name); - @Get('/signin') - async signin(@Query('code') code: string, @Res() res: any) { + @Post('/signin') + async signin(@Body('code') code: string, @Res() res: any) { // code를 이용해 access token을 받아온다. const accessToken = await this.auth42Service.getAccessToken(code); // access token을 이용해 사용자 정보를 받아온다. @@ -43,4 +54,13 @@ export class AuthController { }; return res.send(userSigninResponseDto); } + + // TODO: AuthGuard + @Patch('/login') + @UseInterceptors(FileInterceptor('image')) + async login(@Body('nickname') nickname: string) { + // nickname validation + await this.authService.validateNickname(nickname); + // + } } diff --git a/src/auth/auth.service.ts b/src/auth/auth.service.ts index 82f03a6..c61bf5f 100644 --- a/src/auth/auth.service.ts +++ b/src/auth/auth.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@nestjs/common'; +import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; import { JwtService } from '@nestjs/jwt'; import { User } from 'src/users/entities/user.entity'; import { UserRepository } from './../users/users.repository'; @@ -33,7 +33,7 @@ export class AuthService { } async generateJwtToken(user: User) { - const payload = { id: user.id, nickname: user.nickname }; + const payload = { id: user.id, email: user.email }; // accessToken 생성 const accessToken = await this.jwtService.signAsync(payload); // refreshToken 생성 @@ -42,4 +42,14 @@ export class AuthService { await this.userRepository.update(user.id, { refreshToken }); return { jwtAccessToken: accessToken, jwtRefreshToken: refreshToken }; } + + async validateNickname(nickname: string) { + const user = await this.userRepository.findOneByNickname(nickname); + if (user) { + throw new HttpException( + '이미 존재하는 닉네임입니다.', + HttpStatus.CONFLICT, + ); + } + } } diff --git a/src/common/pipes/positiveInt.pipe.ts b/src/common/pipes/positiveInt.pipe.ts new file mode 100644 index 0000000..4905dd1 --- /dev/null +++ b/src/common/pipes/positiveInt.pipe.ts @@ -0,0 +1,11 @@ +import { HttpException, Injectable, PipeTransform } from '@nestjs/common'; + +@Injectable() +export class PositiveIntPipe implements PipeTransform { + transform(value: number) { + if (value < 0) { + throw new HttpException('value > 0', 400); + } + return value; + } +} diff --git a/src/users/entities/user.entity.ts b/src/users/entities/user.entity.ts index 5edca78..d7a99bc 100644 --- a/src/users/entities/user.entity.ts +++ b/src/users/entities/user.entity.ts @@ -12,7 +12,7 @@ import { Column, Entity, Unique } from 'typeorm'; @Entity() @Unique(['nickname']) export class User extends BaseEntity { - @Column({ default: null }) + @Column({ unique: true }) @IsString() @Length(1, 10) @Matches(/^[ㄱ-ㅎ가-힣a-zA-Z0-9!]+$/) diff --git a/src/users/users.repository.ts b/src/users/users.repository.ts index 8f74368..144caef 100644 --- a/src/users/users.repository.ts +++ b/src/users/users.repository.ts @@ -6,4 +6,8 @@ export class UserRepository extends Repository { constructor(@InjectRepository(User) private dataSource: DataSource) { super(User, dataSource.manager); } + + async findOneByNickname(nickname: string) { + return await this.findOne({ where: { nickname } }); + } }