-
Notifications
You must be signed in to change notification settings - Fork 4
✨ feat: 비밀번호 변경 기능 추가 #458
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
Merged
Merged
Changes from 13 commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
8c6738b
✨ feat: 비밀번호 변경 요청 API의 DTO 구현
CodeVac513 8e79e74
✨ feat: 비밀번호 변경(업데이트) API의 요청 DTO 구현
CodeVac513 6247001
✨ feat: 비밀번호 변경 요청 API와 비밀번호 변경 API 핸들러 구현
CodeVac513 9c5cf3c
✨ feat: 비밀번호 변경 시 사용할 레디스 KEY 상수 추가
CodeVac513 12e9479
✨ feat: 비밀번호 변경을 위한 메일 양식 추가
CodeVac513 6465b75
✨ feat: 비밀번호 변경 메일 전송 로직 구현
CodeVac513 c45c639
✨ feat: 비밀번호 변경 서비스 로직 구현
CodeVac513 ffbd016
🧼 clean: 디버그용 console.log 정리
CodeVac513 e96be98
📝 docs: 비밀번호 변경 요청 API 스웨거 작성 및 적용
CodeVac513 bd14f2b
📝 docs: 비밀번호 변경 API 스웨거 작성 및 적용
CodeVac513 ca4ba24
✅ test: 비밀번호 변경 API 통합테스트 작성
CodeVac513 b0df110
✅ test: forgotPasswordRequestDto의 dto 테스트 작성
CodeVac513 8d1ab4a
✅ test: passwordResetRequestDto의 dto 테스트 작성
CodeVac513 b5aa99b
Merge branch 'main' into feat/password-reset-api
CodeVac513 49ed2e8
🧼 clean: forgotPassword로 메서드명을 수정
CodeVac513 0eeef8c
🧼 clean: passwordResetRequestDto를 resetPasswordRequestDto로 수정
CodeVac513 4147bfd
✨ feat: user 객체 직렬화에서 userId를 저장하고 변경 시 user 객체를 조회하는 방법으로 수정
CodeVac513 680d793
🐛 fix: certificateUser 메서드 내 redis del 메서드의 await 적용
CodeVac513 6a9c07c
✅ test: dto 테스트 리팩토링에 맞게 테스트 코드 수정
CodeVac513 f7f33bb
✅ test: e2e 테스트 수정
CodeVac513 43ab014
Merge branch 'main' into feat/password-reset-api
CodeVac513 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { applyDecorators } from '@nestjs/common'; | ||
import { ApiOkResponse, ApiOperation } from '@nestjs/swagger'; | ||
|
||
export function ApiRequestPasswordReset() { | ||
return applyDecorators( | ||
ApiOperation({ | ||
summary: '비밀번호 변경 요청 API', | ||
}), | ||
ApiOkResponse({ | ||
description: 'Ok', | ||
schema: { | ||
properties: { | ||
message: { | ||
type: 'string', | ||
}, | ||
}, | ||
}, | ||
example: { | ||
message: '비밀번호 재설정 링크를 이메일로 발송했습니다.', | ||
}, | ||
}), | ||
); | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { applyDecorators } from '@nestjs/common'; | ||
import { | ||
ApiNotFoundResponse, | ||
ApiOkResponse, | ||
ApiOperation, | ||
} from '@nestjs/swagger'; | ||
|
||
export function ApiResetPassword() { | ||
return applyDecorators( | ||
ApiOperation({ | ||
summary: '비밀번호 변경 API', | ||
}), | ||
ApiOkResponse({ | ||
description: 'Ok', | ||
schema: { | ||
properties: { | ||
message: { | ||
type: 'string', | ||
}, | ||
}, | ||
}, | ||
example: { | ||
message: '비밀번호가 성공적으로 수정되었습니다.', | ||
}, | ||
}), | ||
ApiNotFoundResponse({ | ||
description: 'Not Found', | ||
example: { | ||
message: '인증에 실패했습니다.', | ||
}, | ||
}), | ||
); | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { IsEmail, IsNotEmpty } from 'class-validator'; | ||
import { ApiProperty } from '@nestjs/swagger'; | ||
|
||
export class ForgotPasswordRequestDto { | ||
@ApiProperty({ | ||
example: '[email protected]', | ||
description: '이메일을 입력해주세요.', | ||
}) | ||
@IsEmail( | ||
{}, | ||
{ | ||
message: '이메일 주소 형식에 맞춰서 작성해주세요.', | ||
}, | ||
) | ||
@IsNotEmpty({ | ||
message: '이메일이 없습니다.', | ||
}) | ||
email: string; | ||
|
||
constructor(email: string) { | ||
this.email = email; | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { ApiProperty } from '@nestjs/swagger'; | ||
import { IsNotEmpty, Matches } from 'class-validator'; | ||
|
||
export class PasswordResetRequestDto { | ||
Jo-Minseok marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
@ApiProperty({ | ||
example: 'd2ba0d98-95ce-4905-87fc-384965ffe7c9', | ||
description: '인증 코드를 입력해주세요.', | ||
}) | ||
@IsNotEmpty({ | ||
message: '인증 코드를 입력해주세요.', | ||
}) | ||
uuid: string; | ||
|
||
@ApiProperty({ | ||
example: 'example1234!', | ||
description: '비밀번호를 입력해주세요.', | ||
}) | ||
@IsNotEmpty({ | ||
message: '비밀번호가 없습니다.', | ||
}) | ||
@Matches( | ||
/^(?=.{8,32}$)(?:(?=.*[a-z])(?=.*[A-Z])|(?=.*[a-z])(?=.*\d)|(?=.*[a-z])(?=.*[^A-Za-z0-9])|(?=.*[A-Z])(?=.*\d)|(?=.*[A-Z])(?=.*[^A-Za-z0-9])|(?=.*\d)(?=.*[^A-Za-z0-9])).*$/, | ||
{ | ||
message: | ||
'비밀번호는 8~32자이며, 영문(대문자/소문자), 숫자, 특수문자 중 2종류 이상을 포함해야 합니다.', | ||
}, | ||
) | ||
password: string; | ||
|
||
constructor(uuid: string, password: string) { | ||
this.uuid = uuid; | ||
this.password = password; | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { validate } from 'class-validator'; | ||
import { ForgotPasswordRequestDto } from '../../../src/user/dto/request/forgotPassword.dto'; | ||
|
||
describe('ForgotPasswordRequestDto Test', () => { | ||
it('이메일 형식이 아니라면 유효성 검사에 실패한다.', async () => { | ||
// given | ||
const dto = new ForgotPasswordRequestDto('invalidEmail'); | ||
|
||
// when | ||
const errors = await validate(dto); | ||
|
||
// then | ||
expect(errors).not.toHaveLength(0); | ||
expect(errors[0].constraints).toHaveProperty('isEmail'); | ||
}); | ||
|
||
it('빈 문자열을 입력하면 유효성 검사에 실패한다.', async () => { | ||
// given | ||
const dto = new ForgotPasswordRequestDto(''); | ||
|
||
// when | ||
const errors = await validate(dto); | ||
|
||
// then | ||
expect(errors).not.toHaveLength(0); | ||
expect(errors[0].constraints).toHaveProperty('isNotEmpty'); | ||
}); | ||
|
||
it('아무 값도 없다면(NULL) 유효성 검사에 실패한다.', async () => { | ||
// given | ||
const dto = new ForgotPasswordRequestDto(null); | ||
|
||
// when | ||
const errors = await validate(dto); | ||
|
||
// then | ||
expect(errors).not.toHaveLength(0); | ||
expect(errors[0].constraints).toHaveProperty('isNotEmpty'); | ||
}); | ||
}); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.