@blamejs/core 0.14.27 → 0.15.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/CHANGELOG.md +6 -0
- package/README.md +2 -2
- package/index.js +4 -0
- package/lib/ai-content-detect.js +9 -10
- package/lib/api-key.js +158 -77
- package/lib/atomic-file.js +29 -1
- package/lib/audit-chain.js +47 -11
- package/lib/audit-sign.js +77 -2
- package/lib/audit-tools.js +79 -51
- package/lib/audit.js +228 -100
- package/lib/backup/index.js +13 -10
- package/lib/break-glass.js +202 -144
- package/lib/cache.js +174 -105
- package/lib/chain-writer.js +38 -16
- package/lib/cli.js +19 -14
- package/lib/cluster-provider-db.js +130 -104
- package/lib/cluster-storage.js +119 -22
- package/lib/cluster.js +119 -71
- package/lib/compliance.js +22 -0
- package/lib/consent.js +82 -29
- package/lib/constants.js +16 -11
- package/lib/crypto-field.js +387 -91
- package/lib/db-declare-row-policy.js +35 -22
- package/lib/db-file-lifecycle.js +3 -2
- package/lib/db-query.js +517 -256
- package/lib/db-schema.js +209 -44
- package/lib/db.js +202 -95
- package/lib/external-db-migrate.js +229 -139
- package/lib/external-db.js +25 -15
- package/lib/framework-error.js +11 -0
- package/lib/framework-files.js +73 -0
- package/lib/framework-schema.js +695 -394
- package/lib/gate-contract.js +596 -1
- package/lib/guard-agent-registry.js +26 -44
- package/lib/guard-all.js +1 -0
- package/lib/guard-auth.js +42 -112
- package/lib/guard-cidr.js +33 -154
- package/lib/guard-csv.js +46 -113
- package/lib/guard-domain.js +34 -157
- package/lib/guard-dsn.js +27 -43
- package/lib/guard-email.js +47 -69
- package/lib/guard-envelope.js +19 -32
- package/lib/guard-event-bus-payload.js +24 -42
- package/lib/guard-event-bus-topic.js +25 -43
- package/lib/guard-filename.js +42 -106
- package/lib/guard-graphql.js +42 -123
- package/lib/guard-html.js +53 -108
- package/lib/guard-idempotency-key.js +24 -42
- package/lib/guard-image.js +46 -103
- package/lib/guard-imap-command.js +18 -32
- package/lib/guard-jmap.js +16 -30
- package/lib/guard-json.js +38 -108
- package/lib/guard-jsonpath.js +38 -171
- package/lib/guard-jwt.js +49 -179
- package/lib/guard-list-id.js +25 -41
- package/lib/guard-list-unsubscribe.js +27 -43
- package/lib/guard-mail-compose.js +24 -42
- package/lib/guard-mail-move.js +26 -44
- package/lib/guard-mail-query.js +28 -46
- package/lib/guard-mail-reply.js +24 -42
- package/lib/guard-mail-sieve.js +24 -42
- package/lib/guard-managesieve-command.js +17 -31
- package/lib/guard-markdown.js +37 -104
- package/lib/guard-message-id.js +26 -45
- package/lib/guard-mime.js +39 -151
- package/lib/guard-oauth.js +54 -135
- package/lib/guard-pdf.js +45 -101
- package/lib/guard-pop3-command.js +21 -31
- package/lib/guard-posture-chain.js +24 -42
- package/lib/guard-regex.js +33 -107
- package/lib/guard-saga-config.js +24 -42
- package/lib/guard-shell.js +42 -172
- package/lib/guard-smtp-command.js +48 -54
- package/lib/guard-snapshot-envelope.js +24 -42
- package/lib/guard-sql.js +1491 -0
- package/lib/guard-stream-args.js +24 -43
- package/lib/guard-svg.js +47 -65
- package/lib/guard-template.js +35 -172
- package/lib/guard-tenant-id.js +26 -45
- package/lib/guard-time.js +32 -154
- package/lib/guard-trace-context.js +25 -44
- package/lib/guard-uuid.js +32 -153
- package/lib/guard-xml.js +38 -113
- package/lib/guard-yaml.js +51 -163
- package/lib/http-client.js +14 -0
- package/lib/inbox.js +120 -107
- package/lib/legal-hold.js +107 -50
- package/lib/log-stream-cloudwatch.js +47 -31
- package/lib/log-stream-otlp.js +32 -18
- package/lib/mail-crypto-smime.js +2 -6
- package/lib/mail-greylist.js +2 -6
- package/lib/mail-helo.js +2 -6
- package/lib/mail-journal.js +85 -64
- package/lib/mail-rbl.js +2 -6
- package/lib/mail-scan.js +2 -6
- package/lib/mail-spam-score.js +2 -6
- package/lib/mail-store.js +293 -154
- package/lib/middleware/fetch-metadata.js +17 -7
- package/lib/middleware/idempotency-key.js +54 -38
- package/lib/middleware/rate-limit.js +102 -32
- package/lib/middleware/security-headers.js +21 -5
- package/lib/migrations.js +108 -66
- package/lib/network-heartbeat.js +7 -0
- package/lib/nonce-store.js +31 -9
- package/lib/object-store/azure-blob-bucket-ops.js +9 -4
- package/lib/object-store/azure-blob.js +31 -3
- package/lib/object-store/sigv4.js +10 -0
- package/lib/outbox.js +136 -82
- package/lib/pqc-agent.js +44 -0
- package/lib/pubsub-cluster.js +42 -20
- package/lib/queue-local.js +202 -139
- package/lib/queue-redis.js +9 -1
- package/lib/queue-sqs.js +6 -0
- package/lib/retention.js +82 -39
- package/lib/safe-dns.js +29 -45
- package/lib/safe-ical.js +18 -33
- package/lib/safe-icap.js +27 -43
- package/lib/safe-sieve.js +21 -40
- package/lib/safe-sql.js +124 -3
- package/lib/safe-vcard.js +18 -33
- package/lib/scheduler.js +35 -12
- package/lib/seeders.js +122 -74
- package/lib/session-stores.js +42 -14
- package/lib/session.js +116 -72
- package/lib/sql.js +3885 -0
- package/lib/static.js +45 -7
- package/lib/subject.js +89 -49
- package/lib/vault/index.js +3 -2
- package/lib/vault/passphrase-ops.js +3 -2
- package/lib/vault/rotate.js +104 -64
- package/lib/vendor-data.js +2 -0
- package/lib/websocket.js +16 -0
- package/package.json +1 -1
- package/sbom.cdx.json +6 -6
package/lib/retention.js
CHANGED
|
@@ -46,6 +46,7 @@ var C = require("./constants");
|
|
|
46
46
|
var lazyRequire = require("./lazy-require");
|
|
47
47
|
var validateOpts = require("./validate-opts");
|
|
48
48
|
var safeSql = require("./safe-sql");
|
|
49
|
+
var sql = require("./sql");
|
|
49
50
|
var { defineClass } = require("./framework-error");
|
|
50
51
|
|
|
51
52
|
var audit = lazyRequire(function () { return require("./audit"); });
|
|
@@ -55,6 +56,25 @@ var legalHold = lazyRequire(function () { return require("./legal-hold"); });
|
|
|
55
56
|
var RetentionError = defineClass("RetentionError", { alwaysPermanent: true });
|
|
56
57
|
var _err = RetentionError.factory;
|
|
57
58
|
|
|
59
|
+
// Resolve the b.sql dialect for the operator-supplied handle. The framework's
|
|
60
|
+
// local b.db handle is always node:sqlite (db.js pins { dialect: "sqlite",
|
|
61
|
+
// quoteName: true }) and exposes no .dialect, so this defaults to "sqlite" —
|
|
62
|
+
// every sweep statement runs against that handle via .prepare(). An operator
|
|
63
|
+
// handle that DOES advertise a dialect (string or () -> string) has it
|
|
64
|
+
// threaded through so the emitted identifier quoting + idioms match the
|
|
65
|
+
// backend the handle dispatches to. quoteName stays on for every retention
|
|
66
|
+
// statement: the rule's table / ageField / softDeleteField identifiers are
|
|
67
|
+
// validated then quoted by construction (no clusterStorage prefix rewrite on
|
|
68
|
+
// this operator-app-schema path).
|
|
69
|
+
function _handleDialect(db) {
|
|
70
|
+
if (db && typeof db.dialect === "function") {
|
|
71
|
+
try { var d = db.dialect(); return typeof d === "string" ? d : "sqlite"; }
|
|
72
|
+
catch (_e) { return "sqlite"; }
|
|
73
|
+
}
|
|
74
|
+
if (db && typeof db.dialect === "string") return db.dialect;
|
|
75
|
+
return "sqlite";
|
|
76
|
+
}
|
|
77
|
+
|
|
58
78
|
// Identifier-level SQLi defense: every operator-supplied table name,
|
|
59
79
|
// column name, and cascade FK must pass safeSql.validateIdentifier
|
|
60
80
|
// before reaching SQL string concatenation. Without this gate a
|
|
@@ -196,6 +216,11 @@ function create(opts) {
|
|
|
196
216
|
throw _err("BAD_OPT", "create: opts.db is required (a b.db handle with .prepare(sql))");
|
|
197
217
|
}
|
|
198
218
|
var db = opts.db;
|
|
219
|
+
// b.sql opts for every retention statement built against this handle. The
|
|
220
|
+
// dialect tracks the handle (sqlite for the framework's local b.db); the
|
|
221
|
+
// validated operator identifiers are quoted by construction (quoteName)
|
|
222
|
+
// with no clusterStorage prefix rewrite on this path.
|
|
223
|
+
var SQL_OPTS = { dialect: _handleDialect(db), quoteName: true };
|
|
199
224
|
var auditOn = opts.audit !== false && opts.audit != null;
|
|
200
225
|
var auditInstance = (opts.audit && opts.audit !== true) ? opts.audit : null;
|
|
201
226
|
var rules = {};
|
|
@@ -235,16 +260,24 @@ function create(opts) {
|
|
|
235
260
|
|
|
236
261
|
function _hardDelete(table, rowId, dryRun) {
|
|
237
262
|
if (dryRun) return { wouldDelete: 1 };
|
|
238
|
-
|
|
239
|
-
|
|
263
|
+
// Operator app table — quoteName so the validated identifier emits as a
|
|
264
|
+
// quoted local name; the row id binds as a placeholder.
|
|
265
|
+
var built = sql.delete(table, SQL_OPTS)
|
|
266
|
+
.where("_id", rowId)
|
|
267
|
+
.toSql();
|
|
268
|
+
var del = db.prepare(built.sql);
|
|
269
|
+
del.run.apply(del, built.params);
|
|
240
270
|
return { deleted: 1 };
|
|
241
271
|
}
|
|
242
272
|
|
|
243
273
|
function _softDelete(table, rowId, softField, dryRun) {
|
|
244
274
|
if (dryRun) return { wouldSoftDelete: 1 };
|
|
245
|
-
var
|
|
246
|
-
|
|
247
|
-
|
|
275
|
+
var built = sql.update(table, SQL_OPTS)
|
|
276
|
+
.set(softField, Date.now())
|
|
277
|
+
.where("_id", rowId)
|
|
278
|
+
.toSql();
|
|
279
|
+
var upd = db.prepare(built.sql);
|
|
280
|
+
upd.run.apply(upd, built.params);
|
|
248
281
|
return { softDeleted: 1 };
|
|
249
282
|
}
|
|
250
283
|
|
|
@@ -261,19 +294,17 @@ function create(opts) {
|
|
|
261
294
|
return _hardDelete(table, row._id, dryRun);
|
|
262
295
|
}
|
|
263
296
|
if (dryRun) return { wouldErase: 1, sealedFieldCount: sealedFields.length };
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
var upd2 = db.prepare("UPDATE \"" + table + "\" SET " + setClauses.join(", ") + " WHERE _id = ?");
|
|
276
|
-
upd2.run.apply(upd2, values);
|
|
297
|
+
// NULL every sealed column + its derived-hash sibling. b.sql binds each
|
|
298
|
+
// null as a placeholder (the set map preserves the column ordering).
|
|
299
|
+
var eraseSet = {};
|
|
300
|
+
for (var si = 0; si < sealedFields.length; si++) eraseSet[sealedFields[si]] = null;
|
|
301
|
+
for (var hi = 0; hi < hashFields.length; hi++) eraseSet[hashFields[hi]] = null;
|
|
302
|
+
var eraseBuilt = sql.update(table, SQL_OPTS)
|
|
303
|
+
.set(eraseSet)
|
|
304
|
+
.where("_id", row._id)
|
|
305
|
+
.toSql();
|
|
306
|
+
var upd2 = db.prepare(eraseBuilt.sql);
|
|
307
|
+
upd2.run.apply(upd2, eraseBuilt.params);
|
|
277
308
|
// Per-row-key tables (declarePerRowKey): NULLing the sealed columns
|
|
278
309
|
// is not enough — WAL / replica residuals keep the old K_row cells.
|
|
279
310
|
// Destroy the row's wrapped secret so K_row is unrecoverable and the
|
|
@@ -294,15 +325,20 @@ function create(opts) {
|
|
|
294
325
|
for (var i = 0; i < rule.cascade.length; i++) {
|
|
295
326
|
var c = rule.cascade[i];
|
|
296
327
|
if (dryRun) {
|
|
297
|
-
var
|
|
298
|
-
"
|
|
299
|
-
|
|
328
|
+
var selBuilt = sql.select(c.table, SQL_OPTS)
|
|
329
|
+
.count("*", "n")
|
|
330
|
+
.where(c.foreignKey, rowId)
|
|
331
|
+
.toSql();
|
|
332
|
+
var sel = db.prepare(selBuilt.sql);
|
|
333
|
+
var n = sel.get.apply(sel, selBuilt.params);
|
|
300
334
|
cascadeSummary.push({ table: c.table, foreignKey: c.foreignKey,
|
|
301
335
|
wouldDelete: (n && typeof n.n === "number") ? n.n : 0 });
|
|
302
336
|
} else {
|
|
303
|
-
var
|
|
304
|
-
|
|
305
|
-
|
|
337
|
+
var delBuilt = sql.delete(c.table, SQL_OPTS)
|
|
338
|
+
.where(c.foreignKey, rowId)
|
|
339
|
+
.toSql();
|
|
340
|
+
var del = db.prepare(delBuilt.sql);
|
|
341
|
+
var result = del.run.apply(del, delBuilt.params);
|
|
306
342
|
cascadeSummary.push({ table: c.table, foreignKey: c.foreignKey,
|
|
307
343
|
deleted: result.changes || 0 });
|
|
308
344
|
}
|
|
@@ -392,24 +428,31 @@ function create(opts) {
|
|
|
392
428
|
while (moreRows) {
|
|
393
429
|
var rows;
|
|
394
430
|
// The candidate WHERE-clause: age + not-already-erased + not-on-legal-hold +
|
|
395
|
-
// (when soft-delete is configured) not-already-soft-deleted.
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
431
|
+
// (when soft-delete is configured) not-already-soft-deleted. Built
|
|
432
|
+
// through b.sql so the operator-supplied table / ageField / softDeleteField
|
|
433
|
+
// identifiers are quoted by construction and every value binds as a
|
|
434
|
+
// placeholder (the '' empty-string compare included — no embedded literal).
|
|
435
|
+
function _candidateBase() {
|
|
436
|
+
var qb = sql.select(rule.table, SQL_OPTS)
|
|
437
|
+
.where(rule.ageField, "<=", cutoff);
|
|
438
|
+
if (rule.softDeleteField) qb.whereNull(rule.softDeleteField);
|
|
439
|
+
return qb;
|
|
400
440
|
}
|
|
401
|
-
var sql = "SELECT * FROM \"" + rule.table + "\" " +
|
|
402
|
-
"WHERE " + whereParts.join(" AND ") + " " +
|
|
403
|
-
"AND (__erasedAt IS NULL OR __erasedAt = '') " +
|
|
404
|
-
"LIMIT ?";
|
|
405
441
|
var selStmt;
|
|
406
|
-
try {
|
|
407
|
-
|
|
442
|
+
try {
|
|
443
|
+
var built = _candidateBase()
|
|
444
|
+
.whereGroup(function (g) {
|
|
445
|
+
g.whereNull("__erasedAt").orWhereOp("__erasedAt", "=", "");
|
|
446
|
+
})
|
|
447
|
+
.limit(rule.batchSize)
|
|
448
|
+
.toSql();
|
|
449
|
+
selStmt = db.prepare(built.sql);
|
|
450
|
+
rows = selStmt.all.apply(selStmt, built.params);
|
|
451
|
+
} catch (_eA) {
|
|
408
452
|
// Fallback: tables without __erasedAt
|
|
409
|
-
var
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
rows = selPlain.all.apply(selPlain, whereArgs.concat([rule.batchSize]));
|
|
453
|
+
var plainBuilt = _candidateBase().limit(rule.batchSize).toSql();
|
|
454
|
+
var selPlain = db.prepare(plainBuilt.sql);
|
|
455
|
+
rows = selPlain.all.apply(selPlain, plainBuilt.params);
|
|
413
456
|
}
|
|
414
457
|
if (!rows || rows.length === 0) { moreRows = false; break; }
|
|
415
458
|
summary.scanned += rows.length;
|
package/lib/safe-dns.js
CHANGED
|
@@ -57,6 +57,7 @@
|
|
|
57
57
|
|
|
58
58
|
var C = require("./constants");
|
|
59
59
|
var { defineClass } = require("./framework-error");
|
|
60
|
+
var gateContract = require("./gate-contract");
|
|
60
61
|
|
|
61
62
|
var SafeDnsError = defineClass("SafeDnsError", { alwaysPermanent: true });
|
|
62
63
|
|
|
@@ -153,11 +154,15 @@ var PROFILES = Object.freeze({
|
|
|
153
154
|
},
|
|
154
155
|
});
|
|
155
156
|
|
|
156
|
-
var COMPLIANCE_POSTURES =
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
157
|
+
var COMPLIANCE_POSTURES = gateContract.ALL_STRICT_POSTURES;
|
|
158
|
+
|
|
159
|
+
var _resolveProfile = gateContract.makeProfileResolver({
|
|
160
|
+
profiles: PROFILES,
|
|
161
|
+
postures: COMPLIANCE_POSTURES,
|
|
162
|
+
defaults: DEFAULT_PROFILE,
|
|
163
|
+
errorClass: SafeDnsError,
|
|
164
|
+
codePrefix: "safe-dns",
|
|
165
|
+
byObject: true,
|
|
161
166
|
});
|
|
162
167
|
|
|
163
168
|
/**
|
|
@@ -349,22 +354,6 @@ function checkCnameChainDepth(depth, opts) {
|
|
|
349
354
|
}
|
|
350
355
|
}
|
|
351
356
|
|
|
352
|
-
/**
|
|
353
|
-
* @primitive b.safeDns.compliancePosture
|
|
354
|
-
* @signature b.safeDns.compliancePosture(posture)
|
|
355
|
-
* @since 0.9.31
|
|
356
|
-
* @status stable
|
|
357
|
-
*
|
|
358
|
-
* Return the effective profile name for a compliance posture, or
|
|
359
|
-
* `null` for unknown posture names (operator typo surfaces here).
|
|
360
|
-
*
|
|
361
|
-
* @example
|
|
362
|
-
* b.safeDns.compliancePosture("hipaa"); // → "strict"
|
|
363
|
-
*/
|
|
364
|
-
function compliancePosture(posture) {
|
|
365
|
-
return COMPLIANCE_POSTURES[posture] || null;
|
|
366
|
-
}
|
|
367
|
-
|
|
368
357
|
function _readName(state, pointerDepth) {
|
|
369
358
|
if (pointerDepth > state.caps.maxPointerDepth) {
|
|
370
359
|
throw new SafeDnsError("safe-dns/oversize-pointer-depth",
|
|
@@ -639,27 +628,22 @@ function _decodeOpt(rr, caps) {
|
|
|
639
628
|
};
|
|
640
629
|
}
|
|
641
630
|
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
RTYPE_NAMES: RTYPE_NAMES,
|
|
662
|
-
SafeDnsError: SafeDnsError,
|
|
663
|
-
NAME: "dns",
|
|
664
|
-
KIND: "dns-response",
|
|
665
|
-
};
|
|
631
|
+
// compliancePosture is assembled by gateContract.defineParser below; its
|
|
632
|
+
// wiki section renders from the single-sourced @abiTemplate (defineParser)
|
|
633
|
+
// block in gate-contract.js, instantiated for this guard by the page
|
|
634
|
+
// generator.
|
|
635
|
+
module.exports = gateContract.defineParser({
|
|
636
|
+
name: "dns",
|
|
637
|
+
entry: parseResponse,
|
|
638
|
+
entryName: "parseResponse",
|
|
639
|
+
errorClass: SafeDnsError,
|
|
640
|
+
profiles: PROFILES,
|
|
641
|
+
postures: COMPLIANCE_POSTURES,
|
|
642
|
+
extra: {
|
|
643
|
+
boundEdns0: boundEdns0,
|
|
644
|
+
checkCnameChainDepth: checkCnameChainDepth,
|
|
645
|
+
RTYPE_NAMES: RTYPE_NAMES,
|
|
646
|
+
NAME: "dns",
|
|
647
|
+
KIND: "dns-response",
|
|
648
|
+
},
|
|
649
|
+
});
|
package/lib/safe-ical.js
CHANGED
|
@@ -81,6 +81,7 @@
|
|
|
81
81
|
|
|
82
82
|
var C = require("./constants");
|
|
83
83
|
var { defineClass } = require("./framework-error");
|
|
84
|
+
var gateContract = require("./gate-contract");
|
|
84
85
|
|
|
85
86
|
var SafeIcalError = defineClass("SafeIcalError", { alwaysPermanent: true });
|
|
86
87
|
|
|
@@ -116,12 +117,7 @@ var PROFILES = Object.freeze({
|
|
|
116
117
|
}),
|
|
117
118
|
});
|
|
118
119
|
|
|
119
|
-
var COMPLIANCE_POSTURES =
|
|
120
|
-
hipaa: "strict",
|
|
121
|
-
"pci-dss": "strict",
|
|
122
|
-
gdpr: "strict",
|
|
123
|
-
soc2: "strict",
|
|
124
|
-
});
|
|
120
|
+
var COMPLIANCE_POSTURES = gateContract.ALL_STRICT_POSTURES;
|
|
125
121
|
|
|
126
122
|
// Property-name allowlist per RFC 5545 §8.7 (Property Registry) +
|
|
127
123
|
// RFC 5546 §4.3 (iTIP additions) + RFC 7986 §5 (new calendar
|
|
@@ -273,24 +269,6 @@ function parse(text, opts) {
|
|
|
273
269
|
: { vcalendar: vcalendars[0], vcalendars: vcalendars };
|
|
274
270
|
}
|
|
275
271
|
|
|
276
|
-
/**
|
|
277
|
-
* @primitive b.safeIcal.compliancePosture
|
|
278
|
-
* @signature b.safeIcal.compliancePosture(name)
|
|
279
|
-
* @since 0.9.81
|
|
280
|
-
* @status stable
|
|
281
|
-
* @related b.safeIcal.parse
|
|
282
|
-
*
|
|
283
|
-
* Map a compliance-posture name to its profile. Returns the profile
|
|
284
|
-
* string for a known posture, `null` for unknown names.
|
|
285
|
-
*
|
|
286
|
-
* @example
|
|
287
|
-
* b.safeIcal.compliancePosture("hipaa"); // → "strict"
|
|
288
|
-
* b.safeIcal.compliancePosture("loose"); // → null
|
|
289
|
-
*/
|
|
290
|
-
function compliancePosture(name) {
|
|
291
|
-
return COMPLIANCE_POSTURES[name] || null;
|
|
292
|
-
}
|
|
293
|
-
|
|
294
272
|
// ---- Profile / opt resolution ----
|
|
295
273
|
|
|
296
274
|
function _resolveCaps(opts) {
|
|
@@ -623,12 +601,19 @@ function _preview(s) {
|
|
|
623
601
|
return s.length > 64 ? s.slice(0, 64) + "..." : s; // log-preview length cap
|
|
624
602
|
}
|
|
625
603
|
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
604
|
+
// compliancePosture is assembled by gateContract.defineParser below; its
|
|
605
|
+
// wiki section renders from the single-sourced @abiTemplate (defineParser)
|
|
606
|
+
// block in gate-contract.js, instantiated for this guard by the page
|
|
607
|
+
// generator.
|
|
608
|
+
module.exports = gateContract.defineParser({
|
|
609
|
+
name: "ical",
|
|
610
|
+
entry: parse,
|
|
611
|
+
entryName: "parse",
|
|
612
|
+
errorClass: SafeIcalError,
|
|
613
|
+
profiles: PROFILES,
|
|
614
|
+
postures: COMPLIANCE_POSTURES,
|
|
615
|
+
extra: {
|
|
616
|
+
KNOWN_PROPERTIES: KNOWN_PROPERTIES,
|
|
617
|
+
KNOWN_COMPONENTS: KNOWN_COMPONENTS,
|
|
618
|
+
},
|
|
619
|
+
});
|
package/lib/safe-icap.js
CHANGED
|
@@ -77,6 +77,7 @@
|
|
|
77
77
|
|
|
78
78
|
var C = require("./constants");
|
|
79
79
|
var { defineClass } = require("./framework-error");
|
|
80
|
+
var gateContract = require("./gate-contract");
|
|
80
81
|
|
|
81
82
|
var SafeIcapError = defineClass("SafeIcapError", { alwaysPermanent: true });
|
|
82
83
|
|
|
@@ -131,11 +132,15 @@ var PROFILES = Object.freeze({
|
|
|
131
132
|
},
|
|
132
133
|
});
|
|
133
134
|
|
|
134
|
-
var COMPLIANCE_POSTURES =
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
135
|
+
var COMPLIANCE_POSTURES = gateContract.ALL_STRICT_POSTURES;
|
|
136
|
+
|
|
137
|
+
var _resolveProfile = gateContract.makeProfileResolver({
|
|
138
|
+
profiles: PROFILES,
|
|
139
|
+
postures: COMPLIANCE_POSTURES,
|
|
140
|
+
defaults: DEFAULT_PROFILE,
|
|
141
|
+
errorClass: SafeIcapError,
|
|
142
|
+
codePrefix: "safe-icap",
|
|
143
|
+
byObject: true,
|
|
139
144
|
});
|
|
140
145
|
|
|
141
146
|
/**
|
|
@@ -257,22 +262,6 @@ function parse(buf, opts) {
|
|
|
257
262
|
};
|
|
258
263
|
}
|
|
259
264
|
|
|
260
|
-
/**
|
|
261
|
-
* @primitive b.safeIcap.compliancePosture
|
|
262
|
-
* @signature b.safeIcap.compliancePosture(posture)
|
|
263
|
-
* @since 0.9.81
|
|
264
|
-
* @status stable
|
|
265
|
-
*
|
|
266
|
-
* Return the effective profile name for a compliance posture, or
|
|
267
|
-
* `null` for unknown posture names.
|
|
268
|
-
*
|
|
269
|
-
* @example
|
|
270
|
-
* b.safeIcap.compliancePosture("hipaa"); // → "strict"
|
|
271
|
-
*/
|
|
272
|
-
function compliancePosture(posture) {
|
|
273
|
-
return COMPLIANCE_POSTURES[posture] || null;
|
|
274
|
-
}
|
|
275
|
-
|
|
276
265
|
// ---- internals ----
|
|
277
266
|
|
|
278
267
|
function _findHeaderEnd(buf, maxHeaderBytes) {
|
|
@@ -479,25 +468,20 @@ function _detectThreat(statusCode, headers) {
|
|
|
479
468
|
return { found: found, name: name };
|
|
480
469
|
}
|
|
481
470
|
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
ALLOWED_STATUS: ALLOWED_STATUS,
|
|
500
|
-
SafeIcapError: SafeIcapError,
|
|
501
|
-
NAME: "icap",
|
|
502
|
-
KIND: "icap-response",
|
|
503
|
-
};
|
|
471
|
+
// compliancePosture is assembled by gateContract.defineParser below; its
|
|
472
|
+
// wiki section renders from the single-sourced @abiTemplate (defineParser)
|
|
473
|
+
// block in gate-contract.js, instantiated for this guard by the page
|
|
474
|
+
// generator.
|
|
475
|
+
module.exports = gateContract.defineParser({
|
|
476
|
+
name: "icap",
|
|
477
|
+
entry: parse,
|
|
478
|
+
entryName: "parse",
|
|
479
|
+
errorClass: SafeIcapError,
|
|
480
|
+
profiles: PROFILES,
|
|
481
|
+
postures: COMPLIANCE_POSTURES,
|
|
482
|
+
extra: {
|
|
483
|
+
ALLOWED_STATUS: ALLOWED_STATUS,
|
|
484
|
+
NAME: "icap",
|
|
485
|
+
KIND: "icap-response",
|
|
486
|
+
},
|
|
487
|
+
});
|
package/lib/safe-sieve.js
CHANGED
|
@@ -49,6 +49,7 @@
|
|
|
49
49
|
*/
|
|
50
50
|
|
|
51
51
|
var { defineClass } = require("./framework-error");
|
|
52
|
+
var gateContract = require("./gate-contract");
|
|
52
53
|
|
|
53
54
|
var SafeSieveError = defineClass("SafeSieveError", { alwaysPermanent: true });
|
|
54
55
|
|
|
@@ -82,12 +83,7 @@ var PROFILES = Object.freeze({
|
|
|
82
83
|
}),
|
|
83
84
|
});
|
|
84
85
|
|
|
85
|
-
var COMPLIANCE_POSTURES =
|
|
86
|
-
hipaa: "strict",
|
|
87
|
-
"pci-dss": "strict",
|
|
88
|
-
gdpr: "strict",
|
|
89
|
-
soc2: "strict",
|
|
90
|
-
});
|
|
86
|
+
var COMPLIANCE_POSTURES = gateContract.ALL_STRICT_POSTURES;
|
|
91
87
|
|
|
92
88
|
// RFC 5228 §1.2 capability identifiers. Each entry lists whether the
|
|
93
89
|
// framework's v0.9.55 interpreter implements the capability. Unknown
|
|
@@ -648,37 +644,22 @@ function validate(script, opts) {
|
|
|
648
644
|
}
|
|
649
645
|
}
|
|
650
646
|
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
return COMPLIANCE_POSTURES[name] || null;
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
module.exports = {
|
|
674
|
-
parse: parse,
|
|
675
|
-
validate: validate,
|
|
676
|
-
compliancePosture: compliancePosture,
|
|
677
|
-
KNOWN_CAPABILITIES: KNOWN_CAPABILITIES,
|
|
678
|
-
PROFILES: PROFILES,
|
|
679
|
-
COMPLIANCE_POSTURES: COMPLIANCE_POSTURES,
|
|
680
|
-
SafeSieveError: SafeSieveError,
|
|
681
|
-
// Internal exports for the interpreter at lib/mail-sieve.js.
|
|
682
|
-
_tokenize: _tokenize,
|
|
683
|
-
_resolveCaps: _resolveCaps,
|
|
684
|
-
};
|
|
647
|
+
// compliancePosture is assembled by gateContract.defineParser below; its
|
|
648
|
+
// wiki section renders from the single-sourced @abiTemplate (defineParser)
|
|
649
|
+
// block in gate-contract.js, instantiated for this guard by the page
|
|
650
|
+
// generator.
|
|
651
|
+
module.exports = gateContract.defineParser({
|
|
652
|
+
name: "sieve",
|
|
653
|
+
entry: parse,
|
|
654
|
+
entryName: "parse",
|
|
655
|
+
errorClass: SafeSieveError,
|
|
656
|
+
profiles: PROFILES,
|
|
657
|
+
postures: COMPLIANCE_POSTURES,
|
|
658
|
+
extra: {
|
|
659
|
+
validate: validate,
|
|
660
|
+
KNOWN_CAPABILITIES: KNOWN_CAPABILITIES,
|
|
661
|
+
// Internal exports for the interpreter at lib/mail-sieve.js.
|
|
662
|
+
_tokenize: _tokenize,
|
|
663
|
+
_resolveCaps: _resolveCaps,
|
|
664
|
+
},
|
|
665
|
+
});
|