@arkstack/notifications 0.17.4 → 0.17.5
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/dist/index.d.ts +47 -13
- package/dist/index.js +65 -15
- package/package.json +4 -4
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { DotPath, DotPathValue, MergedConfig } from "@arkstack/common";
|
|
2
2
|
import { Transporter } from "nodemailer";
|
|
3
3
|
import { Model } from "@arkstack/database";
|
|
4
|
+
import { Logger } from "nodemailer/lib/shared/index.js";
|
|
4
5
|
import { User } from "@app/models/User";
|
|
5
6
|
import { User as User$1 } from "@arkstack/auth";
|
|
6
7
|
import { PhoneNumber } from "@kanun-hq/plugin-phone";
|
|
@@ -33,15 +34,26 @@ type SmsDriverName = 'africastalking' | 'twilio';
|
|
|
33
34
|
type RealtimeDriverName = 'pusher' | 'firebase';
|
|
34
35
|
type NotificationChannel = 'mail' | 'sms' | 'db' | 'realtime';
|
|
35
36
|
type MailDriverOptions = {
|
|
36
|
-
transport?: '
|
|
37
|
+
transport?: 'file' | 'smtp' | 'sendmail' | 'ses';
|
|
38
|
+
url?: string;
|
|
37
39
|
host?: string;
|
|
38
40
|
port?: number;
|
|
39
|
-
secure?: boolean;
|
|
40
41
|
user?: string;
|
|
41
42
|
pass?: string;
|
|
42
43
|
from?: string;
|
|
43
|
-
|
|
44
|
+
debug?: boolean;
|
|
45
|
+
logger?: boolean | Logger;
|
|
46
|
+
secure?: boolean;
|
|
47
|
+
service?: string;
|
|
48
|
+
sesRegion?: string;
|
|
44
49
|
directory?: string;
|
|
50
|
+
ignoreTLS?: boolean;
|
|
51
|
+
requireTLS?: boolean;
|
|
52
|
+
authMethod?: 'PLAIN' | 'LOGIN' | 'CRAM-MD5';
|
|
53
|
+
testAddress?: string;
|
|
54
|
+
sendmailArgs?: string[];
|
|
55
|
+
sendmailPath?: string;
|
|
56
|
+
transactionLog?: boolean;
|
|
45
57
|
};
|
|
46
58
|
type SmsDriverOptions = {
|
|
47
59
|
transport?: SmsDriverName;
|
|
@@ -118,7 +130,7 @@ interface NotificationConfig {
|
|
|
118
130
|
default_driver: 'mail' | 'sms' | 'db';
|
|
119
131
|
drivers: {
|
|
120
132
|
mail: {
|
|
121
|
-
transport: 'smtp' | 'file';
|
|
133
|
+
transport: 'smtp' | 'file' | 'sendmail' | 'ses';
|
|
122
134
|
from: string | {
|
|
123
135
|
name: string;
|
|
124
136
|
address: string;
|
|
@@ -140,28 +152,42 @@ interface NotificationConfig {
|
|
|
140
152
|
};
|
|
141
153
|
};
|
|
142
154
|
transports: {
|
|
143
|
-
smtp: {
|
|
155
|
+
smtp: ({
|
|
144
156
|
host: string;
|
|
145
157
|
port: number;
|
|
146
158
|
secure: boolean;
|
|
159
|
+
debug?: boolean;
|
|
160
|
+
logger?: boolean | Logger;
|
|
161
|
+
service?: string;
|
|
162
|
+
ignore_tls?: boolean;
|
|
163
|
+
require_tls?: boolean;
|
|
164
|
+
auth_method?: 'PLAIN' | 'LOGIN' | 'CRAM-MD5';
|
|
165
|
+
test_address?: string;
|
|
166
|
+
transaction_log?: boolean;
|
|
167
|
+
} & ({
|
|
147
168
|
auth: {
|
|
148
169
|
user: string;
|
|
149
170
|
pass: string;
|
|
150
171
|
};
|
|
151
172
|
user?: string;
|
|
152
173
|
pass?: string;
|
|
153
|
-
test_address?: string;
|
|
154
174
|
} | {
|
|
155
|
-
host: string;
|
|
156
|
-
port: number;
|
|
157
|
-
secure: boolean;
|
|
158
175
|
auth?: {
|
|
159
176
|
user: string;
|
|
160
177
|
pass: string;
|
|
161
178
|
};
|
|
162
179
|
user: string;
|
|
163
180
|
pass: string;
|
|
164
|
-
|
|
181
|
+
})) | {
|
|
182
|
+
url: string;
|
|
183
|
+
};
|
|
184
|
+
ses?: {
|
|
185
|
+
region: string;
|
|
186
|
+
[key: string]: any;
|
|
187
|
+
};
|
|
188
|
+
sendmail?: {
|
|
189
|
+
path?: string;
|
|
190
|
+
args?: string[];
|
|
165
191
|
};
|
|
166
192
|
file: {
|
|
167
193
|
directory: string;
|
|
@@ -196,7 +222,7 @@ interface NotificationConfig {
|
|
|
196
222
|
};
|
|
197
223
|
};
|
|
198
224
|
}
|
|
199
|
-
type MergedTransportConfig = MergedConfig<NotificationConfig['transports'][NonNullable<MailDriverOptions['transport']>]>;
|
|
225
|
+
type MergedTransportConfig = MergedConfig<Required<NotificationConfig['transports']>[NonNullable<MailDriverOptions['transport']>]>;
|
|
200
226
|
//#endregion
|
|
201
227
|
//#region src/Contracts/NotificationContract.d.ts
|
|
202
228
|
declare abstract class NotificationContract<TResult = DriverResult> {
|
|
@@ -244,14 +270,22 @@ declare class DbNotification extends NotificationContract<UserNotification> {
|
|
|
244
270
|
//#region src/drivers/MailNotification.d.ts
|
|
245
271
|
declare class MailNotification extends NotificationContract {
|
|
246
272
|
driver: Transporter;
|
|
273
|
+
private options;
|
|
274
|
+
private ViewName;
|
|
275
|
+
private transport;
|
|
276
|
+
private sesOptions?;
|
|
277
|
+
private recipients?;
|
|
247
278
|
private fromAddress?;
|
|
248
279
|
private subjectLine?;
|
|
249
|
-
private
|
|
250
|
-
private ViewName;
|
|
280
|
+
private driverConfig;
|
|
251
281
|
private htmlTemplate?;
|
|
252
282
|
private textTemplate?;
|
|
253
283
|
private fileDirectory?;
|
|
254
284
|
constructor(options?: MailDriverOptions);
|
|
285
|
+
/**
|
|
286
|
+
* Prepare the mail driver so we can use it to relay the message
|
|
287
|
+
*/
|
|
288
|
+
private prepareDriver;
|
|
255
289
|
from(from: string): this;
|
|
256
290
|
/**
|
|
257
291
|
* The email subject
|
package/dist/index.js
CHANGED
|
@@ -201,41 +201,89 @@ const configure = (key, defaultValue) => {
|
|
|
201
201
|
//#region src/drivers/MailNotification.ts
|
|
202
202
|
var MailNotification = class extends NotificationContract {
|
|
203
203
|
driver;
|
|
204
|
+
options = {};
|
|
205
|
+
ViewName = "~arkstack/notifications.mail";
|
|
206
|
+
transport = "smtp";
|
|
207
|
+
sesOptions;
|
|
208
|
+
recipients;
|
|
204
209
|
fromAddress;
|
|
205
210
|
subjectLine;
|
|
206
|
-
|
|
207
|
-
ViewName = "~arkstack/notifications.mail";
|
|
211
|
+
driverConfig;
|
|
208
212
|
htmlTemplate;
|
|
209
213
|
textTemplate;
|
|
210
214
|
fileDirectory;
|
|
211
215
|
constructor(options = {}) {
|
|
212
216
|
super();
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
+
this.driverConfig = configure("drivers.mail", {});
|
|
218
|
+
this.transport = this.driverConfig.transport ?? "smtp";
|
|
219
|
+
this.options = options;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Prepare the mail driver so we can use it to relay the message
|
|
223
|
+
*/
|
|
224
|
+
async prepareDriver() {
|
|
225
|
+
const options = this.options;
|
|
226
|
+
const transport = configure(`transports.${this.transport}`, {});
|
|
227
|
+
/**
|
|
228
|
+
* Setup nodemailer to stream messages so we can store the mail to file
|
|
229
|
+
*/
|
|
230
|
+
if (this.transport === "file") {
|
|
217
231
|
this.fileDirectory = options.directory ?? transport.directory ?? env("MAIL_FILE_PATH", join(Arkstack.rootDir(), "./storage/framework/mails"));
|
|
218
|
-
this.fromAddress = options.from ??
|
|
232
|
+
this.fromAddress = options.from ?? this.driverConfig.from ?? transport.from ?? env("MAIL_FROM_ADDRESS", "no-reply@example.com");
|
|
219
233
|
this.driver = nodemailer.createTransport({
|
|
220
234
|
streamTransport: true,
|
|
221
235
|
buffer: true
|
|
222
236
|
});
|
|
223
237
|
return;
|
|
224
238
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
239
|
+
/**
|
|
240
|
+
* Setup nodemailer to use sendmail
|
|
241
|
+
*/
|
|
242
|
+
if (this.transport === "sendmail") {
|
|
243
|
+
const path = transport.path ?? options.sendmailPath ?? env("MAIL_SENDMAIL_PATH", "/usr/sbin/sendmail");
|
|
244
|
+
this.driver = nodemailer.createTransport({
|
|
245
|
+
path,
|
|
246
|
+
sendmail: true,
|
|
247
|
+
args: transport.args ?? options.sendmailArgs
|
|
248
|
+
});
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Setup nodemailer to use Amazon SES
|
|
253
|
+
*/
|
|
254
|
+
if (this.transport === "ses") {
|
|
255
|
+
try {
|
|
256
|
+
const { SESv2Client, SendEmailCommand } = await import("@aws-sdk/client-sesv2");
|
|
257
|
+
const { region, ...sesOptions } = transport;
|
|
258
|
+
const sesClient = new SESv2Client({ region: options.sesRegion ?? region ?? env("MAIL_SES_REGION") ?? env("AWS_DEFAULT_REGION") });
|
|
259
|
+
this.sesOptions = sesOptions;
|
|
260
|
+
this.driver = nodemailer.createTransport({ SES: {
|
|
261
|
+
sesClient,
|
|
262
|
+
SendEmailCommand
|
|
263
|
+
} });
|
|
264
|
+
} catch (error) {
|
|
265
|
+
throw new Error("Please install \"@aws-sdk/client-sesv2\" to use the ses transport", { cause: error });
|
|
266
|
+
}
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
228
269
|
const user = options.user ?? transport.auth?.user ?? transport.user ?? env("MAIL_USERNAME", "");
|
|
229
270
|
const pass = options.pass ?? transport.auth?.pass ?? transport.pass ?? env("MAIL_PASSWORD", "");
|
|
230
|
-
this.fromAddress = options.from ??
|
|
271
|
+
this.fromAddress = options.from ?? this.driverConfig.from ?? transport.from ?? env("MAIL_FROM_ADDRESS", "no-reply@example.com");
|
|
231
272
|
this.driver = nodemailer.createTransport({
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
273
|
+
url: transport.url ?? options.url ?? env("MAIL_URL"),
|
|
274
|
+
host: options.host ?? transport.host ?? env("MAIL_HOST", "localhost"),
|
|
275
|
+
port: Number(options.port ?? transport.port ?? env("MAIL_PORT", 1025)),
|
|
235
276
|
auth: user || pass ? {
|
|
236
277
|
user,
|
|
237
278
|
pass
|
|
238
|
-
} : void 0
|
|
279
|
+
} : void 0,
|
|
280
|
+
debug: transport.debug ?? options.debug ?? env("MAIL_DEBUG", false),
|
|
281
|
+
secure: Boolean(options.secure ?? transport.secure ?? env("MAIL_SECURE", false)),
|
|
282
|
+
logger: transport.logger ?? options.logger ?? env("MAIL_LOGGER", false),
|
|
283
|
+
service: transport.service ?? options.service ?? env("MAIL_SERVICE"),
|
|
284
|
+
ignoreTLS: transport.ignore_tls ?? options.ignoreTLS ?? env("MAIL_IGNORE_TLS"),
|
|
285
|
+
requireTLS: transport.require_tls ?? options.requireTLS ?? env("MAIL_REQUIRE_TLS"),
|
|
286
|
+
authMethod: transport.auth_method ?? options.authMethod ?? env("MAIL_AUTH_METHOD")
|
|
239
287
|
});
|
|
240
288
|
}
|
|
241
289
|
from(from) {
|
|
@@ -321,6 +369,7 @@ var MailNotification = class extends NotificationContract {
|
|
|
321
369
|
const resolvedMessage = interpolate(message, mergedData);
|
|
322
370
|
const to = this.resolveRecipients(recipient);
|
|
323
371
|
if (to.length < 1) throw new Error("No recipient provided for mail notification");
|
|
372
|
+
await this.prepareDriver();
|
|
324
373
|
const templateData = {
|
|
325
374
|
...mergedData,
|
|
326
375
|
message: resolvedMessage,
|
|
@@ -337,6 +386,7 @@ var MailNotification = class extends NotificationContract {
|
|
|
337
386
|
}),
|
|
338
387
|
html: this.htmlTemplate ? interpolate(this.htmlTemplate, templateData) : await globalThis.view(this.ViewName, templateData)
|
|
339
388
|
};
|
|
389
|
+
if (this.transport === "ses") payload.ses = this.sesOptions;
|
|
340
390
|
const result = await this.driver.sendMail(payload);
|
|
341
391
|
if (this.fileDirectory) await this.storeFileMail(payload, result);
|
|
342
392
|
return result;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arkstack/notifications",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Framework-agnostic notification module for Arkstack and Nodejs, providing support for multi-channel notification delivery.",
|
|
6
6
|
"homepage": "https://arkstack.toneflix.net/guide/notifications",
|
|
@@ -34,14 +34,14 @@
|
|
|
34
34
|
"africastalking": "^0.8.0",
|
|
35
35
|
"nodemailer": "^8.0.7",
|
|
36
36
|
"twilio": "^6.0.0",
|
|
37
|
-
"@arkstack/common": "^0.17.
|
|
37
|
+
"@arkstack/common": "^0.17.5"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
40
|
"@kanun-hq/plugin-phone": "^0.1.8",
|
|
41
41
|
"firebase-admin": "^13.0.0",
|
|
42
42
|
"pusher": "^5.2.0",
|
|
43
|
-
"@arkstack/contract": "^0.17.
|
|
44
|
-
"@arkstack/database": "^0.17.
|
|
43
|
+
"@arkstack/contract": "^0.17.5",
|
|
44
|
+
"@arkstack/database": "^0.17.5"
|
|
45
45
|
},
|
|
46
46
|
"peerDependenciesMeta": {
|
|
47
47
|
"pusher": {
|