@primitivedotdev/sdk 1.18.0 → 1.20.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.
@@ -1,4 +1,4 @@
1
1
  import { $ as isPaymentFailedEvent, A as RawContentInline, B as InteractionEvent, C as ParsedData, D as ParsedStatus, E as ParsedError, F as ValidateEmailAuthResult, G as PaymentFailedEvent, H as InteractionX402Suffix, I as WebhookAttachment, J as WebhookEventType, K as PaymentSettledEvent, L as WebhookEvent, M as SpfResult, N as TlsReportAnalysis, O as RawContent, P as UnknownEvent, Q as isPaymentEvent, R as EMAIL_EVENT_TYPES, S as KnownWebhookEvent, T as ParsedDataFailed, U as PAYMENT_EVENT_TYPES, V as InteractionX402Event, W as PaymentEvent, X as isInteractionX402Event, Y as isEmailReceivedEvent, Z as isKnownWebhookEventType, _ as ForwardResultAttachmentAnalyzed, a as DkimSignature, b as ForwardVerdict, c as DmarcResult, d as EmailAuth, et as isPaymentSettledEvent, f as EmailReceivedEvent, g as ForwardResult, h as ForwardOriginalSender, i as DkimResult, j as RoutingDecision, k as RawContentDownloadOnly, l as EmailAddress, m as ForwardAnalysis, n as AuthVerdict, o as DmarcPolicy, p as EventType, q as WEBHOOK_EVENT_TYPES, r as BounceAnalysis, s as DmarcReportAnalysis, t as AuthConfidence, u as EmailAnalysis, v as ForwardResultAttachmentSkipped, w as ParsedDataComplete, x as ForwardVerification, y as ForwardResultInline, z as INTERACTION_EVENT_TYPES } from "../types-DVjBmOg0.js";
