ac-ses 1.2.3 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.eslintrc.js CHANGED
@@ -20,7 +20,7 @@ const config = {
20
20
  it: true
21
21
  },
22
22
  'parserOptions': {
23
- 'ecmaVersion': 2018
23
+ 'ecmaVersion': 2022
24
24
  },
25
25
  }
26
26
 
package/.ncurc.js ADDED
@@ -0,0 +1,5 @@
1
+ module.exports = {
2
+ target: (dependencyName, parsedVersion) => {
3
+ return dependencyName === 'chai' ? 'minor' : 'latest'
4
+ }
5
+ }
package/CHANGELOG.md CHANGED
@@ -1,3 +1,50 @@
1
+ <a name="2.0.0"></a>
2
+
3
+ # [2.0.0](https://github.com/admiralcloud/ac-ses/compare/v1.2.4..v2.0.0) (2024-01-06 09:43:38)
4
+
5
+
6
+ ### Bug Fix
7
+
8
+ * **App:** Use async/await and remove some functions | MP | [7f9c4aee85e062dfc08fed09c1f4bf08d37e3673](https://github.com/admiralcloud/ac-ses/commit/7f9c4aee85e062dfc08fed09c1f4bf08d37e3673)
9
+ Package now uses async/await. No more support for blocktime and group messages - use your application logic for that.
10
+ Related issues: [undefined/undefined#master](undefined/browse/master)
11
+ ### Chores
12
+
13
+ * **App:** Some minor updates | MP | [6cdc1d8f9927d5926836b1128e3f84b8ebb1c0f0](https://github.com/admiralcloud/ac-ses/commit/6cdc1d8f9927d5926836b1128e3f84b8ebb1c0f0)
14
+ Some minor updates
15
+ Related issues: [undefined/undefined#master](undefined/browse/master)
16
+ ### Chores
17
+
18
+ * **App:** Updated packages | MP | [21369161d02172ccba704d286dca59b5e0dbbde5](https://github.com/admiralcloud/ac-ses/commit/21369161d02172ccba704d286dca59b5e0dbbde5)
19
+ Updated packages
20
+ Related issues: [undefined/undefined#master](undefined/browse/master)
21
+ ## BREAKING CHANGES
22
+ * **App:** See README breaking changes for version 2
23
+ <a name="1.2.4"></a>
24
+
25
+ ## [1.2.4](https://github.com/admiralcloud/ac-ses/compare/v1.2.3..v1.2.4) (2023-01-31 11:26:12)
26
+
27
+
28
+ ### Bug Fix
29
+
30
+ * **App:** Add debug mode for SES headers | MP | [b11e0374c5956236e80f4b81d9895ba9fd5916f3](https://github.com/admiralcloud/ac-ses/commit/b11e0374c5956236e80f4b81d9895ba9fd5916f3)
31
+ Add debug mode for SES headers
32
+ Related issues: [undefined/undefined#master](undefined/browse/master)
33
+ ### Tests
34
+
35
+ * **App:** Fixed tests after package updates | MP | [ba0a41496ffa202c9bac3d7fbde5a7c4b542d24b](https://github.com/admiralcloud/ac-ses/commit/ba0a41496ffa202c9bac3d7fbde5a7c4b542d24b)
36
+ Fixed tests after package updates
37
+ Related issues: [undefined/undefined#master](undefined/browse/master)
38
+ ### Chores
39
+
40
+ * **App:** Updated packages | MP | [f3affc2c748a2ed6cb96eaad6a31fae2af646d37](https://github.com/admiralcloud/ac-ses/commit/f3affc2c748a2ed6cb96eaad6a31fae2af646d37)
41
+ Updated packages
42
+ Related issues: [undefined/undefined#master](undefined/browse/master)
43
+ ### Chores
44
+
45
+ * **App:** Updated ESLint setting | MP | [a5dd3adfa10ef02ca1c886a0485d324b6ac73aee](https://github.com/admiralcloud/ac-ses/commit/a5dd3adfa10ef02ca1c886a0485d324b6ac73aee)
46
+ Updated ESLint setting to ECMA 2021
47
+ Related issues: [undefined/undefined#master](undefined/browse/master)
1
48
  <a name="1.2.3"></a>
2
49
 
3
50
  ## [1.2.3](https://github.com/admiralcloud/ac-ses/compare/v1.2.2..v1.2.3) (2022-07-22 05:34:50)
package/README.md CHANGED
@@ -1,18 +1,19 @@
1
1
  # AC SES
2
2
  A helper tool to send emails via AWS SES.
3
- It also support "convenience" calls, to inform groups (e.g. support with informSupport function)
4
3
 
5
- ## Usage
4
+ ## BREAKING CHANGES VERSION 2
5
+ + use async/await
6
+ + no more support for blocktime - use your application logic instead
7
+ + no more support for group messages - use your application logid instead
6
8
 
9
+ ## Usage
7
10
  ```
8
11
  const acses = require('ac-ses')
9
12
 
10
13
  // Min requirements
11
14
  acses.init({
12
- aws: {
13
- accessKeyId: 'xxx',
14
- secretAccessKey: 'xxx',
15
- region: 'eu-central-1'
15
+ defaultSender: {
16
+ address: 'sender@domain.com
16
17
  }
17
18
  })
18
19
 
@@ -34,47 +35,35 @@ let email = {
34
35
  html: 'This is my <b>message</b>' // optional
35
36
  }
36
37
 
37
- acses.sendEmail(email, (err, result) => {
38
- console.log(err, result)
39
- // More infos regarding the result:
40
- // https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/SES.html#sendEmail-property
41
- })
38
+ await acses.sendEmail(email)
39
+ // -> Response
40
+ {
41
+ '$metadata': {
42
+ httpStatusCode: 200,
43
+ requestId: '123466-557d-4a75-8d5c-d71e336963ec',
44
+ extendedRequestId: undefined,
45
+ cfId: undefined,
46
+ attempts: 1,
47
+ totalRetryDelay: 0
48
+ },
49
+ MessageId: '12356-2c4f41dd-6f2b-402e-9c26-123355-000000'
50
+ }
42
51
  ```
43
52
 
44
53
  Full setup
45
-
46
54
  ```
47
55
  acses.init({
48
- aws: {
49
- accessKeyId: 'xxx',
50
- secretAccessKey: 'xxx',
51
- region: 'eu-central-1'
52
- },
53
- redis: REDISINSTANCE,
54
- defaultBlockTime: BLOCKTIME FOR SAME MESSAGE,
55
56
  defaultSender: {
56
57
  address: 'defaultSender@admiralcloud.com',
57
58
  name: 'AdmiralCloud Sender'
58
59
  },
59
- securityRecipient: {
60
- address: 'defaultSecurityRecipient@admiralcloud.com',
61
- name: 'AdmiralCloud Security'
62
- },
63
- supportRecipient: {
64
- address: address: 'defaultSupportRecipient@admiralcloud.com',
65
- name: 'AdmiralCloud Support'
66
- },
67
60
  environment: ENVIRONMENT // defaults to proces.env.NODE_ENV,
68
61
  useEnvironmentPrefixInSubject: TRUE|FALSE // defaults to TRUE - prefixes e-mail subject with environment to avoid confusion during development
69
62
  })
70
-
71
-
72
63
  ```
73
64
 
74
65
  ## Links
75
66
  - [Website](https://www.admiralcloud.com/)
76
- - [Twitter (@admiralcloud)](https://twitter.com/admiralcloud)
77
- - [Facebook](https://www.facebook.com/MediaAssetManagement/)
78
67
 
79
68
  ## License
80
- [MIT License](https://opensource.org/licenses/MIT) Copyright © 2009-present, AdmiralCloud, Mark Poepping
69
+ [MIT License](https://opensource.org/licenses/MIT) Copyright © 2009-present, AdmiralCloud AG, Mark Poepping
package/index.js CHANGED
@@ -1,39 +1,21 @@
1
1
  const _ = require('lodash')
2
- const async = require('async')
3
- const aws = require('aws-sdk')
4
-
5
- const crypto = require('crypto')
6
2
  const { v4: uuidV4 } = require('uuid')
7
3
 
8
4
  const quotedPrintable = require('quoted-printable')
9
5
  const utf8 = require('utf8')
10
6
 
11
- const acses = function() {
7
+ const { SESClient, SendRawEmailCommand } = require("@aws-sdk/client-ses")
8
+
9
+ const acses = () => {
12
10
  let ses
13
- let redis // only required if blockTime should be used - use init to set a redis instance from your main app
14
11
 
15
12
  let defaultSender
16
- let supportRecipient
17
- let securityRecipient
18
- let operationsRecipient
19
- let defaultBlockTime = 60 // used for support and security
20
13
  let testMode // if true, no email is sent
21
14
  let environment = process.env.NODE_ENV || 'development'
22
15
  let useEnvironmentPrefixInSubject = environment !== 'production'
23
16
 
24
17
  const init = function(options) {
25
- const awsConfig = {
26
- accessKeyId: _.get(options, 'aws.accessKeyId', process.env.AWS_ACCESS_KEY),
27
- secretAccessKey: _.get(options, 'aws.secretAccessKey', process.env.AWS_ACCESS_SECRET),
28
- region: _.get(options, 'aws.region', process.env.AWS_REGION)
29
- }
30
- ses = new aws.SES(awsConfig)
31
- if (_.get(options, 'redis')) {
32
- redis = _.get(options, 'redis')
33
- }
34
- if (_.get(options, 'defaultBlockTime')) {
35
- defaultBlockTime = _.get(options, 'defaultBlockTime')
36
- }
18
+ ses = new SESClient()
37
19
  if (_.get(options, 'testMode')) {
38
20
  testMode = _.get(options, 'testMode')
39
21
  }
@@ -44,19 +26,11 @@ const acses = function() {
44
26
 
45
27
  // helper
46
28
  if (_.get(options, 'defaultSender') && prepareEmailAddress(_.get(options, 'defaultSender'))) defaultSender = _.get(options, 'defaultSender')
47
- if (_.get(options, 'supportRecipient') && prepareEmailAddress(_.get(options, 'supportRecipient'))) supportRecipient = _.get(options, 'supportRecipient')
48
- if (_.get(options, 'securityRecipient') && prepareEmailAddress(_.get(options, 'securityRecipient'))) securityRecipient = _.get(options, 'securityRecipient')
49
- if (_.get(options, 'operationsRecipient') && prepareEmailAddress(_.get(options, 'operationsRecipient'))) operationsRecipient = _.get(options, 'operationsRecipient')
50
-
29
+
51
30
  return {
52
- awsConfig: _.pick(awsConfig, ['accessKeyId', 'region']),
53
31
  testMode,
54
- defaultBlockTime,
55
32
  environment,
56
- defaultSender,
57
- supportRecipient,
58
- securityRecipient,
59
- operationsRecipient
33
+ defaultSender
60
34
  }
61
35
  }
62
36
 
@@ -67,10 +41,10 @@ const acses = function() {
67
41
  * OUT John Doe <john.doe@example.com>
68
42
  * @param {*} params
69
43
  */
70
- const prepareEmailAddress = function(params) {
71
- if (!_.get(params, 'address')) throw new Error({ message: 'ACSES.prepareEmailAddress - address_required' })
72
- if (!_.isString(_.get(params, 'address'))) throw new Error({ message: 'ACSES.prepareEmailAddress - address_mustBeAString' })
73
- let email = (_.get(params, 'name') ? _.get(params, 'name') + ' <' : '') + _.get(params, 'address') + (_.get(params, 'name') ? '>' : '')
44
+ const prepareEmailAddress = ({ address, name }) => {
45
+ if (!address) throw new Error({ message: 'ACSES.prepareEmailAddress - address_required' })
46
+ if (!_.isString(address)) throw new Error({ message: 'ACSES.prepareEmailAddress - address_mustBeAString' })
47
+ let email = name ? `${name} <${address}>` : address
74
48
  return email
75
49
  }
76
50
 
@@ -89,14 +63,11 @@ const acses = function() {
89
63
  *
90
64
  * @param attachments ARRAY Optional array of objects with properties: filename, content (as base64) and encoding as 'base64'
91
65
  *
92
- * @param blockTime INT OPTIONAL If set, you cannot send an email to the same recipient for the blockTime (helpful for warning messages - you don't want them every second!)
93
- * @param redisKey STRING OPTIONAL You can use your own redisKey for the blockTime feature, or let this app create an MD5 hash from the parameters
94
66
  * @param encoding STRING OPTIONAL Encoding for multipart alternative parts - defaults to "quoted-printable"
95
67
  *
96
- * @param {*} cb Optional callback
97
68
  */
98
- const sendEmail = (params, cb) => {
99
- if (!_.isObject(ses)) return cb({ message: 'pleaseUseInitBeforeSendingEmail' })
69
+ const sendEmail = async(params) => {
70
+ if (!_.isObject(ses)) throw new Error('pleaseUseInitBeforeSendingEmail')
100
71
  if (!_.get(params, 'from') && defaultSender) _.set(params, 'from', defaultSender)
101
72
  const fieldCheck = [
102
73
  { field: 'from', type: _.isPlainObject, required: true },
@@ -109,173 +80,95 @@ const acses = function() {
109
80
  // OPTIONS
110
81
  { field: 'replyTo', type: _.isArray },
111
82
  { field: 'attachments', type: _.isArray },
83
+ { field: 'debug', type: _.isBoolean },
112
84
  ]
113
85
 
114
86
  _.some(fieldCheck, (field) => {
115
- if (field.required && !_.has(params, field.field)) return cb({ message: field.field + '_required' })
116
- if (_.get(params, field.field) && !field.type(_.get(params, field.field))) return cb({ message: field.field + '_typeInvalid' })
87
+ if (field.required && !_.has(params, field.field)) throw new Error(field.field + '_required')
88
+ if (_.get(params, field.field) && !field.type(_.get(params, field.field))) throw new Error(field.field + '_typeInvalid')
117
89
  })
118
90
 
119
91
  const boundaryMixed = uuidV4()
120
92
  const boundaryAlternative = uuidV4()
121
93
  const encoding = _.get(params, 'encoding', 'quoted-printable')
122
94
 
123
- async.series({
124
- checkBlockTime: (done) => {
125
- if (!redis || !params.blockTime) return done()
126
- let sesParams = {
127
- from: params.from,
128
- to: params.to,
129
- subject: params.subject,
130
- text: params.text
131
- }
132
- let redisKey = _.get(params, 'redisKey', crypto.createHash('md5').update(JSON.stringify(sesParams)).digest('hex'))
133
- redis.set(redisKey, 1, 'EX', params.blockTime, 'NX', (err, result) => {
134
- if (err) return done(err)
135
- if (result === 'OK') return done()
136
- return done(423) // the key is already locked
95
+ // sendRawMessage
96
+ let raw = 'From: ' + prepareEmailAddress(_.get(params, 'from')) + '\n'
97
+ // prepare To, Cc, Bcc
98
+ _.forEach(['to', 'cc', 'bcc'], type => {
99
+ if (_.size(_.get(params, type))) {
100
+ let recipients = _.map(_.get(params, type), (recipient) => {
101
+ return prepareEmailAddress(recipient)
137
102
  })
138
- },
139
- sendRawMessage: (done) => {
140
- let raw = 'From: ' + prepareEmailAddress(_.get(params, 'from')) + '\n'
141
- // prepare To, Cc, Bcc
142
- _.forEach(['to', 'cc', 'bcc'], type => {
143
- if (_.size(_.get(params, type))) {
144
- let recipients = _.map(_.get(params, type), (recipient) => {
145
- return prepareEmailAddress(recipient)
146
- })
147
- raw += _.upperFirst(type) + ': ' + _.join(recipients, ', ') + '\n'
148
- }
149
- })
150
- if (params.replyTo) {
151
- let recipients = _.map(_.get(params, 'replyTo'), (recipient) => {
152
- return prepareEmailAddress(recipient)
153
- })
154
- raw += 'Reply-To: ' + _.join(recipients, ', ') + '\n'
155
- }
156
-
157
- raw += 'Subject: ' + (useEnvironmentPrefixInSubject ? (_.toUpper(environment) + ' | ') : '') + params.subject + '\n'
158
-
159
- // announce multipart/mixed
160
- raw += 'Mime-Version: 1.0\n'
161
- raw += 'Content-type: multipart/mixed; boundary="' + boundaryMixed + '"\n\n'
162
- raw += 'This message is in MIME format. Since your mail reader does not understand this format, some or all of this message may not be legible.\n\n'
163
-
164
- // text and HTML are multipart/alternatives with their own boundaries
165
- raw += '--' + boundaryMixed + '\nContent-Type: multipart/alternative; boundary="' + boundaryAlternative + '"\n\n'
166
- if (params.text) {
167
- raw += '--' + boundaryAlternative + '\nContent-Type: text/plain; charset="UTF-8"\nContent-Transfer-Encoding: ' + encoding + '\n\n'
168
- raw += quotedPrintable.encode(utf8.encode(params.text)) + '\n\n'
169
- }
170
- if (params.html) {
171
- raw += '--' + boundaryAlternative + '\nContent-Type: text/html; charset="UTF-8"\nContent-Transfer-Encoding: ' + encoding + '\n\n'
172
- raw += quotedPrintable.encode(utf8.encode(params.html)) + '\n\n'
173
- }
174
- raw += '--' + boundaryAlternative + '--\n\n'
175
-
176
- if (params.attachments) {
177
- _.forEach(params.attachments, attachment => {
178
- raw += '--' + boundaryMixed + '\n'
179
- raw += 'Content-Disposition: attachment; filename="' + attachment.filename + '"\n'
180
- raw += 'Content-Type: ' + attachment.contentType + '; name="' + attachment.filename + '"\nContent-Transfer-Encoding: ' + attachment.encoding + '\n\n'
181
- raw += attachment.content + '\n\n'
182
- })
183
- raw += '--' + boundaryMixed + '--\n'
184
- }
185
-
186
- const rawParams = {
187
- RawMessage: { /* required */
188
- Data: Buffer.from(raw)
189
- }
190
- }
191
- if (testMode) {
192
- // return fake response, but do not send message
193
- let mockResponse = {
194
- ResponseMetadata: {
195
- RequestId: uuidV4()
196
- },
197
- MessageId: Math.random().toString(36) + '-' + uuidV4() + '-000000',
198
- testMode: true
199
- }
200
- return done(null, mockResponse)
201
- }
202
- ses.sendRawEmail(rawParams, done)
103
+ raw += _.upperFirst(type) + ': ' + _.join(recipients, ', ') + '\n'
203
104
  }
204
- }, (err, result) => {
205
- if (err && err === 423) err = null // this is not an error, just blocked
206
- if (_.isFunction(cb)) {
207
- return cb(err, _.get(result, 'sendRawMessage'))
208
- }
209
- if (err) throw new Error(err)
210
105
  })
211
- }
106
+ if (params.replyTo) {
107
+ let recipients = _.map(_.get(params, 'replyTo'), (recipient) => {
108
+ return prepareEmailAddress(recipient)
109
+ })
110
+ raw += 'Reply-To: ' + _.join(recipients, ', ') + '\n'
111
+ }
212
112
 
213
- /**
214
- * Use as as shortcut to inform support - no need for from or to, this is already pre-defined
215
- * Other than that, it works similar to sendEmail
216
- * Differences: no HTML to improve delivery
217
- * @param {*} params
218
- * @param {*} cb
219
- */
220
- const informSecurity = function(params, cb) {
221
- if (!securityRecipient) return cb({ message: 'acses.informSecurity - securityRecipient_notSet' })
222
- let message = {
223
- to: [securityRecipient],
224
- subject: params.subject,
225
- text: params.text,
226
- blockTime: _.get(params, 'blockTime', defaultBlockTime),
227
- redisKey: _.get(params, 'redisKey')
113
+ raw += 'Subject: ' + (useEnvironmentPrefixInSubject ? (_.toUpper(environment) + ' | ') : '') + params.subject + '\n'
114
+ if (params?.debug) {
115
+ console.log('ACSES | DEBUG Headers | %j', raw.split('/n'))
228
116
  }
229
- if (_.isFunction(cb)) sendEmail(message, cb)
230
- else sendEmail(message)
231
- }
232
117
 
233
- /**
234
- * Use as as shortcut to inform support - no need for from or to, this is already pre-defined
235
- * Other than that, it works similar to sendEmail
236
- * Differences: no HTML to improve delivery
237
- * @param {*} params
238
- * @param {*} cb
239
- */
240
- const informSupport = function(params, cb) {
241
- if (!supportRecipient) return cb({ message: 'acses.informSecurity - supportRecipient_notSet' })
242
- let message = {
243
- to: [supportRecipient],
244
- subject: params.subject,
245
- text: params.text,
246
- blockTime: _.get(params, 'blockTime', defaultBlockTime),
247
- redisKey: _.get(params, 'redisKey')
118
+ // announce multipart/mixed
119
+ raw += 'Mime-Version: 1.0\n'
120
+ raw += 'Content-type: multipart/mixed; boundary="' + boundaryMixed + '"\n\n'
121
+ raw += 'This message is in MIME format. Since your mail reader does not understand this format, some or all of this message may not be legible.\n\n'
122
+
123
+ // text and HTML are multipart/alternatives with their own boundaries
124
+ raw += '--' + boundaryMixed + '\nContent-Type: multipart/alternative; boundary="' + boundaryAlternative + '"\n\n'
125
+ if (params.text) {
126
+ raw += '--' + boundaryAlternative + '\nContent-Type: text/plain; charset="UTF-8"\nContent-Transfer-Encoding: ' + encoding + '\n\n'
127
+ raw += quotedPrintable.encode(utf8.encode(params.text)) + '\n\n'
128
+ }
129
+ if (params.html) {
130
+ raw += '--' + boundaryAlternative + '\nContent-Type: text/html; charset="UTF-8"\nContent-Transfer-Encoding: ' + encoding + '\n\n'
131
+ raw += quotedPrintable.encode(utf8.encode(params.html)) + '\n\n'
132
+ }
133
+ raw += '--' + boundaryAlternative + '--\n\n'
134
+
135
+ if (params.attachments) {
136
+ _.forEach(params.attachments, attachment => {
137
+ raw += '--' + boundaryMixed + '\n'
138
+ raw += 'Content-Disposition: attachment; filename="' + attachment.filename + '"\n'
139
+ raw += 'Content-Type: ' + attachment.contentType + '; name="' + attachment.filename + '"\nContent-Transfer-Encoding: ' + attachment.encoding + '\n\n'
140
+ raw += attachment.content + '\n\n'
141
+ })
142
+ raw += '--' + boundaryMixed + '--\n'
248
143
  }
249
- if (_.isFunction(cb)) sendEmail(message, cb)
250
- else sendEmail(message)
251
- }
252
144
 
253
- /**
254
- * Use as as shortcut to inform operations - no need for from or to, this is already pre-defined
255
- * Other than that, it works similar to sendEmail
256
- * Differences: no HTML to improve delivery
257
- * @param {*} params
258
- * @param {*} cb
259
- */
260
- const informOperations = function(params, cb) {
261
- if (!operationsRecipient) return cb({ message: 'acses.informSecurity - operationsRecipient_notSet' })
262
- let message = {
263
- to: [operationsRecipient],
264
- subject: params.subject,
265
- text: params.text,
266
- blockTime: _.get(params, 'blockTime', defaultBlockTime),
267
- redisKey: _.get(params, 'redisKey')
145
+ const rawParams = {
146
+ RawMessage: { /* required */
147
+ Data: Buffer.from(raw)
148
+ }
149
+ }
150
+
151
+ if (testMode) {
152
+ // return fake response, but do not send message
153
+ let mockResponse = {
154
+ '$metadata': {
155
+ httpStatusCode: 200,
156
+ requestId: uuidV4(),
157
+ attempts: 1
158
+ },
159
+ MessageId: Math.random().toString(36) + '-' + uuidV4() + '-000000',
160
+ testMode: true
161
+ }
162
+ return mockResponse
268
163
  }
269
- if (_.isFunction(cb)) sendEmail(message, cb)
270
- else sendEmail(message)
164
+ const command = new SendRawEmailCommand(rawParams)
165
+ const response = await ses.send(command)
166
+ return response
271
167
  }
272
168
 
273
169
  return {
274
170
  init,
275
- sendEmail,
276
- informSecurity,
277
- informSupport,
278
- informOperations
171
+ sendEmail
279
172
  }
280
173
  }
281
174
 
package/package.json CHANGED
@@ -4,28 +4,27 @@
4
4
  "license": "MIT",
5
5
  "repository": "admiralcloud/ac-ses",
6
6
  "homepage": "https://www.admiralcloud.com",
7
- "version": "1.2.3",
7
+ "version": "2.0.0",
8
8
  "dependencies": {
9
- "async": "^3.2.4",
10
- "aws-sdk": "^2.1180.0",
9
+ "@aws-sdk/client-ses": "^3.485.0",
11
10
  "lodash": "^4.17.21",
12
11
  "quoted-printable": "^1.0.1",
13
12
  "utf8": "^3.0.0",
14
- "uuid": "^8.x"
13
+ "uuid": "^9.x"
15
14
  },
16
15
  "devDependencies": {
17
- "ac-semantic-release": "^0.3.3",
18
- "eslint": "7.x",
19
- "expect": "^27.x",
20
- "ioredis": "^4.28.5",
21
- "mocha": "^9.2.2",
22
- "mocha-jenkins-reporter": "0.4.7"
16
+ "ac-semantic-release": "^0.4.2",
17
+ "chai": "^4.4.0",
18
+ "eslint": "8.x",
19
+ "expect": "^29.7.0",
20
+ "mocha": "^10.2.0",
21
+ "mocha-jenkins-reporter": "0.4.8"
23
22
  },
24
23
  "scripts": {
25
24
  "test": "mocha --reporter spec",
26
25
  "test-jenkins": "JUNIT_REPORT_PATH=./report.xml mocha --colors --reporter mocha-jenkins-reporter --reporter-options junit_report_name='AC-SES'"
27
26
  },
28
27
  "engines": {
29
- "node": ">=10.0.0"
28
+ "node": ">=16.0.0"
30
29
  }
31
30
  }
package/test/test.js CHANGED
@@ -1,126 +1,41 @@
1
- const fs = require('fs')
1
+ const fs = require('fs/promises')
2
2
 
3
- const expect = require('expect')
4
3
  const acses = require('../index')
5
4
 
6
- var Redis = require('ioredis')
7
- var redis = new Redis({
8
- host: process.env.REDIS_HOST || 'localhost',
9
- port: process.env.REDIS_PORT || 6379
10
- })
11
-
5
+ const expect = require('chai').expect
12
6
  const testConfig = require('./testConfig.js')
13
7
 
14
8
  describe('CHECKING ERRORS', function () {
15
- it('Send email without init', function(done) {
9
+ it('Send email without init', async() => {
16
10
  let params = testConfig.email
17
- acses.sendEmail(params, (err) => {
18
- expect(err).toEqual({ message: 'pleaseUseInitBeforeSendingEmail' })
19
- return done()
20
- })
11
+ try {
12
+ await acses.sendEmail(params)
13
+ }
14
+ catch(e) {
15
+ expect(e.message).to.eql('pleaseUseInitBeforeSendingEmail')
16
+ }
21
17
  })
22
18
  })
23
19
 
24
20
  describe('TESTING EMAIL', function () {
25
- it('Init AC SES', function(done) {
26
- acses.init(testConfig.init)
27
- return done()
28
- })
29
-
30
- it('Send a text email', function(done) {
31
- let params = testConfig.email
32
- acses.sendEmail(params, (err, result) => {
33
- if (err) return done(err)
34
- expect(result).toHaveProperty('ResponseMetadata')
35
- expect(result).toHaveProperty('MessageId')
36
- return done()
37
- })
38
- })
39
-
40
- it('Send a HTML email', function(done) {
41
- let params = testConfig.email
42
- fs.readFile(process.cwd() + '/test/htmlTemplate.html', (err, data) => {
43
- if (err) return done(err)
44
- params.subject = 'HTML Test E-Mail'
45
- params.html = data.toString()
46
- acses.sendEmail(params, (err, result) => {
47
- if (err) return done(err)
48
- expect(result).toHaveProperty('ResponseMetadata')
49
- expect(result).toHaveProperty('MessageId')
50
- return done()
51
- })
52
- })
53
- })
54
-
55
- it('Send a security email', function(done) {
56
- let params = testConfig.securityEmail
57
- acses.informSecurity(params, (err, result) => {
58
- if (err) return done(err)
59
- expect(result).toHaveProperty('ResponseMetadata')
60
- expect(result).toHaveProperty('MessageId')
61
- return done()
62
- })
63
- })
64
-
65
- it('Send a support email', function(done) {
66
- let params = testConfig.supportEmail
67
- acses.informSecurity(params, (err, result) => {
68
- if (err) return done(err)
69
- expect(result).toHaveProperty('ResponseMetadata')
70
- expect(result).toHaveProperty('MessageId')
71
- return done()
72
- })
73
- })
74
- })
75
-
76
- describe('TESTING BLOCK TIME', function() {
77
- this.timeout(60000)
78
-
79
- it('Init AC SES with Redis support', function(done) {
80
- testConfig.init.redis = redis
21
+ it('Init AC SES', async() => {
81
22
  acses.init(testConfig.init)
82
- return done()
83
23
  })
84
24
 
85
- it('Send a text email', function(done) {
25
+ it('Send a text email', async() => {
86
26
  let params = testConfig.email
87
- params.html = null
88
- params.subject = 'Test email with blocktime'
89
- params.blockTime = 10
90
- acses.sendEmail(params, (err, result) => {
91
- if (err) return done(err)
92
- expect(result).toHaveProperty('ResponseMetadata')
93
- expect(result).toHaveProperty('MessageId')
94
- return done()
95
- })
27
+ let result = await acses.sendEmail(params)
28
+ expect(result).to.have.property('$metadata')
29
+ expect(result).to.have.property('MessageId')
96
30
  })
97
31
 
98
- it('Send a text email - should fail - it is the SAME email and block time is active', function(done) {
32
+ it('Send a HTML email', async() => {
99
33
  let params = testConfig.email
100
- acses.sendEmail(params, (err, result) => {
101
- if (err) return done(err)
102
- expect(result).toBeUndefined()
103
- return done()
104
- })
105
- })
106
-
107
- it('Wait until blocktime is over', function(done) {
108
- setTimeout(done, 10000)
109
- })
110
-
111
- it('Send a text email - should work again', function(done) {
112
- let params = testConfig.email
113
- params.html = null
114
- params.subject = 'Test after block time'
115
- acses.sendEmail(params, (err, result) => {
116
- if (err) return done(err)
117
- expect(result).toHaveProperty('ResponseMetadata')
118
- expect(result).toHaveProperty('MessageId')
119
- return done()
120
- })
121
- })
122
-
123
- it('Close Redis connection', function(done) {
124
- redis.quit(done)
125
- })
126
- })
34
+ const data = await fs.readFile(process.cwd() + '/test/htmlTemplate.html')
35
+ params.subject = 'HTML Test E-Mail'
36
+ params.html = data.toString()
37
+ const result = await acses.sendEmail(params)
38
+ expect(result).to.have.property('$metadata')
39
+ expect(result).to.have.property('MessageId')
40
+ })
41
+ })