mailery 0.19.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +65 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +65 -30
- package/dist/index.js.map +1 -1
- package/dist/{null-DxTHQSrJ.d.cts → null-B3N6bTpc.d.cts} +33 -5
- package/dist/{null-DxTHQSrJ.d.ts → null-B3N6bTpc.d.ts} +33 -5
- package/dist/testing.cjs +63 -28
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +3 -3
- package/dist/testing.d.ts +3 -3
- package/dist/testing.js +63 -28
- package/dist/testing.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2500,7 +2500,7 @@ function derivePlaintext(html) {
|
|
|
2500
2500
|
var PLAIN_TEXT = { noEscape: true };
|
|
2501
2501
|
async function renderTemplate(template, ctx, opts = {}) {
|
|
2502
2502
|
const hb = makeHandlebars(opts.helpers);
|
|
2503
|
-
const subject = hb.compile(template.subject)(ctx);
|
|
2503
|
+
const subject = hb.compile(template.subject, PLAIN_TEXT)(ctx).replace(/[\r\n]+/g, " ");
|
|
2504
2504
|
const preheader = hb.compile(template.preheader)(ctx);
|
|
2505
2505
|
let html;
|
|
2506
2506
|
if (template.body.html) {
|
|
@@ -3912,7 +3912,7 @@ async function runDnsblChecks(ctx, opts = {}) {
|
|
|
3912
3912
|
let listedCount = 0;
|
|
3913
3913
|
async function processPair(p) {
|
|
3914
3914
|
const queryName = buildQueryName(p.target, p.targetKind, spamhausQueryHost(p.list.host, cfg.spamhausDqsKey));
|
|
3915
|
-
const lookup2 = queryName ? await queryDnsbl(resolver, queryName) : { result: "error", returnCodes: [], errorMessage: "unsupported target format" };
|
|
3915
|
+
const lookup2 = queryName ? await queryDnsbl(resolver, queryName, p.list.host) : { result: "error", returnCodes: [], errorMessage: "unsupported target format" };
|
|
3916
3916
|
if (lookup2.transient) return;
|
|
3917
3917
|
if (lookup2.result === "listed") listedCount++;
|
|
3918
3918
|
await ctx.collections.dnsblChecks.updateOne(
|
|
@@ -3973,10 +3973,10 @@ function buildQueryName(target, kind, listHost) {
|
|
|
3973
3973
|
return `${domain}.${listHost}`;
|
|
3974
3974
|
}
|
|
3975
3975
|
var TRANSIENT_DNS_CODES = /* @__PURE__ */ new Set(["ESERVFAIL", "EREFUSED", "ETIMEOUT", "ETIMEDOUT", "ECONNRESET", "ECONNREFUSED"]);
|
|
3976
|
-
async function queryDnsbl(resolver, query) {
|
|
3976
|
+
async function queryDnsbl(resolver, query, listHost) {
|
|
3977
3977
|
try {
|
|
3978
3978
|
const records = await resolver.resolve4(query);
|
|
3979
|
-
return interpretRecords(records);
|
|
3979
|
+
return interpretRecords(records, listHost);
|
|
3980
3980
|
} catch (err) {
|
|
3981
3981
|
const code = err?.code;
|
|
3982
3982
|
if (code === "ENOTFOUND" || code === "ENODATA") {
|
|
@@ -4002,10 +4002,17 @@ var REFUSAL_REASONS = {
|
|
|
4002
4002
|
"127.255.255.254": "queried through a public or shared DNS resolver, which Spamhaus blocks. Set dnsbl.spamhausDqsKey (free Spamhaus DQS key) or use a private resolver",
|
|
4003
4003
|
"127.255.255.255": "this resolver has exceeded the free query limit"
|
|
4004
4004
|
};
|
|
4005
|
-
function interpretRecords(records) {
|
|
4005
|
+
function interpretRecords(records, listHost) {
|
|
4006
4006
|
if (!records || records.length === 0) {
|
|
4007
4007
|
return { result: "clean", returnCodes: [], errorMessage: null };
|
|
4008
4008
|
}
|
|
4009
|
+
if (listHost && REGISTRABLE_ONLY_LISTS.has(listHost) && records.every((r) => r === "127.0.0.1")) {
|
|
4010
|
+
return {
|
|
4011
|
+
result: "error",
|
|
4012
|
+
returnCodes: records,
|
|
4013
|
+
errorMessage: `${listHost} refused the query (127.0.0.1): queried through a public or shared DNS resolver, or over the free query limit. Use a private resolver`
|
|
4014
|
+
};
|
|
4015
|
+
}
|
|
4009
4016
|
const errorish = records.filter((r) => r.startsWith("127.255.255."));
|
|
4010
4017
|
if (errorish.length === records.length) {
|
|
4011
4018
|
const reasons = [...new Set(records.map((r) => REFUSAL_REASONS[r] ?? "unrecognised refusal code"))];
|
|
@@ -5141,6 +5148,7 @@ async function processScheduledBroadcasts2(ctx) {
|
|
|
5141
5148
|
}
|
|
5142
5149
|
|
|
5143
5150
|
// src/server/mailer.ts
|
|
5151
|
+
var STORAGE_REQUIRED = "Mailer.init: give exactly one of `db` (an open Db) or `mongo` (a connection mailery opens)";
|
|
5144
5152
|
var Mailer = class _Mailer {
|
|
5145
5153
|
db;
|
|
5146
5154
|
collections;
|
|
@@ -5150,6 +5158,8 @@ var Mailer = class _Mailer {
|
|
|
5150
5158
|
config;
|
|
5151
5159
|
events;
|
|
5152
5160
|
queueDriver;
|
|
5161
|
+
/** The client `Mailer.init` opened from `config.mongo`; closed by `stop()`. Null when the host gave `db`. */
|
|
5162
|
+
ownedClient;
|
|
5153
5163
|
workersStarted = false;
|
|
5154
5164
|
runnerContext;
|
|
5155
5165
|
constructor(args) {
|
|
@@ -5159,6 +5169,7 @@ var Mailer = class _Mailer {
|
|
|
5159
5169
|
this.adapter = args.adapter;
|
|
5160
5170
|
this.providers = args.providers;
|
|
5161
5171
|
this.queueDriver = args.queueDriver;
|
|
5172
|
+
this.ownedClient = args.ownedClient;
|
|
5162
5173
|
this.queues = args.queueDriver.queues;
|
|
5163
5174
|
this.events = args.events;
|
|
5164
5175
|
this.runnerContext = {
|
|
@@ -5255,36 +5266,58 @@ var Mailer = class _Mailer {
|
|
|
5255
5266
|
});
|
|
5256
5267
|
}
|
|
5257
5268
|
static async init(input) {
|
|
5258
|
-
|
|
5259
|
-
if (!resolveProvider(
|
|
5269
|
+
if (input.db == null === (input.mongo == null)) throw new Error(STORAGE_REQUIRED);
|
|
5270
|
+
if (!resolveProvider(input.providers, input.defaultProvider)) {
|
|
5260
5271
|
throw new Error(
|
|
5261
|
-
`defaultProvider "${
|
|
5272
|
+
`defaultProvider "${input.defaultProvider}" is not a registered provider. Registered: ${registeredProviderNames(input.providers).join(", ") || "(none)"}`
|
|
5262
5273
|
);
|
|
5263
5274
|
}
|
|
5264
|
-
if (
|
|
5275
|
+
if (input.defaultTransactionalProvider != null && !resolveProvider(input.providers, input.defaultTransactionalProvider)) {
|
|
5265
5276
|
throw new Error(
|
|
5266
|
-
`defaultTransactionalProvider "${
|
|
5277
|
+
`defaultTransactionalProvider "${input.defaultTransactionalProvider}" is not a registered provider. Registered: ${registeredProviderNames(input.providers).join(", ") || "(none)"}`
|
|
5267
5278
|
);
|
|
5268
5279
|
}
|
|
5269
|
-
if (
|
|
5280
|
+
if (input.varsAdapter) {
|
|
5270
5281
|
const { assertNoReservedVarKeys: assertNoReservedVarKeys2 } = await Promise.resolve().then(() => (init_vars(), vars_exports));
|
|
5271
|
-
assertNoReservedVarKeys2(
|
|
5272
|
-
}
|
|
5273
|
-
|
|
5274
|
-
|
|
5275
|
-
|
|
5276
|
-
|
|
5277
|
-
await
|
|
5278
|
-
|
|
5279
|
-
|
|
5280
|
-
|
|
5281
|
-
|
|
5282
|
-
|
|
5283
|
-
|
|
5284
|
-
|
|
5285
|
-
|
|
5286
|
-
|
|
5287
|
-
|
|
5282
|
+
assertNoReservedVarKeys2(input.varsAdapter);
|
|
5283
|
+
}
|
|
5284
|
+
let ownedClient = null;
|
|
5285
|
+
let db;
|
|
5286
|
+
if (input.mongo) {
|
|
5287
|
+
const { MongoClient } = await import('mongodb');
|
|
5288
|
+
ownedClient = await MongoClient.connect(input.mongo.uri, input.mongo.clientOptions);
|
|
5289
|
+
db = ownedClient.db(input.mongo.dbName);
|
|
5290
|
+
} else if (input.db) {
|
|
5291
|
+
db = input.db;
|
|
5292
|
+
} else {
|
|
5293
|
+
throw new Error(STORAGE_REQUIRED);
|
|
5294
|
+
}
|
|
5295
|
+
try {
|
|
5296
|
+
const config = resolveConfig({
|
|
5297
|
+
...input,
|
|
5298
|
+
db,
|
|
5299
|
+
adapter: typeof input.adapter === "function" ? input.adapter(db) : input.adapter
|
|
5300
|
+
});
|
|
5301
|
+
const collections = getCollections(config.db, config.collectionPrefix);
|
|
5302
|
+
await ensureIndexes(config.db, config.collectionPrefix);
|
|
5303
|
+
const queueDriver = await createQueueDriver(config.queue, config.db);
|
|
5304
|
+
if (!config.workerless && config.queue.driver !== "noop") {
|
|
5305
|
+
await queueDriver.scheduleRepeatingTick(config.tickIntervalSeconds);
|
|
5306
|
+
}
|
|
5307
|
+
return new _Mailer({
|
|
5308
|
+
config,
|
|
5309
|
+
db: config.db,
|
|
5310
|
+
collections,
|
|
5311
|
+
adapter: config.adapter,
|
|
5312
|
+
providers: config.providers,
|
|
5313
|
+
queueDriver,
|
|
5314
|
+
events: new EventRegistry(),
|
|
5315
|
+
ownedClient
|
|
5316
|
+
});
|
|
5317
|
+
} catch (err) {
|
|
5318
|
+
await ownedClient?.close();
|
|
5319
|
+
throw err;
|
|
5320
|
+
}
|
|
5288
5321
|
}
|
|
5289
5322
|
// -------------------------------------------------------------------------
|
|
5290
5323
|
// Event registration + firing
|
|
@@ -5757,6 +5790,8 @@ var Mailer = class _Mailer {
|
|
|
5757
5790
|
async stop() {
|
|
5758
5791
|
await this.queueDriver.close();
|
|
5759
5792
|
this.workersStarted = false;
|
|
5793
|
+
await this.ownedClient?.close();
|
|
5794
|
+
this.ownedClient = null;
|
|
5760
5795
|
}
|
|
5761
5796
|
/** Used internally by the admin router and tests; not part of the public API. */
|
|
5762
5797
|
getRunnerContext() {
|
|
@@ -9572,7 +9607,7 @@ function unitToMs2(value, unit) {
|
|
|
9572
9607
|
}
|
|
9573
9608
|
|
|
9574
9609
|
// src/server/api/agent.ts
|
|
9575
|
-
var VERSION = "0.
|
|
9610
|
+
var VERSION = "0.20.0" ;
|
|
9576
9611
|
var broadcastCountSchema = zod.z.object({
|
|
9577
9612
|
recipientCap: zod.z.number().int().positive().max(1e7).nullable().optional()
|
|
9578
9613
|
});
|
|
@@ -11639,7 +11674,7 @@ var DEDUPE_POLICIES = [
|
|
|
11639
11674
|
];
|
|
11640
11675
|
|
|
11641
11676
|
// src/server/index.ts
|
|
11642
|
-
var VERSION2 = "0.
|
|
11677
|
+
var VERSION2 = "0.20.0" ;
|
|
11643
11678
|
|
|
11644
11679
|
exports.DEDUPE_POLICIES = DEDUPE_POLICIES;
|
|
11645
11680
|
exports.DEFAULT_BOT_UA_RE = DEFAULT_BOT_UA_RE;
|