@serve.zone/dcrouter 5.0.2 → 5.0.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.
Files changed (202) hide show
  1. package/dist_serve/bundle.js +30539 -0
  2. package/dist_serve/bundle.js.map +7 -0
  3. package/dist_serve/index.html +1 -0
  4. package/dist_ts/00_commitinfo_data.d.ts +8 -0
  5. package/dist_ts/00_commitinfo_data.js +9 -0
  6. package/dist_ts/cache/classes.cache.cleaner.d.ts +47 -0
  7. package/dist_ts/cache/classes.cache.cleaner.js +130 -0
  8. package/dist_ts/cache/classes.cached.document.d.ts +76 -0
  9. package/dist_ts/cache/classes.cached.document.js +100 -0
  10. package/dist_ts/cache/classes.cachedb.d.ts +60 -0
  11. package/dist_ts/cache/classes.cachedb.js +125 -0
  12. package/dist_ts/cache/documents/classes.cached.email.d.ts +125 -0
  13. package/dist_ts/cache/documents/classes.cached.email.js +337 -0
  14. package/dist_ts/cache/documents/classes.cached.ip.reputation.d.ts +119 -0
  15. package/dist_ts/cache/documents/classes.cached.ip.reputation.js +323 -0
  16. package/dist_ts/cache/documents/index.d.ts +2 -0
  17. package/dist_ts/cache/documents/index.js +3 -0
  18. package/dist_ts/cache/index.d.ts +4 -0
  19. package/dist_ts/cache/index.js +7 -0
  20. package/dist_ts/classes.dcrouter.d.ts +276 -0
  21. package/dist_ts/classes.dcrouter.js +1033 -0
  22. package/dist_ts/config/index.d.ts +1 -0
  23. package/dist_ts/config/index.js +3 -0
  24. package/dist_ts/config/validator.d.ts +104 -0
  25. package/dist_ts/config/validator.js +152 -0
  26. package/dist_ts/errors/base.errors.d.ts +224 -0
  27. package/dist_ts/errors/base.errors.js +320 -0
  28. package/dist_ts/errors/error-handler.d.ts +98 -0
  29. package/dist_ts/errors/error-handler.js +282 -0
  30. package/dist_ts/errors/error.codes.d.ts +115 -0
  31. package/dist_ts/errors/error.codes.js +136 -0
  32. package/dist_ts/errors/index.d.ts +54 -0
  33. package/dist_ts/errors/index.js +136 -0
  34. package/dist_ts/errors/reputation.errors.d.ts +183 -0
  35. package/dist_ts/errors/reputation.errors.js +292 -0
  36. package/dist_ts/index.d.ts +6 -0
  37. package/dist_ts/index.js +9 -0
  38. package/dist_ts/logger.d.ts +17 -0
  39. package/dist_ts/logger.js +76 -0
  40. package/dist_ts/monitoring/classes.metricscache.d.ts +32 -0
  41. package/dist_ts/monitoring/classes.metricscache.js +63 -0
  42. package/dist_ts/monitoring/classes.metricsmanager.d.ts +112 -0
  43. package/dist_ts/monitoring/classes.metricsmanager.js +446 -0
  44. package/dist_ts/monitoring/index.d.ts +1 -0
  45. package/dist_ts/monitoring/index.js +2 -0
  46. package/dist_ts/opsserver/classes.opsserver.d.ts +22 -0
  47. package/dist_ts/opsserver/classes.opsserver.js +56 -0
  48. package/dist_ts/opsserver/handlers/admin.handler.d.ts +31 -0
  49. package/dist_ts/opsserver/handlers/admin.handler.js +180 -0
  50. package/dist_ts/opsserver/handlers/config.handler.d.ts +9 -0
  51. package/dist_ts/opsserver/handlers/config.handler.js +67 -0
  52. package/dist_ts/opsserver/handlers/email-ops.handler.d.ts +12 -0
  53. package/dist_ts/opsserver/handlers/email-ops.handler.js +219 -0
  54. package/dist_ts/opsserver/handlers/index.d.ts +7 -0
  55. package/dist_ts/opsserver/handlers/index.js +8 -0
  56. package/dist_ts/opsserver/handlers/logs.handler.d.ts +10 -0
  57. package/dist_ts/opsserver/handlers/logs.handler.js +122 -0
  58. package/dist_ts/opsserver/handlers/radius.handler.d.ts +8 -0
  59. package/dist_ts/opsserver/handlers/radius.handler.js +296 -0
  60. package/dist_ts/opsserver/handlers/security.handler.d.ts +11 -0
  61. package/dist_ts/opsserver/handlers/security.handler.js +217 -0
  62. package/dist_ts/opsserver/handlers/stats.handler.d.ts +13 -0
  63. package/dist_ts/opsserver/handlers/stats.handler.js +366 -0
  64. package/dist_ts/opsserver/helpers/guards.d.ts +25 -0
  65. package/dist_ts/opsserver/helpers/guards.js +41 -0
  66. package/dist_ts/opsserver/index.d.ts +1 -0
  67. package/dist_ts/opsserver/index.js +2 -0
  68. package/dist_ts/paths.d.ts +14 -0
  69. package/dist_ts/paths.js +39 -0
  70. package/dist_ts/plugins.d.ts +78 -0
  71. package/dist_ts/plugins.js +112 -0
  72. package/dist_ts/radius/classes.accounting.manager.d.ts +218 -0
  73. package/dist_ts/radius/classes.accounting.manager.js +417 -0
  74. package/dist_ts/radius/classes.radius.server.d.ts +171 -0
  75. package/dist_ts/radius/classes.radius.server.js +385 -0
  76. package/dist_ts/radius/classes.vlan.manager.d.ts +128 -0
  77. package/dist_ts/radius/classes.vlan.manager.js +272 -0
  78. package/dist_ts/radius/index.d.ts +13 -0
  79. package/dist_ts/radius/index.js +14 -0
  80. package/dist_ts/security/classes.contentscanner.d.ts +160 -0
  81. package/dist_ts/security/classes.contentscanner.js +637 -0
  82. package/dist_ts/security/classes.ipreputationchecker.d.ts +150 -0
  83. package/dist_ts/security/classes.ipreputationchecker.js +512 -0
  84. package/dist_ts/security/classes.securitylogger.d.ts +140 -0
  85. package/dist_ts/security/classes.securitylogger.js +235 -0
  86. package/dist_ts/security/index.d.ts +3 -0
  87. package/dist_ts/security/index.js +4 -0
  88. package/dist_ts/sms/classes.smsservice.d.ts +15 -0
  89. package/dist_ts/sms/classes.smsservice.js +72 -0
  90. package/dist_ts/sms/config/sms.config.d.ts +93 -0
  91. package/dist_ts/sms/config/sms.config.js +2 -0
  92. package/dist_ts/sms/config/sms.schema.d.ts +5 -0
  93. package/dist_ts/sms/config/sms.schema.js +121 -0
  94. package/dist_ts/sms/index.d.ts +1 -0
  95. package/dist_ts/sms/index.js +2 -0
  96. package/dist_ts/storage/classes.storagemanager.d.ts +82 -0
  97. package/dist_ts/storage/classes.storagemanager.js +344 -0
  98. package/dist_ts/storage/index.d.ts +1 -0
  99. package/dist_ts/storage/index.js +3 -0
  100. package/dist_ts_interfaces/data/auth.d.ts +8 -0
  101. package/dist_ts_interfaces/data/auth.js +2 -0
  102. package/dist_ts_interfaces/data/index.d.ts +2 -0
  103. package/dist_ts_interfaces/data/index.js +3 -0
  104. package/dist_ts_interfaces/data/stats.d.ts +120 -0
  105. package/dist_ts_interfaces/data/stats.js +2 -0
  106. package/{ts_interfaces/index.ts → dist_ts_interfaces/index.d.ts} +1 -5
  107. package/dist_ts_interfaces/index.js +8 -0
  108. package/{ts_interfaces/plugins.ts → dist_ts_interfaces/plugins.d.ts} +1 -5
  109. package/dist_ts_interfaces/plugins.js +4 -0
  110. package/dist_ts_interfaces/requests/admin.d.ts +31 -0
  111. package/dist_ts_interfaces/requests/admin.js +3 -0
  112. package/dist_ts_interfaces/requests/combined.stats.d.ts +24 -0
  113. package/dist_ts_interfaces/requests/combined.stats.js +2 -0
  114. package/dist_ts_interfaces/requests/config.d.ts +13 -0
  115. package/dist_ts_interfaces/requests/config.js +3 -0
  116. package/dist_ts_interfaces/requests/email-ops.d.ts +139 -0
  117. package/dist_ts_interfaces/requests/email-ops.js +3 -0
  118. package/{ts_interfaces/requests/index.ts → dist_ts_interfaces/requests/index.d.ts} +1 -1
  119. package/dist_ts_interfaces/requests/index.js +8 -0
  120. package/dist_ts_interfaces/requests/logs.d.ts +34 -0
  121. package/dist_ts_interfaces/requests/logs.js +4 -0
  122. package/dist_ts_interfaces/requests/radius.d.ts +268 -0
  123. package/dist_ts_interfaces/requests/radius.js +3 -0
  124. package/dist_ts_interfaces/requests/stats.d.ts +131 -0
  125. package/dist_ts_interfaces/requests/stats.js +4 -0
  126. package/dist_ts_web/00_commitinfo_data.d.ts +8 -0
  127. package/dist_ts_web/00_commitinfo_data.js +9 -0
  128. package/dist_ts_web/appstate.d.ts +96 -0
  129. package/dist_ts_web/appstate.js +587 -0
  130. package/dist_ts_web/elements/index.d.ts +8 -0
  131. package/dist_ts_web/elements/index.js +9 -0
  132. package/dist_ts_web/elements/ops-dashboard.d.ts +23 -0
  133. package/dist_ts_web/elements/ops-dashboard.js +271 -0
  134. package/dist_ts_web/elements/ops-view-config.d.ts +17 -0
  135. package/dist_ts_web/elements/ops-view-config.js +414 -0
  136. package/dist_ts_web/elements/ops-view-emails.d.ts +44 -0
  137. package/dist_ts_web/elements/ops-view-emails.js +880 -0
  138. package/dist_ts_web/elements/ops-view-logs.d.ts +13 -0
  139. package/dist_ts_web/elements/ops-view-logs.js +249 -0
  140. package/dist_ts_web/elements/ops-view-network.d.ts +65 -0
  141. package/dist_ts_web/elements/ops-view-network.js +579 -0
  142. package/dist_ts_web/elements/ops-view-overview.d.ts +14 -0
  143. package/dist_ts_web/elements/ops-view-overview.js +344 -0
  144. package/dist_ts_web/elements/ops-view-security.d.ts +21 -0
  145. package/dist_ts_web/elements/ops-view-security.js +568 -0
  146. package/dist_ts_web/elements/shared/css.d.ts +1 -0
  147. package/dist_ts_web/elements/shared/css.js +10 -0
  148. package/dist_ts_web/elements/shared/index.d.ts +2 -0
  149. package/dist_ts_web/elements/shared/index.js +3 -0
  150. package/dist_ts_web/elements/shared/ops-sectionheading.d.ts +5 -0
  151. package/dist_ts_web/elements/shared/ops-sectionheading.js +82 -0
  152. package/dist_ts_web/index.d.ts +1 -0
  153. package/dist_ts_web/index.js +10 -0
  154. package/dist_ts_web/plugins.d.ts +4 -0
  155. package/dist_ts_web/plugins.js +7 -0
  156. package/dist_ts_web/router.d.ts +25 -0
  157. package/dist_ts_web/router.js +165 -0
  158. package/package.json +14 -2
  159. package/ts/00_commitinfo_data.ts +1 -1
  160. package/ts_web/00_commitinfo_data.ts +1 -1
  161. package/.dockerignore +0 -1
  162. package/.gitea/workflows/docker_nottags.yaml +0 -71
  163. package/.gitea/workflows/docker_tags.yaml +0 -106
  164. package/.playwright-mcp/dcrouter-scrollbar-issue.png +0 -0
  165. package/.playwright-mcp/page-2026-02-01T23-10-23-737Z.png +0 -0
  166. package/.playwright-mcp/page-2026-02-01T23-11-19-449Z.png +0 -0
  167. package/.playwright-mcp/page-2026-02-01T23-12-03-126Z.png +0 -0
  168. package/.playwright-mcp/page-2026-02-01T23-12-15-576Z.png +0 -0
  169. package/.vscode/launch.json +0 -11
  170. package/.vscode/settings.json +0 -26
  171. package/Dockerfile +0 -46
  172. package/changelog.md +0 -350
  173. package/cli.child.js +0 -4
  174. package/cli.child.ts +0 -4
  175. package/cli.ts.js +0 -5
  176. package/html/index.html +0 -121
  177. package/test/readme.md +0 -443
  178. package/test/test.config.md +0 -175
  179. package/test/test.contentscanner.ts +0 -265
  180. package/test/test.dcrouter.email.ts +0 -159
  181. package/test/test.dns-server-config.ts +0 -140
  182. package/test/test.dns-socket-handler.ts +0 -148
  183. package/test/test.errors.ts +0 -274
  184. package/test/test.ipreputationchecker.ts +0 -179
  185. package/test/test.jwt-auth.ts +0 -131
  186. package/test/test.opsserver-api.ts +0 -84
  187. package/test/test.protected-endpoint.ts +0 -120
  188. package/test/test.storagemanager.ts +0 -289
  189. package/test_watch/devserver.ts +0 -35
  190. package/ts_interfaces/data/auth.ts +0 -8
  191. package/ts_interfaces/data/index.ts +0 -2
  192. package/ts_interfaces/data/stats.ts +0 -131
  193. package/ts_interfaces/readme.md +0 -205
  194. package/ts_interfaces/requests/admin.ts +0 -46
  195. package/ts_interfaces/requests/combined.stats.ts +0 -25
  196. package/ts_interfaces/requests/config.ts +0 -18
  197. package/ts_interfaces/requests/email-ops.ts +0 -239
  198. package/ts_interfaces/requests/logs.ts +0 -44
  199. package/ts_interfaces/requests/radius.ts +0 -329
  200. package/ts_interfaces/requests/stats.ts +0 -162
  201. package/ts_interfaces/tspublish.json +0 -3
  202. package/tsconfig.json +0 -12
