Skip to content

Commit

Permalink
Merge pull request #37 from pre-onboarding-backend-G/feature/user#36
Browse files Browse the repository at this point in the history
사용자 가입승인(API) 이메일 서비스 구현 #36
  • Loading branch information
hojoonSong authored Oct 30, 2023
2 parents d026b65 + 380989c commit d09b3e1
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 25 deletions.
33 changes: 17 additions & 16 deletions src/auth/auth.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { JwtAuthGuard } from './guards/jwt-auth.guard';
import { Response } from 'express';
import { GetUser } from './decorators/user.decorator';
import { User } from 'src/user/schema/user.schema';
import { RegisterUserDto } from 'src/user/dto/registerUserDto';
import { RegisterUserDto } from 'src/user/dto/register-user.dto';

@ApiTags('auth')
@Controller('auth')
Expand Down Expand Up @@ -109,20 +109,21 @@ export class AuthController {
@Post('register')
async Register(
@Body(ValidationPipe) registerUserDto: RegisterUserDto,
@Res() res: Response,
) {
try {
const createdUser = await this.authService.register(registerUserDto);
const token = await this.authService.login(createdUser);
res.status(HttpStatus.CREATED).json({ token });
} catch (error) {
if (error.status === HttpStatus.CONFLICT) {
res.status(HttpStatus.CONFLICT).json({ message: error.message });
} else {
res
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.json({ message: '서버 오류' });
}
}
): Promise<void> {
await this.authService.register(registerUserDto);
}

@Post('verify')
@ApiBody({
schema: {
type: 'object',
properties: {
email: { type: 'string', example: '[email protected]' },
code: { type: 'string', example: '123456' },
},
},
})
async verify(@Body() body: { email: string; code: string }): Promise<void> {
return this.authService.verify(body.email, body.code);
}
}
54 changes: 45 additions & 9 deletions src/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,21 @@ import {
Res,
HttpStatus,
UnauthorizedException,
NotFoundException,
BadRequestException,
} from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { RegisterUserDto } from 'src/user/dto/registerUserDto';
import { User } from 'src/user/schema/user.schema';
import * as bcrypt from 'bcryptjs';
import { ConfigService } from '@nestjs/config';
import { RegisterUserDto } from 'src/user/dto/register-user.dto';
import { VerificationData } from './types/verification.data';

@Injectable()
export class AuthService {
private verificationCodes: Map<string, VerificationData> = new Map();
constructor(
private jwtService: JwtService,
private readonly configService: ConfigService,
Expand Down Expand Up @@ -45,28 +49,60 @@ export class AuthService {

async validateUser(email: string, pass: string): Promise<User | null> {
const user = await this.userModel.findOne({ email });
if (user && user.password === pass) {
//const isMatch = await bcrypt.compare(pass, user.password);와 같은 비밀번호 검증 로직 추가
return user;
if (user) {
const isMatch = await bcrypt.compare(pass, user.password);
if (!isMatch) {
return null;
}
}
return null;
return user;
}

async register(registerUserDto: RegisterUserDto): Promise<User> {
async register(registerUserDto: RegisterUserDto): Promise<void> {
const { email, password, connectedServices } = registerUserDto;
const existingUser = await this.userModel.findOne({ email });
if (existingUser) {
throw new ConflictException('이미 존재하는 이메일입니다.');
}
const hash = await bcrypt.hash(password, 10);

const createdUser = new this.userModel({
const verificationCode = Math.random().toString().slice(-6);
const expires = Date.now() + 5 * 60 * 1000;

this.verificationCodes.set(email, {
email,
hash,
password: hash,
connectedServices,
code: verificationCode,
expires,
});

// 이메일로 전송하는 로직 추가 예정
console.log(`Verification code for ${email}: ${verificationCode}`);
}

async verify(email: string, code: string): Promise<void> {
const storedData = this.verificationCodes.get(email);
if (!storedData) {
throw new NotFoundException('가입하지 않은 이메일입니다.');
}
if (Date.now() > storedData.expires) {
throw new BadRequestException('인증번호가 만료되었습니다.');
}
if (storedData.code !== code) {
throw new BadRequestException('인증번호가 일치하지 않습니다.');
}

const createdUser = new this.userModel({
email: storedData.email,
password: storedData.password,
connectedServices: storedData.connectedServices,
});
await createdUser.save();
return createdUser;

// 인증이 완료되었으므로 저장된 데이터 삭제
this.verificationCodes.delete(email);
return;
}

/**
Expand Down
7 changes: 7 additions & 0 deletions src/auth/types/verification.data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export interface VerificationData {
email: string;
password: string;
connectedServices: any[]; // 실제 타입에 맞게 변경해주세요.
code: string;
expires: number;
}
File renamed without changes.

0 comments on commit d09b3e1

Please sign in to comment.