2
- import { _ as buildForwardSubject, a as RawEmailDecodeErrorCode, b as normalizeReceivedEmail, c as WebhookPayloadError, d as WebhookValidationErrorCode, f as WebhookVerificationError, g as ReceivedEmailThread, h as ReceivedEmailAddress, i as RawEmailDecodeError, l as WebhookPayloadErrorCode, m as ReceivedEmail, n as PrimitiveWebhookError, o as VERIFICATION_ERRORS, p as WebhookVerificationErrorCode, r as RAW_EMAIL_ERRORS, s as WebhookErrorCode, t as PAYLOAD_ERRORS, u as WebhookValidationError, v as buildReplySubject, x as parseHeaderAddress, y as formatAddress } from "../errors-BTHBQqJa.js";
3
- import { A as PRIMITIVE_SIGNATURE_HEADER, B as safeValidateEmailReceivedEvent, C as StandardWebhooksSignResult, D as LEGACY_CONFIRMED_HEADER, E as verifyStandardWebhooksSignature, F as GenerateDownloadTokenOptions, I as VerifyDownloadTokenOptions, L as VerifyDownloadTokenResult, M as VerifyOptions, N as signWebhookPayload, O as LEGACY_SIGNATURE_HEADER, P as verifyWebhookSignature, R as generateDownloadToken, S as STANDARD_WEBHOOK_TIMESTAMP_HEADER, T as signStandardWebhooksPayload, V as validateEmailReceivedEvent, _ as WEBHOOK_VERSION, a as WebhookHeaders, b as STANDARD_WEBHOOK_ID_HEADER, c as getDownloadTimeRemaining, d as handleWebhookEvent, f as isDownloadExpired, g as verifyRawEmailDownload, h as receive, i as WEBHOOK_EVENT_HEADER, j as SignResult, k as PRIMITIVE_CONFIRMED_HEADER, l as getEventHeader, m as parseWebhookEvent, n as HandleWebhookOptions, o as confirmedHeaders, p as isRawIncluded, r as ReceiveRequestOptions, s as decodeRawEmail, t as DecodeRawEmailOptions, u as handleWebhook, v as validateEmailAuth, w as StandardWebhooksVerifyOptions, x as STANDARD_WEBHOOK_SIGNATURE_HEADER, y as emailReceivedEventJsonSchema, z as verifyDownloadToken } from "../index-D2nlv8DS.js";
4
- export { AuthConfidence, AuthVerdict, BounceAnalysis, DecodeRawEmailOptions, DkimResult, DkimSignature, DmarcPolicy, DmarcReportAnalysis, DmarcResult, EMAIL_EVENT_TYPES, EmailAddress, EmailAnalysis, EmailAuth, EmailReceivedEvent, EventType, ForwardAnalysis, ForwardOriginalSender, ForwardResult, ForwardResultAttachmentAnalyzed, ForwardResultAttachmentSkipped, ForwardResultInline, ForwardVerdict, ForwardVerification, GenerateDownloadTokenOptions, HandleWebhookOptions, INTERACTION_EVENT_TYPES, InteractionEvent, InteractionX402Event, InteractionX402Suffix, KnownWebhookEvent, LEGACY_CONFIRMED_HEADER, LEGACY_SIGNATURE_HEADER, PAYLOAD_ERRORS, PAYMENT_EVENT_TYPES, PRIMITIVE_CONFIRMED_HEADER, PRIMITIVE_SIGNATURE_HEADER, ParsedData, ParsedDataComplete, ParsedDataFailed, ParsedError, ParsedStatus, PaymentEvent, PaymentFailedEvent, PaymentSettledEvent, PrimitiveWebhookError, RAW_EMAIL_ERRORS, RawContent, RawContentDownloadOnly, RawContentInline, RawEmailDecodeError, RawEmailDecodeErrorCode, ReceiveRequestOptions, ReceivedEmail, ReceivedEmailAddress, ReceivedEmailThread, RoutingDecision, STANDARD_WEBHOOK_ID_HEADER, STANDARD_WEBHOOK_SIGNATURE_HEADER, STANDARD_WEBHOOK_TIMESTAMP_HEADER, SignResult, SpfResult, StandardWebhooksSignResult, StandardWebhooksVerifyOptions, TlsReportAnalysis, UnknownEvent, VERIFICATION_ERRORS, ValidateEmailAuthResult, VerifyDownloadTokenOptions, VerifyDownloadTokenResult, VerifyOptions, WEBHOOK_EVENT_HEADER, WEBHOOK_EVENT_TYPES, WEBHOOK_VERSION, WebhookAttachment, WebhookErrorCode, WebhookEvent, WebhookEventType, WebhookHeaders, WebhookPayloadError, WebhookPayloadErrorCode, WebhookValidationError, WebhookValidationErrorCode, WebhookVerificationError, WebhookVerificationErrorCode, buildForwardSubject, buildReplySubject, confirmedHeaders, decodeRawEmail, emailReceivedEventJsonSchema, formatAddress, generateDownloadToken, getDownloadTimeRemaining, getEventHeader, handleWebhook, handleWebhookEvent, isDownloadExpired, isEmailReceivedEvent, isInteractionX402Event, isKnownWebhookEventType, isPaymentEvent, isPaymentFailedEvent, isPaymentSettledEvent, isRawIncluded, normalizeReceivedEmail, parseHeaderAddress, parseWebhookEvent, receive, safeValidateEmailReceivedEvent, signStandardWebhooksPayload, signWebhookPayload, validateEmailAuth, validateEmailReceivedEvent, verifyDownloadToken, verifyRawEmailDownload, verifyStandardWebhooksSignature, verifyWebhookSignature };
2
+ import { C as buildReplySubject, E as parseHeaderAddress, S as buildForwardSubject, T as normalizeReceivedEmail, _ as isTrustedSender, a as RawEmailDecodeErrorCode, b as ReceivedEmailAddress, c as WebhookPayloadError, d as WebhookValidationErrorCode, f as WebhookVerificationError, g as TrustedSenderResult, h as TrustedSenderOptions, i as RawEmailDecodeError, l as WebhookPayloadErrorCode, m as TrustReason, n as PrimitiveWebhookError, o as VERIFICATION_ERRORS, p as WebhookVerificationErrorCode, r as RAW_EMAIL_ERRORS, s as WebhookErrorCode, t as PAYLOAD_ERRORS, u as WebhookValidationError, v as validateEmailAuth, w as formatAddress, x as ReceivedEmailThread, y as ReceivedEmail } from "../errors-DAHv2kWU.js";
3
+ import { A as SignResult, B as validateEmailReceivedEvent, C as StandardWebhooksVerifyOptions, D as LEGACY_SIGNATURE_HEADER, E as LEGACY_CONFIRMED_HEADER, F as VerifyDownloadTokenOptions, I as VerifyDownloadTokenResult, L as generateDownloadToken, M as signWebhookPayload, N as verifyWebhookSignature, O as PRIMITIVE_CONFIRMED_HEADER, P as GenerateDownloadTokenOptions, R as verifyDownloadToken, S as StandardWebhooksSignResult, T as verifyStandardWebhooksSignature, _ as WEBHOOK_VERSION, a as WebhookHeaders, b as STANDARD_WEBHOOK_SIGNATURE_HEADER, c as getDownloadTimeRemaining, d as handleWebhookEvent, f as isDownloadExpired, g as verifyRawEmailDownload, h as receive, i as WEBHOOK_EVENT_HEADER, j as VerifyOptions, k as PRIMITIVE_SIGNATURE_HEADER, l as getEventHeader, m as parseWebhookEvent, n as HandleWebhookOptions, o as confirmedHeaders, p as isRawIncluded, r as ReceiveRequestOptions, s as decodeRawEmail, t as DecodeRawEmailOptions, u as handleWebhook, v as emailReceivedEventJsonSchema, w as signStandardWebhooksPayload, x as STANDARD_WEBHOOK_TIMESTAMP_HEADER, y as STANDARD_WEBHOOK_ID_HEADER, z as safeValidateEmailReceivedEvent } from "../index-DJeUuGUn.js";
4
+ export { AuthConfidence, AuthVerdict, BounceAnalysis, DecodeRawEmailOptions, DkimResult, DkimSignature, DmarcPolicy, DmarcReportAnalysis, DmarcResult, EMAIL_EVENT_TYPES, EmailAddress, EmailAnalysis, EmailAuth, EmailReceivedEvent, EventType, ForwardAnalysis, ForwardOriginalSender, ForwardResult, ForwardResultAttachmentAnalyzed, ForwardResultAttachmentSkipped, ForwardResultInline, ForwardVerdict, ForwardVerification, GenerateDownloadTokenOptions, HandleWebhookOptions, INTERACTION_EVENT_TYPES, InteractionEvent, InteractionX402Event, InteractionX402Suffix, KnownWebhookEvent, LEGACY_CONFIRMED_HEADER, LEGACY_SIGNATURE_HEADER, PAYLOAD_ERRORS, PAYMENT_EVENT_TYPES, PRIMITIVE_CONFIRMED_HEADER, PRIMITIVE_SIGNATURE_HEADER, ParsedData, ParsedDataComplete, ParsedDataFailed, ParsedError, ParsedStatus, PaymentEvent, PaymentFailedEvent, PaymentSettledEvent, PrimitiveWebhookError, RAW_EMAIL_ERRORS, RawContent, RawContentDownloadOnly, RawContentInline, RawEmailDecodeError, RawEmailDecodeErrorCode, ReceiveRequestOptions, ReceivedEmail, ReceivedEmailAddress, ReceivedEmailThread, RoutingDecision, STANDARD_WEBHOOK_ID_HEADER, STANDARD_WEBHOOK_SIGNATURE_HEADER, STANDARD_WEBHOOK_TIMESTAMP_HEADER, SignResult, SpfResult, StandardWebhooksSignResult, StandardWebhooksVerifyOptions, TlsReportAnalysis, TrustReason, TrustedSenderOptions, TrustedSenderResult, UnknownEvent, VERIFICATION_ERRORS, ValidateEmailAuthResult, VerifyDownloadTokenOptions, VerifyDownloadTokenResult, VerifyOptions, WEBHOOK_EVENT_HEADER, WEBHOOK_EVENT_TYPES, WEBHOOK_VERSION, WebhookAttachment, WebhookErrorCode, WebhookEvent, WebhookEventType, WebhookHeaders, WebhookPayloadError, WebhookPayloadErrorCode, WebhookValidationError, WebhookValidationErrorCode, WebhookVerificationError, WebhookVerificationErrorCode, buildForwardSubject, buildReplySubject, confirmedHeaders, decodeRawEmail, emailReceivedEventJsonSchema, formatAddress, generateDownloadToken, getDownloadTimeRemaining, getEventHeader, handleWebhook, handleWebhookEvent, isDownloadExpired, isEmailReceivedEvent, isInteractionX402Event, isKnownWebhookEventType, isPaymentEvent, isPaymentFailedEvent, isPaymentSettledEvent, isRawIncluded, isTrustedSender, normalizeReceivedEmail, parseHeaderAddress, parseWebhookEvent, receive, safeValidateEmailReceivedEvent, signStandardWebhooksPayload, signWebhookPayload, validateEmailAuth, validateEmailReceivedEvent, verifyDownloadToken, verifyRawEmailDownload, verifyStandardWebhooksSignature, verifyWebhookSignature };
@@ -1,3 +1,3 @@
1
- import { a as VERIFICATION_ERRORS, c as WebhookVerificationError, d as formatAddress, f as normalizeReceivedEmail, i as RawEmailDecodeError, l as buildForwardSubject, n as PrimitiveWebhookError, o as WebhookPayloadError, p as parseHeaderAddress, r as RAW_EMAIL_ERRORS, s as WebhookValidationError, t as PAYLOAD_ERRORS, u as buildReplySubject } from "../errors-BPJGp9I6.js";
2
- import { A as LEGACY_CONFIRMED_HEADER, B as isEmailReceivedEvent, C as SpfResult, D as STANDARD_WEBHOOK_TIMESTAMP_HEADER, E as STANDARD_WEBHOOK_SIGNATURE_HEADER, F as verifyWebhookSignature, G as isPaymentSettledEvent, H as isKnownWebhookEventType, I as EMAIL_EVENT_TYPES, J as safeValidateEmailReceivedEvent, K as generateDownloadToken, L as INTERACTION_EVENT_TYPES, M as PRIMITIVE_CONFIRMED_HEADER, N as PRIMITIVE_SIGNATURE_HEADER, O as signStandardWebhooksPayload, P as signWebhookPayload, R as PAYMENT_EVENT_TYPES, S as ParsedStatus, T as STANDARD_WEBHOOK_ID_HEADER, U as isPaymentEvent, V as isInteractionX402Event, W as isPaymentFailedEvent, Y as validateEmailReceivedEvent, _ as DkimResult, a as getEventHeader, b as EventType, c as isDownloadExpired, d as receive, f as verifyRawEmailDownload, g as AuthVerdict, h as AuthConfidence, i as getDownloadTimeRemaining, j as LEGACY_SIGNATURE_HEADER, k as verifyStandardWebhooksSignature, l as isRawIncluded, m as validateEmailAuth, n as confirmedHeaders, o as handleWebhook, p as WEBHOOK_VERSION, q as verifyDownloadToken, r as decodeRawEmail, s as handleWebhookEvent, t as WEBHOOK_EVENT_HEADER, u as parseWebhookEvent, v as DmarcPolicy, w as emailReceivedEventJsonSchema, x as ForwardVerdict, y as DmarcResult, z as WEBHOOK_EVENT_TYPES } from "../webhook-BekIm0Uf.js";
3
- export { AuthConfidence, AuthVerdict, DkimResult, DmarcPolicy, DmarcResult, EMAIL_EVENT_TYPES, EventType, ForwardVerdict, INTERACTION_EVENT_TYPES, LEGACY_CONFIRMED_HEADER, LEGACY_SIGNATURE_HEADER, PAYLOAD_ERRORS, PAYMENT_EVENT_TYPES, PRIMITIVE_CONFIRMED_HEADER, PRIMITIVE_SIGNATURE_HEADER, ParsedStatus, PrimitiveWebhookError, RAW_EMAIL_ERRORS, RawEmailDecodeError, STANDARD_WEBHOOK_ID_HEADER, STANDARD_WEBHOOK_SIGNATURE_HEADER, STANDARD_WEBHOOK_TIMESTAMP_HEADER, SpfResult, VERIFICATION_ERRORS, WEBHOOK_EVENT_HEADER, WEBHOOK_EVENT_TYPES, WEBHOOK_VERSION, WebhookPayloadError, WebhookValidationError, WebhookVerificationError, buildForwardSubject, buildReplySubject, confirmedHeaders, decodeRawEmail, emailReceivedEventJsonSchema, formatAddress, generateDownloadToken, getDownloadTimeRemaining, getEventHeader, handleWebhook, handleWebhookEvent, isDownloadExpired, isEmailReceivedEvent, isInteractionX402Event, isKnownWebhookEventType, isPaymentEvent, isPaymentFailedEvent, isPaymentSettledEvent, isRawIncluded, normalizeReceivedEmail, parseHeaderAddress, parseWebhookEvent, receive, safeValidateEmailReceivedEvent, signStandardWebhooksPayload, signWebhookPayload, validateEmailAuth, validateEmailReceivedEvent, verifyDownloadToken, verifyRawEmailDownload, verifyStandardWebhooksSignature, verifyWebhookSignature };
1
+ import { C as normalizeReceivedEmail, S as formatAddress, _ as ForwardVerdict, a as VERIFICATION_ERRORS, b as buildForwardSubject, c as WebhookVerificationError, d as AuthConfidence, f as AuthVerdict, g as EventType, h as DmarcResult, i as RawEmailDecodeError, l as isTrustedSender, m as DmarcPolicy, n as PrimitiveWebhookError, o as WebhookPayloadError, p as DkimResult, r as RAW_EMAIL_ERRORS, s as WebhookValidationError, t as PAYLOAD_ERRORS, u as validateEmailAuth, v as ParsedStatus, w as parseHeaderAddress, x as buildReplySubject, y as SpfResult } from "../errors-D6WjisrD.js";
2
+ import { A as isEmailReceivedEvent, C as PRIMITIVE_SIGNATURE_HEADER, D as INTERACTION_EVENT_TYPES, E as EMAIL_EVENT_TYPES, F as isPaymentSettledEvent, I as generateDownloadToken, L as verifyDownloadToken, M as isKnownWebhookEventType, N as isPaymentEvent, O as PAYMENT_EVENT_TYPES, P as isPaymentFailedEvent, R as safeValidateEmailReceivedEvent, S as PRIMITIVE_CONFIRMED_HEADER, T as verifyWebhookSignature, _ as STANDARD_WEBHOOK_TIMESTAMP_HEADER, a as getEventHeader, b as LEGACY_CONFIRMED_HEADER, c as isDownloadExpired, d as receive, f as verifyRawEmailDownload, g as STANDARD_WEBHOOK_SIGNATURE_HEADER, h as STANDARD_WEBHOOK_ID_HEADER, i as getDownloadTimeRemaining, j as isInteractionX402Event, k as WEBHOOK_EVENT_TYPES, l as isRawIncluded, m as emailReceivedEventJsonSchema, n as confirmedHeaders, o as handleWebhook, p as WEBHOOK_VERSION, r as decodeRawEmail, s as handleWebhookEvent, t as WEBHOOK_EVENT_HEADER, u as parseWebhookEvent, v as signStandardWebhooksPayload, w as signWebhookPayload, x as LEGACY_SIGNATURE_HEADER, y as verifyStandardWebhooksSignature, z as validateEmailReceivedEvent } from "../webhook-1cz088XC.js";
3
+ export { AuthConfidence, AuthVerdict, DkimResult, DmarcPolicy, DmarcResult, EMAIL_EVENT_TYPES, EventType, ForwardVerdict, INTERACTION_EVENT_TYPES, LEGACY_CONFIRMED_HEADER, LEGACY_SIGNATURE_HEADER, PAYLOAD_ERRORS, PAYMENT_EVENT_TYPES, PRIMITIVE_CONFIRMED_HEADER, PRIMITIVE_SIGNATURE_HEADER, ParsedStatus, PrimitiveWebhookError, RAW_EMAIL_ERRORS, RawEmailDecodeError, STANDARD_WEBHOOK_ID_HEADER, STANDARD_WEBHOOK_SIGNATURE_HEADER, STANDARD_WEBHOOK_TIMESTAMP_HEADER, SpfResult, VERIFICATION_ERRORS, WEBHOOK_EVENT_HEADER, WEBHOOK_EVENT_TYPES, WEBHOOK_VERSION, WebhookPayloadError, WebhookValidationError, WebhookVerificationError, buildForwardSubject, buildReplySubject, confirmedHeaders, decodeRawEmail, emailReceivedEventJsonSchema, formatAddress, generateDownloadToken, getDownloadTimeRemaining, getEventHeader, handleWebhook, handleWebhookEvent, isDownloadExpired, isEmailReceivedEvent, isInteractionX402Event, isKnownWebhookEventType, isPaymentEvent, isPaymentFailedEvent, isPaymentSettledEvent, isRawIncluded, isTrustedSender, normalizeReceivedEmail, parseHeaderAddress, parseWebhookEvent, receive, safeValidateEmailReceivedEvent, signStandardWebhooksPayload, signWebhookPayload, validateEmailAuth, validateEmailReceivedEvent, verifyDownloadToken, verifyRawEmailDownload, verifyStandardWebhooksSignature, verifyWebhookSignature };
@@ -1,4 +1,4 @@
1
- import { c as WebhookVerificationError, f as normalizeReceivedEmail, i as RawEmailDecodeError, o as WebhookPayloadError, s as WebhookValidationError } from "./errors-BPJGp9I6.js";
1
+ import { C as normalizeReceivedEmail, c as WebhookVerificationError, i as RawEmailDecodeError, o as WebhookPayloadError, s as WebhookValidationError } from "./errors-D6WjisrD.js";
2
2
  import { createHash, createHmac, timingSafeEqual } from "node:crypto";
