From 944b8efbce8076177f2e89f8ca7217d6f5beb0e3 Mon Sep 17 00:00:00 2001 From: ttipo Date: Mon, 22 Jun 2026 12:34:53 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=9D=B4=EB=A9=94=EC=9D=BC=20=EC=9D=B8?= =?UTF-8?q?=EC=A6=9D=C2=B7=EB=B9=84=EB=B0=80=EB=B2=88=ED=98=B8=20=EC=9E=AC?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20=EB=A7=81=ED=81=AC=EB=A5=BC=20=EC=9A=B4?= =?UTF-8?q?=EC=98=81=20=ED=99=98=EA=B2=BD=EC=97=90=EC=84=9C=EB=8F=84=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=20=EC=B6=9C=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SMTP 미구현 상태에서 운영 환경의 isProd 분기가 인증/재설정 링크를 가려 사실상 인증 불가였던 제한 해제. 개발·운영 공통으로 전체 링크를 로그로 남긴다. 실 메일러 도입 시 토큰 노출 방지를 위해 반드시 제거 필요(주석 경고 명시). Co-Authored-By: Claude Opus 4.8 (1M context) --- backend/src/modules/mail/mail.service.ts | 29 +++++------------------- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/backend/src/modules/mail/mail.service.ts b/backend/src/modules/mail/mail.service.ts index bddba04..fb751e8 100644 --- a/backend/src/modules/mail/mail.service.ts +++ b/backend/src/modules/mail/mail.service.ts @@ -1,25 +1,16 @@ import { Injectable, Logger } from '@nestjs/common'; -import { ConfigService } from '@nestjs/config'; // 메일 발송 서비스 (플레이스홀더) — -// 현재는 실제 SMTP 전송 대신 백엔드 로그로 대체한다. -// 추후 nodemailer 등 도입 시 이 서비스 내부 구현만 교체하면 호출부는 그대로 유지된다. +// 현재는 실제 SMTP 전송 대신 백엔드 로그로 대체한다(개발/운영 공통). +// 실 메일러(nodemailer 등) 도입 전까지는 인증/재설정 링크를 로그에서 확인한다. +// ⚠️ 보안: 링크에는 원문 토큰이 포함된다. 실 메일러 도입 시 반드시 이 로그 출력을 제거하고 +// 실제 이메일 전송으로 교체할 것(운영 로그에 토큰을 남기지 않기 위함). @Injectable() export class MailService { private readonly logger = new Logger(MailService.name); - constructor(private readonly config: ConfigService) {} - - // 가입 인증 메일 — 개발 환경에서만 인증 링크(원문 토큰 포함)를 로그로 출력한다. - // 운영 환경에서는 토큰이 로그에 남지 않도록 수신자만 기록한다(실 메일러로 교체 전제). + // 가입 인증 메일 — 실 메일러 전까지 인증 링크(원문 토큰 포함)를 로그로 출력한다(개발/운영 공통). sendVerificationEmail(to: string, name: string, verifyUrl: string): void { - const isProd = this.config.get('NODE_ENV') === 'production'; - if (isProd) { - this.logger.log( - `[메일 발송 - 가입 인증] 수신자=${to} (인증 링크는 보안상 로그에 남기지 않음 — 실 메일러 필요)`, - ); - return; - } this.logger.log( [ '', @@ -34,16 +25,8 @@ export class MailService { ); } - // 비밀번호 재설정 메일 — 개발 환경에서만 재설정 링크(원문 토큰 포함)를 로그로 출력한다. - // 운영 환경에서는 토큰이 로그에 남지 않도록 수신자만 기록한다(실 메일러로 교체 전제). + // 비밀번호 재설정 메일 — 실 메일러 전까지 재설정 링크(원문 토큰 포함)를 로그로 출력한다(개발/운영 공통). sendPasswordResetEmail(to: string, name: string, resetUrl: string): void { - const isProd = this.config.get('NODE_ENV') === 'production'; - if (isProd) { - this.logger.log( - `[메일 발송 - 비밀번호 재설정] 수신자=${to} (재설정 링크는 보안상 로그에 남기지 않음 — 실 메일러 필요)`, - ); - return; - } this.logger.log( [ '',