Skip to content

Commit de08d82

Browse files
committed
refactor: 이메일 검증 강화
1 parent 41e3ac0 commit de08d82

File tree

2 files changed

+24
-10
lines changed

2 files changed

+24
-10
lines changed

src/controllers/__test__/user.controller.test.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,7 @@ describe('UserController', () => {
412412
mockResponse.redirect = jest.fn().mockReturnThis();
413413
});
414414

415-
it('이메일이 없으면 BadRequestError를 던져야 한다', async () => {
415+
it('이메일이 없으면 메인 페이지로 리다이렉트해야 한다', async () => {
416416
mockRequest.query = {};
417417

418418
await userController.unsubscribeNewsletter(
@@ -421,12 +421,23 @@ describe('UserController', () => {
421421
nextFunction
422422
);
423423

424-
expect(nextFunction).toHaveBeenCalledWith(
425-
expect.objectContaining({
426-
message: '이메일이 필요합니다.',
427-
})
424+
expect(mockUserService.unsubscribeNewsletter).not.toHaveBeenCalled();
425+
expect(mockResponse.redirect).toHaveBeenCalledWith('/main');
426+
expect(nextFunction).not.toHaveBeenCalled();
427+
});
428+
429+
it('잘못된 이메일 형식이면 메인 페이지로 리다이렉트해야 한다', async () => {
430+
mockRequest.query = { email: 'invalid-email' };
431+
432+
await userController.unsubscribeNewsletter(
433+
mockRequest as Request,
434+
mockResponse as Response,
435+
nextFunction
428436
);
429-
expect(mockResponse.redirect).not.toHaveBeenCalled();
437+
438+
expect(mockUserService.unsubscribeNewsletter).not.toHaveBeenCalled();
439+
expect(mockResponse.redirect).toHaveBeenCalledWith('/main');
440+
expect(nextFunction).not.toHaveBeenCalled();
430441
});
431442

432443
it('구독 해제 완료시 메인 페이지로 리다이렉트해야 한다', async () => {

src/controllers/user.controller.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { EmptyResponseDto, LoginResponseDto } from '@/types';
44
import { QRLoginTokenResponseDto } from '@/types/dto/responses/qrResponse.type';
55
import { UserService } from '@/services/user.service';
66
import { fetchVelogApi } from '@/modules/velog/velog.api';
7-
import { QRTokenExpiredError, QRTokenInvalidError, BadRequestError } from '@/exception';
7+
import { QRTokenExpiredError, QRTokenInvalidError } from '@/exception';
88

99
type Token10 = string & { __lengthBrand: 10 };
1010

@@ -173,11 +173,14 @@ export class UserController {
173173
unsubscribeNewsletter: RequestHandler = async (req: Request, res: Response<EmptyResponseDto>, next: NextFunction) => {
174174
try {
175175
const email = req.query.email as string;
176-
if (!email) {
177-
throw new BadRequestError('이메일이 필요합니다.');
176+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
177+
178+
if (!email || !emailRegex.test(email)) {
179+
logger.error(`올바르지 않은 이메일: [email: ${req.query.email}]`);
180+
} else {
181+
await this.userService.unsubscribeNewsletter(email);
178182
}
179183

180-
await this.userService.unsubscribeNewsletter(email);
181184
res.redirect('/main');
182185
} catch (error) {
183186
logger.error(`뉴스레터 구독 해제 실패: [email: ${req.query.email}]`, error);

0 commit comments

Comments
 (0)