@@ -1,265 +0,0 @@
1
- import { tap, expect } from '@git.zone/tstest/tapbundle';
2
- import { ContentScanner, ThreatCategory } from '../ts/security/classes.contentscanner.js';
3
- import { Email } from '@push.rocks/smartmta';
4
-
5
- // Test instantiation
6
- tap.test('ContentScanner - should be instantiable', async () => {
7
- const scanner = ContentScanner.getInstance({
8
- scanBody: true,
9
- scanSubject: true,
10
- scanAttachments: true
11
- });
12
-
13
- expect(scanner).toBeTruthy();
14
- });
15
-
16
- // Test singleton pattern
17
- tap.test('ContentScanner - should use singleton pattern', async () => {
18
- const scanner1 = ContentScanner.getInstance();
19
- const scanner2 = ContentScanner.getInstance();
20
-
21
- // Both instances should be the same object
22
- expect(scanner1 === scanner2).toEqual(true);
23
- });
24
-
25
- // Test clean email can be correctly distinguished from high-risk email
26
- tap.test('ContentScanner - should distinguish between clean and suspicious emails', async () => {
27
- // Create an instance with a higher minimum threat score
28
- const scanner = new ContentScanner({
29
- minThreatScore: 50 // Higher threshold to consider clean
30
- });
31
-
32
- // Create a truly clean email with no potentially sensitive data patterns
33
- const cleanEmail = new Email({
34
- from: 'sender@example.com',
35
- to: 'recipient@example.com',
36
- subject: 'Project Update',
37
- text: 'The project is on track. Let me know if you have questions.',
38
- html: '<p>The project is on track. Let me know if you have questions.</p>'
39
- });
40
-
41
- // Create a highly suspicious email
42
- const suspiciousEmail = new Email({
43
- from: 'admin@bank-fake.com',
44
- to: 'victim@example.com',
45
- subject: 'URGENT: Your account needs verification now!',
46
- text: 'Click here to verify your account or it will be suspended: https://bit.ly/12345',
47
- html: '<p>Click here to verify your account or it will be suspended: <a href="https://bit.ly/12345">click here</a></p>'
48
- });
49
-
50
- // Test both emails
51
- const cleanResult = await scanner.scanEmail(cleanEmail);
52
- const suspiciousResult = await scanner.scanEmail(suspiciousEmail);
53
-
54
- console.log('Clean vs Suspicious results:', {
55
- cleanScore: cleanResult.threatScore,
56
- suspiciousScore: suspiciousResult.threatScore
57
- });
58
-
59
- // Verify the scanner can distinguish between them
60
- // Suspicious email should have a significantly higher score
61
- expect(suspiciousResult.threatScore > cleanResult.threatScore + 40).toEqual(true);
62
-
63
- // Verify clean email scans all expected elements
64
- expect(cleanResult.scannedElements.length > 0).toEqual(true);
65
- });
66
-
67
- // Test phishing detection in subject
68
- tap.test('ContentScanner - should detect phishing in subject', async () => {
69
- // Create a dedicated scanner for this test
70
- const scanner = new ContentScanner({
71
- scanSubject: true,
72
- scanBody: true,
73
- scanAttachments: false,
74
- customRules: []
75
- });
76
-
77
- const email = new Email({
78
- from: 'security@bank-account-verify.com',
79
- to: 'victim@example.com',
80
- subject: 'URGENT: Verify your bank account details immediately',
81
- text: 'Your account will be suspended. Please verify your details.',
82
- html: '<p>Your account will be suspended. Please verify your details.</p>'
83
- });
84
-
85
- const result = await scanner.scanEmail(email);
86
-
87
- console.log('Phishing email scan result:', result);
88
-
89
- // We only care that it detected something suspicious
90
- expect(result.threatScore >= 20).toEqual(true);
91
-
92
- // Check if any threat was detected (specific type may vary)
93
- expect(result.threatType).toBeTruthy();
94
- });
95
-
96
- // Test malware indicators in body
97
- tap.test('ContentScanner - should detect malware indicators in body', async () => {
98
- const scanner = ContentScanner.getInstance();
99
-
100
- const email = new Email({
101
- from: 'invoice@company.com',
102
- to: 'recipient@example.com',
103
- subject: 'Your invoice',
104
- text: 'Please see the attached invoice. You need to enable macros to view this document properly.',
105
- html: '<p>Please see the attached invoice. You need to enable macros to view this document properly.</p>'
106
- });
107
-
108
- const result = await scanner.scanEmail(email);
109
-
110
- expect(result.isClean).toEqual(false);
111
- expect(result.threatType === ThreatCategory.MALWARE || result.threatType).toBeTruthy();
112
- expect(result.threatScore >= 30).toEqual(true);
113
- });
114
-
115
- // Test suspicious link detection
116
- tap.test('ContentScanner - should detect suspicious links', async () => {
117
- const scanner = ContentScanner.getInstance();
118
-
119
- const email = new Email({
120
- from: 'newsletter@example.com',
121
- to: 'recipient@example.com',
122
- subject: 'Weekly Newsletter',
123
- text: 'Check our latest offer at https://bit.ly/2x3F5 and https://t.co/abc123',
124
- html: '<p>Check our latest offer at <a href="https://bit.ly/2x3F5">here</a> and <a href="https://t.co/abc123">here</a></p>'
125
- });
126
-
127
- const result = await scanner.scanEmail(email);
128
-
129
- expect(result.isClean).toEqual(false);
130
- expect(result.threatType).toEqual(ThreatCategory.SUSPICIOUS_LINK);
131
- expect(result.threatScore >= 30).toEqual(true);
132
- });
133
-
134
- // Test script injection detection
135
- tap.test('ContentScanner - should detect script injection', async () => {
136
- const scanner = ContentScanner.getInstance();
137
-
138
- const email = new Email({
139
- from: 'newsletter@example.com',
140
- to: 'recipient@example.com',
141
- subject: 'Newsletter',
142
- text: 'Check our website',
143
- html: '<p>Check our website</p><script>document.cookie="session="+localStorage.getItem("token");</script>'
144
- });
145
-
146
- const result = await scanner.scanEmail(email);
147
-
148
- expect(result.isClean).toEqual(false);
149
- expect(result.threatType).toEqual(ThreatCategory.XSS);
150
- expect(result.threatScore >= 40).toEqual(true);
151
- });
152
-
153
- // Test executable attachment detection
154
- tap.test('ContentScanner - should detect executable attachments', async () => {
155
- const scanner = ContentScanner.getInstance();
156
-
157
- const email = new Email({
158
- from: 'sender@example.com',
159
- to: 'recipient@example.com',
160
- subject: 'Software Update',
161
- text: 'Please install the attached software update.',
162
- attachments: [{
163
- filename: 'update.exe',
164
- content: Buffer.from('MZ...fake executable content...'),
165
- contentType: 'application/octet-stream'
166
- }]
167
- });
168
-
169
- const result = await scanner.scanEmail(email);
170
-
171
- expect(result.isClean).toEqual(false);
172
- expect(result.threatType).toEqual(ThreatCategory.EXECUTABLE);
173
- expect(result.threatScore >= 70).toEqual(true);
174
- });
175
-
176
- // Test macro document detection
177
- tap.test('ContentScanner - should detect macro documents', async () => {
178
- // Create a mock Office document with macro indicators
179
- const fakeDocContent = Buffer.from('Document content...vbaProject.bin...Auto_Open...DocumentOpen...Microsoft VBA...');
180
-
181
- const scanner = ContentScanner.getInstance();
182
-
183
- const email = new Email({
184
- from: 'sender@example.com',
185
- to: 'recipient@example.com',
186
- subject: 'Financial Report',
187
- text: 'Please review the attached financial report.',
188
- attachments: [{
189
- filename: 'report.docm',
190
- content: fakeDocContent,
191
- contentType: 'application/vnd.ms-word.document.macroEnabled.12'
192
- }]
193
- });
194
-
195
- const result = await scanner.scanEmail(email);
196
-
197
- expect(result.isClean).toEqual(false);
198
- expect(result.threatType).toEqual(ThreatCategory.MALICIOUS_MACRO);
199
- expect(result.threatScore >= 60).toEqual(true);
200
- });
201
-
202
- // Test compound threat detection (multiple indicators)
203
- tap.test('ContentScanner - should detect compound threats', async () => {
204
- const scanner = ContentScanner.getInstance();
205
-
206
- const email = new Email({
207
- from: 'security@bank-verify.com',
208
- to: 'victim@example.com',
209
- subject: 'URGENT: Verify your account details immediately',
210
- text: 'Your account will be suspended unless you verify your details at https://bit.ly/2x3F5',
211
- html: '<p>Your account will be suspended unless you verify your details <a href="https://bit.ly/2x3F5">here</a>.</p>',
212
- attachments: [{
213
- filename: 'verification.exe',
214
- content: Buffer.from('MZ...fake executable content...'),
215
- contentType: 'application/octet-stream'
216
- }]
217
- });
218
-
219
- const result = await scanner.scanEmail(email);
220
-
221
- expect(result.isClean).toEqual(false);
222
- expect(result.threatScore > 70).toEqual(true); // Should have a high score due to multiple threats
223
- });
224
-
225
- // Test custom rules
226
- tap.test('ContentScanner - should apply custom rules', async () => {
227
- // Create a scanner with custom rules
228
- const scanner = new ContentScanner({
229
- customRules: [
230
- {
231
- pattern: /CUSTOM_PATTERN_FOR_TESTING/,
232
- type: ThreatCategory.CUSTOM_RULE,
233
- score: 50,
234
- description: 'Custom pattern detected'
235
- }
236
- ]
237
- });
238
-
239
- const email = new Email({
240
- from: 'sender@example.com',
241
- to: 'recipient@example.com',
242
- subject: 'Test Custom Rule',
243
- text: 'This message contains CUSTOM_PATTERN_FOR_TESTING that should be detected.'
244
- });
245
-
246
- const result = await scanner.scanEmail(email);
247
-
248
- expect(result.isClean).toEqual(false);
249
- expect(result.threatType).toEqual(ThreatCategory.CUSTOM_RULE);
250
- expect(result.threatScore >= 50).toEqual(true);
251
- });
252
-
253
- // Test threat level classification
254
- tap.test('ContentScanner - should classify threat levels correctly', async () => {
255
- expect(ContentScanner.getThreatLevel(10)).toEqual('none');
256
- expect(ContentScanner.getThreatLevel(25)).toEqual('low');
257
- expect(ContentScanner.getThreatLevel(50)).toEqual('medium');
258
- expect(ContentScanner.getThreatLevel(80)).toEqual('high');
259
- });
260
-
261
- tap.test('stop', async () => {
262
- await tap.stopForcefully();
263
- });
264
-
265
- export default tap.start();
@@ -1,159 +0,0 @@
1
- import { tap, expect } from '@git.zone/tstest/tapbundle';
2
- import * as plugins from '../ts/plugins.js';
3
- import * as path from 'path';
4
- import * as fs from 'fs';
5
- import { DcRouter, type IDcRouterOptions } from '../ts/classes.dcrouter.js';
6
- import type { IUnifiedEmailServerOptions } from '@push.rocks/smartmta';
7
-
8
-
9
- tap.test('DcRouter class - Custom email port configuration', async () => {
10
- // Define custom port mapping
11
- const customPortMapping: Record<number, number> = {
12
- 25: 11025, // Custom SMTP port mapping
13
- 587: 11587, // Custom submission port mapping
14
- 465: 11465, // Custom SMTPS port mapping
15
- 2525: 12525 // Additional custom port
16
- };
17
-
18
- // Create a custom email configuration using smartmta interfaces
19
- const emailConfig: IUnifiedEmailServerOptions = {
20
- ports: [25, 587, 465, 2525],
21
- hostname: 'mail.example.com',
22
- maxMessageSize: 50 * 1024 * 1024, // 50MB
23
- domains: [
24
- {
25
- domain: 'example.com',
26
- dnsMode: 'external-dns',
27
- },
28
- {
29
- domain: 'example.org',
30
- dnsMode: 'external-dns',
31
- }
32
- ],
33
- routes: [
34
- {
35
- name: 'forward-example-com',
36
- match: {
37
- recipients: '*@example.com',
38
- },
39
- action: {
40
- type: 'forward',
41
- forward: {
42
- host: 'mail1.example.com',
43
- port: 25,
44
- }
45
- }
46
- },
47
- {
48
- name: 'deliver-example-org',
49
- match: {
50
- recipients: '*@example.org',
51
- },
52
- action: {
53
- type: 'deliver',
54
- process: {
55
- dkim: true,
56
- }
57
- }
58
- }
59
- ]
60
- };
61
-
62
- // Create DcRouter options with custom email port configuration
63
- const options: IDcRouterOptions = {
64
- emailConfig,
65
- emailPortConfig: {
66
- portMapping: customPortMapping,
67
- portSettings: {
68
- 2525: {
69
- terminateTls: false,
70
- routeName: 'custom-smtp-route'
71
- }
72
- },
73
- },
74
- tls: {
75
- contactEmail: 'test@example.com'
76
- }
77
- };
78
-
79
- // Create DcRouter instance
80
- const router = new DcRouter(options);
81
-
82
- // Verify the options are correctly set
83
- expect(router.options.emailPortConfig).toBeTruthy();
84
- expect(router.options.emailPortConfig!.portMapping).toEqual(customPortMapping);
85
-
86
- // Test the generateEmailRoutes method
87
- if (typeof (router as any)['generateEmailRoutes'] === 'function') {
88
- const routes = (router as any)['generateEmailRoutes'](emailConfig);
89
-
90
- // Verify that all ports are configured
91
- expect(routes.length).toBeGreaterThan(0);
92
-
93
- // Check the custom port configuration
94
- const customPortRoute = routes.find((r: any) => {
95
- const ports = r.match.ports;
96
- return ports === 2525 || (Array.isArray(ports) && (ports as number[]).includes(2525));
97
- });
98
- expect(customPortRoute).toBeTruthy();
99
- expect(customPortRoute?.name).toEqual('custom-smtp-route');
100
- expect(customPortRoute?.action.targets[0].port).toEqual(12525);
101
-
102
- // Check standard port mappings
103
- const smtpRoute = routes.find((r: any) => {
104
- const ports = r.match.ports;
105
- return ports === 25 || (Array.isArray(ports) && (ports as number[]).includes(25));
106
- });
107
- expect(smtpRoute?.action.targets[0].port).toEqual(11025);
108
-
109
- const submissionRoute = routes.find((r: any) => {
110
- const ports = r.match.ports;
111
- return ports === 587 || (Array.isArray(ports) && (ports as number[]).includes(587));
112
- });
113
- expect(submissionRoute?.action.targets[0].port).toEqual(11587);
114
- }
115
- });
116
-
117
- tap.test('DcRouter class - Email config with domains and routes', async () => {
118
- // Create a basic email configuration
119
- const emailConfig: IUnifiedEmailServerOptions = {
120
- ports: [2525],
121
- hostname: 'mail.example.com',
122
- domains: [],
123
- routes: []
124
- };
125
-
126
- // Create DcRouter options
127
- const options: IDcRouterOptions = {
128
- emailConfig,
129
- tls: {
130
- contactEmail: 'test@example.com'
131
- },
132
- cacheConfig: {
133
- enabled: false,
134
- }
135
- };
136
-
137
- // Create DcRouter instance
138
- const router = new DcRouter(options);
139
-
140
- // Start the router to initialize email services
141
- await router.start();
142
-
143
- // Verify unified email server was initialized
144
- expect(router.emailServer).toBeTruthy();
145
-
146
- // Stop the router
147
- await router.stop();
148
- });
149
-
150
- // Final clean-up test
151
- tap.test('clean up after tests', async () => {
152
- // No-op
153
- });
154
-
155
- tap.test('stop', async () => {
156
- await tap.stopForcefully();
157
- });
158
-
159
- export default tap.start();
@@ -1,140 +0,0 @@
1
- #!/usr/bin/env tsx
2
-
3
- /**
4
- * Test DNS server configuration and record registration
5
- */
6
-
7
- import { tap, expect } from '@git.zone/tstest/tapbundle';
8
- import * as plugins from '../ts/plugins.js';
9
-
10
- // Test DNS configuration
11
- const testDnsConfig = {
12
- udpPort: 5353, // Use non-privileged port for testing
13
- httpsPort: 8443,
14
- httpsKey: './test/fixtures/test-key.pem',
15
- httpsCert: './test/fixtures/test-cert.pem',
16
- dnssecZone: 'test.example.com',
17
- records: [
18
- { name: 'test.example.com', type: 'A', value: '192.168.1.1' },
19
- { name: 'mail.test.example.com', type: 'A', value: '192.168.1.2' },
20
- { name: 'test.example.com', type: 'MX', value: '10 mail.test.example.com' },
21
- { name: 'test.example.com', type: 'TXT', value: 'v=spf1 a:mail.test.example.com ~all' },
22
- { name: 'test.example.com', type: 'NS', value: 'ns1.test.example.com' },
23
- { name: 'ns1.test.example.com', type: 'A', value: '192.168.1.1' }
24
- ]
25
- };
26
-
27
- tap.test('DNS server configuration - should extract records correctly', async () => {
28
- const { records, ...dnsServerOptions } = testDnsConfig;
29
-
30
- expect(dnsServerOptions.udpPort).toEqual(5353);
31
- expect(dnsServerOptions.httpsPort).toEqual(8443);
32
- expect(dnsServerOptions.dnssecZone).toEqual('test.example.com');
33
- expect(records).toBeArray();
34
- expect(records.length).toEqual(6);
35
- });
36
-
37
- tap.test('DNS server configuration - should handle record parsing', async () => {
38
- const parseDnsRecordData = (type: string, value: string): any => {
39
- switch (type) {
40
- case 'A':
41
- return value;
42
- case 'MX':
43
- const [priority, exchange] = value.split(' ');
44
- return { priority: parseInt(priority), exchange };
45
- case 'TXT':
46
- return value;
47
- case 'NS':
48
- return value;
49
- default:
50
- return value;
51
- }
52
- };
53
-
54
- // Test A record parsing
55
- const aRecord = parseDnsRecordData('A', '192.168.1.1');
56
- expect(aRecord).toEqual('192.168.1.1');
57
-
58
- // Test MX record parsing
59
- const mxRecord = parseDnsRecordData('MX', '10 mail.test.example.com');
60
- expect(mxRecord).toHaveProperty('priority', 10);
61
- expect(mxRecord).toHaveProperty('exchange', 'mail.test.example.com');
62
-
63
- // Test TXT record parsing
64
- const txtRecord = parseDnsRecordData('TXT', 'v=spf1 a:mail.test.example.com ~all');
65
- expect(txtRecord).toEqual('v=spf1 a:mail.test.example.com ~all');
66
- });
67
-
68
- tap.test('DNS server configuration - should group records by domain', async () => {
69
- const records = testDnsConfig.records;
70
- const recordsByDomain = new Map<string, typeof records>();
71
-
72
- for (const record of records) {
73
- const pattern = record.name.includes('*') ? record.name : `*.${record.name}`;
74
- if (!recordsByDomain.has(pattern)) {
75
- recordsByDomain.set(pattern, []);
76
- }
77
- recordsByDomain.get(pattern)!.push(record);
78
- }
79
-
80
- // Check grouping
81
- expect(recordsByDomain.size).toBeGreaterThan(0);
82
-
83
- // Verify each group has records
84
- for (const [pattern, domainRecords] of recordsByDomain) {
85
- expect(domainRecords.length).toBeGreaterThan(0);
86
- console.log(`Pattern: ${pattern}, Records: ${domainRecords.length}`);
87
- }
88
- });
89
-
90
- tap.test('DNS server configuration - should extract unique record types', async () => {
91
- const records = testDnsConfig.records;
92
- const recordTypes = [...new Set(records.map(r => r.type))];
93
-
94
- expect(recordTypes).toContain('A');
95
- expect(recordTypes).toContain('MX');
96
- expect(recordTypes).toContain('TXT');
97
- expect(recordTypes).toContain('NS');
98
-
99
- console.log('Unique record types:', recordTypes.join(', '));
100
- });
101
-
102
- tap.test('DNS server - mock handler registration', async () => {
103
- // Mock DNS server for testing
104
- const mockDnsServer = {
105
- handlers: new Map<string, any>(),
106
- registerHandler: function(pattern: string, types: string[], handler: Function) {
107
- this.handlers.set(pattern, { types, handler });
108
- console.log(`Registered handler for pattern: ${pattern}, types: ${types.join(', ')}`);
109
- }
110
- };
111
-
112
- // Simulate record registration
113
- const records = testDnsConfig.records;
114
- const recordsByDomain = new Map<string, typeof records>();
115
-
116
- for (const record of records) {
117
- const pattern = record.name.includes('*') ? record.name : `*.${record.name}`;
118
- if (!recordsByDomain.has(pattern)) {
119
- recordsByDomain.set(pattern, []);
120
- }
121
- recordsByDomain.get(pattern)!.push(record);
122
- }
123
-
124
- // Register handlers
125
- for (const [domainPattern, domainRecords] of recordsByDomain) {
126
- const recordTypes = [...new Set(domainRecords.map(r => r.type))];
127
- mockDnsServer.registerHandler(domainPattern, recordTypes, (question: any) => {
128
- const matchingRecord = domainRecords.find(
129
- r => r.name === question.name && r.type === question.type
130
- );
131
- return matchingRecord || null;
132
- });
133
- }
134
-
135
- expect(mockDnsServer.handlers.size).toBeGreaterThan(0);
136
- });
137
-
138
- tap.start({
139
- throwOnError: true
140
- });