@blamejs/core 0.9.49 → 0.10.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 +951 -908
- package/index.js +25 -0
- package/lib/_test/crypto-fixtures.js +67 -0
- package/lib/agent-event-bus.js +52 -6
- package/lib/agent-idempotency.js +169 -16
- package/lib/agent-orchestrator.js +263 -9
- package/lib/agent-posture-chain.js +163 -5
- package/lib/agent-saga.js +146 -16
- package/lib/agent-snapshot.js +349 -19
- package/lib/agent-stream.js +34 -2
- package/lib/agent-tenant.js +179 -23
- package/lib/agent-trace.js +84 -21
- package/lib/auth/aal.js +8 -1
- package/lib/auth/ciba.js +6 -1
- package/lib/auth/dpop.js +7 -2
- package/lib/auth/fal.js +17 -8
- package/lib/auth/jwt-external.js +128 -4
- package/lib/auth/oauth.js +232 -10
- package/lib/auth/oid4vci.js +67 -7
- package/lib/auth/openid-federation.js +71 -25
- package/lib/auth/passkey.js +140 -6
- package/lib/auth/sd-jwt-vc.js +67 -5
- package/lib/circuit-breaker.js +10 -2
- package/lib/compliance.js +176 -8
- package/lib/crypto-field.js +114 -14
- package/lib/crypto.js +216 -20
- package/lib/db.js +1 -0
- package/lib/guard-jmap.js +321 -0
- package/lib/guard-managesieve-command.js +566 -0
- package/lib/guard-pop3-command.js +317 -0
- package/lib/guard-smtp-command.js +58 -3
- package/lib/mail-agent.js +20 -7
- package/lib/mail-arc-sign.js +12 -8
- package/lib/mail-auth.js +323 -34
- package/lib/mail-crypto-pgp.js +934 -0
- package/lib/mail-crypto-smime.js +340 -0
- package/lib/mail-crypto.js +108 -0
- package/lib/mail-dav.js +1224 -0
- package/lib/mail-deploy.js +492 -0
- package/lib/mail-dkim.js +431 -26
- package/lib/mail-journal.js +435 -0
- package/lib/mail-scan.js +502 -0
- package/lib/mail-server-imap.js +64 -26
- package/lib/mail-server-jmap.js +488 -0
- package/lib/mail-server-managesieve.js +853 -0
- package/lib/mail-server-mx.js +40 -30
- package/lib/mail-server-pop3.js +836 -0
- package/lib/mail-server-rate-limit.js +13 -0
- package/lib/mail-server-submission.js +70 -24
- package/lib/mail-server-tls.js +445 -0
- package/lib/mail-sieve.js +557 -0
- package/lib/mail-spam-score.js +284 -0
- package/lib/mail.js +99 -0
- package/lib/metrics.js +80 -3
- package/lib/middleware/dpop.js +58 -3
- package/lib/middleware/idempotency-key.js +255 -42
- package/lib/middleware/protected-resource-metadata.js +114 -2
- package/lib/network-dns-resolver.js +33 -0
- package/lib/network-tls.js +46 -0
- package/lib/outbox.js +62 -12
- package/lib/pqc-agent.js +13 -5
- package/lib/retry.js +23 -9
- package/lib/router.js +23 -1
- package/lib/safe-ical.js +634 -0
- package/lib/safe-icap.js +502 -0
- package/lib/safe-mime.js +15 -0
- package/lib/safe-sieve.js +684 -0
- package/lib/safe-smtp.js +57 -0
- package/lib/safe-url.js +37 -0
- package/lib/safe-vcard.js +473 -0
- package/lib/self-update-standalone-verifier.js +32 -3
- package/lib/self-update.js +153 -33
- package/lib/vendor/MANIFEST.json +161 -156
- package/lib/vendor-data.js +127 -9
- package/lib/vex.js +324 -59
- package/package.json +1 -1
- package/sbom.cdx.json +6 -6
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @module b.guardJmap
|
|
4
|
+
* @nav Guards
|
|
5
|
+
* @title Guard JMAP Request
|
|
6
|
+
* @order 452
|
|
7
|
+
*
|
|
8
|
+
* @intro
|
|
9
|
+
* JMAP request-envelope validator (RFC 8620 JMAP Core). Validates
|
|
10
|
+
* the shape of an HTTP request body posted to `/jmap/api` and
|
|
11
|
+
* refuses requests that exceed operator caps, omit required
|
|
12
|
+
* capability declarations, or contain malformed back-references.
|
|
13
|
+
*
|
|
14
|
+
* ## Request shape (RFC 8620 §3.3)
|
|
15
|
+
*
|
|
16
|
+
* ```json
|
|
17
|
+
* {
|
|
18
|
+
* "using": ["urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail"],
|
|
19
|
+
* "methodCalls": [
|
|
20
|
+
* ["Mailbox/get", { "accountId": "A1", "ids": null }, "c0"],
|
|
21
|
+
* ["Email/query", { "filter": { "inMailbox": "#c0/list/0" } }, "c1"]
|
|
22
|
+
* ],
|
|
23
|
+
* "createdIds": null
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* `using` is the set of capability URIs the request invokes; the
|
|
28
|
+
* server's `urn:ietf:params:jmap:core` is implicit. `methodCalls`
|
|
29
|
+
* is an array of 3-tuples `[methodName, args, clientId]` where
|
|
30
|
+
* `clientId` echoes back on the response for client-side
|
|
31
|
+
* correlation.
|
|
32
|
+
*
|
|
33
|
+
* ## Back-reference resolution (RFC 8620 §3.7)
|
|
34
|
+
*
|
|
35
|
+
* Subsequent `methodCalls` reference earlier results via
|
|
36
|
+
* `{ "resultOf": <prior-clientId>, "name": <methodName>, "path": <JSONPath> }`
|
|
37
|
+
* placeholders inside the `args` object. The validator detects
|
|
38
|
+
* back-references and caps the chain depth so a pathological
|
|
39
|
+
* chain doesn't degrade into a O(2^N) blowup.
|
|
40
|
+
*
|
|
41
|
+
* ## Caps
|
|
42
|
+
*
|
|
43
|
+
* - `maxCallsInRequest` — default 32 (RFC 8620 §3.6)
|
|
44
|
+
* - `maxObjectsInGet` — default 500
|
|
45
|
+
* - `maxObjectsInSet` — default 500
|
|
46
|
+
* - `maxSizeRequest` — default 10 MiB
|
|
47
|
+
* - `maxBackRefDepth` — default 8 (we add this; spec doesn't)
|
|
48
|
+
* - `maxUsingCapabilities` — default 32 (refuses oversize `using`)
|
|
49
|
+
*
|
|
50
|
+
* Refusals emit a `urn:ietf:params:jmap:error:*` URI per
|
|
51
|
+
* RFC 8620 §3.6.1.
|
|
52
|
+
*
|
|
53
|
+
* @card
|
|
54
|
+
* JMAP request-envelope validator (RFC 8620 §3.3). Refuses oversize
|
|
55
|
+
* requests, capability-unknown / malformed back-reference / pipeline-
|
|
56
|
+
* bomb shapes per RFC 8620 §3.6.1 error vocabulary.
|
|
57
|
+
*/
|
|
58
|
+
|
|
59
|
+
var { defineClass } = require("./framework-error");
|
|
60
|
+
var safeJson = require("./safe-json");
|
|
61
|
+
var validateOpts = require("./validate-opts");
|
|
62
|
+
|
|
63
|
+
var GuardJmapError = defineClass("GuardJmapError", { alwaysPermanent: true });
|
|
64
|
+
|
|
65
|
+
var DEFAULT_PROFILE = "strict";
|
|
66
|
+
|
|
67
|
+
var PROFILES = Object.freeze({
|
|
68
|
+
strict: {
|
|
69
|
+
maxCallsInRequest: 32, // allow:raw-byte-literal — RFC 8620 §3.6 default
|
|
70
|
+
maxObjectsInGet: 500, // allow:raw-byte-literal — RFC 8620 §3.6 default
|
|
71
|
+
maxObjectsInSet: 500, // allow:raw-byte-literal — RFC 8620 §3.6 default
|
|
72
|
+
maxSizeRequest: 10485760, // allow:raw-byte-literal — 10 MiB request body cap
|
|
73
|
+
maxBackRefDepth: 8,
|
|
74
|
+
maxUsingCapabilities: 32, // allow:raw-byte-literal — `using` array length cap
|
|
75
|
+
},
|
|
76
|
+
balanced: {
|
|
77
|
+
maxCallsInRequest: 128, // allow:raw-byte-literal — balanced call cap
|
|
78
|
+
maxObjectsInGet: 1000, // allow:raw-byte-literal — balanced object cap
|
|
79
|
+
maxObjectsInSet: 1000, // allow:raw-byte-literal — balanced object cap
|
|
80
|
+
maxSizeRequest: 52428800, // allow:raw-byte-literal — 50 MiB balanced
|
|
81
|
+
maxBackRefDepth: 16, // allow:raw-byte-literal — balanced depth
|
|
82
|
+
maxUsingCapabilities: 64, // allow:raw-byte-literal — balanced using cap
|
|
83
|
+
},
|
|
84
|
+
permissive: {
|
|
85
|
+
maxCallsInRequest: 512, // allow:raw-byte-literal — permissive call cap
|
|
86
|
+
maxObjectsInGet: 5000, // allow:raw-byte-literal — permissive object cap
|
|
87
|
+
maxObjectsInSet: 5000, // allow:raw-byte-literal — permissive object cap
|
|
88
|
+
maxSizeRequest: 104857600, // allow:raw-byte-literal — 100 MiB permissive
|
|
89
|
+
maxBackRefDepth: 32, // allow:raw-byte-literal — permissive depth
|
|
90
|
+
maxUsingCapabilities: 128, // allow:raw-byte-literal — permissive using cap
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
var COMPLIANCE_POSTURES = Object.freeze({
|
|
95
|
+
hipaa: "strict",
|
|
96
|
+
"pci-dss": "strict",
|
|
97
|
+
gdpr: "strict",
|
|
98
|
+
soc2: "strict",
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// Capability URIs the server's core JMAP implementation always supports.
|
|
102
|
+
// Additional capabilities (mail / contacts / calendars / submission)
|
|
103
|
+
// the operator opts into via opts.serverCapabilities.
|
|
104
|
+
var CORE_CAPABILITIES = Object.freeze({
|
|
105
|
+
"urn:ietf:params:jmap:core": true,
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* @primitive b.guardJmap.validate
|
|
110
|
+
* @signature b.guardJmap.validate(rawBody, opts?)
|
|
111
|
+
* @since 0.9.50
|
|
112
|
+
* @status stable
|
|
113
|
+
* @related b.guardImapCommand.validate, b.safeJson.parse
|
|
114
|
+
*
|
|
115
|
+
* Validate a JMAP request envelope. Accepts either a raw JSON string
|
|
116
|
+
* (bytes) or a pre-parsed object. Returns
|
|
117
|
+
* `{ using, methodCalls, createdIds }` on success; throws
|
|
118
|
+
* `GuardJmapError` with the matching `urn:ietf:params:jmap:error:*`
|
|
119
|
+
* URI on refusal.
|
|
120
|
+
*
|
|
121
|
+
* @opts
|
|
122
|
+
* profile: "strict" | "balanced" | "permissive",
|
|
123
|
+
* posture: "hipaa" | "pci-dss" | "gdpr" | "soc2",
|
|
124
|
+
* serverCapabilities: { "urn:ietf:params:jmap:mail": true, ... },
|
|
125
|
+
* // capability URIs the server has wired; `using`
|
|
126
|
+
* // entries not in this set are refused with
|
|
127
|
+
* // urn:ietf:params:jmap:error:unknownCapability
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* var parsed = b.guardJmap.validate(rawBody, {
|
|
131
|
+
* serverCapabilities: { "urn:ietf:params:jmap:mail": true },
|
|
132
|
+
* });
|
|
133
|
+
* // → { using: [...], methodCalls: [[methodName, args, clientId], ...] }
|
|
134
|
+
*/
|
|
135
|
+
function validate(rawBody, opts) {
|
|
136
|
+
opts = opts || {};
|
|
137
|
+
var profileName = typeof opts.profile === "string" ? opts.profile : DEFAULT_PROFILE;
|
|
138
|
+
if (opts.posture && COMPLIANCE_POSTURES[opts.posture]) {
|
|
139
|
+
profileName = COMPLIANCE_POSTURES[opts.posture];
|
|
140
|
+
}
|
|
141
|
+
var caps = PROFILES[profileName];
|
|
142
|
+
if (!caps) {
|
|
143
|
+
throw new GuardJmapError("guard-jmap/bad-profile",
|
|
144
|
+
"guardJmap.validate: unknown profile '" + profileName + "'");
|
|
145
|
+
}
|
|
146
|
+
// Clone serverCapabilities before injecting the core capability so we
|
|
147
|
+
// never mutate the operator-supplied object. mail.server.jmap.create
|
|
148
|
+
// passes its shared `serverCapabilities` into every validate() call;
|
|
149
|
+
// pre-fix this rewrote the operator's `urn:ietf:params:jmap:core`
|
|
150
|
+
// entry to `true` after the first request, breaking the Session
|
|
151
|
+
// resource's RFC 8620 §2 capability-object shape.
|
|
152
|
+
var serverCaps = Object.assign({}, opts.serverCapabilities || {});
|
|
153
|
+
// Always allow the core capability — the server provides it inherently.
|
|
154
|
+
serverCaps["urn:ietf:params:jmap:core"] = true;
|
|
155
|
+
|
|
156
|
+
// Parse if rawBody is a string. Cap the byte size before parsing.
|
|
157
|
+
var body;
|
|
158
|
+
if (typeof rawBody === "string" || Buffer.isBuffer(rawBody)) {
|
|
159
|
+
var s = typeof rawBody === "string" ? rawBody : rawBody.toString("utf8");
|
|
160
|
+
// Wire-protocol size cap MUST be measured in UTF-8 bytes, not
|
|
161
|
+
// JavaScript UTF-16 code units. A 1 MiB cap interpreted as code
|
|
162
|
+
// units lets non-ASCII payloads (emoji, CJK) past the gate at
|
|
163
|
+
// 2-4× the actual byte budget — directly weakens the DoS cap.
|
|
164
|
+
var byteLen = typeof rawBody === "string" ? Buffer.byteLength(s, "utf8") : rawBody.length;
|
|
165
|
+
if (byteLen > caps.maxSizeRequest) {
|
|
166
|
+
throw new GuardJmapError("urn:ietf:params:jmap:error:requestTooLarge",
|
|
167
|
+
"guardJmap.validate: request body " + byteLen +
|
|
168
|
+
" bytes exceeds cap " + caps.maxSizeRequest);
|
|
169
|
+
}
|
|
170
|
+
try {
|
|
171
|
+
body = safeJson.parse(s);
|
|
172
|
+
} catch (e) {
|
|
173
|
+
throw new GuardJmapError("guard-jmap/bad-json",
|
|
174
|
+
"guardJmap.validate: body is not valid JSON: " + (e && e.message ? e.message : String(e)));
|
|
175
|
+
}
|
|
176
|
+
} else if (rawBody && typeof rawBody === "object") {
|
|
177
|
+
body = rawBody;
|
|
178
|
+
} else {
|
|
179
|
+
throw new GuardJmapError("guard-jmap/bad-input",
|
|
180
|
+
"guardJmap.validate: rawBody must be a JSON string, Buffer, or pre-parsed object");
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (typeof body !== "object" || body === null || Array.isArray(body)) {
|
|
184
|
+
throw new GuardJmapError("urn:ietf:params:jmap:error:invalidArguments",
|
|
185
|
+
"guardJmap.validate: request body must be a JSON object");
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (!Array.isArray(body.using)) {
|
|
189
|
+
throw new GuardJmapError("urn:ietf:params:jmap:error:invalidArguments",
|
|
190
|
+
"guardJmap.validate: `using` must be an array of capability URIs");
|
|
191
|
+
}
|
|
192
|
+
if (body.using.length > caps.maxUsingCapabilities) {
|
|
193
|
+
throw new GuardJmapError("urn:ietf:params:jmap:error:invalidArguments",
|
|
194
|
+
"guardJmap.validate: `using` length " + body.using.length +
|
|
195
|
+
" exceeds cap " + caps.maxUsingCapabilities);
|
|
196
|
+
}
|
|
197
|
+
for (var ui = 0; ui < body.using.length; ui += 1) {
|
|
198
|
+
var cap = body.using[ui];
|
|
199
|
+
if (typeof cap !== "string") {
|
|
200
|
+
throw new GuardJmapError("urn:ietf:params:jmap:error:invalidArguments",
|
|
201
|
+
"guardJmap.validate: `using[" + ui + "]` must be a string capability URI");
|
|
202
|
+
}
|
|
203
|
+
if (!CORE_CAPABILITIES[cap] && !serverCaps[cap]) {
|
|
204
|
+
throw new GuardJmapError("urn:ietf:params:jmap:error:unknownCapability",
|
|
205
|
+
"guardJmap.validate: capability '" + cap + "' not advertised by this server");
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (!Array.isArray(body.methodCalls)) {
|
|
210
|
+
throw new GuardJmapError("urn:ietf:params:jmap:error:invalidArguments",
|
|
211
|
+
"guardJmap.validate: `methodCalls` must be an array");
|
|
212
|
+
}
|
|
213
|
+
if (body.methodCalls.length === 0) {
|
|
214
|
+
throw new GuardJmapError("urn:ietf:params:jmap:error:invalidArguments",
|
|
215
|
+
"guardJmap.validate: `methodCalls` must contain at least one call");
|
|
216
|
+
}
|
|
217
|
+
if (body.methodCalls.length > caps.maxCallsInRequest) {
|
|
218
|
+
throw new GuardJmapError("urn:ietf:params:jmap:error:limit/maxCallsInRequest",
|
|
219
|
+
"guardJmap.validate: " + body.methodCalls.length +
|
|
220
|
+
" methodCalls exceeds cap " + caps.maxCallsInRequest);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
var seenClientIds = Object.create(null);
|
|
224
|
+
for (var ci = 0; ci < body.methodCalls.length; ci += 1) {
|
|
225
|
+
var call = body.methodCalls[ci];
|
|
226
|
+
if (!Array.isArray(call) || call.length !== 3) {
|
|
227
|
+
throw new GuardJmapError("urn:ietf:params:jmap:error:invalidArguments",
|
|
228
|
+
"guardJmap.validate: methodCalls[" + ci + "] must be a 3-tuple [name, args, clientId]");
|
|
229
|
+
}
|
|
230
|
+
if (typeof call[0] !== "string") {
|
|
231
|
+
throw new GuardJmapError("urn:ietf:params:jmap:error:invalidArguments",
|
|
232
|
+
"guardJmap.validate: methodCalls[" + ci + "][0] (method name) must be a string");
|
|
233
|
+
}
|
|
234
|
+
if (typeof call[1] !== "object" || call[1] === null || Array.isArray(call[1])) {
|
|
235
|
+
throw new GuardJmapError("urn:ietf:params:jmap:error:invalidArguments",
|
|
236
|
+
"guardJmap.validate: methodCalls[" + ci + "][1] (args) must be an object");
|
|
237
|
+
}
|
|
238
|
+
if (typeof call[2] !== "string") {
|
|
239
|
+
throw new GuardJmapError("urn:ietf:params:jmap:error:invalidArguments",
|
|
240
|
+
"guardJmap.validate: methodCalls[" + ci + "][2] (clientId) must be a string");
|
|
241
|
+
}
|
|
242
|
+
if (call[2].length === 0 || call[2].length > 256) { // allow:raw-byte-literal — clientId length cap
|
|
243
|
+
throw new GuardJmapError("urn:ietf:params:jmap:error:invalidArguments",
|
|
244
|
+
"guardJmap.validate: methodCalls[" + ci + "][2] (clientId) length must be 1..256");
|
|
245
|
+
}
|
|
246
|
+
// Back-reference depth cap: count `resultOf` occurrences in the
|
|
247
|
+
// args subtree. Pathological depth would let a client chain
|
|
248
|
+
// hundreds of resolutions per call.
|
|
249
|
+
var refCount = _countBackRefs(call[1], 0, caps.maxBackRefDepth);
|
|
250
|
+
if (refCount === -1) {
|
|
251
|
+
throw new GuardJmapError("urn:ietf:params:jmap:error:limit/maxBackRefDepth",
|
|
252
|
+
"guardJmap.validate: methodCalls[" + ci + "] back-reference depth exceeds cap " +
|
|
253
|
+
caps.maxBackRefDepth);
|
|
254
|
+
}
|
|
255
|
+
seenClientIds[call[2]] = true;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
validateOpts.optionalPlainObject(body.createdIds,
|
|
259
|
+
"guardJmap.validate: `createdIds`",
|
|
260
|
+
GuardJmapError, "urn:ietf:params:jmap:error:invalidArguments",
|
|
261
|
+
"null or an object");
|
|
262
|
+
|
|
263
|
+
return {
|
|
264
|
+
using: body.using,
|
|
265
|
+
methodCalls: body.methodCalls,
|
|
266
|
+
createdIds: body.createdIds || null,
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Walk args looking for back-reference markers
|
|
271
|
+
// (`#name`-prefixed keys per RFC 8620 §3.7 or a `resultOf` shape).
|
|
272
|
+
// Returns the maximum depth seen, or -1 if it exceeds maxDepth.
|
|
273
|
+
function _countBackRefs(node, depth, maxDepth) {
|
|
274
|
+
if (depth > maxDepth) return -1;
|
|
275
|
+
if (node === null || typeof node !== "object") return depth;
|
|
276
|
+
if (Array.isArray(node)) {
|
|
277
|
+
var maxA = depth;
|
|
278
|
+
for (var i = 0; i < node.length; i += 1) {
|
|
279
|
+
var d = _countBackRefs(node[i], depth + 1, maxDepth);
|
|
280
|
+
if (d === -1) return -1;
|
|
281
|
+
if (d > maxA) maxA = d;
|
|
282
|
+
}
|
|
283
|
+
return maxA;
|
|
284
|
+
}
|
|
285
|
+
var keys = Object.keys(node);
|
|
286
|
+
if (keys.length > 1000) return -1; // allow:raw-byte-literal — per-object key cap
|
|
287
|
+
var maxO = depth;
|
|
288
|
+
for (var k = 0; k < keys.length; k += 1) {
|
|
289
|
+
var key = keys[k];
|
|
290
|
+
var inc = (key === "resultOf" || key.charCodeAt(0) === 0x23) ? 1 : 0; // allow:raw-byte-literal — `#` (0x23) is the JMAP back-ref prefix
|
|
291
|
+
var d2 = _countBackRefs(node[key], depth + inc, maxDepth);
|
|
292
|
+
if (d2 === -1) return -1;
|
|
293
|
+
if (d2 > maxO) maxO = d2;
|
|
294
|
+
}
|
|
295
|
+
return maxO;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* @primitive b.guardJmap.compliancePosture
|
|
300
|
+
* @signature b.guardJmap.compliancePosture(posture)
|
|
301
|
+
* @since 0.9.50
|
|
302
|
+
* @status stable
|
|
303
|
+
*
|
|
304
|
+
* Return the effective profile for a compliance posture, or `null`
|
|
305
|
+
* for unknown names.
|
|
306
|
+
*
|
|
307
|
+
* @example
|
|
308
|
+
* b.guardJmap.compliancePosture("hipaa"); // → "strict"
|
|
309
|
+
*/
|
|
310
|
+
function compliancePosture(posture) {
|
|
311
|
+
return COMPLIANCE_POSTURES[posture] || null;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
module.exports = {
|
|
315
|
+
validate: validate,
|
|
316
|
+
compliancePosture: compliancePosture,
|
|
317
|
+
PROFILES: PROFILES,
|
|
318
|
+
COMPLIANCE_POSTURES: COMPLIANCE_POSTURES,
|
|
319
|
+
CORE_CAPABILITIES: CORE_CAPABILITIES,
|
|
320
|
+
GuardJmapError: GuardJmapError,
|
|
321
|
+
};
|