@visulima/email 1.0.0-alpha.34 → 1.0.0-alpha.36
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/CHANGELOG.md +53 -0
- package/LICENSE.md +57 -0
- package/README.md +96 -0
- package/dist/crypto/index.d.ts +160 -3
- package/dist/crypto/index.js +1 -1
- package/dist/deliverability/dmarc-report.d.ts +95 -0
- package/dist/deliverability/dmarc-report.js +1 -0
- package/dist/deliverability/index.d.ts +360 -0
- package/dist/deliverability/index.js +1 -0
- package/dist/events/index.d.ts +31 -0
- package/dist/events/index.js +1 -0
- package/dist/inbound/index.d.ts +375 -0
- package/dist/inbound/index.js +1 -0
- package/dist/index.d.ts +12 -734
- package/dist/index.js +1 -1
- package/dist/middleware/index.d.ts +346 -0
- package/dist/middleware/index.js +1 -0
- package/dist/packem_shared/ALL_EVENTS-3kwh5CBE.js +1 -0
- package/dist/packem_shared/DkimSigner-BuSbnos1.js +18 -0
- package/dist/packem_shared/DraftMailMessage-C9tevR8K.js +1 -0
- package/dist/packem_shared/EmailError-B-sEf3bp.js +1 -0
- package/dist/packem_shared/Mail-DpjH0Exh.js +1 -0
- package/dist/packem_shared/MailMessage-L-Q9yc5v.js +1 -0
- package/dist/packem_shared/MemoryEventStore-CuhfO9aj.js +1 -0
- package/dist/packem_shared/MemoryQueue-Dl1Fa6OJ.js +1 -0
- package/dist/packem_shared/MemorySuppressionStore-DZnbz-_B.js +1 -0
- package/dist/packem_shared/RATE_LIMIT_PRESETS-BPADLgcA.js +1 -0
- package/dist/packem_shared/RequiredOptionError-DuNNY_a5.js +1 -0
- package/dist/packem_shared/SmimeEncrypter-C7usORKF.js +6 -0
- package/dist/packem_shared/SmimeSigner-DgAApLPS.js +8 -0
- package/dist/packem_shared/addDarkModeSupport-DZYxULjl.js +1 -0
- package/dist/packem_shared/address-formatter-BWR2Dddx.js +1 -0
- package/dist/packem_shared/aggregate-features-BqEjPd42.js +1 -0
- package/dist/packem_shared/ahaSendProvider-Dq5mElHZ.js +1 -0
- package/dist/packem_shared/arcMessageSignatureBase-BY4j0TxM.js +17 -0
- package/dist/packem_shared/attachment-processor-BjTNoMyb.js +1 -0
- package/dist/packem_shared/awsSesProvider-BGZJUIep.js +32 -0
- package/dist/packem_shared/azureProvider-DlM6UWUv.js +1 -0
- package/dist/packem_shared/brevoProvider-D_Hhc0Z-.js +1 -0
- package/dist/packem_shared/build-mime-message-Be6TOi1T.js +3 -0
- package/dist/packem_shared/buildListUnsubscribe-Cdr8MvR_.js +1 -0
- package/dist/packem_shared/buildMtaStsPolicy-oEQg8y_C.js +6 -0
- package/dist/packem_shared/circuitBreakerMiddleware-D2SA_07f.js +1 -0
- package/dist/packem_shared/cloudflareEmailProvider-D4adkOjA.js +1 -0
- package/dist/packem_shared/composeMiddleware-BHwLLEzK.js +1 -0
- package/dist/packem_shared/create-logger-BQTS3f-I.js +1 -0
- package/dist/packem_shared/createSuppressionStore-CeAZKCbY.js +1 -0
- package/dist/packem_shared/createTestEmail-BM3iNznm.js +1 -0
- package/dist/packem_shared/createWorker-_-yMWcNQ.js +1 -0
- package/dist/packem_shared/dedupeMiddleware-B6ajWOTi.js +1 -0
- package/dist/packem_shared/defineInboundHandler-CnL2BzlL.js +1 -0
- package/dist/packem_shared/defineProvider-C9q-7iwt.js +1 -0
- package/dist/packem_shared/detectMimeType-Dxv4MjZ7.js +1 -0
- package/dist/packem_shared/emailMatchers-DZDkrZ_3.js +1 -0
- package/dist/packem_shared/event-bus.d-DEl3w_EW.d.ts +104 -0
- package/dist/packem_shared/extractCidReferences-BuoTREMp.js +1 -0
- package/dist/packem_shared/extractReply-BUjIBt9A.js +5 -0
- package/dist/packem_shared/failoverProvider-BgX6zfnY.js +1 -0
- package/dist/packem_shared/format-address-DTl-9O70.js +1 -0
- package/dist/packem_shared/generate-boundary-DQbzDiOI.js +1 -0
- package/dist/packem_shared/generate-message-id-gXAuMz4g.js +1 -0
- package/dist/packem_shared/headers-to-record-De1Eg951.js +1 -0
- package/dist/packem_shared/httpProvider-DJAsYSun.js +1 -0
- package/dist/packem_shared/index-yDU-1zOZ.js +11 -0
- package/dist/packem_shared/infobipProvider-oOL-ThpP.js +1 -0
- package/dist/packem_shared/injectPreheader-CF9WHZ7J.js +1 -0
- package/dist/packem_shared/inlineCss-BQ7d2Cyz.js +1 -0
- package/dist/packem_shared/isValidSigningCertUrl-Bii1AMGC.js +3 -0
- package/dist/packem_shared/loggingMiddleware-CZIiVMVp.js +1 -0
- package/dist/packem_shared/loopsProvider-BXr0KSjB.js +1 -0
- package/dist/packem_shared/mail.d-B9SSqyy0.d.ts +909 -0
- package/dist/packem_shared/{mailCrabProvider-B7H6HwWu.js → mailCrabProvider-C7Ao5H9p.js} +1 -1
- package/dist/packem_shared/mailPaceProvider-DklGeGEM.js +1 -0
- package/dist/packem_shared/mailchannelsProvider-DPfQVzUd.js +1 -0
- package/dist/packem_shared/mailerSendProvider-B8iT5Uhb.js +1 -0
- package/dist/packem_shared/mailgunProvider-Ctyrs9d0.js +1 -0
- package/dist/packem_shared/mailjetProvider-v55nFDsr.js +1 -0
- package/dist/packem_shared/mailomatProvider-BCyB4Q4B.js +1 -0
- package/dist/packem_shared/mailtrapProvider-DcVw3sxR.js +1 -0
- package/dist/packem_shared/make-request-BlK_B72c.js +1 -0
- package/dist/packem_shared/mandrillProvider-gqMFMwgs.js +1 -0
- package/dist/packem_shared/mockProvider-Behywbl1.js +1 -0
- package/dist/packem_shared/nodemailerProvider-BFHobXxt.js +1 -0
- package/dist/packem_shared/normalizeMessageId-DAx2pGe2.js +1 -0
- package/dist/packem_shared/oauth2Middleware-CodqXkyj.js +1 -0
- package/dist/packem_shared/opentelemetryProvider-ByHC01ub.js +1 -0
- package/dist/packem_shared/parseAddress-DdbViBAJ.js +1 -0
- package/dist/packem_shared/parseArfReport-Ds6S3c4J.js +6 -0
- package/dist/packem_shared/parseCloudflareInbound-C__j-oNa.js +1 -0
- package/dist/packem_shared/parseDmarcRecord-DXZ-_rF0.js +1 -0
- package/dist/packem_shared/parseMailgunInbound-BpC6uPNe.js +1 -0
- package/dist/packem_shared/parsePostmarkInbound-Co3_c6-9.js +1 -0
- package/dist/packem_shared/parseSendGridInbound-DsALoijO.js +4 -0
- package/dist/packem_shared/parseSesInbound-CH5tHIjp.js +1 -0
- package/dist/packem_shared/parseTlsReport-wPe1lIDs.js +1 -0
- package/dist/packem_shared/plunkProvider-C0LO-1E3.js +1 -0
- package/dist/packem_shared/postProcessHtml-DqKi2Ucg.js +1 -0
- package/dist/packem_shared/postalProvider-B26IqgxE.js +1 -0
- package/dist/packem_shared/postmarkProvider-DWQJv5_M.js +1 -0
- package/dist/packem_shared/provider-base-gIoUu9so.js +1 -0
- package/dist/packem_shared/{provider.d-DcfYeGJJ.d.ts → provider.d-J-y6iogK.d.ts} +1 -1
- package/dist/packem_shared/quoted-printable-nSGDA1tA.js +7 -0
- package/dist/packem_shared/resendProvider-DhvKVyCD.js +1 -0
- package/dist/packem_shared/retry-3pnxTuNs.js +1 -0
- package/dist/packem_shared/retryMiddleware-DbViDX4r.js +1 -0
- package/dist/packem_shared/roundRobinProvider-D1by5KGW.js +1 -0
- package/dist/packem_shared/sanitize-header-DJhgZl3y.js +1 -0
- package/dist/packem_shared/scalewayProvider-D8dmHuwZ.js +1 -0
- package/dist/packem_shared/sendGridProvider-CChhLr7s.js +1 -0
- package/dist/packem_shared/smtpProvider-x4WBN-3W.js +25 -0
- package/dist/packem_shared/sweegoProvider-7xhOvagC.js +1 -0
- package/dist/packem_shared/toEmailSnapshot-DeRqM5SJ.js +1 -0
- package/dist/packem_shared/tracer.d-MU42G1jG.d.ts +494 -0
- package/dist/packem_shared/{types.d-CNnnk-Ya.d.ts → types.d-BId55FW2.d.ts} +6 -1
- package/dist/packem_shared/types.d-CmoWvdZi.d.ts +61 -0
- package/dist/packem_shared/types.d-DCkecJse.d.ts +51 -0
- package/dist/packem_shared/types.d-Mpu0HZoG.d.ts +24 -0
- package/dist/packem_shared/{types.d-wwpgA3to.d.ts → types.d-ejzh-xBP.d.ts} +6 -1
- package/dist/packem_shared/types.d-lcJZmwRK.d.ts +69 -0
- package/dist/packem_shared/utils-BfYfPB_I.js +1 -0
- package/dist/packem_shared/validate-email-options-mCM9dVug.js +1 -0
- package/dist/packem_shared/verifyMailgunWebhook-Cwl0OD3P.js +1 -0
- package/dist/packem_shared/verifyPostmarkWebhook-C72ZvbrG.js +1 -0
- package/dist/packem_shared/verifyResendWebhook-YK2zNDXR.js +1 -0
- package/dist/packem_shared/verifySendGridWebhook-Dbwc1tfG.js +1 -0
- package/dist/packem_shared/withEvents-CCVblSqj.js +1 -0
- package/dist/packem_shared/withMetrics-DWywX_6M.js +1 -0
- package/dist/packem_shared/withRender-VP9wE5Yr.js +1 -0
- package/dist/packem_shared/withSuppression-DBaZDMAr.js +1 -0
- package/dist/packem_shared/withTelemetry-DL2qo0Hp.js +1 -0
- package/dist/packem_shared/zeptomailProvider-D3nQKXRf.js +1 -0
- package/dist/providers/ahasend/index.d.ts +3 -3
- package/dist/providers/ahasend/index.js +1 -1
- package/dist/providers/aws-ses/index.d.ts +3 -3
- package/dist/providers/aws-ses/index.js +1 -1
- package/dist/providers/azure/index.d.ts +3 -3
- package/dist/providers/azure/index.js +1 -1
- package/dist/providers/brevo/index.d.ts +3 -3
- package/dist/providers/brevo/index.js +1 -1
- package/dist/providers/cloudflare-email/index.d.ts +36 -0
- package/dist/providers/cloudflare-email/index.js +1 -0
- package/dist/providers/failover/index.d.ts +3 -3
- package/dist/providers/failover/index.js +1 -1
- package/dist/providers/http/index.d.ts +3 -3
- package/dist/providers/http/index.js +1 -1
- package/dist/providers/infobip/index.d.ts +3 -3
- package/dist/providers/infobip/index.js +1 -1
- package/dist/providers/loops/index.d.ts +47 -0
- package/dist/providers/loops/index.js +1 -0
- package/dist/providers/mailchannels/index.d.ts +26 -0
- package/dist/providers/mailchannels/index.js +1 -0
- package/dist/providers/mailcrab/index.d.ts +3 -3
- package/dist/providers/mailcrab/index.js +1 -1
- package/dist/providers/mailersend/index.d.ts +3 -3
- package/dist/providers/mailersend/index.js +1 -1
- package/dist/providers/mailgun/index.d.ts +3 -3
- package/dist/providers/mailgun/index.js +1 -1
- package/dist/providers/mailjet/index.d.ts +3 -3
- package/dist/providers/mailjet/index.js +1 -1
- package/dist/providers/mailomat/index.d.ts +3 -3
- package/dist/providers/mailomat/index.js +1 -1
- package/dist/providers/mailpace/index.d.ts +3 -3
- package/dist/providers/mailpace/index.js +1 -1
- package/dist/providers/mailtrap/index.d.ts +3 -3
- package/dist/providers/mailtrap/index.js +1 -1
- package/dist/providers/mandrill/index.d.ts +3 -3
- package/dist/providers/mandrill/index.js +1 -1
- package/dist/providers/mock/index.d.ts +6 -53
- package/dist/providers/mock/index.js +1 -1
- package/dist/providers/nodemailer/index.d.ts +3 -3
- package/dist/providers/nodemailer/index.js +1 -1
- package/dist/providers/opentelemetry/index.d.ts +3 -495
- package/dist/providers/opentelemetry/index.js +1 -1
- package/dist/providers/plunk/index.d.ts +3 -3
- package/dist/providers/plunk/index.js +1 -1
- package/dist/providers/postal/index.d.ts +3 -3
- package/dist/providers/postal/index.js +1 -1
- package/dist/providers/postmark/index.d.ts +3 -3
- package/dist/providers/postmark/index.js +1 -1
- package/dist/providers/resend/index.d.ts +3 -3
- package/dist/providers/resend/index.js +1 -1
- package/dist/providers/roundrobin/index.d.ts +3 -3
- package/dist/providers/roundrobin/index.js +1 -1
- package/dist/providers/scaleway/index.d.ts +3 -3
- package/dist/providers/scaleway/index.js +1 -1
- package/dist/providers/sendgrid/index.d.ts +3 -3
- package/dist/providers/sendgrid/index.js +1 -1
- package/dist/providers/smtp/index.d.ts +3 -3
- package/dist/providers/smtp/index.js +1 -1
- package/dist/providers/sweego/index.d.ts +3 -3
- package/dist/providers/sweego/index.js +1 -1
- package/dist/providers/zeptomail/index.d.ts +3 -3
- package/dist/providers/zeptomail/index.js +1 -1
- package/dist/queue/bullmq-queue.d.ts +46 -0
- package/dist/queue/bullmq-queue.js +1 -0
- package/dist/queue/index.d.ts +147 -0
- package/dist/queue/index.js +1 -0
- package/dist/queue/pg-boss-queue.d.ts +41 -0
- package/dist/queue/pg-boss-queue.js +1 -0
- package/dist/queue/sqs-queue.d.ts +72 -0
- package/dist/queue/sqs-queue.js +1 -0
- package/dist/queue/unstorage-queue.d.ts +199 -0
- package/dist/queue/unstorage-queue.js +1 -0
- package/dist/render/index.d.ts +107 -0
- package/dist/render/index.js +1 -0
- package/dist/template-engines/handlebars.js +1 -1
- package/dist/template-engines/html-to-text.js +1 -1
- package/dist/template-engines/i18n.d.ts +61 -0
- package/dist/template-engines/i18n.js +1 -0
- package/dist/template-engines/jsx-email.d.ts +11 -0
- package/dist/template-engines/jsx-email.js +1 -0
- package/dist/template-engines/liquid.d.ts +12 -0
- package/dist/template-engines/liquid.js +1 -0
- package/dist/template-engines/mjml.js +1 -1
- package/dist/template-engines/react-email.js +1 -1
- package/dist/template-engines/vue-email.js +1 -1
- package/dist/test/index.d.ts +159 -0
- package/dist/test/index.js +1 -0
- package/dist/utils/cache.js +1 -1
- package/dist/utils/format-email-address.d.ts +1 -1
- package/dist/utils/format-email-address.js +1 -1
- package/dist/utils/normalize-email-aliases.js +1 -1
- package/dist/utils/parse-address.d.ts +1 -1
- package/dist/utils/parse-address.js +1 -1
- package/dist/utils/parse-eml.d.ts +22 -0
- package/dist/utils/parse-eml.js +6 -0
- package/dist/utils/result.d.ts +49 -0
- package/dist/utils/result.js +1 -0
- package/dist/utils/validation/check-feature-support.d.ts +1 -1
- package/dist/utils/validation/check-feature-support.js +1 -1
- package/dist/utils/validation/check-mx-records.d.ts +1 -1
- package/dist/utils/validation/check-mx-records.js +1 -1
- package/dist/utils/validation/role-accounts.js +1 -1
- package/dist/utils/validation/validate-email.js +1 -1
- package/dist/utils/validation/verify-email.js +1 -1
- package/dist/utils/validation/verify-smtp.js +4 -4
- package/dist/webhooks/index.d.ts +231 -0
- package/dist/webhooks/index.js +1 -0
- package/package.json +122 -6
- package/dist/packem_shared/DkimSigner-CT2DSHD1.js +0 -18
- package/dist/packem_shared/EmailError-zm2ffVav.js +0 -1
- package/dist/packem_shared/Mail-BWSWWq6m.js +0 -1
- package/dist/packem_shared/MailMessage-BvaH5tZZ.js +0 -1
- package/dist/packem_shared/RequiredOptionError-CevW3u2K.js +0 -1
- package/dist/packem_shared/SmimeEncrypter-ZhHEgDwY.js +0 -6
- package/dist/packem_shared/SmimeSigner-CYSVF6ez.js +0 -8
- package/dist/packem_shared/address-formatter-Cm_E_ZMa.js +0 -1
- package/dist/packem_shared/aggregate-features-BvgdYul-.js +0 -1
- package/dist/packem_shared/ahaSendProvider-DOAAW65O.js +0 -1
- package/dist/packem_shared/attachment-processor-DsmIomKc.js +0 -1
- package/dist/packem_shared/awsSesProvider-DX1630Ms.js +0 -32
- package/dist/packem_shared/azureProvider-EkNYKAiF.js +0 -1
- package/dist/packem_shared/brevoProvider-CkR4U4RD.js +0 -1
- package/dist/packem_shared/build-mime-message-6xstxaUV.js +0 -2
- package/dist/packem_shared/create-logger-BiWdqFNg.js +0 -1
- package/dist/packem_shared/defineProvider-CtLH0VBE.js +0 -1
- package/dist/packem_shared/detectMimeType-bo5oxfnt.js +0 -1
- package/dist/packem_shared/failoverProvider-D90MHT2T.js +0 -1
- package/dist/packem_shared/generate-boundary-Cx8nXYS0.js +0 -1
- package/dist/packem_shared/generate-message-id-D4uA8gkj.js +0 -1
- package/dist/packem_shared/headers-to-record-Qo124ImV.js +0 -1
- package/dist/packem_shared/httpProvider-DUg1AQfO.js +0 -1
- package/dist/packem_shared/infobipProvider-BhTsWi7e.js +0 -1
- package/dist/packem_shared/mailPaceProvider-DRt6Z9Hr.js +0 -1
- package/dist/packem_shared/mailerSendProvider-Dx_iHInH.js +0 -1
- package/dist/packem_shared/mailgunProvider-ChkLGZZW.js +0 -1
- package/dist/packem_shared/mailjetProvider-BMRhNe6H.js +0 -1
- package/dist/packem_shared/mailomatProvider-CydV-JB6.js +0 -1
- package/dist/packem_shared/mailtrapProvider-CuAfJWDr.js +0 -1
- package/dist/packem_shared/make-request-CaT4d5oC.js +0 -1
- package/dist/packem_shared/mandrillProvider-BBeLbaw0.js +0 -1
- package/dist/packem_shared/mockProvider-C0P1lKOy.js +0 -1
- package/dist/packem_shared/nodemailerProvider-DFcvoVFv.js +0 -1
- package/dist/packem_shared/opentelemetryProvider-Dwv88G3O.js +0 -1
- package/dist/packem_shared/plunkProvider-BQyjG6YT.js +0 -1
- package/dist/packem_shared/postalProvider-DPHQ620q.js +0 -1
- package/dist/packem_shared/postmarkProvider-bMTC2gdJ.js +0 -1
- package/dist/packem_shared/provider-base-Cmzx6BTO.js +0 -1
- package/dist/packem_shared/readFile-BAVMZg5e-C4whBIPd.js +0 -1
- package/dist/packem_shared/resendProvider-Cns1tvF5.js +0 -1
- package/dist/packem_shared/roundRobinProvider-B_60F0BC.js +0 -1
- package/dist/packem_shared/sanitize-header-wWav-Scu.js +0 -1
- package/dist/packem_shared/scalewayProvider-O1dHz7iJ.js +0 -1
- package/dist/packem_shared/sendGridProvider-DmywC-eT.js +0 -1
- package/dist/packem_shared/smtpProvider-Unjao_fn.js +0 -23
- package/dist/packem_shared/sweegoProvider-D086G6xG.js +0 -1
- package/dist/packem_shared/validate-email-options-DPo3SgC0.js +0 -1
- package/dist/packem_shared/zeptomailProvider-DKKEpEsW.js +0 -1
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Result of verifying an inbound webhook signature.
|
|
3
|
+
*/
|
|
4
|
+
interface WebhookVerificationResult {
|
|
5
|
+
/**
|
|
6
|
+
* Machine-readable reason when {@link WebhookVerificationResult.valid} is `false`.
|
|
7
|
+
*/
|
|
8
|
+
reason?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Whether the signature (and, when applicable, the timestamp) is valid.
|
|
11
|
+
*/
|
|
12
|
+
valid: boolean;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Headers passed to a webhook verifier. Either a plain record or a `Headers` instance.
|
|
16
|
+
*
|
|
17
|
+
* Lookups are case-insensitive.
|
|
18
|
+
*/
|
|
19
|
+
type WebhookHeaders = Headers | Record<string, string | string[] | undefined>;
|
|
20
|
+
/**
|
|
21
|
+
* Shared options for verifiers that enforce a timestamp tolerance to guard against replay attacks.
|
|
22
|
+
*/
|
|
23
|
+
interface TimestampToleranceOptions {
|
|
24
|
+
/**
|
|
25
|
+
* Maximum allowed difference, in seconds, between the signed timestamp and the current time.
|
|
26
|
+
*
|
|
27
|
+
* Set to `0` to disable the replay-protection window.
|
|
28
|
+
* @default 300
|
|
29
|
+
*/
|
|
30
|
+
tolerance?: number;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Options for {@link verifyMailgunWebhook}.
|
|
34
|
+
*
|
|
35
|
+
* Mailgun nests these three fields under a `signature` object in the webhook JSON body.
|
|
36
|
+
*/
|
|
37
|
+
interface MailgunWebhookOptions extends TimestampToleranceOptions {
|
|
38
|
+
/**
|
|
39
|
+
* Override the current time (milliseconds) — primarily for testing.
|
|
40
|
+
*/
|
|
41
|
+
now?: number;
|
|
42
|
+
/**
|
|
43
|
+
* The HMAC value from `signature.signature`.
|
|
44
|
+
*/
|
|
45
|
+
signature: string;
|
|
46
|
+
/**
|
|
47
|
+
* Your Mailgun HTTP webhook signing key (Settings → Webhooks).
|
|
48
|
+
*/
|
|
49
|
+
signingKey: string;
|
|
50
|
+
/**
|
|
51
|
+
* The timestamp from `signature.timestamp` (unix seconds, as a string or number).
|
|
52
|
+
*/
|
|
53
|
+
timestamp: number | string;
|
|
54
|
+
/**
|
|
55
|
+
* The token from `signature.token`.
|
|
56
|
+
*/
|
|
57
|
+
token: string;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Verifies a [Mailgun](https://documentation.mailgun.com/docs/mailgun/user-manual/tracking-messages/#webhooks) webhook.
|
|
61
|
+
*
|
|
62
|
+
* Mailgun computes `HMAC-SHA256(key = signingKey, message = timestamp + token)` and sends the hex
|
|
63
|
+
* digest as `signature.signature`.
|
|
64
|
+
* @param options Verification inputs. See {@link MailgunWebhookOptions}.
|
|
65
|
+
* @returns The verification result.
|
|
66
|
+
*/
|
|
67
|
+
declare const verifyMailgunWebhook: (options: MailgunWebhookOptions) => WebhookVerificationResult;
|
|
68
|
+
/**
|
|
69
|
+
* Options for {@link verifyPostmarkWebhook}.
|
|
70
|
+
*
|
|
71
|
+
* Postmark does not sign webhook payloads; instead it supports HTTP Basic Auth credentials embedded
|
|
72
|
+
* in the webhook URL (and IP allow-listing). This verifier checks the Basic Auth credentials.
|
|
73
|
+
*/
|
|
74
|
+
interface PostmarkWebhookOptions {
|
|
75
|
+
/**
|
|
76
|
+
* The value of the incoming `Authorization` header (e.g. `Basic dXNlcjpwYXNz`).
|
|
77
|
+
*/
|
|
78
|
+
authorization: string | undefined;
|
|
79
|
+
/**
|
|
80
|
+
* The password configured on the Postmark webhook URL.
|
|
81
|
+
*/
|
|
82
|
+
password: string;
|
|
83
|
+
/**
|
|
84
|
+
* The username configured on the Postmark webhook URL.
|
|
85
|
+
*/
|
|
86
|
+
username: string;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Verifies a [Postmark](https://postmarkapp.com/support/article/1213-securing-inbound-and-open-webhooks)
|
|
90
|
+
* webhook by validating its HTTP Basic Auth credentials.
|
|
91
|
+
* @param options Verification inputs. See {@link PostmarkWebhookOptions}.
|
|
92
|
+
* @returns The verification result.
|
|
93
|
+
*/
|
|
94
|
+
declare const verifyPostmarkWebhook: (options: PostmarkWebhookOptions) => WebhookVerificationResult;
|
|
95
|
+
/**
|
|
96
|
+
* Options for {@link verifySendGridWebhook}.
|
|
97
|
+
*/
|
|
98
|
+
interface SendGridWebhookOptions extends TimestampToleranceOptions {
|
|
99
|
+
/**
|
|
100
|
+
* Override the current time (milliseconds) — primarily for testing.
|
|
101
|
+
*/
|
|
102
|
+
now?: number;
|
|
103
|
+
/**
|
|
104
|
+
* The raw, unparsed request body exactly as received.
|
|
105
|
+
*/
|
|
106
|
+
payload: string;
|
|
107
|
+
/**
|
|
108
|
+
* The verification key from the SendGrid Event Webhook settings.
|
|
109
|
+
*
|
|
110
|
+
* Either the base64-encoded DER (SPKI) string SendGrid displays, or a full PEM block.
|
|
111
|
+
*/
|
|
112
|
+
publicKey: string;
|
|
113
|
+
/**
|
|
114
|
+
* The value of the `X-Twilio-Email-Event-Webhook-Signature` header (base64 DER ECDSA signature).
|
|
115
|
+
*/
|
|
116
|
+
signature: string;
|
|
117
|
+
/**
|
|
118
|
+
* The value of the `X-Twilio-Email-Event-Webhook-Timestamp` header (unix epoch seconds).
|
|
119
|
+
*/
|
|
120
|
+
timestamp: string;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Verifies a [SendGrid Event Webhook](https://www.twilio.com/docs/sendgrid/for-developers/tracking-events/getting-started-event-webhook-security-features)
|
|
124
|
+
* using its ECDSA (prime256v1) signature, and rejects stale requests to prevent replay.
|
|
125
|
+
*
|
|
126
|
+
* The signed message is `timestamp + payload`. The signature header is the base64-encoded DER
|
|
127
|
+
* ECDSA signature. The timestamp is unix epoch seconds and must fall within `tolerance` of now.
|
|
128
|
+
* @param options Verification inputs. See {@link SendGridWebhookOptions}.
|
|
129
|
+
* @returns The verification result.
|
|
130
|
+
* @throws {EmailError} When the supplied public key cannot be parsed.
|
|
131
|
+
*/
|
|
132
|
+
declare const verifySendGridWebhook: (options: SendGridWebhookOptions) => WebhookVerificationResult;
|
|
133
|
+
/**
|
|
134
|
+
* The subset of an Amazon SNS message envelope relevant to signature verification.
|
|
135
|
+
*
|
|
136
|
+
* AWS SES delivers events (deliveries, bounces, complaints) wrapped in SNS notifications.
|
|
137
|
+
*/
|
|
138
|
+
interface SnsMessage {
|
|
139
|
+
[key: string]: unknown;
|
|
140
|
+
Message?: string;
|
|
141
|
+
MessageId?: string;
|
|
142
|
+
Signature?: string;
|
|
143
|
+
SignatureVersion?: string;
|
|
144
|
+
SigningCertURL?: string;
|
|
145
|
+
Subject?: string;
|
|
146
|
+
SubscribeURL?: string;
|
|
147
|
+
Timestamp?: string;
|
|
148
|
+
Token?: string;
|
|
149
|
+
TopicArn?: string;
|
|
150
|
+
Type?: string;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Resolves a signing-certificate URL to its PEM contents. Injectable for testing and caching.
|
|
154
|
+
*/
|
|
155
|
+
type CertificateResolver = (url: string) => Promise<string> | string;
|
|
156
|
+
/**
|
|
157
|
+
* Options for {@link verifySnsMessage}.
|
|
158
|
+
*/
|
|
159
|
+
interface SnsVerifyOptions {
|
|
160
|
+
/**
|
|
161
|
+
* Override how the signing certificate is fetched. Defaults to a `fetch`-based resolver that
|
|
162
|
+
* only accepts `https://*.amazonaws.com` URLs.
|
|
163
|
+
*/
|
|
164
|
+
certificateResolver?: CertificateResolver;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Validates that a signing-certificate URL points at an AWS SNS signing host over HTTPS.
|
|
168
|
+
* @param url The `SigningCertURL` from the SNS message.
|
|
169
|
+
* @returns `true` when the URL is an acceptable AWS SNS certificate endpoint.
|
|
170
|
+
*/
|
|
171
|
+
declare const isValidSigningCertUrl: (url: string) => boolean;
|
|
172
|
+
/**
|
|
173
|
+
* Verifies the RSA signature on an Amazon SNS message (used to wrap AWS SES events).
|
|
174
|
+
*
|
|
175
|
+
* Signature version `1` uses SHA1, version `2` uses SHA256. The signing certificate is fetched from
|
|
176
|
+
* `SigningCertURL` (validated to be an `sns.<region>.amazonaws.com` HTTPS endpoint with no userinfo
|
|
177
|
+
* or explicit port) unless a custom {@link CertificateResolver} is supplied.
|
|
178
|
+
* @param message The parsed SNS message envelope.
|
|
179
|
+
* @param options Optional overrides. See {@link SnsVerifyOptions}.
|
|
180
|
+
* @returns The verification result.
|
|
181
|
+
* @throws {EmailError} When the certificate cannot be resolved.
|
|
182
|
+
*/
|
|
183
|
+
declare const verifySnsMessage: (message: SnsMessage, options?: SnsVerifyOptions) => Promise<WebhookVerificationResult>;
|
|
184
|
+
/**
|
|
185
|
+
* Options for {@link verifyStandardWebhook}.
|
|
186
|
+
*/
|
|
187
|
+
interface StandardWebhookOptions extends TimestampToleranceOptions {
|
|
188
|
+
/**
|
|
189
|
+
* The request headers, or the three signature headers as a plain record.
|
|
190
|
+
*
|
|
191
|
+
* Recognized header names (case-insensitive): `webhook-id` / `svix-id`,
|
|
192
|
+
* `webhook-timestamp` / `svix-timestamp`, and `webhook-signature` / `svix-signature`.
|
|
193
|
+
*/
|
|
194
|
+
headers: WebhookHeaders;
|
|
195
|
+
/**
|
|
196
|
+
* Override the current time (milliseconds) — primarily for testing.
|
|
197
|
+
*/
|
|
198
|
+
now?: number;
|
|
199
|
+
/**
|
|
200
|
+
* The raw, unparsed request body exactly as received.
|
|
201
|
+
*
|
|
202
|
+
* Parsing and re-serializing the body changes the bytes and breaks verification.
|
|
203
|
+
*/
|
|
204
|
+
payload: string;
|
|
205
|
+
/**
|
|
206
|
+
* The signing secret. Supports the `whsec_`-prefixed, base64-encoded form used by Svix/Resend,
|
|
207
|
+
* or a raw secret string.
|
|
208
|
+
*/
|
|
209
|
+
secret: string;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Verifies a webhook signed according to the [Standard Webhooks](https://www.standardwebhooks.com/) spec.
|
|
213
|
+
*
|
|
214
|
+
* This is the scheme used by Svix and, by extension, Resend. The signed content is
|
|
215
|
+
* `${id}.${timestamp}.${payload}`, HMAC-SHA256'd with the (base64-decoded) secret and base64-encoded.
|
|
216
|
+
* The `webhook-signature` header may contain multiple space-separated `v1,<sig>` entries; a match
|
|
217
|
+
* against any one of them passes.
|
|
218
|
+
* @param options Verification inputs. See {@link StandardWebhookOptions}.
|
|
219
|
+
* @returns The verification result.
|
|
220
|
+
*/
|
|
221
|
+
declare const verifyStandardWebhook: (options: StandardWebhookOptions) => WebhookVerificationResult;
|
|
222
|
+
/**
|
|
223
|
+
* Verifies a [Resend](https://resend.com/docs/dashboard/webhooks/verify-webhooks-requests) webhook.
|
|
224
|
+
*
|
|
225
|
+
* Resend uses Svix, so this is an alias for {@link verifyStandardWebhook} that accepts the
|
|
226
|
+
* `svix-*` headers.
|
|
227
|
+
* @param options Verification inputs. See {@link StandardWebhookOptions}.
|
|
228
|
+
* @returns The verification result.
|
|
229
|
+
*/
|
|
230
|
+
declare const verifyResendWebhook: (options: StandardWebhookOptions) => WebhookVerificationResult;
|
|
231
|
+
export { type CertificateResolver, type MailgunWebhookOptions, type PostmarkWebhookOptions, type SendGridWebhookOptions, type SnsMessage, type SnsVerifyOptions, type StandardWebhookOptions, type TimestampToleranceOptions, type WebhookHeaders, type WebhookVerificationResult, isValidSigningCertUrl, verifyMailgunWebhook, verifyPostmarkWebhook, verifyResendWebhook, verifySendGridWebhook, verifySnsMessage, verifyStandardWebhook };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{verifyMailgunWebhook as r}from"../packem_shared/verifyMailgunWebhook-Cwl0OD3P.js";import{verifyPostmarkWebhook as f}from"../packem_shared/verifyPostmarkWebhook-C72ZvbrG.js";import{verifySendGridWebhook as n}from"../packem_shared/verifySendGridWebhook-Dbwc1tfG.js";import{isValidSigningCertUrl as d,verifySnsMessage as k}from"../packem_shared/isValidSigningCertUrl-Bii1AMGC.js";import{verifyResendWebhook as s,verifyStandardWebhook as v}from"../packem_shared/verifyResendWebhook-YK2zNDXR.js";export{d as isValidSigningCertUrl,r as verifyMailgunWebhook,f as verifyPostmarkWebhook,s as verifyResendWebhook,n as verifySendGridWebhook,k as verifySnsMessage,v as verifyStandardWebhook};
|
package/package.json
CHANGED
|
@@ -1,19 +1,31 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@visulima/email",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.36",
|
|
4
4
|
"description": "A comprehensive email library with multi-provider support, crypto utilities, and template engines",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ahasend",
|
|
7
|
+
"arc",
|
|
7
8
|
"aws-ses",
|
|
8
9
|
"azure",
|
|
10
|
+
"batch",
|
|
9
11
|
"better-mail",
|
|
10
12
|
"brevo",
|
|
11
13
|
"crypto",
|
|
14
|
+
"deliverability",
|
|
12
15
|
"disposable-email",
|
|
13
16
|
"disposable-email-domains",
|
|
14
17
|
"dkim",
|
|
18
|
+
"dmarc",
|
|
15
19
|
"email",
|
|
16
20
|
"encryption",
|
|
21
|
+
"i18n",
|
|
22
|
+
"inbound-email",
|
|
23
|
+
"jsx-email",
|
|
24
|
+
"liquid",
|
|
25
|
+
"list-unsubscribe",
|
|
26
|
+
"middleware",
|
|
27
|
+
"queue",
|
|
28
|
+
"webhook",
|
|
17
29
|
"failover",
|
|
18
30
|
"handlebars",
|
|
19
31
|
"html-to-text",
|
|
@@ -97,6 +109,18 @@
|
|
|
97
109
|
"types": "./dist/template-engines/html-to-text.d.ts",
|
|
98
110
|
"default": "./dist/template-engines/html-to-text.js"
|
|
99
111
|
},
|
|
112
|
+
"./template/liquid": {
|
|
113
|
+
"types": "./dist/template-engines/liquid.d.ts",
|
|
114
|
+
"default": "./dist/template-engines/liquid.js"
|
|
115
|
+
},
|
|
116
|
+
"./template/jsx-email": {
|
|
117
|
+
"types": "./dist/template-engines/jsx-email.d.ts",
|
|
118
|
+
"default": "./dist/template-engines/jsx-email.js"
|
|
119
|
+
},
|
|
120
|
+
"./template/i18n": {
|
|
121
|
+
"types": "./dist/template-engines/i18n.d.ts",
|
|
122
|
+
"default": "./dist/template-engines/i18n.js"
|
|
123
|
+
},
|
|
100
124
|
"./providers/aws-ses": {
|
|
101
125
|
"types": "./dist/providers/aws-ses/index.d.ts",
|
|
102
126
|
"default": "./dist/providers/aws-ses/index.js"
|
|
@@ -149,6 +173,58 @@
|
|
|
149
173
|
"types": "./dist/crypto/index.d.ts",
|
|
150
174
|
"default": "./dist/crypto/index.js"
|
|
151
175
|
},
|
|
176
|
+
"./render": {
|
|
177
|
+
"types": "./dist/render/index.d.ts",
|
|
178
|
+
"default": "./dist/render/index.js"
|
|
179
|
+
},
|
|
180
|
+
"./webhooks": {
|
|
181
|
+
"types": "./dist/webhooks/index.d.ts",
|
|
182
|
+
"default": "./dist/webhooks/index.js"
|
|
183
|
+
},
|
|
184
|
+
"./deliverability": {
|
|
185
|
+
"types": "./dist/deliverability/index.d.ts",
|
|
186
|
+
"default": "./dist/deliverability/index.js"
|
|
187
|
+
},
|
|
188
|
+
"./deliverability/dmarc-report": {
|
|
189
|
+
"types": "./dist/deliverability/dmarc-report.d.ts",
|
|
190
|
+
"default": "./dist/deliverability/dmarc-report.js"
|
|
191
|
+
},
|
|
192
|
+
"./inbound": {
|
|
193
|
+
"types": "./dist/inbound/index.d.ts",
|
|
194
|
+
"default": "./dist/inbound/index.js"
|
|
195
|
+
},
|
|
196
|
+
"./events": {
|
|
197
|
+
"types": "./dist/events/index.d.ts",
|
|
198
|
+
"default": "./dist/events/index.js"
|
|
199
|
+
},
|
|
200
|
+
"./middleware": {
|
|
201
|
+
"types": "./dist/middleware/index.d.ts",
|
|
202
|
+
"default": "./dist/middleware/index.js"
|
|
203
|
+
},
|
|
204
|
+
"./queue": {
|
|
205
|
+
"types": "./dist/queue/index.d.ts",
|
|
206
|
+
"default": "./dist/queue/index.js"
|
|
207
|
+
},
|
|
208
|
+
"./queue/unstorage": {
|
|
209
|
+
"types": "./dist/queue/unstorage-queue.d.ts",
|
|
210
|
+
"default": "./dist/queue/unstorage-queue.js"
|
|
211
|
+
},
|
|
212
|
+
"./queue/sqs": {
|
|
213
|
+
"types": "./dist/queue/sqs-queue.d.ts",
|
|
214
|
+
"default": "./dist/queue/sqs-queue.js"
|
|
215
|
+
},
|
|
216
|
+
"./queue/pg-boss": {
|
|
217
|
+
"types": "./dist/queue/pg-boss-queue.d.ts",
|
|
218
|
+
"default": "./dist/queue/pg-boss-queue.js"
|
|
219
|
+
},
|
|
220
|
+
"./queue/bullmq": {
|
|
221
|
+
"types": "./dist/queue/bullmq-queue.d.ts",
|
|
222
|
+
"default": "./dist/queue/bullmq-queue.js"
|
|
223
|
+
},
|
|
224
|
+
"./test": {
|
|
225
|
+
"types": "./dist/test/index.d.ts",
|
|
226
|
+
"default": "./dist/test/index.js"
|
|
227
|
+
},
|
|
152
228
|
"./providers/sendgrid": {
|
|
153
229
|
"types": "./dist/providers/sendgrid/index.d.ts",
|
|
154
230
|
"default": "./dist/providers/sendgrid/index.js"
|
|
@@ -213,10 +289,30 @@
|
|
|
213
289
|
"types": "./dist/providers/sweego/index.d.ts",
|
|
214
290
|
"default": "./dist/providers/sweego/index.js"
|
|
215
291
|
},
|
|
292
|
+
"./providers/mailchannels": {
|
|
293
|
+
"types": "./dist/providers/mailchannels/index.d.ts",
|
|
294
|
+
"default": "./dist/providers/mailchannels/index.js"
|
|
295
|
+
},
|
|
296
|
+
"./providers/cloudflare-email": {
|
|
297
|
+
"types": "./dist/providers/cloudflare-email/index.d.ts",
|
|
298
|
+
"default": "./dist/providers/cloudflare-email/index.js"
|
|
299
|
+
},
|
|
300
|
+
"./providers/loops": {
|
|
301
|
+
"types": "./dist/providers/loops/index.d.ts",
|
|
302
|
+
"default": "./dist/providers/loops/index.js"
|
|
303
|
+
},
|
|
216
304
|
"./utils/parse-address": {
|
|
217
305
|
"types": "./dist/utils/parse-address.d.ts",
|
|
218
306
|
"default": "./dist/utils/parse-address.js"
|
|
219
307
|
},
|
|
308
|
+
"./utils/parse-eml": {
|
|
309
|
+
"types": "./dist/utils/parse-eml.d.ts",
|
|
310
|
+
"default": "./dist/utils/parse-eml.js"
|
|
311
|
+
},
|
|
312
|
+
"./utils/result": {
|
|
313
|
+
"types": "./dist/utils/result.d.ts",
|
|
314
|
+
"default": "./dist/utils/result.js"
|
|
315
|
+
},
|
|
220
316
|
"./utils/format-email-address": {
|
|
221
317
|
"types": "./dist/utils/format-email-address.d.ts",
|
|
222
318
|
"default": "./dist/utils/format-email-address.js"
|
|
@@ -265,10 +361,10 @@
|
|
|
265
361
|
"CHANGELOG.md"
|
|
266
362
|
],
|
|
267
363
|
"dependencies": {
|
|
268
|
-
"@visulima/disposable-email-domains": "1.0.0-alpha.
|
|
364
|
+
"@visulima/disposable-email-domains": "1.0.0-alpha.17",
|
|
269
365
|
"html-to-text": "^10.0.0",
|
|
270
|
-
"ical-generator": "
|
|
271
|
-
"lru-cache": "11.
|
|
366
|
+
"ical-generator": "11.0.0",
|
|
367
|
+
"lru-cache": "11.5.1",
|
|
272
368
|
"mime": "^4.1.0"
|
|
273
369
|
},
|
|
274
370
|
"peerDependencies": {
|
|
@@ -276,10 +372,15 @@
|
|
|
276
372
|
"@react-email/render": "^2.0.8",
|
|
277
373
|
"@vue-email/render": "0.0.9",
|
|
278
374
|
"asn1js": "3.0.10",
|
|
375
|
+
"fast-xml-parser": "^4.5.0",
|
|
279
376
|
"handlebars": "4.7.9",
|
|
280
|
-
"
|
|
377
|
+
"jsx-email": "^2.0.0",
|
|
378
|
+
"juice": "^11.0.0",
|
|
379
|
+
"liquidjs": "^10.0.0",
|
|
380
|
+
"mjml": "5.3.0",
|
|
281
381
|
"nodemailer": ">=7",
|
|
282
|
-
"pkijs": "3.4.0"
|
|
382
|
+
"pkijs": "3.4.0",
|
|
383
|
+
"unstorage": "^1.13.0"
|
|
283
384
|
},
|
|
284
385
|
"peerDependenciesMeta": {
|
|
285
386
|
"@opentelemetry/api": {
|
|
@@ -294,9 +395,21 @@
|
|
|
294
395
|
"asn1js": {
|
|
295
396
|
"optional": true
|
|
296
397
|
},
|
|
398
|
+
"fast-xml-parser": {
|
|
399
|
+
"optional": true
|
|
400
|
+
},
|
|
297
401
|
"handlebars": {
|
|
298
402
|
"optional": true
|
|
299
403
|
},
|
|
404
|
+
"jsx-email": {
|
|
405
|
+
"optional": true
|
|
406
|
+
},
|
|
407
|
+
"juice": {
|
|
408
|
+
"optional": true
|
|
409
|
+
},
|
|
410
|
+
"liquidjs": {
|
|
411
|
+
"optional": true
|
|
412
|
+
},
|
|
300
413
|
"mjml": {
|
|
301
414
|
"optional": true
|
|
302
415
|
},
|
|
@@ -305,6 +418,9 @@
|
|
|
305
418
|
},
|
|
306
419
|
"pkijs": {
|
|
307
420
|
"optional": true
|
|
421
|
+
},
|
|
422
|
+
"unstorage": {
|
|
423
|
+
"optional": true
|
|
308
424
|
}
|
|
309
425
|
},
|
|
310
426
|
"engines": {
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
var v=Object.defineProperty;var m=(o,e)=>v(o,"name",{value:e,configurable:!0});import{createRequire as w}from"node:module";import{B as x}from"./readFile-BAVMZg5e-C4whBIPd.js";import{i as z}from"./headers-to-record-Qo124ImV.js";const C=w(import.meta.url),p=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,T=m(o=>{if(typeof p<"u"&&p.versions&&p.versions.node){const[e,t]=p.versions.node.split(".").map(Number);if(e>22||e===22&&t>=3||e===20&&t>=16)return p.getBuiltinModule(o)}return C(o)},"__cjs_getBuiltinModule"),{createHash:M,createSign:S,createPrivateKey:_}=T("node:crypto");var H=Object.defineProperty,d=m((o,e)=>H(o,"name",{value:e,configurable:!0}),"l");const I=d((o,e="simple")=>{const t=[];for(const[r,a]of Object.entries(o)){const n=e==="relaxed"?r.toLowerCase().trim():r,s=e==="relaxed"?a.replaceAll(/\s+/g," ").trim():a;t.push(`${n}:${s}`)}return t.join(`\r
|
|
2
|
-
`)},"canonicalizeHeaders"),K=d((o,e="simple")=>{if(e==="simple"){const n=o.replace(/(\r\n|\r|\n)$/,`
|
|
3
|
-
`);let s=n.length;for(;s>0&&n[s-1]===`
|
|
4
|
-
`;)s-=1;const c=n.slice(0,s);return c?`${c}
|
|
5
|
-
`:`
|
|
6
|
-
`}let t=o.replaceAll(`\r
|
|
7
|
-
`,`
|
|
8
|
-
`).replaceAll("\r",`
|
|
9
|
-
`);t=t.split(`
|
|
10
|
-
`).map(n=>n.replaceAll(/\s+/g," ").replace(/[ \t]+$/,"")).join(`
|
|
11
|
-
`);let r=t.length;for(;r>0&&t[r-1]===`
|
|
12
|
-
`;)r-=1;const a=t.slice(0,r);return a?`${a}
|
|
13
|
-
`:`
|
|
14
|
-
`},"canonicalizeBody"),B=d((o,e,t)=>{const r=e.headerCanon??"simple",a=e.bodyCanon??"simple",n=Object.keys(o).filter(s=>!e.headersToIgnore?.some(c=>c.toLowerCase()===s.toLowerCase())).map(s=>s.toLowerCase()).join(":");return["v=1","a=rsa-sha256",`c=${r}/${a}`,`d=${e.domainName}`,`s=${e.keySelector}`,`h=${n}`,`bh=${t}`,"b="].join("; ")},"createDkimSignatureHeader");class i{static{m(this,"DkimSigner")}static{d(this,"DkimSigner")}static sanitizeDisplayName(e){let t=e.replaceAll(/[\r\n\t]+/g," ");t=[...t].filter(n=>{const s=n.codePointAt(0);return s===void 0?!1:s>=32&&s<=126||s>159}).join("");const r="\\",a='"';return t=t.replaceAll(r,r+r).replaceAll(a,r+a),t=t.trim().replaceAll(/\s+/g," "),t}static formatAddress(e){if(e.name){const t=i.sanitizeDisplayName(e.name);return t?`"${t}" <${e.email}>`:e.email}return e.email}static formatAddresses(e){return(Array.isArray(e)?e:[e]).map(t=>i.formatAddress(t)).join(", ")}options;constructor(e){this.options=e}async sign(e){let t=this.options.privateKey;if(t.startsWith("file://")){const l=t.slice(7);t=await x(l,{encoding:"utf8"})}const r={...e.headers?z(e.headers):{},From:i.formatAddress(e.from),To:i.formatAddresses(e.to)};e.cc&&(r.Cc=i.formatAddresses(e.cc)),e.replyTo&&(r["Reply-To"]=i.formatAddress(e.replyTo)),r.Subject=e.subject,r["MIME-Version"]="1.0";const a=[];e.text&&a.push(e.text),e.html&&a.push(e.html);const n=a.join(`
|
|
15
|
-
|
|
16
|
-
`),s=this.options.headerCanon??"simple",c=this.options.bodyCanon??"simple",g=I(r,s),y=K(n,c),A=M("sha256").update(y).digest("base64"),h=B(r,this.options,A),$=`${g}\r
|
|
17
|
-
DKIM-Signature: ${h}`,f=S("RSA-SHA256");f.update($);let u;try{const l=_({key:t,passphrase:this.options.passphrase});u=f.sign(l,"base64")}catch(l){throw new Error(`Failed to create DKIM signature: ${l.message}`)}const j=u.match(/.{1,72}/g)?.join(`\r
|
|
18
|
-
`)??u,b={...r,"DKIM-Signature":`${h}${j}`};return{...e,headers:b}}}const R=d(o=>new i(o),"createDkimSigner");export{i as DkimSigner,R as createDkimSigner};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var h=Object.defineProperty;var i=(t,e)=>h(t,"name",{value:e,configurable:!0});var E=Object.defineProperty,a=i((t,e)=>E(t,"name",{value:e,configurable:!0}),"s$1"),p=Object.defineProperty,o=a((t,e)=>p(t,"name",{value:e,configurable:!0}),"i"),d=Object.defineProperty,c=o((t,e)=>d(t,"name",{value:e,configurable:!0}),"t");c(t=>t instanceof Error&&t.type==="VisulimaError","isVisulimaError");class f extends Error{static{i(this,"p")}static{a(this,"V")}static{o(this,"VisulimaError")}static{c(this,"VisulimaError")}loc;title;hint;type="VisulimaError";constructor({cause:e,hint:r,location:s,message:n,name:l,stack:u,title:m}){super(n,{cause:e}),this.title=m,this.name=l,this.stack=u??this.stack,this.loc=s,this.hint=r}setLocation(e){this.loc=e}setName(e){this.name=e}setMessage(e){this.message=e}setHint(e){this.hint=e}}var v=Object.defineProperty,b=i((t,e)=>v(t,"name",{value:e,configurable:!0}),"s");class y extends f{static{i(this,"l")}static{b(this,"EmailError")}component;code;constructor(e,r,s){super({cause:s?.cause,hint:s?.hint,message:`[@visulima/email] [${e}] ${r}`,name:"EmailError",title:`Email ${e} Error`}),this.component=e,this.code=s?.code}}export{y as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var p=Object.defineProperty;var n=(a,e)=>p(a,"name",{value:e,configurable:!0});import{MailMessage as c}from"./MailMessage-BvaH5tZZ.js";import m from"./EmailError-zm2ffVav.js";import{z as b}from"./build-mime-message-6xstxaUV.js";import{c as y}from"./create-logger-BiWdqFNg.js";import{i as d}from"./headers-to-record-Qo124ImV.js";import C from"../utils/validation/check-feature-support.js";var v=Object.defineProperty,M=n((a,e)=>v(a,"name",{value:e,configurable:!0}),"s");class f extends c{static{n(this,"DraftMailMessage")}static{M(this,"DraftMailMessage")}constructor(){super(),this.header("X-Unsent","1")}}var w=Object.defineProperty,u=n((a,e)=>w(a,"name",{value:e,configurable:!0}),"d");const T=u((a,e,r)=>{e.success&&e.data?a&&a.info("Email sent successfully",{messageId:e.data.messageId,provider:e.data.provider}):a&&a.error("Email send failed",{error:e.error,provider:r})},"logSendResult");class h{static{n(this,"Mail")}static{u(this,"Mail")}static extractErrorMessages(e){return e instanceof Error?[e.message]:[String(e??"Unknown error")]}provider;logger;loggerInstance;globalConfig;featureCheck;constructor(e,r){this.provider=e,this.featureCheck=r?.featureCheck??"error"}setLogger(e){return this.loggerInstance=e,this.logger=y("Mail",e),this}setFrom(e){return this.globalConfig??={},this.globalConfig.from=e,this.logger&&this.logger.debug("Default from address updated",{from:e.email}),this}setReplyTo(e){return this.globalConfig??={},this.globalConfig.replyTo=e,this.logger&&this.logger.debug("Default reply-to address updated",{replyTo:e.email}),this}setHeaders(e){if(this.globalConfig??={},this.globalConfig.headers=e,this.logger){const r=d(e);this.logger.debug("Default headers updated",{count:Object.keys(r).length,headers:Object.keys(r)})}return this}async draft(e){let r=e instanceof c||e instanceof f?await this.buildDraftFromMessage(e):await this.buildDraftFromOptions(e);r=this.applyGlobalConfig(r);const t=r.headers?d(r.headers):{};r.headers={...t,"X-Unsent":"1"};const s=await b(r);return this.logger&&this.logger.debug("Draft created successfully in EML format",{from:r.from.email,size:s.length,subject:r.subject,to:Array.isArray(r.to)?r.to.length:1}),s}async send(e){if(e instanceof f)throw new TypeError("Cannot send draft messages. Convert to MailMessage first or remove X-Unsent header.");let r;if(e instanceof c)this.logger&&this.logger.debug("Sending MailMessage instance"),this.loggerInstance&&e.setLogger(this.loggerInstance),r=await e.build();else{const o=e;this.logger&&this.logger.debug("Sending email with options",{subject:o.subject,to:Array.isArray(o.to)?o.to.length:1}),r=o}r=this.applyGlobalConfig(r);const t=this.assertFeatureSupport(r);if(t)return{error:t,success:!1};const s=await this.provider.sendEmail(r);return T(this.logger,s,this.provider.name??"unknown"),s}async*sendMany(e,r){const t=this.provider.name;let s=0,o=0,g=0;this.logger&&this.logger.debug("Starting batch email send",{provider:t});for await(const l of e){if(l instanceof f)throw new TypeError("Cannot send draft messages. Convert to MailMessage first or remove X-Unsent header.");if(r?.signal?.aborted){this.logger&&this.logger.warn("Batch send operation was aborted",{failed:g,processed:s,successful:o}),yield{errorMessages:["Send operation was aborted"],provider:t,successful:!1};return}s+=1;try{const i=await this.send(l);i.success&&i.data?(o+=1,this.logger&&this.logger.debug(`Email ${s} sent successfully`,{messageId:i.data.messageId}),yield{messageId:i.data.messageId,provider:i.data.provider??t,response:i.data.response,successful:!0,timestamp:i.data.timestamp}):(g+=1,this.logger&&this.logger.error(`Email ${s} send failed`,{error:i.error}),yield{errorMessages:h.extractErrorMessages(i.error),provider:t,successful:!1})}catch(i){g+=1,this.logger&&this.logger.error(`Email ${s} send failed with exception`,i),yield{errorMessages:h.extractErrorMessages(i),provider:t,successful:!1}}}this.logger&&this.logger.debug("Batch email send completed",{failureCount:g,processedCount:s,provider:t,successCount:o})}assertFeatureSupport(e){if(this.featureCheck==="off")return;const{supported:r,violations:t}=C(e,this.provider.features);if(r)return;const s=this.provider.name??"unknown",o=t.map(l=>l.field),g=t.map(l=>l.message);if(this.featureCheck==="warn"){this.logger&&this.logger.warn("Message uses capabilities the provider does not support",{fields:o,provider:s});return}return this.logger&&this.logger.error("Message rejected by capability guard",{fields:o,provider:s}),new m(s,`Provider does not support the following message fields: ${o.join(", ")}`,{code:"UNSUPPORTED_FEATURES",hint:g})}async buildDraftFromMessage(e){return this.logger&&this.logger.debug("Creating draft from MailMessage instance"),this.loggerInstance&&e.setLogger(this.loggerInstance),this.applyGlobalConfigToMessage(e),await e.build()}async buildDraftFromOptions(e){return this.logger&&this.logger.debug("Creating draft from email options",{subject:e.subject,to:Array.isArray(e.to)?e.to.length:1}),e}applyGlobalConfigToMessage(e){const r=this.globalConfig?.from;r&&!e.getFrom()&&e.from(r);const t=this.globalConfig?.replyTo;if(t&&!e.getReplyTo()&&e.replyTo(t),this.globalConfig?.headers){const s=d(this.globalConfig.headers);Object.entries(s).forEach(([o,g])=>{e.header(o,g)})}}applyGlobalConfig(e){if(!this.globalConfig)return e;const r={...e};if(!r.from&&this.globalConfig.from&&(r.from=this.globalConfig.from,this.logger&&this.logger.debug("Applied global from address",{from:this.globalConfig.from.email})),!r.replyTo&&this.globalConfig.replyTo&&(r.replyTo=this.globalConfig.replyTo,this.logger&&this.logger.debug("Applied global reply-to address",{replyTo:this.globalConfig.replyTo.email})),this.globalConfig.headers){const t=d(this.globalConfig.headers),s=r.headers?d(r.headers):{};r.headers={...t,...s},this.logger&&this.logger.debug("Merged global headers",{globalCount:Object.keys(t).length,messageCount:Object.keys(s).length})}return r}}const A=u((a,e)=>new h(a,e),"createMail");export{h as Mail,A as createMail};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var A=Object.defineProperty;var d=(n,e)=>A(n,"name",{value:e,configurable:!0});import{createRequire as b}from"node:module";import C from"ical-generator";import{readFileAsBuffer as u,detectMimeType as g,generateContentId as m}from"./detectMimeType-bo5oxfnt.js";import p from"../template-engines/html-to-text.js";import{c as E}from"./create-logger-BiWdqFNg.js";import{i as l}from"./headers-to-record-Qo124ImV.js";const T=b(import.meta.url),a=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,f=d(n=>{if(typeof a<"u"&&a.versions&&a.versions.node){const[e,t]=a.versions.node.split(".").map(Number);if(e>22||e===22&&t>=3||e===20&&t>=16)return a.getBuiltinModule(n)}return T(n)},"__cjs_getBuiltinModule"),{basename:c}=f("node:path"),{fileURLToPath:x}=f("node:url");var w=Object.defineProperty,y=d((n,e)=>w(n,"name",{value:e,configurable:!0}),"l");const o=y(n=>Array.isArray(n)?n.map(e=>typeof e=="string"?{email:e}:e):typeof n=="string"?[{email:n}]:[n],"normalizeAddresses");class M{static{d(this,"MailMessage")}static{y(this,"MailMessage")}fromAddress;toAddresses=[];ccAddresses=[];bccAddresses=[];subjectText="";textContent;textCharset="utf8";autoTextEnabled=!0;htmlContent;htmlCharset="utf8";dateValue;returnPathAddress;senderAddress;headers={};attachments=[];replyToAddress;priorityValue;tagsValue=[];signer;encrypter;logger;icalEventData;from(e){return this.fromAddress=typeof e=="string"?{email:e}:e,this}to(e){return this.toAddresses.length=0,this.toAddresses.push(...o(e)),this}cc(e){return this.ccAddresses.length=0,this.ccAddresses.push(...o(e)),this}bcc(e){return this.bccAddresses.length=0,this.bccAddresses.push(...o(e)),this}subject(e){return this.subjectText=e,this}text(e,t="utf8"){return this.textContent=e,this.textCharset=t,this}html(e,t="utf8"){return this.htmlContent=e,this.htmlCharset=t,this}header(e,t){return this.headers[e]=t,this}setHeaders(e){const t=l(e);return Object.assign(this.headers,t),this}async attachFromPath(e,t){try{const s=await u(e),i=t?.filename??(c(e)||"attachment"),r=t?.contentType??g(i);this.attachments.push({cid:t?.cid,content:s,contentDisposition:t?.contentDisposition??"attachment",contentType:r,encoding:t?.encoding,filename:i,headers:t?.headers}),this.logger&&this.logger.debug(`Attachment added from path: ${e}`,{contentType:r,filename:i})}catch(s){throw this.logger&&this.logger.error(`Failed to attach file from path: ${e}`,s),s}return this}attachData(e,t){const s=t.contentType??g(t.filename);return this.attachments.push({cid:t.cid,content:e,contentDisposition:t.contentDisposition??"attachment",contentType:s,encoding:t.encoding,filename:t.filename,headers:t.headers}),this.logger&&this.logger.debug("Attachment added from data",{contentType:s,filename:t.filename}),this}async embedFromPath(e,t){try{const s=await u(e),i=t?.filename??(c(e)||"inline"),r=t?.contentType??g(i),h=m(i);return this.attachments.push({cid:h,content:s,contentDisposition:"inline",contentType:r,filename:i}),this.logger&&this.logger.debug(`Inline attachment embedded from path: ${e}`,{cid:h,contentType:r,filename:i}),h}catch(s){throw this.logger&&this.logger.error(`Failed to embed file from path: ${e}`,s),s}}embedData(e,t,s){const i=s?.contentType??g(t),r=m(t);return this.attachments.push({cid:r,content:e,contentDisposition:"inline",contentType:i,filename:t}),this.logger&&this.logger.debug("Inline attachment embedded from data",{cid:r,contentType:i,filename:t}),r}replyTo(e){return this.replyToAddress=typeof e=="string"?{email:e}:e,this}date(e){return this.dateValue=typeof e=="string"?new Date(e):e,this.logger&&this.logger.debug("Date header set",{date:this.dateValue.toISOString()}),this}returnPath(e){return this.returnPathAddress=typeof e=="string"?{email:e}:e,this.logger&&this.logger.debug("Return-path address set",{returnPath:this.returnPathAddress.email}),this}sender(e){return this.senderAddress=typeof e=="string"?{email:e}:e,this.logger&&this.logger.debug("Sender address set",{sender:this.senderAddress.email}),this}addTo(e){return this.toAddresses.push(...o(e)),this}addCc(e){return this.ccAddresses.push(...o(e)),this}addBcc(e){return this.bccAddresses.push(...o(e)),this}addReplyTo(e){const t=Array.isArray(e)?e:[e];if(t.length>0){const s=t[0];this.replyToAddress=typeof s=="string"?{email:s}:s}return this}addFrom(e){const t=Array.isArray(e)?e:[e];if(t.length>0){const s=t[0];this.fromAddress=typeof s=="string"?{email:s}:s}return this}priority(e){return this.priorityValue=e,this}tags(e){return this.tagsValue=Array.isArray(e)?e:[e],this}sign(e){return this.signer=e,this.logger&&this.logger.debug("Email signer configured"),this}encrypt(e){return this.encrypter=e,this.logger&&this.logger.debug("Email encrypter configured"),this}setLogger(e){return this.logger=E("MailMessage",e),this}icalEvent(e,t){if(typeof e=="function"){const s=C();e(s),this.icalEventData={content:s.toString(),...t}}else this.icalEventData={content:e,...t};return this.logger&&this.logger.debug("Calendar event attached",{method:t?.method}),this}icalEventFromFile(e,t){const s=typeof e=="string"?e:x(e);return this.icalEventData={path:s,...t},this.logger&&this.logger.debug(`Calendar event attached from file: ${s}`,{method:t?.method}),this}icalEventFromUrl(e,t){return this.icalEventData={href:e,...t},this.logger&&this.logger.debug(`Calendar event attached from URL: ${e}`,{method:t?.method}),this}async view(e,t,s,i){try{const r=i?.autoText!==!1;this.autoTextEnabled=r,this.logger&&this.logger.debug("Rendering template",{autoText:r});const h=await e(t,s,i);this.html(h),r&&h&&this.tryAutoGenerateText(h),this.logger&&this.logger.debug("Template rendered successfully")}catch(r){throw this.logger&&this.logger.error("Failed to render template",r),new Error(`Failed to render template: ${r.message}`)}return this}async viewText(e,t,s,i){try{this.logger&&this.logger.debug("Rendering text template");const r=await e(t,s,i);if(typeof r=="string")this.text(r),this.logger&&this.logger.debug("Text template rendered successfully");else throw new TypeError("Text renderer must return a string")}catch(r){throw this.logger&&this.logger.error("Failed to render text template",r),new Error(`Failed to render text template: ${r.message}`)}return this}async build(){if(this.logger&&this.logger.debug("Building email message"),this.fromAddress||this.throwAndLogError("From address is required","Build failed: from address is required"),this.toAddresses.length===0&&this.throwAndLogError("At least one recipient is required","Build failed: at least one recipient is required"),this.subjectText||this.throwAndLogError("Subject is required","Build failed: subject is required"),this.htmlContent&&!this.textContent&&this.autoTextEnabled)try{this.textContent=p(this.htmlContent),this.logger&&this.logger.debug("Auto-generated text content from HTML")}catch{this.logger&&this.logger.debug("Failed to convert HTML to text; proceeding without text content.")}!this.textContent&&!this.htmlContent&&this.throwAndLogError("Either text or html content is required","Build failed: either text or html content is required");let e={from:this.fromAddress,html:this.htmlContent,subject:this.subjectText,text:this.textContent,to:this.toAddresses.length===1?this.toAddresses[0]:this.toAddresses};return this.ccAddresses.length>0&&(e.cc=this.ccAddresses.length===1?this.ccAddresses[0]:this.ccAddresses),this.bccAddresses.length>0&&(e.bcc=this.bccAddresses.length===1?this.bccAddresses[0]:this.bccAddresses),Object.keys(this.headers).length>0&&(e.headers=this.headers),this.attachments.length>0&&(e.attachments=this.attachments,this.logger&&this.logger.debug(`Email includes ${this.attachments.length} attachment(s)`)),this.replyToAddress&&(e.replyTo=this.replyToAddress),this.priorityValue&&(e.priority=this.priorityValue),this.tagsValue.length>0&&(e.tags=this.tagsValue),this.icalEventData&&(e.icalEvent=this.icalEventData,this.logger&&this.logger.debug("Email includes calendar event")),this.dateValue&&(e.headers={...l(e.headers??{}),Date:this.dateValue.toUTCString()}),this.returnPathAddress&&(e.headers={...l(e.headers??{}),"Return-Path":this.returnPathAddress.email}),this.senderAddress&&(e.headers={...l(e.headers??{}),Sender:this.senderAddress.email}),this.signer&&(this.logger&&this.logger.debug("Signing email message"),e=await this.signer.sign(e),this.logger&&this.logger.debug("Email message signed successfully")),this.encrypter&&(this.logger&&this.logger.debug("Encrypting email message"),e=await this.encrypter.encrypt(e),this.logger&&this.logger.debug("Email message encrypted successfully")),this.logger&&this.logger.debug("Email message built successfully",{bcc:this.bccAddresses.length,cc:this.ccAddresses.length,hasHtml:!!this.htmlContent,hasText:!!this.textContent,to:this.toAddresses.length}),e}getSubject(){return this.subjectText}getFrom(){return this.fromAddress}getTo(){return[...this.toAddresses]}getCc(){return[...this.ccAddresses]}getBcc(){return[...this.bccAddresses]}getReplyTo(){return this.replyToAddress}getSender(){return this.senderAddress}getReturnPath(){return this.returnPathAddress}getDate(){return this.dateValue}getPriority(){return this.priorityValue}getTextBody(){return this.textContent}getTextCharset(){return this.textCharset}getHtmlBody(){return this.htmlContent}getHtmlCharset(){return this.htmlCharset}getAttachments(){return[...this.attachments]}tryAutoGenerateText(e){try{const t=p(e);t&&!this.textContent&&this.text(t),this.logger&&this.logger.debug("Auto-generated text content from HTML template")}catch(t){this.logger&&this.logger.warn("Failed to auto-generate text from HTML template",t)}}throwAndLogError(e,t){const s=new Error(e);throw this.logger&&this.logger.error(t??e),s}}export{M as MailMessage,M as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var n=Object.defineProperty;var t=(i,r)=>n(i,"name",{value:r,configurable:!0});import a from"./EmailError-zm2ffVav.js";var p=Object.defineProperty,d=t((i,r)=>p(i,"name",{value:r,configurable:!0}),"s");class c extends a{static{t(this,"d")}static{d(this,"RequiredOptionError")}constructor(r,e){const s=Array.isArray(e)?`Missing required options: ${e.map(o=>`'${o}'`).join(", ")}`:`Missing required option: '${e}'`;super(r,s,{hint:Array.isArray(e)?`Please provide the following required options: ${e.map(o=>`'${o}'`).join(", ")}`:`Please provide the required option: '${e}'`}),this.name="RequiredOptionError"}}export{c as default};
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
var K=Object.defineProperty;var g=(s,e)=>K(s,"name",{value:e,configurable:!0});import{createRequire as U}from"node:module";import{B as S}from"./readFile-BAVMZg5e-C4whBIPd.js";import{fromBER as $,OctetString as T}from"asn1js";import{Certificate as j,EnvelopedData as z,EncryptedContentInfo as J,id_ContentType_Data as Q,RecipientInfo as W,KeyTransRecipientInfo as X,IssuerAndSerialNumber as Y,AlgorithmIdentifier as x,ContentInfo as Z,id_ContentType_EnvelopedData as ee}from"pkijs";const q=U(import.meta.url),h=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,H=g(s=>{if(typeof h<"u"&&h.versions&&h.versions.node){const[e,t]=h.versions.node.split(".").map(Number);if(e>22||e===22&&t>=3||e===20&&t>=16)return h.getBuiltinModule(s)}return q(s)},"__cjs_getBuiltinModule"),{randomBytes:I,createCipheriv:L,createPublicKey:G,publicEncrypt:V}=H("node:crypto");var te=Object.defineProperty,y=g((s,e)=>te(s,"name",{value:e,configurable:!0}),"l");const w=globalThis.Buffer!==void 0,N=y(s=>{const e=s.replaceAll(/-----BEGIN[^-]+-----/g,"").replaceAll(/-----END[^-]+-----/g,"").replaceAll(/\s/g,"");if(w)return Buffer.from(e,"base64");const t=atob(e),n=new Uint8Array(t.length);for(let r=0;r<t.length;r+=1)n[r]=t.charCodeAt(r);return n},"pemToDer"),R=y((s,e)=>{let t;if(w)t=Buffer.from(s).toString("base64");else{const r=new Uint8Array(s);let u="";const o=8192;for(let i=0;i<r.length;i+=o){const m=r.subarray(i,Math.min(i+o,r.length));u+=String.fromCharCode(...m)}t=btoa(u)}const n=t.match(/.{1,64}/g)??[];return`-----BEGIN ${e}-----
|
|
2
|
-
${n.join(`
|
|
3
|
-
`)}
|
|
4
|
-
-----END ${e}-----
|
|
5
|
-
`},"derToPem");class a{static{g(this,"SmimeEncrypter")}static{y(this,"SmimeEncrypter")}static collectRecipients(e){const t=[],n=y(r=>{if(!r)return;const u=Array.isArray(r)?r:[r];for(const o of u){const i=typeof o=="string"?o:o.email;i&&t.push(i)}},"extractEmails");return n(e.to),n(e.cc),n(e.bcc),[...new Set(t)]}static formatAddress(e){return typeof e=="string"?e:e.name?`"${e.name}" <${e.email}>`:e.email}static formatAddresses(e){return(Array.isArray(e)?e:[e]).map(t=>a.formatAddress(t)).join(", ")}options;constructor(e){this.options=e}async encrypt(e){const t=a.collectRecipients(e),n=[];if(typeof this.options.certificates=="string"){const c=await S(this.options.certificates,{encoding:"utf8"}),f=N(c),l=$(f);if(l.offset===-1)throw new Error("Failed to parse certificate: Invalid ASN.1 structure");n.push(new j({schema:l.result}))}else{const c=t.map(async f=>{const l=this.options.certificates[f];if(!l)throw new Error(`No certificate found for recipient: ${f}`);const E=await S(l,{encoding:"utf8"}),v=N(E),p=$(v);if(p.offset===-1)throw new Error(`Failed to parse certificate for ${f}: Invalid ASN.1 structure`);return new j({schema:p.result})});n.push(...await Promise.all(c))}const r=await this.buildMessage(e),u=new TextEncoder().encode(r),o=new z({version:0});o.encryptedContentInfo=new J({contentType:Q});const i=(this.options.algorithm??"aes-256-cbc").toLowerCase();if(i==="3des"||i==="des-ede3-cbc")throw new Error("3DES/DES-EDE3-CBC is deprecated and insecure (Sweet32 vulnerability). Please use AES-256-CBC, AES-192-CBC, or AES-128-CBC instead.");let m,d;switch(i){case"aes128":case"aes-128-cbc":{m="2.16.840.1.101.3.4.1.2",d=16;break}case"aes192":case"aes-192-cbc":{m="2.16.840.1.101.3.4.1.22",d=24;break}default:{m="2.16.840.1.101.3.4.1.42",d=32;break}}const A=I(d),D=w?A:new Uint8Array(A),C=I(16),P=w?C:new Uint8Array(C),B=L(`aes-${d*8}-cbc`,A,C),_=Buffer.from(u),k=[B.update(_),B.final()],b=Buffer.concat(k);o.encryptedContentInfo.encryptedContent=new T({valueHex:b.buffer.slice(b.byteOffset,b.byteOffset+b.byteLength)});const M=await Promise.all(n.map(async c=>{const f=c.toSchema().toBER(!1),l=R(f,"CERTIFICATE"),E=G(l),v=Buffer.from(D),p=V({key:E,padding:1},v);return new W({value:new X({encryptedKey:new T({valueHex:p.buffer.slice(p.byteOffset,p.byteOffset+p.byteLength)}),keyEncryptionAlgorithm:new x({algorithmId:"1.2.840.113549.1.1.1"}),rid:new Y({issuer:c.issuer,serialNumber:c.serialNumber}),version:0}),variant:0})}));o.recipientInfos.push(...M),o.encryptedContentInfo.contentEncryptionAlgorithm=new x({algorithmId:m,algorithmParams:new T({valueHex:P.buffer})});const O=new Z({content:o.toSchema(),contentType:ee}).toSchema().toBER(!1),F=R(O,"PKCS7");return{...e,headers:{...e.headers,"Content-Disposition":"attachment; filename=smime.p7m","Content-Transfer-Encoding":"base64","Content-Type":"application/pkcs7-mime; smime-type=enveloped-data; name=smime.p7m"},html:void 0,text:F}}async buildMessage(e){const t=[`From: ${a.formatAddress(e.from)}`,`To: ${a.formatAddresses(e.to)}`,...e.cc?[`Cc: ${a.formatAddresses(e.cc)}`]:[]];if(e.replyTo&&t.push(`Reply-To: ${a.formatAddress(e.replyTo)}`),t.push(`Subject: ${e.subject}`,"MIME-Version: 1.0"),e.headers)for(const[n,r]of Object.entries(e.headers))t.push(`${n}: ${r}`);return e.html?t.push("Content-Type: text/html; charset=utf-8"):e.text&&t.push("Content-Type: text/plain; charset=utf-8"),t.push(""),e.html?t.push(e.html):e.text&&t.push(e.text),t.join(`\r
|
|
6
|
-
`)}}const ae=y(s=>new a(s),"createSmimeEncrypter");export{a as SmimeEncrypter,ae as createSmimeEncrypter};
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
var L=Object.defineProperty;var g=(n,e)=>L(n,"name",{value:e,configurable:!0});import{createRequire as V}from"node:module";import{B as b}from"./readFile-BAVMZg5e-C4whBIPd.js";import{fromBER as B,ObjectIdentifier as Y,OctetString as E,UTCTime as Z}from"asn1js";import{Certificate as N,SignedData as ee,EncapsulatedContentInfo as te,id_ContentType_Data as D,SignerInfo as re,AlgorithmIdentifier as P,IssuerAndSerialNumber as ne,id_sha256 as se,SignedAndUnsignedAttributes as oe,Attribute as A,ContentInfo as ie,id_ContentType_SignedData as ae}from"pkijs";import{a as ce}from"./generate-boundary-Cx8nXYS0.js";const z=V(import.meta.url),u=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,J=g(n=>{if(typeof u<"u"&&u.versions&&u.versions.node){const[e,t]=u.versions.node.split(".").map(Number);if(e>22||e===22&&t>=3||e===20&&t>=16)return u.getBuiltinModule(n)}return z(n)},"__cjs_getBuiltinModule"),{createPrivateKey:x,createHash:Q,createSign:W,randomBytes:X}=J("node:crypto");var le=Object.defineProperty,y=g((n,e)=>le(n,"name",{value:e,configurable:!0}),"u");const pe="1.2.840.113549.1.9.3",ue="1.2.840.113549.1.9.4",fe="1.2.840.113549.1.9.5",me="1.2.840.113549.1.1.1",de={v1:1},he={v1:1},f=globalThis.Buffer!==void 0,M=y(n=>{const e=n.replaceAll(/-----BEGIN[^-]+-----/g,"").replaceAll(/-----END[^-]+-----/g,"").replaceAll(/\s/g,"");if(f)return Buffer.from(e,"base64");const t=atob(e),o=new Uint8Array(t.length);for(let r=0;r<t.length;r+=1)o[r]=t.codePointAt(r);return o},"pemToDer"),ge=y((n,e)=>{let t;if(f)t=Buffer.from(n).toString("base64");else{const r=new Uint8Array(n);let s="";const a=8192;for(let i=0;i<r.length;i+=a){const d=r.subarray(i,Math.min(i+a,r.length));s+=String.fromCharCode(...d)}t=btoa(s)}const o=t.match(/.{1,64}/g)??[];return`-----BEGIN ${e}-----
|
|
2
|
-
${o.join(`
|
|
3
|
-
`)}
|
|
4
|
-
-----END ${e}-----
|
|
5
|
-
`},"derToPem");class m{static{g(this,"SmimeSigner")}static{y(this,"SmimeSigner")}static formatAddress(e){return e.name?`"${e.name.replaceAll("\\","\\\\").replaceAll('"',String.raw`\"`)}" <${e.email}>`:e.email}options;constructor(e){this.options=e}async sign(e){const t=await b(this.options.certificate,{encoding:"utf8"}),o=await b(this.options.privateKey,{encoding:"utf8"}),r=M(t),s=B(r);if(s.offset===-1)throw new Error("Failed to parse certificate: Invalid ASN.1 structure");const a=new N({schema:s.result});let i;try{i=this.options.passphrase?x({key:o,passphrase:this.options.passphrase}):x(o)}catch(c){throw new Error(`Failed to parse private key: ${c.message}`)}const d=[];if(this.options.intermediateCerts){const c=this.options.intermediateCerts.map(async j=>{const q=await b(j,{encoding:"utf8"}),G=M(q),I=B(G);if(I.offset===-1)throw new Error(`Failed to parse intermediate certificate ${j}: Invalid ASN.1 structure`);return new N({schema:I.result})});d.push(...await Promise.all(c))}const v=this.buildMessage(e),$=new TextEncoder().encode(v),h=new ee({version:de.v1});h.encapContentInfo=new te({eContentType:D});const w=new re({digestAlgorithm:new P({algorithmId:se}),sid:new ne({issuer:a.issuer,serialNumber:a.serialNumber}),signatureAlgorithm:new P({algorithmId:me}),version:he.v1}),C=Q("sha256");C.update(f?Buffer.from($):$);const R=C.digest(),U=new Uint8Array(R),T=new oe({attributes:[new A({type:pe,values:[new Y({value:D})]}),new A({type:ue,values:[new E({valueHex:U.buffer.slice(0)})]}),new A({type:fe,values:[new Z({valueDate:new Date})]})]});w.signedAttrs=T;const S=T.toSchema().toBER(!1),k=f?Buffer.from(S):new Uint8Array(S),_=W("RSA-SHA256");_.update(k);const l=_.sign(i),O=f?l.buffer.slice(l.byteOffset,l.byteOffset+l.byteLength):l.buffer;w.signature=new E({valueHex:O}),h.signerInfos.push(w),h.certificates=[a,...d];const F=new ie({content:h.toSchema(),contentType:ae}).toSchema().toBER(!1),H=ge(F,"PKCS7"),p=`----_=_NextPart_${Date.now()}_${X(8).toString("hex")}`,K=[`Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha-256; boundary="${p}"`,"",`--${p}`,v,`--${p}`,"Content-Type: application/pkcs7-signature; name=smime.p7s","Content-Transfer-Encoding: base64","Content-Disposition: attachment; filename=smime.p7s","",H.split(`
|
|
6
|
-
`).filter(c=>c.trim()&&!c.includes("-----")).join(""),`--${p}--`].join(`\r
|
|
7
|
-
`);return{...e,headers:{...e.headers,"Content-Type":`multipart/signed; protocol="application/pkcs7-signature"; micalg=sha-256; boundary="${p}"`},html:void 0,text:K}}buildMessage(e){const t=[`From: ${m.formatAddress(e.from)}`,`To: ${this.formatAddresses(e.to)}`];if(e.cc&&t.push(`Cc: ${this.formatAddresses(e.cc)}`),e.replyTo&&t.push(`Reply-To: ${m.formatAddress(e.replyTo)}`),t.push(`Subject: ${e.subject}`,"MIME-Version: 1.0"),e.headers)for(const[a,i]of Object.entries(e.headers))t.push(`${a}: ${i}`);const o=!!e.text,r=!!e.html;let s;return o&&r?(s=ce(),t.push(`Content-Type: multipart/alternative; boundary="${s}"`)):r?t.push("Content-Type: text/html; charset=utf-8"):t.push("Content-Type: text/plain; charset=utf-8"),t.push(""),o&&r&&s?t.push(`--${s}`,"Content-Type: text/plain; charset=utf-8","",e.text,"",`--${s}`,"Content-Type: text/html; charset=utf-8","",e.html,"",`--${s}--`):o?t.push(e.text):r&&t.push(e.html),t.join(`\r
|
|
8
|
-
`)}formatAddresses(e){return(Array.isArray(e)?e:[e]).map(t=>m.formatAddress(t)).join(", ")}}const Ce=y(n=>new m(n),"createSmimeSigner");export{m as SmimeSigner,Ce as createSmimeSigner};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var t=Object.defineProperty;var r=(a,s)=>t(a,"name",{value:s,configurable:!0});var A=Object.defineProperty,e=r((a,s)=>A(a,"name",{value:s,configurable:!0}),"t");const o=e(a=>a.name?`${a.name} <${a.email}>`:a.email,"formatAddress"),i=e(a=>(Array.isArray(a)?a:[a]).map(s=>o(s)),"formatAddresses"),l=e(a=>{const s={email:a.email};return a.name&&(s.name=a.name),s},"formatSendGridAddress"),u=e(a=>(Array.isArray(a)?a:[a]).map(s=>l(s)),"formatSendGridAddresses"),c=e(a=>(Array.isArray(a)?a:[a]).map(s=>s.email),"formatAddressEmails"),f=e(a=>({email:a.email,...a.name&&{displayName:a.name}}),"formatAzureAddress"),j=e(a=>(Array.isArray(a)?a:[a]).map(s=>f(s)),"formatAzureAddresses"),n=e(a=>{const s={Email:a.email};return a.name&&(s.Name=a.name),s},"formatMailjetAddress"),P=e(a=>(Array.isArray(a)?a:[a]).map(s=>n(s)),"formatMailjetAddresses"),y=e((a,s="to")=>({email:a.email,...a.name&&{name:a.name},type:s}),"formatMandrillAddress"),z=e((a,s="to")=>(Array.isArray(a)?a:[a]).map(m=>y(m,s)),"formatMandrillAddresses"),d=e(a=>({address:a.email,...a.name&&{name:a.name}}),"formatPostalAddress"),G=e(a=>(Array.isArray(a)?a:[a]).map(s=>d(s)),"formatPostalAddresses"),S=e(a=>i(a),"formatMailpaceAddresses"),p=e(a=>d(a),"formatZeptomailAddress");e(a=>(Array.isArray(a)?a:[a]).map(s=>({email_address:p(s)})),"formatZeptomailAddresses");export{l as a,i as b,o as c,P as d,n as e,u as f,z as g,G as h,d as i,j,f as k,c as l,p as m,S as n};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var u=Object.defineProperty;var o=(e,r)=>u(e,"name",{value:r,configurable:!0});var c=Object.defineProperty,i=o((e,r)=>c(e,"name",{value:r,configurable:!0}),"n");const l=["attachments","batchSending","customHeaders","html","replyTo","scheduling","tagging","templates","tracking"],f=i(e=>typeof e=="function","isProviderFactory"),g=i(e=>e!==null&&typeof e=="object"&&"initialize"in e&&"isAvailable"in e&&"sendEmail"in e,"isProvider"),v=i(e=>{if(g(e))return e.features;if(f(e))try{return e({}).features}catch{return}},"resolveFeatures");function d(e){const r=e.map(t=>v(t)).filter(t=>t!==void 0),a={};if(r.length===0)return a;for(const t of l){const s=r.map(n=>n[t]);s.every(n=>n===!0)?a[t]=!0:s.every(n=>n===!1)&&(a[t]=!1)}return a}o(d,"l");i(d,"aggregateProviderFeatures");export{d as l};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var P=Object.defineProperty;var y=(i,r)=>P(i,"name",{value:r,configurable:!0});import{createRequire as I}from"node:module";import c from"./EmailError-zm2ffVav.js";import S from"./RequiredOptionError-CevW3u2K.js";import{s as _}from"./generate-message-id-D4uA8gkj.js";import{i as E}from"./headers-to-record-Qo124ImV.js";import{m as f}from"./make-request-CaT4d5oC.js";import{c as z,u as b,h as w,P as k}from"./provider-base-Cmzx6BTO.js";import{d as q}from"./validate-email-options-DPo3SgC0.js";import{defineProvider as K}from"./defineProvider-CtLH0VBE.js";import{f as p,a as B}from"./address-formatter-Cm_E_ZMa.js";const T=I(import.meta.url),m=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,$=y(i=>{if(typeof m<"u"&&m.versions&&m.versions.node){const[r,u]=m.versions.node.split(".").map(Number);if(r>22||r===22&&u>=3||r===20&&u>=16)return m.getBuiltinModule(i)}return T(i)},"__cjs_getBuiltinModule"),{Buffer:j}=$("node:buffer"),s="ahasend",C="https://api.ahasend.com",x=3e4,G=3,Q=K((i={})=>{if(!i.apiKey)throw new S(s,"apiKey");const r={apiKey:i.apiKey,debug:i.debug??!1,endpoint:i.endpoint??C,retries:i.retries??G,timeout:i.timeout??x,...i.logger&&{logger:i.logger}},u=new k,n=z(s,i.logger);return{features:{attachments:!0,batchSending:!0,customHeaders:!0,html:!0,replyTo:!0,scheduling:!1,tagging:!0,templates:!0,tracking:!0},async getEmail(e){try{if(!e)return{error:new c(s,"Email ID is required to retrieve email details"),success:!1};await this.initialize();const o={Authorization:`Bearer ${r.apiKey}`,"Content-Type":"application/json"};n.debug("Retrieving email details",{id:e});const t=await b(async()=>f(`${r.endpoint}/emails/${e}`,{headers:o,method:"GET",timeout:r.timeout}),r.retries);return t.success?(n.debug("Email details retrieved successfully"),{data:t.data?.body,success:!0}):(n.debug("API request failed when retrieving email",t.error),{error:new c(s,`Failed to retrieve email: ${t.error instanceof Error?t.error.message:"Unknown error"}`,{cause:t.error}),success:!1})}catch(o){return{error:w(s,"retrieve email",o,n),success:!1}}},async initialize(){await u.ensureInitialized(async()=>{if(!await this.isAvailable())throw new c(s,"AhaSend API not available or invalid API key");n.debug("Provider initialized successfully")},s)},async isAvailable(){try{return n.debug("Checking AhaSend API availability"),!!(await f(`${r.endpoint}/v2/ping`,{headers:{Authorization:`Bearer ${r.apiKey}`,"Content-Type":"application/json"},method:"GET",timeout:r.timeout})).success}catch(e){return n.debug("Error checking availability:",e),!1}},name:s,options:r,async sendEmail(e){try{const o=q(e);if(o.length>0)return{error:new c(s,`Invalid email options: ${o.join(", ")}`),success:!1};await this.initialize();const t={from:{email:e.from.email,name:e.from.name},subject:e.subject,to:p(e.to)};if(e.html&&(t.html=e.html),e.text&&(t.text=e.text),e.cc&&(t.cc=p(e.cc)),e.bcc&&(t.bcc=p(e.bcc)),e.replyTo&&(t.replyTo=B(e.replyTo)),e.templateId&&(t.templateId=e.templateId,e.templateVariables&&(t.templateVariables=e.templateVariables)),e.tags&&e.tags.length>0&&(t.tags=e.tags),e.headers){const a=E(e.headers);t.headers=a}e.attachments&&e.attachments.length>0&&(t.attachments=await Promise.all(e.attachments.map(async a=>{let d;if(a.content)if(typeof a.content=="string")d=a.content;else if(a.content instanceof Promise){const A=await a.content;d=j.from(A).toString("base64")}else d=a.content.toString("base64");else if(a.raw)d=typeof a.raw=="string"?a.raw:a.raw.toString("base64");else throw new c(s,`Attachment ${a.filename} has no content`);return{content:d,contentType:a.contentType??"application/octet-stream",filename:a.filename,...a.cid&&{cid:a.cid}}}))),n.debug("Sending email via AhaSend API",{subject:t.subject,to:t.to});const v={Authorization:`Bearer ${r.apiKey}`,"Content-Type":"application/json"},l=await b(async()=>f(`${r.endpoint}/send`,{headers:v,method:"POST",timeout:r.timeout},JSON.stringify(t)),r.retries);if(!l.success)return n.debug("API request failed when sending email",l.error),{error:l.error??new c(s,"Failed to send email"),success:!1};const g=l.data?.body,h=g?.messageId??g?.id??_();return n.debug("Email sent successfully",{messageId:h}),{data:{messageId:h,provider:s,response:l.data,sent:!0,timestamp:new Date},success:!0}}catch(o){return{error:w(s,"send email",o,n),success:!1}}},async validateCredentials(){return this.isAvailable()}}});export{Q as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var r=Object.defineProperty;var i=(e,t)=>r(e,"name",{value:t,configurable:!0});import{createRequire as m}from"node:module";import d from"./EmailError-zm2ffVav.js";const p=m(import.meta.url),a=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,f=i(e=>{if(typeof a<"u"&&a.versions&&a.versions.node){const[t,n]=a.versions.node.split(".").map(Number);if(t>22||t===22&&n>=3||t===20&&n>=16)return a.getBuiltinModule(e)}return p(e)},"__cjs_getBuiltinModule"),{Buffer:l}=f("node:buffer");var u=Object.defineProperty,o=i((e,t)=>u(e,"name",{value:t,configurable:!0}),"o");const c=o(async(e,t)=>{let n;if(e.content)if(typeof e.content=="string")n=e.content;else if(e.content instanceof Promise){const s=await e.content;n=l.from(s).toString("base64")}else n=e.content.toString("base64");else if(e.raw)n=typeof e.raw=="string"?e.raw:e.raw.toString("base64");else throw new d(t,`Attachment ${e.filename} has no content`);return n},"processAttachmentContent");o(async(e,t)=>({content:await c(e,t),contentType:e.contentType??"application/octet-stream",disposition:e.contentDisposition??"attachment",filename:e.filename,...e.cid&&{contentId:e.cid}}),"createStandardAttachment");const _=o(async(e,t)=>({content:await c(e,t),disposition:e.contentDisposition??"attachment",filename:e.filename,type:e.contentType??"application/octet-stream",...e.cid&&{content_id:e.cid}}),"createSendGridAttachment"),b=o(async(e,t)=>({Content:await c(e,t),ContentType:e.contentType??"application/octet-stream",Name:e.filename,...e.cid&&{ContentID:e.cid}}),"createPostmarkAttachment"),w=o(async(e,t,n)=>({content:await c(e,t),key:`attachment[${n}]`}),"createMailgunAttachment");export{w as a,b,_ as c};
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
var L=Object.defineProperty;var j=(m,a)=>L(m,"name",{value:a,configurable:!0});import{createRequire as V}from"node:module";import T from"./EmailError-zm2ffVav.js";import Q from"./RequiredOptionError-CevW3u2K.js";import{c as X}from"./create-logger-BiWdqFNg.js";import S from"../utils/format-email-address.js";import{i as J}from"./headers-to-record-Qo124ImV.js";import{m as Y}from"./make-request-CaT4d5oC.js";import{s as k,a as Z}from"./sanitize-header-wWav-Scu.js";import{d as ee}from"./validate-email-options-DPo3SgC0.js";import{defineProvider as te}from"./defineProvider-CtLH0VBE.js";const F=V(import.meta.url),$=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,G=j(m=>{if(typeof $<"u"&&$.versions&&$.versions.node){const[a,d]=$.versions.node.split(".").map(Number);if(a>22||a===22&&d>=3||a===20&&d>=16)return $.getBuiltinModule(m)}return F(m)},"__cjs_getBuiltinModule"),{randomUUID:q,createHash:P,createHmac:w}=G("node:crypto");var re=Object.defineProperty,p=j((m,a)=>re(m,"name",{value:a,configurable:!0}),"S");const se=globalThis.Buffer!==void 0,M=p(()=>{if(!se)throw new Error("Buffer is required for AWS SES provider");return globalThis.Buffer},"getBuffer"),y="aws-ses",C={apiVersion:"2010-12-01",maxAttempts:3,region:"us-east-1"},fe=te((m={})=>{const a={...C,...m},d=X("AWS-SES",m.logger),W=p((e,i,t,s,n)=>{const u=Object.keys(t).toSorted().map(c=>{const l=t[c];return l===void 0?"":`${encodeURIComponent(c)}=${encodeURIComponent(l)}`}).filter(Boolean).join("&"),r=`${Object.keys(s).toSorted().map(c=>`${c.toLowerCase()}:${s[c]}`).join(`
|
|
2
|
-
`)}
|
|
3
|
-
`,o=Object.keys(s).toSorted().map(c=>c.toLowerCase()).join(";"),g=P("sha256").update(n).digest("hex");return[e,i,u,r,o,g].join(`
|
|
4
|
-
`)},"createCanonicalRequest"),_=p((e,i,t)=>{const s=e.slice(0,8),n=P("sha256").update(t).digest("hex");return["AWS4-HMAC-SHA256",e,`${s}/${i}/ses/aws4_request`,n].join(`
|
|
5
|
-
`)},"createStringToSign"),K=p((e,i,t,s)=>{const n=i.slice(0,8),u=w("sha256",`AWS4${e}`).update(n).digest(),r=w("sha256",u).update(t).digest(),o=w("sha256",r).update("ses").digest(),g=w("sha256",o).update("aws4_request").digest();return w("sha256",g).update(s).digest("hex")},"calculateSignature"),O=p((e,i,t,s,n)=>{const u=i.slice(0,8),r=Object.keys(s).toSorted().map(o=>o.toLowerCase()).join(";");return[`AWS4-HMAC-SHA256 Credential=${e}/${u}/${t}/ses/aws4_request`,`SignedHeaders=${r}`,`Signature=${n}`].join(", ")},"createAuthHeader"),v=p(async(e,i)=>{if(!a.accessKeyId||!a.secretAccessKey)throw d.debug("Missing required credentials: accessKeyId or secretAccessKey"),new Q(y,["accessKeyId","secretAccessKey"]);try{const t=a.region||C.region,s=a.apiVersion||C.apiVersion,n=a.endpoint||`email.${t}.amazonaws.com`,u="/",r="POST";d.debug("Making request to AWS SES:",{action:e,host:n,region:t});const o=new URLSearchParams;o.append("Action",e),o.append("Version",s),Object.entries(i).forEach(([h,f])=>{f!=null&&o.append(h,String(f))});const g=o.toString();d.debug("Request body:",g);const c=new Date().toISOString().replaceAll(/[:-]|\.\d{3}/g,""),l={"Content-Length":M().byteLength(g).toString(),"Content-Type":"application/x-www-form-urlencoded",Host:n,"X-Amz-Date":c};a.sessionToken&&(l["X-Amz-Security-Token"]=a.sessionToken),d.debug("Request headers:",l);const A=W(r,u,{},l,g),B=_(c,t,A),z=K(a.secretAccessKey,c,t,B);l.Authorization=O(a.accessKeyId,c,t,l,z),d.debug("Making HTTPS request to:",`https://${n}${u}`);const D=`https://${n}${u}`,E=await Y(D,{headers:l,method:r},g);if(!E.success)throw E.error??new Error("AWS SES API request failed");const b=E.data?.body;if(!b)throw new Error("No response body from AWS SES");const H=E.data?.statusCode;d.debug("Response status:",H),d.debug("Response data:",b);const I=H;if(I&&I>=200&&I<300){const h={};if(e==="SendRawEmail"){const f=b.match(/<MessageId>(.*?)<\/MessageId>/);if(f){const[,N]=f;h.MessageId=N,d.debug("Extracted MessageId:",h.MessageId)}}else if(e==="GetSendQuota"){const f=b.match(/<Max24HourSend>(.*?)<\/Max24HourSend>/);f?.[1]&&(h.Max24HourSend=Number.parseFloat(f[1]),d.debug("Extracted Max24HourSend:",h.Max24HourSend))}return h}const x=b.match(/<Message>(.*?)<\/Message>/),R=x?x[1]:"Unknown AWS SES error";throw d.debug("AWS SES Error:",R),new Error(`AWS SES API Error: ${R}`)}catch(t){const s=t instanceof Error?t.message:String(t);throw d.debug("makeAwsRequest exception:",s),t instanceof Error?t:new Error(s)}},"makeAwsRequest"),U=p(e=>{const i=`----=${q().replaceAll("-","")}`,t=new Date().toUTCString(),s=e.from.email.includes("@")?e.from.email.split("@")[1]:"localhost",n=`<${q().replaceAll("-","")}@${s}>`,u=M();let r="";if(r+=`From: ${S(e.from)}\r
|
|
6
|
-
`,r+=Array.isArray(e.to)?`To: ${e.to.map(o=>S(o)).join(", ")}\r
|
|
7
|
-
`:`To: ${S(e.to)}\r
|
|
8
|
-
`,e.cc&&(r+=Array.isArray(e.cc)?`Cc: ${e.cc.map(o=>S(o)).join(", ")}\r
|
|
9
|
-
`:`Cc: ${S(e.cc)}\r
|
|
10
|
-
`),e.bcc&&(r+=Array.isArray(e.bcc)?`Bcc: ${e.bcc.map(o=>S(o)).join(", ")}\r
|
|
11
|
-
`:`Bcc: ${S(e.bcc)}\r
|
|
12
|
-
`),r+=`Subject: ${k(e.subject)}\r
|
|
13
|
-
`,r+=`Date: ${t}\r
|
|
14
|
-
`,r+=`Message-ID: ${n}\r
|
|
15
|
-
`,r+=`MIME-Version: 1.0\r
|
|
16
|
-
`,e.headers){const o=J(e.headers);for(const[g,c]of Object.entries(o)){const l=Z(g),A=k(c);r+=`${l}: ${A}\r
|
|
17
|
-
`}}return r+=`Content-Type: multipart/alternative; boundary="${i}"\r
|
|
18
|
-
\r
|
|
19
|
-
`,e.text&&(r+=`--${i}\r
|
|
20
|
-
`,r+=`Content-Type: text/plain; charset=UTF-8\r
|
|
21
|
-
`,r+=`Content-Transfer-Encoding: base64\r
|
|
22
|
-
\r
|
|
23
|
-
`,r+=`${u.from(e.text,"utf8").toString("base64")}\r
|
|
24
|
-
\r
|
|
25
|
-
`),e.html&&(r+=`--${i}\r
|
|
26
|
-
`,r+=`Content-Type: text/html; charset=UTF-8\r
|
|
27
|
-
`,r+=`Content-Transfer-Encoding: base64\r
|
|
28
|
-
\r
|
|
29
|
-
`,r+=`${u.from(e.html,"utf8").toString("base64")}\r
|
|
30
|
-
\r
|
|
31
|
-
`),r+=`--${i}--\r
|
|
32
|
-
`,r},"generateMimeMessage");return{features:{attachments:!1,batchSending:!1,customHeaders:!0,html:!0,replyTo:!1,scheduling:!1,tagging:!1,templates:!1,tracking:!1},getInstance:p(()=>{},"getInstance"),initialize(){d.debug("Initializing AWS SES provider with options:",{accessKeyId:a.accessKeyId?`***${a.accessKeyId.slice(-4)}`:void 0,endpoint:a.endpoint,region:a.region,secretAccessKey:a.secretAccessKey?"***":void 0})},async isAvailable(){try{return!!(await v("GetSendQuota",{})).Max24HourSend}catch{return!1}},name:y,options:a,async sendEmail(e){const i=p(t=>{const s=[];return t.attachments&&t.attachments.length>0&&s.push("attachments"),t.priority&&s.push("priority"),t.tags&&t.tags.length>0&&s.push("tags (use messageTags instead)"),t.replyTo&&s.push("replyTo"),s},"checkUnsupportedFields");try{const t=ee(e);if(t.length>0)throw new T(y,`Invalid email options: ${t.join(", ")}`);const s=i(e);if(s.length>0)throw new T(y,`Unsupported fields provided: ${s.join(", ")}. These fields are not supported by AWS SES Raw Email API and would be silently ignored.`);const n={};e.configurationSetName&&(n.ConfigurationSetName=e.configurationSetName),e.sourceArn&&(n.SourceArn=e.sourceArn),e.returnPath&&(n.ReturnPath=e.returnPath),e.returnPathArn&&(n.ReturnPathArn=e.returnPathArn),e.messageTags&&Object.keys(e.messageTags).length>0&&Object.entries(e.messageTags).forEach(([c,l],A)=>{n[`Tags.member.${A+1}.Name`]=c,n[`Tags.member.${A+1}.Value`]=l});const u=U(e),r=M().from(u).toString("base64");n["RawMessage.Data"]=r;const o=await v("SendRawEmail",n),g=o.MessageId;return!g||g.trim()===""?{error:new T(y,"AWS SES API returned a response without a MessageId. The email may not have been sent successfully."),success:!1}:{data:{messageId:g,provider:y,response:o,sent:!0,timestamp:new Date},success:!0}}catch(t){return{error:new T(y,`Failed to send email: ${t instanceof Error?t.message:String(t)}`,{cause:t instanceof Error?t:new Error(String(t))}),success:!1}}},async validateCredentials(){return this.isAvailable()}}});export{fe as default};
|