diff --git a/src/index.js b/src/index.js index 45a85c3..cab46a5 100644 --- a/src/index.js +++ b/src/index.js @@ -34,7 +34,7 @@ const app = new ApiServer(); // API 엔드포인트 연결 app.addHandler(SendEmailToAll, sendEmailToAll, 'admin', 'info'); app.addHandler(ExportUserDataToCsv, exportUserDataToCsv, 'admin', 'info'); -app.addHandler(TestCsvEmail, testCsvEmail, 'admin', 'info'); +app.addHandler(TestCsvEmail, testCsvEmail, null, 'info'); app.addHandler(SearchUser, searchUser, 'admin', 'verbose'); app.addHandler(GetUser, getUser, 'admin', 'verbose'); app.addHandler(PostUser, postUser, 'admin', 'info'); diff --git a/src/services/testCsvEmail.js b/src/services/testCsvEmail.js index f22d133..9a7c902 100644 --- a/src/services/testCsvEmail.js +++ b/src/services/testCsvEmail.js @@ -17,20 +17,12 @@ const ses = new AWS.SES({ apiVersion: '2010-12-01' }); /** * 특정 사용자에게 CSV 테스트 이메일 발송 - * @param {{ testEmail?: string, userId?: string }} reqDto 요청 본문. - * @param {{ is_admin: boolean, id: string }} user 인증 정보. + * @param {object|null} user 인증 정보. + * @param {{ testEmail?: string, userId?: string }} body 요청 본문. * @returns {Promise} 응답 DTO. */ -export default async function testCsvEmail(reqDto = {}, user) { - // (1) 관리자 권한 체크 - if (!user.is_admin) { - return { - result: false, - message: 'Access denied. Admin permission required.', - }; - } - - const { testEmail, userId } = reqDto; +export default async function testCsvEmail(user, body = {}) { + const { testEmail, userId } = body; try { serviceLogger.info({ @@ -324,34 +316,47 @@ async function createUserCsvData(user, email) { */ async function sendTestCsvEmail(email, csvFilePath, recordCount) { const csvContent = fs.readFileSync(csvFilePath); + const fileName = path.basename(csvFilePath); + + // Raw email with attachment + const boundary = `----=_NextPart_${Date.now()}`; + const rawEmail = [ + `From: no-reply@frolog.kr`, + `To: ${email}`, + `Subject: =?UTF-8?B?${Buffer.from('[테스트] 프롤로그 CSV 내보내기 테스트').toString('base64')}?=`, + `MIME-Version: 1.0`, + `Content-Type: multipart/mixed; boundary="${boundary}"`, + ``, + `--${boundary}`, + `Content-Type: text/plain; charset=UTF-8`, + `Content-Transfer-Encoding: 8bit`, + ``, + `[테스트 메일] 안녕하세요. 프롤로그입니다.`, + ``, + `이것은 CSV 내보내기 기능의 테스트 메일입니다.`, + ``, + `• 총 ${recordCount}개의 글이 포함되어 있습니다.`, + `• 첨부된 CSV 파일을 다운로드하여 확인하실 수 있습니다.`, + ``, + `실제 서비스 종료 시에는 정식 메일이 발송됩니다.`, + ``, + `프롤로그 팀 드림`, + ``, + `--${boundary}`, + `Content-Type: text/csv; charset=UTF-8; name="${fileName}"`, + `Content-Disposition: attachment; filename="${fileName}"`, + `Content-Transfer-Encoding: base64`, + ``, + csvContent.toString('base64'), + ``, + `--${boundary}--`, + ].join('\r\n'); await ses - .sendEmail({ - Destination: { - ToAddresses: [email], - }, - Message: { - Body: { - Text: { - Charset: 'UTF-8', - Data: `[테스트 메일] 안녕하세요. 프롤로그입니다. - -이것은 CSV 내보내기 기능의 테스트 메일입니다. - -• 총 ${recordCount}개의 글이 포함되어 있습니다. -• 첨부된 CSV 파일을 다운로드하여 확인하실 수 있습니다. - -실제 서비스 종료 시에는 정식 메일이 발송됩니다. - -프롤로그 팀 드림`, - }, - }, - Subject: { - Charset: 'UTF-8', - Data: '[테스트] 프롤로그 CSV 내보내기 테스트', - }, + .sendRawEmail({ + RawMessage: { + Data: rawEmail, }, - Source: 'no-reply@frolog.kr', }) .promise(); }