forked from nodeSolidServer/node-solid-server
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathemail-service.js
More file actions
160 lines (142 loc) · 4.02 KB
/
email-service.js
File metadata and controls
160 lines (142 loc) · 4.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
'use strict'
const nodemailer = require('nodemailer')
const path = require('path')
/**
* Models a Nodemailer-based email sending service.
*
* @see https://nodemailer.com/about/
*/
class EmailService {
/**
* @constructor
*
* @param templatePath {string} Path to the email templates directory
*
* @param config {Object} Nodemailer configuration object
* @see https://nodemailer.com/smtp/
*
* Transport SMTP config options:
* @param config.host {string} e.g. 'smtp.gmail.com'
* @param config.port {string} e.g. '465'
* @param config.secure {boolean} Whether to use TLS when connecting to server
*
* Transport authentication config options:
* @param config.auth {Object}
* @param config.auth.user {string} Smtp username (e.g. 'alice@gmail.com')
* @param config.auth.pass {string} Smtp password
*
* Optional default Sender / `from:` address:
* @param [config.sender] {string} e.g. 'Solid Server <no-reply@databox.me>'
*/
constructor (templatePath, config) {
this.mailer = nodemailer.createTransport(config)
this.sender = this.initSender(config)
this.templatePath = templatePath
}
/**
* Returns the default Sender address based on config.
*
* Note that if using Gmail for SMTP transport, Gmail ignores the sender
* `from:` address and uses the SMTP username instead (`auth.user`).
*
* @param config {Object}
*
* The sender is derived from either:
* @param [config.sender] {string} e.g. 'Solid Server <no-reply@databox.me>'
*
* or, if explicit sender is not passed in, uses:
* @param [config.host] {string} SMTP host from transport config
*
* @return {string} Sender `from:` address
*/
initSender (config) {
let sender
if (config.sender) {
sender = config.sender
} else {
sender = `no-reply@${config.host}`
}
return sender
}
/**
* Sends an email (passes it through to nodemailer).
*
* @param email {Object}
*
* @return {Promise<EmailResponse>}
*/
sendMail (email) {
email.from = email.from || this.sender
return this.mailer.sendMail(email)
}
/**
* Sends an email using a saved email template.
* Usage:
*
* ```
* let data = { webid: 'https://example.com/alice#me', ... }
*
* emailService.sendWithTemplate('welcome', data)
* .then(response => {
* // email sent using the 'welcome' template
* })
* ```
*
* @param templateName {string} Name of a template file in the email-templates
* dir, no extension necessary.
*
* @param data {Object} Key/value hashmap of data for an email template.
*
* @return {Promise<EmailResponse>}
*/
sendWithTemplate (templateName, data) {
return Promise.resolve()
.then(() => {
let renderedEmail = this.emailFromTemplate(templateName, data)
return this.sendMail(renderedEmail)
})
}
/**
* Returns an email from a rendered template.
*
* @param templateName {string}
* @param data {Object} Key/value hashmap of data for an email template.
*
* @return {Object} Rendered email object from template
*/
emailFromTemplate (templateName, data) {
let template = this.readTemplate(templateName)
return Object.assign({}, template.render(data), data)
}
/**
* Reads (requires) and returns the contents of an email template file, for
* a given template name.
*
* @param templateName {string}
*
* @throws {Error} If the template could not be found
*
* @return {Object}
*/
readTemplate (templateName) {
let templateFile = this.templatePathFor(templateName)
let template
try {
template = require(templateFile)
} catch (error) {
throw new Error('Cannot find email template: ' + templateFile)
}
return template
}
/**
* Returns a template file path for a given template name.
*
* @param templateName {string}
*
* @return {string}
*/
templatePathFor (templateName) {
return path.join(this.templatePath, templateName)
}
}
module.exports = EmailService