dkimkit 0.0.0-stage → 0.6.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 (128) hide show
  1. package/README.md +153 -2
  2. package/dist/src/cli.d.ts +2 -0
  3. package/dist/src/cli.js +398 -0
  4. package/dist/src/cli.js.map +1 -0
  5. package/dist/src/dns-host.d.ts +10 -0
  6. package/dist/src/dns-host.js +31 -0
  7. package/dist/src/dns-host.js.map +1 -0
  8. package/dist/src/errors.d.ts +17 -0
  9. package/dist/src/errors.js +51 -0
  10. package/dist/src/errors.js.map +1 -0
  11. package/dist/src/hosted/api.d.ts +95 -0
  12. package/dist/src/hosted/api.js +781 -0
  13. package/dist/src/hosted/api.js.map +1 -0
  14. package/dist/src/hosted/auth.d.ts +70 -0
  15. package/dist/src/hosted/auth.js +121 -0
  16. package/dist/src/hosted/auth.js.map +1 -0
  17. package/dist/src/hosted/billing-dodo.d.ts +58 -0
  18. package/dist/src/hosted/billing-dodo.js +139 -0
  19. package/dist/src/hosted/billing-dodo.js.map +1 -0
  20. package/dist/src/hosted/billing-stripe.d.ts +82 -0
  21. package/dist/src/hosted/billing-stripe.js +205 -0
  22. package/dist/src/hosted/billing-stripe.js.map +1 -0
  23. package/dist/src/hosted/billing.d.ts +114 -0
  24. package/dist/src/hosted/billing.js +173 -0
  25. package/dist/src/hosted/billing.js.map +1 -0
  26. package/dist/src/hosted/cli.d.ts +2 -0
  27. package/dist/src/hosted/cli.js +305 -0
  28. package/dist/src/hosted/cli.js.map +1 -0
  29. package/dist/src/hosted/crypto.d.ts +22 -0
  30. package/dist/src/hosted/crypto.js +55 -0
  31. package/dist/src/hosted/crypto.js.map +1 -0
  32. package/dist/src/hosted/index.d.ts +7 -0
  33. package/dist/src/hosted/index.js +11 -0
  34. package/dist/src/hosted/index.js.map +1 -0
  35. package/dist/src/hosted/markdown.d.ts +16 -0
  36. package/dist/src/hosted/markdown.js +168 -0
  37. package/dist/src/hosted/markdown.js.map +1 -0
  38. package/dist/src/hosted/net.d.ts +9 -0
  39. package/dist/src/hosted/net.js +60 -0
  40. package/dist/src/hosted/net.js.map +1 -0
  41. package/dist/src/hosted/postgres-store.d.ts +62 -0
  42. package/dist/src/hosted/postgres-store.js +387 -0
  43. package/dist/src/hosted/postgres-store.js.map +1 -0
  44. package/dist/src/hosted/serialize.d.ts +144 -0
  45. package/dist/src/hosted/serialize.js +126 -0
  46. package/dist/src/hosted/serialize.js.map +1 -0
  47. package/dist/src/hosted/service.d.ts +166 -0
  48. package/dist/src/hosted/service.js +582 -0
  49. package/dist/src/hosted/service.js.map +1 -0
  50. package/dist/src/hosted/site.d.ts +54 -0
  51. package/dist/src/hosted/site.js +472 -0
  52. package/dist/src/hosted/site.js.map +1 -0
  53. package/dist/src/hosted/sqlite-store.d.ts +45 -0
  54. package/dist/src/hosted/sqlite-store.js +351 -0
  55. package/dist/src/hosted/sqlite-store.js.map +1 -0
  56. package/dist/src/hosted/store.d.ts +257 -0
  57. package/dist/src/hosted/store.js +181 -0
  58. package/dist/src/hosted/store.js.map +1 -0
  59. package/dist/src/hosted/widget.d.ts +46 -0
  60. package/dist/src/hosted/widget.js +130 -0
  61. package/dist/src/hosted/widget.js.map +1 -0
  62. package/dist/src/hosted/worker.d.ts +45 -0
  63. package/dist/src/hosted/worker.js +142 -0
  64. package/dist/src/hosted/worker.js.map +1 -0
  65. package/dist/src/http.d.ts +14 -0
  66. package/dist/src/http.js +54 -0
  67. package/dist/src/http.js.map +1 -0
  68. package/dist/src/index.d.ts +19 -0
  69. package/dist/src/index.js +19 -0
  70. package/dist/src/index.js.map +1 -0
  71. package/dist/src/orchestrator.d.ts +70 -0
  72. package/dist/src/orchestrator.js +69 -0
  73. package/dist/src/orchestrator.js.map +1 -0
  74. package/dist/src/propagation.d.ts +30 -0
  75. package/dist/src/propagation.js +76 -0
  76. package/dist/src/propagation.js.map +1 -0
  77. package/dist/src/providers/dns/aws.d.ts +28 -0
  78. package/dist/src/providers/dns/aws.js +103 -0
  79. package/dist/src/providers/dns/aws.js.map +1 -0
  80. package/dist/src/providers/dns/cloudflare.d.ts +26 -0
  81. package/dist/src/providers/dns/cloudflare.js +97 -0
  82. package/dist/src/providers/dns/cloudflare.js.map +1 -0
  83. package/dist/src/providers/dns/manual.d.ts +12 -0
  84. package/dist/src/providers/dns/manual.js +18 -0
  85. package/dist/src/providers/dns/manual.js.map +1 -0
  86. package/dist/src/providers/dns/route53.d.ts +34 -0
  87. package/dist/src/providers/dns/route53.js +176 -0
  88. package/dist/src/providers/dns/route53.js.map +1 -0
  89. package/dist/src/providers/email/factory.d.ts +29 -0
  90. package/dist/src/providers/email/factory.js +67 -0
  91. package/dist/src/providers/email/factory.js.map +1 -0
  92. package/dist/src/providers/email/mailgun.d.ts +36 -0
  93. package/dist/src/providers/email/mailgun.js +141 -0
  94. package/dist/src/providers/email/mailgun.js.map +1 -0
  95. package/dist/src/providers/email/postmark.d.ts +37 -0
  96. package/dist/src/providers/email/postmark.js +121 -0
  97. package/dist/src/providers/email/postmark.js.map +1 -0
  98. package/dist/src/providers/email/sendgrid.d.ts +31 -0
  99. package/dist/src/providers/email/sendgrid.js +109 -0
  100. package/dist/src/providers/email/sendgrid.js.map +1 -0
  101. package/dist/src/providers/email/ses.d.ts +39 -0
  102. package/dist/src/providers/email/ses.js +123 -0
  103. package/dist/src/providers/email/ses.js.map +1 -0
  104. package/dist/src/providers/factory.d.ts +14 -0
  105. package/dist/src/providers/factory.js +32 -0
  106. package/dist/src/providers/factory.js.map +1 -0
  107. package/dist/src/records.d.ts +35 -0
  108. package/dist/src/records.js +109 -0
  109. package/dist/src/records.js.map +1 -0
  110. package/dist/src/server.d.ts +67 -0
  111. package/dist/src/server.js +301 -0
  112. package/dist/src/server.js.map +1 -0
  113. package/dist/src/types.d.ts +75 -0
  114. package/dist/src/types.js +2 -0
  115. package/dist/src/types.js.map +1 -0
  116. package/dist/src/xml.d.ts +6 -0
  117. package/dist/src/xml.js +23 -0
  118. package/dist/src/xml.js.map +1 -0
  119. package/docs/billing.md +43 -0
  120. package/docs/getting-started.md +57 -0
  121. package/docs/hosted-api.md +192 -0
  122. package/docs/self-hosting.md +148 -0
  123. package/docs/widget.md +121 -0
  124. package/package.json +63 -4
  125. package/web/dashboard.html +390 -0
  126. package/web/index.html +697 -0
  127. package/web/widget-frame.html +480 -0
  128. package/web/widget.js +91 -0
