@push.rocks/smartmta 5.3.1 → 5.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/changelog.md +15 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/mail/core/classes.bouncemanager.d.ts +2 -1
- package/dist_ts/mail/core/classes.bouncemanager.js +6 -5
- package/dist_ts/mail/delivery/classes.delivery.queue.d.ts +3 -2
- package/dist_ts/mail/delivery/classes.delivery.queue.js +4 -1
- package/dist_ts/mail/index.d.ts +1 -0
- package/dist_ts/mail/index.js +2 -1
- package/dist_ts/mail/interfaces.storage.d.ts +7 -0
- package/dist_ts/mail/interfaces.storage.js +4 -0
- package/dist_ts/mail/routing/classes.dkim.manager.d.ts +2 -1
- package/dist_ts/mail/routing/classes.dkim.manager.js +17 -8
- package/dist_ts/mail/routing/classes.dns.manager.d.ts +1 -5
- package/dist_ts/mail/routing/classes.dns.manager.js +2 -2
- package/dist_ts/mail/routing/classes.email.router.d.ts +2 -1
- package/dist_ts/mail/routing/classes.email.router.js +6 -5
- package/dist_ts/mail/routing/classes.unified.email.server.d.ts +17 -3
- package/dist_ts/mail/routing/classes.unified.email.server.js +32 -8
- package/dist_ts/mail/security/classes.dkimcreator.d.ts +10 -5
- package/dist_ts/mail/security/classes.dkimcreator.js +91 -70
- package/dist_ts/security/classes.ipreputationchecker.d.ts +4 -3
- package/dist_ts/security/classes.ipreputationchecker.js +4 -3
- package/package.json +11 -11
- package/readme.hints.md +1 -1
- package/readme.md +17 -0
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/mail/core/classes.bouncemanager.ts +7 -6
- package/ts/mail/delivery/classes.delivery.queue.ts +7 -3
- package/ts/mail/index.ts +2 -1
- package/ts/mail/interfaces.storage.ts +13 -0
- package/ts/mail/routing/classes.dkim.manager.ts +24 -11
- package/ts/mail/routing/classes.dns.manager.ts +3 -8
- package/ts/mail/routing/classes.email.router.ts +7 -6
- package/ts/mail/routing/classes.unified.email.server.ts +52 -12
- package/ts/mail/security/classes.dkimcreator.ts +115 -91
- package/ts/security/classes.ipreputationchecker.ts +7 -6
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as plugins from '../../plugins.js';
|
|
2
2
|
import * as paths from '../../paths.js';
|
|
3
|
+
import { type IStorageManagerLike, hasStorageManagerMethods } from '../interfaces.storage.js';
|
|
3
4
|
|
|
4
5
|
import { Email } from '../core/classes.email.js';
|
|
5
6
|
// MtaService reference removed
|
|
@@ -24,13 +25,47 @@ export interface IDkimKeyMetadata {
|
|
|
24
25
|
|
|
25
26
|
export class DKIMCreator {
|
|
26
27
|
private keysDir: string;
|
|
27
|
-
private storageManager?:
|
|
28
|
+
private storageManager?: IStorageManagerLike;
|
|
28
29
|
|
|
29
|
-
constructor(keysDir = paths.keysDir, storageManager?:
|
|
30
|
+
constructor(keysDir = paths.keysDir, storageManager?: IStorageManagerLike) {
|
|
30
31
|
this.keysDir = keysDir;
|
|
31
32
|
this.storageManager = storageManager;
|
|
32
33
|
}
|
|
33
34
|
|
|
35
|
+
private async writeKeyPairToFilesystem(
|
|
36
|
+
privateKeyPath: string,
|
|
37
|
+
publicKeyPath: string,
|
|
38
|
+
privateKey: string,
|
|
39
|
+
publicKey: string,
|
|
40
|
+
): Promise<void> {
|
|
41
|
+
await Promise.all([writeFile(privateKeyPath, privateKey), writeFile(publicKeyPath, publicKey)]);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
private async storeLegacyKeysToStorage(domain: string, privateKey: string, publicKey: string): Promise<void> {
|
|
45
|
+
if (!hasStorageManagerMethods(this.storageManager, ['set'])) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
await Promise.all([
|
|
49
|
+
this.storageManager.set(`/email/dkim/${domain}/private.key`, privateKey),
|
|
50
|
+
this.storageManager.set(`/email/dkim/${domain}/public.key`, publicKey),
|
|
51
|
+
]);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
private async storeSelectorKeysToStorage(
|
|
55
|
+
domain: string,
|
|
56
|
+
selector: string,
|
|
57
|
+
privateKey: string,
|
|
58
|
+
publicKey: string,
|
|
59
|
+
): Promise<void> {
|
|
60
|
+
if (!hasStorageManagerMethods(this.storageManager, ['set'])) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
await Promise.all([
|
|
64
|
+
this.storageManager.set(`/email/dkim/${domain}/${selector}/private.key`, privateKey),
|
|
65
|
+
this.storageManager.set(`/email/dkim/${domain}/${selector}/public.key`, publicKey),
|
|
66
|
+
]);
|
|
67
|
+
}
|
|
68
|
+
|
|
34
69
|
public async getKeyPathsForDomain(domainArg: string): Promise<IKeyPaths> {
|
|
35
70
|
return {
|
|
36
71
|
privateKeyPath: plugins.path.join(this.keysDir, `${domainArg}-private.pem`),
|
|
@@ -51,6 +86,20 @@ export class DKIMCreator {
|
|
|
51
86
|
}
|
|
52
87
|
}
|
|
53
88
|
|
|
89
|
+
public async handleDKIMKeysForSelector(domainArg: string, selector: string = 'default', keySize: number = 2048): Promise<void> {
|
|
90
|
+
if (selector === 'default') {
|
|
91
|
+
await this.handleDKIMKeysForDomain(domainArg);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
try {
|
|
96
|
+
await this.readDKIMKeysForSelector(domainArg, selector);
|
|
97
|
+
} catch {
|
|
98
|
+
console.log(`No DKIM keys found for ${domainArg}/${selector}. Generating...`);
|
|
99
|
+
await this.createAndStoreDKIMKeysForSelector(domainArg, selector, keySize);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
54
103
|
public async handleDKIMKeysForEmail(email: Email): Promise<void> {
|
|
55
104
|
const domain = email.from.split('@')[1];
|
|
56
105
|
await this.handleDKIMKeysForDomain(domain);
|
|
@@ -59,7 +108,7 @@ export class DKIMCreator {
|
|
|
59
108
|
// Read DKIM keys - always use storage manager, migrate from filesystem if needed
|
|
60
109
|
public async readDKIMKeys(domainArg: string): Promise<{ privateKey: string; publicKey: string }> {
|
|
61
110
|
// Try to read from storage manager first
|
|
62
|
-
if (this.storageManager) {
|
|
111
|
+
if (hasStorageManagerMethods(this.storageManager, ['get', 'set'])) {
|
|
63
112
|
try {
|
|
64
113
|
const [privateKey, publicKey] = await Promise.all([
|
|
65
114
|
this.storageManager.get(`/email/dkim/${domainArg}/private.key`),
|
|
@@ -87,10 +136,7 @@ export class DKIMCreator {
|
|
|
87
136
|
|
|
88
137
|
// Migrate to storage manager
|
|
89
138
|
console.log(`Migrating DKIM keys for ${domainArg} from filesystem to StorageManager`);
|
|
90
|
-
await
|
|
91
|
-
this.storageManager.set(`/email/dkim/${domainArg}/private.key`, privateKey),
|
|
92
|
-
this.storageManager.set(`/email/dkim/${domainArg}/public.key`, publicKey)
|
|
93
|
-
]);
|
|
139
|
+
await this.storeLegacyKeysToStorage(domainArg, privateKey, publicKey);
|
|
94
140
|
|
|
95
141
|
return { privateKey, publicKey };
|
|
96
142
|
} catch (error) {
|
|
@@ -116,9 +162,9 @@ export class DKIMCreator {
|
|
|
116
162
|
}
|
|
117
163
|
|
|
118
164
|
// Create an RSA DKIM key pair - changed to public for API access
|
|
119
|
-
public async createDKIMKeys(): Promise<{ privateKey: string; publicKey: string }> {
|
|
165
|
+
public async createDKIMKeys(keySize: number = 2048): Promise<{ privateKey: string; publicKey: string }> {
|
|
120
166
|
const { privateKey, publicKey } = await generateKeyPair('rsa', {
|
|
121
|
-
modulusLength:
|
|
167
|
+
modulusLength: keySize,
|
|
122
168
|
publicKeyEncoding: { type: 'spki', format: 'pem' },
|
|
123
169
|
privateKeyEncoding: { type: 'pkcs1', format: 'pem' },
|
|
124
170
|
});
|
|
@@ -136,75 +182,58 @@ export class DKIMCreator {
|
|
|
136
182
|
return { privateKey, publicKey };
|
|
137
183
|
}
|
|
138
184
|
|
|
139
|
-
// Store a DKIM key pair - uses storage manager if available, else disk
|
|
140
|
-
public async storeDKIMKeys(
|
|
141
|
-
privateKey: string,
|
|
142
|
-
publicKey: string,
|
|
143
|
-
privateKeyPath: string,
|
|
144
|
-
publicKeyPath: string
|
|
145
|
-
): Promise<void> {
|
|
146
|
-
// Store in storage manager if available
|
|
147
|
-
if (this.storageManager) {
|
|
148
|
-
// Extract domain from path (e.g., /path/to/keys/example.com-private.pem -> example.com)
|
|
149
|
-
const match = privateKeyPath.match(/\/([^\/]+)-private\.pem$/);
|
|
150
|
-
if (match) {
|
|
151
|
-
const domain = match[1];
|
|
152
|
-
await Promise.all([
|
|
153
|
-
this.storageManager.set(`/email/dkim/${domain}/private.key`, privateKey),
|
|
154
|
-
this.storageManager.set(`/email/dkim/${domain}/public.key`, publicKey)
|
|
155
|
-
]);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// Also store to filesystem for backward compatibility
|
|
160
|
-
await Promise.all([writeFile(privateKeyPath, privateKey), writeFile(publicKeyPath, publicKey)]);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
185
|
// Create a DKIM key pair and store it to disk - changed to public for API access
|
|
164
|
-
public async createAndStoreDKIMKeys(domain: string): Promise<void> {
|
|
165
|
-
const { privateKey, publicKey } = await this.createDKIMKeys();
|
|
186
|
+
public async createAndStoreDKIMKeys(domain: string, keySize: number = 2048): Promise<void> {
|
|
187
|
+
const { privateKey, publicKey } = await this.createDKIMKeys(keySize);
|
|
166
188
|
const keyPaths = await this.getKeyPathsForDomain(domain);
|
|
167
|
-
await this.
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
189
|
+
await this.storeLegacyKeysToStorage(domain, privateKey, publicKey);
|
|
190
|
+
await this.writeKeyPairToFilesystem(keyPaths.privateKeyPath, keyPaths.publicKeyPath, privateKey, publicKey);
|
|
191
|
+
await this.saveKeyMetadata({
|
|
192
|
+
domain,
|
|
193
|
+
selector: 'default',
|
|
194
|
+
createdAt: Date.now(),
|
|
195
|
+
keySize,
|
|
196
|
+
});
|
|
173
197
|
console.log(`DKIM keys for ${domain} created and stored.`);
|
|
174
198
|
}
|
|
175
199
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
.replace(pemHeader, '')
|
|
186
|
-
.replace(pemFooter, '')
|
|
187
|
-
.replace(/\n/g, '');
|
|
188
|
-
|
|
189
|
-
// Detect key type from PEM header
|
|
190
|
-
const keyAlgo = keys.privateKey.includes('ED25519') || keys.publicKey.length < 200 ? 'ed25519' : 'rsa';
|
|
200
|
+
public async createAndStoreDKIMKeysForSelector(
|
|
201
|
+
domain: string,
|
|
202
|
+
selector: string,
|
|
203
|
+
keySize: number = 2048,
|
|
204
|
+
): Promise<void> {
|
|
205
|
+
if (selector === 'default') {
|
|
206
|
+
await this.createAndStoreDKIMKeys(domain, keySize);
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
191
209
|
|
|
192
|
-
|
|
193
|
-
const
|
|
210
|
+
const { privateKey, publicKey } = await this.createDKIMKeys(keySize);
|
|
211
|
+
const keyPaths = await this.getKeyPathsForSelector(domain, selector);
|
|
212
|
+
await this.storeSelectorKeysToStorage(domain, selector, privateKey, publicKey);
|
|
213
|
+
await this.writeKeyPairToFilesystem(keyPaths.privateKeyPath, keyPaths.publicKeyPath, privateKey, publicKey);
|
|
214
|
+
await this.saveKeyMetadata({
|
|
215
|
+
domain,
|
|
216
|
+
selector,
|
|
217
|
+
createdAt: Date.now(),
|
|
218
|
+
keySize,
|
|
219
|
+
});
|
|
220
|
+
console.log(`DKIM keys for ${domain}/${selector} created and stored.`);
|
|
221
|
+
}
|
|
194
222
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
223
|
+
// Changed to public for API access
|
|
224
|
+
public async getDNSRecordForDomain(
|
|
225
|
+
domainArg: string,
|
|
226
|
+
selector: string = 'default',
|
|
227
|
+
): Promise<plugins.tsclass.network.IDnsRecord> {
|
|
228
|
+
await this.handleDKIMKeysForSelector(domainArg, selector);
|
|
229
|
+
return this.getDNSRecordForSelector(domainArg, selector);
|
|
201
230
|
}
|
|
202
231
|
|
|
203
232
|
/**
|
|
204
233
|
* Get DKIM key metadata for a domain
|
|
205
234
|
*/
|
|
206
235
|
private async getKeyMetadata(domain: string, selector: string = 'default'): Promise<IDkimKeyMetadata | null> {
|
|
207
|
-
if (!this.storageManager) {
|
|
236
|
+
if (!hasStorageManagerMethods(this.storageManager, ['get'])) {
|
|
208
237
|
return null;
|
|
209
238
|
}
|
|
210
239
|
|
|
@@ -222,7 +251,7 @@ export class DKIMCreator {
|
|
|
222
251
|
* Save DKIM key metadata
|
|
223
252
|
*/
|
|
224
253
|
private async saveKeyMetadata(metadata: IDkimKeyMetadata): Promise<void> {
|
|
225
|
-
if (!this.storageManager) {
|
|
254
|
+
if (!hasStorageManagerMethods(this.storageManager, ['set'])) {
|
|
226
255
|
return;
|
|
227
256
|
}
|
|
228
257
|
|
|
@@ -259,30 +288,16 @@ export class DKIMCreator {
|
|
|
259
288
|
const newSelector = `key${now.getFullYear()}${String(now.getMonth() + 1).padStart(2, '0')}`;
|
|
260
289
|
|
|
261
290
|
// Create new keys with custom key size
|
|
262
|
-
const { privateKey, publicKey } = await
|
|
263
|
-
modulusLength: keySize,
|
|
264
|
-
publicKeyEncoding: { type: 'spki', format: 'pem' },
|
|
265
|
-
privateKeyEncoding: { type: 'pkcs1', format: 'pem' },
|
|
266
|
-
});
|
|
291
|
+
const { privateKey, publicKey } = await this.createDKIMKeys(keySize);
|
|
267
292
|
|
|
268
293
|
// Store new keys with new selector
|
|
269
294
|
const newKeyPaths = await this.getKeyPathsForSelector(domain, newSelector);
|
|
270
295
|
|
|
271
296
|
// Store in storage manager if available
|
|
272
|
-
|
|
273
|
-
await Promise.all([
|
|
274
|
-
this.storageManager.set(`/email/dkim/${domain}/${newSelector}/private.key`, privateKey),
|
|
275
|
-
this.storageManager.set(`/email/dkim/${domain}/${newSelector}/public.key`, publicKey)
|
|
276
|
-
]);
|
|
277
|
-
}
|
|
297
|
+
await this.storeSelectorKeysToStorage(domain, newSelector, privateKey, publicKey);
|
|
278
298
|
|
|
279
299
|
// Also store to filesystem
|
|
280
|
-
await this.
|
|
281
|
-
privateKey,
|
|
282
|
-
publicKey,
|
|
283
|
-
newKeyPaths.privateKeyPath,
|
|
284
|
-
newKeyPaths.publicKeyPath
|
|
285
|
-
);
|
|
300
|
+
await this.writeKeyPairToFilesystem(newKeyPaths.privateKeyPath, newKeyPaths.publicKeyPath, privateKey, publicKey);
|
|
286
301
|
|
|
287
302
|
// Save metadata for new keys
|
|
288
303
|
const metadata: IDkimKeyMetadata = {
|
|
@@ -320,7 +335,7 @@ export class DKIMCreator {
|
|
|
320
335
|
*/
|
|
321
336
|
public async readDKIMKeysForSelector(domain: string, selector: string): Promise<{ privateKey: string; publicKey: string }> {
|
|
322
337
|
// Try to read from storage manager first
|
|
323
|
-
if (this.storageManager) {
|
|
338
|
+
if (hasStorageManagerMethods(this.storageManager, ['get', 'set'])) {
|
|
324
339
|
try {
|
|
325
340
|
const [privateKey, publicKey] = await Promise.all([
|
|
326
341
|
this.storageManager.get(`/email/dkim/${domain}/${selector}/private.key`),
|
|
@@ -330,6 +345,10 @@ export class DKIMCreator {
|
|
|
330
345
|
if (privateKey && publicKey) {
|
|
331
346
|
return { privateKey, publicKey };
|
|
332
347
|
}
|
|
348
|
+
|
|
349
|
+
if (selector === 'default') {
|
|
350
|
+
return await this.readDKIMKeys(domain);
|
|
351
|
+
}
|
|
333
352
|
} catch (error) {
|
|
334
353
|
// Fall through to migration check
|
|
335
354
|
}
|
|
@@ -347,10 +366,7 @@ export class DKIMCreator {
|
|
|
347
366
|
|
|
348
367
|
// Migrate to storage manager
|
|
349
368
|
console.log(`Migrating DKIM keys for ${domain}/${selector} from filesystem to StorageManager`);
|
|
350
|
-
await
|
|
351
|
-
this.storageManager.set(`/email/dkim/${domain}/${selector}/private.key`, privateKey),
|
|
352
|
-
this.storageManager.set(`/email/dkim/${domain}/${selector}/public.key`, publicKey)
|
|
353
|
-
]);
|
|
369
|
+
await this.storeSelectorKeysToStorage(domain, selector, privateKey, publicKey);
|
|
354
370
|
|
|
355
371
|
return { privateKey, publicKey };
|
|
356
372
|
} catch (error) {
|
|
@@ -361,6 +377,9 @@ export class DKIMCreator {
|
|
|
361
377
|
}
|
|
362
378
|
} else {
|
|
363
379
|
// No storage manager, use filesystem directly
|
|
380
|
+
if (selector === 'default') {
|
|
381
|
+
return this.readDKIMKeys(domain);
|
|
382
|
+
}
|
|
364
383
|
const keyPaths = await this.getKeyPathsForSelector(domain, selector);
|
|
365
384
|
const [privateKeyBuffer, publicKeyBuffer] = await Promise.all([
|
|
366
385
|
readFile(keyPaths.privateKeyPath),
|
|
@@ -406,7 +425,8 @@ export class DKIMCreator {
|
|
|
406
425
|
* Clean up old DKIM keys after grace period
|
|
407
426
|
*/
|
|
408
427
|
public async cleanupOldKeys(domain: string, gracePeriodDays: number = 30): Promise<void> {
|
|
409
|
-
if (!this.storageManager) {
|
|
428
|
+
if (!hasStorageManagerMethods(this.storageManager, ['get', 'list', 'delete'])) {
|
|
429
|
+
console.log(`StorageManager for ${domain} does not support list/delete. Skipping DKIM cleanup.`);
|
|
410
430
|
return;
|
|
411
431
|
}
|
|
412
432
|
|
|
@@ -436,7 +456,11 @@ export class DKIMCreator {
|
|
|
436
456
|
console.warn(`Failed to delete old key files: ${error.message}`);
|
|
437
457
|
}
|
|
438
458
|
|
|
439
|
-
// Delete metadata
|
|
459
|
+
// Delete selector-specific storage keys and metadata
|
|
460
|
+
await Promise.all([
|
|
461
|
+
this.storageManager.delete(`/email/dkim/${domain}/${metadata.selector}/private.key`),
|
|
462
|
+
this.storageManager.delete(`/email/dkim/${domain}/${metadata.selector}/public.key`),
|
|
463
|
+
]);
|
|
440
464
|
await this.storageManager.delete(key);
|
|
441
465
|
}
|
|
442
466
|
}
|
|
@@ -444,4 +468,4 @@ export class DKIMCreator {
|
|
|
444
468
|
}
|
|
445
469
|
}
|
|
446
470
|
}
|
|
447
|
-
}
|
|
471
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as plugins from '../plugins.js';
|
|
2
2
|
import * as paths from '../paths.js';
|
|
3
3
|
import { logger } from '../logger.js';
|
|
4
|
+
import { hasStorageManagerMethods, type IStorageManagerLike } from '../mail/interfaces.storage.js';
|
|
4
5
|
import { SecurityLogger, SecurityLogLevel, SecurityEventType } from './classes.securitylogger.js';
|
|
5
6
|
import { RustSecurityBridge } from './classes.rustsecuritybridge.js';
|
|
6
7
|
import { LRUCache } from 'lru-cache';
|
|
@@ -66,7 +67,7 @@ export class IPReputationChecker {
|
|
|
66
67
|
private static instance: IPReputationChecker;
|
|
67
68
|
private reputationCache: LRUCache<string, IReputationResult>;
|
|
68
69
|
private options: Required<IIPReputationOptions>;
|
|
69
|
-
private storageManager?:
|
|
70
|
+
private storageManager?: IStorageManagerLike;
|
|
70
71
|
|
|
71
72
|
private static readonly DEFAULT_OPTIONS: Required<IIPReputationOptions> = {
|
|
72
73
|
maxCacheSize: 10000,
|
|
@@ -80,7 +81,7 @@ export class IPReputationChecker {
|
|
|
80
81
|
enableIPInfo: true
|
|
81
82
|
};
|
|
82
83
|
|
|
83
|
-
constructor(options: IIPReputationOptions = {}, storageManager?:
|
|
84
|
+
constructor(options: IIPReputationOptions = {}, storageManager?: IStorageManagerLike) {
|
|
84
85
|
this.options = {
|
|
85
86
|
...IPReputationChecker.DEFAULT_OPTIONS,
|
|
86
87
|
...options
|
|
@@ -100,7 +101,7 @@ export class IPReputationChecker {
|
|
|
100
101
|
}
|
|
101
102
|
}
|
|
102
103
|
|
|
103
|
-
public static getInstance(options: IIPReputationOptions = {}, storageManager?:
|
|
104
|
+
public static getInstance(options: IIPReputationOptions = {}, storageManager?: IStorageManagerLike): IPReputationChecker {
|
|
104
105
|
if (!IPReputationChecker.instance) {
|
|
105
106
|
IPReputationChecker.instance = new IPReputationChecker(options, storageManager);
|
|
106
107
|
}
|
|
@@ -219,7 +220,7 @@ export class IPReputationChecker {
|
|
|
219
220
|
|
|
220
221
|
const cacheData = JSON.stringify(entries);
|
|
221
222
|
|
|
222
|
-
if (this.storageManager) {
|
|
223
|
+
if (hasStorageManagerMethods(this.storageManager, ['set'])) {
|
|
223
224
|
await this.storageManager.set('/security/ip-reputation-cache.json', cacheData);
|
|
224
225
|
logger.log('info', `Saved ${entries.length} IP reputation cache entries to StorageManager`);
|
|
225
226
|
} else {
|
|
@@ -239,7 +240,7 @@ export class IPReputationChecker {
|
|
|
239
240
|
let cacheData: string | null = null;
|
|
240
241
|
let fromFilesystem = false;
|
|
241
242
|
|
|
242
|
-
if (this.storageManager) {
|
|
243
|
+
if (hasStorageManagerMethods(this.storageManager, ['get', 'set'])) {
|
|
243
244
|
try {
|
|
244
245
|
cacheData = await this.storageManager.get('/security/ip-reputation-cache.json');
|
|
245
246
|
|
|
@@ -302,7 +303,7 @@ export class IPReputationChecker {
|
|
|
302
303
|
}
|
|
303
304
|
}
|
|
304
305
|
|
|
305
|
-
public updateStorageManager(storageManager:
|
|
306
|
+
public updateStorageManager(storageManager: IStorageManagerLike): void {
|
|
306
307
|
this.storageManager = storageManager;
|
|
307
308
|
logger.log('info', 'IPReputationChecker storage manager updated');
|
|
308
309
|
|