/**
* Sent E-Mail in the same way as mail scheduler dose
*
* Usage from a command line:
cd /opt/unitybase/product/my-product
mail --mail-rcpt "my@test.com" -env /var/opt/unitybase/my-app/ubConfig.env
# or
strace -f -e trace=network mail --mail-rcpt "my@test.com" -env /var/opt/unitybase/my-app/ubConfig.env
* @author pavel.mash
* @module mail
* @memberOf module:@unitybase/ubcli
*/
// const fs = require('fs')
// const path = require('path')
const cmdLineOpt = require('@unitybase/base').options
const argv = require('@unitybase/base').argv
module.exports = function mailSend (options) {
if (!options) {
const opts = cmdLineOpt.describe('mail', `Send E-Mail using mailer from server config.
Example for tracing network activity:
cd /opt/unitybase/product/my-product
strace -f -e trace=network ubcli mail --mail-rcpt "my@test.com" -env /var/opt/unitybase/my-app/ubConfig.env`,
'ubcli'
)
.add({ short: 'cfg', long: 'cfg', param: 'serverConfig', defaultValue: 'ubConfig.json', help: 'Server config' })
.add({ short: '-to', long: '-to', param: 'to', help: 'To: mail address' })
.add({ short: '-cc', long: '-cc', param: 'cc', defaultValue: '', help: 'Cc: mail address' })
.add({ short: '-bcc', long: '-bcc', param: 'bcc', defaultValue: '', help: 'Bcc: mail address' })
.add({ short: '-reply-to', long: '-reply-to', param: 'replyTo', defaultValue: '', help: 'Reply-To: mail address' })
// .add({ short: '-upload-file', long: '-mail-rcpt', param: 'uploadFile', defaultValue: '', help: 'File to upload' })
.add({ short: '-body', long: '-body', param: 'body', defaultValue: 'UnityBase mailer test', help: 'E-Mail body' })
options = opts.parseVerbose({}, true)
if (!options) return
}
console.log(options)
const serverConfig = argv.getServerConfiguration()
const mailerParams = serverConfig.application.customSettings.mailerConfig
if (!mailerParams) {
console.error('ubConfig.json "application.customSettings.mailerConfig" section is missed')
return
}
if (!mailerParams.targetHost) {
console.error('ubConfig.json "application.customSettings.mailerConfig.targetHost" is not configured')
return
}
const mailerCfg = {
host: mailerParams.targetHost,
port: mailerParams.targetPort || '25',
user: mailerParams.user || '',
password: mailerParams.password || '',
tls: Boolean(mailerParams.autoTLS),
fullSSL: Boolean(mailerParams.fullSSL),
auth: mailerParams.auth || false,
deferLogin: true
}
console.debug('Mailer config:\n' + JSON.stringify(mailerCfg, null, ' '))
let UBMail
try {
UBMail = require('@unitybase/mailer')
} catch (e) {
console.error('@unitybase/mailer package is not installed for application')
throw e
}
if (mailerParams.oauthProvider) {
console.info(`Try to obtain XOAUTH2 token using customSettings.openIDConnect.${mailerParams.oauthProvider} configuration`)
const oidcCfg = serverConfig.application.customSettings.openIDConnect
if (!oidcCfg) {
throw new Error('ubConfig.application.customSettings.openIDConnect section is empty')
}
const provCfg = oidcCfg[mailerParams.oauthProvider]
if (!provCfg) {
throw new Error(`ubConfig.application.customSettings.openIDConnect.${mailerParams.oauthProvider} section is empty`)
}
console.info('Token provider config is ', provCfg)
const xoauth2Token = openIDGetCCToken(provCfg, provCfg.emailTokenScope)
mailerCfg.OAuth2Token = xoauth2Token
}
console.time('SMTP_session')
const mailSender = new UBMail.TubMailSender(mailerCfg)
mailSender.login()
const mailObj = {
fromAddr: mailerParams.fromAddr || ('no-reply@' + mailerParams.targetHost),
subject: 'Test email',
bodyType: UBMail.TubSendMailBodyType.Text,
body: options['-body'],
toAddr: [options['-to']]
}
if (options['-cc']) {
mailObj.ccAddr = options['-cc']
}
if (options['-bcc']) {
mailObj.bccAddr = options['-bcc']
}
if (options['-reply-to']) {
mailObj.replyTo = options['-reply-to']
}
console.debug('mailSender.sendMail params:', mailObj)
const fRes = mailSender.sendMail(mailObj)
console.timeEnd('SMTP_session')
if (!fRes) {
console.error('Got answer:', mailSender.lastError)
} else {
console.info('Message send')
}
}
/**
* @unitybase/openid-connect cannot be used in command line script, so here we emulate getCCToken function locally
* @param {object} providerConfig
* @param {string} scope
* @returns {string}
*/
function openIDGetCCToken (providerConfig, scope) {
console.time('gotOIDCToken')
const http = require('http')
let fields = `grant_type=client_credentials&client_id=${providerConfig.client_id}&client_secret=${providerConfig.client_secret}`
fields += `&scope=${scope}`
const tokenRequest = http.request({
URL: providerConfig.tokenUrl,
method: 'POST'
})
tokenRequest.setHeader('Content-Type', 'application/x-www-form-urlencoded')
console.debug(`sending POST HTTP request to ${providerConfig.tokenUrl}, body: ${fields}`)
const tokenResponse = tokenRequest.end(fields)
if (tokenResponse.statusCode !== 200) {
const errBody = tokenResponse.read()
throw new Error(`OpenIDConnect provider return invalid response for tokens request ${tokenResponse.statusCode} body: ${errBody}`)
}
const tokenResp = tokenResponse.json()
const token = tokenResp.access_token
console.debug('Got access_token:', token)
console.timeEnd('gotOIDCToken')
return token
}
module.exports.shortDoc = 'Send E-Mail using mailer config from ubConfig.json'