@nka212bg/backend-utils 0.1.46 → 0.1.48

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.
@@ -10,25 +10,53 @@ const emailListFilePath = `${__basedir}/state/useremailList.json`;
10
10
 
11
11
  let EMAILS_LIST = existsSync(emailListFilePath) ? JSON.parse(readFileSync(emailListFilePath, "utf8") || "{}") : {};
12
12
 
13
- const mailTransport = nodemailer.createTransport({
14
- pool: true,
15
- maxMessages: Infinity,
16
- maxConnections: 20,
17
-
18
- host: process.env.SMTP_HOST,
19
- port: parseInt(process.env.SMTP_PORT),
20
- secure: true, // true for 465, false for other ports
21
- auth: {
22
- user: process.env.SMTP_USER,
23
- pass: process.env.SMTP_PASS,
24
- },
25
- });
13
+ // set via require(".../mailSmsTools")({ ... }), empty values fall back to process.env
14
+ const config = {
15
+ name: "", // "From" display name
16
+ logoUrl: "",
17
+ baseUrl: "",
18
+ smtp: {}, // nodemailer transport options, override the env defaults
19
+ twilio: {}, // { accountSid, authToken, sender }
20
+ };
21
+ let mailTransport;
22
+ let twilio;
26
23
 
24
+ // callable with options, named exports still work:
25
+ // const { sendEmail } = require(".../mailSmsTools")({ name, logoUrl, baseUrl, smtp, twilio });
26
+ // const { sendEmail } = require(".../mailSmsTools");
27
+ module.exports = Object.assign((options = {}) => {
28
+ Object.assign(config, options);
29
+ mailTransport = twilio = null; // recreate with the new options on next send
30
+ return module.exports;
31
+ }, exports);
32
+
33
+ // created on first send, so the config is already applied
34
+ const nodemailerTransport = () =>
35
+ (mailTransport ??= nodemailer.createTransport({
36
+ pool: true,
37
+ maxMessages: Infinity,
38
+ maxConnections: 20,
39
+
40
+ host: process.env.SMTP_HOST,
41
+ port: parseInt(process.env.SMTP_PORT),
42
+ secure: true, // true for 465, false for other ports
43
+ auth: {
44
+ user: process.env.SMTP_USER,
45
+ pass: process.env.SMTP_PASS,
46
+ },
47
+ ...config.smtp,
48
+ }));
49
+
50
+ /* -------------------- EMAIL -------------------- */
27
51
  exports.sendEmail = async ({ email, content, subject, attachments, unsubscribe, userIp, logoUrl } = {}) => {
28
52
  if (!content) return { error: "missing_content" };
29
- if (!subject || subject === "") subject = email_content.substring(0, 25) + "... ";
53
+ if (!subject || subject === "") subject = content.substring(0, 25) + "... ";
30
54
 
31
- const emailArray = strToEmailsArray(email || process.env.SMTP_USER);
55
+ const baseUrl = config.baseUrl || process.env.BASE_URL;
56
+ const smtpUser = config.smtp.auth?.user || process.env.SMTP_USER;
57
+ logoUrl ||= config.logoUrl || `${baseUrl}/logo_black.png`;
58
+
59
+ const emailArray = strToEmailsArray(email || smtpUser);
32
60
  if (!emailArray.length) {
33
61
  return { error: "missing_email" };
34
62
  //
@@ -63,13 +91,13 @@ exports.sendEmail = async ({ email, content, subject, attachments, unsubscribe,
63
91
  <tbody>
64
92
  <tr>
65
93
  <td style="padding-bottom: 6px">
66
- <img src="${logoUrl || `${process.env.BASE_URL}/logo_black.png`}" style="height: 36px; background-size: contain; background-repeat: no-repeat" />
94
+ <img src="${logoUrl}" style="height: 36px; background-size: contain; background-repeat: no-repeat" />
67
95
  </td>
68
96
  </tr>
69
97
  <tr><td style="padding-bottom: 20px">${content}</td></tr>
70
98
  <tr>
71
99
  <td>
72
- <a href="${process.env.BASE_URL}" target="_blank" style="text-decoration: none; color: gray; font-size: 12px">${new Date().getFullYear()} ${process.env.BASE_URL}</a>
100
+ <a href="${baseUrl}" target="_blank" style="text-decoration: none; color: gray; font-size: 12px">${new Date().getFullYear()} ${baseUrl}</a>
73
101
  </td>
74
102
  </tr>
75
103
  </tbody>
@@ -77,7 +105,7 @@ exports.sendEmail = async ({ email, content, subject, attachments, unsubscribe,
77
105
  </div>`;
78
106
 
79
107
  const mailOptions = {
80
- from: process.env.SMTP_USER,
108
+ from: config.name ? { name: config.name, address: smtpUser } : smtpUser,
81
109
  // html: handlebars({ template: defaultTemplate, content, subject, logoUrl: `${process.env.BASE_URL}/logo_black.png` }),
82
110
  html,
83
111
  subject,
@@ -85,7 +113,7 @@ exports.sendEmail = async ({ email, content, subject, attachments, unsubscribe,
85
113
  attachments,
86
114
  };
87
115
 
88
- mailTransport.sendMail(mailOptions, (error, info) => {
116
+ nodemailerTransport().sendMail(mailOptions, (error, info) => {
89
117
  error ? errorEmails.push(error) : successEmails.push(info);
90
118
 
91
119
  if (i + 1 >= emailArray.length) resolve({ error: errorEmails.length ? errorEmails : null, emailList: emailListEmails.length ? emailListEmails : null, data: successEmails });
@@ -95,11 +123,10 @@ exports.sendEmail = async ({ email, content, subject, attachments, unsubscribe,
95
123
  };
96
124
 
97
125
  /* -------------------- SMS -------------------- */
98
- let twilio;
99
- exports.sendSMS = async ({ phones, content, sender = process.env.TWILIO_SENDER } = {}) => {
126
+ exports.sendSMS = async ({ phones, content, sender = config.twilio.sender || process.env.TWILIO_SENDER } = {}) => {
100
127
  if (!phones) return { error: "missing_phones" };
101
128
  if (!content) return { error: "missing_content" };
102
- if (!twilio) twilio = require("twilio")(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);
129
+ if (!twilio) twilio = require("twilio")(config.twilio.accountSid || process.env.TWILIO_ACCOUNT_SID, config.twilio.authToken || process.env.TWILIO_AUTH_TOKEN);
103
130
 
104
131
  return new Promise((resolve, reject) => {
105
132
  const errorPhones = [];
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@nka212bg/backend-utils",
3
3
  "author": "nka212bg",
4
- "version": "0.1.46",
4
+ "version": "0.1.48",
5
5
  "main": "index.js",
6
6
  "dependencies": {
7
7
  "@maxmind/geoip2-node": "^5.0.0",
package/session.js CHANGED
@@ -88,7 +88,7 @@ exports.serverState = new Proxy(
88
88
  },
89
89
 
90
90
  // SET / UPDATE / DELETE
91
- // serverState["abc123"] = {name: 'alice'}; // create (stamps expirePeriod/expireTime/uuid)
91
+ // serverState["abc123"] = {name: 'alice'}; // create (stamps expirePeriod/expireTime/uid)
92
92
  // serverState["abc123"] = {name: 'alice2'}; // update (merges into existing)
93
93
  // serverState["abc123"] = null; // delete, cookie-expiry trick
94
94
  // serverState["name=alice"] = {name: 'john'}; // bulk update, merges into every entry where name == "alice"
@@ -123,7 +123,7 @@ exports.serverState = new Proxy(
123
123
 
124
124
  fields.expirePeriod ||= 60000 * 60 * 24 * 7; // 7 days
125
125
  fields.expireTime = now + fields.expirePeriod;
126
- fields.uuid = createToken({ type: "date" });
126
+ fields.uid = createToken({ type: "date" });
127
127
 
128
128
  STATE[token] = fields;
129
129
  return { ...fields };
@@ -154,7 +154,7 @@ exports.session = {
154
154
 
155
155
  if (!payload.expirePeriod) payload.expirePeriod = 60000 * 60 * 24 * 7; // 7days
156
156
  payload.expireTime = now + payload.expirePeriod;
157
- payload.uuid = createToken({ type: "date" });
157
+ payload.uid = createToken({ type: "date" });
158
158
 
159
159
  SESSION[token] = payload;
160
160
  return { ...payload, expireIn: payload.expirePeriod + 60000 };