@growth-labs/mailer 0.4.11 → 0.5.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.
Files changed (69) hide show
  1. package/README.md +18 -2
  2. package/dist/options.d.ts +12 -6
  3. package/dist/options.d.ts.map +1 -1
  4. package/dist/options.js +4 -2
  5. package/dist/options.js.map +1 -1
  6. package/dist/queue/consumer.d.ts +12 -2
  7. package/dist/queue/consumer.d.ts.map +1 -1
  8. package/dist/queue/consumer.js +66 -0
  9. package/dist/queue/consumer.js.map +1 -1
  10. package/dist/routes/confirm.d.ts.map +1 -1
  11. package/dist/routes/confirm.js +6 -2
  12. package/dist/routes/confirm.js.map +1 -1
  13. package/dist/routes/subscribe.d.ts.map +1 -1
  14. package/dist/routes/subscribe.js +11 -3
  15. package/dist/routes/subscribe.js.map +1 -1
  16. package/dist/routes/unsubscribe.d.ts.map +1 -1
  17. package/dist/routes/unsubscribe.js +14 -3
  18. package/dist/routes/unsubscribe.js.map +1 -1
  19. package/dist/schema/sends.d.ts +38 -0
  20. package/dist/schema/sends.d.ts.map +1 -1
  21. package/dist/schema/sends.js +2 -0
  22. package/dist/schema/sends.js.map +1 -1
  23. package/dist/types.d.ts +22 -1
  24. package/dist/types.d.ts.map +1 -1
  25. package/dist/utils/broadcast.d.ts +12 -0
  26. package/dist/utils/broadcast.d.ts.map +1 -1
  27. package/dist/utils/broadcast.js +17 -3
  28. package/dist/utils/broadcast.js.map +1 -1
  29. package/dist/utils/delivery-claim.d.ts +37 -0
  30. package/dist/utils/delivery-claim.d.ts.map +1 -0
  31. package/dist/utils/delivery-claim.js +46 -0
  32. package/dist/utils/delivery-claim.js.map +1 -0
  33. package/dist/utils/runtime-secrets.d.ts +25 -0
  34. package/dist/utils/runtime-secrets.d.ts.map +1 -0
  35. package/dist/utils/runtime-secrets.js +96 -0
  36. package/dist/utils/runtime-secrets.js.map +1 -0
  37. package/dist/utils/send.d.ts.map +1 -1
  38. package/dist/utils/send.js +24 -6
  39. package/dist/utils/send.js.map +1 -1
  40. package/dist/utils/tokens.d.ts +3 -1
  41. package/dist/utils/tokens.d.ts.map +1 -1
  42. package/dist/utils/tokens.js +14 -5
  43. package/dist/utils/tokens.js.map +1 -1
  44. package/dist/utils/urls.d.ts +1 -1
  45. package/dist/utils/urls.d.ts.map +1 -1
  46. package/dist/utils/urls.js +9 -3
  47. package/dist/utils/urls.js.map +1 -1
  48. package/dist/vite-plugin.d.ts +1 -0
  49. package/dist/vite-plugin.d.ts.map +1 -1
  50. package/dist/vite-plugin.js +13 -1
  51. package/dist/vite-plugin.js.map +1 -1
  52. package/migrations/0003_add_delivery_claim_to_email_sends.sql +8 -0
  53. package/package.json +4 -4
  54. package/src/options.ts +4 -2
  55. package/src/queue/consumer.ts +116 -2
  56. package/src/routes/confirm.ts +9 -2
  57. package/src/routes/preferences.astro +12 -3
  58. package/src/routes/subscribe.ts +15 -3
  59. package/src/routes/unsubscribe.ts +16 -3
  60. package/src/schema/sends.ts +2 -0
  61. package/src/types.ts +23 -0
  62. package/src/utils/broadcast.ts +16 -3
  63. package/src/utils/delivery-claim.ts +66 -0
  64. package/src/utils/runtime-secrets.ts +144 -0
  65. package/src/utils/send.ts +27 -5
  66. package/src/utils/tokens.ts +16 -5
  67. package/src/utils/urls.ts +9 -6
  68. package/src/virtual.d.ts +4 -2
  69. package/src/vite-plugin.ts +18 -1
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,gBAAgB,CAAA;IACxB,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,qBAAqB,CAAA;IACnC,eAAe,EAAE,MAAM,CAAA;IACvB,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,QAAQ,GAAG,cAAc,GAAG,SAAS,GAAG,YAAY,CAAA;AAE/F,MAAM,WAAW,qBAAqB;IACrC,aAAa,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;CACpB;AAID,MAAM,WAAW,gBAAgB;IAChC,MAAM,CAAC,EAAE,gBAAgB,EAAE,CAAA;IAC3B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;CACjB;AAID,MAAM,WAAW,iBAAiB;IACjC,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,eAAe,GAAG,UAAU,GAAG,QAAQ,GAAG,WAAW,CAAA;IAC3D,UAAU,EAAE,cAAc,EAAE,CAAA;IAC5B,OAAO,EAAE,MAAM,CAAA;IACf,YAAY,EAAE,MAAM,CAAA;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,UAAU,CAAC,EAAE,MAAM,CAAA;CACnB;AAID;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAChC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,KAAK,CAAC,EAAE;QACP,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,YAAY,CAAC,EAAE,MAAM,CAAA;QACrB,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,UAAU,CAAC,EAAE,MAAM,CAAA;KACnB,CAAA;CACD;AAED;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAC9B,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KACxB,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAA;AAErC;;;;;;;GAOG;AACH,MAAM,MAAM,sBAAsB,GAAG,CACpC,MAAM,EAAE;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAC/D,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KACxB,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAA;AAErC,MAAM,WAAW,cAAc;IAC9B,KAAK,EAAE,MAAM,CAAA;IACb,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,gBAAgB,EAAE,MAAM,CAAA;IACxB,gBAAgB,EAAE,MAAM,CAAA;IACxB;;;;;;OAMG;IACH,aAAa,EAAE,MAAM,CAAA;CACrB;AAID,MAAM,WAAW,SAAS;IACzB,EAAE,EAAE,MAAM,CAAA;IACV,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,eAAe,GAAG,UAAU,GAAG,QAAQ,GAAG,WAAW,CAAA;IAC3D,MAAM,EAAE,eAAe,CAAA;IACvB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,MAAM,eAAe,GACxB,QAAQ,GACR,SAAS,GACT,MAAM,GACN,WAAW,GACX,QAAQ,GACR,SAAS,GACT,SAAS,GACT,YAAY,GACZ,YAAY,CAAA;AAIf,MAAM,WAAW,aAAa;IAC7B,IAAI,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;IAC/C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,aAAa;IAC7B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAChC;AAED,MAAM,WAAW,UAAU;IAC1B,OAAO,EAAE,OAAO,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,OAAO,CAAA;CAClB;AAID,MAAM,MAAM,YAAY,GACrB,cAAc,GACd,SAAS,GACT,UAAU,GACV,QAAQ,GACR,eAAe,GACf,qBAAqB,CAAA;AAExB,MAAM,WAAW,YAAY;IAC5B,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,cAAc,EAAE,MAAM,CAAA;IACtB,cAAc,EAAE,MAAM,CAAA;IACtB,KAAK,EAAE;QACN,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,YAAY,EAAE,MAAM,CAAA;QACpB,WAAW,EAAE,MAAM,CAAA;QACnB,UAAU,CAAC,EAAE,MAAM,CAAA;KACnB,CAAA;IACD,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACtB;AAID,MAAM,WAAW,UAAU;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,CAAC,EAAE,MAAM,CAAA;CACf"}
@@ -1,5 +1,17 @@
1
1
  import type { ResolvedMailerOptions } from '../options.js';