@@ -0,0 +1,582 @@
1
+ import { ApiError, apiErrorHint, ConfigError, DnsConflictError } from '../errors.js';
2
+ import { setupDomain } from '../orchestrator.js';
3
+ import { authoritativeLookup } from '../propagation.js';
4
+ import { assertEmailCredentials, createEmailProvider, EMAIL_PROVIDER_LABELS, pickEmailCredentials, } from '../providers/email/factory.js';
5
+ import { createDnsProvider } from '../providers/factory.js';
6
+ import { normalizeName } from '../records.js';
7
+ import { hashApiKey, newApiKey, newId, newWebhookSecret } from './crypto.js';
8
+ import { assertPublicHttpsUrl } from './net.js';
9
+ import { iso, toPublicDomain } from './serialize.js';
10
+ import { DuplicateError, utcDay, } from './store.js';
11
+ /** Tenant credentials only: never falls back to the operator's environment or ~/.aws files. */
12
+ export const realProviders = {
13
+ email: (provider, credentials, subuser) => createEmailProvider(provider, credentials, { subuser }),
14
+ dns: (provider, c) => {
15
+ assertDnsCredentials(provider, c);
16
+ return createDnsProvider(provider, {
17
+ cloudflareApiToken: c.cloudflareApiToken,
18
+ aws: { accessKeyId: c.awsAccessKeyId, secretAccessKey: c.awsSecretAccessKey, sessionToken: c.awsSessionToken },
19
+ route53HostedZoneId: c.route53HostedZoneId,
20
+ env: {},
21
+ });
22
+ },
23
+ };
24
+ export class NotFoundError extends Error {
25
+ }
26
+ /** The account is at its plan's domain limit. */
27
+ export class PlanLimitError extends Error {
28
+ limit;
29
+ upgradeUrl;
30
+ constructor(limit, message = `Your plan allows ${limit} domain${limit === 1 ? '' : 's'}. Delete one or upgrade to add more.`,
31
+ /** Where to fix it, e.g. the billing dashboard. */
32
+ upgradeUrl) {
33
+ super(message);
34
+ this.limit = limit;
35
+ this.upgradeUrl = upgradeUrl;
36
+ }
37
+ }
38
+ export class ConflictError extends Error {
39
+ existingId;
40
+ constructor(message, existingId) {
41
+ super(message);
42
+ this.existingId = existingId;
43
+ }
44
+ }
45
+ const RETRY_DELAYS_MS = [30e3, 60e3, 2 * 60e3, 5 * 60e3, 10 * 60e3, 15 * 60e3, 30 * 60e3];
46
+ const HOUR = 3600e3;
47
+ export class DomainService {
48
+ opts;
49
+ store;
50
+ vault;
51
+ providers;
52
+ lookup;
53
+ now;
54
+ maxAgeMs;
55
+ reverifyMs;
56
+ log;
57
+ constructor(opts) {
58
+ this.opts = opts;
59
+ this.store = opts.store;
60
+ this.vault = opts.vault;
61
+ this.providers = opts.providers ?? realProviders;
62
+ this.lookup = opts.lookup ?? authoritativeLookup;
63
+ this.now = opts.now ?? Date.now;
64
+ this.maxAgeMs = opts.maxAgeMs ?? 72 * HOUR;
65
+ this.reverifyMs = opts.reverifyMs ?? 24 * HOUR;
66
+ this.log = opts.log ?? (() => { });
67
+ }
68
+ // ---- accounts ----
69
+ /** `provider` is the email provider and credentials, or a SendGrid API key as shorthand. */
70
+ async createAccount(name, provider, opts = {}) {
71
+ const setting = typeof provider === 'string' ? { provider: 'sendgrid', credentials: { apiKey: provider } } : provider;
72
+ if (setting)
73
+ assertEmailCredentials(setting.provider, setting.credentials);
74
+ const apiKey = newApiKey();
75
+ const account = {
76
+ id: newId('acct'),
77
+ name,
78
+ apiKeyHash: hashApiKey(apiKey),
79
+ emailProvider: setting?.provider ?? 'sendgrid',
80
+ emailCredentialsEnc: setting ? this.vault.encryptJson(pickEmailCredentials(setting.provider, setting.credentials)) : null,
81
+ webhookUrl: null,
82
+ webhookSecret: newWebhookSecret(),
83
+ widgetOrigins: [],
84
+ domainLimit: null,
85
+ email: opts.email ?? null,
86
+ billingCustomerId: null,
87
+ billingSubscriptionId: null,
88
+ billingStatus: 'free',
89
+ billingPeriodStart: null,
90
+ billingPeriodEnd: null,
91
+ reportedQuantity: 0,
92
+ billingEventAt: null,
93
+ createdAt: this.now(),
94
+ };
95
+ await this.store.createAccount(account);
96
+ return { account, apiKey };
97
+ }
98
+ async authenticate(apiKey) {
99
+ return await this.store.getAccountByKeyHash(hashApiKey(apiKey));
100
+ }
101
+ async updateAccount(account, patch) {
102
+ const changes = {};
103
+ if (patch.name !== undefined)
104
+ changes.name = patch.name;
105
+ const setting = patch.emailProvider ?? (patch.sendgridApiKey !== undefined ? { provider: 'sendgrid', credentials: { apiKey: patch.sendgridApiKey } } : undefined);
106
+ if (setting) {
107
+ // Fields left out keep their saved values (e.g. updating only the region).
108
+ const current = setting.provider === account.emailProvider ? this.credentialsOf(account) : {};
109
+ const credentials = pickEmailCredentials(setting.provider, { ...current, ...setting.credentials });
110
+ // Input errors first, then the switching rule.
111
+ assertEmailCredentials(setting.provider, credentials);
112
+ // Existing domains belong to the provider they were created at.
113
+ if (setting.provider !== account.emailProvider && (await this.store.countDomains(account.id)) > 0) {
114
+ throw new ConfigError(`This account's domains are at ${EMAIL_PROVIDER_LABELS[account.emailProvider] ?? account.emailProvider}. Delete them before switching email provider.`);
115
+ }
116
+ changes.emailProvider = setting.provider;
117
+ changes.emailCredentialsEnc = this.vault.encryptJson(credentials);
118
+ }
119
+ if (patch.widgetOrigins !== undefined)
120
+ changes.widgetOrigins = patch.widgetOrigins;
121
+ if (patch.webhookUrl !== undefined) {
122
+ if (patch.webhookUrl !== null) {
123
+ await assertPublicHttpsUrl(patch.webhookUrl, { allowPrivate: this.opts.allowPrivateWebhooks });
124
+ }
125
+ changes.webhookUrl = patch.webhookUrl;
126
+ }
127
+ await this.store.updateAccount(account.id, changes);
128
+ return (await this.store.getAccount(account.id));
129
+ }
130
+ async rotateApiKey(account) {
131
+ const apiKey = newApiKey();
132
+ await this.store.updateAccount(account.id, { apiKeyHash: hashApiKey(apiKey) });
133
+ return apiKey;
134
+ }
135
+ async rotateWebhookSecret(account) {
136
+ await this.store.updateAccount(account.id, { webhookSecret: newWebhookSecret() });
137
+ return (await this.store.getAccount(account.id));
138
+ }
139
+ // ---- domains ----
140
+ async getDomain(account, id) {
141
+ const row = await this.store.getDomain(account.id, id);
142
+ if (!row)
143
+ throw new NotFoundError(`No domain with id ${id}.`);
144
+ return row;
145
+ }
146
+ async listDomains(account, query) {
147
+ return await this.store.listDomains(account.id, query);
148
+ }
149
+ async listEvents(domainId, limit = 100) {
150
+ return await this.store.listEvents(domainId, limit);
151
+ }
152
+ /** Creates the domain at the email provider right away so the response can include its DNS records. */
153
+ async createDomain(account, input) {
154
+ const domain = normalizeName(input.domain);
155
+ const subdomain = input.subdomain || null;
156
+ const existing = await this.store.findDomain(account.id, domain, subdomain);
157
+ if (existing)
158
+ throw new ConflictError(`${domain} is already registered.`, existing.id);
159
+ const credentials = pickCredentials(input.dnsProvider, input.dnsCredentials ?? {});
160
+ assertDnsCredentials(input.dnsProvider, credentials);
161
+ // Before anything is created at the email provider. Soft limits: two simultaneous creates can both pass.
162
+ const cap = this.opts.planCap?.(account) ?? null;
163
+ if (account.domainLimit !== null || cap) {
164
+ const count = await this.store.countDomains(account.id);
165
+ if (cap && count >= cap.limit)
166
+ throw new PlanLimitError(cap.limit, cap.message, cap.upgradeUrl);
167
+ if (account.domainLimit !== null && count >= account.domainLimit)
168
+ throw new PlanLimitError(account.domainLimit);
169
+ }
170
+ const sendgridSubuser = input.sendgridSubuser || null;
171
+ const email = this.emailFor(account, sendgridSubuser);
172
+ const inbound = this.resolveInbound(email, domain, input.inbound ?? null);
173
+ const auth = await email.ensureDomain(domain, { subdomain: subdomain ?? undefined });
174
+ const now = this.now();
175
+ const records = [...auth.records, ...(inbound ? email.inboundRecords(inbound.hostname) : [])];
176
+ const row = {
177
+ id: newId('dom'),
178
+ accountId: account.id,
179
+ domain,
180
+ subdomain,
181
+ tenantId: input.tenantId ?? null,
182
+ metadata: input.metadata ?? {},
183
+ status: 'pending',
184
+ providerDomainId: auth.id,
185
+ sendgridSubuser,
186
+ dnsProvider: input.dnsProvider,
187
+ dnsCredentialsEnc: input.dnsProvider === 'manual' ? null : this.vault.encryptJson(credentials),
188
+ inbound,
189
+ overwrite: input.overwrite ?? false,
190
+ records,
191
+ pending: records.map((r) => r.name),
192
+ validation: null,
193
+ conflicts: null,
194
+ lastError: null,
195
+ attempts: 0,
196
+ nextRunAt: now,
197
+ lockedUntil: null,
198
+ verifiedAt: null,
199
+ expiresAt: now + this.maxAgeMs,
200
+ createdAt: now,
201
+ updatedAt: now,
202
+ };
203
+ try {
204
+ await this.store.insertDomain(row);
205
+ }
206
+ catch (err) {
207
+ if (!(err instanceof DuplicateError))
208
+ throw err;
209
+ const winner = await this.store.findDomain(account.id, domain, subdomain);
210
+ throw new ConflictError(`${domain} is already registered.`, winner?.id ?? '');
211
+ }
212
+ await this.emit(account, row, 'domain.created');
213
+ await this.recordUsage(row, 'domain_created', `domain_created:${row.id}`);
214
+ return row;
215
+ }
216
+ async updateDomain(account, id, patch) {
217
+ const row = await this.getDomain(account, id);
218
+ const now = this.now();
219
+ const changes = { updatedAt: now };
220
+ let rerun = false;
221
+ if (patch.tenantId !== undefined)
222
+ changes.tenantId = patch.tenantId;
223
+ if (patch.metadata !== undefined)
224
+ changes.metadata = patch.metadata;
225
+ if (patch.dnsProvider !== undefined || patch.dnsCredentials !== undefined) {
226
+ const provider = patch.dnsProvider ?? row.dnsProvider;
227
+ const providerChanged = provider !== row.dnsProvider;
228
+ const current = row.dnsCredentialsEnc && !providerChanged ? this.vault.decryptJson(row.dnsCredentialsEnc) : {};
229
+ const credentials = pickCredentials(provider, { ...current, ...patch.dnsCredentials });
230
+ assertDnsCredentials(provider, credentials);
231
+ changes.dnsProvider = provider;
232
+ changes.dnsCredentialsEnc = provider === 'manual' ? null : this.vault.encryptJson(credentials);
233
+ rerun = true;
234
+ }
235
+ if (patch.overwrite !== undefined && patch.overwrite !== row.overwrite) {
236
+ changes.overwrite = patch.overwrite;
237
+ rerun = true;
238
+ }
239
+ if (patch.inbound !== undefined) {
240
+ const email = this.emailFor(account, row.sendgridSubuser);
241
+ const inbound = this.resolveInbound(email, row.domain, patch.inbound);
242
+ const old = row.inbound;
243
+ if (old && old.hostname !== inbound?.hostname) {
244
+ await ignoreNotFound(email.deleteInboundParse(old.hostname));
245
+ }
246
+ // The old MX record stays in the tenant's DNS; we never delete DNS records.
247
+ const withoutOldMx = row.records.filter((r) => !(old && r.type === 'MX' && r.name === old.hostname));
248
+ changes.inbound = inbound;
249
+ changes.records = [...withoutOldMx, ...(inbound ? email.inboundRecords(inbound.hostname) : [])];
250
+ rerun = true;
251
+ }
252
+ if (rerun) {
253
+ Object.assign(changes, {
254
+ status: 'pending',
255
+ conflicts: null,
256
+ lastError: null,
257
+ attempts: 0,
258
+ expiresAt: now + this.maxAgeMs,
259
+ nextRunAt: now,
260
+ });
261
+ }
262
+ return await this.store.updateDomain(row.id, changes);
263
+ }
264
+ /**
265
+ * Checks that DNS credentials work for this domain's zone by planning the
266
+ * changes, without writing anything. Throws the provider's error if not.
267
+ */
268
+ async testDnsAccess(row, provider, credentials) {
269
+ const picked = pickCredentials(provider, credentials);
270
+ assertDnsCredentials(provider, picked);
271
+ if (provider === 'manual')
272
+ return [];
273
+ return this.providers.dns(provider, picked).plan(row.records, { overwrite: row.overwrite });
274
+ }
275
+ /** Schedules an immediate check. Restarts the clock for failed or conflicting domains. */
276
+ async verifyNow(account, id) {
277
+ const row = await this.getDomain(account, id);
278
+ const now = this.now();
279
+ if (row.lockedUntil !== null && row.lockedUntil > now)
280
+ return row;
281
+ const restart = row.status === 'failed' || row.status === 'conflict';
282
+ return await this.store.updateDomain(row.id, {
283
+ nextRunAt: now,
284
+ attempts: 0,
285
+ updatedAt: now,
286
+ ...(restart ? { status: 'pending', conflicts: null, lastError: null, expiresAt: now + this.maxAgeMs } : {}),
287
+ });
288
+ }
289
+ /** Removes the domain here; with `remote`, also deletes it (and its inbound parse) at the email provider. */
290
+ async deleteDomain(account, id, { remote = false } = {}) {
291
+ const row = await this.getDomain(account, id);
292
+ if (remote) {
293
+ const email = this.emailFor(account, row.sendgridSubuser);
294
+ if (row.inbound)
295
+ await ignoreNotFound(email.deleteInboundParse(row.inbound.hostname));
296
+ await ignoreNotFound(email.deleteDomain(row.providerDomainId));
297
+ }
298
+ await this.emit(account, row, 'domain.deleted', { remote });
299
+ await this.store.deleteDomain(row.id);
300
+ }
301
+ /**
302
+ * One step of the lifecycle for a leased domain: write DNS if needed, check
303
+ * propagation once, validate once, then reschedule. Always releases the lease.
304
+ */
305
+ async runDomain(leased) {
306
+ const account = await this.store.getAccount(leased.accountId);
307
+ if (!account) {
308
+ await this.store.deleteDomain(leased.id);
309
+ return leased;
310
+ }
311
+ const now = this.now();
312
+ try {
313
+ const email = this.emailFor(account, leased.sendgridSubuser);
314
+ if (leased.status === 'verified')
315
+ return await this.reverify(account, leased, email, now);
316
+ if (leased.expiresAt !== null && now > leased.expiresAt) {
317
+ return await this.fail(account, leased, now, 'Not verified in time. Check the DNS records, then call POST /v1/domains/{id}/verify to try again.');
318
+ }
319
+ let written = 0;
320
+ const result = await setupDomain(pinDomain(email, leased.providerDomainId), this.dnsFor(leased), {
321
+ domain: leased.domain,
322
+ subdomain: leased.subdomain ?? undefined,
323
+ overwrite: leased.overwrite,
324
+ inbound: leased.inbound ?? undefined,
325
+ propagation: { lookup: await this.lookup(leased.domain), timeoutMs: 0 },
326
+ validation: { attempts: 1 },
327
+ onEvent: (e) => {
328
+ if (e.type === 'applied')
329
+ written = e.changes.length;
330
+ },
331
+ });
332
+ const records = result.changes.map((c) => c.record);
333
+ const base = { records, conflicts: null, lastError: null, updatedAt: now };
334
+ let row;
335
+ if (result.status === 'complete') {
336
+ row = await this.store.updateDomain(leased.id, {
337
+ ...base,
338
+ status: 'verified',
339
+ pending: [],
340
+ validation: result.validation ?? null,
341
+ attempts: 0,
342
+ verifiedAt: now,
343
+ nextRunAt: now + this.reverifyMs,
344
+ lockedUntil: null,
345
+ });
346
+ }
347
+ else if (result.status === 'dns-pending') {
348
+ row = await this.store.updateDomain(leased.id, {
349
+ ...base,
350
+ status: 'awaiting_dns',
351
+ pending: (result.pending ?? []).map((r) => r.name),
352
+ ...this.retry(leased, now),
353
+ });
354
+ }
355
+ else {
356
+ row = await this.store.updateDomain(leased.id, {
357
+ ...base,
358
+ status: 'verifying',
359
+ pending: [],
360
+ validation: result.validation ?? null,
361
+ ...this.retry(leased, now),
362
+ });
363
+ }
364
+ if (written > 0)
365
+ await this.emit(account, row, 'domain.dns_written', { count: written });
366
+ if (row.status === 'verified') {
367
+ await this.emit(account, row, 'domain.verified');
368
+ await this.recordUsage(row, 'domain_verified', `domain_verified:${row.id}:${now}`);
369
+ await this.recordUsage(row, 'active_domain_day', `active_domain_day:${row.id}:${utcDay(now)}`);
370
+ }
371
+ return row;
372
+ }
373
+ catch (err) {
374
+ return await this.handleError(account, leased, now, err);
375
+ }
376
+ }
377
+ async reverify(account, row, email, now) {
378
+ const validation = await email.validateDomain(row.providerDomainId);
379
+ if (validation.valid) {
380
+ await this.recordUsage(row, 'active_domain_day', `active_domain_day:${row.id}:${utcDay(now)}`);
381
+ return await this.store.updateDomain(row.id, {
382
+ validation, lastError: null, attempts: 0, nextRunAt: now + this.reverifyMs, lockedUntil: null, updatedAt: now,
383
+ });
384
+ }
385
+ const lost = await this.store.updateDomain(row.id, {
386
+ status: 'awaiting_dns',
387
+ validation,
388
+ verifiedAt: null,
389
+ attempts: 0,
390
+ expiresAt: now + this.maxAgeMs,
391
+ nextRunAt: now + RETRY_DELAYS_MS[0],
392
+ lockedUntil: null,
393
+ updatedAt: now,
394
+ });
395
+ await this.emit(account, lost, 'domain.verification_lost');
396
+ return lost;
397
+ }
398
+ async handleError(account, row, now, err) {
399
+ if (err instanceof DnsConflictError) {
400
+ const updated = await this.store.updateDomain(row.id, {
401
+ status: 'conflict', conflicts: err.conflicts, lastError: err.message, nextRunAt: null, lockedUntil: null, updatedAt: now,
402
+ });
403
+ await this.emit(account, updated, 'domain.conflict');
404
+ return updated;
405
+ }
406
+ // Bad credentials, missing zones, a provider domain deleted out of band: retrying won't help.
407
+ if (err instanceof ConfigError || (err instanceof ApiError && [400, 401, 403, 404].includes(err.status))) {
408
+ const hint = err instanceof ApiError ? apiErrorHint(err) : undefined;
409
+ return await this.fail(account, row, now, hint ? `${err.message} ${hint}` : err.message);
410
+ }
411
+ const message = err instanceof Error ? err.message : String(err);
412
+ this.log('warn', 'domain check failed; will retry', { domain_id: row.id, error: message });
413
+ return await this.store.updateDomain(row.id, { lastError: message, updatedAt: now, ...this.retry(row, now) });
414
+ }
415
+ async fail(account, row, now, reason) {
416
+ const updated = await this.store.updateDomain(row.id, {
417
+ status: 'failed', lastError: reason, nextRunAt: null, lockedUntil: null, updatedAt: now,
418
+ });
419
+ await this.emit(account, updated, 'domain.failed', { reason });
420
+ return updated;
421
+ }
422
+ retry(row, now) {
423
+ const attempts = row.attempts + 1;
424
+ const delay = RETRY_DELAYS_MS[Math.min(attempts - 1, RETRY_DELAYS_MS.length - 1)];
425
+ return { attempts, nextRunAt: now + delay, lockedUntil: null };
426
+ }
427
+ // ---- usage metering ----
428
+ /** Records an active day for every verified domain. Idempotent; the runner calls it hourly. */
429
+ async meterActiveDomains() {
430
+ const now = this.now();
431
+ await this.store.recordActiveDomainDays(utcDay(now), now);
432
+ }
433
+ /** One account's usage for a period, optionally broken down by tenant. */
434
+ async usage(account, from, to, groupByTenant) {
435
+ const [total] = await this.store.summarizeUsage({ from, to, accountId: account.id });
436
+ return {
437
+ totals: total ?? emptyTotals(),
438
+ byTenant: groupByTenant ? await this.store.summarizeUsage({ from, to, accountId: account.id, groupByTenant: true }) : null,
439
+ domainCount: await this.store.countDomains(account.id),
440
+ };
441
+ }
442
+ /** Every account's usage for a period, for invoicing. */
443
+ async usageReport(from, to) {
444
+ const rows = new Map((await this.store.summarizeUsage({ from, to })).map((r) => [r.accountId, r]));
445
+ return (await this.store.listAccounts()).map((a) => ({
446
+ ...(rows.get(a.id) ?? { accountId: a.id, ...emptyTotals() }),
447
+ name: a.name,
448
+ domainLimit: a.domainLimit,
449
+ }));
450
+ }
451
+ async setDomainLimit(accountId, limit) {
452
+ if (!(await this.store.getAccount(accountId)))
453
+ throw new NotFoundError(`No account with id ${accountId}.`);
454
+ await this.store.updateAccount(accountId, { domainLimit: limit });
455
+ return (await this.store.getAccount(accountId));
456
+ }
457
+ async recordUsage(row, metric, id) {
458
+ const now = this.now();
459
+ await this.store.recordUsage([
460
+ { id, accountId: row.accountId, tenantId: row.tenantId, domainId: row.id, domain: row.domain, metric, quantity: 1, day: utcDay(now), occurredAt: now },
461
+ ]);
462
+ }
463
+ async emit(account, row, type, data = {}) {
464
+ const now = this.now();
465
+ const event = { id: newId('evt'), domainId: row.id, accountId: account.id, type, data, createdAt: now };
466
+ await this.store.addEvent(event);
467
+ if (!account.webhookUrl)
468
+ return;
469
+ await this.store.addDelivery({
470
+ id: newId('whd'),
471
+ accountId: account.id,
472
+ eventId: event.id,
473
+ url: account.webhookUrl,
474
+ payload: JSON.stringify({
475
+ id: event.id,
476
+ object: 'event',
477
+ type,
478
+ created_at: iso(now),
479
+ data: { ...data, domain: toPublicDomain(row) },
480
+ }),
481
+ status: 'pending',
482
+ attempts: 0,
483
+ nextAttemptAt: now,
484
+ lockedUntil: null,
485
+ lastError: null,
486
+ responseStatus: null,
487
+ createdAt: now,
488
+ });
489
+ }
490
+ /** Fills in the provider's default inbound hostname, and rejects inbound where the provider can't receive. */
491
+ resolveInbound(email, domain, inbound) {
492
+ if (!inbound)
493
+ return null;
494
+ if (!email.supportsInbound)
495
+ throw new ConfigError(`Receiving email isn't supported with ${email.label} yet.`);
496
+ return { ...inbound, hostname: inbound.hostname ?? email.defaultInboundHostname(domain) };
497
+ }
498
+ /** The account's provider credentials; legacy rows hold a bare (encrypted) SendGrid key. */
499
+ credentialsOf(account) {
500
+ if (!account.emailCredentialsEnc)
501
+ return {};
502
+ const plain = this.vault.decrypt(account.emailCredentialsEnc);
503
+ try {
504
+ const parsed = JSON.parse(plain);
505
+ if (parsed && typeof parsed === 'object')
506
+ return parsed;
507
+ }
508
+ catch {
509
+ // Not JSON: a legacy SendGrid key.
510
+ }
511
+ return { apiKey: plain };
512
+ }
513
+ emailFor(account, subuser) {
514
+ if (!account.emailCredentialsEnc) {
515
+ throw new ConfigError('Add your email provider credentials first: PATCH /v1/account with email_provider (or Settings in the dashboard).');
516
+ }
517
+ if (subuser && account.emailProvider !== 'sendgrid')
518
+ throw new ConfigError('sendgrid_subuser only applies to SendGrid accounts.');
519
+ return this.providers.email(account.emailProvider, this.credentialsOf(account), subuser);
520
+ }
521
+ dnsFor(row) {
522
+ const credentials = row.dnsCredentialsEnc ? this.vault.decryptJson(row.dnsCredentialsEnc) : {};
523
+ return this.providers.dns(row.dnsProvider, credentials);
524
+ }
525
+ }
526
+ export function assertDnsCredentials(provider, c) {
527
+ switch (provider) {
528
+ case 'manual':
529
+ return;
530
+ case 'cloudflare':
531
+ if (!c.cloudflareApiToken)
532
+ throw new ConfigError('dns.cloudflare_api_token is required for Cloudflare.');
533
+ return;
534
+ case 'route53':
535
+ if (!c.awsAccessKeyId || !c.awsSecretAccessKey) {
536
+ throw new ConfigError('dns.aws_access_key_id and dns.aws_secret_access_key are required for Route 53.');
537
+ }
538
+ return;
539
+ default:
540
+ throw new ConfigError('dns.provider must be one of: manual, cloudflare, route53.');
541
+ }
542
+ }
543
+ /** Keeps only the credentials the provider uses, so nothing extra is stored. */
544
+ function pickCredentials(provider, c) {
545
+ if (provider === 'cloudflare')
546
+ return { cloudflareApiToken: c.cloudflareApiToken };
547
+ if (provider === 'route53') {
548
+ const { awsAccessKeyId, awsSecretAccessKey, awsSessionToken, route53HostedZoneId } = c;
549
+ return Object.fromEntries(Object.entries({ awsAccessKeyId, awsSecretAccessKey, awsSessionToken, route53HostedZoneId }).filter(([, v]) => v));
550
+ }
551
+ return {};
552
+ }
553
+ /** Makes `ensureDomain` return the provider domain this row was created with, by id. */
554
+ function pinDomain(email, id) {
555
+ return {
556
+ name: email.name,
557
+ label: email.label,
558
+ supportsInbound: email.supportsInbound,
559
+ defaultInboundHostname: (domain) => email.defaultInboundHostname(domain),
560
+ findDomain: (domain, subdomain) => email.findDomain(domain, subdomain),
561
+ ensureDomain: () => email.getDomain(id),
562
+ getDomain: (i) => email.getDomain(i),
563
+ deleteDomain: (i) => email.deleteDomain(i),
564
+ validateDomain: (i) => email.validateDomain(i),
565
+ inboundRecords: (hostname) => email.inboundRecords(hostname),
566
+ ensureInboundParse: (o) => email.ensureInboundParse(o),
567
+ deleteInboundParse: (hostname) => email.deleteInboundParse(hostname),
568
+ };
569
+ }
570
+ async function ignoreNotFound(p) {
571
+ try {
572
+ await p;
573
+ }
574
+ catch (err) {
575
+ if (!(err instanceof ApiError && err.status === 404))
576
+ throw err;
577
+ }
578
+ }
579
+ function emptyTotals() {
580
+ return { domainsCreated: 0, verifications: 0, activeDomains: 0, activeDomainDays: 0 };
581
+ }
582
+ //# sourceMappingURL=service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../../src/hosted/service.ts"],"names":[],"mappings":"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"}