@primitivedotdev/sdk 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/generated/sdk.gen.js +7 -4
- package/dist/api/index.d.ts +50 -5
- package/dist/contract/index.d.ts +81 -3
- package/dist/contract/index.js +72 -2
- package/dist/{index-D2OuDGVz.d.ts → index-C7tHPMZM.d.ts} +90 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/oclif/api-command.js +72 -8
- package/dist/openapi/index.d.ts +1 -0
- package/dist/openapi/openapi.generated.js +74 -3
- package/dist/openapi/operations.generated.js +41 -2
- package/dist/webhook/index.d.ts +2 -2
- package/dist/webhook/index.js +2 -2
- package/dist/{webhook-uSco6pyX.js → webhook-C5kOt3fb.js} +97 -1
- package/oclif.manifest.json +15 -3
- package/package.json +4 -4
|
@@ -188,8 +188,10 @@ export const downloadAttachments = (options) => (options.client ?? client).get({
|
|
|
188
188
|
* Replay email webhooks
|
|
189
189
|
*
|
|
190
190
|
* Re-delivers the webhook payload for this email to all active
|
|
191
|
-
* endpoints matching the email's domain.
|
|
192
|
-
*
|
|
191
|
+
* endpoints matching the email's domain. Rate limited per-email
|
|
192
|
+
* (short cooldown between successive replays of the same email)
|
|
193
|
+
* and per-org (burst + sustained windows), sharing an org-wide
|
|
194
|
+
* budget with delivery replays.
|
|
193
195
|
*
|
|
194
196
|
*/
|
|
195
197
|
export const replayEmailWebhooks = (options) => (options.client ?? client).post({
|
|
@@ -333,8 +335,9 @@ export const listDeliveries = (options) => (options?.client ?? client).get({
|
|
|
333
335
|
*
|
|
334
336
|
* Re-sends the stored webhook payload from a previous delivery attempt.
|
|
335
337
|
* If the original endpoint is still active, it is targeted. If the
|
|
336
|
-
* original endpoint was deleted, the
|
|
337
|
-
* Deactivated endpoints cannot be replayed to.
|
|
338
|
+
* original endpoint was deleted, the oldest active endpoint is used.
|
|
339
|
+
* Deactivated endpoints cannot be replayed to. Rate limited per-org,
|
|
340
|
+
* sharing an org-wide budget with email replays.
|
|
338
341
|
*
|
|
339
342
|
*/
|
|
340
343
|
export const replayDelivery = (options) => (options.client ?? client).post({
|
package/dist/api/index.d.ts
CHANGED
|
@@ -348,8 +348,30 @@ type PaginationMeta = {
|
|
|
348
348
|
type ErrorResponse = {
|
|
349
349
|
success: boolean;
|
|
350
350
|
error: {
|
|
351
|
-
code: 'unauthorized' | 'forbidden' | 'not_found' | 'validation_error' | 'rate_limit_exceeded' | 'internal_error';
|
|
351
|
+
code: 'unauthorized' | 'forbidden' | 'not_found' | 'validation_error' | 'rate_limit_exceeded' | 'internal_error' | 'conflict' | 'mx_conflict';
|
|
352
352
|
message: string;
|
|
353
|
+
/**
|
|
354
|
+
* Optional structured data that callers can inspect to recover
|
|
355
|
+
* from the error. The fields present depend on `code`. Additional
|
|
356
|
+
* keys may be added over time without a major-version bump.
|
|
357
|
+
*
|
|
358
|
+
*/
|
|
359
|
+
details?: {
|
|
360
|
+
/**
|
|
361
|
+
* Present when `code == mx_conflict`.
|
|
362
|
+
*/
|
|
363
|
+
mx_conflict?: {
|
|
364
|
+
/**
|
|
365
|
+
* Human-readable name of the detected mailbox provider (e.g. "Google Workspace").
|
|
366
|
+
*/
|
|
367
|
+
provider_name: string;
|
|
368
|
+
/**
|
|
369
|
+
* Subdomain to try instead (e.g. "mail" for `mail.example.com`).
|
|
370
|
+
*/
|
|
371
|
+
suggested_subdomain: string;
|
|
372
|
+
};
|
|
373
|
+
[key: string]: unknown;
|
|
374
|
+
};
|
|
353
375
|
};
|
|
354
376
|
};
|
|
355
377
|
type Account = {
|
|
@@ -866,6 +888,18 @@ type AddDomainErrors = {
|
|
|
866
888
|
* Invalid or missing API key
|
|
867
889
|
*/
|
|
868
890
|
401: ErrorResponse;
|
|
891
|
+
/**
|
|
892
|
+
* Domain claim conflicts with existing state. Two error codes
|
|
893
|
+
* are possible:
|
|
894
|
+
* * `mx_conflict`: the domain's current MX records point at
|
|
895
|
+
* another mailbox provider. The response includes
|
|
896
|
+
* `error.details.mx_conflict` with the detected provider
|
|
897
|
+
* and a suggested subdomain.
|
|
898
|
+
* * `conflict`: the domain is already claimed by another
|
|
899
|
+
* org, or a pending claim exists for another user.
|
|
900
|
+
*
|
|
901
|
+
*/
|
|
902
|
+
409: ErrorResponse;
|
|
869
903
|
};
|
|
870
904
|
type AddDomainError = AddDomainErrors[keyof AddDomainErrors];
|
|
871
905
|
type AddDomainResponses = {
|
|
@@ -1213,6 +1247,10 @@ type ReplayEmailWebhooksErrors = {
|
|
|
1213
1247
|
* Resource not found
|
|
1214
1248
|
*/
|
|
1215
1249
|
404: ErrorResponse;
|
|
1250
|
+
/**
|
|
1251
|
+
* Rate limit exceeded
|
|
1252
|
+
*/
|
|
1253
|
+
429: ErrorResponse;
|
|
1216
1254
|
};
|
|
1217
1255
|
type ReplayEmailWebhooksError = ReplayEmailWebhooksErrors[keyof ReplayEmailWebhooksErrors];
|
|
1218
1256
|
type ReplayEmailWebhooksResponses = {
|
|
@@ -1584,6 +1622,10 @@ type ReplayDeliveryErrors = {
|
|
|
1584
1622
|
* Resource not found
|
|
1585
1623
|
*/
|
|
1586
1624
|
404: ErrorResponse;
|
|
1625
|
+
/**
|
|
1626
|
+
* Rate limit exceeded
|
|
1627
|
+
*/
|
|
1628
|
+
429: ErrorResponse;
|
|
1587
1629
|
};
|
|
1588
1630
|
type ReplayDeliveryError = ReplayDeliveryErrors[keyof ReplayDeliveryErrors];
|
|
1589
1631
|
type ReplayDeliveryResponses = {
|
|
@@ -1720,8 +1762,10 @@ declare const downloadAttachments: <ThrowOnError extends boolean = false>(option
|
|
|
1720
1762
|
* Replay email webhooks
|
|
1721
1763
|
*
|
|
1722
1764
|
* Re-delivers the webhook payload for this email to all active
|
|
1723
|
-
* endpoints matching the email's domain.
|
|
1724
|
-
*
|
|
1765
|
+
* endpoints matching the email's domain. Rate limited per-email
|
|
1766
|
+
* (short cooldown between successive replays of the same email)
|
|
1767
|
+
* and per-org (burst + sustained windows), sharing an org-wide
|
|
1768
|
+
* budget with delivery replays.
|
|
1725
1769
|
*
|
|
1726
1770
|
*/
|
|
1727
1771
|
declare const replayEmailWebhooks: <ThrowOnError extends boolean = false>(options: Options$1<ReplayEmailWebhooksData, ThrowOnError>) => RequestResult<ReplayEmailWebhooksResponses, ReplayEmailWebhooksErrors, ThrowOnError, "fields">;
|
|
@@ -1805,8 +1849,9 @@ declare const listDeliveries: <ThrowOnError extends boolean = false>(options?: O
|
|
|
1805
1849
|
*
|
|
1806
1850
|
* Re-sends the stored webhook payload from a previous delivery attempt.
|
|
1807
1851
|
* If the original endpoint is still active, it is targeted. If the
|
|
1808
|
-
* original endpoint was deleted, the
|
|
1809
|
-
* Deactivated endpoints cannot be replayed to.
|
|
1852
|
+
* original endpoint was deleted, the oldest active endpoint is used.
|
|
1853
|
+
* Deactivated endpoints cannot be replayed to. Rate limited per-org,
|
|
1854
|
+
* sharing an org-wide budget with email replays.
|
|
1810
1855
|
*
|
|
1811
1856
|
*/
|
|
1812
1857
|
declare const replayDelivery: <ThrowOnError extends boolean = false>(options: Options$1<ReplayDeliveryData, ThrowOnError>) => RequestResult<ReplayDeliveryResponses, ReplayDeliveryErrors, ThrowOnError, "fields">;
|
package/dist/contract/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { EmailAddress, EmailAnalysis, EmailAuth, EmailReceivedEvent, ParsedDataComplete, ParsedDataFailed, ParsedError, RawContentDownloadOnly, RawContentInline, WebhookAttachment } from "../types-C3ms4R0d.js";
|
|
2
|
-
import { SignResult, StandardWebhooksSignResult, WEBHOOK_VERSION$1 as WEBHOOK_VERSION, signStandardWebhooksPayload$1 as signStandardWebhooksPayload, signWebhookPayload$1 as signWebhookPayload } from "../index-
|
|
2
|
+
import { SignResult, StandardWebhooksSignResult, WEBHOOK_VERSION$1 as WEBHOOK_VERSION, signStandardWebhooksPayload$1 as signStandardWebhooksPayload, signWebhookPayload$1 as signWebhookPayload } from "../index-C7tHPMZM.js";
|
|
3
3
|
|
|
4
4
|
//#region src/contract/contract.d.ts
|
|
5
5
|
/** Maximum raw email size for inline inclusion (256 KB). */
|
|
@@ -146,5 +146,83 @@ declare function buildEmailReceivedEvent(input: EmailReceivedEventInput, options
|
|
|
146
146
|
event_id?: string;
|
|
147
147
|
/** Override the attempted-at timestamp, typically for tests. */
|
|
148
148
|
attempted_at?: string;
|
|
149
|
-
}): EmailReceivedEvent;
|
|
150
|
-
|
|
149
|
+
}): EmailReceivedEvent;
|
|
150
|
+
/**
|
|
151
|
+
* Input for building an `EmailReceivedEvent` directly from parser output.
|
|
152
|
+
*/
|
|
153
|
+
interface BuildEventFromParsedDataOptions {
|
|
154
|
+
/** Unique email ID chosen by the producer. */
|
|
155
|
+
emailId: string;
|
|
156
|
+
/** ID of the webhook endpoint receiving this event. */
|
|
157
|
+
endpointId: string;
|
|
158
|
+
/** Raw RFC 5322 bytes. Used to compute sha256 and inline data. */
|
|
159
|
+
rawBytes: Buffer;
|
|
160
|
+
/** Parser output with attachments, body, and threading headers populated. */
|
|
161
|
+
parsed: ParsedDataComplete;
|
|
162
|
+
/** Message-ID header value, or null if the email had none. */
|
|
163
|
+
messageId: string | null;
|
|
164
|
+
/** From header value. */
|
|
165
|
+
sender: string;
|
|
166
|
+
/** To header value. */
|
|
167
|
+
recipient: string;
|
|
168
|
+
/** Subject header value, or null. */
|
|
169
|
+
subject: string | null;
|
|
170
|
+
/** ISO 8601 timestamp when the producer accepted the email. */
|
|
171
|
+
receivedAt: string;
|
|
172
|
+
/** SMTP HELO/EHLO hostname, or null if not captured. */
|
|
173
|
+
smtpHelo: string | null;
|
|
174
|
+
/** SMTP envelope MAIL FROM. */
|
|
175
|
+
smtpMailFrom: string;
|
|
176
|
+
/** SMTP envelope RCPT TO recipients. Must contain at least one entry. */
|
|
177
|
+
smtpRcptTo: [string, ...string[]];
|
|
178
|
+
/** Email authentication results (camelCase per the schema). */
|
|
179
|
+
auth: EmailAuth;
|
|
180
|
+
/** Email analysis block. */
|
|
181
|
+
analysis: EmailAnalysis;
|
|
182
|
+
/** HTTPS download URL for the raw email. Always populated. */
|
|
183
|
+
downloadUrl: string;
|
|
184
|
+
/** ISO 8601 expiry for the raw-email download URL. */
|
|
185
|
+
downloadExpiresAt: string;
|
|
186
|
+
/**
|
|
187
|
+
* Download URL for the attachments tarball.
|
|
188
|
+
* Must be null iff `parsed.attachments` is empty — mismatch throws.
|
|
189
|
+
*/
|
|
190
|
+
attachmentsDownloadUrl: string | null;
|
|
191
|
+
/** Delivery attempt number, starting at 1. */
|
|
192
|
+
attemptCount: number;
|
|
193
|
+
/** Original Date header value, or null. */
|
|
194
|
+
dateHeader?: string | null;
|
|
195
|
+
/** Optional overrides forwarded to `buildEmailReceivedEvent`. */
|
|
196
|
+
buildOptions?: {
|
|
197
|
+
event_id?: string;
|
|
198
|
+
attempted_at?: string;
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Build an `EmailReceivedEvent` from parsed email data plus delivery metadata.
|
|
203
|
+
*
|
|
204
|
+
* Pure adapter: the caller supplies the raw bytes and the already-parsed
|
|
205
|
+
* data; this function computes sha256 and size, enforces the attachments
|
|
206
|
+
* invariant, and delegates to `buildEmailReceivedEvent` for schema
|
|
207
|
+
* validation. It never reads from disk, so it is safe to use in any
|
|
208
|
+
* runtime that has the data in memory.
|
|
209
|
+
*
|
|
210
|
+
* Inline vs. download-only behavior: when `rawBytes.length` is at or below
|
|
211
|
+
* `RAW_EMAIL_INLINE_THRESHOLD`, the event's `raw.data` is populated and
|
|
212
|
+
* `download.url` is still populated. Above the threshold, only `download.url`
|
|
213
|
+
* is populated. The download URL is always set regardless of inline status.
|
|
214
|
+
*
|
|
215
|
+
* Callers using the bundled parser can populate the header fields
|
|
216
|
+
* (`messageId`, `sender`, `recipient`, `subject`, `dateHeader`) directly
|
|
217
|
+
* from `toCanonicalHeaders(parsed)`. Accepting the flat fields rather than
|
|
218
|
+
* a canonical-headers object keeps this function usable by callers that
|
|
219
|
+
* do not use the bundled parser. A future release may add an optional
|
|
220
|
+
* canonical-headers parameter as an ergonomic alternative.
|
|
221
|
+
*
|
|
222
|
+
* @throws Error if `attachmentsDownloadUrl` disagrees with whether
|
|
223
|
+
* `parsed.attachments` is empty.
|
|
224
|
+
* @throws Error if `smtpRcptTo` is empty.
|
|
225
|
+
* @throws WebhookValidationError if the assembled event fails schema validation.
|
|
226
|
+
*/
|
|
227
|
+
declare function buildEventFromParsedData(params: BuildEventFromParsedDataOptions): EmailReceivedEvent; //#endregion
|
|
228
|
+
export { BuildEventFromParsedDataOptions, EmailAddress, EmailAnalysis, EmailAuth, EmailReceivedEvent, EmailReceivedEventInput, ParsedDataComplete, ParsedDataFailed, ParsedError, ParsedInput, ParsedInputComplete, ParsedInputFailed, RAW_EMAIL_INLINE_THRESHOLD, RawContentDownloadOnly, RawContentInline, SignResult, StandardWebhooksSignResult, WEBHOOK_VERSION, WebhookAttachment, buildEmailReceivedEvent, buildEventFromParsedData, generateEventId, signStandardWebhooksPayload, signWebhookPayload };
|
package/dist/contract/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { WEBHOOK_VERSION, signStandardWebhooksPayload, signWebhookPayload, validateEmailReceivedEvent } from "../webhook-
|
|
1
|
+
import { WEBHOOK_VERSION, signStandardWebhooksPayload, signWebhookPayload, validateEmailReceivedEvent } from "../webhook-C5kOt3fb.js";
|
|
2
2
|
import { createHash } from "node:crypto";
|
|
3
3
|
|
|
4
4
|
//#region src/contract/contract.ts
|
|
@@ -194,6 +194,76 @@ function buildEmailReceivedEvent(input, options) {
|
|
|
194
194
|
};
|
|
195
195
|
return validateEmailReceivedEvent(event);
|
|
196
196
|
}
|
|
197
|
+
/**
|
|
198
|
+
* Build an `EmailReceivedEvent` from parsed email data plus delivery metadata.
|
|
199
|
+
*
|
|
200
|
+
* Pure adapter: the caller supplies the raw bytes and the already-parsed
|
|
201
|
+
* data; this function computes sha256 and size, enforces the attachments
|
|
202
|
+
* invariant, and delegates to `buildEmailReceivedEvent` for schema
|
|
203
|
+
* validation. It never reads from disk, so it is safe to use in any
|
|
204
|
+
* runtime that has the data in memory.
|
|
205
|
+
*
|
|
206
|
+
* Inline vs. download-only behavior: when `rawBytes.length` is at or below
|
|
207
|
+
* `RAW_EMAIL_INLINE_THRESHOLD`, the event's `raw.data` is populated and
|
|
208
|
+
* `download.url` is still populated. Above the threshold, only `download.url`
|
|
209
|
+
* is populated. The download URL is always set regardless of inline status.
|
|
210
|
+
*
|
|
211
|
+
* Callers using the bundled parser can populate the header fields
|
|
212
|
+
* (`messageId`, `sender`, `recipient`, `subject`, `dateHeader`) directly
|
|
213
|
+
* from `toCanonicalHeaders(parsed)`. Accepting the flat fields rather than
|
|
214
|
+
* a canonical-headers object keeps this function usable by callers that
|
|
215
|
+
* do not use the bundled parser. A future release may add an optional
|
|
216
|
+
* canonical-headers parameter as an ergonomic alternative.
|
|
217
|
+
*
|
|
218
|
+
* @throws Error if `attachmentsDownloadUrl` disagrees with whether
|
|
219
|
+
* `parsed.attachments` is empty.
|
|
220
|
+
* @throws Error if `smtpRcptTo` is empty.
|
|
221
|
+
* @throws WebhookValidationError if the assembled event fails schema validation.
|
|
222
|
+
*/
|
|
223
|
+
function buildEventFromParsedData(params) {
|
|
224
|
+
const { parsed, attachmentsDownloadUrl, smtpRcptTo } = params;
|
|
225
|
+
const hasAttachments = parsed.attachments.length > 0;
|
|
226
|
+
if (hasAttachments && attachmentsDownloadUrl === null) throw new Error(`[@primitivedotdev/sdk/contract] attachmentsDownloadUrl must be non-null when parsed.attachments has ${parsed.attachments.length} entries`);
|
|
227
|
+
if (!hasAttachments && attachmentsDownloadUrl !== null) throw new Error(`[@primitivedotdev/sdk/contract] attachmentsDownloadUrl must be null when parsed.attachments is empty (got: ${JSON.stringify(attachmentsDownloadUrl)})`);
|
|
228
|
+
if (smtpRcptTo.length === 0) throw new Error("[@primitivedotdev/sdk/contract] smtpRcptTo must contain at least one recipient");
|
|
229
|
+
const raw_size_bytes = params.rawBytes.length;
|
|
230
|
+
const raw_sha256 = createHash("sha256").update(params.rawBytes).digest("hex");
|
|
231
|
+
const parsedInput = {
|
|
232
|
+
status: "complete",
|
|
233
|
+
body_text: parsed.body_text,
|
|
234
|
+
body_html: parsed.body_html,
|
|
235
|
+
reply_to: parsed.reply_to,
|
|
236
|
+
cc: parsed.cc,
|
|
237
|
+
bcc: parsed.bcc,
|
|
238
|
+
in_reply_to: parsed.in_reply_to,
|
|
239
|
+
references: parsed.references,
|
|
240
|
+
attachments: parsed.attachments
|
|
241
|
+
};
|
|
242
|
+
const input = {
|
|
243
|
+
email_id: params.emailId,
|
|
244
|
+
endpoint_id: params.endpointId,
|
|
245
|
+
message_id: params.messageId,
|
|
246
|
+
sender: params.sender,
|
|
247
|
+
recipient: params.recipient,
|
|
248
|
+
subject: params.subject,
|
|
249
|
+
received_at: params.receivedAt,
|
|
250
|
+
smtp_helo: params.smtpHelo,
|
|
251
|
+
smtp_mail_from: params.smtpMailFrom,
|
|
252
|
+
smtp_rcpt_to: smtpRcptTo,
|
|
253
|
+
raw_bytes: params.rawBytes,
|
|
254
|
+
raw_sha256,
|
|
255
|
+
raw_size_bytes,
|
|
256
|
+
attempt_count: params.attemptCount,
|
|
257
|
+
date_header: params.dateHeader ?? null,
|
|
258
|
+
download_url: params.downloadUrl,
|
|
259
|
+
download_expires_at: params.downloadExpiresAt,
|
|
260
|
+
attachments_download_url: attachmentsDownloadUrl,
|
|
261
|
+
parsed: parsedInput,
|
|
262
|
+
auth: params.auth,
|
|
263
|
+
analysis: params.analysis
|
|
264
|
+
};
|
|
265
|
+
return buildEmailReceivedEvent(input, params.buildOptions);
|
|
266
|
+
}
|
|
197
267
|
|
|
198
268
|
//#endregion
|
|
199
|
-
export { RAW_EMAIL_INLINE_THRESHOLD, WEBHOOK_VERSION, buildEmailReceivedEvent, generateEventId, signStandardWebhooksPayload, signWebhookPayload };
|
|
269
|
+
export { RAW_EMAIL_INLINE_THRESHOLD, WEBHOOK_VERSION, buildEmailReceivedEvent, buildEventFromParsedData, generateEventId, signStandardWebhooksPayload, signWebhookPayload };
|
|
@@ -224,6 +224,95 @@ type ValidationResult<T> = ValidationSuccess<T> | ValidationFailure;
|
|
|
224
224
|
declare function validateEmailReceivedEvent(input: unknown): EmailReceivedEvent;
|
|
225
225
|
declare function safeValidateEmailReceivedEvent(input: unknown): ValidationResult<EmailReceivedEvent>;
|
|
226
226
|
|
|
227
|
+
//#endregion
|
|
228
|
+
//#region src/webhook/download-tokens.d.ts
|
|
229
|
+
/**
|
|
230
|
+
* Signed download tokens.
|
|
231
|
+
*
|
|
232
|
+
* A download token is a self-describing bearer credential for fetching a
|
|
233
|
+
* specific email's raw bytes or attachment bundle from a per-deployment
|
|
234
|
+
* download endpoint. It binds:
|
|
235
|
+
*
|
|
236
|
+
* - `email_id` — the specific email the token authorizes.
|
|
237
|
+
* - `aud` — a caller-chosen audience label (e.g. the resource kind being
|
|
238
|
+
* downloaded). Tokens minted for one audience will not verify under another.
|
|
239
|
+
* - `exp` — an absolute expiration time (unix seconds).
|
|
240
|
+
*
|
|
241
|
+
* Format: `<base64url(payload)>.<base64url(signature)>` where `signature`
|
|
242
|
+
* is HMAC-SHA256 over the base64url-encoded payload using the shared secret.
|
|
243
|
+
*
|
|
244
|
+
* The audience is an opaque caller-chosen string. Both the issuer and the
|
|
245
|
+
* verifier must agree on the exact bytes; the SDK does not prescribe a
|
|
246
|
+
* convention. New integrations are encouraged to namespace audiences
|
|
247
|
+
* (e.g. `primitive:raw-download`).
|
|
248
|
+
*
|
|
249
|
+
* Tokens are stateless: verification needs only the shared secret. Keep
|
|
250
|
+
* expirations as short as operationally tolerable.
|
|
251
|
+
*/
|
|
252
|
+
/**
|
|
253
|
+
* Input for issuing a download token.
|
|
254
|
+
*/
|
|
255
|
+
interface GenerateDownloadTokenOptions {
|
|
256
|
+
/** The email ID the token authorizes. */
|
|
257
|
+
emailId: string;
|
|
258
|
+
/** Absolute expiration as unix seconds (not a TTL). */
|
|
259
|
+
expiresAt: number;
|
|
260
|
+
/** Caller-chosen audience label; the verifier must supply the same value. */
|
|
261
|
+
audience: string;
|
|
262
|
+
/** Shared HMAC secret. */
|
|
263
|
+
secret: string;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Issue a signed download token.
|
|
267
|
+
*
|
|
268
|
+
* The resulting token is `<base64url-payload>.<base64url-signature>`, where
|
|
269
|
+
* the payload is `{"email_id":"...","exp":...,"aud":"..."}` (snake_case,
|
|
270
|
+
* field order fixed) and the signature is HMAC-SHA256 of the base64url
|
|
271
|
+
* payload string using `secret`.
|
|
272
|
+
*
|
|
273
|
+
* @param params - Token inputs.
|
|
274
|
+
* @returns The signed token string.
|
|
275
|
+
*/
|
|
276
|
+
declare function generateDownloadToken(params: GenerateDownloadTokenOptions): string;
|
|
277
|
+
/**
|
|
278
|
+
* Input for verifying a download token.
|
|
279
|
+
*/
|
|
280
|
+
interface VerifyDownloadTokenOptions {
|
|
281
|
+
/** The token string to verify. */
|
|
282
|
+
token: string;
|
|
283
|
+
/** Expected email ID — must match the token payload exactly. */
|
|
284
|
+
emailId: string;
|
|
285
|
+
/** Expected audience — must match the token payload exactly. */
|
|
286
|
+
audience: string;
|
|
287
|
+
/** Shared HMAC secret. */
|
|
288
|
+
secret: string;
|
|
289
|
+
/** Override the current time (unix seconds) for deterministic tests. */
|
|
290
|
+
nowSeconds?: number;
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Result of verifying a download token.
|
|
294
|
+
*
|
|
295
|
+
* On failure, `error` is a short human-readable reason suitable for logs.
|
|
296
|
+
* Do not surface it to untrusted clients — it may reveal which check failed.
|
|
297
|
+
*/
|
|
298
|
+
type VerifyDownloadTokenResult = {
|
|
299
|
+
valid: true;
|
|
300
|
+
} | {
|
|
301
|
+
valid: false;
|
|
302
|
+
error: string;
|
|
303
|
+
};
|
|
304
|
+
/**
|
|
305
|
+
* Verify a signed download token.
|
|
306
|
+
*
|
|
307
|
+
* Returns a discriminated-union result. The function never throws for
|
|
308
|
+
* verification failures — only malformed inputs at the crypto layer would
|
|
309
|
+
* surface. Callers should check `result.valid` and log `result.error`.
|
|
310
|
+
*
|
|
311
|
+
* @param params - Verification inputs.
|
|
312
|
+
* @returns Whether the token is valid, plus a reason on failure.
|
|
313
|
+
*/
|
|
314
|
+
declare function verifyDownloadToken(params: VerifyDownloadTokenOptions): VerifyDownloadTokenResult;
|
|
315
|
+
|
|
227
316
|
//#endregion
|
|
228
317
|
//#region src/webhook/signing.d.ts
|
|
229
318
|
/**
|
|
@@ -1552,4 +1641,4 @@ declare function decodeRawEmail(event: EmailReceivedEvent, options?: DecodeRawEm
|
|
|
1552
1641
|
declare function verifyRawEmailDownload(downloaded: Buffer | ArrayBuffer | Uint8Array, event: EmailReceivedEvent): Buffer;
|
|
1553
1642
|
|
|
1554
1643
|
//#endregion
|
|
1555
|
-
export { DecodeRawEmailOptions, HandleWebhookOptions, LEGACY_CONFIRMED_HEADER as LEGACY_CONFIRMED_HEADER$1, LEGACY_SIGNATURE_HEADER as LEGACY_SIGNATURE_HEADER$1, PAYLOAD_ERRORS as PAYLOAD_ERRORS$1, PRIMITIVE_CONFIRMED_HEADER as PRIMITIVE_CONFIRMED_HEADER$1, PRIMITIVE_SIGNATURE_HEADER as PRIMITIVE_SIGNATURE_HEADER$1, PrimitiveWebhookError as PrimitiveWebhookError$1, RAW_EMAIL_ERRORS as RAW_EMAIL_ERRORS$1, RawEmailDecodeError as RawEmailDecodeError$1, RawEmailDecodeErrorCode, STANDARD_WEBHOOK_ID_HEADER as STANDARD_WEBHOOK_ID_HEADER$1, STANDARD_WEBHOOK_SIGNATURE_HEADER as STANDARD_WEBHOOK_SIGNATURE_HEADER$1, STANDARD_WEBHOOK_TIMESTAMP_HEADER as STANDARD_WEBHOOK_TIMESTAMP_HEADER$1, SignResult, StandardWebhooksSignResult, StandardWebhooksVerifyOptions, VERIFICATION_ERRORS as VERIFICATION_ERRORS$1, VerifyOptions, WEBHOOK_VERSION as WEBHOOK_VERSION$1, WebhookErrorCode, WebhookHeaders, WebhookPayloadError as WebhookPayloadError$1, WebhookPayloadErrorCode, WebhookValidationError as WebhookValidationError$1, WebhookValidationErrorCode, WebhookVerificationError as WebhookVerificationError$1, WebhookVerificationErrorCode, confirmedHeaders as confirmedHeaders$1, decodeRawEmail as decodeRawEmail$1, emailReceivedEventJsonSchema as emailReceivedEventJsonSchema$1, getDownloadTimeRemaining as getDownloadTimeRemaining$1, handleWebhook as handleWebhook$1, isDownloadExpired as isDownloadExpired$1, isEmailReceivedEvent as isEmailReceivedEvent$1, isRawIncluded as isRawIncluded$1, parseWebhookEvent as parseWebhookEvent$1, safeValidateEmailReceivedEvent as safeValidateEmailReceivedEvent$1, signStandardWebhooksPayload as signStandardWebhooksPayload$1, signWebhookPayload as signWebhookPayload$1, validateEmailAuth as validateEmailAuth$1, validateEmailReceivedEvent as validateEmailReceivedEvent$1, verifyRawEmailDownload as verifyRawEmailDownload$1, verifyStandardWebhooksSignature as verifyStandardWebhooksSignature$1, verifyWebhookSignature as verifyWebhookSignature$1 };
|
|
1644
|
+
export { DecodeRawEmailOptions, GenerateDownloadTokenOptions, HandleWebhookOptions, LEGACY_CONFIRMED_HEADER as LEGACY_CONFIRMED_HEADER$1, LEGACY_SIGNATURE_HEADER as LEGACY_SIGNATURE_HEADER$1, PAYLOAD_ERRORS as PAYLOAD_ERRORS$1, PRIMITIVE_CONFIRMED_HEADER as PRIMITIVE_CONFIRMED_HEADER$1, PRIMITIVE_SIGNATURE_HEADER as PRIMITIVE_SIGNATURE_HEADER$1, PrimitiveWebhookError as PrimitiveWebhookError$1, RAW_EMAIL_ERRORS as RAW_EMAIL_ERRORS$1, RawEmailDecodeError as RawEmailDecodeError$1, RawEmailDecodeErrorCode, STANDARD_WEBHOOK_ID_HEADER as STANDARD_WEBHOOK_ID_HEADER$1, STANDARD_WEBHOOK_SIGNATURE_HEADER as STANDARD_WEBHOOK_SIGNATURE_HEADER$1, STANDARD_WEBHOOK_TIMESTAMP_HEADER as STANDARD_WEBHOOK_TIMESTAMP_HEADER$1, SignResult, StandardWebhooksSignResult, StandardWebhooksVerifyOptions, VERIFICATION_ERRORS as VERIFICATION_ERRORS$1, VerifyDownloadTokenOptions, VerifyDownloadTokenResult, VerifyOptions, WEBHOOK_VERSION as WEBHOOK_VERSION$1, WebhookErrorCode, WebhookHeaders, WebhookPayloadError as WebhookPayloadError$1, WebhookPayloadErrorCode, WebhookValidationError as WebhookValidationError$1, WebhookValidationErrorCode, WebhookVerificationError as WebhookVerificationError$1, WebhookVerificationErrorCode, confirmedHeaders as confirmedHeaders$1, decodeRawEmail as decodeRawEmail$1, emailReceivedEventJsonSchema as emailReceivedEventJsonSchema$1, generateDownloadToken as generateDownloadToken$1, getDownloadTimeRemaining as getDownloadTimeRemaining$1, handleWebhook as handleWebhook$1, isDownloadExpired as isDownloadExpired$1, isEmailReceivedEvent as isEmailReceivedEvent$1, isRawIncluded as isRawIncluded$1, parseWebhookEvent as parseWebhookEvent$1, safeValidateEmailReceivedEvent as safeValidateEmailReceivedEvent$1, signStandardWebhooksPayload as signStandardWebhooksPayload$1, signWebhookPayload as signWebhookPayload$1, validateEmailAuth as validateEmailAuth$1, validateEmailReceivedEvent as validateEmailReceivedEvent$1, verifyDownloadToken as verifyDownloadToken$1, verifyRawEmailDownload as verifyRawEmailDownload$1, verifyStandardWebhooksSignature as verifyStandardWebhooksSignature$1, verifyWebhookSignature as verifyWebhookSignature$1 };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { AuthConfidence$1 as AuthConfidence, AuthVerdict$1 as AuthVerdict, DkimResult$1 as DkimResult, DkimSignature, DmarcPolicy$1 as DmarcPolicy, DmarcResult$1 as DmarcResult, EmailAddress, EmailAnalysis, EmailAuth, EmailReceivedEvent, EventType$1 as EventType, ForwardAnalysis, ForwardOriginalSender, ForwardResult, ForwardResultAttachmentAnalyzed, ForwardResultAttachmentSkipped, ForwardResultInline, ForwardVerdict$1 as ForwardVerdict, ForwardVerification, KnownWebhookEvent, ParsedData, ParsedDataComplete, ParsedDataFailed, ParsedError, ParsedStatus$1 as ParsedStatus, RawContent, RawContentDownloadOnly, RawContentInline, SpfResult$1 as SpfResult, UnknownEvent, ValidateEmailAuthResult, WebhookAttachment, WebhookEvent } from "./types-C3ms4R0d.js";
|
|
2
|
-
import { DecodeRawEmailOptions, HandleWebhookOptions, LEGACY_CONFIRMED_HEADER$1 as LEGACY_CONFIRMED_HEADER, LEGACY_SIGNATURE_HEADER$1 as LEGACY_SIGNATURE_HEADER, PAYLOAD_ERRORS$1 as PAYLOAD_ERRORS, PRIMITIVE_CONFIRMED_HEADER$1 as PRIMITIVE_CONFIRMED_HEADER, PRIMITIVE_SIGNATURE_HEADER$1 as PRIMITIVE_SIGNATURE_HEADER, PrimitiveWebhookError$1 as PrimitiveWebhookError, RAW_EMAIL_ERRORS$1 as RAW_EMAIL_ERRORS, RawEmailDecodeError$1 as RawEmailDecodeError, RawEmailDecodeErrorCode, STANDARD_WEBHOOK_ID_HEADER$1 as STANDARD_WEBHOOK_ID_HEADER, STANDARD_WEBHOOK_SIGNATURE_HEADER$1 as STANDARD_WEBHOOK_SIGNATURE_HEADER, STANDARD_WEBHOOK_TIMESTAMP_HEADER$1 as STANDARD_WEBHOOK_TIMESTAMP_HEADER, SignResult, StandardWebhooksSignResult, StandardWebhooksVerifyOptions, VERIFICATION_ERRORS$1 as VERIFICATION_ERRORS, VerifyOptions, WEBHOOK_VERSION$1 as WEBHOOK_VERSION, WebhookErrorCode, WebhookHeaders, WebhookPayloadError$1 as WebhookPayloadError, WebhookPayloadErrorCode, WebhookValidationError$1 as WebhookValidationError, WebhookValidationErrorCode, WebhookVerificationError$1 as WebhookVerificationError, WebhookVerificationErrorCode, confirmedHeaders$1 as confirmedHeaders, decodeRawEmail$1 as decodeRawEmail, emailReceivedEventJsonSchema$1 as emailReceivedEventJsonSchema, getDownloadTimeRemaining$1 as getDownloadTimeRemaining, handleWebhook$1 as handleWebhook, isDownloadExpired$1 as isDownloadExpired, isEmailReceivedEvent$1 as isEmailReceivedEvent, isRawIncluded$1 as isRawIncluded, parseWebhookEvent$1 as parseWebhookEvent, safeValidateEmailReceivedEvent$1 as safeValidateEmailReceivedEvent, signStandardWebhooksPayload$1 as signStandardWebhooksPayload, signWebhookPayload$1 as signWebhookPayload, validateEmailAuth$1 as validateEmailAuth, validateEmailReceivedEvent$1 as validateEmailReceivedEvent, verifyRawEmailDownload$1 as verifyRawEmailDownload, verifyStandardWebhooksSignature$1 as verifyStandardWebhooksSignature, verifyWebhookSignature$1 as verifyWebhookSignature } from "./index-
|
|
3
|
-
export { AuthConfidence, AuthVerdict, DecodeRawEmailOptions, DkimResult, DkimSignature, DmarcPolicy, DmarcResult, EmailAddress, EmailAnalysis, EmailAuth, EmailReceivedEvent, EventType, ForwardAnalysis, ForwardOriginalSender, ForwardResult, ForwardResultAttachmentAnalyzed, ForwardResultAttachmentSkipped, ForwardResultInline, ForwardVerdict, ForwardVerification, HandleWebhookOptions, KnownWebhookEvent, LEGACY_CONFIRMED_HEADER, LEGACY_SIGNATURE_HEADER, PAYLOAD_ERRORS, PRIMITIVE_CONFIRMED_HEADER, PRIMITIVE_SIGNATURE_HEADER, ParsedData, ParsedDataComplete, ParsedDataFailed, ParsedError, ParsedStatus, PrimitiveWebhookError, RAW_EMAIL_ERRORS, RawContent, RawContentDownloadOnly, RawContentInline, RawEmailDecodeError, RawEmailDecodeErrorCode, STANDARD_WEBHOOK_ID_HEADER, STANDARD_WEBHOOK_SIGNATURE_HEADER, STANDARD_WEBHOOK_TIMESTAMP_HEADER, SignResult, SpfResult, StandardWebhooksSignResult, StandardWebhooksVerifyOptions, UnknownEvent, VERIFICATION_ERRORS, ValidateEmailAuthResult, VerifyOptions, WEBHOOK_VERSION, WebhookAttachment, WebhookErrorCode, WebhookEvent, WebhookHeaders, WebhookPayloadError, WebhookPayloadErrorCode, WebhookValidationError, WebhookValidationErrorCode, WebhookVerificationError, WebhookVerificationErrorCode, confirmedHeaders, decodeRawEmail, emailReceivedEventJsonSchema, getDownloadTimeRemaining, handleWebhook, isDownloadExpired, isEmailReceivedEvent, isRawIncluded, parseWebhookEvent, safeValidateEmailReceivedEvent, signStandardWebhooksPayload, signWebhookPayload, validateEmailAuth, validateEmailReceivedEvent, verifyRawEmailDownload, verifyStandardWebhooksSignature, verifyWebhookSignature };
|
|
2
|
+
import { DecodeRawEmailOptions, GenerateDownloadTokenOptions, HandleWebhookOptions, LEGACY_CONFIRMED_HEADER$1 as LEGACY_CONFIRMED_HEADER, LEGACY_SIGNATURE_HEADER$1 as LEGACY_SIGNATURE_HEADER, PAYLOAD_ERRORS$1 as PAYLOAD_ERRORS, PRIMITIVE_CONFIRMED_HEADER$1 as PRIMITIVE_CONFIRMED_HEADER, PRIMITIVE_SIGNATURE_HEADER$1 as PRIMITIVE_SIGNATURE_HEADER, PrimitiveWebhookError$1 as PrimitiveWebhookError, RAW_EMAIL_ERRORS$1 as RAW_EMAIL_ERRORS, RawEmailDecodeError$1 as RawEmailDecodeError, RawEmailDecodeErrorCode, STANDARD_WEBHOOK_ID_HEADER$1 as STANDARD_WEBHOOK_ID_HEADER, STANDARD_WEBHOOK_SIGNATURE_HEADER$1 as STANDARD_WEBHOOK_SIGNATURE_HEADER, STANDARD_WEBHOOK_TIMESTAMP_HEADER$1 as STANDARD_WEBHOOK_TIMESTAMP_HEADER, SignResult, StandardWebhooksSignResult, StandardWebhooksVerifyOptions, VERIFICATION_ERRORS$1 as VERIFICATION_ERRORS, VerifyDownloadTokenOptions, VerifyDownloadTokenResult, VerifyOptions, WEBHOOK_VERSION$1 as WEBHOOK_VERSION, WebhookErrorCode, WebhookHeaders, WebhookPayloadError$1 as WebhookPayloadError, WebhookPayloadErrorCode, WebhookValidationError$1 as WebhookValidationError, WebhookValidationErrorCode, WebhookVerificationError$1 as WebhookVerificationError, WebhookVerificationErrorCode, confirmedHeaders$1 as confirmedHeaders, decodeRawEmail$1 as decodeRawEmail, emailReceivedEventJsonSchema$1 as emailReceivedEventJsonSchema, generateDownloadToken$1 as generateDownloadToken, getDownloadTimeRemaining$1 as getDownloadTimeRemaining, handleWebhook$1 as handleWebhook, isDownloadExpired$1 as isDownloadExpired, isEmailReceivedEvent$1 as isEmailReceivedEvent, isRawIncluded$1 as isRawIncluded, parseWebhookEvent$1 as parseWebhookEvent, safeValidateEmailReceivedEvent$1 as safeValidateEmailReceivedEvent, signStandardWebhooksPayload$1 as signStandardWebhooksPayload, signWebhookPayload$1 as signWebhookPayload, validateEmailAuth$1 as validateEmailAuth, validateEmailReceivedEvent$1 as validateEmailReceivedEvent, verifyDownloadToken$1 as verifyDownloadToken, verifyRawEmailDownload$1 as verifyRawEmailDownload, verifyStandardWebhooksSignature$1 as verifyStandardWebhooksSignature, verifyWebhookSignature$1 as verifyWebhookSignature } from "./index-C7tHPMZM.js";
|
|
3
|
+
export { AuthConfidence, AuthVerdict, DecodeRawEmailOptions, DkimResult, DkimSignature, DmarcPolicy, DmarcResult, EmailAddress, EmailAnalysis, EmailAuth, EmailReceivedEvent, EventType, ForwardAnalysis, ForwardOriginalSender, ForwardResult, ForwardResultAttachmentAnalyzed, ForwardResultAttachmentSkipped, ForwardResultInline, ForwardVerdict, ForwardVerification, GenerateDownloadTokenOptions, HandleWebhookOptions, KnownWebhookEvent, LEGACY_CONFIRMED_HEADER, LEGACY_SIGNATURE_HEADER, PAYLOAD_ERRORS, PRIMITIVE_CONFIRMED_HEADER, PRIMITIVE_SIGNATURE_HEADER, ParsedData, ParsedDataComplete, ParsedDataFailed, ParsedError, ParsedStatus, PrimitiveWebhookError, RAW_EMAIL_ERRORS, RawContent, RawContentDownloadOnly, RawContentInline, RawEmailDecodeError, RawEmailDecodeErrorCode, STANDARD_WEBHOOK_ID_HEADER, STANDARD_WEBHOOK_SIGNATURE_HEADER, STANDARD_WEBHOOK_TIMESTAMP_HEADER, SignResult, SpfResult, StandardWebhooksSignResult, StandardWebhooksVerifyOptions, UnknownEvent, VERIFICATION_ERRORS, ValidateEmailAuthResult, VerifyDownloadTokenOptions, VerifyDownloadTokenResult, VerifyOptions, WEBHOOK_VERSION, WebhookAttachment, WebhookErrorCode, WebhookEvent, WebhookHeaders, WebhookPayloadError, WebhookPayloadErrorCode, WebhookValidationError, WebhookValidationErrorCode, WebhookVerificationError, WebhookVerificationErrorCode, confirmedHeaders, decodeRawEmail, emailReceivedEventJsonSchema, generateDownloadToken, getDownloadTimeRemaining, handleWebhook, isDownloadExpired, isEmailReceivedEvent, isRawIncluded, parseWebhookEvent, safeValidateEmailReceivedEvent, signStandardWebhooksPayload, signWebhookPayload, validateEmailAuth, validateEmailReceivedEvent, verifyDownloadToken, verifyRawEmailDownload, verifyStandardWebhooksSignature, verifyWebhookSignature };
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { AuthConfidence, AuthVerdict, DkimResult, DmarcPolicy, DmarcResult, EventType, ForwardVerdict, LEGACY_CONFIRMED_HEADER, LEGACY_SIGNATURE_HEADER, PAYLOAD_ERRORS, 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_VERSION, WebhookPayloadError, WebhookValidationError, WebhookVerificationError, confirmedHeaders, decodeRawEmail, emailReceivedEventJsonSchema, getDownloadTimeRemaining, handleWebhook, isDownloadExpired, isEmailReceivedEvent, isRawIncluded, parseWebhookEvent, safeValidateEmailReceivedEvent, signStandardWebhooksPayload, signWebhookPayload, validateEmailAuth, validateEmailReceivedEvent, verifyRawEmailDownload, verifyStandardWebhooksSignature, verifyWebhookSignature } from "./webhook-
|
|
1
|
+
import { AuthConfidence, AuthVerdict, DkimResult, DmarcPolicy, DmarcResult, EventType, ForwardVerdict, LEGACY_CONFIRMED_HEADER, LEGACY_SIGNATURE_HEADER, PAYLOAD_ERRORS, 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_VERSION, WebhookPayloadError, WebhookValidationError, WebhookVerificationError, confirmedHeaders, decodeRawEmail, emailReceivedEventJsonSchema, generateDownloadToken, getDownloadTimeRemaining, handleWebhook, isDownloadExpired, isEmailReceivedEvent, isRawIncluded, parseWebhookEvent, safeValidateEmailReceivedEvent, signStandardWebhooksPayload, signWebhookPayload, validateEmailAuth, validateEmailReceivedEvent, verifyDownloadToken, verifyRawEmailDownload, verifyStandardWebhooksSignature, verifyWebhookSignature } from "./webhook-C5kOt3fb.js";
|
|
2
2
|
|
|
3
|
-
export { AuthConfidence, AuthVerdict, DkimResult, DmarcPolicy, DmarcResult, EventType, ForwardVerdict, LEGACY_CONFIRMED_HEADER, LEGACY_SIGNATURE_HEADER, PAYLOAD_ERRORS, 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_VERSION, WebhookPayloadError, WebhookValidationError, WebhookVerificationError, confirmedHeaders, decodeRawEmail, emailReceivedEventJsonSchema, getDownloadTimeRemaining, handleWebhook, isDownloadExpired, isEmailReceivedEvent, isRawIncluded, parseWebhookEvent, safeValidateEmailReceivedEvent, signStandardWebhooksPayload, signWebhookPayload, validateEmailAuth, validateEmailReceivedEvent, verifyRawEmailDownload, verifyStandardWebhooksSignature, verifyWebhookSignature };
|
|
3
|
+
export { AuthConfidence, AuthVerdict, DkimResult, DmarcPolicy, DmarcResult, EventType, ForwardVerdict, LEGACY_CONFIRMED_HEADER, LEGACY_SIGNATURE_HEADER, PAYLOAD_ERRORS, 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_VERSION, WebhookPayloadError, WebhookValidationError, WebhookVerificationError, confirmedHeaders, decodeRawEmail, emailReceivedEventJsonSchema, generateDownloadToken, getDownloadTimeRemaining, handleWebhook, isDownloadExpired, isEmailReceivedEvent, isRawIncluded, parseWebhookEvent, safeValidateEmailReceivedEvent, signStandardWebhooksPayload, signWebhookPayload, validateEmailAuth, validateEmailReceivedEvent, verifyDownloadToken, verifyRawEmailDownload, verifyStandardWebhooksSignature, verifyWebhookSignature };
|
|
@@ -7,7 +7,7 @@ function flagName(parameterName) {
|
|
|
7
7
|
function flagDescription(parameter) {
|
|
8
8
|
return parameter.description ?? parameter.name;
|
|
9
9
|
}
|
|
10
|
-
function flagForParameter(parameter) {
|
|
10
|
+
export function flagForParameter(parameter) {
|
|
11
11
|
const common = {
|
|
12
12
|
description: flagDescription(parameter),
|
|
13
13
|
required: parameter.required,
|
|
@@ -18,6 +18,9 @@ function flagForParameter(parameter) {
|
|
|
18
18
|
if (parameter.type === "integer") {
|
|
19
19
|
return Flags.integer(common);
|
|
20
20
|
}
|
|
21
|
+
if (parameter.enum && parameter.enum.length > 0) {
|
|
22
|
+
return Flags.string({ ...common, options: parameter.enum });
|
|
23
|
+
}
|
|
21
24
|
return Flags.string(common);
|
|
22
25
|
}
|
|
23
26
|
function coerceParameterValue(parameter, value) {
|
|
@@ -41,20 +44,82 @@ function coerceParameterValue(parameter, value) {
|
|
|
41
44
|
}
|
|
42
45
|
throw new Errors.CLIError(`Unsupported flag value for --${parameter.name}`);
|
|
43
46
|
}
|
|
44
|
-
function
|
|
47
|
+
function cliError(message) {
|
|
48
|
+
return new Errors.CLIError(message, { exit: 1 });
|
|
49
|
+
}
|
|
50
|
+
function parseJson(source, flagLabel) {
|
|
51
|
+
try {
|
|
52
|
+
return JSON.parse(source);
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
56
|
+
throw cliError(`${flagLabel} is not valid JSON: ${detail}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
export function readJsonBody(flags) {
|
|
45
60
|
const bodyFile = flags["body-file"];
|
|
46
61
|
const body = flags.body;
|
|
47
62
|
if (bodyFile && body) {
|
|
48
|
-
throw
|
|
63
|
+
throw cliError("Use either --body or --body-file, not both");
|
|
49
64
|
}
|
|
50
65
|
if (typeof bodyFile === "string") {
|
|
51
|
-
|
|
66
|
+
let contents;
|
|
67
|
+
try {
|
|
68
|
+
contents = readFileSync(bodyFile, "utf8");
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
72
|
+
throw cliError(`Could not read --body-file ${bodyFile}: ${detail}`);
|
|
73
|
+
}
|
|
74
|
+
return parseJson(contents, `--body-file ${bodyFile}`);
|
|
52
75
|
}
|
|
53
76
|
if (typeof body === "string") {
|
|
54
|
-
return
|
|
77
|
+
return parseJson(body, "--body");
|
|
55
78
|
}
|
|
56
79
|
return undefined;
|
|
57
80
|
}
|
|
81
|
+
export function extractErrorPayload(raw) {
|
|
82
|
+
if (raw &&
|
|
83
|
+
typeof raw === "object" &&
|
|
84
|
+
!(raw instanceof Error) &&
|
|
85
|
+
"error" in raw) {
|
|
86
|
+
const inner = raw.error;
|
|
87
|
+
if (inner !== null && inner !== undefined) {
|
|
88
|
+
return inner;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return raw;
|
|
92
|
+
}
|
|
93
|
+
function extractCauseDetails(cause) {
|
|
94
|
+
const details = {};
|
|
95
|
+
let code;
|
|
96
|
+
if (!cause || typeof cause !== "object") {
|
|
97
|
+
return { details };
|
|
98
|
+
}
|
|
99
|
+
for (const [key, value] of Object.entries(cause)) {
|
|
100
|
+
if (typeof value === "string" || typeof value === "number") {
|
|
101
|
+
details[key] = value;
|
|
102
|
+
if (key === "code" && typeof value === "string") {
|
|
103
|
+
code = value;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return { code, details };
|
|
108
|
+
}
|
|
109
|
+
export function formatErrorPayload(payload) {
|
|
110
|
+
if (payload instanceof Error) {
|
|
111
|
+
const { code, details } = extractCauseDetails(payload.cause);
|
|
112
|
+
const body = {
|
|
113
|
+
code: code ?? "client_error",
|
|
114
|
+
message: payload.message || payload.name || String(payload),
|
|
115
|
+
};
|
|
116
|
+
if (Object.keys(details).length > 0) {
|
|
117
|
+
body.cause = details;
|
|
118
|
+
}
|
|
119
|
+
return JSON.stringify(body, null, 2);
|
|
120
|
+
}
|
|
121
|
+
return JSON.stringify(payload, null, 2);
|
|
122
|
+
}
|
|
58
123
|
function buildFlags(operation) {
|
|
59
124
|
const flags = {
|
|
60
125
|
"api-key": Flags.string({
|
|
@@ -125,9 +190,8 @@ export function createOperationCommand(operation) {
|
|
|
125
190
|
responseStyle: "fields",
|
|
126
191
|
});
|
|
127
192
|
if (result.error) {
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
process.stderr.write(`${JSON.stringify(errorPayload, null, 2)}\n`);
|
|
193
|
+
const errorPayload = extractErrorPayload(result.error);
|
|
194
|
+
process.stderr.write(`${formatErrorPayload(errorPayload)}\n`);
|
|
131
195
|
process.exitCode = 1;
|
|
132
196
|
return;
|
|
133
197
|
}
|
package/dist/openapi/index.d.ts
CHANGED
|
@@ -355,6 +355,44 @@ export const openapiDocument = {
|
|
|
355
355
|
},
|
|
356
356
|
"401": {
|
|
357
357
|
"$ref": "#/components/responses/Unauthorized"
|
|
358
|
+
},
|
|
359
|
+
"409": {
|
|
360
|
+
"description": "Domain claim conflicts with existing state. Two error codes\nare possible:\n * `mx_conflict`: the domain's current MX records point at\n another mailbox provider. The response includes\n `error.details.mx_conflict` with the detected provider\n and a suggested subdomain.\n * `conflict`: the domain is already claimed by another\n org, or a pending claim exists for another user.\n",
|
|
361
|
+
"content": {
|
|
362
|
+
"application/json": {
|
|
363
|
+
"schema": {
|
|
364
|
+
"$ref": "#/components/schemas/ErrorResponse"
|
|
365
|
+
},
|
|
366
|
+
"examples": {
|
|
367
|
+
"mx_conflict": {
|
|
368
|
+
"summary": "Domain has MX records on another provider",
|
|
369
|
+
"value": {
|
|
370
|
+
"success": false,
|
|
371
|
+
"error": {
|
|
372
|
+
"code": "mx_conflict",
|
|
373
|
+
"message": "Domain is currently receiving mail via another provider",
|
|
374
|
+
"details": {
|
|
375
|
+
"mx_conflict": {
|
|
376
|
+
"provider_name": "Google Workspace",
|
|
377
|
+
"suggested_subdomain": "mail"
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
},
|
|
383
|
+
"already_claimed": {
|
|
384
|
+
"summary": "Domain already claimed by another org",
|
|
385
|
+
"value": {
|
|
386
|
+
"success": false,
|
|
387
|
+
"error": {
|
|
388
|
+
"code": "conflict",
|
|
389
|
+
"message": "Domain is already claimed by another organization"
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
358
396
|
}
|
|
359
397
|
}
|
|
360
398
|
}
|
|
@@ -809,7 +847,7 @@ export const openapiDocument = {
|
|
|
809
847
|
"post": {
|
|
810
848
|
"operationId": "replayEmailWebhooks",
|
|
811
849
|
"summary": "Replay email webhooks",
|
|
812
|
-
"description": "Re-delivers the webhook payload for this email to all active\nendpoints matching the email's domain.
|
|
850
|
+
"description": "Re-delivers the webhook payload for this email to all active\nendpoints matching the email's domain. Rate limited per-email\n(short cooldown between successive replays of the same email)\nand per-org (burst + sustained windows), sharing an org-wide\nbudget with delivery replays.\n",
|
|
813
851
|
"tags": [
|
|
814
852
|
"Emails"
|
|
815
853
|
],
|
|
@@ -844,6 +882,9 @@ export const openapiDocument = {
|
|
|
844
882
|
},
|
|
845
883
|
"404": {
|
|
846
884
|
"$ref": "#/components/responses/NotFound"
|
|
885
|
+
},
|
|
886
|
+
"429": {
|
|
887
|
+
"$ref": "#/components/responses/RateLimited"
|
|
847
888
|
}
|
|
848
889
|
}
|
|
849
890
|
}
|
|
@@ -1345,7 +1386,7 @@ export const openapiDocument = {
|
|
|
1345
1386
|
"post": {
|
|
1346
1387
|
"operationId": "replayDelivery",
|
|
1347
1388
|
"summary": "Replay a webhook delivery",
|
|
1348
|
-
"description": "Re-sends the stored webhook payload from a previous delivery attempt.\nIf the original endpoint is still active, it is targeted. If the\noriginal endpoint was deleted, the
|
|
1389
|
+
"description": "Re-sends the stored webhook payload from a previous delivery attempt.\nIf the original endpoint is still active, it is targeted. If the\noriginal endpoint was deleted, the oldest active endpoint is used.\nDeactivated endpoints cannot be replayed to. Rate limited per-org,\nsharing an org-wide budget with email replays.\n",
|
|
1349
1390
|
"tags": [
|
|
1350
1391
|
"Webhook Deliveries"
|
|
1351
1392
|
],
|
|
@@ -1380,6 +1421,9 @@ export const openapiDocument = {
|
|
|
1380
1421
|
},
|
|
1381
1422
|
"404": {
|
|
1382
1423
|
"$ref": "#/components/responses/NotFound"
|
|
1424
|
+
},
|
|
1425
|
+
"429": {
|
|
1426
|
+
"$ref": "#/components/responses/RateLimited"
|
|
1383
1427
|
}
|
|
1384
1428
|
}
|
|
1385
1429
|
}
|
|
@@ -1613,11 +1657,38 @@ export const openapiDocument = {
|
|
|
1613
1657
|
"not_found",
|
|
1614
1658
|
"validation_error",
|
|
1615
1659
|
"rate_limit_exceeded",
|
|
1616
|
-
"internal_error"
|
|
1660
|
+
"internal_error",
|
|
1661
|
+
"conflict",
|
|
1662
|
+
"mx_conflict"
|
|
1617
1663
|
]
|
|
1618
1664
|
},
|
|
1619
1665
|
"message": {
|
|
1620
1666
|
"type": "string"
|
|
1667
|
+
},
|
|
1668
|
+
"details": {
|
|
1669
|
+
"type": "object",
|
|
1670
|
+
"description": "Optional structured data that callers can inspect to recover\nfrom the error. The fields present depend on `code`. Additional\nkeys may be added over time without a major-version bump.\n",
|
|
1671
|
+
"additionalProperties": true,
|
|
1672
|
+
"properties": {
|
|
1673
|
+
"mx_conflict": {
|
|
1674
|
+
"type": "object",
|
|
1675
|
+
"description": "Present when `code == mx_conflict`.",
|
|
1676
|
+
"required": [
|
|
1677
|
+
"provider_name",
|
|
1678
|
+
"suggested_subdomain"
|
|
1679
|
+
],
|
|
1680
|
+
"properties": {
|
|
1681
|
+
"provider_name": {
|
|
1682
|
+
"type": "string",
|
|
1683
|
+
"description": "Human-readable name of the detected mailbox provider (e.g. \"Google Workspace\")."
|
|
1684
|
+
},
|
|
1685
|
+
"suggested_subdomain": {
|
|
1686
|
+
"type": "string",
|
|
1687
|
+
"description": "Subdomain to try instead (e.g. \"mail\" for `mail.example.com`)."
|
|
1688
|
+
}
|
|
1689
|
+
}
|
|
1690
|
+
}
|
|
1691
|
+
}
|
|
1621
1692
|
}
|
|
1622
1693
|
},
|
|
1623
1694
|
"required": [
|
|
@@ -113,6 +113,7 @@ export const operationManifest = [
|
|
|
113
113
|
"pathParams": [
|
|
114
114
|
{
|
|
115
115
|
"description": "Resource UUID",
|
|
116
|
+
"enum": null,
|
|
116
117
|
"name": "id",
|
|
117
118
|
"required": true,
|
|
118
119
|
"type": "string"
|
|
@@ -152,6 +153,7 @@ export const operationManifest = [
|
|
|
152
153
|
"pathParams": [
|
|
153
154
|
{
|
|
154
155
|
"description": "Resource UUID",
|
|
156
|
+
"enum": null,
|
|
155
157
|
"name": "id",
|
|
156
158
|
"required": true,
|
|
157
159
|
"type": "string"
|
|
@@ -175,6 +177,7 @@ export const operationManifest = [
|
|
|
175
177
|
"pathParams": [
|
|
176
178
|
{
|
|
177
179
|
"description": "Resource UUID",
|
|
180
|
+
"enum": null,
|
|
178
181
|
"name": "id",
|
|
179
182
|
"required": true,
|
|
180
183
|
"type": "string"
|
|
@@ -198,6 +201,7 @@ export const operationManifest = [
|
|
|
198
201
|
"pathParams": [
|
|
199
202
|
{
|
|
200
203
|
"description": "Resource UUID",
|
|
204
|
+
"enum": null,
|
|
201
205
|
"name": "id",
|
|
202
206
|
"required": true,
|
|
203
207
|
"type": "string"
|
|
@@ -221,6 +225,7 @@ export const operationManifest = [
|
|
|
221
225
|
"pathParams": [
|
|
222
226
|
{
|
|
223
227
|
"description": "Resource UUID",
|
|
228
|
+
"enum": null,
|
|
224
229
|
"name": "id",
|
|
225
230
|
"required": true,
|
|
226
231
|
"type": "string"
|
|
@@ -229,6 +234,7 @@ export const operationManifest = [
|
|
|
229
234
|
"queryParams": [
|
|
230
235
|
{
|
|
231
236
|
"description": "Signed download token from webhook payload",
|
|
237
|
+
"enum": null,
|
|
232
238
|
"name": "token",
|
|
233
239
|
"required": false,
|
|
234
240
|
"type": "string"
|
|
@@ -251,6 +257,7 @@ export const operationManifest = [
|
|
|
251
257
|
"pathParams": [
|
|
252
258
|
{
|
|
253
259
|
"description": "Resource UUID",
|
|
260
|
+
"enum": null,
|
|
254
261
|
"name": "id",
|
|
255
262
|
"required": true,
|
|
256
263
|
"type": "string"
|
|
@@ -259,6 +266,7 @@ export const operationManifest = [
|
|
|
259
266
|
"queryParams": [
|
|
260
267
|
{
|
|
261
268
|
"description": "Signed download token from webhook payload",
|
|
269
|
+
"enum": null,
|
|
262
270
|
"name": "token",
|
|
263
271
|
"required": false,
|
|
264
272
|
"type": "string"
|
|
@@ -281,6 +289,7 @@ export const operationManifest = [
|
|
|
281
289
|
"pathParams": [
|
|
282
290
|
{
|
|
283
291
|
"description": "Resource UUID",
|
|
292
|
+
"enum": null,
|
|
284
293
|
"name": "id",
|
|
285
294
|
"required": true,
|
|
286
295
|
"type": "string"
|
|
@@ -305,42 +314,54 @@ export const operationManifest = [
|
|
|
305
314
|
"queryParams": [
|
|
306
315
|
{
|
|
307
316
|
"description": "Pagination cursor from a previous response's `meta.cursor` field.\nFormat: `{ISO-datetime}|{id}`\n",
|
|
317
|
+
"enum": null,
|
|
308
318
|
"name": "cursor",
|
|
309
319
|
"required": false,
|
|
310
320
|
"type": "string"
|
|
311
321
|
},
|
|
312
322
|
{
|
|
313
323
|
"description": "Number of results per page",
|
|
324
|
+
"enum": null,
|
|
314
325
|
"name": "limit",
|
|
315
326
|
"required": false,
|
|
316
327
|
"type": "integer"
|
|
317
328
|
},
|
|
318
329
|
{
|
|
319
330
|
"description": "Filter by domain ID",
|
|
331
|
+
"enum": null,
|
|
320
332
|
"name": "domain_id",
|
|
321
333
|
"required": false,
|
|
322
334
|
"type": "string"
|
|
323
335
|
},
|
|
324
336
|
{
|
|
325
337
|
"description": "Filter by email status",
|
|
338
|
+
"enum": [
|
|
339
|
+
"pending",
|
|
340
|
+
"accepted",
|
|
341
|
+
"completed",
|
|
342
|
+
"rejected"
|
|
343
|
+
],
|
|
326
344
|
"name": "status",
|
|
327
345
|
"required": false,
|
|
328
346
|
"type": "string"
|
|
329
347
|
},
|
|
330
348
|
{
|
|
331
349
|
"description": "Search subject, sender, and recipient (case-insensitive)",
|
|
350
|
+
"enum": null,
|
|
332
351
|
"name": "search",
|
|
333
352
|
"required": false,
|
|
334
353
|
"type": "string"
|
|
335
354
|
},
|
|
336
355
|
{
|
|
337
356
|
"description": "Filter emails created on or after this timestamp",
|
|
357
|
+
"enum": null,
|
|
338
358
|
"name": "date_from",
|
|
339
359
|
"required": false,
|
|
340
360
|
"type": "string"
|
|
341
361
|
},
|
|
342
362
|
{
|
|
343
363
|
"description": "Filter emails created on or before this timestamp",
|
|
364
|
+
"enum": null,
|
|
344
365
|
"name": "date_to",
|
|
345
366
|
"required": false,
|
|
346
367
|
"type": "string"
|
|
@@ -355,7 +376,7 @@ export const operationManifest = [
|
|
|
355
376
|
"binaryResponse": false,
|
|
356
377
|
"bodyRequired": false,
|
|
357
378
|
"command": "replay-email-webhooks",
|
|
358
|
-
"description": "Re-delivers the webhook payload for this email to all active\nendpoints matching the email's domain.
|
|
379
|
+
"description": "Re-delivers the webhook payload for this email to all active\nendpoints matching the email's domain. Rate limited per-email\n(short cooldown between successive replays of the same email)\nand per-org (burst + sustained windows), sharing an org-wide\nbudget with delivery replays.\n",
|
|
359
380
|
"hasJsonBody": false,
|
|
360
381
|
"method": "POST",
|
|
361
382
|
"operationId": "replayEmailWebhooks",
|
|
@@ -363,6 +384,7 @@ export const operationManifest = [
|
|
|
363
384
|
"pathParams": [
|
|
364
385
|
{
|
|
365
386
|
"description": "Resource UUID",
|
|
387
|
+
"enum": null,
|
|
366
388
|
"name": "id",
|
|
367
389
|
"required": true,
|
|
368
390
|
"type": "string"
|
|
@@ -402,6 +424,7 @@ export const operationManifest = [
|
|
|
402
424
|
"pathParams": [
|
|
403
425
|
{
|
|
404
426
|
"description": "Resource UUID",
|
|
427
|
+
"enum": null,
|
|
405
428
|
"name": "id",
|
|
406
429
|
"required": true,
|
|
407
430
|
"type": "string"
|
|
@@ -441,6 +464,7 @@ export const operationManifest = [
|
|
|
441
464
|
"pathParams": [
|
|
442
465
|
{
|
|
443
466
|
"description": "Resource UUID",
|
|
467
|
+
"enum": null,
|
|
444
468
|
"name": "id",
|
|
445
469
|
"required": true,
|
|
446
470
|
"type": "string"
|
|
@@ -464,6 +488,7 @@ export const operationManifest = [
|
|
|
464
488
|
"pathParams": [
|
|
465
489
|
{
|
|
466
490
|
"description": "Resource UUID",
|
|
491
|
+
"enum": null,
|
|
467
492
|
"name": "id",
|
|
468
493
|
"required": true,
|
|
469
494
|
"type": "string"
|
|
@@ -503,6 +528,7 @@ export const operationManifest = [
|
|
|
503
528
|
"pathParams": [
|
|
504
529
|
{
|
|
505
530
|
"description": "Resource UUID",
|
|
531
|
+
"enum": null,
|
|
506
532
|
"name": "id",
|
|
507
533
|
"required": true,
|
|
508
534
|
"type": "string"
|
|
@@ -542,6 +568,7 @@ export const operationManifest = [
|
|
|
542
568
|
"pathParams": [
|
|
543
569
|
{
|
|
544
570
|
"description": "Resource UUID",
|
|
571
|
+
"enum": null,
|
|
545
572
|
"name": "id",
|
|
546
573
|
"required": true,
|
|
547
574
|
"type": "string"
|
|
@@ -566,36 +593,47 @@ export const operationManifest = [
|
|
|
566
593
|
"queryParams": [
|
|
567
594
|
{
|
|
568
595
|
"description": "Pagination cursor from a previous response's `meta.cursor` field.\nFormat: `{ISO-datetime}|{id}`\n",
|
|
596
|
+
"enum": null,
|
|
569
597
|
"name": "cursor",
|
|
570
598
|
"required": false,
|
|
571
599
|
"type": "string"
|
|
572
600
|
},
|
|
573
601
|
{
|
|
574
602
|
"description": "Number of results per page",
|
|
603
|
+
"enum": null,
|
|
575
604
|
"name": "limit",
|
|
576
605
|
"required": false,
|
|
577
606
|
"type": "integer"
|
|
578
607
|
},
|
|
579
608
|
{
|
|
580
609
|
"description": "Filter by email ID",
|
|
610
|
+
"enum": null,
|
|
581
611
|
"name": "email_id",
|
|
582
612
|
"required": false,
|
|
583
613
|
"type": "string"
|
|
584
614
|
},
|
|
585
615
|
{
|
|
586
616
|
"description": "Filter by delivery status",
|
|
617
|
+
"enum": [
|
|
618
|
+
"pending",
|
|
619
|
+
"delivered",
|
|
620
|
+
"header_confirmed",
|
|
621
|
+
"failed"
|
|
622
|
+
],
|
|
587
623
|
"name": "status",
|
|
588
624
|
"required": false,
|
|
589
625
|
"type": "string"
|
|
590
626
|
},
|
|
591
627
|
{
|
|
592
628
|
"description": "Filter deliveries created on or after this timestamp",
|
|
629
|
+
"enum": null,
|
|
593
630
|
"name": "date_from",
|
|
594
631
|
"required": false,
|
|
595
632
|
"type": "string"
|
|
596
633
|
},
|
|
597
634
|
{
|
|
598
635
|
"description": "Filter deliveries created on or before this timestamp",
|
|
636
|
+
"enum": null,
|
|
599
637
|
"name": "date_to",
|
|
600
638
|
"required": false,
|
|
601
639
|
"type": "string"
|
|
@@ -610,7 +648,7 @@ export const operationManifest = [
|
|
|
610
648
|
"binaryResponse": false,
|
|
611
649
|
"bodyRequired": false,
|
|
612
650
|
"command": "replay-delivery",
|
|
613
|
-
"description": "Re-sends the stored webhook payload from a previous delivery attempt.\nIf the original endpoint is still active, it is targeted. If the\noriginal endpoint was deleted, the
|
|
651
|
+
"description": "Re-sends the stored webhook payload from a previous delivery attempt.\nIf the original endpoint is still active, it is targeted. If the\noriginal endpoint was deleted, the oldest active endpoint is used.\nDeactivated endpoints cannot be replayed to. Rate limited per-org,\nsharing an org-wide budget with email replays.\n",
|
|
614
652
|
"hasJsonBody": false,
|
|
615
653
|
"method": "POST",
|
|
616
654
|
"operationId": "replayDelivery",
|
|
@@ -618,6 +656,7 @@ export const operationManifest = [
|
|
|
618
656
|
"pathParams": [
|
|
619
657
|
{
|
|
620
658
|
"description": "Delivery ID (numeric)",
|
|
659
|
+
"enum": null,
|
|
621
660
|
"name": "id",
|
|
622
661
|
"required": true,
|
|
623
662
|
"type": "string"
|
package/dist/webhook/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { AuthConfidence$1 as AuthConfidence, AuthVerdict$1 as AuthVerdict, DkimResult$1 as DkimResult, DkimSignature, DmarcPolicy$1 as DmarcPolicy, DmarcResult$1 as DmarcResult, EmailAddress, EmailAnalysis, EmailAuth, EmailReceivedEvent, EventType$1 as EventType, ForwardAnalysis, ForwardOriginalSender, ForwardResult, ForwardResultAttachmentAnalyzed, ForwardResultAttachmentSkipped, ForwardResultInline, ForwardVerdict$1 as ForwardVerdict, ForwardVerification, KnownWebhookEvent, ParsedData, ParsedDataComplete, ParsedDataFailed, ParsedError, ParsedStatus$1 as ParsedStatus, RawContent, RawContentDownloadOnly, RawContentInline, SpfResult$1 as SpfResult, UnknownEvent, ValidateEmailAuthResult, WebhookAttachment, WebhookEvent } from "../types-C3ms4R0d.js";
|
|
2
|
-
import { DecodeRawEmailOptions, HandleWebhookOptions, LEGACY_CONFIRMED_HEADER$1 as LEGACY_CONFIRMED_HEADER, LEGACY_SIGNATURE_HEADER$1 as LEGACY_SIGNATURE_HEADER, PAYLOAD_ERRORS$1 as PAYLOAD_ERRORS, PRIMITIVE_CONFIRMED_HEADER$1 as PRIMITIVE_CONFIRMED_HEADER, PRIMITIVE_SIGNATURE_HEADER$1 as PRIMITIVE_SIGNATURE_HEADER, PrimitiveWebhookError$1 as PrimitiveWebhookError, RAW_EMAIL_ERRORS$1 as RAW_EMAIL_ERRORS, RawEmailDecodeError$1 as RawEmailDecodeError, RawEmailDecodeErrorCode, STANDARD_WEBHOOK_ID_HEADER$1 as STANDARD_WEBHOOK_ID_HEADER, STANDARD_WEBHOOK_SIGNATURE_HEADER$1 as STANDARD_WEBHOOK_SIGNATURE_HEADER, STANDARD_WEBHOOK_TIMESTAMP_HEADER$1 as STANDARD_WEBHOOK_TIMESTAMP_HEADER, SignResult, StandardWebhooksSignResult, StandardWebhooksVerifyOptions, VERIFICATION_ERRORS$1 as VERIFICATION_ERRORS, VerifyOptions, WEBHOOK_VERSION$1 as WEBHOOK_VERSION, WebhookErrorCode, WebhookHeaders, WebhookPayloadError$1 as WebhookPayloadError, WebhookPayloadErrorCode, WebhookValidationError$1 as WebhookValidationError, WebhookValidationErrorCode, WebhookVerificationError$1 as WebhookVerificationError, WebhookVerificationErrorCode, confirmedHeaders$1 as confirmedHeaders, decodeRawEmail$1 as decodeRawEmail, emailReceivedEventJsonSchema$1 as emailReceivedEventJsonSchema, getDownloadTimeRemaining$1 as getDownloadTimeRemaining, handleWebhook$1 as handleWebhook, isDownloadExpired$1 as isDownloadExpired, isEmailReceivedEvent$1 as isEmailReceivedEvent, isRawIncluded$1 as isRawIncluded, parseWebhookEvent$1 as parseWebhookEvent, safeValidateEmailReceivedEvent$1 as safeValidateEmailReceivedEvent, signStandardWebhooksPayload$1 as signStandardWebhooksPayload, signWebhookPayload$1 as signWebhookPayload, validateEmailAuth$1 as validateEmailAuth, validateEmailReceivedEvent$1 as validateEmailReceivedEvent, verifyRawEmailDownload$1 as verifyRawEmailDownload, verifyStandardWebhooksSignature$1 as verifyStandardWebhooksSignature, verifyWebhookSignature$1 as verifyWebhookSignature } from "../index-
|
|
3
|
-
export { AuthConfidence, AuthVerdict, DecodeRawEmailOptions, DkimResult, DkimSignature, DmarcPolicy, DmarcResult, EmailAddress, EmailAnalysis, EmailAuth, EmailReceivedEvent, EventType, ForwardAnalysis, ForwardOriginalSender, ForwardResult, ForwardResultAttachmentAnalyzed, ForwardResultAttachmentSkipped, ForwardResultInline, ForwardVerdict, ForwardVerification, HandleWebhookOptions, KnownWebhookEvent, LEGACY_CONFIRMED_HEADER, LEGACY_SIGNATURE_HEADER, PAYLOAD_ERRORS, PRIMITIVE_CONFIRMED_HEADER, PRIMITIVE_SIGNATURE_HEADER, ParsedData, ParsedDataComplete, ParsedDataFailed, ParsedError, ParsedStatus, PrimitiveWebhookError, RAW_EMAIL_ERRORS, RawContent, RawContentDownloadOnly, RawContentInline, RawEmailDecodeError, RawEmailDecodeErrorCode, STANDARD_WEBHOOK_ID_HEADER, STANDARD_WEBHOOK_SIGNATURE_HEADER, STANDARD_WEBHOOK_TIMESTAMP_HEADER, SignResult, SpfResult, StandardWebhooksSignResult, StandardWebhooksVerifyOptions, UnknownEvent, VERIFICATION_ERRORS, ValidateEmailAuthResult, VerifyOptions, WEBHOOK_VERSION, WebhookAttachment, WebhookErrorCode, WebhookEvent, WebhookHeaders, WebhookPayloadError, WebhookPayloadErrorCode, WebhookValidationError, WebhookValidationErrorCode, WebhookVerificationError, WebhookVerificationErrorCode, confirmedHeaders, decodeRawEmail, emailReceivedEventJsonSchema, getDownloadTimeRemaining, handleWebhook, isDownloadExpired, isEmailReceivedEvent, isRawIncluded, parseWebhookEvent, safeValidateEmailReceivedEvent, signStandardWebhooksPayload, signWebhookPayload, validateEmailAuth, validateEmailReceivedEvent, verifyRawEmailDownload, verifyStandardWebhooksSignature, verifyWebhookSignature };
|
|
2
|
+
import { DecodeRawEmailOptions, GenerateDownloadTokenOptions, HandleWebhookOptions, LEGACY_CONFIRMED_HEADER$1 as LEGACY_CONFIRMED_HEADER, LEGACY_SIGNATURE_HEADER$1 as LEGACY_SIGNATURE_HEADER, PAYLOAD_ERRORS$1 as PAYLOAD_ERRORS, PRIMITIVE_CONFIRMED_HEADER$1 as PRIMITIVE_CONFIRMED_HEADER, PRIMITIVE_SIGNATURE_HEADER$1 as PRIMITIVE_SIGNATURE_HEADER, PrimitiveWebhookError$1 as PrimitiveWebhookError, RAW_EMAIL_ERRORS$1 as RAW_EMAIL_ERRORS, RawEmailDecodeError$1 as RawEmailDecodeError, RawEmailDecodeErrorCode, STANDARD_WEBHOOK_ID_HEADER$1 as STANDARD_WEBHOOK_ID_HEADER, STANDARD_WEBHOOK_SIGNATURE_HEADER$1 as STANDARD_WEBHOOK_SIGNATURE_HEADER, STANDARD_WEBHOOK_TIMESTAMP_HEADER$1 as STANDARD_WEBHOOK_TIMESTAMP_HEADER, SignResult, StandardWebhooksSignResult, StandardWebhooksVerifyOptions, VERIFICATION_ERRORS$1 as VERIFICATION_ERRORS, VerifyDownloadTokenOptions, VerifyDownloadTokenResult, VerifyOptions, WEBHOOK_VERSION$1 as WEBHOOK_VERSION, WebhookErrorCode, WebhookHeaders, WebhookPayloadError$1 as WebhookPayloadError, WebhookPayloadErrorCode, WebhookValidationError$1 as WebhookValidationError, WebhookValidationErrorCode, WebhookVerificationError$1 as WebhookVerificationError, WebhookVerificationErrorCode, confirmedHeaders$1 as confirmedHeaders, decodeRawEmail$1 as decodeRawEmail, emailReceivedEventJsonSchema$1 as emailReceivedEventJsonSchema, generateDownloadToken$1 as generateDownloadToken, getDownloadTimeRemaining$1 as getDownloadTimeRemaining, handleWebhook$1 as handleWebhook, isDownloadExpired$1 as isDownloadExpired, isEmailReceivedEvent$1 as isEmailReceivedEvent, isRawIncluded$1 as isRawIncluded, parseWebhookEvent$1 as parseWebhookEvent, safeValidateEmailReceivedEvent$1 as safeValidateEmailReceivedEvent, signStandardWebhooksPayload$1 as signStandardWebhooksPayload, signWebhookPayload$1 as signWebhookPayload, validateEmailAuth$1 as validateEmailAuth, validateEmailReceivedEvent$1 as validateEmailReceivedEvent, verifyDownloadToken$1 as verifyDownloadToken, verifyRawEmailDownload$1 as verifyRawEmailDownload, verifyStandardWebhooksSignature$1 as verifyStandardWebhooksSignature, verifyWebhookSignature$1 as verifyWebhookSignature } from "../index-C7tHPMZM.js";
|
|
3
|
+
export { AuthConfidence, AuthVerdict, DecodeRawEmailOptions, DkimResult, DkimSignature, DmarcPolicy, DmarcResult, EmailAddress, EmailAnalysis, EmailAuth, EmailReceivedEvent, EventType, ForwardAnalysis, ForwardOriginalSender, ForwardResult, ForwardResultAttachmentAnalyzed, ForwardResultAttachmentSkipped, ForwardResultInline, ForwardVerdict, ForwardVerification, GenerateDownloadTokenOptions, HandleWebhookOptions, KnownWebhookEvent, LEGACY_CONFIRMED_HEADER, LEGACY_SIGNATURE_HEADER, PAYLOAD_ERRORS, PRIMITIVE_CONFIRMED_HEADER, PRIMITIVE_SIGNATURE_HEADER, ParsedData, ParsedDataComplete, ParsedDataFailed, ParsedError, ParsedStatus, PrimitiveWebhookError, RAW_EMAIL_ERRORS, RawContent, RawContentDownloadOnly, RawContentInline, RawEmailDecodeError, RawEmailDecodeErrorCode, STANDARD_WEBHOOK_ID_HEADER, STANDARD_WEBHOOK_SIGNATURE_HEADER, STANDARD_WEBHOOK_TIMESTAMP_HEADER, SignResult, SpfResult, StandardWebhooksSignResult, StandardWebhooksVerifyOptions, UnknownEvent, VERIFICATION_ERRORS, ValidateEmailAuthResult, VerifyDownloadTokenOptions, VerifyDownloadTokenResult, VerifyOptions, WEBHOOK_VERSION, WebhookAttachment, WebhookErrorCode, WebhookEvent, WebhookHeaders, WebhookPayloadError, WebhookPayloadErrorCode, WebhookValidationError, WebhookValidationErrorCode, WebhookVerificationError, WebhookVerificationErrorCode, confirmedHeaders, decodeRawEmail, emailReceivedEventJsonSchema, generateDownloadToken, getDownloadTimeRemaining, handleWebhook, isDownloadExpired, isEmailReceivedEvent, isRawIncluded, parseWebhookEvent, safeValidateEmailReceivedEvent, signStandardWebhooksPayload, signWebhookPayload, validateEmailAuth, validateEmailReceivedEvent, verifyDownloadToken, verifyRawEmailDownload, verifyStandardWebhooksSignature, verifyWebhookSignature };
|
package/dist/webhook/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { AuthConfidence, AuthVerdict, DkimResult, DmarcPolicy, DmarcResult, EventType, ForwardVerdict, LEGACY_CONFIRMED_HEADER, LEGACY_SIGNATURE_HEADER, PAYLOAD_ERRORS, 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_VERSION, WebhookPayloadError, WebhookValidationError, WebhookVerificationError, confirmedHeaders, decodeRawEmail, emailReceivedEventJsonSchema, getDownloadTimeRemaining, handleWebhook, isDownloadExpired, isEmailReceivedEvent, isRawIncluded, parseWebhookEvent, safeValidateEmailReceivedEvent, signStandardWebhooksPayload, signWebhookPayload, validateEmailAuth, validateEmailReceivedEvent, verifyRawEmailDownload, verifyStandardWebhooksSignature, verifyWebhookSignature } from "../webhook-
|
|
1
|
+
import { AuthConfidence, AuthVerdict, DkimResult, DmarcPolicy, DmarcResult, EventType, ForwardVerdict, LEGACY_CONFIRMED_HEADER, LEGACY_SIGNATURE_HEADER, PAYLOAD_ERRORS, 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_VERSION, WebhookPayloadError, WebhookValidationError, WebhookVerificationError, confirmedHeaders, decodeRawEmail, emailReceivedEventJsonSchema, generateDownloadToken, getDownloadTimeRemaining, handleWebhook, isDownloadExpired, isEmailReceivedEvent, isRawIncluded, parseWebhookEvent, safeValidateEmailReceivedEvent, signStandardWebhooksPayload, signWebhookPayload, validateEmailAuth, validateEmailReceivedEvent, verifyDownloadToken, verifyRawEmailDownload, verifyStandardWebhooksSignature, verifyWebhookSignature } from "../webhook-C5kOt3fb.js";
|
|
2
2
|
|
|
3
|
-
export { AuthConfidence, AuthVerdict, DkimResult, DmarcPolicy, DmarcResult, EventType, ForwardVerdict, LEGACY_CONFIRMED_HEADER, LEGACY_SIGNATURE_HEADER, PAYLOAD_ERRORS, 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_VERSION, WebhookPayloadError, WebhookValidationError, WebhookVerificationError, confirmedHeaders, decodeRawEmail, emailReceivedEventJsonSchema, getDownloadTimeRemaining, handleWebhook, isDownloadExpired, isEmailReceivedEvent, isRawIncluded, parseWebhookEvent, safeValidateEmailReceivedEvent, signStandardWebhooksPayload, signWebhookPayload, validateEmailAuth, validateEmailReceivedEvent, verifyRawEmailDownload, verifyStandardWebhooksSignature, verifyWebhookSignature };
|
|
3
|
+
export { AuthConfidence, AuthVerdict, DkimResult, DmarcPolicy, DmarcResult, EventType, ForwardVerdict, LEGACY_CONFIRMED_HEADER, LEGACY_SIGNATURE_HEADER, PAYLOAD_ERRORS, 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_VERSION, WebhookPayloadError, WebhookValidationError, WebhookVerificationError, confirmedHeaders, decodeRawEmail, emailReceivedEventJsonSchema, generateDownloadToken, getDownloadTimeRemaining, handleWebhook, isDownloadExpired, isEmailReceivedEvent, isRawIncluded, parseWebhookEvent, safeValidateEmailReceivedEvent, signStandardWebhooksPayload, signWebhookPayload, validateEmailAuth, validateEmailReceivedEvent, verifyDownloadToken, verifyRawEmailDownload, verifyStandardWebhooksSignature, verifyWebhookSignature };
|
|
@@ -6043,6 +6043,102 @@ function safeValidateEmailReceivedEvent(input) {
|
|
|
6043
6043
|
};
|
|
6044
6044
|
}
|
|
6045
6045
|
|
|
6046
|
+
//#endregion
|
|
6047
|
+
//#region src/webhook/download-tokens.ts
|
|
6048
|
+
const BASE64URL_PATTERN = /^[A-Za-z0-9_-]+$/;
|
|
6049
|
+
/**
|
|
6050
|
+
* Issue a signed download token.
|
|
6051
|
+
*
|
|
6052
|
+
* The resulting token is `<base64url-payload>.<base64url-signature>`, where
|
|
6053
|
+
* the payload is `{"email_id":"...","exp":...,"aud":"..."}` (snake_case,
|
|
6054
|
+
* field order fixed) and the signature is HMAC-SHA256 of the base64url
|
|
6055
|
+
* payload string using `secret`.
|
|
6056
|
+
*
|
|
6057
|
+
* @param params - Token inputs.
|
|
6058
|
+
* @returns The signed token string.
|
|
6059
|
+
*/
|
|
6060
|
+
function generateDownloadToken(params) {
|
|
6061
|
+
const { emailId, expiresAt, audience, secret } = params;
|
|
6062
|
+
const payload = {
|
|
6063
|
+
email_id: emailId,
|
|
6064
|
+
exp: expiresAt,
|
|
6065
|
+
aud: audience
|
|
6066
|
+
};
|
|
6067
|
+
const payloadJson = JSON.stringify(payload);
|
|
6068
|
+
const payloadStr = Buffer.from(payloadJson, "utf8").toString("base64url");
|
|
6069
|
+
const signature = createHmac("sha256", secret).update(payloadStr).digest("base64url");
|
|
6070
|
+
return `${payloadStr}.${signature}`;
|
|
6071
|
+
}
|
|
6072
|
+
/**
|
|
6073
|
+
* Verify a signed download token.
|
|
6074
|
+
*
|
|
6075
|
+
* Returns a discriminated-union result. The function never throws for
|
|
6076
|
+
* verification failures — only malformed inputs at the crypto layer would
|
|
6077
|
+
* surface. Callers should check `result.valid` and log `result.error`.
|
|
6078
|
+
*
|
|
6079
|
+
* @param params - Verification inputs.
|
|
6080
|
+
* @returns Whether the token is valid, plus a reason on failure.
|
|
6081
|
+
*/
|
|
6082
|
+
function verifyDownloadToken(params) {
|
|
6083
|
+
const { token, emailId, audience, secret, nowSeconds } = params;
|
|
6084
|
+
if (typeof token !== "string" || token.length === 0) return {
|
|
6085
|
+
valid: false,
|
|
6086
|
+
error: "Token is empty"
|
|
6087
|
+
};
|
|
6088
|
+
const firstDot = token.indexOf(".");
|
|
6089
|
+
const lastDot = token.lastIndexOf(".");
|
|
6090
|
+
if (firstDot === -1 || firstDot !== lastDot) return {
|
|
6091
|
+
valid: false,
|
|
6092
|
+
error: "Token is malformed: expected one '.'"
|
|
6093
|
+
};
|
|
6094
|
+
const payloadStr = token.slice(0, firstDot);
|
|
6095
|
+
const providedSignature = token.slice(firstDot + 1);
|
|
6096
|
+
if (payloadStr.length === 0 || providedSignature.length === 0) return {
|
|
6097
|
+
valid: false,
|
|
6098
|
+
error: "Token is malformed: empty part"
|
|
6099
|
+
};
|
|
6100
|
+
const expectedSignature = createHmac("sha256", secret).update(payloadStr).digest("base64url");
|
|
6101
|
+
const providedBytes = Buffer.from(providedSignature, "base64url");
|
|
6102
|
+
const expectedBytes = Buffer.from(expectedSignature, "base64url");
|
|
6103
|
+
if (providedBytes.length !== expectedBytes.length || !timingSafeEqual(providedBytes, expectedBytes)) return {
|
|
6104
|
+
valid: false,
|
|
6105
|
+
error: "Invalid signature"
|
|
6106
|
+
};
|
|
6107
|
+
if (!BASE64URL_PATTERN.test(payloadStr)) return {
|
|
6108
|
+
valid: false,
|
|
6109
|
+
error: "Token payload is not valid base64url"
|
|
6110
|
+
};
|
|
6111
|
+
const decodedJson = Buffer.from(payloadStr, "base64url").toString("utf8");
|
|
6112
|
+
let payload;
|
|
6113
|
+
try {
|
|
6114
|
+
payload = JSON.parse(decodedJson);
|
|
6115
|
+
} catch {
|
|
6116
|
+
return {
|
|
6117
|
+
valid: false,
|
|
6118
|
+
error: "Token payload is not valid JSON"
|
|
6119
|
+
};
|
|
6120
|
+
}
|
|
6121
|
+
if (!payload || typeof payload !== "object" || Array.isArray(payload) || typeof payload.email_id !== "string" || typeof payload.aud !== "string" || typeof payload.exp !== "number") return {
|
|
6122
|
+
valid: false,
|
|
6123
|
+
error: "Token payload has wrong shape"
|
|
6124
|
+
};
|
|
6125
|
+
const { email_id, aud, exp } = payload;
|
|
6126
|
+
if (aud !== audience) return {
|
|
6127
|
+
valid: false,
|
|
6128
|
+
error: "Audience mismatch"
|
|
6129
|
+
};
|
|
6130
|
+
if (email_id !== emailId) return {
|
|
6131
|
+
valid: false,
|
|
6132
|
+
error: "Email ID mismatch"
|
|
6133
|
+
};
|
|
6134
|
+
const now = nowSeconds ?? Math.floor(Date.now() / 1e3);
|
|
6135
|
+
if (exp <= now) return {
|
|
6136
|
+
valid: false,
|
|
6137
|
+
error: "Token is expired"
|
|
6138
|
+
};
|
|
6139
|
+
return { valid: true };
|
|
6140
|
+
}
|
|
6141
|
+
|
|
6046
6142
|
//#endregion
|
|
6047
6143
|
//#region src/webhook/encoding.ts
|
|
6048
6144
|
const utf8Decoder = new TextDecoder("utf-8", { fatal: true });
|
|
@@ -7907,4 +8003,4 @@ function verifyRawEmailDownload(downloaded, event) {
|
|
|
7907
8003
|
}
|
|
7908
8004
|
|
|
7909
8005
|
//#endregion
|
|
7910
|
-
export { AuthConfidence, AuthVerdict, DkimResult, DmarcPolicy, DmarcResult, EventType, ForwardVerdict, LEGACY_CONFIRMED_HEADER, LEGACY_SIGNATURE_HEADER, PAYLOAD_ERRORS, 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_VERSION, WebhookPayloadError, WebhookValidationError, WebhookVerificationError, confirmedHeaders, decodeRawEmail, emailReceivedEventJsonSchema, getDownloadTimeRemaining, handleWebhook, isDownloadExpired, isEmailReceivedEvent, isRawIncluded, parseWebhookEvent, safeValidateEmailReceivedEvent, signStandardWebhooksPayload, signWebhookPayload, validateEmailAuth, validateEmailReceivedEvent, verifyRawEmailDownload, verifyStandardWebhooksSignature, verifyWebhookSignature };
|
|
8006
|
+
export { AuthConfidence, AuthVerdict, DkimResult, DmarcPolicy, DmarcResult, EventType, ForwardVerdict, LEGACY_CONFIRMED_HEADER, LEGACY_SIGNATURE_HEADER, PAYLOAD_ERRORS, 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_VERSION, WebhookPayloadError, WebhookValidationError, WebhookVerificationError, confirmedHeaders, decodeRawEmail, emailReceivedEventJsonSchema, generateDownloadToken, getDownloadTimeRemaining, handleWebhook, isDownloadExpired, isEmailReceivedEvent, isRawIncluded, parseWebhookEvent, safeValidateEmailReceivedEvent, signStandardWebhooksPayload, signWebhookPayload, validateEmailAuth, validateEmailReceivedEvent, verifyDownloadToken, verifyRawEmailDownload, verifyStandardWebhooksSignature, verifyWebhookSignature };
|
package/oclif.manifest.json
CHANGED
|
@@ -669,6 +669,12 @@
|
|
|
669
669
|
"required": false,
|
|
670
670
|
"hasDynamicHelp": false,
|
|
671
671
|
"multiple": false,
|
|
672
|
+
"options": [
|
|
673
|
+
"pending",
|
|
674
|
+
"accepted",
|
|
675
|
+
"completed",
|
|
676
|
+
"rejected"
|
|
677
|
+
],
|
|
672
678
|
"type": "option"
|
|
673
679
|
},
|
|
674
680
|
"search": {
|
|
@@ -709,7 +715,7 @@
|
|
|
709
715
|
"emails:replay-email-webhooks": {
|
|
710
716
|
"aliases": [],
|
|
711
717
|
"args": {},
|
|
712
|
-
"description": "Re-delivers the webhook payload for this email to all active\nendpoints matching the email's domain.
|
|
718
|
+
"description": "Re-delivers the webhook payload for this email to all active\nendpoints matching the email's domain. Rate limited per-email\n(short cooldown between successive replays of the same email)\nand per-org (burst + sustained windows), sharing an org-wide\nbudget with delivery replays.\n",
|
|
713
719
|
"flags": {
|
|
714
720
|
"api-key": {
|
|
715
721
|
"description": "Primitive API key (defaults to PRIMITIVE_API_KEY)",
|
|
@@ -1181,6 +1187,12 @@
|
|
|
1181
1187
|
"required": false,
|
|
1182
1188
|
"hasDynamicHelp": false,
|
|
1183
1189
|
"multiple": false,
|
|
1190
|
+
"options": [
|
|
1191
|
+
"pending",
|
|
1192
|
+
"delivered",
|
|
1193
|
+
"header_confirmed",
|
|
1194
|
+
"failed"
|
|
1195
|
+
],
|
|
1184
1196
|
"type": "option"
|
|
1185
1197
|
},
|
|
1186
1198
|
"date-from": {
|
|
@@ -1213,7 +1225,7 @@
|
|
|
1213
1225
|
"webhook-deliveries:replay-delivery": {
|
|
1214
1226
|
"aliases": [],
|
|
1215
1227
|
"args": {},
|
|
1216
|
-
"description": "Re-sends the stored webhook payload from a previous delivery attempt.\nIf the original endpoint is still active, it is targeted. If the\noriginal endpoint was deleted, the
|
|
1228
|
+
"description": "Re-sends the stored webhook payload from a previous delivery attempt.\nIf the original endpoint is still active, it is targeted. If the\noriginal endpoint was deleted, the oldest active endpoint is used.\nDeactivated endpoints cannot be replayed to. Rate limited per-org,\nsharing an org-wide budget with email replays.\n",
|
|
1217
1229
|
"flags": {
|
|
1218
1230
|
"api-key": {
|
|
1219
1231
|
"description": "Primitive API key (defaults to PRIMITIVE_API_KEY)",
|
|
@@ -1251,5 +1263,5 @@
|
|
|
1251
1263
|
"enableJsonFlag": false
|
|
1252
1264
|
}
|
|
1253
1265
|
},
|
|
1254
|
-
"version": "0.
|
|
1266
|
+
"version": "0.5.0"
|
|
1255
1267
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@primitivedotdev/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Official Primitive Node.js SDK — webhook, api, openapi, contract, and parser modules",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -93,9 +93,9 @@
|
|
|
93
93
|
"test": "vitest run",
|
|
94
94
|
"test:coverage": "vitest run --coverage",
|
|
95
95
|
"test:watch": "vitest",
|
|
96
|
-
"typecheck": "pnpm generate && tsc --noEmit",
|
|
97
|
-
"lint": "biome check src/index.ts src/validation.ts src/types.ts src/webhook src/contract src/parser src/api/index.ts src/openapi/index.ts src/oclif tests/",
|
|
98
|
-
"lint:fix": "biome check --write src/index.ts src/validation.ts src/types.ts src/webhook src/contract src/parser src/api/index.ts src/openapi/index.ts src/oclif tests/",
|
|
96
|
+
"typecheck": "pnpm generate && tsc --noEmit -p tsconfig.typecheck.json",
|
|
97
|
+
"lint": "biome check --error-on-warnings src/index.ts src/validation.ts src/types.ts src/webhook src/contract src/parser src/api/index.ts src/openapi/index.ts src/oclif tests/",
|
|
98
|
+
"lint:fix": "biome check --write --error-on-warnings src/index.ts src/validation.ts src/types.ts src/webhook src/contract src/parser src/api/index.ts src/openapi/index.ts src/oclif tests/",
|
|
99
99
|
"prepack": "pnpm build && oclif manifest",
|
|
100
100
|
"postpack": "shx rm -f oclif.manifest.json",
|
|
101
101
|
"prepublishOnly": "pnpm build"
|