'use strict' /** * Copyright (c) 2017~2024, OBCon Inc. * All rights reserved. */ /** * @file * @copyright 2017~2024, OBCon Inc. * @author gye hyun james kim [pnuskgh@gmail.com] */ const fs = require('fs'); const nodemailer = require('nodemailer'); class Emails { constructor() { this.templateTitle = 'zzEmailTitlezz'; //--- Email Template에 제목을 채우기 위해 사용 한다. this.templateHtml = 'zzEmailHtmlzz'; //--- Email Template에 본문을 채우기 위해 사용 한다. this.templateSignature = 'zzEmailSignaturezz'; //--- Email Template에 서명을 채우기 위해 사용 한다. this.templateCopyright = 'zzEmailCopyRightzz'; //--- Email Template에 Copyright를 채우기 위해 사용 한다. this._transporter = {}; this._from = {}; //--- 보낸 사람 this._signature = {}; //--- 서명 : 명명 규칙 - ${service}_signature.htm this._template = {}; //--- Email Template : 명명 규칙 - ${service}_template.htm //--- Service 관리자용 이메일 서비스를 생성 한다. // if (config.email.port == 587) { // this.createService(config.email.service, { // host: config.email.host, //--- Email Host // port: config.email.port, //--- Email Port : 25, 587 (TLS) // secureConnection: false, // auth: { // user: config.email.username, //--- 로그인 아이디 // pass: security.decrypt(config.email.password) //--- 로그인 비밀번호 // }, // tls: { // ciphers:'SSLv3' // } // }, null, null); // // }, 'admin_signature.htm', null) // } else { if (config.email.use) { try { this.createService(config.email.service, { host: config.email.host, //--- Email Host port: config.email.port, //--- Email Port : 25, 587 (TLS) secure: config.email.secure, //--- true. 보안 이메일 auth: { user: config.email.username, //--- 로그인 아이디 pass: security.decrypt(config.email.password) //--- 로그인 비밀번호 } }, null, null); } catch(err) { utils.obj.loggerError(err); } } // }, 'admin_signature.htm', null) // } } // init() { // global.sendNotification = function(subject, html) { // if (process.platform == 'linux') { //--- linux, win32 // config.notification.emails.forEach(function(emailTo) { // emails.sendEmail(config.email.service, config.email.username, emailTo, subject, html); // }); // } // }; // } _readFile(signatureFile) { let file = utils.getPath('files', 'emailTemplate', signatureFile); if (fs.existsSync(file)) { return fs.readFileSync(file, 'utf8'); } else { return ''; } } //--- Site 모듈에서 ajaxTestEmail()에서만 사용중 createService(service, options, signatureFile, templateFile, rebuild=false) { let file = null; if (rebuild) { if (this._transporter.hasOwnProperty(service)) { delete this._transporter[service]; } } if ((!this._transporter.hasOwnProperty(service)) || (rebuild)) { if (options.port == 587) { let optionsNew = { host: options.host, //--- Email Host port: options.port, //--- Email Port : 25, 587 (TLS) secureConnection: false, auth: { user: options.auth.user, //--- 로그인 아이디 pass: options.auth.pass //--- 로그인 비밀번호 }, tls: { ciphers:'SSLv3' } }; this._transporter[service] = nodemailer.createTransport(optionsNew); } else { this._transporter[service] = nodemailer.createTransport(options); } this._from[service] = options.auth.user; if (templateFile == null) { file = utils.getPath('files', 'emailTemplate', service + '_template.htm'); if (fs.existsSync(file)) { this._template[service] = this._readFile(service + '_template.htm'); } else { this._template[service] = null; } } else { this._template[service] = this._readFile(templateFile); } if (signatureFile == null) { file = utils.getPath('files', 'emailTemplate', service + '_signature.htm'); if (fs.existsSync(file)) { this._signature[service] = this._readFile(service + '_signature.htm'); } else { this._signature[service] = null; } } else { this._signature[service] = this._readFile(signatureFile); } } } //--- createService() 함수를 통해서 이메일 service를 먼저 생성한 후 sendEmail() 함수를 호출 한다. sendEmail(service, from, to, subject, html, callback=null) { let options = { from: from, to: to, subject: subject, }; if (service == null) { service = 'OBCon'; } if (from == null) { options.from = this._from[service]; } //--- template와 signature를 사용하여 이메일을 작성 한다. if (this._template[service] == null) { // options.html = `${service}

${html}



${this.templateSignature}

`; options.html = `

${html}



${this.templateSignature}

`; } else { options.html = this._template[service].replace(this.templateTitle, subject).replace(this.templateHtml, html); } if (this._signature[service] == null) { options.html = options.html.replace(this.templateSignature, ''); } else { options.html = options.html.replace(this.templateSignature, this._signature[service]); } options.html = options.html.replace(this.templateCopyright, config.service.copyright); //--- createService() 함수에 의해서 생성된 transporter를 사용하여 이메일을 발송 한다. logger.info(`Send email :: ${service}, ${from}, ${to}, ${subject}`); this._transporter[service].sendMail(options, function(error, info) { if (error) { logger.error('include/emails.js : ' + JSON.stringify(error)); //--- error: {"library":"SSL routines","function":"ssl3_get_record","reason":"wrong version number","code":"ESOCKET","command":"CONN"} } else { logger.info(`include/emails.js : Message send: ${info.messageId}`); logger.info(`include/emails.js : Message send: ${info.response}`); } this._transporter[service].close(); if (callback != null) { callback(error, info); } }.bind(this)); } //--- Service 관리자에게 이메일 발송 // sendNotificationAdmin(subject, html) { // if (process.platform == 'linux') { //--- linux, win32 // config.notification.emails.forEach(function(emailTo) { // this.sendEmail(config.email.service, config.email.sender, emailTo, subject, html); // }.bind(this)); // } // } //--- emails.notification(null, '제목', '알림'); async notification(notifications, subject, html) { try { notifications = notifications || config.email.notifications; notifications.forEach(function(item) { this.sendEmail(config.email.service, config.email.sender, item.email, subject, html); }.bind(this)); } catch(ex) { utils.obj.loggerError(ex); return { code: 500, message: ex.message, data: {}, err: ex }; } } sendNotification(siteId, siteKey, type, pos, title, msg) { // logger.info('include/emails.js : Start sendNotification'); if (siteKey == null) { let query = { where: { id: siteId, deleted: false } }; modules.sites.model.table.findOne(query) .then(function(site) { if (site == null) { logger.error('include/emails.js : ' + siteId + ' Site not found.'); return; } this._sendNotification(siteId, site.siteKey, type, pos, title, msg); }.bind(this)).catch(utils.obj.loggerError); } else { this._sendNotification(siteId, siteKey, type, pos, title, msg); } } _sendNotification(siteId, siteKey, type, pos, title, msg) { logger.info('include/emails.js : site - ' + siteId + ', type - ' + type + ', pos - ' + pos + ', msg - ' + msg); let email = settingSync.getSetting(siteKey, null, 'email', config.email); if (email.use == false) { logger.info('include/emails.js : Email 사용 설정이 되어 있지 않습니다.'); return; } let query = { where: { site: siteId, moduleName: 'user', // moduleId: userId, category: 'Notification Setting', name: 'email_sms', deleted: false } }; modules.settings.model.table.findAll(query) .then(function(data) { if (data == null) { return; } // logger.info('include/emails.js : emails send start'); let count = 0; let receiver = []; for (let idx = 0; idx < data.length; idx++) { let item = JSON.parse(data[idx].custom); let emailWork = item.emailWork; if (typeof(emailWork) == 'undefined') { continue; } emailWork = emailWork.trim(); if (emailWork == '') { continue; } if (item.status == '0') { //--- 모든 알람을 수신하지 않습니다. continue; } let deviceCondition = ''; if (utils.existField(item, 'deviceCondition' + type)) { deviceCondition = item['deviceCondition' + type]; } let flag = utils.getFlagString(deviceCondition, pos); if ((flag != '1') && (flag != '3')) { //--- 해당되는 Email을 수신하지 않습니다. continue; } count = count + 1; receiver.push(emailWork); } if (count == 0) { return; } logger.info('include/emails.js : email receivers : ' + receiver.join(',')); //--- Site를 위한 이메일 서비스 생성 // if (email.port == 587) { // this.createService(email.service, { // host: email.host, //--- Email Host // port: email.port, //--- Email Port : 25, 587 (TLS) // secureConnection: false, // auth: { // user: email.username, //--- 로그인 아이디 // pass: security.decrypt(email.password) //--- 로그인 비밀번호 // }, // tls: { // ciphers:'SSLv3' // } // }, null, config.service.name + '_notification.htm', true); // } else { this.createService(email.service, { host: email.host, //--- Email Host port: email.port, //--- Email Port : 25, 587 (TLS) secure: email.secure, //--- true. 보안 이메일 auth: { user: email.username, //--- 로그인 아이디 pass: security.decrypt(email.password) //--- 로그인 비밀번호 } }, null, config.service.name + '_notification.htm', true); // } receiver.forEach(function(emailTo) { this.sendEmail(email.service, email.sender, emailTo, title, msg); }.bind(this)); }.bind(this)).catch(utils.obj.loggerError); } } module.exports = Emails;