@primitivedotdev/sdk 1.3.0 → 1.4.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.
@@ -16,8 +16,14 @@ const schema12 = {
16
16
  },
17
17
  "event": {
18
18
  "type": "string",
19
- "const": "email.received",
20
- "description": "Event type identifier. Always `\"email.received\"` for this event type."
19
+ "enum": [
20
+ "email.received",
21
+ "email.bounced",
22
+ "email.tls_report",
23
+ "email.dmarc_report",
24
+ "email.dmarc_failure"
25
+ ],
26
+ "description": "Event type identifier.\n\n- `email.received` - A normal inbound email.\n- `email.bounced` - A delivery status notification (DSN) reporting that a message delivery failed. Carries `email.analysis.bounce`.\n- `email.tls_report` - An SMTP TLS report (RFC 8460). Carries `email.analysis.tls_report`.\n- `email.dmarc_report` - A DMARC aggregate report (RFC 7489). Carries `email.analysis.dmarc_report`.\n- `email.dmarc_failure` - A DMARC failure (forensic) report.\n\nMachine-generated mail (bounces and the report types above) is delivered under its own event type rather than `email.received`, so an endpoint subscribed only to `email.received` receives just normal inbound mail. The payload shape is otherwise identical across event types; the type-specific details live under `email.analysis`."
21
27
  },