3
3
  //#region src/generated/email-received-event.validator.generated.ts
4
4
  /**
@@ -10026,256 +10026,6 @@ const emailReceivedEventJsonSchema = {
10026
10026
  }
10027
10027
  };
10028
10028
  //#endregion
10029
- //#region src/types.ts
10030
- const EventType = {
10031
- EmailReceived: "email.received",
10032
- EmailBounced: "email.bounced",
10033
- EmailTlsReport: "email.tls_report",
10034
- EmailDmarcReport: "email.dmarc_report",
10035
- EmailDmarcFailure: "email.dmarc_failure"
10036
- };
10037
- const ParsedStatus = {
10038
- Complete: "complete",
10039
- Failed: "failed"
10040
- };
10041
- const ForwardVerdict = {
10042
- Legit: "legit",
10043
- Unknown: "unknown"
10044
- };
10045
- const SpfResult = {
10046
- Pass: "pass",
10047
- Fail: "fail",
10048
- Softfail: "softfail",
10049
- Neutral: "neutral",
10050
- None: "none",
10051
- Temperror: "temperror",
10052
- Permerror: "permerror"
10053
- };
10054
- const DmarcResult = {
10055
- Pass: "pass",
10056
- Fail: "fail",
10057
- None: "none",
10058
- Temperror: "temperror",
10059
- Permerror: "permerror"
10060
- };
10061
- const DmarcPolicy = {
10062
- Reject: "reject",
10063
- Quarantine: "quarantine",
10064
- None: "none"
10065
- };
10066
- const DkimResult = {
10067
- Pass: "pass",
10068
- Fail: "fail",
10069
- Temperror: "temperror",
10070
- Permerror: "permerror"
10071
- };
10072
- const AuthConfidence = {
10073
- High: "high",
10074
- Medium: "medium",
10075
- Low: "low"
10076
- };
10077
- const AuthVerdict = {
10078
- Legit: "legit",
10079
- Suspicious: "suspicious",
10080
- Unknown: "unknown"
10081
- };
10082
- //#endregion
10083
- //#region src/webhook/auth.ts
10084
- /**
10085
- * Minimum DKIM key size considered acceptable.
10086
- *
10087
- * 1024-bit RSA keys are cryptographically weak by modern standards (NIST
10088
- * deprecated them in 2013), but they remain extremely common in email due to:
10089
- * - DNS TXT record size limits (255 bytes per string)
10090
- * - Legacy infrastructure constraints
10091
- * - Major ESPs like Amazon SES and Resend still use 1024-bit keys
10092
- *
10093
- * We flag keys <1024 bits as weak (these are truly dangerous), while accepting
10094
- * >=1024 bits to avoid false positives against legitimate senders. For maximum
10095
- * security, domain owners should use 2048+ bit keys where possible.
10096
- */
10097
- const MIN_SECURE_KEY_BITS = 1024;
10098
- /**
10099
- * Validate email authentication and compute a verdict.
10100
- *
10101
- * This function analyzes SPF, DKIM, and DMARC results to determine
10102
- * whether an email is likely authentic ("legit"), potentially spoofed
10103
- * ("suspicious"), or indeterminate ("unknown").
10104
- *
10105
- * ## Verdict Logic
10106
- *
10107
- * **Legit (high confidence):**
10108
- * - DMARC pass with DKIM alignment (cryptographic proof of authenticity)
10109
- *
10110
- * **Legit (medium confidence):**
10111
- * - DMARC pass with SPF alignment only (no DKIM)
10112
- * - Note: SPF can break through forwarding, but DMARC pass is still meaningful
10113
- *
10114
- * **Suspicious (high confidence):**
10115
- * - DMARC fail when domain has `reject` or `quarantine` policy
10116
- * - The domain owner explicitly says to distrust failing emails
10117
- * - SPF explicitly fails (IP not authorized by sender)
10118
- *
10119
- * **Suspicious (low confidence):**
10120
- * - DMARC fail when domain has `none` policy (monitoring mode)
10121
- * - No DMARC record but SPF/DKIM fail
10122
- *
10123
- * **Unknown:**
10124
- * - No DMARC record and no clear pass/fail
10125
- * - Temporary errors during authentication
10126
- * - No authentication data available
10127
- *
10128
- * @param auth - Email authentication results from the webhook
10129
- * @returns Verdict, confidence level, and explanatory reasons
10130
- *
10131
- * @example
10132
- * ```typescript
10133
- * const result = validateEmailAuth({
10134
- * spf: 'pass',
10135
- * dmarc: 'pass',
10136
- * dmarcPolicy: 'reject',
10137
- * dmarcFromDomain: 'example.com',
10138
- * dmarcSpfAligned: true,
10139
- * dmarcDkimAligned: true,
10140
- * dmarcSpfStrict: false,
10141
- * dmarcDkimStrict: false,
10142
- * dkimSignatures: [{
10143
- * domain: 'example.com',
10144
- * selector: 'default',
10145
- * result: 'pass',
10146
- * aligned: true,
10147
- * keyBits: 2048,
10148
- * algo: 'rsa-sha256',
10149
- * }],
10150
- * });
10151
- *
10152
- * // result.verdict === 'legit'
10153
- * // result.confidence === 'high'
10154
- * // result.reasons === ['DMARC passed with DKIM alignment']
10155
- * ```
10156
- */
10157
- function validateEmailAuth(auth) {
10158
- const reasons = [];
10159
- let verdict;
10160
- let confidence;
10161
- if (auth.dmarc === "temperror" || auth.dmarc === "permerror") return {
10162
- verdict: "unknown",
10163
- confidence: "low",
10164
- reasons: [`DMARC verification error (${auth.dmarc})`, "Cannot determine email authenticity due to DNS or policy errors"]
10165
- };
10166
- if (auth.spf === "temperror" || auth.spf === "permerror") reasons.push(`SPF verification error (${auth.spf})`);
10167
- const weakKeySignatures = auth.dkimSignatures.filter((sig) => sig.keyBits != null && sig.keyBits < MIN_SECURE_KEY_BITS);
10168
- if (weakKeySignatures.length > 0) for (const sig of weakKeySignatures) reasons.push(`Weak DKIM key (${sig.keyBits} bits) for ${sig.domain} - minimum ${MIN_SECURE_KEY_BITS} bits recommended`);
10169
- if (auth.dmarc === "pass") {
10170
- const alignedSigs = auth.dkimSignatures.filter((sig) => sig.result === "pass" && sig.aligned);
10171
- if (auth.dmarcDkimAligned && alignedSigs.length > 0) {
10172
- const domains = alignedSigs.map((sig) => sig.domain).join(", ");
10173
- reasons.unshift(`DMARC passed with DKIM alignment (${domains})`);
10174
- verdict = "legit";
10175
- confidence = weakKeySignatures.length > 0 ? "medium" : "high";
10176
- return {
10177
- verdict,
10178
- confidence,
10179
- reasons
10180
- };
10181
- }
10182
- if (auth.dmarcSpfAligned && auth.spf === "pass") {
10183
- reasons.unshift("DMARC passed with SPF alignment");
10184
- reasons.push("No aligned DKIM signature (SPF can break through forwarding)");
10185
- return {
10186
- verdict: "legit",
10187
- confidence: "medium",
10188
- reasons
10189
- };
10190
- }
10191
- reasons.unshift("DMARC passed");
10192
- return {
10193
- verdict: "legit",
10194
- confidence: "medium",
10195
- reasons
10196
- };
10197
- }
10198
- if (auth.dmarc === "fail") {
10199
- if (auth.dmarcPolicy === "reject") {
10200
- reasons.unshift("DMARC failed and domain has reject policy");
10201
- reasons.push("The sender's domain explicitly rejects emails that fail authentication");
10202
- return {
10203
- verdict: "suspicious",
10204
- confidence: "high",
10205
- reasons
10206
- };
10207
- }
10208
- if (auth.dmarcPolicy === "quarantine") {
10209
- reasons.unshift("DMARC failed and domain has quarantine policy");
10210
- reasons.push("The sender's domain marks failing emails as suspicious");
10211
- return {
10212
- verdict: "suspicious",
10213
- confidence: "high",
10214
- reasons
10215
- };
10216
- }
10217
- reasons.unshift("DMARC failed (domain is in monitoring mode)");
10218
- if (auth.spf === "fail") {
10219
- reasons.push("SPF failed - sending IP not authorized");
10220
- return {
10221
- verdict: "suspicious",
10222
- confidence: "medium",
10223
- reasons
10224
- };
10225
- }
10226
- return {
10227
- verdict: "suspicious",
10228
- confidence: "low",
10229
- reasons
10230
- };
10231
- }
10232
- if (auth.dmarc === "none") {
10233
- if (auth.spf === "fail") {
10234
- reasons.push("No DMARC record for sender domain");
10235
- reasons.push("SPF failed - sending IP not authorized");
10236
- return {
10237
- verdict: "suspicious",
10238
- confidence: "medium",
10239
- reasons
10240
- };
10241
- }
10242
- const passingDkim = auth.dkimSignatures.filter((sig) => sig.result === "pass");
10243
- if (passingDkim.length > 0) {
10244
- const domains = passingDkim.map((sig) => sig.domain).join(", ");
10245
- reasons.push("No DMARC record for sender domain");
10246
- reasons.push(`DKIM verified for: ${domains}`);
10247
- if (auth.spf === "pass") reasons.push("SPF passed");
10248
- return {
10249
- verdict: "unknown",
10250
- confidence: "low",
10251
- reasons
10252
- };
10253
- }
10254
- if (auth.spf === "pass") {
10255
- reasons.push("No DMARC record for sender domain");
10256
- reasons.push("No DKIM signatures present");
10257
- reasons.push("SPF passed (but SPF alone is weak authentication)");
10258
- return {
10259
- verdict: "unknown",
10260
- confidence: "low",
10261
- reasons
10262
- };
10263
- }
10264
- reasons.push("No DMARC record for sender domain");
10265
- reasons.push("No valid authentication found");
10266
- return {
10267
- verdict: "unknown",
10268
- confidence: "low",
10269
- reasons
10270
- };
10271
- }
10272
- return {
10273
- verdict: "unknown",
10274
- confidence: "low",
10275
- reasons: ["Unable to determine email authenticity"]
10276
- };
10277
- }
10278
- //#endregion
10279
10029
  //#region src/webhook/version.ts
