11package learningFlow .learningFlow_BE .service .auth .common ;
22
3+ import jakarta .mail .MessagingException ;
4+ import jakarta .mail .internet .MimeMessage ;
35import lombok .RequiredArgsConstructor ;
46import lombok .extern .slf4j .Slf4j ;
57import org .springframework .beans .factory .annotation .Value ;
68import org .springframework .mail .SimpleMailMessage ;
79import org .springframework .mail .javamail .JavaMailSender ;
10+ import org .springframework .mail .javamail .MimeMessageHelper ;
811import org .springframework .stereotype .Service ;
912
1013@ Service
@@ -19,20 +22,81 @@ public class UserVerificationEmailService {
1922
2023 public void sendVerificationEmail (String email , String token ) {
2124 try {
22- SimpleMailMessage message = new SimpleMailMessage ();
23- message .setTo (email );
24- message .setSubject ("[OnBoarding] 이메일 인증" );
25- message .setText (
26- "안녕하세요, OnBoarding입니다.\n \n " +
27- "회원가입을 완료하기 위해 아래 링크를 클릭하여 추가 정보를 입력해주세요:\n \n " +
28- baseUrl + "/register/complete?token=" + token + "\n \n " +
29- "이 링크는 24시간 동안 유효합니다.\n " +
30- "본인이 요청하지 않은 경우 이 이메일을 무시해주세요."
31- );
25+ MimeMessage message = emailSender .createMimeMessage ();
26+ MimeMessageHelper helper = new MimeMessageHelper (message , true , "UTF-8" );
27+
28+ helper .setTo (email );
29+ helper .setSubject ("[OnBoarding] 이메일 인증" );
3230
31+ String htmlContent = """
32+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional //EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
33+ <html xmlns="http://www.w3.org/1999/xhtml">
34+ <head>
35+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
36+ <title></title>
37+ <meta http-equiv="X-UA-Compatible" content="IE=edge" />
38+ <meta name="viewport" content="width=device-width" />
39+ <style type="text/css">
40+ @media only screen and (min-width: 620px) {
41+ .wrapper { min-width: 600px !important; }
42+ }
43+ body { margin: 0; padding: 0; -webkit-text-size-adjust: 100%%; }
44+ .wrapper { background-color: #f0f0f0; }
45+ .header { background-color: #5e52ff; }
46+ .btn {
47+ display: inline-block;
48+ padding: 12px 24px;
49+ background-color: #5e52ff;
50+ color: #ffffff;
51+ text-decoration: none;
52+ border-radius: 4px;
53+ font-weight: bold;
54+ }
55+ </style>
56+ </head>
57+ <body>
58+ <table class="wrapper" style="border-collapse: collapse; width: 100%%;">
59+ <tr>
60+ <td align="center">
61+ <div style="max-width: 600px; margin: 0 auto;">
62+ <div style="text-align: center; padding: 20px;">
63+ <img src="https://i.imgur.com/qqvcW0H.jpg" alt="OnBoarding" style="max-width: 369px; width: 100%%;"/>
64+ </div>
65+
66+ <div style="background-color: #ffffff; padding: 40px 20px; text-align: center;">
67+ <h1 style="color: #565656; font-size: 28px; margin-bottom: 20px;">
68+ 회원가입을 위해 메일을 인증해주세요
69+ </h1>
70+
71+ <p style="color: #787778; font-size: 16px; line-height: 24px; margin-bottom: 30px;">
72+ 안녕하세요, OnBoarding입니다.<br/>
73+ 회원가입을 완료하기 위해 메일을 인증해주세요.<br/>
74+ 버튼을 누르면 자동으로 인증 후 추가 정보 입력 페이지로 이동합니다.
75+ </p>
76+
77+ <a href="%s/register/complete?token=%s"
78+ class="btn"
79+ style="background-color: #5e52ff; color: #ffffff; text-decoration: none; padding: 12px 24px; border-radius: 4px; font-weight: bold; display: inline-block; margin: 20px 0;">
80+ 이메일 인증하기
81+ </a>
82+
83+ <p style="color: #787778; font-size: 14px; font-style: italic; margin-top: 30px;">
84+ 이 메일은 24시간 동안 유효합니다.<br/>
85+ 본인이 요청하지 않은 경우, 이 메일을 무시해주세요.
86+ </p>
87+ </div>
88+ </div>
89+ </td>
90+ </tr>
91+ </table>
92+ </body>
93+ </html>
94+ """ .formatted (baseUrl , token );
95+
96+ helper .setText (htmlContent , true );
3397 emailSender .send (message );
3498 log .info ("이메일 인증 메일 발송 완료: {}" , email );
35- } catch (Exception e ) {
99+ } catch (MessagingException e ) {
36100 log .error ("이메일 발송 실패: {}" , e .getMessage ());
37101 throw new RuntimeException ("이메일 발송에 실패했습니다." );
38102 }
0 commit comments