Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[강지은] 휴대폰 인증 API #11

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,11 @@ module.exports = {
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'prettier/prettier': [
'error',
{
endOfLine: 'auto',
},
],
},
};
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ Ran all test suites.
2. 010-1234-5678로 전송된 인증번호를 입력하면 인증이 완료된다.

총 2개의 API 엔드포인트로 구성한다.
- 휴대전화 번호를 인증번호를 전송하는 API
- 휴대전화 번호로 인증번호를 전송하는 API
- 실제 휴대전화 번호로 전송되는 것이 아니라, 휴대전화 번호를 입력하면 인증번호가 전송된다고 가정한다.
- 인증번호은 인증 요청시간으로부터 5분간 유효하다고 가정한다.
- 인증번호는 인증 요청시간으로부터 5분간 유효하다고 가정한다.
- 인증번호 전송시에는 API 응답으로 인증번호를 리턴한다.


Expand Down Expand Up @@ -98,4 +98,4 @@ result : true
## ✏️ 과제 진행 요구 사항

- 미션은 [nest-phone-verify](https://github.com/eojjeoda-nest/nest-phone-verify-1) 저장소를 Fork & Clone 하고 시작한다.
- **기능을 구현하기 전 `README.md`에 구현할 기능/예외처리를 목록으로 정리**해 추가한다.
- **기능을 구현하기 전 `README.md`에 구현할 기능/예외처리를 목록으로 정리**해 추가한다.
File renamed without changes.
2 changes: 1 addition & 1 deletion template/package/package.typeorm.json → package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"@nestjs/swagger": "^7.1.13",
"@nestjs/typeorm": "^10.0.0",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
"class-validator": "^0.14.1",
"dotenv": "^16.3.1",
"mysql2": "^3.6.1",
"reflect-metadata": "^0.1.13",
Expand Down
11 changes: 11 additions & 0 deletions src/api/phone-verify/dto/phone-verify.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { IsNotEmpty, IsString } from 'class-validator';

export class PhoneVerifyDto {
@IsNotEmpty()
@IsString()
readonly phoneNumber: string;

@IsNotEmpty()
@IsString()
readonly code: string;
}
7 changes: 7 additions & 0 deletions src/api/phone-verify/dto/send-code.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { IsNotEmpty, IsString } from 'class-validator';

export class SendCodeDto {
@IsNotEmpty()
@IsString()
readonly phoneNumber: string;
}
24 changes: 24 additions & 0 deletions src/api/phone-verify/entities/phone-verify.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import {
Entity,
PrimaryGeneratedColumn,
Column,
UpdateDateColumn,
} from 'typeorm';

@Entity()
export class PhoneVerify {
@PrimaryGeneratedColumn()
id: number;

@Column()
phoneNumber: string;

@Column()
code: string;

@UpdateDateColumn()
sendAt: Date;

@Column()
isVerified: boolean;
}
18 changes: 18 additions & 0 deletions src/api/phone-verify/phone-verify.controller.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { PhoneVerifyController } from './phone-verify.controller';

describe('PhoneVerifyController', () => {
let controller: PhoneVerifyController;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [PhoneVerifyController],
}).compile();

controller = module.get<PhoneVerifyController>(PhoneVerifyController);
});

it('should be defined', () => {
expect(controller).toBeDefined();
});
});
34 changes: 34 additions & 0 deletions src/api/phone-verify/phone-verify.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Controller, Post, Body } from '@nestjs/common';
import { PhoneVerifyService } from './phone-verify.service';
import { PhoneVerifyDto } from './dto/phone-verify.dto';
import { SendCodeDto } from './dto/send-code.dto';
import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger';