10280
10030
  /**
10281
10031
  * Webhook API Version
@@ -10749,4 +10499,4 @@ function verifyRawEmailDownload(downloaded, event) {
10749
10499
  return buffer;
10750
10500
  }
10751
10501
  //#endregion
10752
- export { LEGACY_CONFIRMED_HEADER as A, isEmailReceivedEvent as B, SpfResult as C, STANDARD_WEBHOOK_TIMESTAMP_HEADER as D, STANDARD_WEBHOOK_SIGNATURE_HEADER as E, verifyWebhookSignature as F, isPaymentSettledEvent as G, isKnownWebhookEventType as H, EMAIL_EVENT_TYPES as I, safeValidateEmailReceivedEvent as J, generateDownloadToken as K, INTERACTION_EVENT_TYPES as L, PRIMITIVE_CONFIRMED_HEADER as M, PRIMITIVE_SIGNATURE_HEADER as N, signStandardWebhooksPayload as O, signWebhookPayload as P, PAYMENT_EVENT_TYPES as R, ParsedStatus as S, STANDARD_WEBHOOK_ID_HEADER as T, isPaymentEvent as U, isInteractionX402Event as V, isPaymentFailedEvent as W, validateEmailReceivedEvent as Y, DkimResult as _, getEventHeader as a, EventType as b, isDownloadExpired as c, receive as d, verifyRawEmailDownload as f, AuthVerdict as g, AuthConfidence as h, getDownloadTimeRemaining as i, LEGACY_SIGNATURE_HEADER as j, verifyStandardWebhooksSignature as k, isRawIncluded as l, validateEmailAuth as m, confirmedHeaders as n, handleWebhook as o, WEBHOOK_VERSION as p, verifyDownloadToken as q, decodeRawEmail as r, handleWebhookEvent as s, WEBHOOK_EVENT_HEADER as t, parseWebhookEvent as u, DmarcPolicy as v, emailReceivedEventJsonSchema as w, ForwardVerdict as x, DmarcResult as y, WEBHOOK_EVENT_TYPES as z };
10502
+ export { isEmailReceivedEvent as A, PRIMITIVE_SIGNATURE_HEADER as C, INTERACTION_EVENT_TYPES as D, EMAIL_EVENT_TYPES as E, isPaymentSettledEvent as F, generateDownloadToken as I, verifyDownloadToken as L, isKnownWebhookEventType as M, isPaymentEvent as N, PAYMENT_EVENT_TYPES as O, isPaymentFailedEvent as P, safeValidateEmailReceivedEvent as R, PRIMITIVE_CONFIRMED_HEADER as S, verifyWebhookSignature as T, STANDARD_WEBHOOK_TIMESTAMP_HEADER as _, getEventHeader as a, LEGACY_CONFIRMED_HEADER as b, isDownloadExpired as c, receive as d, verifyRawEmailDownload as f, STANDARD_WEBHOOK_SIGNATURE_HEADER as g, STANDARD_WEBHOOK_ID_HEADER as h, getDownloadTimeRemaining as i, isInteractionX402Event as j, WEBHOOK_EVENT_TYPES as k, isRawIncluded as l, emailReceivedEventJsonSchema as m, confirmedHeaders as n, handleWebhook as o, WEBHOOK_VERSION as p, decodeRawEmail as r, handleWebhookEvent as s, WEBHOOK_EVENT_HEADER as t, parseWebhookEvent as u, signStandardWebhooksPayload as v, signWebhookPayload as w, LEGACY_SIGNATURE_HEADER as x, verifyStandardWebhooksSignature as y, validateEmailReceivedEvent as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primitivedotdev/sdk",
3
- "version": "1.18.0",
3
+ "version": "1.20.0",
4
4
  "description": "Official Primitive Node.js SDK: webhook, api, openapi, contract, and parser runtime modules.",
5
5
  "type": "module",
6
6
  "module": "./dist/index.js",
@@ -1,287 +0,0 @@
1
- import { n as parseFromHeaderLoose } from "./address-parser-CQbFjgRC.js";
2
- //#region src/webhook/received-email.ts
3
- const REPLY_PREFIX_RE = /^re\s*:/i;
4
- const FORWARD_PREFIX_RE = /^(fwd?|fw)\s*:/i;
5
- function normalizeReceivedEmail(event) {
6
- const receivedBy = event.email.smtp.rcpt_to[0];
7
- if (!receivedBy) throw new Error("email.smtp.rcpt_to must contain at least one recipient");
8
- const sender = parseHeaderAddress(event.email.headers.from) ?? {
9
- address: event.email.smtp.mail_from.trim().toLowerCase(),
10
- name: null
11
- };
12
- const replyTarget = firstStructuredAddress(event.email.parsed.reply_to) ?? sender;
13
- const subject = event.email.headers.subject ?? null;
14
- const references = event.email.parsed.references ?? [];
15
- const messageId = event.email.headers.message_id ?? null;
16
- return {
17
- id: event.email.id,
18
- eventId: event.id,
19
- receivedAt: event.email.received_at,
20
- sender,
21
- replyTarget,
22
- receivedBy,
23
- receivedByAll: [...event.email.smtp.rcpt_to],
24
- subject,
25
- replySubject: buildReplySubject(subject),
26
- forwardSubject: buildForwardSubject(subject),
27
- text: event.email.parsed.body_text ?? null,
28
- thread: {
29
- messageId,
30
- inReplyTo: event.email.parsed.in_reply_to ?? [],
31
- references
32
- },
33
- attachments: event.email.parsed.attachments ?? [],
34
- auth: event.email.auth,
35
- analysis: event.email.analysis,
36
- raw: event
37
- };
38
- }
39
- function buildReplySubject(subject) {
40
- const trimmed = subject?.trim() ?? "";
41
- if (trimmed.length === 0) return "Re:";
42
- return REPLY_PREFIX_RE.test(trimmed) ? trimmed : `Re: ${trimmed}`;
43
- }
44
- function buildForwardSubject(subject) {
45
- const trimmed = subject?.trim() ?? "";
46
- if (trimmed.length === 0) return "Fwd:";
47
- return FORWARD_PREFIX_RE.test(trimmed) ? trimmed : `Fwd: ${trimmed}`;
48
- }
49
- function formatAddress(address) {
50
- return address.name ? `${address.name} <${address.address}>` : address.address;
51
- }
52
- function firstStructuredAddress(addresses) {
53
- const address = addresses?.[0];
54
- if (!address) return null;
55
- return {
56
- address: address.address.trim().toLowerCase(),
57
- name: address.name ?? null
58
- };
59
- }
60
- function parseHeaderAddress(value) {
61
- const parsed = parseFromHeaderLoose(value);
62
- if (!parsed) return null;
63
- return {
64
- address: parsed.address,
65
- name: parsed.name?.trim() || null
66
- };
67
- }
68
- //#endregion
69
- //#region src/webhook/errors.ts
70
- /**
71
- * Verification error definitions.
72
- * Use these for documentation, dashboards, and i18n.
73
- */
74
- const VERIFICATION_ERRORS = {
75
- INVALID_SIGNATURE_HEADER: {
76
- message: "Missing or malformed Primitive-Signature header",
77
- suggestion: "Check that you're reading the correct header (Primitive-Signature) and it's being passed correctly from your web framework."
78
- },
79
- TIMESTAMP_OUT_OF_RANGE: {
80
- message: "Timestamp is too old (possible replay attack)",
81
- suggestion: "This could indicate a replay attack, network delay, or server clock drift. Check your server's time is synced."
82
- },
83
- SIGNATURE_MISMATCH: {
84
- message: "Signature doesn't match expected value",
85
- suggestion: "Verify the webhook secret matches and you're using the raw request body (not re-serialized JSON)."
86
- },
87
- MISSING_SECRET: {
88
- message: "No webhook secret was provided",
89
- suggestion: "Pass your webhook secret from the Primitive dashboard. Check that the environment variable is set."
90
- }
91
- };
92
- /**
93
- * Payload parsing error definitions.
94
- * Use these for documentation, dashboards, and i18n.
95
- */
96
- const PAYLOAD_ERRORS = {
97
- PAYLOAD_NULL: {
98
- message: "Webhook payload is null",
99
- suggestion: "Ensure you're passing the parsed JSON body, not null. Check your framework's body parsing middleware."
100
- },
101
- PAYLOAD_UNDEFINED: {
102
- message: "Webhook payload is undefined",
103
- suggestion: "The payload was not provided. Make sure you're passing the request body to the handler."
104
- },
105
- PAYLOAD_WRONG_TYPE: {
106
- message: "Webhook payload must be an object",
107
- suggestion: "The payload should be a parsed JSON object. Check that you're not passing a string or other primitive."
108
- },
109
- PAYLOAD_IS_ARRAY: {
110
- message: "Webhook payload is an array, expected object",
111
- suggestion: "Primitive webhooks are single event objects, not arrays. Check the payload structure."
112
- },
113
- PAYLOAD_MISSING_EVENT: {
114
- message: "Webhook payload missing 'event' field",
115
- suggestion: "All webhook payloads must have an 'event' field. This may not be a valid Primitive webhook."
116
- },
117
- PAYLOAD_UNKNOWN_EVENT: {
118
- message: "Unknown webhook event type",
119
- suggestion: "This event type is not recognized. You may need to update your SDK or handle unknown events gracefully."
120
- },
121
- PAYLOAD_EMPTY_BODY: {
122
- message: "Request body is empty",
123
- suggestion: "The request body was empty. Ensure the webhook is sending data and your framework is parsing it correctly."
124
- },
125
- JSON_PARSE_FAILED: {
126
- message: "Failed to parse JSON body",
127
- suggestion: "The request body is not valid JSON. Check the raw body content and Content-Type header."
128
- },
129
- INVALID_ENCODING: {
130
- message: "Invalid body encoding",
131
- suggestion: "The request body encoding is not supported. Primitive webhooks use UTF-8 encoded JSON."
132
- }
133
- };
134
- /**
135
- * Raw email decode error definitions.
136
- * Use these for documentation, dashboards, and i18n.
137
- */
138
- const RAW_EMAIL_ERRORS = {
139
- NOT_INCLUDED: {
140
- message: "Raw email content not included inline",
141
- suggestion: "Use the download URL at event.email.content.download.url to fetch the raw email."
142
- },
143
- INVALID_BASE64: {
144
- message: "Raw email content is not valid base64",
145
- suggestion: "The raw email data is malformed. Fetch the raw email from the download URL or regenerate the webhook payload."
146
- },
147
- HASH_MISMATCH: {
148
- message: "SHA-256 hash verification failed",
149
- suggestion: "The raw email data may be corrupted. Try downloading from the URL instead."
150
- }
151
- };
152
- /**
153
- * Base class for all Primitive webhook errors.
154
- *
155
- * Catch this to handle any error from the SDK in a single catch block.
156
- *
157
- * @example
158
- * ```typescript
159
- * import { handleWebhook, PrimitiveWebhookError } from '@primitivedotdev/sdk';
160
- *
161
- * try {
162
- * const event = handleWebhook({ body, headers, secret });
163
- * } catch (err) {
164
- * if (err instanceof PrimitiveWebhookError) {
165
- * console.error(`[${err.code}] ${err.message}`);
166
- * return res.status(400).json({ error: err.code });
167
- * }
168
- * throw err;
169
- * }
170
- * ```
171
- */
172
- var PrimitiveWebhookError = class extends Error {
173
- /**
174
- * Formats the error for logging/display.
175
- */
176
- toString() {
177
- return `${this.name} [${this.code}]: ${this.message}\n\nSuggestion: ${this.suggestion}`;
178
- }
179
- /**
180
- * Serializes cleanly for structured logging (Datadog, CloudWatch, etc.)
181
- */
182
- toJSON() {
183
- return {
184
- name: this.name,
185
- code: this.code,
186
- message: this.message,
187
- suggestion: this.suggestion
188
- };
189
- }
190
- };
191
- /**
192
- * Error thrown when webhook signature verification fails.
193
- *
194
- * Use the `code` property to programmatically handle specific error cases.
195
- */
196
- var WebhookVerificationError = class extends PrimitiveWebhookError {
197
- code;
198
- suggestion;
199
- constructor(code, message, suggestion) {
200
- super(message ?? VERIFICATION_ERRORS[code].message);
201
- this.name = "WebhookVerificationError";
202
- this.code = code;
203
- this.suggestion = suggestion ?? VERIFICATION_ERRORS[code].suggestion;
204
- }
205
- };
206
- /**
207
- * Error thrown when webhook payload parsing fails (lightweight parser).
208
- *
209
- * Use the `code` property for programmatic handling and monitoring.
210
- * The `suggestion` property contains actionable guidance for fixing the issue.
211
- */
212
- var WebhookPayloadError = class extends PrimitiveWebhookError {
213
- code;
214
- suggestion;
215
- /** Original error if this wraps another error (e.g., JSON.parse failure) */
216
- cause;
217
- constructor(code, message, suggestion, cause) {
218
- super(message ?? PAYLOAD_ERRORS[code].message);
219
- this.name = "WebhookPayloadError";
220
- this.code = code;
221
- this.suggestion = suggestion ?? PAYLOAD_ERRORS[code].suggestion;
222
- this.cause = cause;
223
- }
224
- };
225
- /**
226
- * Error thrown when schema validation fails.
227
- */
228
- var WebhookValidationError = class extends PrimitiveWebhookError {
229
- code = "SCHEMA_VALIDATION_FAILED";
230
- suggestion;
231
- /** The specific field path that failed (e.g., "email.headers.from") */
232
- field;
233
- /** Original schema validation errors for advanced debugging */
234
- validationErrors;
235
- /** Number of additional validation errors beyond the first */
236
- additionalErrorCount;
237
- constructor(field, message, suggestion, validationErrors) {
238
- super(message);
239
- this.name = "WebhookValidationError";
240
- this.field = field;
241
- this.suggestion = suggestion;
242
- this.validationErrors = validationErrors;
243
- this.additionalErrorCount = Math.max(0, validationErrors.length - 1);
244
- }
245
- /**
246
- * Formats the error for logging/display.
247
- * Includes error count and suggestion.
248
- */
249
- toString() {
250
- let output = `${this.name} [${this.code}]: ${this.message}`;
251
- if (this.additionalErrorCount > 0) output += ` (and ${this.additionalErrorCount} more validation error${this.additionalErrorCount > 1 ? "s" : ""})`;
252
- output += `\n\nSuggestion: ${this.suggestion}`;
253
- return output;
254
- }
255
- /**
256
- * Serializes cleanly for structured logging (Datadog, CloudWatch, etc.)
257
- */
258
- toJSON() {
259
- return {
260
- name: this.name,
261
- code: this.code,
262
- field: this.field,
263
- message: this.message,
264
- suggestion: this.suggestion,
265
- additionalErrorCount: this.additionalErrorCount
266
- };
267
- }
268
- };
269
- /**
270
- * Error thrown when raw email decoding or verification fails.
271
- *
272
- * Use the `code` property to determine the failure reason:
273
- * - `NOT_INCLUDED`: Raw email not inline, must download from URL
274
- * - `HASH_MISMATCH`: SHA-256 verification failed, content may be corrupted
275
- */
276
- var RawEmailDecodeError = class extends PrimitiveWebhookError {
277
- code;
278
- suggestion;
279
- constructor(code, message) {
280
- super(message ?? RAW_EMAIL_ERRORS[code].message);
281
- this.name = "RawEmailDecodeError";
282
- this.code = code;
283
- this.suggestion = RAW_EMAIL_ERRORS[code].suggestion;
284
- }
285
- };
286
- //#endregion
287
- export { VERIFICATION_ERRORS as a, WebhookVerificationError as c, formatAddress as d, normalizeReceivedEmail as f, RawEmailDecodeError as i, buildForwardSubject as l, PrimitiveWebhookError as n, WebhookPayloadError as o, parseHeaderAddress as p, RAW_EMAIL_ERRORS as r, WebhookValidationError as s, PAYLOAD_ERRORS as t, buildReplySubject as u };