@brightchain/brightchain-api-lib 0.29.12 → 0.29.15
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 +1 -1
- package/src/lib/application.d.ts.map +1 -1
- package/src/lib/application.js +57 -26
- package/src/lib/application.js.map +1 -1
- package/src/lib/enumerations/email-services.d.ts +7 -0
- package/src/lib/enumerations/email-services.d.ts.map +1 -0
- package/src/lib/enumerations/email-services.js +11 -0
- package/src/lib/enumerations/email-services.js.map +1 -0
- package/src/lib/environment.d.ts +32 -7
- package/src/lib/environment.d.ts.map +1 -1
- package/src/lib/environment.js +55 -21
- package/src/lib/environment.js.map +1 -1
- package/src/lib/interfaces/environment.d.ts +5 -0
- package/src/lib/interfaces/environment.d.ts.map +1 -1
- package/src/lib/interfaces/index.d.ts +1 -0
- package/src/lib/interfaces/index.d.ts.map +1 -1
- package/src/lib/interfaces/postfix-email-service-config.d.ts +29 -0
- package/src/lib/interfaces/postfix-email-service-config.d.ts.map +1 -0
- package/src/lib/interfaces/postfix-email-service-config.js +3 -0
- package/src/lib/interfaces/postfix-email-service-config.js.map +1 -0
- package/src/lib/routers/api.d.ts +14 -0
- package/src/lib/routers/api.d.ts.map +1 -1
- package/src/lib/routers/api.js +18 -2
- package/src/lib/routers/api.js.map +1 -1
- package/src/lib/services/auth.d.ts +4 -4
- package/src/lib/services/auth.d.ts.map +1 -1
- package/src/lib/services/auth.js +6 -2
- package/src/lib/services/auth.js.map +1 -1
- package/src/lib/services/emailGateway/emailGatewayConfig.d.ts +60 -2
- package/src/lib/services/emailGateway/emailGatewayConfig.d.ts.map +1 -1
- package/src/lib/services/emailGateway/emailGatewayConfig.js +73 -1
- package/src/lib/services/emailGateway/emailGatewayConfig.js.map +1 -1
- package/src/lib/services/emailGateway/index.d.ts +1 -0
- package/src/lib/services/emailGateway/index.d.ts.map +1 -1
- package/src/lib/services/emailGateway/index.js +1 -0
- package/src/lib/services/emailGateway/index.js.map +1 -1
- package/src/lib/services/emailGateway/testModeTransports.d.ts +106 -0
- package/src/lib/services/emailGateway/testModeTransports.d.ts.map +1 -0
- package/src/lib/services/emailGateway/testModeTransports.js +174 -0
- package/src/lib/services/emailGateway/testModeTransports.js.map +1 -0
- package/src/lib/services/index.d.ts +2 -1
- package/src/lib/services/index.d.ts.map +1 -1
- package/src/lib/services/index.js +2 -1
- package/src/lib/services/index.js.map +1 -1
- package/src/lib/services/postfixEmail.d.ts +91 -0
- package/src/lib/services/postfixEmail.d.ts.map +1 -0
- package/src/lib/services/postfixEmail.js +184 -0
- package/src/lib/services/postfixEmail.js.map +1 -0
- package/src/lib/services/{email.d.ts → sesEmail.d.ts} +3 -3
- package/src/lib/services/sesEmail.d.ts.map +1 -0
- package/src/lib/services/{email.js → sesEmail.js} +4 -4
- package/src/lib/services/sesEmail.js.map +1 -0
- package/src/lib/services/email.d.ts.map +0 -1
- package/src/lib/services/email.js.map +0 -1
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test Mode Transports for Email Gateway
|
|
3
|
+
*
|
|
4
|
+
* Provides mock/stub implementations of IPostfixTransport and IDkimSigner
|
|
5
|
+
* for use in test mode. These capture outbound mail to the filesystem
|
|
6
|
+
* instead of delivering via SMTP, enabling local development and testing
|
|
7
|
+
* without real DNS, MX records, or external connectivity.
|
|
8
|
+
*
|
|
9
|
+
* @see Requirement 8.8 — Test mode for local development
|
|
10
|
+
* @module testModeTransports
|
|
11
|
+
*/
|
|
12
|
+
import type { IEmailGatewayConfig } from './emailGatewayConfig';
|
|
13
|
+
import type { IDkimSigner, IPostfixTransport, IPostfixTransportResult } from './outboundDeliveryWorker';
|
|
14
|
+
/**
|
|
15
|
+
* A captured email message stored by the CatchallTransport.
|
|
16
|
+
*/
|
|
17
|
+
export interface ICapturedEmail {
|
|
18
|
+
/** Envelope sender address */
|
|
19
|
+
from: string;
|
|
20
|
+
/** Envelope recipient addresses */
|
|
21
|
+
to: string[];
|
|
22
|
+
/** Raw RFC 5322 message bytes */
|
|
23
|
+
rawMessage: Uint8Array;
|
|
24
|
+
/** Timestamp when the message was captured */
|
|
25
|
+
capturedAt: Date;
|
|
26
|
+
/** Filename in the catchall directory */
|
|
27
|
+
filename: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Test transport that captures outbound mail to the filesystem instead of
|
|
31
|
+
* delivering via SMTP. Messages are stored in Maildir format in the
|
|
32
|
+
* configured catchall directory.
|
|
33
|
+
*
|
|
34
|
+
* This enables inspection of sent messages during development and testing.
|
|
35
|
+
*
|
|
36
|
+
* @see Requirement 8.8 — Test mode for local development
|
|
37
|
+
*/
|
|
38
|
+
export declare class CatchallTransport implements IPostfixTransport {
|
|
39
|
+
private readonly config;
|
|
40
|
+
/** In-memory list of captured emails (for programmatic access in tests) */
|
|
41
|
+
private readonly captured;
|
|
42
|
+
constructor(config: IEmailGatewayConfig);
|
|
43
|
+
/**
|
|
44
|
+
* Capture a message to the catchall directory instead of sending via SMTP.
|
|
45
|
+
*
|
|
46
|
+
* @param from - Envelope sender address
|
|
47
|
+
* @param to - Envelope recipient addresses
|
|
48
|
+
* @param rawMessage - Complete RFC 5322 message bytes
|
|
49
|
+
* @returns Always returns success (250)
|
|
50
|
+
*/
|
|
51
|
+
send(from: string, to: string[], rawMessage: Uint8Array): Promise<IPostfixTransportResult>;
|
|
52
|
+
/**
|
|
53
|
+
* Get all captured emails (for programmatic access in tests).
|
|
54
|
+
*/
|
|
55
|
+
getCapturedEmails(): readonly ICapturedEmail[];
|
|
56
|
+
/**
|
|
57
|
+
* Clear all captured emails (for test cleanup).
|
|
58
|
+
*/
|
|
59
|
+
clearCaptured(): void;
|
|
60
|
+
/**
|
|
61
|
+
* Get the most recently captured email.
|
|
62
|
+
*/
|
|
63
|
+
getLastCaptured(): ICapturedEmail | undefined;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* No-op DKIM signer for test mode. Returns the message unchanged.
|
|
67
|
+
*
|
|
68
|
+
* Use this when DKIM signing should be skipped (e.g., no real key available).
|
|
69
|
+
*
|
|
70
|
+
* @see Requirement 8.8 — Test mode for local development
|
|
71
|
+
*/
|
|
72
|
+
export declare class NoOpDkimSigner implements IDkimSigner {
|
|
73
|
+
/**
|
|
74
|
+
* Return the message unchanged (no DKIM signature applied).
|
|
75
|
+
*/
|
|
76
|
+
sign(rawMessage: Uint8Array, _domain: string, _selector: string): Promise<Uint8Array>;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Test DKIM signer that adds a fake DKIM-Signature header for testing.
|
|
80
|
+
*
|
|
81
|
+
* The signature is not cryptographically valid but allows testing the
|
|
82
|
+
* DKIM signing flow without real key material.
|
|
83
|
+
*/
|
|
84
|
+
export declare class FakeDkimSigner implements IDkimSigner {
|
|
85
|
+
/**
|
|
86
|
+
* Add a fake DKIM-Signature header to the message.
|
|
87
|
+
*/
|
|
88
|
+
sign(rawMessage: Uint8Array, domain: string, selector: string): Promise<Uint8Array>;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Factory function to create the appropriate transport based on config.
|
|
92
|
+
*
|
|
93
|
+
* @param config - Gateway configuration
|
|
94
|
+
* @param productionTransport - The real transport to use in production mode
|
|
95
|
+
* @returns CatchallTransport in test mode with catchall enabled, otherwise productionTransport
|
|
96
|
+
*/
|
|
97
|
+
export declare function createTransport(config: IEmailGatewayConfig, productionTransport: IPostfixTransport): IPostfixTransport;
|
|
98
|
+
/**
|
|
99
|
+
* Factory function to create the appropriate DKIM signer based on config.
|
|
100
|
+
*
|
|
101
|
+
* @param config - Gateway configuration
|
|
102
|
+
* @param productionSigner - The real signer to use in production mode
|
|
103
|
+
* @returns NoOpDkimSigner if test mode with skipDkim, otherwise productionSigner
|
|
104
|
+
*/
|
|
105
|
+
export declare function createDkimSigner(config: IEmailGatewayConfig, productionSigner: IDkimSigner): IDkimSigner;
|
|
106
|
+
//# sourceMappingURL=testModeTransports.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testModeTransports.d.ts","sourceRoot":"","sources":["../../../../../../brightchain-api-lib/src/lib/services/emailGateway/testModeTransports.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,KAAK,EACV,WAAW,EACX,iBAAiB,EACjB,uBAAuB,EACxB,MAAM,0BAA0B,CAAC;AAElC;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,EAAE,EAAE,MAAM,EAAE,CAAC;IACb,iCAAiC;IACjC,UAAU,EAAE,UAAU,CAAC;IACvB,8CAA8C;IAC9C,UAAU,EAAE,IAAI,CAAC;IACjB,yCAAyC;IACzC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;GAQG;AACH,qBAAa,iBAAkB,YAAW,iBAAiB;IAI7C,OAAO,CAAC,QAAQ,CAAC,MAAM;IAHnC,2EAA2E;IAC3E,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwB;gBAEpB,MAAM,EAAE,mBAAmB;IAgBxD;;;;;;;OAOG;IACG,IAAI,CACR,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EAAE,EACZ,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,uBAAuB,CAAC;IA0CnC;;OAEG;IACH,iBAAiB,IAAI,SAAS,cAAc,EAAE;IAI9C;;OAEG;IACH,aAAa,IAAI,IAAI;IAIrB;;OAEG;IACH,eAAe,IAAI,cAAc,GAAG,SAAS;CAG9C;AAED;;;;;;GAMG;AACH,qBAAa,cAAe,YAAW,WAAW;IAChD;;OAEG;IACG,IAAI,CACR,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,UAAU,CAAC;CAGvB;AAED;;;;;GAKG;AACH,qBAAa,cAAe,YAAW,WAAW;IAChD;;OAEG;IACG,IAAI,CACR,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,CAAC;CAevB;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,mBAAmB,EAC3B,mBAAmB,EAAE,iBAAiB,GACrC,iBAAiB,CAKnB;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,mBAAmB,EAC3B,gBAAgB,EAAE,WAAW,GAC5B,WAAW,CAKb"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Test Mode Transports for Email Gateway
|
|
4
|
+
*
|
|
5
|
+
* Provides mock/stub implementations of IPostfixTransport and IDkimSigner
|
|
6
|
+
* for use in test mode. These capture outbound mail to the filesystem
|
|
7
|
+
* instead of delivering via SMTP, enabling local development and testing
|
|
8
|
+
* without real DNS, MX records, or external connectivity.
|
|
9
|
+
*
|
|
10
|
+
* @see Requirement 8.8 — Test mode for local development
|
|
11
|
+
* @module testModeTransports
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.FakeDkimSigner = exports.NoOpDkimSigner = exports.CatchallTransport = void 0;
|
|
15
|
+
exports.createTransport = createTransport;
|
|
16
|
+
exports.createDkimSigner = createDkimSigner;
|
|
17
|
+
const tslib_1 = require("tslib");
|
|
18
|
+
const fs = tslib_1.__importStar(require("fs"));
|
|
19
|
+
const path = tslib_1.__importStar(require("path"));
|
|
20
|
+
/**
|
|
21
|
+
* Test transport that captures outbound mail to the filesystem instead of
|
|
22
|
+
* delivering via SMTP. Messages are stored in Maildir format in the
|
|
23
|
+
* configured catchall directory.
|
|
24
|
+
*
|
|
25
|
+
* This enables inspection of sent messages during development and testing.
|
|
26
|
+
*
|
|
27
|
+
* @see Requirement 8.8 — Test mode for local development
|
|
28
|
+
*/
|
|
29
|
+
class CatchallTransport {
|
|
30
|
+
config;
|
|
31
|
+
/** In-memory list of captured emails (for programmatic access in tests) */
|
|
32
|
+
captured = [];
|
|
33
|
+
constructor(config) {
|
|
34
|
+
this.config = config;
|
|
35
|
+
// Ensure catchall directory structure exists
|
|
36
|
+
const catchallDir = config.testMode.catchallDirectory;
|
|
37
|
+
const dirs = [
|
|
38
|
+
catchallDir,
|
|
39
|
+
path.join(catchallDir, 'new'),
|
|
40
|
+
path.join(catchallDir, 'cur'),
|
|
41
|
+
path.join(catchallDir, 'tmp'),
|
|
42
|
+
];
|
|
43
|
+
for (const dir of dirs) {
|
|
44
|
+
if (!fs.existsSync(dir)) {
|
|
45
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Capture a message to the catchall directory instead of sending via SMTP.
|
|
51
|
+
*
|
|
52
|
+
* @param from - Envelope sender address
|
|
53
|
+
* @param to - Envelope recipient addresses
|
|
54
|
+
* @param rawMessage - Complete RFC 5322 message bytes
|
|
55
|
+
* @returns Always returns success (250)
|
|
56
|
+
*/
|
|
57
|
+
async send(from, to, rawMessage) {
|
|
58
|
+
const timestamp = Date.now();
|
|
59
|
+
const random = Math.random().toString(36).substring(2, 10);
|
|
60
|
+
const filename = `${timestamp}.${random}.catchall`;
|
|
61
|
+
const catchallDir = this.config.testMode.catchallDirectory;
|
|
62
|
+
const tmpPath = path.join(catchallDir, 'tmp', filename);
|
|
63
|
+
const newPath = path.join(catchallDir, 'new', filename);
|
|
64
|
+
// Write to tmp first, then move to new (Maildir semantics)
|
|
65
|
+
await fs.promises.writeFile(tmpPath, rawMessage);
|
|
66
|
+
await fs.promises.rename(tmpPath, newPath);
|
|
67
|
+
// Also write metadata sidecar file for easy inspection
|
|
68
|
+
const metadata = {
|
|
69
|
+
from,
|
|
70
|
+
to,
|
|
71
|
+
capturedAt: new Date().toISOString(),
|
|
72
|
+
sizeBytes: rawMessage.byteLength,
|
|
73
|
+
};
|
|
74
|
+
await fs.promises.writeFile(`${newPath}.meta.json`, JSON.stringify(metadata, null, 2));
|
|
75
|
+
// Track in memory for programmatic access
|
|
76
|
+
const captured = {
|
|
77
|
+
from,
|
|
78
|
+
to,
|
|
79
|
+
rawMessage,
|
|
80
|
+
capturedAt: new Date(),
|
|
81
|
+
filename,
|
|
82
|
+
};
|
|
83
|
+
this.captured.push(captured);
|
|
84
|
+
return {
|
|
85
|
+
success: true,
|
|
86
|
+
responseCode: 250,
|
|
87
|
+
responseMessage: `Message captured to ${filename}`,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Get all captured emails (for programmatic access in tests).
|
|
92
|
+
*/
|
|
93
|
+
getCapturedEmails() {
|
|
94
|
+
return this.captured;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Clear all captured emails (for test cleanup).
|
|
98
|
+
*/
|
|
99
|
+
clearCaptured() {
|
|
100
|
+
this.captured.length = 0;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Get the most recently captured email.
|
|
104
|
+
*/
|
|
105
|
+
getLastCaptured() {
|
|
106
|
+
return this.captured[this.captured.length - 1];
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
exports.CatchallTransport = CatchallTransport;
|
|
110
|
+
/**
|
|
111
|
+
* No-op DKIM signer for test mode. Returns the message unchanged.
|
|
112
|
+
*
|
|
113
|
+
* Use this when DKIM signing should be skipped (e.g., no real key available).
|
|
114
|
+
*
|
|
115
|
+
* @see Requirement 8.8 — Test mode for local development
|
|
116
|
+
*/
|
|
117
|
+
class NoOpDkimSigner {
|
|
118
|
+
/**
|
|
119
|
+
* Return the message unchanged (no DKIM signature applied).
|
|
120
|
+
*/
|
|
121
|
+
async sign(rawMessage, _domain, _selector) {
|
|
122
|
+
return rawMessage;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
exports.NoOpDkimSigner = NoOpDkimSigner;
|
|
126
|
+
/**
|
|
127
|
+
* Test DKIM signer that adds a fake DKIM-Signature header for testing.
|
|
128
|
+
*
|
|
129
|
+
* The signature is not cryptographically valid but allows testing the
|
|
130
|
+
* DKIM signing flow without real key material.
|
|
131
|
+
*/
|
|
132
|
+
class FakeDkimSigner {
|
|
133
|
+
/**
|
|
134
|
+
* Add a fake DKIM-Signature header to the message.
|
|
135
|
+
*/
|
|
136
|
+
async sign(rawMessage, domain, selector) {
|
|
137
|
+
const fakeSignature = `DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=${domain}; ` +
|
|
138
|
+
`s=${selector}; h=from:to:subject:date; ` +
|
|
139
|
+
`b=FAKE_SIGNATURE_FOR_TESTING_ONLY\r\n`;
|
|
140
|
+
const signatureBytes = new TextEncoder().encode(fakeSignature);
|
|
141
|
+
const result = new Uint8Array(signatureBytes.byteLength + rawMessage.byteLength);
|
|
142
|
+
result.set(signatureBytes, 0);
|
|
143
|
+
result.set(rawMessage, signatureBytes.byteLength);
|
|
144
|
+
return result;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
exports.FakeDkimSigner = FakeDkimSigner;
|
|
148
|
+
/**
|
|
149
|
+
* Factory function to create the appropriate transport based on config.
|
|
150
|
+
*
|
|
151
|
+
* @param config - Gateway configuration
|
|
152
|
+
* @param productionTransport - The real transport to use in production mode
|
|
153
|
+
* @returns CatchallTransport in test mode with catchall enabled, otherwise productionTransport
|
|
154
|
+
*/
|
|
155
|
+
function createTransport(config, productionTransport) {
|
|
156
|
+
if (config.testMode.enabled && config.testMode.catchallEnabled) {
|
|
157
|
+
return new CatchallTransport(config);
|
|
158
|
+
}
|
|
159
|
+
return productionTransport;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Factory function to create the appropriate DKIM signer based on config.
|
|
163
|
+
*
|
|
164
|
+
* @param config - Gateway configuration
|
|
165
|
+
* @param productionSigner - The real signer to use in production mode
|
|
166
|
+
* @returns NoOpDkimSigner if test mode with skipDkim, otherwise productionSigner
|
|
167
|
+
*/
|
|
168
|
+
function createDkimSigner(config, productionSigner) {
|
|
169
|
+
if (config.testMode.enabled && config.testMode.skipDkim) {
|
|
170
|
+
return new NoOpDkimSigner();
|
|
171
|
+
}
|
|
172
|
+
return productionSigner;
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=testModeTransports.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testModeTransports.js","sourceRoot":"","sources":["../../../../../../brightchain-api-lib/src/lib/services/emailGateway/testModeTransports.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,7 +11,8 @@ export * from './cliOperatorPrompt';
|
|
|
11
11
|
export * from './contentAwareBlocksService';
|
|
12
12
|
export * from './contentIngestionService';
|
|
13
13
|
export * from './diskQuorumService';
|
|
14
|
-
export * from './
|
|
14
|
+
export * from './sesEmail';
|
|
15
|
+
export * from './postfixEmail';
|
|
15
16
|
export * from './emailGateway';
|
|
16
17
|
export * from './eventNotificationSystem';
|
|
17
18
|
export * from './fakeEmailService';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../brightchain-api-lib/src/lib/services/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,uBAAuB,CAAC;AACtC,cAAc,cAAc,CAAC;AAC7B,cAAc,mCAAmC,CAAC;AAClD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,aAAa,CAAC;AAC5B,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../brightchain-api-lib/src/lib/services/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,uBAAuB,CAAC;AACtC,cAAc,cAAc,CAAC;AAC7B,cAAc,mCAAmC,CAAC;AAClD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,aAAa,CAAC;AAC5B,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iCAAiC,CAAC;AAChD,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,UAAU,CAAC;AACzB,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC;AAC9B,cAAc,QAAQ,CAAC;AACvB,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC"}
|
|
@@ -15,7 +15,8 @@ tslib_1.__exportStar(require("./cliOperatorPrompt"), exports);
|
|
|
15
15
|
tslib_1.__exportStar(require("./contentAwareBlocksService"), exports);
|
|
16
16
|
tslib_1.__exportStar(require("./contentIngestionService"), exports);
|
|
17
17
|
tslib_1.__exportStar(require("./diskQuorumService"), exports);
|
|
18
|
-
tslib_1.__exportStar(require("./
|
|
18
|
+
tslib_1.__exportStar(require("./sesEmail"), exports);
|
|
19
|
+
tslib_1.__exportStar(require("./postfixEmail"), exports);
|
|
19
20
|
tslib_1.__exportStar(require("./emailGateway"), exports);
|
|
20
21
|
tslib_1.__exportStar(require("./eventNotificationSystem"), exports);
|
|
21
22
|
tslib_1.__exportStar(require("./fakeEmailService"), exports);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../brightchain-api-lib/src/lib/services/index.ts"],"names":[],"mappings":";;;;AAAA,iDAAuB;AACvB,iDAAuB;AACvB,mDAAyB;AACzB,gEAAsC;AACtC,uDAA6B;AAC7B,4EAAkD;AAClD,yEAA+C;AAC/C,sDAA4B;AAC5B,kEAAwC;AACxC,8DAAoC;AACpC,sEAA4C;AAC5C,oEAA0C;AAC1C,8DAAoC;AACpC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../brightchain-api-lib/src/lib/services/index.ts"],"names":[],"mappings":";;;;AAAA,iDAAuB;AACvB,iDAAuB;AACvB,mDAAyB;AACzB,gEAAsC;AACtC,uDAA6B;AAC7B,4EAAkD;AAClD,yEAA+C;AAC/C,sDAA4B;AAC5B,kEAAwC;AACxC,8DAAoC;AACpC,sEAA4C;AAC5C,oEAA0C;AAC1C,8DAAoC;AACpC,qDAA2B;AAC3B,yDAA+B;AAC/B,yDAA+B;AAC/B,oEAA0C;AAC1C,6DAAmC;AACnC,6BAAuC;AAA9B,qGAAA,cAAc,OAAA;AACvB,8DAAoC;AACpC,4DAAkC;AAClC,wEAA8C;AAC9C,0EAAgD;AAChD,kEAAwC;AACxC,kEAAwC;AACxC,+DAAqC;AACrC,4DAAkC;AAClC,mDAAyB;AACzB,kEAAwC;AACxC,+DAAqC;AACrC,wDAA8B;AAC9B,iDAAuB;AACvB,6DAAmC;AACnC,2DAAiC;AACjC,6DAAmC;AACnC,mEAAyC;AACzC,kEAAwC;AACxC,sEAA4C"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Postfix email service for sending emails via local Postfix MTA.
|
|
3
|
+
* Implements IEmailService interface for compatibility with the application's
|
|
4
|
+
* email service abstraction.
|
|
5
|
+
*
|
|
6
|
+
* Uses nodemailer with SMTP transport to connect to a local or remote Postfix
|
|
7
|
+
* server. Configuration is read from the email gateway config (environment variables).
|
|
8
|
+
*
|
|
9
|
+
* @module services/postfixEmail
|
|
10
|
+
*/
|
|
11
|
+
import { PlatformID } from '@digitaldefiance/node-ecies-lib';
|
|
12
|
+
import { IApplication, IEmailService } from '@digitaldefiance/node-express-suite';
|
|
13
|
+
import { IPostfixEmailServiceConfig } from '../interfaces';
|
|
14
|
+
import { DefaultBackendIdType } from '../types/backend-id';
|
|
15
|
+
/**
|
|
16
|
+
* Email service implementation using Postfix MTA via SMTP.
|
|
17
|
+
*
|
|
18
|
+
* This service connects to a Postfix server (local or remote) to send emails.
|
|
19
|
+
* It's designed as an alternative to SES for self-hosted deployments.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* // Using with application context
|
|
24
|
+
* const emailService = new PostfixEmailService(application);
|
|
25
|
+
* await emailService.sendEmail(
|
|
26
|
+
* 'user@example.com',
|
|
27
|
+
* 'Welcome!',
|
|
28
|
+
* 'Plain text body',
|
|
29
|
+
* '<h1>HTML body</h1>'
|
|
30
|
+
* );
|
|
31
|
+
*
|
|
32
|
+
* // Using with explicit config
|
|
33
|
+
* const emailService = PostfixEmailService.fromConfig({
|
|
34
|
+
* host: 'localhost',
|
|
35
|
+
* port: 25,
|
|
36
|
+
* emailSender: 'noreply@brightchain.org',
|
|
37
|
+
* });
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export declare class PostfixEmailService<TID extends PlatformID = DefaultBackendIdType> implements IEmailService {
|
|
41
|
+
private readonly transporter;
|
|
42
|
+
private readonly emailSender;
|
|
43
|
+
private readonly disableEmailSend;
|
|
44
|
+
private readonly debug;
|
|
45
|
+
/**
|
|
46
|
+
* Constructs a PostfixEmailService using application context.
|
|
47
|
+
*
|
|
48
|
+
* Reads Postfix connection settings from the email gateway configuration
|
|
49
|
+
* (environment variables) and email sender from the application environment.
|
|
50
|
+
*
|
|
51
|
+
* @param application - The application context containing environment config
|
|
52
|
+
*/
|
|
53
|
+
constructor(application: IApplication<TID>);
|
|
54
|
+
/**
|
|
55
|
+
* Creates a PostfixEmailService with explicit configuration.
|
|
56
|
+
*
|
|
57
|
+
* Use this factory method when you need fine-grained control over the
|
|
58
|
+
* Postfix connection settings or when not using the application context.
|
|
59
|
+
*
|
|
60
|
+
* @param config - Explicit configuration options
|
|
61
|
+
* @returns A configured PostfixEmailService instance
|
|
62
|
+
*/
|
|
63
|
+
static fromConfig(config: IPostfixEmailServiceConfig): PostfixEmailService;
|
|
64
|
+
/**
|
|
65
|
+
* Sends an email via the Postfix SMTP server.
|
|
66
|
+
*
|
|
67
|
+
* @param to - Recipient email address
|
|
68
|
+
* @param subject - Email subject line
|
|
69
|
+
* @param text - Plain text body of the email
|
|
70
|
+
* @param html - HTML body of the email
|
|
71
|
+
* @returns Promise that resolves when the email is sent
|
|
72
|
+
* @throws Error if email sending fails
|
|
73
|
+
*/
|
|
74
|
+
sendEmail(to: string, subject: string, text: string, html: string): Promise<void>;
|
|
75
|
+
/**
|
|
76
|
+
* Verifies the SMTP connection to Postfix.
|
|
77
|
+
*
|
|
78
|
+
* Useful for health checks and startup validation.
|
|
79
|
+
*
|
|
80
|
+
* @returns Promise that resolves to true if connection is successful
|
|
81
|
+
* @throws Error if connection verification fails
|
|
82
|
+
*/
|
|
83
|
+
verifyConnection(): Promise<boolean>;
|
|
84
|
+
/**
|
|
85
|
+
* Closes the SMTP connection pool.
|
|
86
|
+
*
|
|
87
|
+
* Call this when shutting down the service to clean up resources.
|
|
88
|
+
*/
|
|
89
|
+
close(): void;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=postfixEmail.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postfixEmail.d.ts","sourceRoot":"","sources":["../../../../../brightchain-api-lib/src/lib/services/postfixEmail.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC7D,OAAO,EACL,YAAY,EACZ,aAAa,EACd,MAAM,qCAAqC,CAAC;AAG7C,OAAO,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAqB3D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAAa,mBAAmB,CAAC,GAAG,SAAS,UAAU,GAAG,oBAAoB,CAC5E,YAAW,aAAa;IAExB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA6C;IACzE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAU;IAC3C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAU;IAEhC;;;;;;;OAOG;gBACS,WAAW,EAAE,YAAY,CAAC,GAAG,CAAC;IAoB1C;;;;;;;;OAQG;WACW,UAAU,CACtB,MAAM,EAAE,0BAA0B,GACjC,mBAAmB;IAwCtB;;;;;;;;;OASG;IACU,SAAS,CACpB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC;IA2ChB;;;;;;;OAOG;IACU,gBAAgB,IAAI,OAAO,CAAC,OAAO,CAAC;IAoBjD;;;;OAIG;IACI,KAAK,IAAI,IAAI;CAIrB"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview Postfix email service for sending emails via local Postfix MTA.
|
|
4
|
+
* Implements IEmailService interface for compatibility with the application's
|
|
5
|
+
* email service abstraction.
|
|
6
|
+
*
|
|
7
|
+
* Uses nodemailer with SMTP transport to connect to a local or remote Postfix
|
|
8
|
+
* server. Configuration is read from the email gateway config (environment variables).
|
|
9
|
+
*
|
|
10
|
+
* @module services/postfixEmail
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.PostfixEmailService = void 0;
|
|
14
|
+
const nodemailer_1 = require("nodemailer");
|
|
15
|
+
const emailGatewayConfig_1 = require("./emailGateway/emailGatewayConfig");
|
|
16
|
+
/**
|
|
17
|
+
* Debug logging helper.
|
|
18
|
+
*/
|
|
19
|
+
function debugLog(debug, type, message,
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
21
|
+
...args) {
|
|
22
|
+
if (debug) {
|
|
23
|
+
console[type](`[PostfixEmailService] ${message}`, ...args);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Email service implementation using Postfix MTA via SMTP.
|
|
28
|
+
*
|
|
29
|
+
* This service connects to a Postfix server (local or remote) to send emails.
|
|
30
|
+
* It's designed as an alternative to SES for self-hosted deployments.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```typescript
|
|
34
|
+
* // Using with application context
|
|
35
|
+
* const emailService = new PostfixEmailService(application);
|
|
36
|
+
* await emailService.sendEmail(
|
|
37
|
+
* 'user@example.com',
|
|
38
|
+
* 'Welcome!',
|
|
39
|
+
* 'Plain text body',
|
|
40
|
+
* '<h1>HTML body</h1>'
|
|
41
|
+
* );
|
|
42
|
+
*
|
|
43
|
+
* // Using with explicit config
|
|
44
|
+
* const emailService = PostfixEmailService.fromConfig({
|
|
45
|
+
* host: 'localhost',
|
|
46
|
+
* port: 25,
|
|
47
|
+
* emailSender: 'noreply@brightchain.org',
|
|
48
|
+
* });
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
class PostfixEmailService {
|
|
52
|
+
transporter;
|
|
53
|
+
emailSender;
|
|
54
|
+
disableEmailSend;
|
|
55
|
+
debug;
|
|
56
|
+
/**
|
|
57
|
+
* Constructs a PostfixEmailService using application context.
|
|
58
|
+
*
|
|
59
|
+
* Reads Postfix connection settings from the email gateway configuration
|
|
60
|
+
* (environment variables) and email sender from the application environment.
|
|
61
|
+
*
|
|
62
|
+
* @param application - The application context containing environment config
|
|
63
|
+
*/
|
|
64
|
+
constructor(application) {
|
|
65
|
+
const gatewayConfig = (0, emailGatewayConfig_1.loadGatewayConfig)();
|
|
66
|
+
this.emailSender = application.environment.emailSender;
|
|
67
|
+
this.disableEmailSend = application.environment.disableEmailSend;
|
|
68
|
+
this.debug = application.environment.debug;
|
|
69
|
+
this.transporter = (0, nodemailer_1.createTransport)({
|
|
70
|
+
host: gatewayConfig.postfixHost,
|
|
71
|
+
port: gatewayConfig.postfixPort,
|
|
72
|
+
secure: false, // Postfix typically uses STARTTLS or plain on port 25
|
|
73
|
+
auth: gatewayConfig.postfixAuth,
|
|
74
|
+
connectionTimeout: 10000,
|
|
75
|
+
socketTimeout: 10000,
|
|
76
|
+
tls: {
|
|
77
|
+
rejectUnauthorized: false, // Allow self-signed certs for local Postfix
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Creates a PostfixEmailService with explicit configuration.
|
|
83
|
+
*
|
|
84
|
+
* Use this factory method when you need fine-grained control over the
|
|
85
|
+
* Postfix connection settings or when not using the application context.
|
|
86
|
+
*
|
|
87
|
+
* @param config - Explicit configuration options
|
|
88
|
+
* @returns A configured PostfixEmailService instance
|
|
89
|
+
*/
|
|
90
|
+
static fromConfig(config) {
|
|
91
|
+
const instance = Object.create(PostfixEmailService.prototype);
|
|
92
|
+
// Use Object.defineProperty to set readonly fields
|
|
93
|
+
Object.defineProperty(instance, 'emailSender', {
|
|
94
|
+
value: config.emailSender,
|
|
95
|
+
writable: false,
|
|
96
|
+
});
|
|
97
|
+
Object.defineProperty(instance, 'disableEmailSend', {
|
|
98
|
+
value: config.disableEmailSend ?? false,
|
|
99
|
+
writable: false,
|
|
100
|
+
});
|
|
101
|
+
Object.defineProperty(instance, 'debug', {
|
|
102
|
+
value: config.debug ?? false,
|
|
103
|
+
writable: false,
|
|
104
|
+
});
|
|
105
|
+
const transporter = (0, nodemailer_1.createTransport)({
|
|
106
|
+
host: config.host ?? 'localhost',
|
|
107
|
+
port: config.port ?? 25,
|
|
108
|
+
secure: config.secure ?? false,
|
|
109
|
+
auth: config.auth,
|
|
110
|
+
connectionTimeout: config.connectionTimeout ?? 10000,
|
|
111
|
+
socketTimeout: config.socketTimeout ?? 10000,
|
|
112
|
+
ignoreTLS: config.ignoreTLS ?? true,
|
|
113
|
+
tls: {
|
|
114
|
+
rejectUnauthorized: false,
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
Object.defineProperty(instance, 'transporter', {
|
|
118
|
+
value: transporter,
|
|
119
|
+
writable: false,
|
|
120
|
+
});
|
|
121
|
+
return instance;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Sends an email via the Postfix SMTP server.
|
|
125
|
+
*
|
|
126
|
+
* @param to - Recipient email address
|
|
127
|
+
* @param subject - Email subject line
|
|
128
|
+
* @param text - Plain text body of the email
|
|
129
|
+
* @param html - HTML body of the email
|
|
130
|
+
* @returns Promise that resolves when the email is sent
|
|
131
|
+
* @throws Error if email sending fails
|
|
132
|
+
*/
|
|
133
|
+
async sendEmail(to, subject, text, html) {
|
|
134
|
+
if (this.disableEmailSend) {
|
|
135
|
+
debugLog(this.debug, 'log', `Email sending disabled for: ${to} - Subject: ${subject}`);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
debugLog(this.debug, 'log', `Sending email to ${to} with subject: ${subject}`);
|
|
139
|
+
try {
|
|
140
|
+
const info = await this.transporter.sendMail({
|
|
141
|
+
from: this.emailSender,
|
|
142
|
+
to,
|
|
143
|
+
subject,
|
|
144
|
+
text,
|
|
145
|
+
html,
|
|
146
|
+
});
|
|
147
|
+
debugLog(this.debug, 'log', `Email sent successfully to ${to}, messageId: ${info.messageId}`);
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
console.error(`[PostfixEmailService] Failed to send email to ${to}:`, error);
|
|
151
|
+
throw new Error(`Failed to send email via Postfix: ${error instanceof Error ? error.message : String(error)}`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Verifies the SMTP connection to Postfix.
|
|
156
|
+
*
|
|
157
|
+
* Useful for health checks and startup validation.
|
|
158
|
+
*
|
|
159
|
+
* @returns Promise that resolves to true if connection is successful
|
|
160
|
+
* @throws Error if connection verification fails
|
|
161
|
+
*/
|
|
162
|
+
async verifyConnection() {
|
|
163
|
+
try {
|
|
164
|
+
await this.transporter.verify();
|
|
165
|
+
debugLog(this.debug, 'log', 'Postfix SMTP connection verified');
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
catch (error) {
|
|
169
|
+
debugLog(this.debug, 'error', 'Postfix SMTP connection verification failed:', error);
|
|
170
|
+
throw new Error(`Postfix connection verification failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Closes the SMTP connection pool.
|
|
175
|
+
*
|
|
176
|
+
* Call this when shutting down the service to clean up resources.
|
|
177
|
+
*/
|
|
178
|
+
close() {
|
|
179
|
+
this.transporter.close();
|
|
180
|
+
debugLog(this.debug, 'log', 'Postfix SMTP connection closed');
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
exports.PostfixEmailService = PostfixEmailService;
|
|
184
|
+
//# sourceMappingURL=postfixEmail.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postfixEmail.js","sourceRoot":"","sources":["../../../../../brightchain-api-lib/src/lib/services/postfixEmail.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { PlatformID } from '@digitaldefiance/node-ecies-lib';
|
|
2
|
-
import { IApplication } from '@digitaldefiance/node-express-suite';
|
|
2
|
+
import { IApplication, IEmailService } from '@digitaldefiance/node-express-suite';
|
|
3
3
|
import { DefaultBackendIdType } from '../types/backend-id';
|
|
4
4
|
/**
|
|
5
5
|
* A generic service for sending emails using Amazon SES.
|
|
6
6
|
*/
|
|
7
|
-
export declare class
|
|
7
|
+
export declare class SESEmailService<TID extends PlatformID = DefaultBackendIdType> implements IEmailService {
|
|
8
8
|
private readonly sesClient;
|
|
9
9
|
private readonly emailSender;
|
|
10
10
|
private readonly disableEmailSend;
|
|
@@ -26,4 +26,4 @@ export declare class EmailService<TID extends PlatformID = DefaultBackendIdType>
|
|
|
26
26
|
*/
|
|
27
27
|
sendEmail(to: string, subject: string, text: string, html: string): Promise<void>;
|
|
28
28
|
}
|
|
29
|
-
//# sourceMappingURL=
|
|
29
|
+
//# sourceMappingURL=sesEmail.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sesEmail.d.ts","sourceRoot":"","sources":["../../../../../brightchain-api-lib/src/lib/services/sesEmail.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC7D,OAAO,EACL,YAAY,EACZ,aAAa,EACd,MAAM,qCAAqC,CAAC;AAE7C,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAa3D;;GAEG;AACH,qBAAa,eAAe,CAAC,GAAG,SAAS,UAAU,GAAG,oBAAoB,CACxE,YAAW,aAAa;IAExB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAU;IAC3C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAU;IAChC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAoB;IAEhD;;;OAGG;gBACS,WAAW,EAAE,YAAY,CAAC,GAAG,CAAC;IAiB1C;;;;;;;;OAQG;IACU,SAAS,CACpB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC;CAiDjB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.SESEmailService = void 0;
|
|
4
4
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
5
5
|
const client_ses_1 = require("@aws-sdk/client-ses");
|
|
6
6
|
// import { debugLog } from '../utils';
|
|
@@ -12,7 +12,7 @@ const debugLog = (debug, type, message, ...args) => {
|
|
|
12
12
|
/**
|
|
13
13
|
* A generic service for sending emails using Amazon SES.
|
|
14
14
|
*/
|
|
15
|
-
class
|
|
15
|
+
class SESEmailService {
|
|
16
16
|
sesClient;
|
|
17
17
|
emailSender;
|
|
18
18
|
disableEmailSend;
|
|
@@ -83,5 +83,5 @@ class EmailService {
|
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
|
-
exports.
|
|
87
|
-
//# sourceMappingURL=
|
|
86
|
+
exports.SESEmailService = SESEmailService;
|
|
87
|
+
//# sourceMappingURL=sesEmail.js.map
|