@ApiTags('전화번호 인증 API')
@Controller('phone-verify')
export class PhoneVerifyController {
constructor(private readonly phoneVerifyService: PhoneVerifyService) {}

// 인증번호 생성
@Post('code')
@ApiOperation({ summary: '인증번호 생성' })
@ApiResponse({ status: 201, description: '인증번호가 전송되었습니다.' })
@ApiResponse({ status: 400, description: '올바른 전화번호를 입력하세요.' })
async sendCode(@Body() sendCodeDto: SendCodeDto): Promise<{ code: string }> {
const code = await this.phoneVerifyService.send(sendCodeDto.phoneNumber);
return { code };
}

// 인증번호 입력
@Post('verify')
@ApiOperation({ summary: '인증번호 입력' })
@ApiResponse({ status: 200, description: '인증이 완료되었습니다.' })
@ApiResponse({ status: 400, description: '올바른 인증번호를 입력하세요.' })
async verifyCode(
@Body() phoneVerifyDto: PhoneVerifyDto,
): Promise<{ result: boolean }> {
const { phoneNumber, code } = phoneVerifyDto;
const result = await this.phoneVerifyService.verify(phoneNumber, code);
return { result };
}
}
12 changes: 12 additions & 0 deletions src/api/phone-verify/phone-verify.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Module } from '@nestjs/common';
import { PhoneVerifyController } from './phone-verify.controller';
import { PhoneVerifyService } from './phone-verify.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { PhoneVerify } from './entities/phone-verify.entity';

@Module({
imports: [TypeOrmModule.forFeature([PhoneVerify])],
controllers: [PhoneVerifyController],
providers: [PhoneVerifyService],
})
export class PhoneVerifyModule {}
18 changes: 18 additions & 0 deletions src/api/phone-verify/phone-verify.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { PhoneVerifyService } from './phone-verify.service';

describe('PhoneVerifyService', () => {
let service: PhoneVerifyService;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [PhoneVerifyService],
}).compile();

service = module.get<PhoneVerifyService>(PhoneVerifyService);
});

it('should be defined', () => {
expect(service).toBeDefined();
});
});
47 changes: 47 additions & 0 deletions src/api/phone-verify/phone-verify.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { PhoneVerify } from './entities/phone-verify.entity';
import { Repository } from 'typeorm';

@Injectable()
export class PhoneVerifyService {
constructor(
@InjectRepository(PhoneVerify)
private readonly phoneVerifyRepository: Repository<PhoneVerify>,
) {}

// 인증번호 생성
async send(phoneNumber: string): Promise<string> {
const code = Math.floor(100000 + Math.random() * 900000).toString();
await this.phoneVerifyRepository.save({
phoneNumber,
code,
sendAt: new Date(),
});
return code;
}

// 인증번호 입력
async verify(phoneNumber: string, code: string): Promise<boolean> {
const verification = await this.phoneVerifyRepository.findOne({
where: {
phoneNumber,
code,
},
});

const currentTime = new Date();
const diffTime =
currentTime.getMinutes() - verification.sendAt.getMinutes();

if (!verification) {
throw new NotFoundException('인증번호가 일치하지 않습니다.');
}

if (diffTime <= 5) {
return true;
} else {
throw new NotFoundException('인증번호 유효 시간이 만료되었습니다.');
}
}
}
2 changes: 0 additions & 2 deletions template/source/typeorm/app.module.ts → src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,5 @@ import { DataSource } from 'typeorm';
},
}),
],
controllers: [],
providers: [],
})
export class AppModule {}
34 changes: 34 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { ValidationPipe } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { initializeTransactionalContext } from 'typeorm-transactional';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';

async function bootstrap() {
initializeTransactionalContext();

const app = await NestFactory.create(AppModule);

// 파이프라인 설정
app.useGlobalPipes(
new ValidationPipe({
whitelist: true,
forbidNonWhitelisted: true,
transform: true,
}),
);

// Swagger 적용
const config = new DocumentBuilder()
.setTitle('phone-verify API')
.setDescription('어쩌다 nest 1주차')
.setVersion('1.0')
.build();

const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api', app, document);

await app.listen(process.env.PORT || 8000);
}

bootstrap();
6 changes: 0 additions & 6 deletions template/environment/prisma/.env.example

This file was deleted.

39 changes: 0 additions & 39 deletions template/environment/prisma/docker-compose.yml

This file was deleted.

11 changes: 0 additions & 11 deletions template/environment/typeorm/.env.example

This file was deleted.

Loading