2
+ import type { SubscriberStatus } from '../types.js';
2
3
  import type { MailerEnv } from './send.js';
4
+ /**
5
+ * Statuses that mean "do not send" — the suppression list. A broadcast skips
6
+ * every recipient whose `gl_subscribers` row carries one of these. `active` is
7
+ * the ONLY sendable status; everything else (including `pending`, i.e. an
8
+ * unconfirmed double-opt-in subscriber) is suppressed so a one-off blast can
9
+ * never re-permission or re-mail a suppressed address.
10
+ *
11
+ * Exported so the queue consumer can recheck against the same set at send
12
+ * admission (WM-01) — the same statuses that block enqueue must block send.
13
+ */
14
+ export declare const SUPPRESSED_STATUSES: ReadonlySet<SubscriberStatus>;
3
15
  /**
4
16
  * One recipient of a broadcast. `subscriberId` is optional: when omitted the
5
17
  * subscriber is resolved by `email` against `gl_subscribers` (needed both for
@@ -1 +1 @@
1
- {"version":3,"file":"broadcast.d.ts","sourceRoot":"","sources":["../../src/utils/broadcast.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAA;AAK1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAsB1C;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IAClC,KAAK,EAAE,MAAM,CAAA;IACb,YAAY,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,mBAAmB;IACnC;;;;;OAKG;IACH,UAAU,CAAC,EAAE,KAAK,CAAC,kBAAkB,GAAG,MAAM,CAAC,CAAA;IAC/C;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,KAAK,CAAC,kBAAkB,GAAG,MAAM,CAAC,CAAC,CAAA;IAExF,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IAEZ;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB,gFAAgF;IAChF,MAAM,CAAC,EAAE,OAAO,CAAA;IAEhB;;;OAGG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAEhC;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC1B;AAED,MAAM,WAAW,mBAAmB;IACnC,UAAU,EAAE,MAAM,CAAA;IAClB,6DAA6D;IAC7D,cAAc,EAAE,MAAM,CAAA;IACtB,kFAAkF;IAClF,eAAe,EAAE,MAAM,CAAA;IACvB,uFAAuF;IACvF,gBAAgB,EAAE,MAAM,CAAA;IACxB,wDAAwD;IACxD,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,OAAO,CAAA;CACf;AA8JD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,aAAa,CAClC,GAAG,EAAE,SAAS,EACd,OAAO,EAAE,qBAAqB,EAC9B,MAAM,EAAE,mBAAmB,GACzB,OAAO,CAAC,mBAAmB,CAAC,CA+H9B"}
1
+ {"version":3,"file":"broadcast.d.ts","sourceRoot":"","sources":["../../src/utils/broadcast.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAA;AAG1D,OAAO,KAAK,EAAqC,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAGtF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAM1C;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,EAAE,WAAW,CAAC,gBAAgB,CAK5D,CAAA;AAIF;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IAClC,KAAK,EAAE,MAAM,CAAA;IACb,YAAY,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,mBAAmB;IACnC;;;;;OAKG;IACH,UAAU,CAAC,EAAE,KAAK,CAAC,kBAAkB,GAAG,MAAM,CAAC,CAAA;IAC/C;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,KAAK,CAAC,kBAAkB,GAAG,MAAM,CAAC,CAAC,CAAA;IAExF,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IAEZ;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB,gFAAgF;IAChF,MAAM,CAAC,EAAE,OAAO,CAAA;IAEhB;;;OAGG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAEhC;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC1B;AAED,MAAM,WAAW,mBAAmB;IACnC,UAAU,EAAE,MAAM,CAAA;IAClB,6DAA6D;IAC7D,cAAc,EAAE,MAAM,CAAA;IACtB,kFAAkF;IAClF,eAAe,EAAE,MAAM,CAAA;IACvB,uFAAuF;IACvF,gBAAgB,EAAE,MAAM,CAAA;IACxB,wDAAwD;IACxD,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,OAAO,CAAA;CACf;AA8JD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,aAAa,CAClC,GAAG,EAAE,SAAS,EACd,OAAO,EAAE,qBAAqB,EAC9B,MAAM,EAAE,mBAAmB,GACzB,OAAO,CAAC,mBAAmB,CAAC,CAwI9B"}
@@ -4,6 +4,7 @@ import { ulid } from 'ulidx';
4
4
  import { emailSends } from '../schema/sends.js';
5
5
  import { subscribers } from '../schema/subscribers.js';
6
6
  import { sleep } from './providers.js';
7
+ import { resolveSigningSecret, siteHost } from './runtime-secrets.js';
7
8
  import { generateToken } from './tokens.js';
8
9
  import { injectTrackingPixel, rewriteLinksForTracking } from './tracking.js';
9
10
  /**
@@ -12,8 +13,11 @@ import { injectTrackingPixel, rewriteLinksForTracking } from './tracking.js';
12
13
  * the ONLY sendable status; everything else (including `pending`, i.e. an
13
14
  * unconfirmed double-opt-in subscriber) is suppressed so a one-off blast can
14
15
  * never re-permission or re-mail a suppressed address.
16
+ *
17
+ * Exported so the queue consumer can recheck against the same set at send
18
+ * admission (WM-01) — the same statuses that block enqueue must block send.
15
19
  */
