mailery 0.16.0 → 0.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -286,8 +286,36 @@ var init_webhook_tolerance = __esm({
286
286
  // src/server/providers/sendgrid.ts
287
287
  var sendgrid_exports = {};
288
288
  __export(sendgrid_exports, {
289
- SendGridProvider: () => exports.SendGridProvider
289
+ SendGridProvider: () => exports.SendGridProvider,
290
+ normalizeWebhookVerificationKey: () => normalizeWebhookVerificationKey
290
291
  });
292
+ function normalizeWebhookVerificationKey(input) {
293
+ let key = String(input ?? "").trim().replace(/^["']|["']$/g, "");
294
+ if (key.includes("\\n")) key = key.replace(/\\n/g, "\n");
295
+ let pem;
296
+ if (key.includes(PEM_HEADER)) {
297
+ pem = key;
298
+ } else {
299
+ const b64 = key.replace(/\s+/g, "");
300
+ if (!b64 || !/^[A-Za-z0-9+/=]+$/.test(b64)) {
301
+ throw new Error(
302
+ "SendGridProvider: webhookVerificationKey is neither a PEM public key nor a base64 SPKI key. Copy the Verification Key from SendGrid \u2192 Settings \u2192 Mail Settings \u2192 Signed Event Webhook."
303
+ );
304
+ }
305
+ pem = `${PEM_HEADER}
306
+ ${b64.match(/.{1,64}/g).join("\n")}
307
+ ${PEM_FOOTER}
308
+ `;
309
+ }
310
+ try {
311
+ crypto2__default.default.createPublicKey(pem);
312
+ } catch (err) {
313
+ throw new Error(
314
+ `SendGridProvider: webhookVerificationKey did not parse as a public key (${String(err?.message ?? err)}). Copy the Verification Key from SendGrid \u2192 Settings \u2192 Mail Settings \u2192 Signed Event Webhook.`
315
+ );
316
+ }
317
+ return pem;
318
+ }
291
319
  function normalizeSendGridEvent(e) {
292
320
  const type = mapEventType(e.event);
293
321
  if (!type) return null;
@@ -326,24 +354,29 @@ function mapEventType(sgEvent) {
326
354
  return null;
327
355
  }
328
356
  }
329
- var SG_SIG_HEADER, SG_TS_HEADER; exports.SendGridProvider = void 0;
357
+ var SG_SIG_HEADER, SG_TS_HEADER, PEM_HEADER, PEM_FOOTER; exports.SendGridProvider = void 0;
330
358
  var init_sendgrid = __esm({
331
359
  "src/server/providers/sendgrid.ts"() {
332
360
  init_webhook_tolerance();
333
361
  SG_SIG_HEADER = "x-twilio-email-event-webhook-signature";
334
362
  SG_TS_HEADER = "x-twilio-email-event-webhook-timestamp";
363
+ PEM_HEADER = "-----BEGIN PUBLIC KEY-----";
364
+ PEM_FOOTER = "-----END PUBLIC KEY-----";
335
365
  exports.SendGridProvider = class {
336
366
  constructor(opts) {
337
367
  this.opts = opts;
338
368
  sgMail__default.default.setApiKey(opts.apiKey);
339
369
  this.sendRatePerSecond = opts.sendRatePerSecond ?? 10;
340
370
  this.webhookToleranceSeconds = resolveWebhookToleranceSeconds(opts.webhookToleranceSeconds);
371
+ this.verificationKeyPem = opts.webhookVerificationKey ? normalizeWebhookVerificationKey(opts.webhookVerificationKey) : null;
341
372
  }
342
373
  opts;
343
374
  name = "sendgrid";
344
375
  sendRatePerSecond;
345
376
  /** Resolved replay window in seconds; `0` means the check is disabled. */
346
377
  webhookToleranceSeconds;
378
+ /** The verification key as PEM, whatever shape it was configured in. */
379
+ verificationKeyPem;
347
380
  async send(args) {
348
381
  const msg = {
349
382
  to: args.to,
@@ -375,7 +408,7 @@ var init_sendgrid = __esm({
375
408
  };
376
409
  }
377
410
  async verifyWebhook(rawBody, headers) {
378
- if (!this.opts.webhookVerificationKey) return false;
411
+ if (!this.verificationKeyPem) return false;
379
412
  const sig = headers[SG_SIG_HEADER];
380
413
  const ts = headers[SG_TS_HEADER];
381
414
  if (!sig || !ts) return false;
@@ -383,7 +416,7 @@ var init_sendgrid = __esm({
383
416
  try {
384
417
  const verifier = crypto2__default.default.createVerify("sha256");
385
418
  verifier.update(payload);
386
- if (!verifier.verify(this.opts.webhookVerificationKey, sig, "base64")) return false;
419
+ if (!verifier.verify(this.verificationKeyPem, sig, "base64")) return false;
387
420
  } catch {
388
421
  return false;
389
422
  }
@@ -8223,7 +8256,7 @@ function unitToMs2(value, unit) {
8223
8256
  }
8224
8257
 
8225
8258
  // src/server/api/agent.ts
8226
- var VERSION = "0.16.0" ;
8259
+ var VERSION = "0.16.1" ;
8227
8260
  var MIN_AGENT_TOKEN_LENGTH = 24;
8228
8261
  function createAgentRouter(mailer, opts) {
8229
8262
  if (!opts || !Array.isArray(opts.tokens) || opts.tokens.length === 0) {
@@ -9923,7 +9956,7 @@ var DEDUPE_POLICIES = [
9923
9956
  ];
9924
9957
 
9925
9958
  // src/server/index.ts
9926
- var VERSION2 = "0.16.0" ;
9959
+ var VERSION2 = "0.16.1" ;
9927
9960
 
9928
9961
  exports.DEDUPE_POLICIES = DEDUPE_POLICIES;
9929
9962
  exports.DEFAULT_BOT_UA_RE = DEFAULT_BOT_UA_RE;