@brightchain/brightchain-api-lib 0.25.0 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +4 -3
- package/src/lib/appConstants.d.ts +1 -1
- package/src/lib/appConstants.js +1 -1
- package/src/lib/application.d.ts +3 -14
- package/src/lib/application.d.ts.map +1 -1
- package/src/lib/application.js +91 -34
- package/src/lib/application.js.map +1 -1
- package/src/lib/constants.d.ts.map +1 -1
- package/src/lib/constants.js +1 -1
- package/src/lib/constants.js.map +1 -1
- package/src/lib/databaseInit.d.ts +7 -11
- package/src/lib/databaseInit.d.ts.map +1 -1
- package/src/lib/databaseInit.js +41 -107
- package/src/lib/databaseInit.js.map +1 -1
- package/src/lib/datastore/block-document-store-factory.d.ts +3 -0
- package/src/lib/datastore/block-document-store-factory.d.ts.map +1 -1
- package/src/lib/datastore/block-document-store-factory.js +15 -18
- package/src/lib/datastore/block-document-store-factory.js.map +1 -1
- package/src/lib/datastore/block-document-store.d.ts +2 -191
- package/src/lib/datastore/block-document-store.d.ts.map +1 -1
- package/src/lib/datastore/block-document-store.js +4 -628
- package/src/lib/datastore/block-document-store.js.map +1 -1
- package/src/lib/datastore/document-store.d.ts +1 -62
- package/src/lib/datastore/document-store.d.ts.map +1 -1
- package/src/lib/datastore/memory-document-store.d.ts +1 -8
- package/src/lib/datastore/memory-document-store.d.ts.map +1 -1
- package/src/lib/datastore/memory-document-store.js +3 -214
- package/src/lib/datastore/memory-document-store.js.map +1 -1
- package/src/lib/environment.d.ts +4 -47
- package/src/lib/environment.d.ts.map +1 -1
- package/src/lib/environment.js +2 -136
- package/src/lib/environment.js.map +1 -1
- package/src/lib/interfaces/environment.d.ts +3 -25
- package/src/lib/interfaces/environment.d.ts.map +1 -1
- package/src/lib/interfaces/responses/emailGatewayResponses.d.ts +30 -0
- package/src/lib/interfaces/responses/emailGatewayResponses.d.ts.map +1 -0
- package/src/lib/interfaces/responses/emailGatewayResponses.js +3 -0
- package/src/lib/interfaces/responses/emailGatewayResponses.js.map +1 -0
- package/src/lib/interfaces/responses/index.d.ts +1 -0
- package/src/lib/interfaces/responses/index.d.ts.map +1 -1
- package/src/lib/middleware/index.d.ts +1 -1
- package/src/lib/middleware/index.d.ts.map +1 -1
- package/src/lib/middleware/index.js +3 -2
- package/src/lib/middleware/index.js.map +1 -1
- package/src/lib/middleware/validateBody.d.ts +1 -12
- package/src/lib/middleware/validateBody.d.ts.map +1 -1
- package/src/lib/middleware/validateBody.js +4 -32
- package/src/lib/middleware/validateBody.js.map +1 -1
- package/src/lib/middlewares.d.ts.map +1 -1
- package/src/lib/middlewares.js +7 -1
- package/src/lib/middlewares.js.map +1 -1
- package/src/lib/plugins/brightchain-database-plugin.d.ts +27 -79
- package/src/lib/plugins/brightchain-database-plugin.d.ts.map +1 -1
- package/src/lib/plugins/brightchain-database-plugin.js +32 -103
- package/src/lib/plugins/brightchain-database-plugin.js.map +1 -1
- package/src/lib/routers/app.d.ts.map +1 -1
- package/src/lib/routers/app.js +1 -0
- package/src/lib/routers/app.js.map +1 -1
- package/src/lib/services/emailGateway/antiSpamFilter.d.ts +229 -0
- package/src/lib/services/emailGateway/antiSpamFilter.d.ts.map +1 -0
- package/src/lib/services/emailGateway/antiSpamFilter.js +325 -0
- package/src/lib/services/emailGateway/antiSpamFilter.js.map +1 -0
- package/src/lib/services/emailGateway/bounceProcessor.d.ts +182 -0
- package/src/lib/services/emailGateway/bounceProcessor.d.ts.map +1 -0
- package/src/lib/services/emailGateway/bounceProcessor.js +391 -0
- package/src/lib/services/emailGateway/bounceProcessor.js.map +1 -0
- package/src/lib/services/emailGateway/emailAuthVerifier.d.ts +99 -0
- package/src/lib/services/emailGateway/emailAuthVerifier.d.ts.map +1 -0
- package/src/lib/services/emailGateway/emailAuthVerifier.js +202 -0
- package/src/lib/services/emailGateway/emailAuthVerifier.js.map +1 -0
- package/src/lib/services/emailGateway/emailGatewayConfig.d.ts +74 -0
- package/src/lib/services/emailGateway/emailGatewayConfig.d.ts.map +1 -0
- package/src/lib/services/emailGateway/emailGatewayConfig.js +107 -0
- package/src/lib/services/emailGateway/emailGatewayConfig.js.map +1 -0
- package/src/lib/services/emailGateway/emailGatewayService.d.ts +209 -0
- package/src/lib/services/emailGateway/emailGatewayService.d.ts.map +1 -0
- package/src/lib/services/emailGateway/emailGatewayService.js +254 -0
- package/src/lib/services/emailGateway/emailGatewayService.js.map +1 -0
- package/src/lib/services/emailGateway/gatewayObservability.d.ts +123 -0
- package/src/lib/services/emailGateway/gatewayObservability.d.ts.map +1 -0
- package/src/lib/services/emailGateway/gatewayObservability.js +186 -0
- package/src/lib/services/emailGateway/gatewayObservability.js.map +1 -0
- package/src/lib/services/emailGateway/inboundProcessor.d.ts +113 -0
- package/src/lib/services/emailGateway/inboundProcessor.d.ts.map +1 -0
- package/src/lib/services/emailGateway/inboundProcessor.js +298 -0
- package/src/lib/services/emailGateway/inboundProcessor.js.map +1 -0
- package/src/lib/services/emailGateway/index.d.ts +23 -0
- package/src/lib/services/emailGateway/index.d.ts.map +1 -0
- package/src/lib/services/emailGateway/index.js +26 -0
- package/src/lib/services/emailGateway/index.js.map +1 -0
- package/src/lib/services/emailGateway/outboundDeliveryWorker.d.ts +122 -0
- package/src/lib/services/emailGateway/outboundDeliveryWorker.d.ts.map +1 -0
- package/src/lib/services/emailGateway/outboundDeliveryWorker.js +110 -0
- package/src/lib/services/emailGateway/outboundDeliveryWorker.js.map +1 -0
- package/src/lib/services/emailGateway/outboundQueue.d.ts +135 -0
- package/src/lib/services/emailGateway/outboundQueue.d.ts.map +1 -0
- package/src/lib/services/emailGateway/outboundQueue.js +227 -0
- package/src/lib/services/emailGateway/outboundQueue.js.map +1 -0
- package/src/lib/services/emailGateway/outboundQueueStore.d.ts +110 -0
- package/src/lib/services/emailGateway/outboundQueueStore.d.ts.map +1 -0
- package/src/lib/services/emailGateway/outboundQueueStore.js +131 -0
- package/src/lib/services/emailGateway/outboundQueueStore.js.map +1 -0
- package/src/lib/services/emailGateway/recipientLookupService.d.ts +146 -0
- package/src/lib/services/emailGateway/recipientLookupService.d.ts.map +1 -0
- package/src/lib/services/emailGateway/recipientLookupService.js +307 -0
- package/src/lib/services/emailGateway/recipientLookupService.js.map +1 -0
- package/src/lib/services/emailGateway/retryBackoff.d.ts +79 -0
- package/src/lib/services/emailGateway/retryBackoff.d.ts.map +1 -0
- package/src/lib/services/emailGateway/retryBackoff.js +77 -0
- package/src/lib/services/emailGateway/retryBackoff.js.map +1 -0
- package/src/lib/services/index.d.ts +1 -0
- package/src/lib/services/index.d.ts.map +1 -1
- package/src/lib/services/index.js +1 -0
- package/src/lib/services/index.js.map +1 -1
- package/src/lib/services/quorumDatabaseAdapter.d.ts +7 -1
- package/src/lib/services/quorumDatabaseAdapter.d.ts.map +1 -1
- package/src/lib/services/quorumDatabaseAdapter.js +83 -0
- package/src/lib/services/quorumDatabaseAdapter.js.map +1 -1
- package/src/lib/services/sessionAdapter.d.ts +2 -61
- package/src/lib/services/sessionAdapter.d.ts.map +1 -1
- package/src/lib/services/sessionAdapter.js +2 -102
- package/src/lib/services/sessionAdapter.js.map +1 -1
- package/src/lib/shared-types.d.ts +7 -15
- package/src/lib/shared-types.d.ts.map +1 -1
- package/src/lib/types/backend-id.d.ts +1 -2
- package/src/lib/types/backend-id.d.ts.map +1 -1
- package/src/lib/validation/userValidation.d.ts +2 -43
- package/src/lib/validation/userValidation.d.ts.map +1 -1
- package/src/lib/validation/userValidation.js +6 -144
- package/src/lib/validation/userValidation.js.map +1 -1
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Email Authentication Verifier — parses SPF/DKIM/DMARC authentication
|
|
3
|
+
* results from inbound email messages.
|
|
4
|
+
*
|
|
5
|
+
* In a typical deployment, Postfix and its milters (e.g. OpenDKIM,
|
|
6
|
+
* opendmarc, pypolicyd-spf) perform the actual SPF, DKIM, and DMARC
|
|
7
|
+
* verification before depositing the message in the Mail Drop Directory.
|
|
8
|
+
* These results are recorded in the `Authentication-Results` header
|
|
9
|
+
* (RFC 8601).
|
|
10
|
+
*
|
|
11
|
+
* This verifier parses those headers from the raw message to extract
|
|
12
|
+
* structured `IEmailAuthenticationResult` metadata that the
|
|
13
|
+
* InboundProcessor stores alongside the message.
|
|
14
|
+
*
|
|
15
|
+
* @see Requirements 6.4, 6.5
|
|
16
|
+
* @module emailAuthVerifier
|
|
17
|
+
*/
|
|
18
|
+
import type { IEmailAuthenticationResult } from '@brightchain/brightchain-lib';
|
|
19
|
+
/**
|
|
20
|
+
* Interface for verifying email authentication results.
|
|
21
|
+
*
|
|
22
|
+
* Implementations parse the `Authentication-Results` header from a raw
|
|
23
|
+
* RFC 5322 message and return structured SPF/DKIM/DMARC results.
|
|
24
|
+
*
|
|
25
|
+
* @see Requirements 6.4, 6.5
|
|
26
|
+
*/
|
|
27
|
+
export interface IEmailAuthVerifier {
|
|
28
|
+
/**
|
|
29
|
+
* Verify authentication results for an inbound email message.
|
|
30
|
+
*
|
|
31
|
+
* @param rawMessage - The raw RFC 5322 message bytes (as deposited by Postfix)
|
|
32
|
+
* @param senderIp - Optional IP address of the sending server (for logging)
|
|
33
|
+
* @returns Structured authentication results for SPF, DKIM, and DMARC
|
|
34
|
+
*/
|
|
35
|
+
verify(rawMessage: Uint8Array | Buffer, senderIp?: string): IEmailAuthenticationResult;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Returns a default `IEmailAuthenticationResult` with all statuses set to `'none'`.
|
|
39
|
+
*/
|
|
40
|
+
export declare function defaultAuthResult(): IEmailAuthenticationResult;
|
|
41
|
+
/**
|
|
42
|
+
* Parses `Authentication-Results` headers from raw RFC 5322 messages to
|
|
43
|
+
* extract SPF, DKIM, and DMARC verification results.
|
|
44
|
+
*
|
|
45
|
+
* This is an adapter/stub that reads results already computed by
|
|
46
|
+
* Postfix milters. It does NOT perform cryptographic DKIM verification
|
|
47
|
+
* or DNS lookups itself.
|
|
48
|
+
*
|
|
49
|
+
* @see Requirements 6.4, 6.5
|
|
50
|
+
*/
|
|
51
|
+
export declare class EmailAuthVerifier implements IEmailAuthVerifier {
|
|
52
|
+
/**
|
|
53
|
+
* Parse authentication results from the raw message headers.
|
|
54
|
+
*
|
|
55
|
+
* Extracts the `Authentication-Results` header value and parses
|
|
56
|
+
* individual method results (spf=, dkim=, dmarc=).
|
|
57
|
+
*
|
|
58
|
+
* @param rawMessage - Raw RFC 5322 message bytes
|
|
59
|
+
* @param _senderIp - Sender IP (unused; reserved for future direct verification)
|
|
60
|
+
* @returns Structured authentication results
|
|
61
|
+
*/
|
|
62
|
+
verify(rawMessage: Uint8Array | Buffer, _senderIp?: string): IEmailAuthenticationResult;
|
|
63
|
+
/**
|
|
64
|
+
* Check whether the authentication result indicates a DMARC reject
|
|
65
|
+
* condition — i.e. DMARC status is `'fail'`.
|
|
66
|
+
*
|
|
67
|
+
* The caller (InboundProcessor) uses this to decide whether to move
|
|
68
|
+
* the message to the error directory with a 550-equivalent rejection.
|
|
69
|
+
*
|
|
70
|
+
* @param result - The parsed authentication result
|
|
71
|
+
* @returns `true` if DMARC failed (reject policy should apply)
|
|
72
|
+
*
|
|
73
|
+
* @see Requirement 6.5
|
|
74
|
+
*/
|
|
75
|
+
static shouldRejectDmarc(result: IEmailAuthenticationResult): boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Extract the value of the first `Authentication-Results` header from
|
|
78
|
+
* the raw message bytes.
|
|
79
|
+
*
|
|
80
|
+
* RFC 5322 headers end at the first blank line (`\r\n\r\n` or `\n\n`).
|
|
81
|
+
* Header continuation (folding) is handled by joining lines that start
|
|
82
|
+
* with whitespace.
|
|
83
|
+
*/
|
|
84
|
+
private extractAuthResultsHeader;
|
|
85
|
+
/**
|
|
86
|
+
* Parse an `Authentication-Results` header value into structured results.
|
|
87
|
+
*
|
|
88
|
+
* The header format (RFC 8601) is roughly:
|
|
89
|
+
* `authserv-id; method=status (details); method=status ...`
|
|
90
|
+
*
|
|
91
|
+
* We split on `;` and look for `spf=`, `dkim=`, `dmarc=` prefixes.
|
|
92
|
+
*/
|
|
93
|
+
private parseAuthResultsHeader;
|
|
94
|
+
/**
|
|
95
|
+
* Parse a single method result segment like `spf=pass (details here)`.
|
|
96
|
+
*/
|
|
97
|
+
private parseMethodResult;
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=emailAuthVerifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emailAuthVerifier.d.ts","sourceRoot":"","sources":["../../../../../../brightchain-api-lib/src/lib/services/emailGateway/emailAuthVerifier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAI/E;;;;;;;GAOG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;;;OAMG;IACH,MAAM,CACJ,UAAU,EAAE,UAAU,GAAG,MAAM,EAC/B,QAAQ,CAAC,EAAE,MAAM,GAChB,0BAA0B,CAAC;CAC/B;AAoCD;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,0BAA0B,CAM9D;AAID;;;;;;;;;GASG;AACH,qBAAa,iBAAkB,YAAW,kBAAkB;IAC1D;;;;;;;;;OASG;IACH,MAAM,CACJ,UAAU,EAAE,UAAU,GAAG,MAAM,EAC/B,SAAS,CAAC,EAAE,MAAM,GACjB,0BAA0B;IAQ7B;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,iBAAiB,CAAC,MAAM,EAAE,0BAA0B,GAAG,OAAO;IAMrE;;;;;;;OAOG;IACH,OAAO,CAAC,wBAAwB;IA8ChC;;;;;;;OAOG;IACH,OAAO,CAAC,sBAAsB;IAmB9B;;OAEG;IACH,OAAO,CAAC,iBAAiB;CAqC1B"}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Email Authentication Verifier — parses SPF/DKIM/DMARC authentication
|
|
4
|
+
* results from inbound email messages.
|
|
5
|
+
*
|
|
6
|
+
* In a typical deployment, Postfix and its milters (e.g. OpenDKIM,
|
|
7
|
+
* opendmarc, pypolicyd-spf) perform the actual SPF, DKIM, and DMARC
|
|
8
|
+
* verification before depositing the message in the Mail Drop Directory.
|
|
9
|
+
* These results are recorded in the `Authentication-Results` header
|
|
10
|
+
* (RFC 8601).
|
|
11
|
+
*
|
|
12
|
+
* This verifier parses those headers from the raw message to extract
|
|
13
|
+
* structured `IEmailAuthenticationResult` metadata that the
|
|
14
|
+
* InboundProcessor stores alongside the message.
|
|
15
|
+
*
|
|
16
|
+
* @see Requirements 6.4, 6.5
|
|
17
|
+
* @module emailAuthVerifier
|
|
18
|
+
*/
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.EmailAuthVerifier = void 0;
|
|
21
|
+
exports.defaultAuthResult = defaultAuthResult;
|
|
22
|
+
const VALID_SPF_STATUSES = new Set([
|
|
23
|
+
'pass',
|
|
24
|
+
'fail',
|
|
25
|
+
'softfail',
|
|
26
|
+
'neutral',
|
|
27
|
+
'none',
|
|
28
|
+
'temperror',
|
|
29
|
+
'permerror',
|
|
30
|
+
]);
|
|
31
|
+
const VALID_DKIM_STATUSES = new Set([
|
|
32
|
+
'pass',
|
|
33
|
+
'fail',
|
|
34
|
+
'none',
|
|
35
|
+
'temperror',
|
|
36
|
+
'permerror',
|
|
37
|
+
]);
|
|
38
|
+
const VALID_DMARC_STATUSES = new Set([
|
|
39
|
+
'pass',
|
|
40
|
+
'fail',
|
|
41
|
+
'none',
|
|
42
|
+
'temperror',
|
|
43
|
+
'permerror',
|
|
44
|
+
]);
|
|
45
|
+
// ─── Default result ─────────────────────────────────────────────────────────
|
|
46
|
+
/**
|
|
47
|
+
* Returns a default `IEmailAuthenticationResult` with all statuses set to `'none'`.
|
|
48
|
+
*/
|
|
49
|
+
function defaultAuthResult() {
|
|
50
|
+
return {
|
|
51
|
+
spf: { status: 'none' },
|
|
52
|
+
dkim: { status: 'none' },
|
|
53
|
+
dmarc: { status: 'none' },
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
// ─── Implementation ─────────────────────────────────────────────────────────
|
|
57
|
+
/**
|
|
58
|
+
* Parses `Authentication-Results` headers from raw RFC 5322 messages to
|
|
59
|
+
* extract SPF, DKIM, and DMARC verification results.
|
|
60
|
+
*
|
|
61
|
+
* This is an adapter/stub that reads results already computed by
|
|
62
|
+
* Postfix milters. It does NOT perform cryptographic DKIM verification
|
|
63
|
+
* or DNS lookups itself.
|
|
64
|
+
*
|
|
65
|
+
* @see Requirements 6.4, 6.5
|
|
66
|
+
*/
|
|
67
|
+
class EmailAuthVerifier {
|
|
68
|
+
/**
|
|
69
|
+
* Parse authentication results from the raw message headers.
|
|
70
|
+
*
|
|
71
|
+
* Extracts the `Authentication-Results` header value and parses
|
|
72
|
+
* individual method results (spf=, dkim=, dmarc=).
|
|
73
|
+
*
|
|
74
|
+
* @param rawMessage - Raw RFC 5322 message bytes
|
|
75
|
+
* @param _senderIp - Sender IP (unused; reserved for future direct verification)
|
|
76
|
+
* @returns Structured authentication results
|
|
77
|
+
*/
|
|
78
|
+
verify(rawMessage, _senderIp) {
|
|
79
|
+
const headerValue = this.extractAuthResultsHeader(rawMessage);
|
|
80
|
+
if (!headerValue) {
|
|
81
|
+
return defaultAuthResult();
|
|
82
|
+
}
|
|
83
|
+
return this.parseAuthResultsHeader(headerValue);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Check whether the authentication result indicates a DMARC reject
|
|
87
|
+
* condition — i.e. DMARC status is `'fail'`.
|
|
88
|
+
*
|
|
89
|
+
* The caller (InboundProcessor) uses this to decide whether to move
|
|
90
|
+
* the message to the error directory with a 550-equivalent rejection.
|
|
91
|
+
*
|
|
92
|
+
* @param result - The parsed authentication result
|
|
93
|
+
* @returns `true` if DMARC failed (reject policy should apply)
|
|
94
|
+
*
|
|
95
|
+
* @see Requirement 6.5
|
|
96
|
+
*/
|
|
97
|
+
static shouldRejectDmarc(result) {
|
|
98
|
+
return result.dmarc.status === 'fail';
|
|
99
|
+
}
|
|
100
|
+
// ─── Header extraction ──────────────────────────────────────────────
|
|
101
|
+
/**
|
|
102
|
+
* Extract the value of the first `Authentication-Results` header from
|
|
103
|
+
* the raw message bytes.
|
|
104
|
+
*
|
|
105
|
+
* RFC 5322 headers end at the first blank line (`\r\n\r\n` or `\n\n`).
|
|
106
|
+
* Header continuation (folding) is handled by joining lines that start
|
|
107
|
+
* with whitespace.
|
|
108
|
+
*/
|
|
109
|
+
extractAuthResultsHeader(rawMessage) {
|
|
110
|
+
const text = typeof rawMessage === 'string'
|
|
111
|
+
? rawMessage
|
|
112
|
+
: Buffer.isBuffer(rawMessage)
|
|
113
|
+
? rawMessage.toString('utf-8')
|
|
114
|
+
: new TextDecoder().decode(rawMessage);
|
|
115
|
+
// Split headers from body at the first blank line.
|
|
116
|
+
const headerEndCrLf = text.indexOf('\r\n\r\n');
|
|
117
|
+
const headerEndLf = text.indexOf('\n\n');
|
|
118
|
+
let headerSection;
|
|
119
|
+
if (headerEndCrLf >= 0 &&
|
|
120
|
+
(headerEndLf < 0 || headerEndCrLf <= headerEndLf)) {
|
|
121
|
+
headerSection = text.substring(0, headerEndCrLf);
|
|
122
|
+
}
|
|
123
|
+
else if (headerEndLf >= 0) {
|
|
124
|
+
headerSection = text.substring(0, headerEndLf);
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
// No blank line — treat entire content as headers.
|
|
128
|
+
headerSection = text;
|
|
129
|
+
}
|
|
130
|
+
// Unfold continuation lines (lines starting with whitespace are
|
|
131
|
+
// continuations of the previous header per RFC 5322 §2.2.3).
|
|
132
|
+
const unfolded = headerSection.replace(/\r?\n([ \t])/g, ' ');
|
|
133
|
+
// Split into individual header lines.
|
|
134
|
+
const lines = unfolded.split(/\r?\n/);
|
|
135
|
+
for (const line of lines) {
|
|
136
|
+
const match = line.match(/^Authentication-Results:\s*(.+)$/i);
|
|
137
|
+
if (match) {
|
|
138
|
+
return match[1].trim();
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
// ─── Header parsing ─────────────────────────────────────────────────
|
|
144
|
+
/**
|
|
145
|
+
* Parse an `Authentication-Results` header value into structured results.
|
|
146
|
+
*
|
|
147
|
+
* The header format (RFC 8601) is roughly:
|
|
148
|
+
* `authserv-id; method=status (details); method=status ...`
|
|
149
|
+
*
|
|
150
|
+
* We split on `;` and look for `spf=`, `dkim=`, `dmarc=` prefixes.
|
|
151
|
+
*/
|
|
152
|
+
parseAuthResultsHeader(headerValue) {
|
|
153
|
+
const result = defaultAuthResult();
|
|
154
|
+
// Split on semicolons — first segment is the authserv-id, rest are results.
|
|
155
|
+
const segments = headerValue.split(';').map((s) => s.trim());
|
|
156
|
+
// Skip the first segment (authserv-id).
|
|
157
|
+
for (let i = 1; i < segments.length; i++) {
|
|
158
|
+
const segment = segments[i];
|
|
159
|
+
if (!segment)
|
|
160
|
+
continue;
|
|
161
|
+
this.parseMethodResult(segment, result);
|
|
162
|
+
}
|
|
163
|
+
return result;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Parse a single method result segment like `spf=pass (details here)`.
|
|
167
|
+
*/
|
|
168
|
+
parseMethodResult(segment, result) {
|
|
169
|
+
// Match pattern: method=status with optional details in parentheses or after whitespace
|
|
170
|
+
// Examples:
|
|
171
|
+
// spf=pass (sender SPF authorized)
|
|
172
|
+
// dkim=pass header.d=example.com
|
|
173
|
+
// dmarc=fail (p=reject)
|
|
174
|
+
const methodMatch = segment.match(/^\s*(spf|dkim|dmarc)\s*=\s*(\S+)/i);
|
|
175
|
+
if (!methodMatch)
|
|
176
|
+
return;
|
|
177
|
+
const method = methodMatch[1].toLowerCase();
|
|
178
|
+
const rawStatus = methodMatch[2].toLowerCase();
|
|
179
|
+
// Extract optional details in parentheses.
|
|
180
|
+
const detailsMatch = segment.match(/\(([^)]*)\)/);
|
|
181
|
+
const details = detailsMatch ? detailsMatch[1].trim() : undefined;
|
|
182
|
+
switch (method) {
|
|
183
|
+
case 'spf':
|
|
184
|
+
if (VALID_SPF_STATUSES.has(rawStatus)) {
|
|
185
|
+
result.spf = { status: rawStatus, details };
|
|
186
|
+
}
|
|
187
|
+
break;
|
|
188
|
+
case 'dkim':
|
|
189
|
+
if (VALID_DKIM_STATUSES.has(rawStatus)) {
|
|
190
|
+
result.dkim = { status: rawStatus, details };
|
|
191
|
+
}
|
|
192
|
+
break;
|
|
193
|
+
case 'dmarc':
|
|
194
|
+
if (VALID_DMARC_STATUSES.has(rawStatus)) {
|
|
195
|
+
result.dmarc = { status: rawStatus, details };
|
|
196
|
+
}
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
exports.EmailAuthVerifier = EmailAuthVerifier;
|
|
202
|
+
//# sourceMappingURL=emailAuthVerifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emailAuthVerifier.js","sourceRoot":"","sources":["../../../../../../brightchain-api-lib/src/lib/services/emailGateway/emailAuthVerifier.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Email Gateway Configuration
|
|
3
|
+
*
|
|
4
|
+
* Defines the `IEmailGatewayConfig` interface and a `loadGatewayConfig()` loader
|
|
5
|
+
* that reads values from `environment.emailDomain` (EMAIL_DOMAIN env var) and
|
|
6
|
+
* other environment variables with sensible defaults.
|
|
7
|
+
*
|
|
8
|
+
* All Node.js-specific gateway configuration lives here in brightchain-api-lib.
|
|
9
|
+
* The shared `ISpamThresholds` interface is imported from brightchain-lib.
|
|
10
|
+
*
|
|
11
|
+
* @see Requirements 8.1, 8.2, 8.3, 8.4, 8.5, 8.6, 8.7
|
|
12
|
+
* @module emailGatewayConfig
|
|
13
|
+
*/
|
|
14
|
+
import { type ISpamThresholds } from '@brightchain/brightchain-lib';
|
|
15
|
+
/**
|
|
16
|
+
* Complete configuration for the Email Gateway.
|
|
17
|
+
*
|
|
18
|
+
* Each field maps to an environment variable (noted in comments) with a
|
|
19
|
+
* default value applied by `loadGatewayConfig()` when the variable is unset.
|
|
20
|
+
*
|
|
21
|
+
* @see Requirements 8.1, 8.2, 8.3, 8.4, 8.5, 8.6, 8.7
|
|
22
|
+
*/
|
|
23
|
+
export interface IEmailGatewayConfig {
|
|
24
|
+
/** Canonical email domain for this BrightChain instance (from environment.emailDomain / EMAIL_DOMAIN env var). Req 8.1 */
|
|
25
|
+
canonicalDomain: string;
|
|
26
|
+
/** Postfix MTA hostname. env: GATEWAY_POSTFIX_HOST. Req 8.2 */
|
|
27
|
+
postfixHost: string;
|
|
28
|
+
/** Postfix MTA port. env: GATEWAY_POSTFIX_PORT. Req 8.2 */
|
|
29
|
+
postfixPort: number;
|
|
30
|
+
/** Optional Postfix authentication credentials. env: GATEWAY_POSTFIX_USER / GATEWAY_POSTFIX_PASS. Req 8.2 */
|
|
31
|
+
postfixAuth?: {
|
|
32
|
+
user: string;
|
|
33
|
+
pass: string;
|
|
34
|
+
};
|
|
35
|
+
/** Path to the DKIM private key file. env: GATEWAY_DKIM_KEY_PATH. Req 8.3 */
|
|
36
|
+
dkimKeyPath: string;
|
|
37
|
+
/** DKIM selector for DNS lookup. env: GATEWAY_DKIM_SELECTOR. Req 8.3 */
|
|
38
|
+
dkimSelector: string;
|
|
39
|
+
/** Directory where Postfix deposits inbound mail (Maildir format). env: GATEWAY_MAIL_DROP_DIR. Req 8.6 */
|
|
40
|
+
mailDropDirectory: string;
|
|
41
|
+
/** Directory for messages that fail inbound processing. env: GATEWAY_ERROR_DIR. Req 8.6 */
|
|
42
|
+
errorDirectory: string;
|
|
43
|
+
/** Maximum outbound message size in bytes. env: GATEWAY_MAX_MESSAGE_SIZE. Req 8.4 */
|
|
44
|
+
maxMessageSizeBytes: number;
|
|
45
|
+
/** TCP port for the Recipient Lookup Service (socketmap). env: GATEWAY_LOOKUP_PORT. Req 8.7 */
|
|
46
|
+
recipientLookupPort: number;
|
|
47
|
+
/** Cache TTL in seconds for positive recipient lookups. env: GATEWAY_LOOKUP_CACHE_TTL. Req 8.7 */
|
|
48
|
+
recipientLookupCacheTtlSeconds: number;
|
|
49
|
+
/** Anti-spam engine selection. env: GATEWAY_SPAM_ENGINE. Req 8.4 */
|
|
50
|
+
spamEngine: 'spamassassin' | 'rspamd';
|
|
51
|
+
/** Score thresholds for spam classification. env: GATEWAY_SPAM_PROBABLE / GATEWAY_SPAM_DEFINITE. Req 8.4 */
|
|
52
|
+
spamThresholds: ISpamThresholds;
|
|
53
|
+
/** Maximum concurrent outbound SMTP connections. env: GATEWAY_QUEUE_CONCURRENCY. Req 8.4 */
|
|
54
|
+
queueConcurrency: number;
|
|
55
|
+
/** Maximum number of delivery retry attempts. env: GATEWAY_RETRY_MAX_COUNT. Req 8.4 */
|
|
56
|
+
retryMaxCount: number;
|
|
57
|
+
/** Maximum total retry duration in milliseconds. env: GATEWAY_RETRY_MAX_DURATION. Req 8.4 */
|
|
58
|
+
retryMaxDurationMs: number;
|
|
59
|
+
/** Base interval in milliseconds for exponential back-off. env: GATEWAY_RETRY_BASE_INTERVAL. Req 8.4 */
|
|
60
|
+
retryBaseIntervalMs: number;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Load the Email Gateway configuration from environment variables.
|
|
64
|
+
*
|
|
65
|
+
* The canonical domain is read from the `EMAIL_DOMAIN` env var (matching
|
|
66
|
+
* `environment.emailDomain`). All other settings are read from their
|
|
67
|
+
* respective `GATEWAY_*` env vars with sensible defaults.
|
|
68
|
+
*
|
|
69
|
+
* @returns A fully populated `IEmailGatewayConfig`.
|
|
70
|
+
*
|
|
71
|
+
* @see Requirements 8.1, 8.2, 8.3, 8.4, 8.5, 8.6, 8.7
|
|
72
|
+
*/
|
|
73
|
+
export declare function loadGatewayConfig(): IEmailGatewayConfig;
|
|
74
|
+
//# sourceMappingURL=emailGatewayConfig.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emailGatewayConfig.d.ts","sourceRoot":"","sources":["../../../../../../brightchain-api-lib/src/lib/services/emailGateway/emailGatewayConfig.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EACL,KAAK,eAAe,EACrB,MAAM,8BAA8B,CAAC;AAEtC;;;;;;;GAOG;AACH,MAAM,WAAW,mBAAmB;IAClC,0HAA0H;IAC1H,eAAe,EAAE,MAAM,CAAC;IAExB,+DAA+D;IAC/D,WAAW,EAAE,MAAM,CAAC;IAEpB,2DAA2D;IAC3D,WAAW,EAAE,MAAM,CAAC;IAEpB,6GAA6G;IAC7G,WAAW,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAE7C,6EAA6E;IAC7E,WAAW,EAAE,MAAM,CAAC;IAEpB,wEAAwE;IACxE,YAAY,EAAE,MAAM,CAAC;IAErB,0GAA0G;IAC1G,iBAAiB,EAAE,MAAM,CAAC;IAE1B,2FAA2F;IAC3F,cAAc,EAAE,MAAM,CAAC;IAEvB,qFAAqF;IACrF,mBAAmB,EAAE,MAAM,CAAC;IAE5B,+FAA+F;IAC/F,mBAAmB,EAAE,MAAM,CAAC;IAE5B,kGAAkG;IAClG,8BAA8B,EAAE,MAAM,CAAC;IAEvC,oEAAoE;IACpE,UAAU,EAAE,cAAc,GAAG,QAAQ,CAAC;IAEtC,4GAA4G;IAC5G,cAAc,EAAE,eAAe,CAAC;IAEhC,4FAA4F;IAC5F,gBAAgB,EAAE,MAAM,CAAC;IAEzB,uFAAuF;IACvF,aAAa,EAAE,MAAM,CAAC;IAEtB,6FAA6F;IAC7F,kBAAkB,EAAE,MAAM,CAAC;IAE3B,wGAAwG;IACxG,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAmED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,IAAI,mBAAmB,CAuDvD"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Email Gateway Configuration
|
|
4
|
+
*
|
|
5
|
+
* Defines the `IEmailGatewayConfig` interface and a `loadGatewayConfig()` loader
|
|
6
|
+
* that reads values from `environment.emailDomain` (EMAIL_DOMAIN env var) and
|
|
7
|
+
* other environment variables with sensible defaults.
|
|
8
|
+
*
|
|
9
|
+
* All Node.js-specific gateway configuration lives here in brightchain-api-lib.
|
|
10
|
+
* The shared `ISpamThresholds` interface is imported from brightchain-lib.
|
|
11
|
+
*
|
|
12
|
+
* @see Requirements 8.1, 8.2, 8.3, 8.4, 8.5, 8.6, 8.7
|
|
13
|
+
* @module emailGatewayConfig
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.loadGatewayConfig = loadGatewayConfig;
|
|
17
|
+
/** Default mail drop directory path */
|
|
18
|
+
const DEFAULT_MAIL_DROP_DIR = '/var/spool/brightchain/incoming/';
|
|
19
|
+
/** Default error directory path */
|
|
20
|
+
const DEFAULT_ERROR_DIR = '/var/spool/brightchain/errors/';
|
|
21
|
+
/** Default maximum message size: 25 MB */
|
|
22
|
+
const DEFAULT_MAX_MESSAGE_SIZE = 25 * 1024 * 1024;
|
|
23
|
+
/** Default recipient lookup port */
|
|
24
|
+
const DEFAULT_LOOKUP_PORT = 2526;
|
|
25
|
+
/** Default recipient lookup cache TTL in seconds */
|
|
26
|
+
const DEFAULT_LOOKUP_CACHE_TTL = 300;
|
|
27
|
+
/** Default queue concurrency */
|
|
28
|
+
const DEFAULT_QUEUE_CONCURRENCY = 10;
|
|
29
|
+
/** Default retry max count */
|
|
30
|
+
const DEFAULT_RETRY_MAX_COUNT = 5;
|
|
31
|
+
/** Default retry max duration: 48 hours in ms */
|
|
32
|
+
const DEFAULT_RETRY_MAX_DURATION = 48 * 60 * 60 * 1000;
|
|
33
|
+
/** Default retry base interval: 60 seconds in ms */
|
|
34
|
+
const DEFAULT_RETRY_BASE_INTERVAL = 60_000;
|
|
35
|
+
/** Default probable spam score threshold */
|
|
36
|
+
const DEFAULT_SPAM_PROBABLE = 5.0;
|
|
37
|
+
/** Default definite spam score threshold */
|
|
38
|
+
const DEFAULT_SPAM_DEFINITE = 10.0;
|
|
39
|
+
/**
|
|
40
|
+
* Parse an integer from an environment variable, returning a default if unset or invalid.
|
|
41
|
+
*/
|
|
42
|
+
function envInt(name, defaultValue) {
|
|
43
|
+
const raw = process.env[name];
|
|
44
|
+
if (raw === undefined || raw === '') {
|
|
45
|
+
return defaultValue;
|
|
46
|
+
}
|
|
47
|
+
const parsed = parseInt(raw, 10);
|
|
48
|
+
return Number.isNaN(parsed) ? defaultValue : parsed;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Parse a float from an environment variable, returning a default if unset or invalid.
|
|
52
|
+
*/
|
|
53
|
+
function envFloat(name, defaultValue) {
|
|
54
|
+
const raw = process.env[name];
|
|
55
|
+
if (raw === undefined || raw === '') {
|
|
56
|
+
return defaultValue;
|
|
57
|
+
}
|
|
58
|
+
const parsed = parseFloat(raw);
|
|
59
|
+
return Number.isNaN(parsed) ? defaultValue : parsed;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Read a string environment variable, returning a default if unset.
|
|
63
|
+
*/
|
|
64
|
+
function envString(name, defaultValue) {
|
|
65
|
+
const raw = process.env[name];
|
|
66
|
+
return raw !== undefined && raw !== '' ? raw : defaultValue;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Load the Email Gateway configuration from environment variables.
|
|
70
|
+
*
|
|
71
|
+
* The canonical domain is read from the `EMAIL_DOMAIN` env var (matching
|
|
72
|
+
* `environment.emailDomain`). All other settings are read from their
|
|
73
|
+
* respective `GATEWAY_*` env vars with sensible defaults.
|
|
74
|
+
*
|
|
75
|
+
* @returns A fully populated `IEmailGatewayConfig`.
|
|
76
|
+
*
|
|
77
|
+
* @see Requirements 8.1, 8.2, 8.3, 8.4, 8.5, 8.6, 8.7
|
|
78
|
+
*/
|
|
79
|
+
function loadGatewayConfig() {
|
|
80
|
+
const postfixUser = process.env['GATEWAY_POSTFIX_USER'];
|
|
81
|
+
const postfixPass = process.env['GATEWAY_POSTFIX_PASS'];
|
|
82
|
+
return {
|
|
83
|
+
canonicalDomain: envString('EMAIL_DOMAIN', 'example.com'),
|
|
84
|
+
postfixHost: envString('GATEWAY_POSTFIX_HOST', 'localhost'),
|
|
85
|
+
postfixPort: envInt('GATEWAY_POSTFIX_PORT', 25),
|
|
86
|
+
postfixAuth: postfixUser && postfixPass
|
|
87
|
+
? { user: postfixUser, pass: postfixPass }
|
|
88
|
+
: undefined,
|
|
89
|
+
dkimKeyPath: envString('GATEWAY_DKIM_KEY_PATH', '/etc/dkim/private.key'),
|
|
90
|
+
dkimSelector: envString('GATEWAY_DKIM_SELECTOR', 'default'),
|
|
91
|
+
mailDropDirectory: envString('GATEWAY_MAIL_DROP_DIR', DEFAULT_MAIL_DROP_DIR),
|
|
92
|
+
errorDirectory: envString('GATEWAY_ERROR_DIR', DEFAULT_ERROR_DIR),
|
|
93
|
+
maxMessageSizeBytes: envInt('GATEWAY_MAX_MESSAGE_SIZE', DEFAULT_MAX_MESSAGE_SIZE),
|
|
94
|
+
recipientLookupPort: envInt('GATEWAY_LOOKUP_PORT', DEFAULT_LOOKUP_PORT),
|
|
95
|
+
recipientLookupCacheTtlSeconds: envInt('GATEWAY_LOOKUP_CACHE_TTL', DEFAULT_LOOKUP_CACHE_TTL),
|
|
96
|
+
spamEngine: envString('GATEWAY_SPAM_ENGINE', 'spamassassin'),
|
|
97
|
+
spamThresholds: {
|
|
98
|
+
probableSpamScore: envFloat('GATEWAY_SPAM_PROBABLE', DEFAULT_SPAM_PROBABLE),
|
|
99
|
+
definiteSpamScore: envFloat('GATEWAY_SPAM_DEFINITE', DEFAULT_SPAM_DEFINITE),
|
|
100
|
+
},
|
|
101
|
+
queueConcurrency: envInt('GATEWAY_QUEUE_CONCURRENCY', DEFAULT_QUEUE_CONCURRENCY),
|
|
102
|
+
retryMaxCount: envInt('GATEWAY_RETRY_MAX_COUNT', DEFAULT_RETRY_MAX_COUNT),
|
|
103
|
+
retryMaxDurationMs: envInt('GATEWAY_RETRY_MAX_DURATION', DEFAULT_RETRY_MAX_DURATION),
|
|
104
|
+
retryBaseIntervalMs: envInt('GATEWAY_RETRY_BASE_INTERVAL', DEFAULT_RETRY_BASE_INTERVAL),
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=emailGatewayConfig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emailGatewayConfig.js","sourceRoot":"","sources":["../../../../../../brightchain-api-lib/src/lib/services/emailGateway/emailGatewayConfig.ts"],"names":[],"mappings":"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"}
|