16
- const SUPPRESSED_STATUSES = new Set([
20
+ export const SUPPRESSED_STATUSES = new Set([
17
21
  'unsubscribed',
18
22
  'bounced',
19
23
  'complained',
@@ -194,20 +198,28 @@ export async function sendBroadcast(env, options, params) {
194
198
  dryRun: false,
195
199
  };
196
200
  }
201
+ const signingSecretResult = await resolveSigningSecret(env, options, options.siteUrl);
202
+ if (!signingSecretResult.ok)
203
+ throw new Error(signingSecretResult.code);
204
+ const signingSecret = signingSecretResult.secret;
205
+ const host = siteHost(options.siteUrl);
197
206
  const html = prepareBroadcastHtml(params.html, options);
198
207
  const now = new Date().toISOString();
199
208
  // 4. Per-recipient row write + queue-recipient build.
200
209
  const queueRecipients = [];
201
210
  for (const recipient of fresh) {
202
211
  const trackingId = ulid();
212
+ const deliveryToken = ulid();
203
213
  const [unsubscribeToken, preferencesToken] = await Promise.all([
204
- generateToken(options.signingSecret, {
214
+ generateToken(signingSecret, {
205
215
  subscriberId: recipient.subscriberId,
206
216
  action: 'unsubscribe',
217
+ host,
207
218
  }),
208
- generateToken(options.signingSecret, {
219
+ generateToken(signingSecret, {
209
220
  subscriberId: recipient.subscriberId,
210
221
  action: 'preferences',
222
+ host,
211
223
  }),
212
224
  ]);
213
225
  await sendsDb.insert(emailSends).values({
@@ -220,6 +232,7 @@ export async function sendBroadcast(env, options, params) {
220
232
  type: 'broadcast',
221
233
  status: 'queued',
222
234
  trackingId,
235
+ deliveryToken,
223
236
  createdAt: now,
224
237
  });
225
238
  queueRecipients.push({
@@ -228,6 +241,7 @@ export async function sendBroadcast(env, options, params) {
228
241
  trackingId,
229
242
  unsubscribeToken,
230
243
  preferencesToken,
244
+ deliveryToken,
231
245
  });
232
246
  }
233
247
  // 5. Batched fan-out, paced to the configured send rate.
@@ -1 +1 @@
1
- {"version":3,"file":"broadcast.js","sourceRoot":"","sources":["../../src/utils/broadcast.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"broadcast.js","sourceRoot":"","sources":["../../src/utils/broadcast.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import type { drizzle } from 'drizzle-orm/d1';
2
+ type DrizzleDB = ReturnType<typeof drizzle>;
3
+ export type ClaimOutcome =
4
+ /** This invocation owns the send — no prior claim exists. */
5
+ 'claimed'
6
+ /** A prior claim never reached ack (crash/timeout). Reconcile, don't resend. */
7
+ | 'reconcile-in-flight'
8
+ /** The row is already in a terminal state — a duplicate enqueue, no-op. */
9
+ | 'already-terminal'
10
+ /** The row exists but under a different delivery_token — a superseded or replayed message. */
11
+ | 'invalid-authorization'
12
+ /** No row for this trackingId at all — lost or not-yet-visible write. */
13
+ | 'missing';
14
+ /**
15
+ * Atomically claim a queued send for this delivery attempt (WM-01) — the
16
+ * stable per-(campaign, recipient) delivery claim the mailer consumer needs.
17
+ * `trackingId` is unique per recipient/attempt; the update is a
18
+ * compare-and-swap gated on the row still being `queued`, so of two
19
+ * concurrent or sequential claim attempts for the same row only one can
20
+ * succeed — D1 serializes writes, so the loser always observes the winner's
21
+ * new status.
22
+ *
23
+ * `deliveryToken` is minted once at enqueue time and carried in the queue
24
+ * message. Matching it against the row's stored token means a message from
25
+ * a superseded generation of the same trackingId (a fresh resend cycle
26
+ * re-keyed the row, or the message is a stale replay from before a D1
27
+ * restore) can never claim or act on the current row — it reads back as
28
+ * `invalid-authorization`, never `claimed` or `reconcile-in-flight`.
29
+ *
30
+ * An empty `deliveryToken` skips the token match: queue messages already
31
+ * in flight when this column shipped carry no token, and requiring one
32
+ * would strand that one-time backlog instead of letting it drain under the
33
+ * trackingId + status guard alone.
34
+ */
35
+ export declare function claimDelivery(db: DrizzleDB, trackingId: string, deliveryToken: string, now: string): Promise<ClaimOutcome>;
36
+ export {};
37
+ //# sourceMappingURL=delivery-claim.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delivery-claim.d.ts","sourceRoot":"","sources":["../../src/utils/delivery-claim.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA;AAG7C,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAA;AAE3C,MAAM,MAAM,YAAY;AACvB,6DAA6D;AAC3D,SAAS;AACX,gFAAgF;GAC9E,qBAAqB;AACvB,2EAA2E;GACzE,kBAAkB;AACpB,8FAA8F;GAC5F,uBAAuB;AACzB,yEAAyE;GACvE,SAAS,CAAA;AAEZ;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,aAAa,CAClC,EAAE,EAAE,SAAS,EACb,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,MAAM,EACrB,GAAG,EAAE,MAAM,GACT,OAAO,CAAC,YAAY,CAAC,CAqBvB"}
@@ -0,0 +1,46 @@
1
+ import { and, eq } from 'drizzle-orm';
2
+ import { emailSends } from '../schema/sends.js';
3
+ /**
4
+ * Atomically claim a queued send for this delivery attempt (WM-01) — the
5
+ * stable per-(campaign, recipient) delivery claim the mailer consumer needs.
6
+ * `trackingId` is unique per recipient/attempt; the update is a
7
+ * compare-and-swap gated on the row still being `queued`, so of two
8
+ * concurrent or sequential claim attempts for the same row only one can
9
+ * succeed — D1 serializes writes, so the loser always observes the winner's
10
+ * new status.
11
+ *
12
+ * `deliveryToken` is minted once at enqueue time and carried in the queue
13
+ * message. Matching it against the row's stored token means a message from
14
+ * a superseded generation of the same trackingId (a fresh resend cycle
15
+ * re-keyed the row, or the message is a stale replay from before a D1
16
+ * restore) can never claim or act on the current row — it reads back as
17
+ * `invalid-authorization`, never `claimed` or `reconcile-in-flight`.
18
+ *
19
+ * An empty `deliveryToken` skips the token match: queue messages already
20
+ * in flight when this column shipped carry no token, and requiring one
21
+ * would strand that one-time backlog instead of letting it drain under the
22
+ * trackingId + status guard alone.
23
+ */
24
+ export async function claimDelivery(db, trackingId, deliveryToken, now) {
25
+ const claimConditions = [eq(emailSends.trackingId, trackingId), eq(emailSends.status, 'queued')];
26
+ if (deliveryToken)
27
+ claimConditions.push(eq(emailSends.deliveryToken, deliveryToken));
28
+ const claimed = await db
29
+ .update(emailSends)
30
+ .set({ status: 'sending', claimedAt: now })
31
+ .where(and(...claimConditions))
32
+ .returning({ id: emailSends.id });
33
+ if (claimed.length > 0)
34
+ return 'claimed';
35
+ const rows = await db.select().from(emailSends).where(eq(emailSends.trackingId, trackingId));
36
+ if (rows.length === 0)
37
+ return 'missing';
38
+ const row = rows[0];
39
+ if (deliveryToken && row.deliveryToken && row.deliveryToken !== deliveryToken) {
40
+ return 'invalid-authorization';
41
+ }
42
+ if (row.status === 'sending')
43
+ return 'reconcile-in-flight';
44
+ return 'already-terminal';
45
+ }
46
+ //# sourceMappingURL=delivery-claim.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delivery-claim.js","sourceRoot":"","sources":["../../src/utils/delivery-claim.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,aAAa,CAAA;AAErC,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAgB/C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAClC,EAAa,EACb,UAAkB,EAClB,aAAqB,EACrB,GAAW;IAEX,MAAM,eAAe,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAA;IAChG,IAAI,aAAa;QAAE,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC,CAAA;IAEpF,MAAM,OAAO,GAAG,MAAM,EAAE;SACtB,MAAM,CAAC,UAAU,CAAC;SAClB,GAAG,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;SAC1C,KAAK,CAAC,GAAG,CAAC,GAAG,eAAe,CAAC,CAAC;SAC9B,SAAS,CAAC,EAAE,EAAE,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC,CAAA;IAElC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,SAAS,CAAA;IAExC,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAA;IAC5F,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAA;IAEvC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAqD,CAAA;IACvE,IAAI,aAAa,IAAI,GAAG,CAAC,aAAa,IAAI,GAAG,CAAC,aAAa,KAAK,aAAa,EAAE,CAAC;QAC/E,OAAO,uBAAuB,CAAA;IAC/B,CAAC;IACD,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS;QAAE,OAAO,qBAAqB,CAAA;IAC1D,OAAO,kBAAkB,CAAA;AAC1B,CAAC"}
@@ -0,0 +1,25 @@
1
+ import type { ResolvedMailerOptions } from '../options.js';
2
+ export declare const GL_MAILER_TURNSTILE_UNCONFIGURED = "GL_MAILER_TURNSTILE_UNCONFIGURED";
3
+ export declare const GL_MAILER_SIGNING_UNCONFIGURED = "GL_MAILER_SIGNING_UNCONFIGURED";
4
+ type SecretKind = 'turnstile' | 'signing';
5
+ export type MailerRuntimeSecretFailure = {
6
+ ok: false;
7
+ code: typeof GL_MAILER_TURNSTILE_UNCONFIGURED | typeof GL_MAILER_SIGNING_UNCONFIGURED;
8
+ };
9
+ export type MailerRuntimeSecretResult = {
10
+ ok: true;
11
+ secret: string;
12
+ } | MailerRuntimeSecretFailure;
13
+ export declare function resolveMailerRuntimeSecret({ bindingsEnv, bindingName, legacyValue, requestUrl, kind, }: {
14
+ bindingsEnv: Record<string, unknown>;
15
+ bindingName: string;
16
+ legacyValue?: string;
17
+ requestUrl: string;
18
+ kind: SecretKind;
19
+ }): Promise<MailerRuntimeSecretResult>;
20
+ export declare function resolveTurnstileSecret(bindingsEnv: Record<string, unknown>, options: ResolvedMailerOptions, requestUrl: string): Promise<MailerRuntimeSecretResult>;
21
+ export declare function resolveSigningSecret(bindingsEnv: Record<string, unknown>, options: ResolvedMailerOptions, requestUrl: string): Promise<MailerRuntimeSecretResult>;
22
+ export declare function runtimeSecretErrorResponse(failure: MailerRuntimeSecretFailure): Response;
23
+ export declare function siteHost(siteUrl: string): string;
24
+ export {};
25
+ //# sourceMappingURL=runtime-secrets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-secrets.d.ts","sourceRoot":"","sources":["../../src/utils/runtime-secrets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAA;AAE1D,eAAO,MAAM,gCAAgC,qCAAqC,CAAA;AAClF,eAAO,MAAM,8BAA8B,mCAAmC,CAAA;AAQ9E,KAAK,UAAU,GAAG,WAAW,GAAG,SAAS,CAAA;AAGzC,MAAM,MAAM,0BAA0B,GAAG;IACxC,EAAE,EAAE,KAAK,CAAA;IACT,IAAI,EAAE,OAAO,gCAAgC,GAAG,OAAO,8BAA8B,CAAA;CACrF,CAAA;AAED,MAAM,MAAM,yBAAyB,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,0BAA0B,CAAA;AAmDjG,wBAAsB,0BAA0B,CAAC,EAChD,WAAW,EACX,WAAW,EACX,WAAW,EACX,UAAU,EACV,IAAI,GACJ,EAAE;IACF,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACpC,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,UAAU,CAAA;CAChB,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAsBrC;AAED,wBAAsB,sBAAsB,CAC3C,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,OAAO,EAAE,qBAAqB,EAC9B,UAAU,EAAE,MAAM,GAChB,OAAO,CAAC,yBAAyB,CAAC,CAQpC;AAED,wBAAsB,oBAAoB,CACzC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,OAAO,EAAE,qBAAqB,EAC9B,UAAU,EAAE,MAAM,GAChB,OAAO,CAAC,yBAAyB,CAAC,CAQpC;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,0BAA0B,GAAG,QAAQ,CAKxF;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEhD"}
@@ -0,0 +1,96 @@
1
+ export const GL_MAILER_TURNSTILE_UNCONFIGURED = 'GL_MAILER_TURNSTILE_UNCONFIGURED';
2
+ export const GL_MAILER_SIGNING_UNCONFIGURED = 'GL_MAILER_SIGNING_UNCONFIGURED';
3
+ const TURNSTILE_TEST_SECRETS = new Set([
4
+ '1x0000000000000000000000000000000AA',
5
+ '2x0000000000000000000000000000000AA',
6
+ '3x0000000000000000000000000000000AA',
7
+ ]);
8
+ const secretStoreCache = new WeakMap();
9
+ function isSecretStoreBinding(value) {
10
+ return (typeof value === 'object' &&
11
+ value !== null &&
12
+ 'get' in value &&
13
+ typeof value.get === 'function');
14
+ }
15
+ async function readBinding(value) {
16
+ if (typeof value === 'string')
17
+ return value.trim() || undefined;
18
+ if (!isSecretStoreBinding(value))
19
+ return undefined;
20
+ let pending = secretStoreCache.get(value);
21
+ if (!pending) {
22
+ pending = Promise.resolve()
23
+ .then(() => value.get())
24
+ .then((secret) => {
25
+ const resolved = typeof secret === 'string' ? secret.trim() || undefined : undefined;
26
+ if (!resolved)
27
+ secretStoreCache.delete(value);
28
+ return resolved;
29
+ })
30
+ .catch(() => {
31
+ secretStoreCache.delete(value);
32
+ return undefined;
33
+ });
34
+ secretStoreCache.set(value, pending);
35
+ }
36
+ return pending;
37
+ }
38
+ function hostFromUrl(url) {
39
+ try {
40
+ const parsed = new URL(url);
41
+ return {
42
+ host: parsed.host.toLowerCase(),
43
+ isLocal: parsed.hostname === 'localhost' || parsed.hostname === '127.0.0.1',
44
+ };
45
+ }
46
+ catch {
47
+ return { host: 'unknown', isLocal: false };
48
+ }
49
+ }
50
+ function failureCode(kind) {
51
+ return kind === 'turnstile' ? GL_MAILER_TURNSTILE_UNCONFIGURED : GL_MAILER_SIGNING_UNCONFIGURED;
52
+ }
53
+ export async function resolveMailerRuntimeSecret({ bindingsEnv, bindingName, legacyValue, requestUrl, kind, }) {
54
+ const requestHost = hostFromUrl(requestUrl);
55
+ let secret = await readBinding(bindingsEnv[bindingName]);
56
+ // Build-time literals are a localhost-only development escape hatch. A
57
+ // production request must always resolve its secret from the Worker env.
58
+ if (!secret && requestHost.isLocal)
59
+ secret = legacyValue?.trim() || undefined;
60
+ if (kind === 'turnstile' &&
61
+ secret &&
62
+ TURNSTILE_TEST_SECRETS.has(secret) &&
63
+ !requestHost.isLocal) {
64
+ secret = undefined;
65
+ }
66
+ if (secret)
67
+ return { ok: true, secret };
68
+ const code = failureCode(kind);
69
+ console.error(`[${code}] @growth-labs/mailer: host=${requestHost.host} binding=${bindingName}`);
70
+ return { ok: false, code };
71
+ }
72
+ export async function resolveTurnstileSecret(bindingsEnv, options, requestUrl) {
73
+ return resolveMailerRuntimeSecret({
74
+ bindingsEnv,
75
+ bindingName: options.turnstileSecretBinding,
76
+ legacyValue: options.turnstileSecretKey,
77
+ requestUrl,
78
+ kind: 'turnstile',
79
+ });
80
+ }
81
+ export async function resolveSigningSecret(bindingsEnv, options, requestUrl) {
82
+ return resolveMailerRuntimeSecret({
83
+ bindingsEnv,
84
+ bindingName: options.signingSecretBinding,
85
+ legacyValue: options.signingSecret,
86
+ requestUrl,
87
+ kind: 'signing',
88
+ });
89
+ }
90
+ export function runtimeSecretErrorResponse(failure) {
91
+ return Response.json({ error: failure.code }, { status: 503, headers: { 'Cache-Control': 'no-store' } });
92
+ }
93
+ export function siteHost(siteUrl) {
94
+ return new URL(siteUrl).host.toLowerCase();
95
+ }
96
+ //# sourceMappingURL=runtime-secrets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-secrets.js","sourceRoot":"","sources":["../../src/utils/runtime-secrets.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"send.d.ts","sourceRoot":"","sources":["../../src/utils/send.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA;AAExC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAA;AAE1D,OAAO,KAAK,EACX,UAAU,EAGV,gBAAgB,EAEhB,YAAY,EACZ,MAAM,aAAa,CAAA;AAOpB,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAA;AAI3C;;;;;GAKG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAyC/C,wBAAsB,iBAAiB,CACtC,GAAG,EAAE,SAAS,EACd,OAAO,EAAE,qBAAqB,EAC9B,MAAM,EAAE;IACP,EAAE,EAAE,MAAM,CAAA;IACV,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,YAAY,CAAA;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC9B,GACC,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CA0DjC;AAiFD,wBAAsB,YAAY,CACjC,GAAG,EAAE,SAAS,EACd,OAAO,EAAE,qBAAqB,EAC9B,MAAM,EAAE;IACP,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,UAAU,CAAA;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,MAAM,CAAC,EAAE,gBAAgB,CAAA;IACzB,UAAU,CAAC,EAAE,MAAM,CAAA;CACnB,GACC,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,CAAC,CAoCzD;AAID,wBAAsB,UAAU,CAC/B,GAAG,EAAE,SAAS,EACd,OAAO,EAAE,qBAAqB,EAC9B,MAAM,EAAE;IACP,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,UAAU,EAAE,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,gBAAgB,CAAA;IACzB,UAAU,CAAC,EAAE,MAAM,CAAA;CACnB,GACC,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,CAAC,CA+BzD;AAID,wBAAsB,gBAAgB,CACrC,EAAE,EAAE,SAAS,EACb,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,GACpC,OAAO,CAAC,IAAI,CAAC,CAKf"}
1
+ {"version":3,"file":"send.d.ts","sourceRoot":"","sources":["../../src/utils/send.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA;AAExC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAA;AAE1D,OAAO,KAAK,EACX,UAAU,EAGV,gBAAgB,EAEhB,YAAY,EACZ,MAAM,aAAa,CAAA;AAQpB,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAA;AAI3C;;;;;GAKG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAkD/C,wBAAsB,iBAAiB,CACtC,GAAG,EAAE,SAAS,EACd,OAAO,EAAE,qBAAqB,EAC9B,MAAM,EAAE;IACP,EAAE,EAAE,MAAM,CAAA;IACV,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,YAAY,CAAA;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC9B,GACC,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CA8DjC;AAuFD,wBAAsB,YAAY,CACjC,GAAG,EAAE,SAAS,EACd,OAAO,EAAE,qBAAqB,EAC9B,MAAM,EAAE;IACP,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,UAAU,CAAA;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,MAAM,CAAC,EAAE,gBAAgB,CAAA;IACzB,UAAU,CAAC,EAAE,MAAM,CAAA;CACnB,GACC,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,CAAC,CAqCzD;AAID,wBAAsB,UAAU,CAC/B,GAAG,EAAE,SAAS,EACd,OAAO,EAAE,qBAAqB,EAC9B,MAAM,EAAE;IACP,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,UAAU,EAAE,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,gBAAgB,CAAA;IACzB,UAAU,CAAC,EAAE,MAAM,CAAA;CACnB,GACC,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,CAAC,CAgCzD;AAID,wBAAsB,gBAAgB,CACrC,EAAE,EAAE,SAAS,EACb,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,GACpC,OAAO,CAAC,IAAI,CAAC,CAKf"}
@@ -2,11 +2,18 @@ import { eq } from 'drizzle-orm';
2
2
  import { drizzle } from 'drizzle-orm/d1';
3
3
  import { ulid } from 'ulidx';
4
4
  import { emailSends } from '../schema/sends.js';
5
+ import { resolveSigningSecret, siteHost } from './runtime-secrets.js';
5
6
  import { getSubscriberBatch } from './subscribers.js';
6
7
  import { renderDigestItems, renderEmail } from './templates.js';
7
8
  import { generateToken } from './tokens.js';
8
9
  import { injectTrackingPixel, rewriteLinksForTracking } from './tracking.js';
9
10
  import { buildSubscriberManageUrls } from './urls.js';
11
+ async function requireSigningSecret(env, options) {
12
+ const result = await resolveSigningSecret(env, options, options.siteUrl);
13
+ if (!result.ok)
14
+ throw new Error(result.code);
15
+ return result.secret;
16
+ }
10
17
  function resolveProducerBindings(env, options) {
11
18
  const d1 = env[options.d1Binding];
12
19
  if (!d1) {
@@ -28,13 +35,15 @@ function resolveProducerBindings(env, options) {
28
35
  }
29
36
  // ─── sendTransactional ───
30
37
  export async function sendTransactional(env, options, params) {
38
+ const signingSecret = params.subscriberId ? await requireSigningSecret(env, options) : undefined;
31
39
  const { sendsDb, queue } = resolveProducerBindings(env, options);
32
40
  const trackingId = ulid();
41
+ const deliveryToken = ulid();
33
42
  const subscriberId = params.subscriberId ?? ulid();
34
43
  // Render HTML
35
44
  let html;
36
45
  if (params.template) {
37
- const manageUrls = await buildSubscriberManageUrls(options, params.subscriberId);
46
+ const manageUrls = await buildSubscriberManageUrls(options, params.subscriberId, signingSecret);
38
47
  html = renderEmail(params.template, {
39
48
  ...params.data,
40
49
  senderName: options.senderName,
@@ -60,6 +69,7 @@ export async function sendTransactional(env, options, params) {
60
69
  type: 'transactional',
61
70
  status: 'queued',
62
71
  trackingId,
72
+ deliveryToken,
63
73
  createdAt: new Date().toISOString(),
64
74
  });
65
75
  // Build and enqueue the message
@@ -73,6 +83,7 @@ export async function sendTransactional(env, options, params) {
73
83
  trackingId,
74
84
  unsubscribeToken: '',
75
85
  preferencesToken: '',
86
+ deliveryToken,
76
87
  },
77
88
  ],
78
89
  subject: params.subject,
@@ -84,7 +95,7 @@ export async function sendTransactional(env, options, params) {
84
95
  return { trackingId };
85
96
  }
86
97
  // ─── Fan-out helper (shared by campaign + digest) ───
87
- async function fanOutToSubscribers(queue, db, sendsDb, options, params) {
98
+ async function fanOutToSubscribers(queue, db, sendsDb, options, signingSecret, params) {
88
99
  let cursor = null;
89
100
  let recipientCount = 0;
90
101
  const filter = params.filter ?? { status: ['active'] };
@@ -97,13 +108,16 @@ async function fanOutToSubscribers(queue, db, sendsDb, options, params) {
97
108
  const recipients = [];
98
109
  for (const sub of batch) {
99
110
  const trackingId = ulid();
100
- const unsubscribeToken = await generateToken(options.signingSecret, {
111
+ const deliveryToken = ulid();
112
+ const unsubscribeToken = await generateToken(signingSecret, {
101
113
  subscriberId: sub.id,
102
114
  action: 'unsubscribe',
115
+ host: siteHost(options.siteUrl),
103
116
  });
104
- const preferencesToken = await generateToken(options.signingSecret, {
117
+ const preferencesToken = await generateToken(signingSecret, {
105
118
  subscriberId: sub.id,
106
119
  action: 'preferences',
120
+ host: siteHost(options.siteUrl),
107
121
  });
108
122
  await sendsDb.insert(emailSends).values({
109
123
  id: ulid(),
@@ -115,6 +129,7 @@ async function fanOutToSubscribers(queue, db, sendsDb, options, params) {
115
129
  type: params.type,
116
130
  status: 'queued',
117
131
  trackingId,
132
+ deliveryToken,
118
133
  createdAt: new Date().toISOString(),
119
134
  });
120
135
  recipients.push({
@@ -123,6 +138,7 @@ async function fanOutToSubscribers(queue, db, sendsDb, options, params) {
123
138
  trackingId,
124
139
  unsubscribeToken,
125
140
  preferencesToken,
141
+ deliveryToken,
126
142
  });
127
143
  }
128
144
  const message = {
@@ -144,6 +160,7 @@ async function fanOutToSubscribers(queue, db, sendsDb, options, params) {
144
160
  // ─── sendCampaign ───
145
161
  export async function sendCampaign(env, options, params) {
146
162
  const campaignId = params.campaignId ?? ulid();
163
+ const signingSecret = await requireSigningSecret(env, options);
147
164
  const { db, sendsDb, queue } = resolveProducerBindings(env, options);
148
165
  // Render HTML
149
166
  let html;
@@ -168,7 +185,7 @@ export async function sendCampaign(env, options, params) {
168
185
  const trackClickUrl = `${options.siteUrl}${options.trackClickPath}`;
169
186
  html = injectTrackingPixel(html, trackOpenUrl);
170
187
  html = rewriteLinksForTracking(html, trackClickUrl);
171
- const recipientCount = await fanOutToSubscribers(queue, db, sendsDb, options, {
188
+ const recipientCount = await fanOutToSubscribers(queue, db, sendsDb, options, signingSecret, {
172
189
  subject: params.subject,
173
190
  html,
174
191
  campaignId,
@@ -180,6 +197,7 @@ export async function sendCampaign(env, options, params) {
180
197
  // ─── sendDigest ───
181
198
  export async function sendDigest(env, options, params) {
182
199
  const campaignId = params.campaignId ?? ulid();
200
+ const signingSecret = await requireSigningSecret(env, options);
183
201
  const { db, sendsDb, queue } = resolveProducerBindings(env, options);
184
202
  // Render digest items then full template
185
203
  const itemsHtml = renderDigestItems(params.items);
@@ -197,7 +215,7 @@ export async function sendDigest(env, options, params) {
197
215
  const trackClickUrl = `${options.siteUrl}${options.trackClickPath}`;
198
216
  html = injectTrackingPixel(html, trackOpenUrl);
199
217
  html = rewriteLinksForTracking(html, trackClickUrl);
200
- const recipientCount = await fanOutToSubscribers(queue, db, sendsDb, options, {
218
+ const recipientCount = await fanOutToSubscribers(queue, db, sendsDb, options, signingSecret, {
201
219
  subject: params.subject,
202
220
  html,
203
221
  campaignId,
@@ -1 +1 @@
1
- {"version":3,"file":"send.js","sourceRoot":"","sources":["../../src/utils/send.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"send.js","sourceRoot":"","sources":["../../src/utils/send.ts"],"names":[],"mappings":"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"}
@@ -1,12 +1,14 @@
1
1
  interface TokenPayload {
2
2
  subscriberId: string;
3
3
  action: 'confirm' | 'unsubscribe' | 'preferences';
4
+ host: string;
4
5
  exp?: number;
5
6
  }
6
7
  export declare function generateToken(secret: string, payload: TokenPayload): Promise<string>;
7
- export declare function verifyToken(secret: string, token: string): Promise<{
8
+ export declare function verifyToken(secret: string, token: string, expectedHost: string): Promise<{
8
9
  subscriberId: string;
9
10
  action: string;
11
+ host: string;
10
12
  exp?: number;
11
13
  } | null>;
12
14
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../src/utils/tokens.ts"],"names":[],"mappings":"AA0CA,UAAU,YAAY;IACrB,YAAY,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,SAAS,GAAG,aAAa,GAAG,aAAa,CAAA;IACjD,GAAG,CAAC,EAAE,MAAM,CAAA;CACZ;AAID,wBAAsB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAU1F;AAED,wBAAsB,WAAW,CAChC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACX,OAAO,CAAC;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAyBxE"}
1
+ {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../src/utils/tokens.ts"],"names":[],"mappings":"AA0CA,UAAU,YAAY;IACrB,YAAY,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,SAAS,GAAG,aAAa,GAAG,aAAa,CAAA;IACjD,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAA;CACZ;AAID,wBAAsB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAc1F;AAED,wBAAsB,WAAW,CAChC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,GAClB,OAAO,CAAC;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CA8BtF"}
@@ -30,6 +30,9 @@ async function hmacVerify(secret, data, signature) {
30
30
  }
31
31
  const SEVEN_DAYS_MS = 7 * 24 * 60 * 60 * 1000;
32
32
  export async function generateToken(secret, payload) {
33
+ if (typeof payload.host !== 'string' || !payload.host.trim()) {
34
+ throw new Error('GL_MAILER_TOKEN_HOST_REQUIRED');
35
+ }
33
36
  const finalPayload = { ...payload };
34
37
  if (finalPayload.action === 'confirm' && finalPayload.exp === undefined) {
35
38
  finalPayload.exp = Date.now() + SEVEN_DAYS_MS;
@@ -38,7 +41,9 @@ export async function generateToken(secret, payload) {
38
41
  const signature = await hmacSign(secret, payloadB64);
39
42
  return `${payloadB64}.${signature}`;
40
43
  }
41
- export async function verifyToken(secret, token) {
44
+ export async function verifyToken(secret, token, expectedHost) {
45
+ if (typeof expectedHost !== 'string' || !expectedHost.trim())
46
+ return null;
42
47
  const dotIndex = token.indexOf('.');
43
48
  if (dotIndex === -1)
44
49
  return null;
@@ -46,14 +51,18 @@ export async function verifyToken(secret, token) {
46
51
  const signature = token.slice(dotIndex + 1);
47
52
  if (!payloadB64 || !signature)
48
53
  return null;
49
- const valid = await hmacVerify(secret, payloadB64, signature);
50
- if (!valid)
51
- return null;
52
54
  try {
55
+ const valid = await hmacVerify(secret, payloadB64, signature);
56
+ if (!valid)
57
+ return null;
53
58
  const decoded = JSON.parse(new TextDecoder().decode(fromBase64Url(payloadB64)));
54
59
  if (decoded.exp !== undefined && decoded.exp < Date.now())
55
60
  return null;
56
- return decoded;
61
+ if (typeof decoded.host !== 'string' || !decoded.host.trim())
62
+ return null;
63
+ if (decoded.host !== expectedHost)
64
+ return null;
65
+ return { ...decoded, host: decoded.host };
57
66
  }
58
67
  catch {
59
68
  return null;