Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down
79 changes: 42 additions & 37 deletions src/services/testCsvEmail.js
Original file line number Diff line number Diff line change
Expand Up @@ -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<object>} 응답 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({
Expand Down Expand Up @@ -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();
}
Expand Down
Loading