Просмотр исходного кода

refactor mailer -> MailService

Yuki Takei 5 лет назад
Родитель
Сommit
3135c26314

+ 1 - 3
config/logger/config.dev.js

@@ -18,6 +18,7 @@ module.exports = {
   'growi:service:PassportService': 'debug',
   'growi:service:config-pubsub:*': 'debug',
   // 'growi:service:ConfigManager': 'debug',
+  // 'growi:service:mail': 'debug',
   'growi:lib:search': 'debug',
   // 'growi:service:GlobalNotification': 'debug',
   // 'growi:lib:importer': 'debug',
@@ -25,9 +26,6 @@ module.exports = {
   'growi-plugin:*': 'debug',
   // 'growi:InterceptorManager': 'debug',
 
-  // email
-  // 'growi:lib:mailer': 'debug',
-
   /*
    * configure level for client
    */

+ 3 - 10
src/server/crowi/index.js

@@ -37,7 +37,7 @@ function Crowi(rootdir) {
 
   this.config = {};
   this.configManager = null;
-  this.mailer = {};
+  this.mailService = null;
   this.passportService = null;
   this.globalNotificationService = null;
   this.slackNotificationService = null;
@@ -286,10 +286,6 @@ Crowi.prototype.scanRuntimeVersions = async function() {
   });
 };
 
-Crowi.prototype.getMailer = function() {
-  return this.mailer;
-};
-
 Crowi.prototype.getSlack = function() {
   return this.slack;
 };
@@ -342,11 +338,8 @@ Crowi.prototype.setupSearcher = async function() {
 };
 
 Crowi.prototype.setupMailer = async function() {
-  const self = this;
-  return new Promise(((resolve, reject) => {
-    self.mailer = require('../util/mailer')(self);
-    resolve();
-  }));
+  const MailService = require('@server/service/mail');
+  this.mailService = new MailService(this);
 };
 
 Crowi.prototype.setupSlack = async function() {

+ 3 - 3
src/server/models/user.js

@@ -604,8 +604,8 @@ module.exports = function(crowi) {
   };
 
   userSchema.statics.sendEmailbyUserList = async function(userList) {
-    const mailer = crowi.getMailer();
-    const appTitle = crowi.appService.getAppTitle();
+    const { appService, mailService } = crowi;
+    const appTitle = appService.getAppTitle();
 
     await Promise.all(userList.map(async(user) => {
       if (user.password == null) {
@@ -613,7 +613,7 @@ module.exports = function(crowi) {
       }
 
       try {
-        return mailer.send({
+        return mailService.send({
           to: user.email,
           subject: `Invitation to ${appTitle}`,
           template: path.join(crowi.localeDir, 'en_US/admin/userInvitation.txt'),

+ 17 - 10
src/server/routes/apiv3/app-settings.js

@@ -292,7 +292,7 @@ module.exports = (crowi) => {
    * validate mail setting send test mail
    */
   async function validateMailSetting(req) {
-    const mailer = crowi.mailer;
+    const { mailService } = crowi;
     const option = {
       host: req.body.smtpHost,
       port: req.body.smtpPort,
@@ -307,7 +307,7 @@ module.exports = (crowi) => {
       option.secure = true;
     }
 
-    const smtpClient = mailer.createSMTPClient(option);
+    const smtpClient = mailService.createSMTPClient(option);
     debug('mailer setup for validate SMTP setting', smtpClient);
 
     const mailOptions = {
@@ -344,7 +344,6 @@ module.exports = (crowi) => {
    *                  $ref: '#/components/schemas/MailSettingParams'
    */
   router.put('/mail-setting', loginRequiredStrictly, adminRequired, csrf, validator.mailSetting, apiV3FormValidator, async(req, res) => {
-    // テストメール送信によるバリデート
     try {
       await validateMailSetting(req);
     }
@@ -365,13 +364,17 @@ module.exports = (crowi) => {
     };
 
     try {
-      await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestMailSettingParams);
+      const { configManager, mailService } = crowi;
+
+      await configManager.updateConfigsInTheSameNamespace('crowi', requestMailSettingParams);
+      await mailService.initialize();
+
       const mailSettingParams = {
-        fromAddress: crowi.configManager.getConfig('crowi', 'mail:from'),
-        smtpHost: crowi.configManager.getConfig('crowi', 'mail:smtpHost'),
-        smtpPort: crowi.configManager.getConfig('crowi', 'mail:smtpPort'),
-        smtpUser: crowi.configManager.getConfig('crowi', 'mail:smtpUser'),
-        smtpPassword: crowi.configManager.getConfig('crowi', 'mail:smtpPassword'),
+        fromAddress: configManager.getConfig('crowi', 'mail:from'),
+        smtpHost: configManager.getConfig('crowi', 'mail:smtpHost'),
+        smtpPort: configManager.getConfig('crowi', 'mail:smtpPort'),
+        smtpUser: configManager.getConfig('crowi', 'mail:smtpUser'),
+        smtpPassword: configManager.getConfig('crowi', 'mail:smtpPassword'),
       };
       return res.apiv3({ mailSettingParams });
     }
@@ -415,7 +418,11 @@ module.exports = (crowi) => {
     };
 
     try {
-      await crowi.configManager.updateConfigsInTheSameNamespace('crowi', requestAwsSettingParams);
+      const { configManager, mailService } = crowi;
+
+      await configManager.updateConfigsInTheSameNamespace('crowi', requestAwsSettingParams);
+      await mailService.initialize();
+
       const awsSettingParams = {
         region: crowi.configManager.getConfig('crowi', 'aws:region'),
         customEndpoint: crowi.configManager.getConfig('crowi', 'aws:customEndpoint'),

+ 2 - 3
src/server/routes/login.js

@@ -7,9 +7,8 @@ module.exports = function(crowi, app) {
   const debug = require('debug')('growi:routes:login');
   const logger = require('@alias/logger')('growi:routes:login');
   const path = require('path');
-  const mailer = crowi.getMailer();
   const User = crowi.model('User');
-  const { configManager, appService, aclService } = crowi;
+  const { configManager, appService, aclService, mailService } = crowi;
 
   const actions = {};
 
@@ -158,7 +157,7 @@ module.exports = function(crowi, app) {
     const appTitle = appService.getAppTitle();
 
     const promises = admins.map((admin) => {
-      return mailer.send({
+      return mailService.send({
         to: admin.email,
         subject: `[${appTitle}:admin] A New User Created and Waiting for Activation`,
         template: path.join(crowi.localeDir, 'en_US/admin/userWaitingActivation.txt'),

+ 3 - 2
src/server/service/global-notification/global-notification-mail.js

@@ -8,7 +8,6 @@ class GlobalNotificationMailService {
 
   constructor(crowi) {
     this.crowi = crowi;
-    this.mailer = crowi.getMailer();
     this.type = crowi.model('GlobalNotificationSetting').TYPE.MAIL;
     this.event = crowi.model('GlobalNotificationSetting').EVENT;
   }
@@ -24,13 +23,15 @@ class GlobalNotificationMailService {
    * @param {{ comment: Comment, oldPath: string }} _ event specific vars
    */
   async fire(event, path, triggeredBy, vars) {
+    const { mailService } = this.crowi;
+
     const GlobalNotification = this.crowi.model('GlobalNotificationSetting');
     const notifications = await GlobalNotification.findSettingByPathAndEvent(event, path, this.type);
 
     const option = this.generateOption(event, path, triggeredBy, vars);
 
     await Promise.all(notifications.map((notification) => {
-      return this.mailer.send({ ...option, to: notification.toEmail });
+      return mailService.send({ ...option, to: notification.toEmail });
     }));
   }
 

+ 54 - 54
src/server/service/mail.js

@@ -1,18 +1,49 @@
-/**
- * mailer
- */
+const logger = require('@alias/logger')('growi:service:mail');
 
-module.exports = function(crowi) {
-  const logger = require('@alias/logger')('growi:lib:mailer');
-  const nodemailer = require('nodemailer');
-  const swig = require('swig-templates');
+const nodemailer = require('nodemailer');
+const swig = require('swig-templates');
 
-  const { configManager, appService } = crowi;
+class MailService {
 
-  const mailConfig = {};
-  let mailer = {};
+  constructor(crowi) {
+    this.appService = crowi.appService;
+    this.configManager = crowi.configManager;
+
+    this.mailConfig = {};
+    this.mailer = {};
+
+    this.initialize();
+  }
+
+  initialize() {
+    const { appService, configManager } = this;
+
+    if (!configManager.getConfig('crowi', 'mail:from')) {
+      this.mailer = null;
+      return;
+    }
+
+    // Priority 1. SMTP
+    if (configManager.getConfig('crowi', 'mail:smtpHost') && configManager.getConfig('crowi', 'mail:smtpPort')) {
+      this.mailer = this.createSMTPClient();
+    }
+    // Priority 2. SES
+    else if (configManager.getConfig('crowi', 'aws:accessKeyId') && configManager.getConfig('crowi', 'aws:secretAccessKey')) {
+      this.mailer = this.createSESClient();
+    }
+    else {
+      this.mailer = null;
+    }
+
+    this.mailConfig.from = configManager.getConfig('crowi', 'mail:from');
+    this.mailConfig.subject = `${appService.getAppTitle()}からのメール`;
+
+    logger.debug('mailer initialized');
+  }
+
+  createSMTPClient(option) {
+    const { configManager } = this;
 
-  function createSMTPClient(option) {
     logger.debug('createSMTPClient option', option);
     if (!option) {
       option = { // eslint-disable-line no-param-reassign
@@ -38,7 +69,9 @@ module.exports = function(crowi) {
     return client;
   }
 
-  function createSESClient(option) {
+  createSESClient(option) {
+    const { configManager } = this;
+
     if (!option) {
       option = { // eslint-disable-line no-param-reassign
         accessKeyId: configManager.getConfig('crowi', 'aws:accessKeyId'),
@@ -53,48 +86,22 @@ module.exports = function(crowi) {
     return client;
   }
 
-  function initialize() {
-    if (!configManager.getConfig('crowi', 'mail:from')) {
-      mailer = undefined;
-      return;
-    }
-
-    if (configManager.getConfig('crowi', 'mail:smtpHost') && configManager.getConfig('crowi', 'mail:smtpPort')
-    ) {
-      // SMTP 設定がある場合はそれを優先
-      mailer = createSMTPClient();
-    }
-    else if (configManager.getConfig('crowi', 'aws:accessKeyId') && configManager.getConfig('crowi', 'aws:secretAccessKey')) {
-      // AWS 設定がある場合はSESを設定
-      mailer = createSESClient();
-    }
-    else {
-      mailer = undefined;
-    }
-
-    mailConfig.from = configManager.getConfig('crowi', 'mail:from');
-    mailConfig.subject = `${appService.getAppTitle()}からのメール`;
-
-    logger.debug('mailer initialized');
-  }
-
-  function setupMailConfig(overrideConfig) {
+  setupMailConfig(overrideConfig) {
     const c = overrideConfig;
 
-
     let mc = {};
-    mc = mailConfig;
+    mc = this.mailConfig;
 
     mc.to = c.to;
-    mc.from = c.from || mailConfig.from;
+    mc.from = c.from || this.mailConfig.from;
     mc.text = c.text;
-    mc.subject = c.subject || mailConfig.subject;
+    mc.subject = c.subject || this.mailConfig.subject;
 
     return mc;
   }
 
-  async function send(config) {
-    if (mailer == null) {
+  async send(config) {
+    if (this.mailer == null) {
       throw new Error('Mailer is not completed to set up. Please set up SMTP or AWS setting.');
     }
 
@@ -105,16 +112,9 @@ module.exports = function(crowi) {
     );
 
     config.text = output;
-    return mailer.sendMail(setupMailConfig(config));
+    return this.mailer.sendMail(this.setupMailConfig(config));
   }
 
+}
 
-  initialize();
-
-  return {
-    createSMTPClient,
-    createSESClient,
-    mailer,
-    send,
-  };
-};
+module.exports = MailService;