22
28
  "version": {
23
29
  "$ref": "#/definitions/WebhookVersion",
@@ -2722,6 +2728,106 @@ function validate14(data, { instancePath = "", parentData, parentDataProperty, r
2722
2728
  validate14.errors = vErrors;
2723
2729
  return errors === 0;
2724
2730
  }
2731
+ const schema39 = {
2732
+ "type": "object",
2733
+ "properties": {
2734
+ "is_bounce": {
2735
+ "type": "boolean",
2736
+ "const": true,
2737
+ "description": "Always `true` on a parsed bounce."
2738
+ },
2739
+ "kind": {
2740
+ "type": "string",
2741
+ "const": "dsn",
2742
+ "description": "The machine-mail kind. Always `dsn` for a bounce."
2743
+ },
2744
+ "type": {
2745
+ "type": "string",
2746
+ "enum": [
2747
+ "permanent",
2748
+ "transient",
2749
+ "undetermined"
2750
+ ],
2751
+ "description": "Whether the failure is permanent (hard bounce), transient (soft bounce, may be retried), or undetermined."
2752
+ },
2753
+ "category": {
2754
+ "type": "string",
2755
+ "enum": [
2756
+ "mailbox_does_not_exist",
2757
+ "domain_does_not_exist",
2758
+ "domain_not_accepting_mail",
2759
+ "mailbox_full",
2760
+ "mailbox_inactive",
2761
+ "message_too_large",
2762
+ "content_rejected",
2763
+ "policy_blocked",
2764
+ "auth_failure",
2765
+ "relay_denied",
2766
+ "rate_limited",
2767
+ "network_error",
2768
+ "recipient_moved",
2769
+ "expired",
2770
+ "undetermined"
2771
+ ],
2772
+ "description": "Best-effort reason category for the failure."
2773
+ },
2774
+ "classified_by": {
2775
+ "type": "string",
2776
+ "enum": [
2777
+ "status_code",
2778
+ "smtp_code",
2779
+ "pattern",
2780
+ "provider",
2781
+ "none"
2782
+ ],
2783
+ "description": "Which signal produced `category` (for transparency and debugging)."
2784
+ },
2785
+ "failed_recipient": {
2786
+ "type": ["string", "null"],
2787
+ "description": "The recipient address that failed, if the report identifies one."
2788
+ },
2789
+ "smtp_code": {
2790
+ "type": ["integer", "null"],
2791
+ "description": "SMTP reply code (e.g. `550`), if reported."
2792
+ },
2793
+ "status_code": {
2794
+ "type": ["string", "null"],
2795
+ "description": "Enhanced mail system status code (RFC 3463, e.g. `5.1.1`), if reported."
2796
+ },
2797
+ "diagnostic_code": {
2798
+ "type": ["string", "null"],
2799
+ "description": "Raw diagnostic text from the reporting MTA, if present."
2800
+ },
2801
+ "reported_by_mta": {
2802
+ "type": ["string", "null"],
2803
+ "description": "The MTA that generated the report, if identifiable."
2804
+ },
2805
+ "original_message_id": {
2806
+ "type": ["string", "null"],
2807
+ "description": "Message-ID of the original message that bounced, if recoverable. Match this against the `message_id` of a message you sent to correlate the bounce."
2808
+ },
2809
+ "reasons": {
2810
+ "type": "array",
2811
+ "items": { "type": "string" },
2812
+ "description": "Human-readable reason strings extracted from the report."
2813
+ }
2814
+ },
2815
+ "required": [
2816
+ "is_bounce",
2817
+ "kind",
2818
+ "type",
2819
+ "category",
2820
+ "classified_by",
2821
+ "failed_recipient",
2822
+ "smtp_code",
2823
+ "status_code",
2824
+ "diagnostic_code",
2825
+ "reported_by_mta",
2826
+ "original_message_id",
2827
+ "reasons"
2828
+ ],
2829
+ "description": "Parsed delivery status notification (bounce). Present as `email.analysis.bounce` on `email.bounced` events."
2830
+ };
2725
2831
  const schema28 = {
2726
2832
  "type": "object",
2727
2833
  "properties": {
@@ -4127,275 +4233,2178 @@ function validate21(data, { instancePath = "", parentData, parentDataProperty, r
4127
4233
  validate21.errors = vErrors;
4128
4234
  return errors === 0;
4129
4235
  }
4130
- function validate20(data, { instancePath = "", parentData, parentDataProperty, rootData = data } = {}) {
4131
- let vErrors = null;
4132
- let errors = 0;
4133
- if (data && typeof data == "object" && !Array.isArray(data)) {
4134
- if (data.spamassassin !== void 0) {
4135
- let data0 = data.spamassassin;
4136
- if (data0 && typeof data0 == "object" && !Array.isArray(data0)) {
4137
- if (data0.score === void 0) {
4138
- const err0 = {
4139
- instancePath: instancePath + "/spamassassin",
4140
- schemaPath: "#/properties/spamassassin/required",
4141
- keyword: "required",
4142
- params: { missingProperty: "score" },
4143
- message: "must have required property 'score'"
4144
- };
4145
- if (vErrors === null) vErrors = [err0];
4146
- else vErrors.push(err0);
4147
- errors++;
4148
- }
4149
- if (data0.score !== void 0) {
4150
- if (!(typeof data0.score == "number")) {
4151
- const err1 = {
4152
- instancePath: instancePath + "/spamassassin/score",
4153
- schemaPath: "#/properties/spamassassin/properties/score/type",
4154
- keyword: "type",
4155
- params: { type: "number" },
4156
- message: "must be number"
4157
- };
4158
- if (vErrors === null) vErrors = [err1];
4159
- else vErrors.push(err1);
4160
- errors++;
4161
- }
4162
- }
4163
- } else {
4164
- const err2 = {
4165
- instancePath: instancePath + "/spamassassin",
4166
- schemaPath: "#/properties/spamassassin/type",
4167
- keyword: "type",
4168
- params: { type: "object" },
4169
- message: "must be object"
4170
- };
4171
- if (vErrors === null) vErrors = [err2];
4172
- else vErrors.push(err2);
4173
- errors++;
4174
- }
4175
- }
4176
- if (data.forward !== void 0) {
4177
- if (!validate21(data.forward, {
4178
- instancePath: instancePath + "/forward",
4179
- parentData: data,
4180
- parentDataProperty: "forward",
4181
- rootData
4182
- })) {
4183
- vErrors = vErrors === null ? validate21.errors : vErrors.concat(validate21.errors);
4184
- errors = vErrors.length;
4185
- }
4186
- }
4187
- } else {
4188
- const err3 = {
4189
- instancePath,
4190
- schemaPath: "#/type",
4191
- keyword: "type",
4192
- params: { type: "object" },
4193
- message: "must be object"
4194
- };
4195
- if (vErrors === null) vErrors = [err3];
4196
- else vErrors.push(err3);
4197
- errors++;
4198
- }
4199
- validate20.errors = vErrors;
4200
- return errors === 0;
4201
- }
4202
- const schema39 = {
4236
+ const schema40 = {
4203
4237
  "type": "object",
4204
4238
  "properties": {
4205
- "spf": {
4206
- "$ref": "#/definitions/SpfResult",
4207
- "description": "SPF verification result.\n\nSPF checks if the sending IP is authorized by the envelope sender's domain. \"pass\" means the IP is authorized; \"fail\" means it's explicitly not allowed."
4208
- },
4209
- "dmarc": {
4210
- "$ref": "#/definitions/DmarcResult",
4211
- "description": "DMARC verification result.\n\nDMARC passes if either SPF or DKIM passes AND aligns with the From: domain. \"pass\" means the email is authenticated according to the sender's policy."
4212
- },
4213
- "dmarcPolicy": {
4214
- "$ref": "#/definitions/DmarcPolicy",
4215
- "description": "DMARC policy from the sender's DNS record.\n\n- `reject`: Domain wants receivers to reject failing emails\n- `quarantine`: Domain wants failing emails marked as suspicious\n- `none`: Domain is monitoring only (no action requested)\n- `null`: No DMARC record found for this domain"
4239
+ "kind": {
4240
+ "type": "string",
4241
+ "const": "tls_report"
4216
4242
  },
4217
- "dmarcFromDomain": {
4243
+ "organization": {
4218
4244
  "type": ["string", "null"],
4219
- "description": "The organizational domain used for DMARC lookups.\n\nFor example, if the From: address is `user@mail.example.com`, the DMARC lookup checks `_dmarc.mail.example.com`, then falls back to `_dmarc.example.com`. This field shows which domain's policy was used."
4220
- },
4221
- "dmarcSpfAligned": {
4222
- "type": "boolean",
4223
- "description": "Whether SPF aligned with the From: domain for DMARC purposes.\n\nTrue if the envelope sender domain matches the From: domain (per alignment mode)."
4224
- },
4225
- "dmarcDkimAligned": {
4226
- "type": "boolean",
4227
- "description": "Whether DKIM aligned with the From: domain for DMARC purposes.\n\nTrue if at least one DKIM signature's domain matches the From: domain."
4245
+ "description": "Reporting organization name."
4228
4246
  },
4229
- "dmarcSpfStrict": {
4230
- "type": ["boolean", "null"],
4231
- "description": "Whether DMARC SPF alignment mode is strict.\n\n- `true`: Strict alignment required (exact domain match)\n- `false`: Relaxed alignment allowed (organizational domain match)\n- `null`: No DMARC record found"
4247
+ "report_id": { "type": ["string", "null"] },
4248
+ "contact": {
4249
+ "type": ["string", "null"],
4250
+ "description": "Reporter contact, if provided."
4232
4251
  },
4233
- "dmarcDkimStrict": {
4234
- "type": ["boolean", "null"],
4235
- "description": "Whether DMARC DKIM alignment mode is strict.\n\n- `true`: Strict alignment required (exact domain match)\n- `false`: Relaxed alignment allowed (organizational domain match)\n- `null`: No DMARC record found"
4252
+ "date_range": {
4253
+ "type": "object",
4254
+ "properties": {
4255
+ "start": {
4256
+ "type": ["string", "null"],
4257
+ "description": "ISO 8601 start of the reporting window."
4258
+ },
4259
+ "end": {
4260
+ "type": ["string", "null"],
4261
+ "description": "ISO 8601 end of the reporting window."
4262
+ }
4263
+ },
4264
+ "required": ["start", "end"]
4236
4265
  },
4237
- "dkimSignatures": {
4266
+ "total_successful_sessions": { "type": "integer" },
4267
+ "total_failed_sessions": { "type": "integer" },
4268
+ "policies": {
4238
4269
  "type": "array",
4239
- "items": { "$ref": "#/definitions/DkimSignature" },
4240
- "description": "All DKIM signatures found in the email with their verification results.\n\nMay be empty if no DKIM signatures were present."
4270
+ "items": { "$ref": "#/definitions/TlsReportPolicy" }
4241
4271
  }
4242
4272
  },
4243
4273
  "required": [
4244
- "spf",
4245
- "dmarc",
4246
- "dmarcPolicy",
4247
- "dmarcFromDomain",
4248
- "dmarcSpfAligned",
4249
- "dmarcDkimAligned",
4250
- "dmarcSpfStrict",
4251
- "dmarcDkimStrict",
4252
- "dkimSignatures"
4253
- ],
4254
- "description": "Email authentication results for SPF, DKIM, and DMARC.\n\nUse `validateEmailAuth()` to compute a verdict based on these results."
4255
- };
4256
- const schema40 = {
4257
- "type": "string",
4258
- "enum": [
4259
- "pass",
4260
- "fail",
4261
- "softfail",
4262
- "neutral",
4263
- "none",
4264
- "temperror",
4265
- "permerror"
4274
+ "kind",
4275
+ "organization",
4276
+ "report_id",
4277
+ "contact",
4278
+ "date_range",
4279
+ "total_successful_sessions",
4280
+ "total_failed_sessions",
4281
+ "policies"
4266
4282
  ],
4267
- "description": "SPF verification result."
4283
+ "description": "Parsed SMTP TLS report (RFC 8460). Present as `email.analysis.tls_report` on `email.tls_report` events."
4268
4284
  };
4269
4285
  const schema41 = {
4270
- "type": "string",
4271
- "enum": [
4272
- "pass",
4273
- "fail",
4274
- "none",
4275
- "temperror",
4276
- "permerror"
4277
- ],
4278
- "description": "DMARC verification result."
4279
- };
4280
- const schema43 = {
4281
4286
  "type": "object",
4282
4287
  "properties": {
4283
- "domain": {
4284
- "type": "string",
4285
- "description": "The domain that signed this DKIM signature (d= tag). This may differ from the From: domain (that's what alignment checks)."
4286
- },
4287
- "selector": {
4288
+ "policy_domain": { "type": ["string", "null"] },
4289
+ "policy_type": {
4288
4290
  "type": ["string", "null"],
4289
- "description": "The DKIM selector used to locate the public key (s= tag). Combined with the domain to form the DNS lookup: `selector._domainkey.domain`\n\nOptional in self-hosted environments where the milter may not provide selector info."
4291
+ "description": "Policy type the sessions were evaluated against (e.g. `sts`, `tlsa`, `no-policy-found`)."
4290
4292
  },
4291
- "result": {
4292
- "$ref": "#/definitions/DkimResult",
4293
- "description": "Verification result for this specific signature."
4294
- },
4295
- "aligned": {
4296
- "type": "boolean",
4297
- "description": "Whether this signature's domain aligns with the From: domain (for DMARC).\n\nAlignment can be \"strict\" (exact match) or \"relaxed\" (organizational domain match). For example, if From: is `user@sub.example.com` and DKIM is signed by `example.com`:\n- Relaxed alignment: true (same organizational domain)\n- Strict alignment: false (not exact match)"
4298
- },
4299
- "keyBits": {
4300
- "type": ["integer", "null"],
4301
- "minimum": 1,
4302
- "maximum": 16384,
4303
- "description": "Key size in bits (e.g., 1024, 2048). Null if the key size couldn't be determined.\n\nOptional in self-hosted environments."
4304
- },
4305
- "algo": {
4306
- "type": ["string", "null"],
4307
- "description": "Signing algorithm (e.g., \"rsa-sha256\", \"ed25519-sha256\").\n\nOptional in self-hosted environments."
4293
+ "successful_sessions": { "type": "integer" },
4294
+ "failed_sessions": { "type": "integer" },
4295
+ "failures": {
4296
+ "type": "array",
4297
+ "items": { "$ref": "#/definitions/TlsReportFailure" }
4308
4298
  }
4309
4299
  },
4310
4300
  "required": [
4311
- "domain",
4312
- "selector",
4313
- "result",
4314
- "aligned",
4315
- "keyBits",
4316
- "algo"
4317
- ],
4318
- "description": "Details about a single DKIM signature found in the email.\n\nAn email may have multiple DKIM signatures (e.g., one from the sending domain and one from the ESP). Each signature is verified independently."
4301
+ "policy_domain",
4302
+ "policy_type",
4303
+ "successful_sessions",
4304
+ "failed_sessions",
4305
+ "failures"
4306
+ ]
4319
4307
  };
4320
- const schema44 = {
4321
- "type": "string",
4322
- "enum": [
4323
- "pass",
4324
- "fail",
4325
- "temperror",
4326
- "permerror"
4327
- ],
4328
- "description": "DKIM signature verification result for a single signature."
4308
+ const schema42 = {
4309
+ "type": "object",
4310
+ "properties": {
4311
+ "result_type": {
4312
+ "type": ["string", "null"],
4313
+ "description": "Failure result type (e.g. `certificate-expired`, `starttls-not-supported`)."
4314
+ },
4315
+ "count": {
4316
+ "type": "integer",
4317
+ "description": "Number of sessions that hit this failure."
4318
+ },
4319
+ "sending_mta_ip": { "type": ["string", "null"] },
4320
+ "receiving_mx_hostname": { "type": ["string", "null"] }
4321
+ },
4322
+ "required": [
4323
+ "result_type",
4324
+ "count",
4325
+ "sending_mta_ip",
4326
+ "receiving_mx_hostname"
4327
+ ]
4329
4328
  };
4330
- function validate34(data, { instancePath = "", parentData, parentDataProperty, rootData = data } = {}) {
4329
+ function validate33(data, { instancePath = "", parentData, parentDataProperty, rootData = data } = {}) {
4331
4330
  let vErrors = null;
4332
4331
  let errors = 0;
4333
4332
  if (data && typeof data == "object" && !Array.isArray(data)) {
4334
- if (data.domain === void 0) {
4333
+ if (data.policy_domain === void 0) {
4335
4334
  const err0 = {
4336
4335
  instancePath,
4337
4336
  schemaPath: "#/required",
4338
4337
  keyword: "required",
4339
- params: { missingProperty: "domain" },
4340
- message: "must have required property 'domain'"
4338
+ params: { missingProperty: "policy_domain" },
4339
+ message: "must have required property 'policy_domain'"
4341
4340
  };
4342
4341
  if (vErrors === null) vErrors = [err0];
4343
4342
  else vErrors.push(err0);
4344
4343
  errors++;
4345
4344
  }
4346
- if (data.selector === void 0) {
4345
+ if (data.policy_type === void 0) {
4347
4346
  const err1 = {
4348
4347
  instancePath,
4349
4348
  schemaPath: "#/required",
4350
4349
  keyword: "required",
4351
- params: { missingProperty: "selector" },
4352
- message: "must have required property 'selector'"
4350
+ params: { missingProperty: "policy_type" },
4351
+ message: "must have required property 'policy_type'"
4353
4352
  };
4354
4353
  if (vErrors === null) vErrors = [err1];
4355
4354
  else vErrors.push(err1);
4356
4355
  errors++;
4357
4356
  }
4358
- if (data.result === void 0) {
4357
+ if (data.successful_sessions === void 0) {
4359
4358
  const err2 = {
4360
4359
  instancePath,
4361
4360
  schemaPath: "#/required",
4362
4361
  keyword: "required",
4363
- params: { missingProperty: "result" },
4364
- message: "must have required property 'result'"
4362
+ params: { missingProperty: "successful_sessions" },
4363
+ message: "must have required property 'successful_sessions'"
4365
4364
  };
4366
4365
  if (vErrors === null) vErrors = [err2];
4367
4366
  else vErrors.push(err2);
4368
4367
  errors++;
4369
4368
  }
4370
- if (data.aligned === void 0) {
4369
+ if (data.failed_sessions === void 0) {
4371
4370
  const err3 = {
4372
4371
  instancePath,
4373
4372
  schemaPath: "#/required",
4374
4373
  keyword: "required",
4375
- params: { missingProperty: "aligned" },
4376
- message: "must have required property 'aligned'"
4374
+ params: { missingProperty: "failed_sessions" },
4375
+ message: "must have required property 'failed_sessions'"
4377
4376
  };
4378
4377
  if (vErrors === null) vErrors = [err3];
4379
4378
  else vErrors.push(err3);
4380
4379
  errors++;
4381
4380
  }
4382
- if (data.keyBits === void 0) {
4381
+ if (data.failures === void 0) {
4383
4382
  const err4 = {
4384
4383
  instancePath,
4385
4384
  schemaPath: "#/required",
4386
4385
  keyword: "required",
4387
- params: { missingProperty: "keyBits" },
4388
- message: "must have required property 'keyBits'"
4386
+ params: { missingProperty: "failures" },
4387
+ message: "must have required property 'failures'"
4389
4388
  };
4390
4389
  if (vErrors === null) vErrors = [err4];
4391
4390
  else vErrors.push(err4);
4392
4391
  errors++;
4393
4392
  }
4394
- if (data.algo === void 0) {
4395
- const err5 = {
4396
- instancePath,
4397
- schemaPath: "#/required",
4398
- keyword: "required",
4393
+ if (data.policy_domain !== void 0) {
4394
+ let data0 = data.policy_domain;
4395
+ if (typeof data0 !== "string" && data0 !== null) {
4396
+ const err5 = {
4397
+ instancePath: instancePath + "/policy_domain",
4398
+ schemaPath: "#/properties/policy_domain/type",
4399
+ keyword: "type",
4400
+ params: { type: schema41.properties.policy_domain.type },
4401
+ message: "must be string,null"
4402
+ };
4403
+ if (vErrors === null) vErrors = [err5];
4404
+ else vErrors.push(err5);
4405
+ errors++;
4406
+ }
4407
+ }
4408
+ if (data.policy_type !== void 0) {
4409
+ let data1 = data.policy_type;
4410
+ if (typeof data1 !== "string" && data1 !== null) {
4411
+ const err6 = {
4412
+ instancePath: instancePath + "/policy_type",
4413
+ schemaPath: "#/properties/policy_type/type",
4414
+ keyword: "type",
4415
+ params: { type: schema41.properties.policy_type.type },
4416
+ message: "must be string,null"
4417
+ };
4418
+ if (vErrors === null) vErrors = [err6];
4419
+ else vErrors.push(err6);
4420
+ errors++;
4421
+ }
4422
+ }
4423
+ if (data.successful_sessions !== void 0) {
4424
+ let data2 = data.successful_sessions;
4425
+ if (!(typeof data2 == "number" && !(data2 % 1) && !isNaN(data2))) {
4426
+ const err7 = {
4427
+ instancePath: instancePath + "/successful_sessions",
4428
+ schemaPath: "#/properties/successful_sessions/type",
4429
+ keyword: "type",
4430
+ params: { type: "integer" },
4431
+ message: "must be integer"
4432
+ };
4433
+ if (vErrors === null) vErrors = [err7];
4434
+ else vErrors.push(err7);
4435
+ errors++;
4436
+ }
4437
+ }
4438
+ if (data.failed_sessions !== void 0) {
4439
+ let data3 = data.failed_sessions;
4440
+ if (!(typeof data3 == "number" && !(data3 % 1) && !isNaN(data3))) {
4441
+ const err8 = {
4442
+ instancePath: instancePath + "/failed_sessions",
4443
+ schemaPath: "#/properties/failed_sessions/type",
4444
+ keyword: "type",
4445
+ params: { type: "integer" },
4446
+ message: "must be integer"
4447
+ };
4448
+ if (vErrors === null) vErrors = [err8];
4449
+ else vErrors.push(err8);
4450
+ errors++;
4451
+ }
4452
+ }
4453
+ if (data.failures !== void 0) {
4454
+ let data4 = data.failures;
4455
+ if (Array.isArray(data4)) {
4456
+ const len0 = data4.length;
4457
+ for (let i0 = 0; i0 < len0; i0++) {
4458
+ let data5 = data4[i0];
4459
+ if (data5 && typeof data5 == "object" && !Array.isArray(data5)) {
4460
+ if (data5.result_type === void 0) {
4461
+ const err9 = {
4462
+ instancePath: instancePath + "/failures/" + i0,
4463
+ schemaPath: "#/definitions/TlsReportFailure/required",
4464
+ keyword: "required",
4465
+ params: { missingProperty: "result_type" },
4466
+ message: "must have required property 'result_type'"
4467
+ };
4468
+ if (vErrors === null) vErrors = [err9];
4469
+ else vErrors.push(err9);
4470
+ errors++;
4471
+ }
4472
+ if (data5.count === void 0) {
4473
+ const err10 = {
4474
+ instancePath: instancePath + "/failures/" + i0,
4475
+ schemaPath: "#/definitions/TlsReportFailure/required",
4476
+ keyword: "required",
4477
+ params: { missingProperty: "count" },
4478
+ message: "must have required property 'count'"
4479
+ };
4480
+ if (vErrors === null) vErrors = [err10];
4481
+ else vErrors.push(err10);
4482
+ errors++;
4483
+ }
4484
+ if (data5.sending_mta_ip === void 0) {
4485
+ const err11 = {
4486
+ instancePath: instancePath + "/failures/" + i0,
4487
+ schemaPath: "#/definitions/TlsReportFailure/required",
4488
+ keyword: "required",
4489
+ params: { missingProperty: "sending_mta_ip" },
4490
+ message: "must have required property 'sending_mta_ip'"
4491
+ };
4492
+ if (vErrors === null) vErrors = [err11];
4493
+ else vErrors.push(err11);
4494
+ errors++;
4495
+ }
4496
+ if (data5.receiving_mx_hostname === void 0) {
4497
+ const err12 = {
4498
+ instancePath: instancePath + "/failures/" + i0,
4499
+ schemaPath: "#/definitions/TlsReportFailure/required",
4500
+ keyword: "required",
4501
+ params: { missingProperty: "receiving_mx_hostname" },
4502
+ message: "must have required property 'receiving_mx_hostname'"
4503
+ };
4504
+ if (vErrors === null) vErrors = [err12];
4505
+ else vErrors.push(err12);
4506
+ errors++;
4507
+ }
4508
+ if (data5.result_type !== void 0) {
4509
+ let data6 = data5.result_type;
4510
+ if (typeof data6 !== "string" && data6 !== null) {
4511
+ const err13 = {
4512
+ instancePath: instancePath + "/failures/" + i0 + "/result_type",
4513
+ schemaPath: "#/definitions/TlsReportFailure/properties/result_type/type",
4514
+ keyword: "type",
4515
+ params: { type: schema42.properties.result_type.type },
4516
+ message: "must be string,null"
4517
+ };
4518
+ if (vErrors === null) vErrors = [err13];
4519
+ else vErrors.push(err13);
4520
+ errors++;
4521
+ }
4522
+ }
4523
+ if (data5.count !== void 0) {
4524
+ let data7 = data5.count;
4525
+ if (!(typeof data7 == "number" && !(data7 % 1) && !isNaN(data7))) {
4526
+ const err14 = {
4527
+ instancePath: instancePath + "/failures/" + i0 + "/count",
4528
+ schemaPath: "#/definitions/TlsReportFailure/properties/count/type",
4529
+ keyword: "type",
4530
+ params: { type: "integer" },
4531
+ message: "must be integer"
4532
+ };
4533
+ if (vErrors === null) vErrors = [err14];
4534
+ else vErrors.push(err14);
4535
+ errors++;
4536
+ }
4537
+ }
4538
+ if (data5.sending_mta_ip !== void 0) {
4539
+ let data8 = data5.sending_mta_ip;
4540
+ if (typeof data8 !== "string" && data8 !== null) {
4541
+ const err15 = {
4542
+ instancePath: instancePath + "/failures/" + i0 + "/sending_mta_ip",
4543
+ schemaPath: "#/definitions/TlsReportFailure/properties/sending_mta_ip/type",
4544
+ keyword: "type",
4545
+ params: { type: schema42.properties.sending_mta_ip.type },
4546
+ message: "must be string,null"
4547
+ };
4548
+ if (vErrors === null) vErrors = [err15];
4549
+ else vErrors.push(err15);
4550
+ errors++;
4551
+ }
4552
+ }
4553
+ if (data5.receiving_mx_hostname !== void 0) {
4554
+ let data9 = data5.receiving_mx_hostname;
4555
+ if (typeof data9 !== "string" && data9 !== null) {
4556
+ const err16 = {
4557
+ instancePath: instancePath + "/failures/" + i0 + "/receiving_mx_hostname",
4558
+ schemaPath: "#/definitions/TlsReportFailure/properties/receiving_mx_hostname/type",
4559
+ keyword: "type",
4560
+ params: { type: schema42.properties.receiving_mx_hostname.type },
4561
+ message: "must be string,null"
4562
+ };
4563
+ if (vErrors === null) vErrors = [err16];
4564
+ else vErrors.push(err16);
4565
+ errors++;
4566
+ }
4567
+ }
4568
+ } else {
4569
+ const err17 = {
4570
+ instancePath: instancePath + "/failures/" + i0,
4571
+ schemaPath: "#/definitions/TlsReportFailure/type",
4572
+ keyword: "type",
4573
+ params: { type: "object" },
4574
+ message: "must be object"
4575
+ };
4576
+ if (vErrors === null) vErrors = [err17];
4577
+ else vErrors.push(err17);
4578
+ errors++;
4579
+ }
4580
+ }
4581
+ } else {
4582
+ const err18 = {
4583
+ instancePath: instancePath + "/failures",
4584
+ schemaPath: "#/properties/failures/type",
4585
+ keyword: "type",
4586
+ params: { type: "array" },
4587
+ message: "must be array"
4588
+ };
4589
+ if (vErrors === null) vErrors = [err18];
4590
+ else vErrors.push(err18);
4591
+ errors++;
4592
+ }
4593
+ }
4594
+ } else {
4595
+ const err19 = {
4596
+ instancePath,
4597
+ schemaPath: "#/type",
4598
+ keyword: "type",
4599
+ params: { type: "object" },
4600
+ message: "must be object"
4601
+ };
4602
+ if (vErrors === null) vErrors = [err19];
4603
+ else vErrors.push(err19);
4604
+ errors++;
4605
+ }
4606
+ validate33.errors = vErrors;
4607
+ return errors === 0;
4608
+ }
4609
+ function validate32(data, { instancePath = "", parentData, parentDataProperty, rootData = data } = {}) {
4610
+ let vErrors = null;
4611
+ let errors = 0;
4612
+ if (data && typeof data == "object" && !Array.isArray(data)) {
4613
+ if (data.kind === void 0) {
4614
+ const err0 = {
4615
+ instancePath,
4616
+ schemaPath: "#/required",
4617
+ keyword: "required",
4618
+ params: { missingProperty: "kind" },
4619
+ message: "must have required property 'kind'"
4620
+ };
4621
+ if (vErrors === null) vErrors = [err0];
4622
+ else vErrors.push(err0);
4623
+ errors++;
4624
+ }
4625
+ if (data.organization === void 0) {
4626
+ const err1 = {
4627
+ instancePath,
4628
+ schemaPath: "#/required",
4629
+ keyword: "required",
4630
+ params: { missingProperty: "organization" },
4631
+ message: "must have required property 'organization'"
4632
+ };
4633
+ if (vErrors === null) vErrors = [err1];
4634
+ else vErrors.push(err1);
4635
+ errors++;
4636
+ }
4637
+ if (data.report_id === void 0) {
4638
+ const err2 = {
4639
+ instancePath,
4640
+ schemaPath: "#/required",
4641
+ keyword: "required",
4642
+ params: { missingProperty: "report_id" },
4643
+ message: "must have required property 'report_id'"
4644
+ };
4645
+ if (vErrors === null) vErrors = [err2];
4646
+ else vErrors.push(err2);
4647
+ errors++;
4648
+ }
4649
+ if (data.contact === void 0) {
4650
+ const err3 = {
4651
+ instancePath,
4652
+ schemaPath: "#/required",
4653
+ keyword: "required",
4654
+ params: { missingProperty: "contact" },
4655
+ message: "must have required property 'contact'"
4656
+ };
4657
+ if (vErrors === null) vErrors = [err3];
4658
+ else vErrors.push(err3);
4659
+ errors++;
4660
+ }
4661
+ if (data.date_range === void 0) {
4662
+ const err4 = {
4663
+ instancePath,
4664
+ schemaPath: "#/required",
4665
+ keyword: "required",
4666
+ params: { missingProperty: "date_range" },
4667
+ message: "must have required property 'date_range'"
4668
+ };
4669
+ if (vErrors === null) vErrors = [err4];
4670
+ else vErrors.push(err4);
4671
+ errors++;
4672
+ }
4673
+ if (data.total_successful_sessions === void 0) {
4674
+ const err5 = {
4675
+ instancePath,
4676
+ schemaPath: "#/required",
4677
+ keyword: "required",
4678
+ params: { missingProperty: "total_successful_sessions" },
4679
+ message: "must have required property 'total_successful_sessions'"
4680
+ };
4681
+ if (vErrors === null) vErrors = [err5];
4682
+ else vErrors.push(err5);
4683
+ errors++;
4684
+ }
4685
+ if (data.total_failed_sessions === void 0) {
4686
+ const err6 = {
4687
+ instancePath,
4688
+ schemaPath: "#/required",
4689
+ keyword: "required",
4690
+ params: { missingProperty: "total_failed_sessions" },
4691
+ message: "must have required property 'total_failed_sessions'"
4692
+ };
4693
+ if (vErrors === null) vErrors = [err6];
4694
+ else vErrors.push(err6);
4695
+ errors++;
4696
+ }
4697
+ if (data.policies === void 0) {
4698
+ const err7 = {
4699
+ instancePath,
4700
+ schemaPath: "#/required",
4701
+ keyword: "required",
4702
+ params: { missingProperty: "policies" },
4703
+ message: "must have required property 'policies'"
4704
+ };
4705
+ if (vErrors === null) vErrors = [err7];
4706
+ else vErrors.push(err7);
4707
+ errors++;
4708
+ }
4709
+ if (data.kind !== void 0) {
4710
+ let data0 = data.kind;
4711
+ if (typeof data0 !== "string") {
4712
+ const err8 = {
4713
+ instancePath: instancePath + "/kind",
4714
+ schemaPath: "#/properties/kind/type",
4715
+ keyword: "type",
4716
+ params: { type: "string" },
4717
+ message: "must be string"
4718
+ };
4719
+ if (vErrors === null) vErrors = [err8];
4720
+ else vErrors.push(err8);
4721
+ errors++;
4722
+ }
4723
+ if ("tls_report" !== data0) {
4724
+ const err9 = {
4725
+ instancePath: instancePath + "/kind",
4726
+ schemaPath: "#/properties/kind/const",
4727
+ keyword: "const",
4728
+ params: { allowedValue: "tls_report" },
4729
+ message: "must be equal to constant"
4730
+ };
4731
+ if (vErrors === null) vErrors = [err9];
4732
+ else vErrors.push(err9);
4733
+ errors++;
4734
+ }
4735
+ }
4736
+ if (data.organization !== void 0) {
4737
+ let data1 = data.organization;
4738
+ if (typeof data1 !== "string" && data1 !== null) {
4739
+ const err10 = {
4740
+ instancePath: instancePath + "/organization",
4741
+ schemaPath: "#/properties/organization/type",
4742
+ keyword: "type",
4743
+ params: { type: schema40.properties.organization.type },
4744
+ message: "must be string,null"
4745
+ };
4746
+ if (vErrors === null) vErrors = [err10];
4747
+ else vErrors.push(err10);
4748
+ errors++;
4749
+ }
4750
+ }
4751
+ if (data.report_id !== void 0) {
4752
+ let data2 = data.report_id;
4753
+ if (typeof data2 !== "string" && data2 !== null) {
4754
+ const err11 = {
4755
+ instancePath: instancePath + "/report_id",
4756
+ schemaPath: "#/properties/report_id/type",
4757
+ keyword: "type",
4758
+ params: { type: schema40.properties.report_id.type },
4759
+ message: "must be string,null"
4760
+ };
4761
+ if (vErrors === null) vErrors = [err11];
4762
+ else vErrors.push(err11);
4763
+ errors++;
4764
+ }
4765
+ }
4766
+ if (data.contact !== void 0) {
4767
+ let data3 = data.contact;
4768
+ if (typeof data3 !== "string" && data3 !== null) {
4769
+ const err12 = {
4770
+ instancePath: instancePath + "/contact",
4771
+ schemaPath: "#/properties/contact/type",
4772
+ keyword: "type",
4773
+ params: { type: schema40.properties.contact.type },
4774
+ message: "must be string,null"
4775
+ };
4776
+ if (vErrors === null) vErrors = [err12];
4777
+ else vErrors.push(err12);
4778
+ errors++;
4779
+ }
4780
+ }
4781
+ if (data.date_range !== void 0) {
4782
+ let data4 = data.date_range;
4783
+ if (data4 && typeof data4 == "object" && !Array.isArray(data4)) {
4784
+ if (data4.start === void 0) {
4785
+ const err13 = {
4786
+ instancePath: instancePath + "/date_range",
4787
+ schemaPath: "#/properties/date_range/required",
4788
+ keyword: "required",
4789
+ params: { missingProperty: "start" },
4790
+ message: "must have required property 'start'"
4791
+ };
4792
+ if (vErrors === null) vErrors = [err13];
4793
+ else vErrors.push(err13);
4794
+ errors++;
4795
+ }
4796
+ if (data4.end === void 0) {
4797
+ const err14 = {
4798
+ instancePath: instancePath + "/date_range",
4799
+ schemaPath: "#/properties/date_range/required",
4800
+ keyword: "required",
4801
+ params: { missingProperty: "end" },
4802
+ message: "must have required property 'end'"
4803
+ };
4804
+ if (vErrors === null) vErrors = [err14];
4805
+ else vErrors.push(err14);
4806
+ errors++;
4807
+ }
4808
+ if (data4.start !== void 0) {
4809
+ let data5 = data4.start;
4810
+ if (typeof data5 !== "string" && data5 !== null) {
4811
+ const err15 = {
4812
+ instancePath: instancePath + "/date_range/start",
4813
+ schemaPath: "#/properties/date_range/properties/start/type",
4814
+ keyword: "type",
4815
+ params: { type: schema40.properties.date_range.properties.start.type },
4816
+ message: "must be string,null"
4817
+ };
4818
+ if (vErrors === null) vErrors = [err15];
4819
+ else vErrors.push(err15);
4820
+ errors++;
4821
+ }
4822
+ }
4823
+ if (data4.end !== void 0) {
4824
+ let data6 = data4.end;
4825
+ if (typeof data6 !== "string" && data6 !== null) {
4826
+ const err16 = {
4827
+ instancePath: instancePath + "/date_range/end",
4828
+ schemaPath: "#/properties/date_range/properties/end/type",
4829
+ keyword: "type",
4830
+ params: { type: schema40.properties.date_range.properties.end.type },
4831
+ message: "must be string,null"
4832
+ };
4833
+ if (vErrors === null) vErrors = [err16];
4834
+ else vErrors.push(err16);
4835
+ errors++;
4836
+ }
4837
+ }
4838
+ } else {
4839
+ const err17 = {
4840
+ instancePath: instancePath + "/date_range",
4841
+ schemaPath: "#/properties/date_range/type",
4842
+ keyword: "type",
4843
+ params: { type: "object" },
4844
+ message: "must be object"
4845
+ };
4846
+ if (vErrors === null) vErrors = [err17];
4847
+ else vErrors.push(err17);
4848
+ errors++;
4849
+ }
4850
+ }
4851
+ if (data.total_successful_sessions !== void 0) {
4852
+ let data7 = data.total_successful_sessions;
4853
+ if (!(typeof data7 == "number" && !(data7 % 1) && !isNaN(data7))) {
4854
+ const err18 = {
4855
+ instancePath: instancePath + "/total_successful_sessions",
4856
+ schemaPath: "#/properties/total_successful_sessions/type",
4857
+ keyword: "type",
4858
+ params: { type: "integer" },
4859
+ message: "must be integer"
4860
+ };
4861
+ if (vErrors === null) vErrors = [err18];
4862
+ else vErrors.push(err18);
4863
+ errors++;
4864
+ }
4865
+ }
4866
+ if (data.total_failed_sessions !== void 0) {
4867
+ let data8 = data.total_failed_sessions;
4868
+ if (!(typeof data8 == "number" && !(data8 % 1) && !isNaN(data8))) {
4869
+ const err19 = {
4870
+ instancePath: instancePath + "/total_failed_sessions",
4871
+ schemaPath: "#/properties/total_failed_sessions/type",
4872
+ keyword: "type",
4873
+ params: { type: "integer" },
4874
+ message: "must be integer"
4875
+ };
4876
+ if (vErrors === null) vErrors = [err19];
4877
+ else vErrors.push(err19);
4878
+ errors++;
4879
+ }
4880
+ }
4881
+ if (data.policies !== void 0) {
4882
+ let data9 = data.policies;
4883
+ if (Array.isArray(data9)) {
4884
+ const len0 = data9.length;
4885
+ for (let i0 = 0; i0 < len0; i0++) if (!validate33(data9[i0], {
4886
+ instancePath: instancePath + "/policies/" + i0,
4887
+ parentData: data9,
4888
+ parentDataProperty: i0,
4889
+ rootData
4890
+ })) {
4891
+ vErrors = vErrors === null ? validate33.errors : vErrors.concat(validate33.errors);
4892
+ errors = vErrors.length;
4893
+ }
4894
+ } else {
4895
+ const err20 = {
4896
+ instancePath: instancePath + "/policies",
4897
+ schemaPath: "#/properties/policies/type",
4898
+ keyword: "type",
4899
+ params: { type: "array" },
4900
+ message: "must be array"
4901
+ };
4902
+ if (vErrors === null) vErrors = [err20];
4903
+ else vErrors.push(err20);
4904
+ errors++;
4905
+ }
4906
+ }
4907
+ } else {
4908
+ const err21 = {
4909
+ instancePath,
4910
+ schemaPath: "#/type",
4911
+ keyword: "type",
4912
+ params: { type: "object" },
4913
+ message: "must be object"
4914
+ };
4915
+ if (vErrors === null) vErrors = [err21];
4916
+ else vErrors.push(err21);
4917
+ errors++;
4918
+ }
4919
+ validate32.errors = vErrors;
4920
+ return errors === 0;
4921
+ }
4922
+ const schema43 = {
4923
+ "type": "object",
4924
+ "properties": {
4925
+ "kind": {
4926
+ "type": "string",
4927
+ "const": "dmarc_report"
4928
+ },
4929
+ "organization": { "type": ["string", "null"] },
4930
+ "report_id": { "type": ["string", "null"] },
4931
+ "date_range": {
4932
+ "type": "object",
4933
+ "properties": {
4934
+ "start": {
4935
+ "type": ["string", "null"],
4936
+ "description": "ISO 8601 start of the reporting window."
4937
+ },
4938
+ "end": {
4939
+ "type": ["string", "null"],
4940
+ "description": "ISO 8601 end of the reporting window."
4941
+ }
4942
+ },
4943
+ "required": ["start", "end"]
4944
+ },
4945
+ "policy_published": {
4946
+ "type": "object",
4947
+ "properties": {
4948
+ "domain": { "type": ["string", "null"] },
4949
+ "p": {
4950
+ "type": ["string", "null"],
4951
+ "description": "Published domain policy: `none`, `quarantine`, or `reject`."
4952
+ },
4953
+ "sp": {
4954
+ "type": ["string", "null"],
4955
+ "description": "Published subdomain policy."
4956
+ },
4957
+ "pct": {
4958
+ "type": ["integer", "null"],
4959
+ "description": "Percentage of messages the policy is applied to."
4960
+ },
4961
+ "adkim": {
4962
+ "type": ["string", "null"],
4963
+ "description": "DKIM alignment mode: `r` (relaxed) or `s` (strict)."
4964
+ },
4965
+ "aspf": {
4966
+ "type": ["string", "null"],
4967
+ "description": "SPF alignment mode: `r` (relaxed) or `s` (strict)."
4968
+ }
4969
+ },
4970
+ "required": [
4971
+ "domain",
4972
+ "p",
4973
+ "sp",
4974
+ "pct",
4975
+ "adkim",
4976
+ "aspf"
4977
+ ]
4978
+ },
4979
+ "total_count": {
4980
+ "type": "integer",
4981
+ "description": "Total messages covered by the report."
4982
+ },
4983
+ "dkim_pass_count": { "type": "integer" },
4984
+ "spf_pass_count": { "type": "integer" },
4985
+ "records": {
4986
+ "type": "array",
4987
+ "items": { "$ref": "#/definitions/DmarcRecord" }
4988
+ }
4989
+ },
4990
+ "required": [
4991
+ "kind",
4992
+ "organization",
4993
+ "report_id",
4994
+ "date_range",
4995
+ "policy_published",
4996
+ "total_count",
4997
+ "dkim_pass_count",
4998
+ "spf_pass_count",
4999
+ "records"
5000
+ ],
5001
+ "description": "Parsed DMARC aggregate report (RFC 7489). Present as `email.analysis.dmarc_report` on `email.dmarc_report` events."
5002
+ };
5003
+ const schema44 = {
5004
+ "type": "object",
5005
+ "properties": {
5006
+ "source_ip": { "type": ["string", "null"] },
5007
+ "count": { "type": "integer" },
5008
+ "disposition": {
5009
+ "type": ["string", "null"],
5010
+ "description": "Disposition applied by the receiver: `none`, `quarantine`, or `reject`."
5011
+ },
5012
+ "dkim": {
5013
+ "type": ["string", "null"],
5014
+ "description": "DKIM alignment result: `pass` or `fail`."
5015
+ },
5016
+ "spf": {
5017
+ "type": ["string", "null"],
5018
+ "description": "SPF alignment result: `pass` or `fail`."
5019
+ },
5020
+ "header_from": { "type": ["string", "null"] }
5021
+ },
5022
+ "required": [
5023
+ "source_ip",
5024
+ "count",
5025
+ "disposition",
5026
+ "dkim",
5027
+ "spf",
5028
+ "header_from"
5029
+ ]
5030
+ };
5031
+ function validate36(data, { instancePath = "", parentData, parentDataProperty, rootData = data } = {}) {
5032
+ let vErrors = null;
5033
+ let errors = 0;
5034
+ if (data && typeof data == "object" && !Array.isArray(data)) {
5035
+ if (data.kind === void 0) {
5036
+ const err0 = {
5037
+ instancePath,
5038
+ schemaPath: "#/required",
5039
+ keyword: "required",
5040
+ params: { missingProperty: "kind" },
5041
+ message: "must have required property 'kind'"
5042
+ };
5043
+ if (vErrors === null) vErrors = [err0];
5044
+ else vErrors.push(err0);
5045
+ errors++;
5046
+ }
5047
+ if (data.organization === void 0) {
5048
+ const err1 = {
5049
+ instancePath,
5050
+ schemaPath: "#/required",
5051
+ keyword: "required",
5052
+ params: { missingProperty: "organization" },
5053
+ message: "must have required property 'organization'"
5054
+ };
5055
+ if (vErrors === null) vErrors = [err1];
5056
+ else vErrors.push(err1);
5057
+ errors++;
5058
+ }
5059
+ if (data.report_id === void 0) {
5060
+ const err2 = {
5061
+ instancePath,
5062
+ schemaPath: "#/required",
5063
+ keyword: "required",
5064
+ params: { missingProperty: "report_id" },
5065
+ message: "must have required property 'report_id'"
5066
+ };
5067
+ if (vErrors === null) vErrors = [err2];
5068
+ else vErrors.push(err2);
5069
+ errors++;
5070
+ }
5071
+ if (data.date_range === void 0) {
5072
+ const err3 = {
5073
+ instancePath,
5074
+ schemaPath: "#/required",
5075
+ keyword: "required",
5076
+ params: { missingProperty: "date_range" },
5077
+ message: "must have required property 'date_range'"
5078
+ };
5079
+ if (vErrors === null) vErrors = [err3];
5080
+ else vErrors.push(err3);
5081
+ errors++;
5082
+ }
5083
+ if (data.policy_published === void 0) {
5084
+ const err4 = {
5085
+ instancePath,
5086
+ schemaPath: "#/required",
5087
+ keyword: "required",
5088
+ params: { missingProperty: "policy_published" },
5089
+ message: "must have required property 'policy_published'"
5090
+ };
5091
+ if (vErrors === null) vErrors = [err4];
5092
+ else vErrors.push(err4);
5093
+ errors++;
5094
+ }
5095
+ if (data.total_count === void 0) {
5096
+ const err5 = {
5097
+ instancePath,
5098
+ schemaPath: "#/required",
5099
+ keyword: "required",
5100
+ params: { missingProperty: "total_count" },
5101
+ message: "must have required property 'total_count'"
5102
+ };
5103
+ if (vErrors === null) vErrors = [err5];
5104
+ else vErrors.push(err5);
5105
+ errors++;
5106
+ }
5107
+ if (data.dkim_pass_count === void 0) {
5108
+ const err6 = {
5109
+ instancePath,
5110
+ schemaPath: "#/required",
5111
+ keyword: "required",
5112
+ params: { missingProperty: "dkim_pass_count" },
5113
+ message: "must have required property 'dkim_pass_count'"
5114
+ };
5115
+ if (vErrors === null) vErrors = [err6];
5116
+ else vErrors.push(err6);
5117
+ errors++;
5118
+ }
5119
+ if (data.spf_pass_count === void 0) {
5120
+ const err7 = {
5121
+ instancePath,
5122
+ schemaPath: "#/required",
5123
+ keyword: "required",
5124
+ params: { missingProperty: "spf_pass_count" },
5125
+ message: "must have required property 'spf_pass_count'"
5126
+ };
5127
+ if (vErrors === null) vErrors = [err7];
5128
+ else vErrors.push(err7);
5129
+ errors++;
5130
+ }
5131
+ if (data.records === void 0) {
5132
+ const err8 = {
5133
+ instancePath,
5134
+ schemaPath: "#/required",
5135
+ keyword: "required",
5136
+ params: { missingProperty: "records" },
5137
+ message: "must have required property 'records'"
5138
+ };
5139
+ if (vErrors === null) vErrors = [err8];
5140
+ else vErrors.push(err8);
5141
+ errors++;
5142
+ }
5143
+ if (data.kind !== void 0) {
5144
+ let data0 = data.kind;
5145
+ if (typeof data0 !== "string") {
5146
+ const err9 = {
5147
+ instancePath: instancePath + "/kind",
5148
+ schemaPath: "#/properties/kind/type",
5149
+ keyword: "type",
5150
+ params: { type: "string" },
5151
+ message: "must be string"
5152
+ };
5153
+ if (vErrors === null) vErrors = [err9];
5154
+ else vErrors.push(err9);
5155
+ errors++;
5156
+ }
5157
+ if ("dmarc_report" !== data0) {
5158
+ const err10 = {
5159
+ instancePath: instancePath + "/kind",
5160
+ schemaPath: "#/properties/kind/const",
5161
+ keyword: "const",
5162
+ params: { allowedValue: "dmarc_report" },
5163
+ message: "must be equal to constant"
5164
+ };
5165
+ if (vErrors === null) vErrors = [err10];
5166
+ else vErrors.push(err10);
5167
+ errors++;
5168
+ }
5169
+ }
5170
+ if (data.organization !== void 0) {
5171
+ let data1 = data.organization;
5172
+ if (typeof data1 !== "string" && data1 !== null) {
5173
+ const err11 = {
5174
+ instancePath: instancePath + "/organization",
5175
+ schemaPath: "#/properties/organization/type",
5176
+ keyword: "type",
5177
+ params: { type: schema43.properties.organization.type },
5178
+ message: "must be string,null"
5179
+ };
5180
+ if (vErrors === null) vErrors = [err11];
5181
+ else vErrors.push(err11);
5182
+ errors++;
5183
+ }
5184
+ }
5185
+ if (data.report_id !== void 0) {
5186
+ let data2 = data.report_id;
5187
+ if (typeof data2 !== "string" && data2 !== null) {
5188
+ const err12 = {
5189
+ instancePath: instancePath + "/report_id",
5190
+ schemaPath: "#/properties/report_id/type",
5191
+ keyword: "type",
5192
+ params: { type: schema43.properties.report_id.type },
5193
+ message: "must be string,null"
5194
+ };
5195
+ if (vErrors === null) vErrors = [err12];
5196
+ else vErrors.push(err12);
5197
+ errors++;
5198
+ }
5199
+ }
5200
+ if (data.date_range !== void 0) {
5201
+ let data3 = data.date_range;
5202
+ if (data3 && typeof data3 == "object" && !Array.isArray(data3)) {
5203
+ if (data3.start === void 0) {
5204
+ const err13 = {
5205
+ instancePath: instancePath + "/date_range",
5206
+ schemaPath: "#/properties/date_range/required",
5207
+ keyword: "required",
5208
+ params: { missingProperty: "start" },
5209
+ message: "must have required property 'start'"
5210
+ };
5211
+ if (vErrors === null) vErrors = [err13];
5212
+ else vErrors.push(err13);
5213
+ errors++;
5214
+ }
5215
+ if (data3.end === void 0) {
5216
+ const err14 = {
5217
+ instancePath: instancePath + "/date_range",
5218
+ schemaPath: "#/properties/date_range/required",
5219
+ keyword: "required",
5220
+ params: { missingProperty: "end" },
5221
+ message: "must have required property 'end'"
5222
+ };
5223
+ if (vErrors === null) vErrors = [err14];
5224
+ else vErrors.push(err14);
5225
+ errors++;
5226
+ }
5227
+ if (data3.start !== void 0) {
5228
+ let data4 = data3.start;
5229
+ if (typeof data4 !== "string" && data4 !== null) {
5230
+ const err15 = {
5231
+ instancePath: instancePath + "/date_range/start",
5232
+ schemaPath: "#/properties/date_range/properties/start/type",
5233
+ keyword: "type",
5234
+ params: { type: schema43.properties.date_range.properties.start.type },
5235
+ message: "must be string,null"
5236
+ };
5237
+ if (vErrors === null) vErrors = [err15];
5238
+ else vErrors.push(err15);
5239
+ errors++;
5240
+ }
5241
+ }
5242
+ if (data3.end !== void 0) {
5243
+ let data5 = data3.end;
5244
+ if (typeof data5 !== "string" && data5 !== null) {
5245
+ const err16 = {
5246
+ instancePath: instancePath + "/date_range/end",
5247
+ schemaPath: "#/properties/date_range/properties/end/type",
5248
+ keyword: "type",
5249
+ params: { type: schema43.properties.date_range.properties.end.type },
5250
+ message: "must be string,null"
5251
+ };
5252
+ if (vErrors === null) vErrors = [err16];
5253
+ else vErrors.push(err16);
5254
+ errors++;
5255
+ }
5256
+ }
5257
+ } else {
5258
+ const err17 = {
5259
+ instancePath: instancePath + "/date_range",
5260
+ schemaPath: "#/properties/date_range/type",
5261
+ keyword: "type",
5262
+ params: { type: "object" },
5263
+ message: "must be object"
5264
+ };
5265
+ if (vErrors === null) vErrors = [err17];
5266
+ else vErrors.push(err17);
5267
+ errors++;
5268
+ }
5269
+ }
5270
+ if (data.policy_published !== void 0) {
5271
+ let data6 = data.policy_published;
5272
+ if (data6 && typeof data6 == "object" && !Array.isArray(data6)) {
5273
+ if (data6.domain === void 0) {
5274
+ const err18 = {
5275
+ instancePath: instancePath + "/policy_published",
5276
+ schemaPath: "#/properties/policy_published/required",
5277
+ keyword: "required",
5278
+ params: { missingProperty: "domain" },
5279
+ message: "must have required property 'domain'"
5280
+ };
5281
+ if (vErrors === null) vErrors = [err18];
5282
+ else vErrors.push(err18);
5283
+ errors++;
5284
+ }
5285
+ if (data6.p === void 0) {
5286
+ const err19 = {
5287
+ instancePath: instancePath + "/policy_published",
5288
+ schemaPath: "#/properties/policy_published/required",
5289
+ keyword: "required",
5290
+ params: { missingProperty: "p" },
5291
+ message: "must have required property 'p'"
5292
+ };
5293
+ if (vErrors === null) vErrors = [err19];
5294
+ else vErrors.push(err19);
5295
+ errors++;
5296
+ }
5297
+ if (data6.sp === void 0) {
5298
+ const err20 = {
5299
+ instancePath: instancePath + "/policy_published",
5300
+ schemaPath: "#/properties/policy_published/required",
5301
+ keyword: "required",
5302
+ params: { missingProperty: "sp" },
5303
+ message: "must have required property 'sp'"
5304
+ };
5305
+ if (vErrors === null) vErrors = [err20];
5306
+ else vErrors.push(err20);
5307
+ errors++;
5308
+ }
5309
+ if (data6.pct === void 0) {
5310
+ const err21 = {
5311
+ instancePath: instancePath + "/policy_published",
5312
+ schemaPath: "#/properties/policy_published/required",
5313
+ keyword: "required",
5314
+ params: { missingProperty: "pct" },
5315
+ message: "must have required property 'pct'"
5316
+ };
5317
+ if (vErrors === null) vErrors = [err21];
5318
+ else vErrors.push(err21);
5319
+ errors++;
5320
+ }
5321
+ if (data6.adkim === void 0) {
5322
+ const err22 = {
5323
+ instancePath: instancePath + "/policy_published",
5324
+ schemaPath: "#/properties/policy_published/required",
5325
+ keyword: "required",
5326
+ params: { missingProperty: "adkim" },
5327
+ message: "must have required property 'adkim'"
5328
+ };
5329
+ if (vErrors === null) vErrors = [err22];
5330
+ else vErrors.push(err22);
5331
+ errors++;
5332
+ }
5333
+ if (data6.aspf === void 0) {
5334
+ const err23 = {
5335
+ instancePath: instancePath + "/policy_published",
5336
+ schemaPath: "#/properties/policy_published/required",
5337
+ keyword: "required",
5338
+ params: { missingProperty: "aspf" },
5339
+ message: "must have required property 'aspf'"
5340
+ };
5341
+ if (vErrors === null) vErrors = [err23];
5342
+ else vErrors.push(err23);
5343
+ errors++;
5344
+ }
5345
+ if (data6.domain !== void 0) {
5346
+ let data7 = data6.domain;
5347
+ if (typeof data7 !== "string" && data7 !== null) {
5348
+ const err24 = {
5349
+ instancePath: instancePath + "/policy_published/domain",
5350
+ schemaPath: "#/properties/policy_published/properties/domain/type",
5351
+ keyword: "type",
5352
+ params: { type: schema43.properties.policy_published.properties.domain.type },
5353
+ message: "must be string,null"
5354
+ };
5355
+ if (vErrors === null) vErrors = [err24];
5356
+ else vErrors.push(err24);
5357
+ errors++;
5358
+ }
5359
+ }
5360
+ if (data6.p !== void 0) {
5361
+ let data8 = data6.p;
5362
+ if (typeof data8 !== "string" && data8 !== null) {
5363
+ const err25 = {
5364
+ instancePath: instancePath + "/policy_published/p",
5365
+ schemaPath: "#/properties/policy_published/properties/p/type",
5366
+ keyword: "type",
5367
+ params: { type: schema43.properties.policy_published.properties.p.type },
5368
+ message: "must be string,null"
5369
+ };
5370
+ if (vErrors === null) vErrors = [err25];
5371
+ else vErrors.push(err25);
5372
+ errors++;
5373
+ }
5374
+ }
5375
+ if (data6.sp !== void 0) {
5376
+ let data9 = data6.sp;
5377
+ if (typeof data9 !== "string" && data9 !== null) {
5378
+ const err26 = {
5379
+ instancePath: instancePath + "/policy_published/sp",
5380
+ schemaPath: "#/properties/policy_published/properties/sp/type",
5381
+ keyword: "type",
5382
+ params: { type: schema43.properties.policy_published.properties.sp.type },
5383
+ message: "must be string,null"
5384
+ };
5385
+ if (vErrors === null) vErrors = [err26];
5386
+ else vErrors.push(err26);
5387
+ errors++;
5388
+ }
5389
+ }
5390
+ if (data6.pct !== void 0) {
5391
+ let data10 = data6.pct;
5392
+ if (!(typeof data10 == "number" && !(data10 % 1) && !isNaN(data10)) && data10 !== null) {
5393
+ const err27 = {
5394
+ instancePath: instancePath + "/policy_published/pct",
5395
+ schemaPath: "#/properties/policy_published/properties/pct/type",
5396
+ keyword: "type",
5397
+ params: { type: schema43.properties.policy_published.properties.pct.type },
5398
+ message: "must be integer,null"
5399
+ };
5400
+ if (vErrors === null) vErrors = [err27];
5401
+ else vErrors.push(err27);
5402
+ errors++;
5403
+ }
5404
+ }
5405
+ if (data6.adkim !== void 0) {
5406
+ let data11 = data6.adkim;
5407
+ if (typeof data11 !== "string" && data11 !== null) {
5408
+ const err28 = {
5409
+ instancePath: instancePath + "/policy_published/adkim",
5410
+ schemaPath: "#/properties/policy_published/properties/adkim/type",
5411
+ keyword: "type",
5412
+ params: { type: schema43.properties.policy_published.properties.adkim.type },
5413
+ message: "must be string,null"
5414
+ };
5415
+ if (vErrors === null) vErrors = [err28];
5416
+ else vErrors.push(err28);
5417
+ errors++;
5418
+ }
5419
+ }
5420
+ if (data6.aspf !== void 0) {
5421
+ let data12 = data6.aspf;
5422
+ if (typeof data12 !== "string" && data12 !== null) {
5423
+ const err29 = {
5424
+ instancePath: instancePath + "/policy_published/aspf",
5425
+ schemaPath: "#/properties/policy_published/properties/aspf/type",
5426
+ keyword: "type",
5427
+ params: { type: schema43.properties.policy_published.properties.aspf.type },
5428
+ message: "must be string,null"
5429
+ };
5430
+ if (vErrors === null) vErrors = [err29];
5431
+ else vErrors.push(err29);
5432
+ errors++;
5433
+ }
5434
+ }
5435
+ } else {
5436
+ const err30 = {
5437
+ instancePath: instancePath + "/policy_published",
5438
+ schemaPath: "#/properties/policy_published/type",
5439
+ keyword: "type",
5440
+ params: { type: "object" },
5441
+ message: "must be object"
5442
+ };
5443
+ if (vErrors === null) vErrors = [err30];
5444
+ else vErrors.push(err30);
5445
+ errors++;
5446
+ }
5447
+ }
5448
+ if (data.total_count !== void 0) {
5449
+ let data13 = data.total_count;
5450
+ if (!(typeof data13 == "number" && !(data13 % 1) && !isNaN(data13))) {
5451
+ const err31 = {
5452
+ instancePath: instancePath + "/total_count",
5453
+ schemaPath: "#/properties/total_count/type",
5454
+ keyword: "type",
5455
+ params: { type: "integer" },
5456
+ message: "must be integer"
5457
+ };
5458
+ if (vErrors === null) vErrors = [err31];
5459
+ else vErrors.push(err31);
5460
+ errors++;
5461
+ }
5462
+ }
5463
+ if (data.dkim_pass_count !== void 0) {
5464
+ let data14 = data.dkim_pass_count;
5465
+ if (!(typeof data14 == "number" && !(data14 % 1) && !isNaN(data14))) {
5466
+ const err32 = {
5467
+ instancePath: instancePath + "/dkim_pass_count",
5468
+ schemaPath: "#/properties/dkim_pass_count/type",
5469
+ keyword: "type",
5470
+ params: { type: "integer" },
5471
+ message: "must be integer"
5472
+ };
5473
+ if (vErrors === null) vErrors = [err32];
5474
+ else vErrors.push(err32);
5475
+ errors++;
5476
+ }
5477
+ }
5478
+ if (data.spf_pass_count !== void 0) {
5479
+ let data15 = data.spf_pass_count;
5480
+ if (!(typeof data15 == "number" && !(data15 % 1) && !isNaN(data15))) {
5481
+ const err33 = {
5482
+ instancePath: instancePath + "/spf_pass_count",
5483
+ schemaPath: "#/properties/spf_pass_count/type",
5484
+ keyword: "type",
5485
+ params: { type: "integer" },
5486
+ message: "must be integer"
5487
+ };
5488
+ if (vErrors === null) vErrors = [err33];
5489
+ else vErrors.push(err33);
5490
+ errors++;
5491
+ }
5492
+ }
5493
+ if (data.records !== void 0) {
5494
+ let data16 = data.records;
5495
+ if (Array.isArray(data16)) {
5496
+ const len0 = data16.length;
5497
+ for (let i0 = 0; i0 < len0; i0++) {
5498
+ let data17 = data16[i0];
5499
+ if (data17 && typeof data17 == "object" && !Array.isArray(data17)) {
5500
+ if (data17.source_ip === void 0) {
5501
+ const err34 = {
5502
+ instancePath: instancePath + "/records/" + i0,
5503
+ schemaPath: "#/definitions/DmarcRecord/required",
5504
+ keyword: "required",
5505
+ params: { missingProperty: "source_ip" },
5506
+ message: "must have required property 'source_ip'"
5507
+ };
5508
+ if (vErrors === null) vErrors = [err34];
5509
+ else vErrors.push(err34);
5510
+ errors++;
5511
+ }
5512
+ if (data17.count === void 0) {
5513
+ const err35 = {
5514
+ instancePath: instancePath + "/records/" + i0,
5515
+ schemaPath: "#/definitions/DmarcRecord/required",
5516
+ keyword: "required",
5517
+ params: { missingProperty: "count" },
5518
+ message: "must have required property 'count'"
5519
+ };
5520
+ if (vErrors === null) vErrors = [err35];
5521
+ else vErrors.push(err35);
5522
+ errors++;
5523
+ }
5524
+ if (data17.disposition === void 0) {
5525
+ const err36 = {
5526
+ instancePath: instancePath + "/records/" + i0,
5527
+ schemaPath: "#/definitions/DmarcRecord/required",
5528
+ keyword: "required",
5529
+ params: { missingProperty: "disposition" },
5530
+ message: "must have required property 'disposition'"
5531
+ };
5532
+ if (vErrors === null) vErrors = [err36];
5533
+ else vErrors.push(err36);
5534
+ errors++;
5535
+ }
5536
+ if (data17.dkim === void 0) {
5537
+ const err37 = {
5538
+ instancePath: instancePath + "/records/" + i0,
5539
+ schemaPath: "#/definitions/DmarcRecord/required",
5540
+ keyword: "required",
5541
+ params: { missingProperty: "dkim" },
5542
+ message: "must have required property 'dkim'"
5543
+ };
5544
+ if (vErrors === null) vErrors = [err37];
5545
+ else vErrors.push(err37);
5546
+ errors++;
5547
+ }
5548
+ if (data17.spf === void 0) {
5549
+ const err38 = {
5550
+ instancePath: instancePath + "/records/" + i0,
5551
+ schemaPath: "#/definitions/DmarcRecord/required",
5552
+ keyword: "required",
5553
+ params: { missingProperty: "spf" },
5554
+ message: "must have required property 'spf'"
5555
+ };
5556
+ if (vErrors === null) vErrors = [err38];
5557
+ else vErrors.push(err38);
5558
+ errors++;
5559
+ }
5560
+ if (data17.header_from === void 0) {
5561
+ const err39 = {
5562
+ instancePath: instancePath + "/records/" + i0,
5563
+ schemaPath: "#/definitions/DmarcRecord/required",
5564
+ keyword: "required",
5565
+ params: { missingProperty: "header_from" },
5566
+ message: "must have required property 'header_from'"
5567
+ };
5568
+ if (vErrors === null) vErrors = [err39];
5569
+ else vErrors.push(err39);
5570
+ errors++;
5571
+ }
5572
+ if (data17.source_ip !== void 0) {
5573
+ let data18 = data17.source_ip;
5574
+ if (typeof data18 !== "string" && data18 !== null) {
5575
+ const err40 = {
5576
+ instancePath: instancePath + "/records/" + i0 + "/source_ip",
5577
+ schemaPath: "#/definitions/DmarcRecord/properties/source_ip/type",
5578
+ keyword: "type",
5579
+ params: { type: schema44.properties.source_ip.type },
5580
+ message: "must be string,null"
5581
+ };
5582
+ if (vErrors === null) vErrors = [err40];
5583
+ else vErrors.push(err40);
5584
+ errors++;
5585
+ }
5586
+ }
5587
+ if (data17.count !== void 0) {
5588
+ let data19 = data17.count;
5589
+ if (!(typeof data19 == "number" && !(data19 % 1) && !isNaN(data19))) {
5590
+ const err41 = {
5591
+ instancePath: instancePath + "/records/" + i0 + "/count",
5592
+ schemaPath: "#/definitions/DmarcRecord/properties/count/type",
5593
+ keyword: "type",
5594
+ params: { type: "integer" },
5595
+ message: "must be integer"
5596
+ };
5597
+ if (vErrors === null) vErrors = [err41];
5598
+ else vErrors.push(err41);
5599
+ errors++;
5600
+ }
5601
+ }
5602
+ if (data17.disposition !== void 0) {
5603
+ let data20 = data17.disposition;
5604
+ if (typeof data20 !== "string" && data20 !== null) {
5605
+ const err42 = {
5606
+ instancePath: instancePath + "/records/" + i0 + "/disposition",
5607
+ schemaPath: "#/definitions/DmarcRecord/properties/disposition/type",
5608
+ keyword: "type",
5609
+ params: { type: schema44.properties.disposition.type },
5610
+ message: "must be string,null"
5611
+ };
5612
+ if (vErrors === null) vErrors = [err42];
5613
+ else vErrors.push(err42);
5614
+ errors++;
5615
+ }
5616
+ }
5617
+ if (data17.dkim !== void 0) {
5618
+ let data21 = data17.dkim;
5619
+ if (typeof data21 !== "string" && data21 !== null) {
5620
+ const err43 = {
5621
+ instancePath: instancePath + "/records/" + i0 + "/dkim",
5622
+ schemaPath: "#/definitions/DmarcRecord/properties/dkim/type",
5623
+ keyword: "type",
5624
+ params: { type: schema44.properties.dkim.type },
5625
+ message: "must be string,null"
5626
+ };
5627
+ if (vErrors === null) vErrors = [err43];
5628
+ else vErrors.push(err43);
5629
+ errors++;
5630
+ }
5631
+ }
5632
+ if (data17.spf !== void 0) {
5633
+ let data22 = data17.spf;
5634
+ if (typeof data22 !== "string" && data22 !== null) {
5635
+ const err44 = {
5636
+ instancePath: instancePath + "/records/" + i0 + "/spf",
5637
+ schemaPath: "#/definitions/DmarcRecord/properties/spf/type",
5638
+ keyword: "type",
5639
+ params: { type: schema44.properties.spf.type },
5640
+ message: "must be string,null"
5641
+ };
5642
+ if (vErrors === null) vErrors = [err44];
5643
+ else vErrors.push(err44);
5644
+ errors++;
5645
+ }
5646
+ }
5647
+ if (data17.header_from !== void 0) {
5648
+ let data23 = data17.header_from;
5649
+ if (typeof data23 !== "string" && data23 !== null) {
5650
+ const err45 = {
5651
+ instancePath: instancePath + "/records/" + i0 + "/header_from",
5652
+ schemaPath: "#/definitions/DmarcRecord/properties/header_from/type",
5653
+ keyword: "type",
5654
+ params: { type: schema44.properties.header_from.type },
5655
+ message: "must be string,null"
5656
+ };
5657
+ if (vErrors === null) vErrors = [err45];
5658
+ else vErrors.push(err45);
5659
+ errors++;
5660
+ }
5661
+ }
5662
+ } else {
5663
+ const err46 = {
5664
+ instancePath: instancePath + "/records/" + i0,
5665
+ schemaPath: "#/definitions/DmarcRecord/type",
5666
+ keyword: "type",
5667
+ params: { type: "object" },
5668
+ message: "must be object"
5669
+ };
5670
+ if (vErrors === null) vErrors = [err46];
5671
+ else vErrors.push(err46);
5672
+ errors++;
5673
+ }
5674
+ }
5675
+ } else {
5676
+ const err47 = {
5677
+ instancePath: instancePath + "/records",
5678
+ schemaPath: "#/properties/records/type",
5679
+ keyword: "type",
5680
+ params: { type: "array" },
5681
+ message: "must be array"
5682
+ };
5683
+ if (vErrors === null) vErrors = [err47];
5684
+ else vErrors.push(err47);
5685
+ errors++;
5686
+ }
5687
+ }
5688
+ } else {
5689
+ const err48 = {
5690
+ instancePath,
5691
+ schemaPath: "#/type",
5692
+ keyword: "type",
5693
+ params: { type: "object" },
5694
+ message: "must be object"
5695
+ };
5696
+ if (vErrors === null) vErrors = [err48];
5697
+ else vErrors.push(err48);
5698
+ errors++;
5699
+ }
5700
+ validate36.errors = vErrors;
5701
+ return errors === 0;
5702
+ }
5703
+ function validate20(data, { instancePath = "", parentData, parentDataProperty, rootData = data } = {}) {
5704
+ let vErrors = null;
5705
+ let errors = 0;
5706
+ if (data && typeof data == "object" && !Array.isArray(data)) {
5707
+ if (data.spamassassin !== void 0) {
5708
+ let data0 = data.spamassassin;
5709
+ if (data0 && typeof data0 == "object" && !Array.isArray(data0)) {
5710
+ if (data0.score === void 0) {
5711
+ const err0 = {
5712
+ instancePath: instancePath + "/spamassassin",
5713
+ schemaPath: "#/properties/spamassassin/required",
5714
+ keyword: "required",
5715
+ params: { missingProperty: "score" },
5716
+ message: "must have required property 'score'"
5717
+ };
5718
+ if (vErrors === null) vErrors = [err0];
5719
+ else vErrors.push(err0);
5720
+ errors++;
5721
+ }
5722
+ if (data0.score !== void 0) {
5723
+ if (!(typeof data0.score == "number")) {
5724
+ const err1 = {
5725
+ instancePath: instancePath + "/spamassassin/score",
5726
+ schemaPath: "#/properties/spamassassin/properties/score/type",
5727
+ keyword: "type",
5728
+ params: { type: "number" },
5729
+ message: "must be number"
5730
+ };
5731
+ if (vErrors === null) vErrors = [err1];
5732
+ else vErrors.push(err1);
5733
+ errors++;
5734
+ }
5735
+ }
5736
+ } else {
5737
+ const err2 = {
5738
+ instancePath: instancePath + "/spamassassin",
5739
+ schemaPath: "#/properties/spamassassin/type",
5740
+ keyword: "type",
5741
+ params: { type: "object" },
5742
+ message: "must be object"
5743
+ };
5744
+ if (vErrors === null) vErrors = [err2];
5745
+ else vErrors.push(err2);
5746
+ errors++;
5747
+ }
5748
+ }
5749
+ if (data.forward !== void 0) {
5750
+ if (!validate21(data.forward, {
5751
+ instancePath: instancePath + "/forward",
5752
+ parentData: data,
5753
+ parentDataProperty: "forward",
5754
+ rootData
5755
+ })) {
5756
+ vErrors = vErrors === null ? validate21.errors : vErrors.concat(validate21.errors);
5757
+ errors = vErrors.length;
5758
+ }
5759
+ }
5760
+ if (data.bounce !== void 0) {
5761
+ let data3 = data.bounce;
5762
+ if (data3 && typeof data3 == "object" && !Array.isArray(data3)) {
5763
+ if (data3.is_bounce === void 0) {
5764
+ const err3 = {
5765
+ instancePath: instancePath + "/bounce",
5766
+ schemaPath: "#/definitions/BounceAnalysis/required",
5767
+ keyword: "required",
5768
+ params: { missingProperty: "is_bounce" },
5769
+ message: "must have required property 'is_bounce'"
5770
+ };
5771
+ if (vErrors === null) vErrors = [err3];
5772
+ else vErrors.push(err3);
5773
+ errors++;
5774
+ }
5775
+ if (data3.kind === void 0) {
5776
+ const err4 = {
5777
+ instancePath: instancePath + "/bounce",
5778
+ schemaPath: "#/definitions/BounceAnalysis/required",
5779
+ keyword: "required",
5780
+ params: { missingProperty: "kind" },
5781
+ message: "must have required property 'kind'"
5782
+ };
5783
+ if (vErrors === null) vErrors = [err4];
5784
+ else vErrors.push(err4);
5785
+ errors++;
5786
+ }
5787
+ if (data3.type === void 0) {
5788
+ const err5 = {
5789
+ instancePath: instancePath + "/bounce",
5790
+ schemaPath: "#/definitions/BounceAnalysis/required",
5791
+ keyword: "required",
5792
+ params: { missingProperty: "type" },
5793
+ message: "must have required property 'type'"
5794
+ };
5795
+ if (vErrors === null) vErrors = [err5];
5796
+ else vErrors.push(err5);
5797
+ errors++;
5798
+ }
5799
+ if (data3.category === void 0) {
5800
+ const err6 = {
5801
+ instancePath: instancePath + "/bounce",
5802
+ schemaPath: "#/definitions/BounceAnalysis/required",
5803
+ keyword: "required",
5804
+ params: { missingProperty: "category" },
5805
+ message: "must have required property 'category'"
5806
+ };
5807
+ if (vErrors === null) vErrors = [err6];
5808
+ else vErrors.push(err6);
5809
+ errors++;
5810
+ }
5811
+ if (data3.classified_by === void 0) {
5812
+ const err7 = {
5813
+ instancePath: instancePath + "/bounce",
5814
+ schemaPath: "#/definitions/BounceAnalysis/required",
5815
+ keyword: "required",
5816
+ params: { missingProperty: "classified_by" },
5817
+ message: "must have required property 'classified_by'"
5818
+ };
5819
+ if (vErrors === null) vErrors = [err7];
5820
+ else vErrors.push(err7);
5821
+ errors++;
5822
+ }
5823
+ if (data3.failed_recipient === void 0) {
5824
+ const err8 = {
5825
+ instancePath: instancePath + "/bounce",
5826
+ schemaPath: "#/definitions/BounceAnalysis/required",
5827
+ keyword: "required",
5828
+ params: { missingProperty: "failed_recipient" },
5829
+ message: "must have required property 'failed_recipient'"
5830
+ };
5831
+ if (vErrors === null) vErrors = [err8];
5832
+ else vErrors.push(err8);
5833
+ errors++;
5834
+ }
5835
+ if (data3.smtp_code === void 0) {
5836
+ const err9 = {
5837
+ instancePath: instancePath + "/bounce",
5838
+ schemaPath: "#/definitions/BounceAnalysis/required",
5839
+ keyword: "required",
5840
+ params: { missingProperty: "smtp_code" },
5841
+ message: "must have required property 'smtp_code'"
5842
+ };
5843
+ if (vErrors === null) vErrors = [err9];
5844
+ else vErrors.push(err9);
5845
+ errors++;
5846
+ }
5847
+ if (data3.status_code === void 0) {
5848
+ const err10 = {
5849
+ instancePath: instancePath + "/bounce",
5850
+ schemaPath: "#/definitions/BounceAnalysis/required",
5851
+ keyword: "required",
5852
+ params: { missingProperty: "status_code" },
5853
+ message: "must have required property 'status_code'"
5854
+ };
5855
+ if (vErrors === null) vErrors = [err10];
5856
+ else vErrors.push(err10);
5857
+ errors++;
5858
+ }
5859
+ if (data3.diagnostic_code === void 0) {
5860
+ const err11 = {
5861
+ instancePath: instancePath + "/bounce",
5862
+ schemaPath: "#/definitions/BounceAnalysis/required",
5863
+ keyword: "required",
5864
+ params: { missingProperty: "diagnostic_code" },
5865
+ message: "must have required property 'diagnostic_code'"
5866
+ };
5867
+ if (vErrors === null) vErrors = [err11];
5868
+ else vErrors.push(err11);
5869
+ errors++;
5870
+ }
5871
+ if (data3.reported_by_mta === void 0) {
5872
+ const err12 = {
5873
+ instancePath: instancePath + "/bounce",
5874
+ schemaPath: "#/definitions/BounceAnalysis/required",
5875
+ keyword: "required",
5876
+ params: { missingProperty: "reported_by_mta" },
5877
+ message: "must have required property 'reported_by_mta'"
5878
+ };
5879
+ if (vErrors === null) vErrors = [err12];
5880
+ else vErrors.push(err12);
5881
+ errors++;
5882
+ }
5883
+ if (data3.original_message_id === void 0) {
5884
+ const err13 = {
5885
+ instancePath: instancePath + "/bounce",
5886
+ schemaPath: "#/definitions/BounceAnalysis/required",
5887
+ keyword: "required",
5888
+ params: { missingProperty: "original_message_id" },
5889
+ message: "must have required property 'original_message_id'"
5890
+ };
5891
+ if (vErrors === null) vErrors = [err13];
5892
+ else vErrors.push(err13);
5893
+ errors++;
5894
+ }
5895
+ if (data3.reasons === void 0) {
5896
+ const err14 = {
5897
+ instancePath: instancePath + "/bounce",
5898
+ schemaPath: "#/definitions/BounceAnalysis/required",
5899
+ keyword: "required",
5900
+ params: { missingProperty: "reasons" },
5901
+ message: "must have required property 'reasons'"
5902
+ };
5903
+ if (vErrors === null) vErrors = [err14];
5904
+ else vErrors.push(err14);
5905
+ errors++;
5906
+ }
5907
+ if (data3.is_bounce !== void 0) {
5908
+ let data4 = data3.is_bounce;
5909
+ if (typeof data4 !== "boolean") {
5910
+ const err15 = {
5911
+ instancePath: instancePath + "/bounce/is_bounce",
5912
+ schemaPath: "#/definitions/BounceAnalysis/properties/is_bounce/type",
5913
+ keyword: "type",
5914
+ params: { type: "boolean" },
5915
+ message: "must be boolean"
5916
+ };
5917
+ if (vErrors === null) vErrors = [err15];
5918
+ else vErrors.push(err15);
5919
+ errors++;
5920
+ }
5921
+ if (true !== data4) {
5922
+ const err16 = {
5923
+ instancePath: instancePath + "/bounce/is_bounce",
5924
+ schemaPath: "#/definitions/BounceAnalysis/properties/is_bounce/const",
5925
+ keyword: "const",
5926
+ params: { allowedValue: true },
5927
+ message: "must be equal to constant"
5928
+ };
5929
+ if (vErrors === null) vErrors = [err16];
5930
+ else vErrors.push(err16);
5931
+ errors++;
5932
+ }
5933
+ }
5934
+ if (data3.kind !== void 0) {
5935
+ let data5 = data3.kind;
5936
+ if (typeof data5 !== "string") {
5937
+ const err17 = {
5938
+ instancePath: instancePath + "/bounce/kind",
5939
+ schemaPath: "#/definitions/BounceAnalysis/properties/kind/type",
5940
+ keyword: "type",
5941
+ params: { type: "string" },
5942
+ message: "must be string"
5943
+ };
5944
+ if (vErrors === null) vErrors = [err17];
5945
+ else vErrors.push(err17);
5946
+ errors++;
5947
+ }
5948
+ if ("dsn" !== data5) {
5949
+ const err18 = {
5950
+ instancePath: instancePath + "/bounce/kind",
5951
+ schemaPath: "#/definitions/BounceAnalysis/properties/kind/const",
5952
+ keyword: "const",
5953
+ params: { allowedValue: "dsn" },
5954
+ message: "must be equal to constant"
5955
+ };
5956
+ if (vErrors === null) vErrors = [err18];
5957
+ else vErrors.push(err18);
5958
+ errors++;
5959
+ }
5960
+ }
5961
+ if (data3.type !== void 0) {
5962
+ let data6 = data3.type;
5963
+ if (typeof data6 !== "string") {
5964
+ const err19 = {
5965
+ instancePath: instancePath + "/bounce/type",
5966
+ schemaPath: "#/definitions/BounceAnalysis/properties/type/type",
5967
+ keyword: "type",
5968
+ params: { type: "string" },
5969
+ message: "must be string"
5970
+ };
5971
+ if (vErrors === null) vErrors = [err19];
5972
+ else vErrors.push(err19);
5973
+ errors++;
5974
+ }
5975
+ if (!(data6 === "permanent" || data6 === "transient" || data6 === "undetermined")) {
5976
+ const err20 = {
5977
+ instancePath: instancePath + "/bounce/type",
5978
+ schemaPath: "#/definitions/BounceAnalysis/properties/type/enum",
5979
+ keyword: "enum",
5980
+ params: { allowedValues: schema39.properties.type.enum },
5981
+ message: "must be equal to one of the allowed values"
5982
+ };
5983
+ if (vErrors === null) vErrors = [err20];
5984
+ else vErrors.push(err20);
5985
+ errors++;
5986
+ }
5987
+ }
5988
+ if (data3.category !== void 0) {
5989
+ let data7 = data3.category;
5990
+ if (typeof data7 !== "string") {
5991
+ const err21 = {
5992
+ instancePath: instancePath + "/bounce/category",
5993
+ schemaPath: "#/definitions/BounceAnalysis/properties/category/type",
5994
+ keyword: "type",
5995
+ params: { type: "string" },
5996
+ message: "must be string"
5997
+ };
5998
+ if (vErrors === null) vErrors = [err21];
5999
+ else vErrors.push(err21);
6000
+ errors++;
6001
+ }
6002
+ if (!(data7 === "mailbox_does_not_exist" || data7 === "domain_does_not_exist" || data7 === "domain_not_accepting_mail" || data7 === "mailbox_full" || data7 === "mailbox_inactive" || data7 === "message_too_large" || data7 === "content_rejected" || data7 === "policy_blocked" || data7 === "auth_failure" || data7 === "relay_denied" || data7 === "rate_limited" || data7 === "network_error" || data7 === "recipient_moved" || data7 === "expired" || data7 === "undetermined")) {
6003
+ const err22 = {
6004
+ instancePath: instancePath + "/bounce/category",
6005
+ schemaPath: "#/definitions/BounceAnalysis/properties/category/enum",
6006
+ keyword: "enum",
6007
+ params: { allowedValues: schema39.properties.category.enum },
6008
+ message: "must be equal to one of the allowed values"
6009
+ };
6010
+ if (vErrors === null) vErrors = [err22];
6011
+ else vErrors.push(err22);
6012
+ errors++;
6013
+ }
6014
+ }
6015
+ if (data3.classified_by !== void 0) {
6016
+ let data8 = data3.classified_by;
6017
+ if (typeof data8 !== "string") {
6018
+ const err23 = {
6019
+ instancePath: instancePath + "/bounce/classified_by",
6020
+ schemaPath: "#/definitions/BounceAnalysis/properties/classified_by/type",
6021
+ keyword: "type",
6022
+ params: { type: "string" },
6023
+ message: "must be string"
6024
+ };
6025
+ if (vErrors === null) vErrors = [err23];
6026
+ else vErrors.push(err23);
6027
+ errors++;
6028
+ }
6029
+ if (!(data8 === "status_code" || data8 === "smtp_code" || data8 === "pattern" || data8 === "provider" || data8 === "none")) {
6030
+ const err24 = {
6031
+ instancePath: instancePath + "/bounce/classified_by",
6032
+ schemaPath: "#/definitions/BounceAnalysis/properties/classified_by/enum",
6033
+ keyword: "enum",
6034
+ params: { allowedValues: schema39.properties.classified_by.enum },
6035
+ message: "must be equal to one of the allowed values"
6036
+ };
6037
+ if (vErrors === null) vErrors = [err24];
6038
+ else vErrors.push(err24);
6039
+ errors++;
6040
+ }
6041
+ }
6042
+ if (data3.failed_recipient !== void 0) {
6043
+ let data9 = data3.failed_recipient;
6044
+ if (typeof data9 !== "string" && data9 !== null) {
6045
+ const err25 = {
6046
+ instancePath: instancePath + "/bounce/failed_recipient",
6047
+ schemaPath: "#/definitions/BounceAnalysis/properties/failed_recipient/type",
6048
+ keyword: "type",
6049
+ params: { type: schema39.properties.failed_recipient.type },
6050
+ message: "must be string,null"
6051
+ };
6052
+ if (vErrors === null) vErrors = [err25];
6053
+ else vErrors.push(err25);
6054
+ errors++;
6055
+ }
6056
+ }
6057
+ if (data3.smtp_code !== void 0) {
6058
+ let data10 = data3.smtp_code;
6059
+ if (!(typeof data10 == "number" && !(data10 % 1) && !isNaN(data10)) && data10 !== null) {
6060
+ const err26 = {
6061
+ instancePath: instancePath + "/bounce/smtp_code",
6062
+ schemaPath: "#/definitions/BounceAnalysis/properties/smtp_code/type",
6063
+ keyword: "type",
6064
+ params: { type: schema39.properties.smtp_code.type },
6065
+ message: "must be integer,null"
6066
+ };
6067
+ if (vErrors === null) vErrors = [err26];
6068
+ else vErrors.push(err26);
6069
+ errors++;
6070
+ }
6071
+ }
6072
+ if (data3.status_code !== void 0) {
6073
+ let data11 = data3.status_code;
6074
+ if (typeof data11 !== "string" && data11 !== null) {
6075
+ const err27 = {
6076
+ instancePath: instancePath + "/bounce/status_code",
6077
+ schemaPath: "#/definitions/BounceAnalysis/properties/status_code/type",
6078
+ keyword: "type",
6079
+ params: { type: schema39.properties.status_code.type },
6080
+ message: "must be string,null"
6081
+ };
6082
+ if (vErrors === null) vErrors = [err27];
6083
+ else vErrors.push(err27);
6084
+ errors++;
6085
+ }
6086
+ }
6087
+ if (data3.diagnostic_code !== void 0) {
6088
+ let data12 = data3.diagnostic_code;
6089
+ if (typeof data12 !== "string" && data12 !== null) {
6090
+ const err28 = {
6091
+ instancePath: instancePath + "/bounce/diagnostic_code",
6092
+ schemaPath: "#/definitions/BounceAnalysis/properties/diagnostic_code/type",
6093
+ keyword: "type",
6094
+ params: { type: schema39.properties.diagnostic_code.type },
6095
+ message: "must be string,null"
6096
+ };
6097
+ if (vErrors === null) vErrors = [err28];
6098
+ else vErrors.push(err28);
6099
+ errors++;
6100
+ }
6101
+ }
6102
+ if (data3.reported_by_mta !== void 0) {
6103
+ let data13 = data3.reported_by_mta;
6104
+ if (typeof data13 !== "string" && data13 !== null) {
6105
+ const err29 = {
6106
+ instancePath: instancePath + "/bounce/reported_by_mta",
6107
+ schemaPath: "#/definitions/BounceAnalysis/properties/reported_by_mta/type",
6108
+ keyword: "type",
6109
+ params: { type: schema39.properties.reported_by_mta.type },
6110
+ message: "must be string,null"
6111
+ };
6112
+ if (vErrors === null) vErrors = [err29];
6113
+ else vErrors.push(err29);
6114
+ errors++;
6115
+ }
6116
+ }
6117
+ if (data3.original_message_id !== void 0) {
6118
+ let data14 = data3.original_message_id;
6119
+ if (typeof data14 !== "string" && data14 !== null) {
6120
+ const err30 = {
6121
+ instancePath: instancePath + "/bounce/original_message_id",
6122
+ schemaPath: "#/definitions/BounceAnalysis/properties/original_message_id/type",
6123
+ keyword: "type",
6124
+ params: { type: schema39.properties.original_message_id.type },
6125
+ message: "must be string,null"
6126
+ };
6127
+ if (vErrors === null) vErrors = [err30];
6128
+ else vErrors.push(err30);
6129
+ errors++;
6130
+ }
6131
+ }
6132
+ if (data3.reasons !== void 0) {
6133
+ let data15 = data3.reasons;
6134
+ if (Array.isArray(data15)) {
6135
+ const len0 = data15.length;
6136
+ for (let i0 = 0; i0 < len0; i0++) if (typeof data15[i0] !== "string") {
6137
+ const err31 = {
6138
+ instancePath: instancePath + "/bounce/reasons/" + i0,
6139
+ schemaPath: "#/definitions/BounceAnalysis/properties/reasons/items/type",
6140
+ keyword: "type",
6141
+ params: { type: "string" },
6142
+ message: "must be string"
6143
+ };
6144
+ if (vErrors === null) vErrors = [err31];
6145
+ else vErrors.push(err31);
6146
+ errors++;
6147
+ }
6148
+ } else {
6149
+ const err32 = {
6150
+ instancePath: instancePath + "/bounce/reasons",
6151
+ schemaPath: "#/definitions/BounceAnalysis/properties/reasons/type",
6152
+ keyword: "type",
6153
+ params: { type: "array" },
6154
+ message: "must be array"
6155
+ };
6156
+ if (vErrors === null) vErrors = [err32];
6157
+ else vErrors.push(err32);
6158
+ errors++;
6159
+ }
6160
+ }
6161
+ } else {
6162
+ const err33 = {
6163
+ instancePath: instancePath + "/bounce",
6164
+ schemaPath: "#/definitions/BounceAnalysis/type",
6165
+ keyword: "type",
6166
+ params: { type: "object" },
6167
+ message: "must be object"
6168
+ };
6169
+ if (vErrors === null) vErrors = [err33];
6170
+ else vErrors.push(err33);
6171
+ errors++;
6172
+ }
6173
+ }
6174
+ if (data.tls_report !== void 0) {
6175
+ if (!validate32(data.tls_report, {
6176
+ instancePath: instancePath + "/tls_report",
6177
+ parentData: data,
6178
+ parentDataProperty: "tls_report",
6179
+ rootData
6180
+ })) {
6181
+ vErrors = vErrors === null ? validate32.errors : vErrors.concat(validate32.errors);
6182
+ errors = vErrors.length;
6183
+ }
6184
+ }
6185
+ if (data.dmarc_report !== void 0) {
6186
+ if (!validate36(data.dmarc_report, {
6187
+ instancePath: instancePath + "/dmarc_report",
6188
+ parentData: data,
6189
+ parentDataProperty: "dmarc_report",
6190
+ rootData
6191
+ })) {
6192
+ vErrors = vErrors === null ? validate36.errors : vErrors.concat(validate36.errors);
6193
+ errors = vErrors.length;
6194
+ }
6195
+ }
6196
+ } else {
6197
+ const err34 = {
6198
+ instancePath,
6199
+ schemaPath: "#/type",
6200
+ keyword: "type",
6201
+ params: { type: "object" },
6202
+ message: "must be object"
6203
+ };
6204
+ if (vErrors === null) vErrors = [err34];
6205
+ else vErrors.push(err34);
6206
+ errors++;
6207
+ }
6208
+ validate20.errors = vErrors;
6209
+ return errors === 0;
6210
+ }
6211
+ const schema45 = {
6212
+ "type": "object",
6213
+ "properties": {
6214
+ "spf": {
6215
+ "$ref": "#/definitions/SpfResult",
6216
+ "description": "SPF verification result.\n\nSPF checks if the sending IP is authorized by the envelope sender's domain. \"pass\" means the IP is authorized; \"fail\" means it's explicitly not allowed."
6217
+ },
6218
+ "dmarc": {
6219
+ "$ref": "#/definitions/DmarcResult",
6220
+ "description": "DMARC verification result.\n\nDMARC passes if either SPF or DKIM passes AND aligns with the From: domain. \"pass\" means the email is authenticated according to the sender's policy."
6221
+ },
6222
+ "dmarcPolicy": {
6223
+ "$ref": "#/definitions/DmarcPolicy",
6224
+ "description": "DMARC policy from the sender's DNS record.\n\n- `reject`: Domain wants receivers to reject failing emails\n- `quarantine`: Domain wants failing emails marked as suspicious\n- `none`: Domain is monitoring only (no action requested)\n- `null`: No DMARC record found for this domain"
6225
+ },
6226
+ "dmarcFromDomain": {
6227
+ "type": ["string", "null"],
6228
+ "description": "The organizational domain used for DMARC lookups.\n\nFor example, if the From: address is `user@mail.example.com`, the DMARC lookup checks `_dmarc.mail.example.com`, then falls back to `_dmarc.example.com`. This field shows which domain's policy was used."
6229
+ },
6230
+ "dmarcSpfAligned": {
6231
+ "type": "boolean",
6232
+ "description": "Whether SPF aligned with the From: domain for DMARC purposes.\n\nTrue if the envelope sender domain matches the From: domain (per alignment mode)."
6233
+ },
6234
+ "dmarcDkimAligned": {
6235
+ "type": "boolean",
6236
+ "description": "Whether DKIM aligned with the From: domain for DMARC purposes.\n\nTrue if at least one DKIM signature's domain matches the From: domain."
6237
+ },
6238
+ "dmarcSpfStrict": {
6239
+ "type": ["boolean", "null"],
6240
+ "description": "Whether DMARC SPF alignment mode is strict.\n\n- `true`: Strict alignment required (exact domain match)\n- `false`: Relaxed alignment allowed (organizational domain match)\n- `null`: No DMARC record found"
6241
+ },
6242
+ "dmarcDkimStrict": {
6243
+ "type": ["boolean", "null"],
6244
+ "description": "Whether DMARC DKIM alignment mode is strict.\n\n- `true`: Strict alignment required (exact domain match)\n- `false`: Relaxed alignment allowed (organizational domain match)\n- `null`: No DMARC record found"
6245
+ },
6246
+ "dkimSignatures": {
6247
+ "type": "array",
6248
+ "items": { "$ref": "#/definitions/DkimSignature" },
6249
+ "description": "All DKIM signatures found in the email with their verification results.\n\nMay be empty if no DKIM signatures were present."
6250
+ }
6251
+ },
6252
+ "required": [
6253
+ "spf",
6254
+ "dmarc",
6255
+ "dmarcPolicy",
6256
+ "dmarcFromDomain",
6257
+ "dmarcSpfAligned",
6258
+ "dmarcDkimAligned",
6259
+ "dmarcSpfStrict",
6260
+ "dmarcDkimStrict",
6261
+ "dkimSignatures"
6262
+ ],
6263
+ "description": "Email authentication results for SPF, DKIM, and DMARC.\n\nUse `validateEmailAuth()` to compute a verdict based on these results."
6264
+ };
6265
+ const schema46 = {
6266
+ "type": "string",
6267
+ "enum": [
6268
+ "pass",
6269
+ "fail",
6270
+ "softfail",
6271
+ "neutral",
6272
+ "none",
6273
+ "temperror",
6274
+ "permerror"
6275
+ ],
6276
+ "description": "SPF verification result."
6277
+ };
6278
+ const schema47 = {
6279
+ "type": "string",
6280
+ "enum": [
6281
+ "pass",
6282
+ "fail",
6283
+ "none",
6284
+ "temperror",
6285
+ "permerror"
6286
+ ],
6287
+ "description": "DMARC verification result."
6288
+ };
6289
+ const schema49 = {
6290
+ "type": "object",
6291
+ "properties": {
6292
+ "domain": {
6293
+ "type": "string",
6294
+ "description": "The domain that signed this DKIM signature (d= tag). This may differ from the From: domain (that's what alignment checks)."
6295
+ },
6296
+ "selector": {
6297
+ "type": ["string", "null"],
6298
+ "description": "The DKIM selector used to locate the public key (s= tag). Combined with the domain to form the DNS lookup: `selector._domainkey.domain`\n\nOptional in self-hosted environments where the milter may not provide selector info."
6299
+ },
6300
+ "result": {
6301
+ "$ref": "#/definitions/DkimResult",
6302
+ "description": "Verification result for this specific signature."
6303
+ },
6304
+ "aligned": {
6305
+ "type": "boolean",
6306
+ "description": "Whether this signature's domain aligns with the From: domain (for DMARC).\n\nAlignment can be \"strict\" (exact match) or \"relaxed\" (organizational domain match). For example, if From: is `user@sub.example.com` and DKIM is signed by `example.com`:\n- Relaxed alignment: true (same organizational domain)\n- Strict alignment: false (not exact match)"
6307
+ },
6308
+ "keyBits": {
6309
+ "type": ["integer", "null"],
6310
+ "minimum": 1,
6311
+ "maximum": 16384,
6312
+ "description": "Key size in bits (e.g., 1024, 2048). Null if the key size couldn't be determined.\n\nOptional in self-hosted environments."
6313
+ },
6314
+ "algo": {
6315
+ "type": ["string", "null"],
6316
+ "description": "Signing algorithm (e.g., \"rsa-sha256\", \"ed25519-sha256\").\n\nOptional in self-hosted environments."
6317
+ }
6318
+ },
6319
+ "required": [
6320
+ "domain",
6321
+ "selector",
6322
+ "result",
6323
+ "aligned",
6324
+ "keyBits",
6325
+ "algo"
6326
+ ],
6327
+ "description": "Details about a single DKIM signature found in the email.\n\nAn email may have multiple DKIM signatures (e.g., one from the sending domain and one from the ESP). Each signature is verified independently."
6328
+ };
6329
+ const schema50 = {
6330
+ "type": "string",
6331
+ "enum": [
6332
+ "pass",
6333
+ "fail",
6334
+ "temperror",
6335
+ "permerror"
6336
+ ],
6337
+ "description": "DKIM signature verification result for a single signature."
6338
+ };
6339
+ function validate40(data, { instancePath = "", parentData, parentDataProperty, rootData = data } = {}) {
6340
+ let vErrors = null;
6341
+ let errors = 0;
6342
+ if (data && typeof data == "object" && !Array.isArray(data)) {
6343
+ if (data.domain === void 0) {
6344
+ const err0 = {
6345
+ instancePath,
6346
+ schemaPath: "#/required",
6347
+ keyword: "required",
6348
+ params: { missingProperty: "domain" },
6349
+ message: "must have required property 'domain'"
6350
+ };
6351
+ if (vErrors === null) vErrors = [err0];
6352
+ else vErrors.push(err0);
6353
+ errors++;
6354
+ }
6355
+ if (data.selector === void 0) {
6356
+ const err1 = {
6357
+ instancePath,
6358
+ schemaPath: "#/required",
6359
+ keyword: "required",
6360
+ params: { missingProperty: "selector" },
6361
+ message: "must have required property 'selector'"
6362
+ };
6363
+ if (vErrors === null) vErrors = [err1];
6364
+ else vErrors.push(err1);
6365
+ errors++;
6366
+ }
6367
+ if (data.result === void 0) {
6368
+ const err2 = {
6369
+ instancePath,
6370
+ schemaPath: "#/required",
6371
+ keyword: "required",
6372
+ params: { missingProperty: "result" },
6373
+ message: "must have required property 'result'"
6374
+ };
6375
+ if (vErrors === null) vErrors = [err2];
6376
+ else vErrors.push(err2);
6377
+ errors++;
6378
+ }
6379
+ if (data.aligned === void 0) {
6380
+ const err3 = {
6381
+ instancePath,
6382
+ schemaPath: "#/required",
6383
+ keyword: "required",
6384
+ params: { missingProperty: "aligned" },
6385
+ message: "must have required property 'aligned'"
6386
+ };
6387
+ if (vErrors === null) vErrors = [err3];
6388
+ else vErrors.push(err3);
6389
+ errors++;
6390
+ }
6391
+ if (data.keyBits === void 0) {
6392
+ const err4 = {
6393
+ instancePath,
6394
+ schemaPath: "#/required",
6395
+ keyword: "required",
6396
+ params: { missingProperty: "keyBits" },
6397
+ message: "must have required property 'keyBits'"
6398
+ };
6399
+ if (vErrors === null) vErrors = [err4];
6400
+ else vErrors.push(err4);
6401
+ errors++;
6402
+ }
6403
+ if (data.algo === void 0) {
6404
+ const err5 = {
6405
+ instancePath,
6406
+ schemaPath: "#/required",
6407
+ keyword: "required",
4399
6408
  params: { missingProperty: "algo" },
4400
6409
  message: "must have required property 'algo'"
4401
6410
  };
@@ -4424,7 +6433,7 @@ function validate34(data, { instancePath = "", parentData, parentDataProperty, r
4424
6433
  instancePath: instancePath + "/selector",
4425
6434
  schemaPath: "#/properties/selector/type",
4426
6435
  keyword: "type",
4427
- params: { type: schema43.properties.selector.type },
6436
+ params: { type: schema49.properties.selector.type },
4428
6437
  message: "must be string,null"
4429
6438
  };
4430
6439
  if (vErrors === null) vErrors = [err7];
@@ -4451,7 +6460,7 @@ function validate34(data, { instancePath = "", parentData, parentDataProperty, r
4451
6460
  instancePath: instancePath + "/result",
4452
6461
  schemaPath: "#/definitions/DkimResult/enum",
4453
6462
  keyword: "enum",
4454
- params: { allowedValues: schema44.enum },
6463
+ params: { allowedValues: schema50.enum },
4455
6464
  message: "must be equal to one of the allowed values"
4456
6465
  };
4457
6466
  if (vErrors === null) vErrors = [err9];
@@ -4480,7 +6489,7 @@ function validate34(data, { instancePath = "", parentData, parentDataProperty, r
4480
6489
  instancePath: instancePath + "/keyBits",
4481
6490
  schemaPath: "#/properties/keyBits/type",
4482
6491
  keyword: "type",
4483
- params: { type: schema43.properties.keyBits.type },
6492
+ params: { type: schema49.properties.keyBits.type },
4484
6493
  message: "must be integer,null"
4485
6494
  };
4486
6495
  if (vErrors === null) vErrors = [err11];
@@ -4527,7 +6536,7 @@ function validate34(data, { instancePath = "", parentData, parentDataProperty, r
4527
6536
  instancePath: instancePath + "/algo",
4528
6537
  schemaPath: "#/properties/algo/type",
4529
6538
  keyword: "type",
4530
- params: { type: schema43.properties.algo.type },
6539
+ params: { type: schema49.properties.algo.type },
4531
6540
  message: "must be string,null"
4532
6541
  };
4533
6542
  if (vErrors === null) vErrors = [err14];
@@ -4547,10 +6556,10 @@ function validate34(data, { instancePath = "", parentData, parentDataProperty, r
4547
6556
  else vErrors.push(err15);
4548
6557
  errors++;
4549
6558
  }
4550
- validate34.errors = vErrors;
6559
+ validate40.errors = vErrors;
4551
6560
  return errors === 0;
4552
6561
  }
4553
- function validate33(data, { instancePath = "", parentData, parentDataProperty, rootData = data } = {}) {
6562
+ function validate39(data, { instancePath = "", parentData, parentDataProperty, rootData = data } = {}) {
4554
6563
  let vErrors = null;
4555
6564
  let errors = 0;
4556
6565
  if (data && typeof data == "object" && !Array.isArray(data)) {
@@ -4681,7 +6690,7 @@ function validate33(data, { instancePath = "", parentData, parentDataProperty, r
4681
6690
  instancePath: instancePath + "/spf",
4682
6691
  schemaPath: "#/definitions/SpfResult/enum",
4683
6692
  keyword: "enum",
4684
- params: { allowedValues: schema40.enum },
6693
+ params: { allowedValues: schema46.enum },
4685
6694
  message: "must be equal to one of the allowed values"
4686
6695
  };
4687
6696
  if (vErrors === null) vErrors = [err10];
@@ -4708,7 +6717,7 @@ function validate33(data, { instancePath = "", parentData, parentDataProperty, r
4708
6717
  instancePath: instancePath + "/dmarc",
4709
6718
  schemaPath: "#/definitions/DmarcResult/enum",
4710
6719
  keyword: "enum",
4711
- params: { allowedValues: schema41.enum },
6720
+ params: { allowedValues: schema47.enum },
4712
6721
  message: "must be equal to one of the allowed values"
4713
6722
  };
4714
6723
  if (vErrors === null) vErrors = [err12];
@@ -4750,7 +6759,7 @@ function validate33(data, { instancePath = "", parentData, parentDataProperty, r
4750
6759
  instancePath: instancePath + "/dmarcFromDomain",
4751
6760
  schemaPath: "#/properties/dmarcFromDomain/type",
4752
6761
  keyword: "type",
4753
- params: { type: schema39.properties.dmarcFromDomain.type },
6762
+ params: { type: schema45.properties.dmarcFromDomain.type },
4754
6763
  message: "must be string,null"
4755
6764
  };
4756
6765
  if (vErrors === null) vErrors = [err15];
@@ -4793,7 +6802,7 @@ function validate33(data, { instancePath = "", parentData, parentDataProperty, r
4793
6802
  instancePath: instancePath + "/dmarcSpfStrict",
4794
6803
  schemaPath: "#/properties/dmarcSpfStrict/type",
4795
6804
  keyword: "type",
4796
- params: { type: schema39.properties.dmarcSpfStrict.type },
6805
+ params: { type: schema45.properties.dmarcSpfStrict.type },
4797
6806
  message: "must be boolean,null"
4798
6807
  };
4799
6808
  if (vErrors === null) vErrors = [err18];
@@ -4808,7 +6817,7 @@ function validate33(data, { instancePath = "", parentData, parentDataProperty, r
4808
6817
  instancePath: instancePath + "/dmarcDkimStrict",
4809
6818
  schemaPath: "#/properties/dmarcDkimStrict/type",
4810
6819
  keyword: "type",
4811
- params: { type: schema39.properties.dmarcDkimStrict.type },
6820
+ params: { type: schema45.properties.dmarcDkimStrict.type },
4812
6821
  message: "must be boolean,null"
4813
6822
  };
4814
6823
  if (vErrors === null) vErrors = [err19];
@@ -4820,13 +6829,13 @@ function validate33(data, { instancePath = "", parentData, parentDataProperty, r
4820
6829
  let data8 = data.dkimSignatures;
4821
6830
  if (Array.isArray(data8)) {
4822
6831
  const len0 = data8.length;
4823
- for (let i0 = 0; i0 < len0; i0++) if (!validate34(data8[i0], {
6832
+ for (let i0 = 0; i0 < len0; i0++) if (!validate40(data8[i0], {
4824
6833
  instancePath: instancePath + "/dkimSignatures/" + i0,
4825
6834
  parentData: data8,
4826
6835
  parentDataProperty: i0,
4827
6836
  rootData
4828
6837
  })) {
4829
- vErrors = vErrors === null ? validate34.errors : vErrors.concat(validate34.errors);
6838
+ vErrors = vErrors === null ? validate40.errors : vErrors.concat(validate40.errors);
4830
6839
  errors = vErrors.length;
4831
6840
  }
4832
6841
  } else {
@@ -4854,7 +6863,7 @@ function validate33(data, { instancePath = "", parentData, parentDataProperty, r
4854
6863
  else vErrors.push(err21);
4855
6864
  errors++;
4856
6865
  }
4857
- validate33.errors = vErrors;
6866
+ validate39.errors = vErrors;
4858
6867
  return errors === 0;
4859
6868
  }
4860
6869
  function validate11(data, { instancePath = "", parentData, parentDataProperty, rootData = data } = {}) {
@@ -4963,13 +6972,13 @@ function validate11(data, { instancePath = "", parentData, parentDataProperty, r
4963
6972
  else vErrors.push(err7);
4964
6973
  errors++;
4965
6974
  }
4966
- if ("email.received" !== data1) {
6975
+ if (!(data1 === "email.received" || data1 === "email.bounced" || data1 === "email.tls_report" || data1 === "email.dmarc_report" || data1 === "email.dmarc_failure")) {
4967
6976
  const err8 = {
4968
6977
  instancePath: instancePath + "/event",
4969
- schemaPath: "#/properties/event/const",
4970
- keyword: "const",
4971
- params: { allowedValue: "email.received" },
4972
- message: "must be equal to constant"
6978
+ schemaPath: "#/properties/event/enum",
6979
+ keyword: "enum",
6980
+ params: { allowedValues: schema12.properties.event.enum },
6981
+ message: "must be equal to one of the allowed values"
4973
6982
  };
4974
6983
  if (vErrors === null) vErrors = [err8];
4975
6984
  else vErrors.push(err8);
@@ -5767,13 +7776,13 @@ function validate11(data, { instancePath = "", parentData, parentDataProperty, r
5767
7776
  }
5768
7777
  }
5769
7778
  if (data7.auth !== void 0) {
5770
- if (!validate33(data7.auth, {
7779
+ if (!validate39(data7.auth, {
5771
7780
  instancePath: instancePath + "/email/auth",
5772
7781
  parentData: data7,
5773
7782
  parentDataProperty: "auth",
5774
7783
  rootData
5775
7784
  })) {
5776
- vErrors = vErrors === null ? validate33.errors : vErrors.concat(validate33.errors);
7785
+ vErrors = vErrors === null ? validate39.errors : vErrors.concat(validate39.errors);
5777
7786
  errors = vErrors.length;
5778
7787
  }
5779
7788
  }
@@ -6460,8 +8469,14 @@ const emailReceivedEventJsonSchema = {
6460
8469
  },
6461
8470
  "event": {
6462
8471
  "type": "string",
6463
- "const": "email.received",
6464
- "description": "Event type identifier. Always `\"email.received\"` for this event type."
8472
+ "enum": [
8473
+ "email.received",
8474
+ "email.bounced",
8475
+ "email.tls_report",
8476
+ "email.dmarc_report",
8477
+ "email.dmarc_failure"
8478
+ ],
8479
+ "description": "Event type identifier.\n\n- `email.received` - A normal inbound email.\n- `email.bounced` - A delivery status notification (DSN) reporting that a message delivery failed. Carries `email.analysis.bounce`.\n- `email.tls_report` - An SMTP TLS report (RFC 8460). Carries `email.analysis.tls_report`.\n- `email.dmarc_report` - A DMARC aggregate report (RFC 7489). Carries `email.analysis.dmarc_report`.\n- `email.dmarc_failure` - A DMARC failure (forensic) report.\n\nMachine-generated mail (bounces and the report types above) is delivered under its own event type rather than `email.received`, so an endpoint subscribed only to `email.received` receives just normal inbound mail. The payload shape is otherwise identical across event types; the type-specific details live under `email.analysis`."
6465
8480
  },
6466
8481
  "version": {
6467
8482
  "$ref": "#/definitions/WebhookVersion",
@@ -6985,10 +9000,324 @@ const emailReceivedEventJsonSchema = {
6985
9000
  "forward": {
6986
9001
  "$ref": "#/definitions/ForwardAnalysis",
6987
9002
  "description": "Forward detection and analysis results.\n\nOptional. Present when the email was processed by a forward-detection pipeline (always present in Primitive's managed service). When absent, forward detection was not performed on this email."
9003
+ },
9004
+ "bounce": {
9005
+ "$ref": "#/definitions/BounceAnalysis",
9006
+ "description": "Bounce (delivery status notification) analysis.\n\nPresent on `email.bounced` events: the parsed DSN reporting that a message you sent could not be delivered. Absent on all other event types."
9007
+ },
9008
+ "tls_report": {
9009
+ "$ref": "#/definitions/TlsReportAnalysis",
9010
+ "description": "SMTP TLS report analysis (RFC 8460).\n\nPresent on `email.tls_report` events: a remote MTA's report of TLS negotiation results for mail sent to your domain. Absent on all other event types."
9011
+ },
9012
+ "dmarc_report": {
9013
+ "$ref": "#/definitions/DmarcReportAnalysis",
9014
+ "description": "DMARC aggregate report analysis (RFC 7489).\n\nPresent on `email.dmarc_report` events: a receiver's periodic aggregate report of DMARC authentication results for your domain. Absent on all other event types."
6988
9015
  }
6989
9016
  },
6990
9017
  "description": "Email analysis and classification results.\n\nAll properties in this object are optional. Which fields are present depends on the analysis pipeline processing the email. Primitive's managed service populates all fields. Self-hosted or third-party deployments may include some, all, or none of these fields depending on their pipeline configuration.\n\nWhen a field is absent, it means that particular analysis was not performed, not that the analysis produced no results. For example, a missing `spamassassin` field means SpamAssassin was not run, not that the email scored 0.\n\nThese fields may be omitted from the payload entirely but must not be set to null."
6991
9018
  },
9019
+ "BounceAnalysis": {
9020
+ "type": "object",
9021
+ "properties": {
9022
+ "is_bounce": {
9023
+ "type": "boolean",
9024
+ "const": true,
9025
+ "description": "Always `true` on a parsed bounce."
9026
+ },
9027
+ "kind": {
9028
+ "type": "string",
9029
+ "const": "dsn",
9030
+ "description": "The machine-mail kind. Always `dsn` for a bounce."
9031
+ },
9032
+ "type": {
9033
+ "type": "string",
9034
+ "enum": [
9035
+ "permanent",
9036
+ "transient",
9037
+ "undetermined"
9038
+ ],
9039
+ "description": "Whether the failure is permanent (hard bounce), transient (soft bounce, may be retried), or undetermined."
9040
+ },
9041
+ "category": {
9042
+ "type": "string",
9043
+ "enum": [
9044
+ "mailbox_does_not_exist",
9045
+ "domain_does_not_exist",
9046
+ "domain_not_accepting_mail",
9047
+ "mailbox_full",
9048
+ "mailbox_inactive",
9049
+ "message_too_large",
9050
+ "content_rejected",
9051
+ "policy_blocked",
9052
+ "auth_failure",
9053
+ "relay_denied",
9054
+ "rate_limited",
9055
+ "network_error",
9056
+ "recipient_moved",
9057
+ "expired",
9058
+ "undetermined"
9059
+ ],
9060
+ "description": "Best-effort reason category for the failure."
9061
+ },
9062
+ "classified_by": {
9063
+ "type": "string",
9064
+ "enum": [
9065
+ "status_code",
9066
+ "smtp_code",
9067
+ "pattern",
9068
+ "provider",
9069
+ "none"
9070
+ ],
9071
+ "description": "Which signal produced `category` (for transparency and debugging)."
9072
+ },
9073
+ "failed_recipient": {
9074
+ "type": ["string", "null"],
9075
+ "description": "The recipient address that failed, if the report identifies one."
9076
+ },
9077
+ "smtp_code": {
9078
+ "type": ["integer", "null"],
9079
+ "description": "SMTP reply code (e.g. `550`), if reported."
9080
+ },
9081
+ "status_code": {
9082
+ "type": ["string", "null"],
9083
+ "description": "Enhanced mail system status code (RFC 3463, e.g. `5.1.1`), if reported."
9084
+ },
9085
+ "diagnostic_code": {
9086
+ "type": ["string", "null"],
9087
+ "description": "Raw diagnostic text from the reporting MTA, if present."
9088
+ },
9089
+ "reported_by_mta": {
9090
+ "type": ["string", "null"],
9091
+ "description": "The MTA that generated the report, if identifiable."
9092
+ },
9093
+ "original_message_id": {
9094
+ "type": ["string", "null"],
9095
+ "description": "Message-ID of the original message that bounced, if recoverable. Match this against the `message_id` of a message you sent to correlate the bounce."
9096
+ },
9097
+ "reasons": {
9098
+ "type": "array",
9099
+ "items": { "type": "string" },
9100
+ "description": "Human-readable reason strings extracted from the report."
9101
+ }
9102
+ },
9103
+ "required": [
9104
+ "is_bounce",
9105
+ "kind",
9106
+ "type",
9107
+ "category",
9108
+ "classified_by",
9109
+ "failed_recipient",
9110
+ "smtp_code",
9111
+ "status_code",
9112
+ "diagnostic_code",
9113
+ "reported_by_mta",
9114
+ "original_message_id",
9115
+ "reasons"
9116
+ ],
9117
+ "description": "Parsed delivery status notification (bounce). Present as `email.analysis.bounce` on `email.bounced` events."
9118
+ },
9119
+ "TlsReportFailure": {
9120
+ "type": "object",
9121
+ "properties": {
9122
+ "result_type": {
9123
+ "type": ["string", "null"],
9124
+ "description": "Failure result type (e.g. `certificate-expired`, `starttls-not-supported`)."
9125
+ },
9126
+ "count": {
9127
+ "type": "integer",
9128
+ "description": "Number of sessions that hit this failure."
9129
+ },
9130
+ "sending_mta_ip": { "type": ["string", "null"] },
9131
+ "receiving_mx_hostname": { "type": ["string", "null"] }
9132
+ },
9133
+ "required": [
9134
+ "result_type",
9135
+ "count",
9136
+ "sending_mta_ip",
9137
+ "receiving_mx_hostname"
9138
+ ]
9139
+ },
9140
+ "TlsReportPolicy": {
9141
+ "type": "object",
9142
+ "properties": {
9143
+ "policy_domain": { "type": ["string", "null"] },
9144
+ "policy_type": {
9145
+ "type": ["string", "null"],
9146
+ "description": "Policy type the sessions were evaluated against (e.g. `sts`, `tlsa`, `no-policy-found`)."
9147
+ },
9148
+ "successful_sessions": { "type": "integer" },
9149
+ "failed_sessions": { "type": "integer" },
9150
+ "failures": {
9151
+ "type": "array",
9152
+ "items": { "$ref": "#/definitions/TlsReportFailure" }
9153
+ }
9154
+ },
9155
+ "required": [
9156
+ "policy_domain",
9157
+ "policy_type",
9158
+ "successful_sessions",
9159
+ "failed_sessions",
9160
+ "failures"
9161
+ ]
9162
+ },
9163
+ "TlsReportAnalysis": {
9164
+ "type": "object",
9165
+ "properties": {
9166
+ "kind": {
9167
+ "type": "string",
9168
+ "const": "tls_report"
9169
+ },
9170
+ "organization": {
9171
+ "type": ["string", "null"],
9172
+ "description": "Reporting organization name."
9173
+ },
9174
+ "report_id": { "type": ["string", "null"] },
9175
+ "contact": {
9176
+ "type": ["string", "null"],
9177
+ "description": "Reporter contact, if provided."
9178
+ },
9179
+ "date_range": {
9180
+ "type": "object",
9181
+ "properties": {
9182
+ "start": {
9183
+ "type": ["string", "null"],
9184
+ "description": "ISO 8601 start of the reporting window."
9185
+ },
9186
+ "end": {
9187
+ "type": ["string", "null"],
9188
+ "description": "ISO 8601 end of the reporting window."
9189
+ }
9190
+ },
9191
+ "required": ["start", "end"]
9192
+ },
9193
+ "total_successful_sessions": { "type": "integer" },
9194
+ "total_failed_sessions": { "type": "integer" },
9195
+ "policies": {
9196
+ "type": "array",
9197
+ "items": { "$ref": "#/definitions/TlsReportPolicy" }
9198
+ }
9199
+ },
9200
+ "required": [
9201
+ "kind",
9202
+ "organization",
9203
+ "report_id",
9204
+ "contact",
9205
+ "date_range",
9206
+ "total_successful_sessions",
9207
+ "total_failed_sessions",
9208
+ "policies"
9209
+ ],
9210
+ "description": "Parsed SMTP TLS report (RFC 8460). Present as `email.analysis.tls_report` on `email.tls_report` events."
9211
+ },
9212
+ "DmarcRecord": {
9213
+ "type": "object",
9214
+ "properties": {
9215
+ "source_ip": { "type": ["string", "null"] },
9216
+ "count": { "type": "integer" },
9217
+ "disposition": {
9218
+ "type": ["string", "null"],
9219
+ "description": "Disposition applied by the receiver: `none`, `quarantine`, or `reject`."
9220
+ },
9221
+ "dkim": {
9222
+ "type": ["string", "null"],
9223
+ "description": "DKIM alignment result: `pass` or `fail`."
9224
+ },
9225
+ "spf": {
9226
+ "type": ["string", "null"],
9227
+ "description": "SPF alignment result: `pass` or `fail`."
9228
+ },
9229
+ "header_from": { "type": ["string", "null"] }
9230
+ },
9231
+ "required": [
9232
+ "source_ip",
9233
+ "count",
9234
+ "disposition",
9235
+ "dkim",
9236
+ "spf",
9237
+ "header_from"
9238
+ ]
9239
+ },
9240
+ "DmarcReportAnalysis": {
9241
+ "type": "object",
9242
+ "properties": {
9243
+ "kind": {
9244
+ "type": "string",
9245
+ "const": "dmarc_report"
9246
+ },
9247
+ "organization": { "type": ["string", "null"] },
9248
+ "report_id": { "type": ["string", "null"] },
9249
+ "date_range": {
9250
+ "type": "object",
9251
+ "properties": {
9252
+ "start": {
9253
+ "type": ["string", "null"],
9254
+ "description": "ISO 8601 start of the reporting window."
9255
+ },
9256
+ "end": {
9257
+ "type": ["string", "null"],
9258
+ "description": "ISO 8601 end of the reporting window."
9259
+ }
9260
+ },
9261
+ "required": ["start", "end"]
9262
+ },
9263
+ "policy_published": {
9264
+ "type": "object",
9265
+ "properties": {
9266
+ "domain": { "type": ["string", "null"] },
9267
+ "p": {
9268
+ "type": ["string", "null"],
9269
+ "description": "Published domain policy: `none`, `quarantine`, or `reject`."
9270
+ },
9271
+ "sp": {
9272
+ "type": ["string", "null"],
9273
+ "description": "Published subdomain policy."
9274
+ },
9275
+ "pct": {
9276
+ "type": ["integer", "null"],
9277
+ "description": "Percentage of messages the policy is applied to."
9278
+ },
9279
+ "adkim": {
9280
+ "type": ["string", "null"],
9281
+ "description": "DKIM alignment mode: `r` (relaxed) or `s` (strict)."
9282
+ },
9283
+ "aspf": {
9284
+ "type": ["string", "null"],
9285
+ "description": "SPF alignment mode: `r` (relaxed) or `s` (strict)."
9286
+ }
9287
+ },
9288
+ "required": [
9289
+ "domain",
9290
+ "p",
9291
+ "sp",
9292
+ "pct",
9293
+ "adkim",
9294
+ "aspf"
9295
+ ]
9296
+ },
9297
+ "total_count": {
9298
+ "type": "integer",
9299
+ "description": "Total messages covered by the report."
9300
+ },
9301
+ "dkim_pass_count": { "type": "integer" },
9302
+ "spf_pass_count": { "type": "integer" },
9303
+ "records": {
9304
+ "type": "array",
9305
+ "items": { "$ref": "#/definitions/DmarcRecord" }
9306
+ }
9307
+ },
9308
+ "required": [
9309
+ "kind",
9310
+ "organization",
9311
+ "report_id",
9312
+ "date_range",
9313
+ "policy_published",
9314
+ "total_count",
9315
+ "dkim_pass_count",
9316
+ "spf_pass_count",
9317
+ "records"
9318
+ ],
9319
+ "description": "Parsed DMARC aggregate report (RFC 7489). Present as `email.analysis.dmarc_report` on `email.dmarc_report` events."
9320
+ },
6992
9321
  "ForwardAnalysis": {
6993
9322
  "type": "object",
6994
9323
  "properties": {
@@ -7354,7 +9683,13 @@ const emailReceivedEventJsonSchema = {
7354
9683
  };
7355
9684
  //#endregion
7356
9685
  //#region src/types.ts
7357
- const EventType = { EmailReceived: "email.received" };
9686
+ const EventType = {
9687
+ EmailReceived: "email.received",
9688
+ EmailBounced: "email.bounced",
9689
+ EmailTlsReport: "email.tls_report",
9690
+ EmailDmarcReport: "email.dmarc_report",
9691
+ EmailDmarcFailure: "email.dmarc_failure"
9692
+ };
7358
9693
  const ParsedStatus = {
7359
9694
  Complete: "complete",
7360
9695
  Failed: "failed"