ts-mailkit 3.0.0 → 3.1.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/README.md +6 -2
- package/dist/core/client.d.ts +4 -3
- package/dist/core/client.d.ts.map +1 -1
- package/dist/core/types.d.ts +4 -2
- package/dist/core/types.d.ts.map +1 -1
- package/dist/index.cjs +75 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +75 -33
- package/dist/index.js.map +1 -1
- package/dist/renderers/default/default-renderer.d.ts +5 -22
- package/dist/renderers/default/default-renderer.d.ts.map +1 -1
- package/dist/renderers/renderer.interface.d.ts +25 -0
- package/dist/renderers/renderer.interface.d.ts.map +1 -1
- package/dist/templates/dto/index.d.ts +13 -24
- package/dist/templates/dto/index.d.ts.map +1 -1
- package/dist/templates/factory.d.ts +1 -0
- package/dist/templates/factory.d.ts.map +1 -1
- package/dist/templates/template-builder.d.ts +2 -19
- package/dist/templates/template-builder.d.ts.map +1 -1
- package/dist/transports/cpaas/cpaas-sender.d.ts +8 -0
- package/dist/transports/cpaas/cpaas-sender.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ Works seamlessly in **Node.js**, **Cloudflare Workers** (`workerd`), **Bun**, **
|
|
|
10
10
|
|
|
11
11
|
- **Type-Safe DTOs**: Strongly-typed Data Transfer Objects for transactional emails (verification, password reset, 2FA, magic links, newsletters).
|
|
12
12
|
- **Pluggable Transports (`IEmailSender`)**: Decoupled transport adapter interface with built-in senders:
|
|
13
|
-
- `CpaasHttpSender` (Zoho CPaaS transactional API via native `fetch
|
|
13
|
+
- `CpaasHttpSender` (Zoho CPaaS transactional API via native `fetch`; rejects requests over 500 recipients before dispatch).
|
|
14
14
|
- `MemoryEmailSender` (In-memory mock transport for unit and integration testing).
|
|
15
15
|
- `ConsoleEmailSender` (Formatted terminal logger for local development).
|
|
16
16
|
- **Zero Runtime Dependencies**: Core uses standard web APIs (global `fetch`), ensuring zero heavy dependencies and complete edge compatibility.
|
|
@@ -261,7 +261,9 @@ export class CustomSmtpSender implements IEmailSender {
|
|
|
261
261
|
`MailKit` exposes four canonical send methods. Bulk methods hit the provider's batch endpoints directly (no client-side loops) and deliver an individual copy to each recipient.
|
|
262
262
|
|
|
263
263
|
```ts
|
|
264
|
-
// 1. Bulk manual template:
|
|
264
|
+
// 1. Bulk manual template: the SAME rendered DTO is delivered individually
|
|
265
|
+
// to every recipient (one batch call). For per-recipient content, use
|
|
266
|
+
// sendBulkKnownTemplate below.
|
|
265
267
|
await mailer.sendBulkMail({
|
|
266
268
|
to: ["a@example.com", "b@example.com"],
|
|
267
269
|
template: newsletterDto,
|
|
@@ -288,6 +290,8 @@ await mailer.sendBulkKnownTemplate({
|
|
|
288
290
|
|
|
289
291
|
Set `CpaasHttpConfig.preferTemplateAlias: true` to send `template_alias` instead of `template_key`. Every transport returns a unified `SendResult` whose `rawResponse` field holds the provider's raw response (typed via the exported `CpaasSuccessResponse` / `CpaasErrorResponse` types).
|
|
290
292
|
|
|
293
|
+
> **Recipient limit:** Zoho CPaaS accepts at most **500 recipients per request**, counted across `to`, `cc`, and `bcc`. `CpaasHttpSender` validates this before making any network request and throws a `TransportError` when exceeded.
|
|
294
|
+
|
|
291
295
|
### 8. Building Upload-Ready Templates
|
|
292
296
|
|
|
293
297
|
`buildHTMLTemplate` and `buildPlainTextTemplate` turn the canonical `EmailTemplateDto` into content you can upload to a messaging platform:
|
package/dist/core/client.d.ts
CHANGED
|
@@ -74,11 +74,12 @@ export declare class MailKit {
|
|
|
74
74
|
*/
|
|
75
75
|
sendMail(options: SendTemplateOptions): Promise<SendResult>;
|
|
76
76
|
/**
|
|
77
|
-
* Sends
|
|
77
|
+
* Sends the same rendered template DTO to every recipient in a single batch.
|
|
78
78
|
*
|
|
79
79
|
* The transport delivers an individual copy to each recipient, so
|
|
80
|
-
* recipients are not exposed to one another.
|
|
81
|
-
*
|
|
80
|
+
* recipients are not exposed to one another. The content is identical for
|
|
81
|
+
* everyone; for per-recipient content, use {@link sendBulkKnownTemplate}
|
|
82
|
+
* with a provider-side template and `mergeInfo`.
|
|
82
83
|
*
|
|
83
84
|
* Example:
|
|
84
85
|
* ```ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/core/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AAGxF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAEL,KAAK,4BAA4B,EACjC,KAAK,wBAAwB,EAC7B,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,SAAS,EACd,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,UAAU,EAChB,MAAM,YAAY,CAAC;AAGpB,MAAM,WAAW,mBAAoB,SAAQ,kBAAkB,EAAE,mBAAmB;IAClF;;OAEG;IACH,EAAE,EAAE,SAAS,GAAG,SAAS,EAAE,CAAC;IAC5B;;OAEG;IACH,QAAQ,EAAE,gBAAgB,CAAC;IAC3B;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,SAAS,EAAE,YAAY,CAAC;IACxB;;OAEG;IACH,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B;;OAEG;IACH,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;CACpD;AAED;;GAEG;AACH,qBAAa,OAAO;IAClB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;IACzC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiB;IAC1C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAY;IACzC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAiC;IAEpE,YAAY,OAAO,EAAE,cAAc,EASlC;IAED;;OAEG;IACH,YAAY,IAAI,YAAY,CAE3B;IAED;;OAEG;IACG,MAAM,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,aAAa,CAAC,CAE/D;IAED;;;;;;;;;;OAUG;IACG,QAAQ,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC,CAkChE;IAED
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/core/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AAGxF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAEL,KAAK,4BAA4B,EACjC,KAAK,wBAAwB,EAC7B,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,SAAS,EACd,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,UAAU,EAChB,MAAM,YAAY,CAAC;AAGpB,MAAM,WAAW,mBAAoB,SAAQ,kBAAkB,EAAE,mBAAmB;IAClF;;OAEG;IACH,EAAE,EAAE,SAAS,GAAG,SAAS,EAAE,CAAC;IAC5B;;OAEG;IACH,QAAQ,EAAE,gBAAgB,CAAC;IAC3B;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,SAAS,EAAE,YAAY,CAAC;IACxB;;OAEG;IACH,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B;;OAEG;IACH,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;CACpD;AAED;;GAEG;AACH,qBAAa,OAAO;IAClB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;IACzC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiB;IAC1C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAY;IACzC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAiC;IAEpE,YAAY,OAAO,EAAE,cAAc,EASlC;IAED;;OAEG;IACH,YAAY,IAAI,YAAY,CAE3B;IAED;;OAEG;IACG,MAAM,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,aAAa,CAAC,CAE/D;IAED;;;;;;;;;;OAUG;IACG,QAAQ,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC,CAkChE;IAED;;;;;;;;;;;;;;;OAeG;IACG,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC,CAiCpE;IAED;;OAEG;IACG,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,UAAU,CAAC,CAY9E;IAED;;;OAGG;IACG,qBAAqB,CAAC,OAAO,EAAE,4BAA4B,GAAG,OAAO,CAAC,UAAU,CAAC,CAYtF;YAEa,eAAe;IAc7B,OAAO,CAAC,aAAa;IAWrB;;;OAGG;IACG,OAAO,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC,CAQ3D;CACF;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAE9D"}
|
package/dist/core/types.d.ts
CHANGED
|
@@ -166,11 +166,13 @@ export interface BulkKnownTemplateSendOptions extends MailAddressOptions, Tracki
|
|
|
166
166
|
to: BulkRecipient[];
|
|
167
167
|
}
|
|
168
168
|
/**
|
|
169
|
-
* Client-level options for sending
|
|
169
|
+
* Client-level options for sending the same in-built template DTO to many
|
|
170
|
+
* recipients. For per-recipient content, use `sendBulkKnownTemplate` with a
|
|
171
|
+
* provider-side template and `mergeInfo`.
|
|
170
172
|
*/
|
|
171
173
|
export interface SendBulkMailOptions extends MailAddressOptions, MailMetadataOptions, TrackingOptions {
|
|
172
174
|
/**
|
|
173
|
-
* Templated email DTO
|
|
175
|
+
* Templated email DTO rendered once and sent to every recipient.
|
|
174
176
|
*/
|
|
175
177
|
template: EmailTemplateDto;
|
|
176
178
|
/**
|
package/dist/core/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"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"}
|
package/dist/index.cjs
CHANGED
|
@@ -259,11 +259,12 @@ var MailKit = class {
|
|
|
259
259
|
});
|
|
260
260
|
}
|
|
261
261
|
/**
|
|
262
|
-
* Sends
|
|
262
|
+
* Sends the same rendered template DTO to every recipient in a single batch.
|
|
263
263
|
*
|
|
264
264
|
* The transport delivers an individual copy to each recipient, so
|
|
265
|
-
* recipients are not exposed to one another.
|
|
266
|
-
*
|
|
265
|
+
* recipients are not exposed to one another. The content is identical for
|
|
266
|
+
* everyone; for per-recipient content, use {@link sendBulkKnownTemplate}
|
|
267
|
+
* with a provider-side template and `mergeInfo`.
|
|
267
268
|
*
|
|
268
269
|
* Example:
|
|
269
270
|
* ```ts
|
|
@@ -360,6 +361,11 @@ function createMailKit(options) {
|
|
|
360
361
|
//#endregion
|
|
361
362
|
//#region src/transports/cpaas/cpaas-sender.ts
|
|
362
363
|
/**
|
|
364
|
+
* Zoho CPaaS accepts at most 500 recipients per request, counted across
|
|
365
|
+
* `to`, `cc`, and `bcc`.
|
|
366
|
+
*/
|
|
367
|
+
const CPAAS_MAX_RECIPIENTS = 500;
|
|
368
|
+
/**
|
|
363
369
|
* Zoho CPaaS transactional email HTTP transport adapter.
|
|
364
370
|
*
|
|
365
371
|
* Uses the standard global `fetch` API for zero-dependency, universal edge
|
|
@@ -370,6 +376,9 @@ function createMailKit(options) {
|
|
|
370
376
|
* - `sendBulk` — batch raw email (`POST /v1.1/email/batch`)
|
|
371
377
|
* - `sendKnownTemplate` — single template email (`POST /v1.1/email/template`)
|
|
372
378
|
* - `sendBulkKnownTemplate` — batch template email (`POST /v1.1/email/template/batch`)
|
|
379
|
+
*
|
|
380
|
+
* Requests exceeding Zoho's 500-recipient limit (across `to`, `cc`, and `bcc`)
|
|
381
|
+
* are rejected before any network call is made.
|
|
373
382
|
*/
|
|
374
383
|
var CpaasHttpSender = class {
|
|
375
384
|
name = "cpaas";
|
|
@@ -422,7 +431,16 @@ var CpaasHttpSender = class {
|
|
|
422
431
|
const payload = this.buildBatchTemplatePayload(options);
|
|
423
432
|
return await this.post(`${this.apiBase}/email/template/batch`, payload);
|
|
424
433
|
}
|
|
434
|
+
/**
|
|
435
|
+
* Guards against requests that exceed Zoho CPaaS's per-request recipient
|
|
436
|
+
* limit, counted across `to`, `cc`, and `bcc`.
|
|
437
|
+
*/
|
|
438
|
+
assertRecipientLimit(to, cc, bcc) {
|
|
439
|
+
const total = normalizeRecipients(to).length + normalizeRecipients(cc).length + normalizeRecipients(bcc).length;
|
|
440
|
+
if (total > CPAAS_MAX_RECIPIENTS) throw new TransportError(`CpaasHttpSender: Too many recipients (${total}). Zoho CPaaS accepts at most ${CPAAS_MAX_RECIPIENTS} recipients per request across to, cc, and bcc.`, { transportName: this.name });
|
|
441
|
+
}
|
|
425
442
|
buildSendPayload(options) {
|
|
443
|
+
this.assertRecipientLimit(options.to, options.cc, options.bcc);
|
|
426
444
|
const toRecipients = normalizeRecipients(options.to);
|
|
427
445
|
if (toRecipients.length === 0) throw new TransportError("CpaasHttpSender: At least one recipient (to) must be specified.", { transportName: this.name });
|
|
428
446
|
const resolvedFrom = options.from ? normalizeRecipient(options.from) : this.defaultFrom;
|
|
@@ -443,6 +461,7 @@ var CpaasHttpSender = class {
|
|
|
443
461
|
return payload;
|
|
444
462
|
}
|
|
445
463
|
buildTemplatePayload(options) {
|
|
464
|
+
this.assertRecipientLimit(options.to, options.cc, options.bcc);
|
|
446
465
|
const toRecipients = normalizeRecipients(options.to);
|
|
447
466
|
if (toRecipients.length === 0) throw new TransportError("CpaasHttpSender: At least one recipient (to) must be specified.", { transportName: this.name });
|
|
448
467
|
const resolvedFrom = options.from ? normalizeRecipient(options.from) : this.defaultFrom;
|
|
@@ -462,6 +481,7 @@ var CpaasHttpSender = class {
|
|
|
462
481
|
return payload;
|
|
463
482
|
}
|
|
464
483
|
buildBatchTemplatePayload(options) {
|
|
484
|
+
this.assertRecipientLimit(options.to, options.cc, options.bcc);
|
|
465
485
|
if (!options.to || options.to.length === 0) throw new TransportError("CpaasHttpSender: At least one recipient (to) must be specified.", { transportName: this.name });
|
|
466
486
|
const resolvedFrom = options.from ? normalizeRecipient(options.from) : this.defaultFrom;
|
|
467
487
|
const payload = {
|
|
@@ -770,130 +790,152 @@ var EmailTemplateFactory = class EmailTemplateFactory {
|
|
|
770
790
|
buildFooter(brandName) {
|
|
771
791
|
return this.footerResolver(brandName);
|
|
772
792
|
}
|
|
793
|
+
arrangePlainTextWithExtras(base, extraMessage, footer) {
|
|
794
|
+
const parts = [base];
|
|
795
|
+
if (extraMessage) parts.push(htmlToPlainText(extraMessage));
|
|
796
|
+
if (footer) parts.push(htmlToPlainText(footer));
|
|
797
|
+
return parts.join("\n\n");
|
|
798
|
+
}
|
|
773
799
|
/**
|
|
774
800
|
* Welcome / email-verification email sent after registration.
|
|
775
801
|
*/
|
|
776
802
|
createEmailVerification(params) {
|
|
777
|
-
const { username, verificationUrl, otp, brandName } = params;
|
|
803
|
+
const { username, verificationUrl, otp, brandName, logoUrl, extraMessage, footer } = params;
|
|
778
804
|
const brand = this.resolveBrand(brandName);
|
|
779
805
|
const body = `Hi ${username},<br/>Thank you for signing up. Use the code below or click the button to verify your email address.`;
|
|
806
|
+
const resolvedExtraMessage = extraMessage ?? this.defaultSecurityMessage;
|
|
807
|
+
const resolvedFooter = footer ?? this.buildFooter(brand);
|
|
808
|
+
const plainTextBody = htmlToPlainText(body) + `\n\nYour verification code is: ${otp}\n\nAlternatively, verify here:\n${verificationUrl}`;
|
|
780
809
|
return {
|
|
781
810
|
subject: "Verify Your Email Address",
|
|
782
811
|
header: `Welcome to ${brand}!`,
|
|
783
812
|
body,
|
|
784
|
-
logoUrl: this.defaultLogoUrl,
|
|
813
|
+
logoUrl: logoUrl ?? this.defaultLogoUrl,
|
|
785
814
|
otpCode: otp,
|
|
786
815
|
actionUrl: verificationUrl,
|
|
787
816
|
actionText: "Verify Email",
|
|
788
|
-
extraMessage:
|
|
789
|
-
footer:
|
|
817
|
+
extraMessage: resolvedExtraMessage,
|
|
818
|
+
footer: resolvedFooter,
|
|
790
819
|
userName: username,
|
|
791
820
|
fromName: brand,
|
|
792
|
-
noHtmlMessage:
|
|
821
|
+
noHtmlMessage: this.arrangePlainTextWithExtras(plainTextBody, resolvedExtraMessage, resolvedFooter)
|
|
793
822
|
};
|
|
794
823
|
}
|
|
795
824
|
/**
|
|
796
825
|
* Password-reset email with an optional OTP code and action link.
|
|
797
826
|
*/
|
|
798
827
|
createPasswordReset(params) {
|
|
799
|
-
const { username, resetUrl, otp = "", brandName } = params;
|
|
828
|
+
const { username, resetUrl, otp = "", brandName, logoUrl, extraMessage, footer } = params;
|
|
800
829
|
const brand = this.resolveBrand(brandName);
|
|
801
830
|
const body = `Hi ${username},<br/>We received a request to reset your password. Use the OTP code below or click the button to proceed.`;
|
|
802
831
|
const plainTextOtp = otp ? `\n\nYour OTP code is: ${otp}` : "";
|
|
832
|
+
const resolvedExtraMessage = extraMessage ?? this.defaultSecurityMessage;
|
|
833
|
+
const resolvedFooter = footer ?? this.buildFooter(brand);
|
|
834
|
+
const plainTextBody = htmlToPlainText(body) + plainTextOtp + `\n\nAlternatively, you can use the following link to reset your password:\n${resetUrl}`;
|
|
803
835
|
return {
|
|
804
836
|
subject: "Password Reset Request",
|
|
805
837
|
header: "Reset Your Password",
|
|
806
838
|
body,
|
|
807
|
-
logoUrl: this.defaultLogoUrl,
|
|
839
|
+
logoUrl: logoUrl ?? this.defaultLogoUrl,
|
|
808
840
|
otpCode: otp || void 0,
|
|
809
841
|
actionUrl: resetUrl,
|
|
810
842
|
actionText: "Reset Password",
|
|
811
|
-
extraMessage:
|
|
812
|
-
footer:
|
|
843
|
+
extraMessage: resolvedExtraMessage,
|
|
844
|
+
footer: resolvedFooter,
|
|
813
845
|
userName: username,
|
|
814
846
|
fromName: brand,
|
|
815
|
-
noHtmlMessage:
|
|
847
|
+
noHtmlMessage: this.arrangePlainTextWithExtras(plainTextBody, resolvedExtraMessage, resolvedFooter)
|
|
816
848
|
};
|
|
817
849
|
}
|
|
818
850
|
/**
|
|
819
851
|
* Generic plain message email (no action button, no OTP).
|
|
820
852
|
*/
|
|
821
853
|
createSimpleMessage(params) {
|
|
822
|
-
const { subject, header, body, brandName } = params;
|
|
854
|
+
const { subject, header, body, brandName, logoUrl, extraMessage, footer } = params;
|
|
823
855
|
const brand = this.resolveBrand(brandName);
|
|
856
|
+
const resolvedFooter = footer ?? this.buildFooter(brand);
|
|
824
857
|
return {
|
|
825
858
|
subject,
|
|
826
859
|
header,
|
|
827
860
|
body,
|
|
828
|
-
logoUrl: this.defaultLogoUrl,
|
|
829
|
-
|
|
861
|
+
logoUrl: logoUrl ?? this.defaultLogoUrl,
|
|
862
|
+
extraMessage,
|
|
863
|
+
footer: resolvedFooter,
|
|
830
864
|
fromName: brand,
|
|
831
|
-
noHtmlMessage: htmlToPlainText(body)
|
|
865
|
+
noHtmlMessage: this.arrangePlainTextWithExtras(htmlToPlainText(body), extraMessage, resolvedFooter)
|
|
832
866
|
};
|
|
833
867
|
}
|
|
834
868
|
/**
|
|
835
869
|
* Newsletter / announcement email with an optional hero image and CTA button.
|
|
836
870
|
*/
|
|
837
871
|
createNewsLetter(params) {
|
|
838
|
-
const { subject, header, body, imageUrl, actionUrl, actionText, brandName, logoUrl } = params;
|
|
872
|
+
const { subject, header, body, imageUrl, actionUrl, actionText, brandName, logoUrl, extraMessage, footer } = params;
|
|
839
873
|
const brand = this.resolveBrand(brandName);
|
|
840
|
-
|
|
841
|
-
|
|
874
|
+
const resolvedFooter = footer ?? this.buildFooter(brand);
|
|
875
|
+
let plainTextBody = htmlToPlainText(body);
|
|
876
|
+
if (actionUrl) plainTextBody += `\n\n${actionText || "Learn more"}: ${actionUrl}`;
|
|
842
877
|
return {
|
|
843
878
|
subject,
|
|
844
879
|
header,
|
|
845
880
|
body,
|
|
846
|
-
logoUrl: logoUrl
|
|
881
|
+
logoUrl: logoUrl ?? this.defaultLogoUrl,
|
|
847
882
|
imageUrl,
|
|
848
883
|
actionUrl,
|
|
849
884
|
actionText,
|
|
850
|
-
|
|
885
|
+
extraMessage,
|
|
886
|
+
footer: resolvedFooter,
|
|
851
887
|
fromName: brand,
|
|
852
|
-
noHtmlMessage
|
|
888
|
+
noHtmlMessage: this.arrangePlainTextWithExtras(plainTextBody, extraMessage, resolvedFooter)
|
|
853
889
|
};
|
|
854
890
|
}
|
|
855
891
|
/**
|
|
856
892
|
* Two-factor authentication email with OTP code and optional magic link.
|
|
857
893
|
*/
|
|
858
894
|
create2FAEmail(params) {
|
|
859
|
-
const { username, otp, magicLink = "", brandName } = params;
|
|
895
|
+
const { username, otp, magicLink = "", brandName, logoUrl, extraMessage, footer } = params;
|
|
860
896
|
const brand = this.resolveBrand(brandName);
|
|
861
897
|
const body = `Hi ${username},<br/>Use the code below or click the button to complete your login.`;
|
|
862
898
|
const plainLink = magicLink ? `\n\nAlternatively, verify here:\n${magicLink}` : "";
|
|
899
|
+
const resolvedExtraMessage = extraMessage ?? this.defaultSecurityMessage;
|
|
900
|
+
const resolvedFooter = footer ?? this.buildFooter(brand);
|
|
901
|
+
const plainTextBody = htmlToPlainText(body) + `\n\nYour verification code is: ${otp}` + plainLink;
|
|
863
902
|
return {
|
|
864
903
|
subject: "Your Login Verification Code",
|
|
865
904
|
header: "Two-Factor Authentication",
|
|
866
905
|
body,
|
|
867
|
-
logoUrl: this.defaultLogoUrl,
|
|
906
|
+
logoUrl: logoUrl ?? this.defaultLogoUrl,
|
|
868
907
|
otpCode: otp,
|
|
869
908
|
actionUrl: magicLink || void 0,
|
|
870
909
|
actionText: magicLink ? "Verify Login" : void 0,
|
|
871
|
-
extraMessage:
|
|
872
|
-
footer:
|
|
910
|
+
extraMessage: resolvedExtraMessage,
|
|
911
|
+
footer: resolvedFooter,
|
|
873
912
|
userName: username,
|
|
874
913
|
fromName: brand,
|
|
875
|
-
noHtmlMessage:
|
|
914
|
+
noHtmlMessage: this.arrangePlainTextWithExtras(plainTextBody, resolvedExtraMessage, resolvedFooter)
|
|
876
915
|
};
|
|
877
916
|
}
|
|
878
917
|
/**
|
|
879
918
|
* Magic link sign-in email (no OTP, button only).
|
|
880
919
|
*/
|
|
881
920
|
createMagicLinkEmail(params) {
|
|
882
|
-
const { username, magicLink, brandName } = params;
|
|
921
|
+
const { username, magicLink, brandName, logoUrl, extraMessage, footer } = params;
|
|
883
922
|
const brand = this.resolveBrand(brandName);
|
|
884
923
|
const body = `Hi ${username},<br/>Click the button below to sign in. No password needed.`;
|
|
924
|
+
const resolvedExtraMessage = extraMessage ?? this.defaultSecurityMessage;
|
|
925
|
+
const resolvedFooter = footer ?? this.buildFooter(brand);
|
|
926
|
+
const plainTextBody = htmlToPlainText(body) + `\n\nSign in here:\n${magicLink}`;
|
|
885
927
|
return {
|
|
886
928
|
subject: "Your Magic Link",
|
|
887
929
|
header: `Sign In to ${brand}`,
|
|
888
930
|
body,
|
|
889
|
-
logoUrl: this.defaultLogoUrl,
|
|
931
|
+
logoUrl: logoUrl ?? this.defaultLogoUrl,
|
|
890
932
|
actionUrl: magicLink,
|
|
891
933
|
actionText: "Sign In",
|
|
892
|
-
extraMessage:
|
|
893
|
-
footer:
|
|
934
|
+
extraMessage: resolvedExtraMessage,
|
|
935
|
+
footer: resolvedFooter,
|
|
894
936
|
userName: username,
|
|
895
937
|
fromName: brand,
|
|
896
|
-
noHtmlMessage:
|
|
938
|
+
noHtmlMessage: this.arrangePlainTextWithExtras(plainTextBody, resolvedExtraMessage, resolvedFooter)
|
|
897
939
|
};
|
|
898
940
|
}
|
|
899
941
|
static _defaultInstance;
|