@serve.zone/dcrouter 13.16.0 → 13.17.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.
Files changed (389) hide show
  1. package/dist_serve/bundle.js +729 -721
  2. package/package.json +2 -2
  3. package/ts/00_commitinfo_data.ts +1 -1
  4. package/ts/monitoring/classes.metricsmanager.ts +43 -34
  5. package/ts_web/00_commitinfo_data.ts +1 -1
  6. package/ts_web/elements/network/ops-view-network-activity.ts +2 -1
  7. package/ts_web/elements/network/ops-view-routes.ts +24 -8
  8. package/dist_ts/00_commitinfo_data.d.ts +0 -8
  9. package/dist_ts/00_commitinfo_data.js +0 -9
  10. package/dist_ts/acme/index.d.ts +0 -1
  11. package/dist_ts/acme/index.js +0 -2
  12. package/dist_ts/acme/manager.acme-config.d.ts +0 -48
  13. package/dist_ts/acme/manager.acme-config.js +0 -156
  14. package/dist_ts/classes.cert-provision-scheduler.d.ts +0 -52
  15. package/dist_ts/classes.cert-provision-scheduler.js +0 -138
  16. package/dist_ts/classes.dcrouter.d.ts +0 -401
  17. package/dist_ts/classes.dcrouter.js +0 -1852
  18. package/dist_ts/classes.storage-cert-manager.d.ts +0 -15
  19. package/dist_ts/classes.storage-cert-manager.js +0 -53
  20. package/dist_ts/config/classes.api-token-manager.d.ts +0 -44
  21. package/dist_ts/config/classes.api-token-manager.js +0 -180
  22. package/dist_ts/config/classes.db-seeder.d.ts +0 -25
  23. package/dist_ts/config/classes.db-seeder.js +0 -69
  24. package/dist_ts/config/classes.reference-resolver.d.ts +0 -80
  25. package/dist_ts/config/classes.reference-resolver.js +0 -483
  26. package/dist_ts/config/classes.route-config-manager.d.ts +0 -54
  27. package/dist_ts/config/classes.route-config-manager.js +0 -370
  28. package/dist_ts/config/classes.target-profile-manager.d.ts +0 -82
  29. package/dist_ts/config/classes.target-profile-manager.js +0 -349
  30. package/dist_ts/config/index.d.ts +0 -6
  31. package/dist_ts/config/index.js +0 -8
  32. package/dist_ts/config/validator.d.ts +0 -104
  33. package/dist_ts/config/validator.js +0 -152
  34. package/dist_ts/db/classes.cache.cleaner.d.ts +0 -47
  35. package/dist_ts/db/classes.cache.cleaner.js +0 -130
  36. package/dist_ts/db/classes.cached.document.d.ts +0 -76
  37. package/dist_ts/db/classes.cached.document.js +0 -100
  38. package/dist_ts/db/classes.dcrouter-db.d.ts +0 -70
  39. package/dist_ts/db/classes.dcrouter-db.js +0 -146
  40. package/dist_ts/db/documents/classes.accounting-session.doc.d.ts +0 -32
  41. package/dist_ts/db/documents/classes.accounting-session.doc.js +0 -214
  42. package/dist_ts/db/documents/classes.acme-cert.doc.d.ts +0 -13
  43. package/dist_ts/db/documents/classes.acme-cert.doc.js +0 -109
  44. package/dist_ts/db/documents/classes.acme-config.doc.d.ts +0 -22
  45. package/dist_ts/db/documents/classes.acme-config.doc.js +0 -121
  46. package/dist_ts/db/documents/classes.api-token.doc.d.ts +0 -18
  47. package/dist_ts/db/documents/classes.api-token.doc.js +0 -127
  48. package/dist_ts/db/documents/classes.cached.email.d.ts +0 -125
  49. package/dist_ts/db/documents/classes.cached.email.js +0 -337
  50. package/dist_ts/db/documents/classes.cached.ip.reputation.d.ts +0 -119
  51. package/dist_ts/db/documents/classes.cached.ip.reputation.js +0 -323
  52. package/dist_ts/db/documents/classes.cert-backoff.doc.d.ts +0 -11
  53. package/dist_ts/db/documents/classes.cert-backoff.doc.js +0 -97
  54. package/dist_ts/db/documents/classes.dns-provider.doc.d.ts +0 -22
  55. package/dist_ts/db/documents/classes.dns-provider.doc.js +0 -134
  56. package/dist_ts/db/documents/classes.dns-record.doc.d.ts +0 -21
  57. package/dist_ts/db/documents/classes.dns-record.doc.js +0 -143
  58. package/dist_ts/db/documents/classes.domain.doc.d.ts +0 -22
  59. package/dist_ts/db/documents/classes.domain.doc.js +0 -146
  60. package/dist_ts/db/documents/classes.email-domain.doc.d.ts +0 -17
  61. package/dist_ts/db/documents/classes.email-domain.doc.js +0 -124
  62. package/dist_ts/db/documents/classes.network-target.doc.d.ts +0 -15
  63. package/dist_ts/db/documents/classes.network-target.doc.js +0 -118
  64. package/dist_ts/db/documents/classes.proxy-cert.doc.d.ts +0 -12
  65. package/dist_ts/db/documents/classes.proxy-cert.doc.js +0 -103
  66. package/dist_ts/db/documents/classes.remote-ingress-edge.doc.d.ts +0 -17
  67. package/dist_ts/db/documents/classes.remote-ingress-edge.doc.js +0 -130
  68. package/dist_ts/db/documents/classes.route.doc.d.ts +0 -18
  69. package/dist_ts/db/documents/classes.route.doc.js +0 -121
  70. package/dist_ts/db/documents/classes.source-profile.doc.d.ts +0 -15
  71. package/dist_ts/db/documents/classes.source-profile.doc.js +0 -115
  72. package/dist_ts/db/documents/classes.target-profile.doc.d.ts +0 -16
  73. package/dist_ts/db/documents/classes.target-profile.doc.js +0 -121
  74. package/dist_ts/db/documents/classes.vlan-mappings.doc.d.ts +0 -15
  75. package/dist_ts/db/documents/classes.vlan-mappings.doc.js +0 -77
  76. package/dist_ts/db/documents/classes.vpn-client.doc.d.ts +0 -23
  77. package/dist_ts/db/documents/classes.vpn-client.doc.js +0 -172
  78. package/dist_ts/db/documents/classes.vpn-server-keys.doc.d.ts +0 -10
  79. package/dist_ts/db/documents/classes.vpn-server-keys.doc.js +0 -94
  80. package/dist_ts/db/documents/index.d.ts +0 -20
  81. package/dist_ts/db/documents/index.js +0 -30
  82. package/dist_ts/db/index.d.ts +0 -4
  83. package/dist_ts/db/index.js +0 -9
  84. package/dist_ts/dns/index.d.ts +0 -2
  85. package/dist_ts/dns/index.js +0 -3
  86. package/dist_ts/dns/manager.dns.d.ts +0 -267
  87. package/dist_ts/dns/manager.dns.js +0 -906
  88. package/dist_ts/dns/providers/cloudflare.provider.d.ts +0 -21
  89. package/dist_ts/dns/providers/cloudflare.provider.js +0 -106
  90. package/dist_ts/dns/providers/factory.d.ts +0 -23
  91. package/dist_ts/dns/providers/factory.js +0 -47
  92. package/dist_ts/dns/providers/index.d.ts +0 -3
  93. package/dist_ts/dns/providers/index.js +0 -4
  94. package/dist_ts/dns/providers/interfaces.d.ts +0 -54
  95. package/dist_ts/dns/providers/interfaces.js +0 -2
  96. package/dist_ts/email/classes.email-domain.manager.d.ts +0 -46
  97. package/dist_ts/email/classes.email-domain.manager.js +0 -276
  98. package/dist_ts/email/index.d.ts +0 -1
  99. package/dist_ts/email/index.js +0 -2
  100. package/dist_ts/errors/base.errors.d.ts +0 -224
  101. package/dist_ts/errors/base.errors.js +0 -320
  102. package/dist_ts/errors/error-handler.d.ts +0 -98
  103. package/dist_ts/errors/error-handler.js +0 -282
  104. package/dist_ts/errors/error.codes.d.ts +0 -115
  105. package/dist_ts/errors/error.codes.js +0 -136
  106. package/dist_ts/errors/index.d.ts +0 -54
  107. package/dist_ts/errors/index.js +0 -136
  108. package/dist_ts/errors/reputation.errors.d.ts +0 -183
  109. package/dist_ts/errors/reputation.errors.js +0 -292
  110. package/dist_ts/http3/http3-route-augmentation.d.ts +0 -50
  111. package/dist_ts/http3/http3-route-augmentation.js +0 -98
  112. package/dist_ts/http3/index.d.ts +0 -1
  113. package/dist_ts/http3/index.js +0 -2
  114. package/dist_ts/index.d.ts +0 -8
  115. package/dist_ts/index.js +0 -29
  116. package/dist_ts/logger.d.ts +0 -21
  117. package/dist_ts/logger.js +0 -81
  118. package/dist_ts/monitoring/classes.metricscache.d.ts +0 -32
  119. package/dist_ts/monitoring/classes.metricscache.js +0 -63
  120. package/dist_ts/monitoring/classes.metricsmanager.d.ts +0 -233
  121. package/dist_ts/monitoring/classes.metricsmanager.js +0 -897
  122. package/dist_ts/monitoring/index.d.ts +0 -1
  123. package/dist_ts/monitoring/index.js +0 -2
  124. package/dist_ts/opsserver/classes.opsserver.d.ts +0 -47
  125. package/dist_ts/opsserver/classes.opsserver.js +0 -105
  126. package/dist_ts/opsserver/handlers/acme-config.handler.d.ts +0 -16
  127. package/dist_ts/opsserver/handlers/acme-config.handler.js +0 -77
  128. package/dist_ts/opsserver/handlers/admin.handler.d.ts +0 -40
  129. package/dist_ts/opsserver/handlers/admin.handler.js +0 -191
  130. package/dist_ts/opsserver/handlers/api-token.handler.d.ts +0 -6
  131. package/dist_ts/opsserver/handlers/api-token.handler.js +0 -62
  132. package/dist_ts/opsserver/handlers/certificate.handler.d.ts +0 -77
  133. package/dist_ts/opsserver/handlers/certificate.handler.js +0 -574
  134. package/dist_ts/opsserver/handlers/config.handler.d.ts +0 -7
  135. package/dist_ts/opsserver/handlers/config.handler.js +0 -200
  136. package/dist_ts/opsserver/handlers/dns-provider.handler.d.ts +0 -16
  137. package/dist_ts/opsserver/handlers/dns-provider.handler.js +0 -156
  138. package/dist_ts/opsserver/handlers/dns-record.handler.d.ts +0 -13
  139. package/dist_ts/opsserver/handlers/dns-record.handler.js +0 -98
  140. package/dist_ts/opsserver/handlers/domain.handler.d.ts +0 -13
  141. package/dist_ts/opsserver/handlers/domain.handler.js +0 -137
  142. package/dist_ts/opsserver/handlers/email-domain.handler.d.ts +0 -16
  143. package/dist_ts/opsserver/handlers/email-domain.handler.js +0 -150
  144. package/dist_ts/opsserver/handlers/email-ops.handler.d.ts +0 -30
  145. package/dist_ts/opsserver/handlers/email-ops.handler.js +0 -227
  146. package/dist_ts/opsserver/handlers/index.d.ts +0 -21
  147. package/dist_ts/opsserver/handlers/index.js +0 -22
  148. package/dist_ts/opsserver/handlers/logs.handler.d.ts +0 -25
  149. package/dist_ts/opsserver/handlers/logs.handler.js +0 -264
  150. package/dist_ts/opsserver/handlers/network-target.handler.d.ts +0 -10
  151. package/dist_ts/opsserver/handlers/network-target.handler.js +0 -117
  152. package/dist_ts/opsserver/handlers/radius.handler.d.ts +0 -6
  153. package/dist_ts/opsserver/handlers/radius.handler.js +0 -295
  154. package/dist_ts/opsserver/handlers/remoteingress.handler.d.ts +0 -6
  155. package/dist_ts/opsserver/handlers/remoteingress.handler.js +0 -156
  156. package/dist_ts/opsserver/handlers/route-management.handler.d.ts +0 -14
  157. package/dist_ts/opsserver/handlers/route-management.handler.js +0 -98
  158. package/dist_ts/opsserver/handlers/security.handler.d.ts +0 -9
  159. package/dist_ts/opsserver/handlers/security.handler.js +0 -237
  160. package/dist_ts/opsserver/handlers/source-profile.handler.d.ts +0 -10
  161. package/dist_ts/opsserver/handlers/source-profile.handler.js +0 -119
  162. package/dist_ts/opsserver/handlers/stats.handler.d.ts +0 -11
  163. package/dist_ts/opsserver/handlers/stats.handler.js +0 -461
  164. package/dist_ts/opsserver/handlers/target-profile.handler.d.ts +0 -10
  165. package/dist_ts/opsserver/handlers/target-profile.handler.js +0 -117
  166. package/dist_ts/opsserver/handlers/users.handler.d.ts +0 -12
  167. package/dist_ts/opsserver/handlers/users.handler.js +0 -24
  168. package/dist_ts/opsserver/handlers/vpn.handler.d.ts +0 -6
  169. package/dist_ts/opsserver/handlers/vpn.handler.js +0 -262
  170. package/dist_ts/opsserver/helpers/guards.d.ts +0 -27
  171. package/dist_ts/opsserver/helpers/guards.js +0 -43
  172. package/dist_ts/opsserver/index.d.ts +0 -1
  173. package/dist_ts/opsserver/index.js +0 -2
  174. package/dist_ts/paths.d.ts +0 -25
  175. package/dist_ts/paths.js +0 -44
  176. package/dist_ts/plugins.d.ts +0 -81
  177. package/dist_ts/plugins.js +0 -115
  178. package/dist_ts/radius/classes.accounting.manager.d.ts +0 -223
  179. package/dist_ts/radius/classes.accounting.manager.js +0 -449
  180. package/dist_ts/radius/classes.radius.server.d.ts +0 -169
  181. package/dist_ts/radius/classes.radius.server.js +0 -384
  182. package/dist_ts/radius/classes.vlan.manager.d.ts +0 -124
  183. package/dist_ts/radius/classes.vlan.manager.js +0 -272
  184. package/dist_ts/radius/index.d.ts +0 -13
  185. package/dist_ts/radius/index.js +0 -14
  186. package/dist_ts/remoteingress/classes.remoteingress-manager.d.ts +0 -92
  187. package/dist_ts/remoteingress/classes.remoteingress-manager.js +0 -291
  188. package/dist_ts/remoteingress/classes.tunnel-manager.d.ts +0 -59
  189. package/dist_ts/remoteingress/classes.tunnel-manager.js +0 -165
  190. package/dist_ts/remoteingress/index.d.ts +0 -2
  191. package/dist_ts/remoteingress/index.js +0 -3
  192. package/dist_ts/security/classes.contentscanner.d.ts +0 -164
  193. package/dist_ts/security/classes.contentscanner.js +0 -642
  194. package/dist_ts/security/classes.ipreputationchecker.d.ts +0 -145
  195. package/dist_ts/security/classes.ipreputationchecker.js +0 -458
  196. package/dist_ts/security/classes.securitylogger.d.ts +0 -144
  197. package/dist_ts/security/classes.securitylogger.js +0 -235
  198. package/dist_ts/security/index.d.ts +0 -3
  199. package/dist_ts/security/index.js +0 -4
  200. package/dist_ts/sms/classes.smsservice.d.ts +0 -15
  201. package/dist_ts/sms/classes.smsservice.js +0 -72
  202. package/dist_ts/sms/config/sms.config.d.ts +0 -93
  203. package/dist_ts/sms/config/sms.config.js +0 -2
  204. package/dist_ts/sms/config/sms.schema.d.ts +0 -5
  205. package/dist_ts/sms/config/sms.schema.js +0 -121
  206. package/dist_ts/sms/index.d.ts +0 -1
  207. package/dist_ts/sms/index.js +0 -2
  208. package/dist_ts/vpn/classes.vpn-manager.d.ts +0 -159
  209. package/dist_ts/vpn/classes.vpn-manager.js +0 -459
  210. package/dist_ts/vpn/index.d.ts +0 -1
  211. package/dist_ts/vpn/index.js +0 -2
  212. package/dist_ts_apiclient/classes.apitoken.d.ts +0 -41
  213. package/dist_ts_apiclient/classes.apitoken.js +0 -115
  214. package/dist_ts_apiclient/classes.certificate.d.ts +0 -57
  215. package/dist_ts_apiclient/classes.certificate.js +0 -69
  216. package/dist_ts_apiclient/classes.config.d.ts +0 -7
  217. package/dist_ts_apiclient/classes.config.js +0 -11
  218. package/dist_ts_apiclient/classes.dcrouterapiclient.d.ts +0 -41
  219. package/dist_ts_apiclient/classes.dcrouterapiclient.js +0 -81
  220. package/dist_ts_apiclient/classes.email.d.ts +0 -30
  221. package/dist_ts_apiclient/classes.email.js +0 -52
  222. package/dist_ts_apiclient/classes.logs.d.ts +0 -21
  223. package/dist_ts_apiclient/classes.logs.js +0 -14
  224. package/dist_ts_apiclient/classes.radius.d.ts +0 -59
  225. package/dist_ts_apiclient/classes.radius.js +0 -95
  226. package/dist_ts_apiclient/classes.remoteingress.d.ts +0 -54
  227. package/dist_ts_apiclient/classes.remoteingress.js +0 -136
  228. package/dist_ts_apiclient/classes.route.d.ts +0 -39
  229. package/dist_ts_apiclient/classes.route.js +0 -125
  230. package/dist_ts_apiclient/classes.stats.d.ts +0 -47
  231. package/dist_ts_apiclient/classes.stats.js +0 -38
  232. package/dist_ts_apiclient/index.d.ts +0 -10
  233. package/dist_ts_apiclient/index.js +0 -14
  234. package/dist_ts_apiclient/plugins.d.ts +0 -3
  235. package/dist_ts_apiclient/plugins.js +0 -5
  236. package/dist_ts_interfaces/data/acme-config.d.ts +0 -25
  237. package/dist_ts_interfaces/data/acme-config.js +0 -2
  238. package/dist_ts_interfaces/data/auth.d.ts +0 -8
  239. package/dist_ts_interfaces/data/auth.js +0 -2
  240. package/dist_ts_interfaces/data/dns-provider.d.ts +0 -136
  241. package/dist_ts_interfaces/data/dns-provider.js +0 -41
  242. package/dist_ts_interfaces/data/dns-record.d.ts +0 -42
  243. package/dist_ts_interfaces/data/dns-record.js +0 -2
  244. package/dist_ts_interfaces/data/domain.d.ts +0 -35
  245. package/dist_ts_interfaces/data/domain.js +0 -2
  246. package/dist_ts_interfaces/data/email-domain.d.ts +0 -70
  247. package/dist_ts_interfaces/data/email-domain.js +0 -2
  248. package/dist_ts_interfaces/data/index.d.ts +0 -11
  249. package/dist_ts_interfaces/data/index.js +0 -12
  250. package/dist_ts_interfaces/data/remoteingress.d.ts +0 -60
  251. package/dist_ts_interfaces/data/remoteingress.js +0 -2
  252. package/dist_ts_interfaces/data/route-management.d.ts +0 -110
  253. package/dist_ts_interfaces/data/route-management.js +0 -2
  254. package/dist_ts_interfaces/data/stats.d.ts +0 -238
  255. package/dist_ts_interfaces/data/stats.js +0 -2
  256. package/dist_ts_interfaces/data/target-profile.d.ts +0 -28
  257. package/dist_ts_interfaces/data/target-profile.js +0 -2
  258. package/dist_ts_interfaces/data/vpn.d.ts +0 -61
  259. package/dist_ts_interfaces/data/vpn.js +0 -2
  260. package/dist_ts_interfaces/index.d.ts +0 -5
  261. package/dist_ts_interfaces/index.js +0 -8
  262. package/dist_ts_interfaces/plugins.d.ts +0 -2
  263. package/dist_ts_interfaces/plugins.js +0 -4
  264. package/dist_ts_interfaces/requests/acme-config.d.ts +0 -42
  265. package/dist_ts_interfaces/requests/acme-config.js +0 -2
  266. package/dist_ts_interfaces/requests/admin.d.ts +0 -31
  267. package/dist_ts_interfaces/requests/admin.js +0 -3
  268. package/dist_ts_interfaces/requests/api-tokens.d.ts +0 -79
  269. package/dist_ts_interfaces/requests/api-tokens.js +0 -2
  270. package/dist_ts_interfaces/requests/certificate.d.ts +0 -111
  271. package/dist_ts_interfaces/requests/certificate.js +0 -3
  272. package/dist_ts_interfaces/requests/combined.stats.d.ts +0 -28
  273. package/dist_ts_interfaces/requests/combined.stats.js +0 -2
  274. package/dist_ts_interfaces/requests/config.d.ts +0 -90
  275. package/dist_ts_interfaces/requests/config.js +0 -3
  276. package/dist_ts_interfaces/requests/dns-providers.d.ts +0 -117
  277. package/dist_ts_interfaces/requests/dns-providers.js +0 -2
  278. package/dist_ts_interfaces/requests/dns-records.d.ts +0 -89
  279. package/dist_ts_interfaces/requests/dns-records.js +0 -2
  280. package/dist_ts_interfaces/requests/domains.d.ts +0 -142
  281. package/dist_ts_interfaces/requests/domains.js +0 -2
  282. package/dist_ts_interfaces/requests/email-domains.d.ts +0 -142
  283. package/dist_ts_interfaces/requests/email-domains.js +0 -2
  284. package/dist_ts_interfaces/requests/email-ops.d.ts +0 -82
  285. package/dist_ts_interfaces/requests/email-ops.js +0 -3
  286. package/dist_ts_interfaces/requests/index.d.ts +0 -21
  287. package/dist_ts_interfaces/requests/index.js +0 -22
  288. package/dist_ts_interfaces/requests/logs.d.ts +0 -41
  289. package/dist_ts_interfaces/requests/logs.js +0 -4
  290. package/dist_ts_interfaces/requests/network-targets.d.ts +0 -102
  291. package/dist_ts_interfaces/requests/network-targets.js +0 -2
  292. package/dist_ts_interfaces/requests/radius.d.ts +0 -268
  293. package/dist_ts_interfaces/requests/radius.js +0 -3
  294. package/dist_ts_interfaces/requests/remoteingress.d.ts +0 -108
  295. package/dist_ts_interfaces/requests/remoteingress.js +0 -3
  296. package/dist_ts_interfaces/requests/route-management.d.ts +0 -85
  297. package/dist_ts_interfaces/requests/route-management.js +0 -2
  298. package/dist_ts_interfaces/requests/source-profiles.d.ts +0 -102
  299. package/dist_ts_interfaces/requests/source-profiles.js +0 -2
  300. package/dist_ts_interfaces/requests/stats.d.ts +0 -177
  301. package/dist_ts_interfaces/requests/stats.js +0 -4
  302. package/dist_ts_interfaces/requests/target-profiles.d.ts +0 -103
  303. package/dist_ts_interfaces/requests/target-profiles.js +0 -2
  304. package/dist_ts_interfaces/requests/users.d.ts +0 -19
  305. package/dist_ts_interfaces/requests/users.js +0 -3
  306. package/dist_ts_interfaces/requests/vpn.d.ts +0 -177
  307. package/dist_ts_interfaces/requests/vpn.js +0 -3
  308. package/dist_ts_migrations/index.d.ts +0 -28
  309. package/dist_ts_migrations/index.js +0 -82
  310. package/dist_ts_oci_container/index.d.ts +0 -8
  311. package/dist_ts_oci_container/index.js +0 -110
  312. package/dist_ts_oci_container/plugins.d.ts +0 -3
  313. package/dist_ts_oci_container/plugins.js +0 -4
  314. package/dist_ts_web/00_commitinfo_data.d.ts +0 -8
  315. package/dist_ts_web/00_commitinfo_data.js +0 -9
  316. package/dist_ts_web/appstate.d.ts +0 -478
  317. package/dist_ts_web/appstate.js +0 -1968
  318. package/dist_ts_web/elements/access/index.d.ts +0 -2
  319. package/dist_ts_web/elements/access/index.js +0 -3
  320. package/dist_ts_web/elements/access/ops-view-apitokens.d.ts +0 -13
  321. package/dist_ts_web/elements/access/ops-view-apitokens.js +0 -372
  322. package/dist_ts_web/elements/access/ops-view-users.d.ts +0 -11
  323. package/dist_ts_web/elements/access/ops-view-users.js +0 -190
  324. package/dist_ts_web/elements/domains/dns-provider-form.d.ts +0 -60
  325. package/dist_ts_web/elements/domains/dns-provider-form.js +0 -259
  326. package/dist_ts_web/elements/domains/index.d.ts +0 -5
  327. package/dist_ts_web/elements/domains/index.js +0 -6
  328. package/dist_ts_web/elements/domains/ops-view-certificates.d.ts +0 -25
  329. package/dist_ts_web/elements/domains/ops-view-certificates.js +0 -669
  330. package/dist_ts_web/elements/domains/ops-view-dns.d.ts +0 -17
  331. package/dist_ts_web/elements/domains/ops-view-dns.js +0 -305
  332. package/dist_ts_web/elements/domains/ops-view-domains.d.ts +0 -19
  333. package/dist_ts_web/elements/domains/ops-view-domains.js +0 -456
  334. package/dist_ts_web/elements/domains/ops-view-providers.d.ts +0 -21
  335. package/dist_ts_web/elements/domains/ops-view-providers.js +0 -330
  336. package/dist_ts_web/elements/email/index.d.ts +0 -3
  337. package/dist_ts_web/elements/email/index.js +0 -4
  338. package/dist_ts_web/elements/email/ops-view-email-domains.d.ts +0 -19
  339. package/dist_ts_web/elements/email/ops-view-email-domains.js +0 -410
  340. package/dist_ts_web/elements/email/ops-view-email-security.d.ts +0 -14
  341. package/dist_ts_web/elements/email/ops-view-email-security.js +0 -178
  342. package/dist_ts_web/elements/email/ops-view-emails.d.ts +0 -21
  343. package/dist_ts_web/elements/email/ops-view-emails.js +0 -165
  344. package/dist_ts_web/elements/index.d.ts +0 -9
  345. package/dist_ts_web/elements/index.js +0 -10
  346. package/dist_ts_web/elements/network/index.d.ts +0 -7
  347. package/dist_ts_web/elements/network/index.js +0 -8
  348. package/dist_ts_web/elements/network/ops-view-network-activity.d.ts +0 -60
  349. package/dist_ts_web/elements/network/ops-view-network-activity.js +0 -753
  350. package/dist_ts_web/elements/network/ops-view-networktargets.d.ts +0 -17
  351. package/dist_ts_web/elements/network/ops-view-networktargets.js +0 -255
  352. package/dist_ts_web/elements/network/ops-view-remoteingress.d.ts +0 -20
  353. package/dist_ts_web/elements/network/ops-view-remoteingress.js +0 -497
  354. package/dist_ts_web/elements/network/ops-view-routes.d.ts +0 -16
  355. package/dist_ts_web/elements/network/ops-view-routes.js +0 -674
  356. package/dist_ts_web/elements/network/ops-view-sourceprofiles.d.ts +0 -17
  357. package/dist_ts_web/elements/network/ops-view-sourceprofiles.js +0 -278
  358. package/dist_ts_web/elements/network/ops-view-targetprofiles.d.ts +0 -21
  359. package/dist_ts_web/elements/network/ops-view-targetprofiles.js +0 -420
  360. package/dist_ts_web/elements/network/ops-view-vpn.d.ts +0 -31
  361. package/dist_ts_web/elements/network/ops-view-vpn.js +0 -873
  362. package/dist_ts_web/elements/ops-dashboard.d.ts +0 -31
  363. package/dist_ts_web/elements/ops-dashboard.js +0 -405
  364. package/dist_ts_web/elements/ops-view-logs.d.ts +0 -13
  365. package/dist_ts_web/elements/ops-view-logs.js +0 -159
  366. package/dist_ts_web/elements/overview/index.d.ts +0 -2
  367. package/dist_ts_web/elements/overview/index.js +0 -3
  368. package/dist_ts_web/elements/overview/ops-view-config.d.ts +0 -19
  369. package/dist_ts_web/elements/overview/ops-view-config.js +0 -339
  370. package/dist_ts_web/elements/overview/ops-view-overview.d.ts +0 -24
  371. package/dist_ts_web/elements/overview/ops-view-overview.js +0 -545
  372. package/dist_ts_web/elements/security/index.d.ts +0 -3
  373. package/dist_ts_web/elements/security/index.js +0 -4
  374. package/dist_ts_web/elements/security/ops-view-security-authentication.d.ts +0 -13
  375. package/dist_ts_web/elements/security/ops-view-security-authentication.js +0 -157
  376. package/dist_ts_web/elements/security/ops-view-security-blocked.d.ts +0 -15
  377. package/dist_ts_web/elements/security/ops-view-security-blocked.js +0 -153
  378. package/dist_ts_web/elements/security/ops-view-security-overview.d.ts +0 -16
  379. package/dist_ts_web/elements/security/ops-view-security-overview.js +0 -205
  380. package/dist_ts_web/elements/shared/css.d.ts +0 -1
  381. package/dist_ts_web/elements/shared/css.js +0 -10
  382. package/dist_ts_web/elements/shared/index.d.ts +0 -1
  383. package/dist_ts_web/elements/shared/index.js +0 -2
  384. package/dist_ts_web/index.d.ts +0 -1
  385. package/dist_ts_web/index.js +0 -10
  386. package/dist_ts_web/plugins.d.ts +0 -7
  387. package/dist_ts_web/plugins.js +0 -13
  388. package/dist_ts_web/router.d.ts +0 -21
  389. package/dist_ts_web/router.js +0 -151
@@ -1,642 +0,0 @@
1
- import * as plugins from '../plugins.js';
2
- import { logger } from '../logger.js';
3
- import { Email } from '@push.rocks/smartmta';
4
- import { SecurityLogger, SecurityLogLevel, SecurityEventType } from './classes.securitylogger.js';
5
- import { LRUCache } from 'lru-cache';
6
- /**
7
- * Threat categories
8
- */
9
- export var ThreatCategory;
10
- (function (ThreatCategory) {
11
- ThreatCategory["SPAM"] = "spam";
12
- ThreatCategory["PHISHING"] = "phishing";
13
- ThreatCategory["MALWARE"] = "malware";
14
- ThreatCategory["EXECUTABLE"] = "executable";
15
- ThreatCategory["SUSPICIOUS_LINK"] = "suspicious_link";
16
- ThreatCategory["MALICIOUS_MACRO"] = "malicious_macro";
17
- ThreatCategory["XSS"] = "xss";
18
- ThreatCategory["SENSITIVE_DATA"] = "sensitive_data";
19
- ThreatCategory["BLACKLISTED_CONTENT"] = "blacklisted_content";
20
- ThreatCategory["CUSTOM_RULE"] = "custom_rule";
21
- })(ThreatCategory || (ThreatCategory = {}));
22
- /**
23
- * Content Scanner for detecting malicious email content
24
- */
25
- export class ContentScanner {
26
- static instance;
27
- scanCache;
28
- options;
29
- // Predefined patterns for common threats
30
- static MALICIOUS_PATTERNS = {
31
- // Phishing patterns
32
- phishing: [
33
- /(?:verify|confirm|update|login).*(?:account|password|details)/i,
34
- /urgent.*(?:action|attention|required)/i,
35
- /(?:paypal|apple|microsoft|amazon|google|bank).*(?:verify|confirm|suspend)/i,
36
- /your.*(?:account).*(?:suspended|compromised|locked)/i,
37
- /\b(?:password reset|security alert|security notice)\b/i
38
- ],
39
- // Spam indicators
40
- spam: [
41
- /\b(?:viagra|cialis|enlargement|diet pill|lose weight fast|cheap meds)\b/i,
42
- /\b(?:million dollars|lottery winner|prize claim|inheritance|rich widow)\b/i,
43
- /\b(?:earn from home|make money fast|earn \$\d{3,}\/day)\b/i,
44
- /\b(?:limited time offer|act now|exclusive deal|only \d+ left)\b/i,
45
- /\b(?:forex|stock tip|investment opportunity|cryptocurrency|bitcoin)\b/i
46
- ],
47
- // Malware indicators in text
48
- malware: [
49
- /(?:attached file|see attachment).*(?:invoice|receipt|statement|document)/i,
50
- /open.*(?:the attached|this attachment)/i,
51
- /(?:enable|allow).*(?:macros|content|editing)/i,
52
- /download.*(?:attachment|file|document)/i,
53
- /\b(?:ransomware protection|virus alert|malware detected)\b/i
54
- ],
55
- // Suspicious links
56
- suspiciousLinks: [
57
- /https?:\/\/bit\.ly\//i,
58
- /https?:\/\/goo\.gl\//i,
59
- /https?:\/\/t\.co\//i,
60
- /https?:\/\/tinyurl\.com\//i,
61
- /https?:\/\/(?:\d{1,3}\.){3}\d{1,3}/i, // IP address URLs
62
- /https?:\/\/.*\.(?:xyz|top|club|gq|cf)\//i, // Suspicious TLDs
63
- /(?:login|account|signin|auth).*\.(?!gov|edu|com|org|net)\w+\.\w+/i, // Login pages on unusual domains
64
- ],
65
- // XSS and script injection
66
- scriptInjection: [
67
- /<script.*>.*<\/script>/is,
68
- /javascript:/i,
69
- /on(?:click|load|mouse|error|focus|blur)=".*"/i,
70
- /document\.(?:cookie|write|location)/i,
71
- /eval\s*\(/i
72
- ],
73
- // Sensitive data patterns
74
- sensitiveData: [
75
- /\b(?:\d{3}-\d{2}-\d{4}|\d{9})\b/, // SSN
76
- /\b\d{13,16}\b/, // Credit card numbers
77
- /\b(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})\b/ // Possible Base64
78
- ]
79
- };
80
- // Common executable extensions
81
- static EXECUTABLE_EXTENSIONS = [
82
- '.exe', '.dll', '.bat', '.cmd', '.msi', '.js', '.vbs', '.ps1',
83
- '.sh', '.jar', '.py', '.com', '.scr', '.pif', '.hta', '.cpl',
84
- '.reg', '.vba', '.lnk', '.wsf', '.msi', '.msp', '.mst'
85
- ];
86
- // Document formats that may contain macros
87
- static MACRO_DOCUMENT_EXTENSIONS = [
88
- '.doc', '.docm', '.xls', '.xlsm', '.ppt', '.pptm', '.dotm', '.xlsb', '.ppam', '.potm'
89
- ];
90
- /**
91
- * Default options for the content scanner
92
- */
93
- static DEFAULT_OPTIONS = {
94
- maxCacheSize: 10000,
95
- cacheTTL: 24 * 60 * 60 * 1000, // 24 hours
96
- scanSubject: true,
97
- scanBody: true,
98
- scanAttachments: true,
99
- maxAttachmentSizeToScan: 10 * 1024 * 1024, // 10MB
100
- scanAttachmentNames: true,
101
- blockExecutables: true,
102
- blockMacros: true,
103
- customRules: [],
104
- minThreatScore: 30, // Minimum score to consider content as a threat
105
- highThreatScore: 70 // Score above which content is considered high threat
106
- };
107
- /**
108
- * Constructor for the ContentScanner
109
- * @param options Configuration options
110
- */
111
- constructor(options = {}) {
112
- // Merge with default options
113
- this.options = {
114
- ...ContentScanner.DEFAULT_OPTIONS,
115
- ...options
116
- };
117
- // Initialize cache
118
- this.scanCache = new LRUCache({
119
- max: this.options.maxCacheSize,
120
- ttl: this.options.cacheTTL,
121
- });
122
- logger.log('info', 'ContentScanner initialized');
123
- }
124
- /**
125
- * Get the singleton instance of the scanner
126
- * @param options Configuration options
127
- * @returns Singleton scanner instance
128
- */
129
- static getInstance(options = {}) {
130
- if (!ContentScanner.instance) {
131
- ContentScanner.instance = new ContentScanner(options);
132
- }
133
- return ContentScanner.instance;
134
- }
135
- /**
136
- * Reset the singleton instance (for shutdown/testing)
137
- */
138
- static resetInstance() {
139
- ContentScanner.instance = undefined;
140
- }
141
- /**
142
- * Scan an email for malicious content
143
- * @param email The email to scan
144
- * @returns Scan result
145
- */
146
- async scanEmail(email) {
147
- try {
148
- // Generate a cache key from the email
149
- const cacheKey = this.generateCacheKey(email);
150
- // Check cache first
151
- const cachedResult = this.scanCache.get(cacheKey);
152
- if (cachedResult) {
153
- logger.log('info', `Using cached scan result for email ${email.getMessageId()}`);
154
- return cachedResult;
155
- }
156
- // Initialize scan result
157
- const result = {
158
- isClean: true,
159
- threatScore: 0,
160
- scannedElements: [],
161
- timestamp: Date.now()
162
- };
163
- // List of scan promises
164
- const scanPromises = [];
165
- // Scan subject
166
- if (this.options.scanSubject && email.subject) {
167
- scanPromises.push(this.scanSubject(email.subject, result));
168
- }
169
- // Scan body content
170
- if (this.options.scanBody) {
171
- if (email.text) {
172
- scanPromises.push(this.scanTextContent(email.text, result));
173
- }
174
- if (email.html) {
175
- scanPromises.push(this.scanHtmlContent(email.html, result));
176
- }
177
- }
178
- // Scan attachments
179
- if (this.options.scanAttachments && email.attachments && email.attachments.length > 0) {
180
- for (const attachment of email.attachments) {
181
- scanPromises.push(this.scanAttachment(attachment, result));
182
- }
183
- }
184
- // Run all scans in parallel
185
- await Promise.all(scanPromises);
186
- // Determine if the email is clean based on threat score
187
- result.isClean = result.threatScore < this.options.minThreatScore;
188
- // Save to cache
189
- this.scanCache.set(cacheKey, result);
190
- // Log high threat findings
191
- if (result.threatScore >= this.options.highThreatScore) {
192
- this.logHighThreatFound(email, result);
193
- }
194
- else if (!result.isClean) {
195
- this.logThreatFound(email, result);
196
- }
197
- return result;
198
- }
199
- catch (error) {
200
- logger.log('error', `Error scanning email: ${error.message}`, {
201
- messageId: email.getMessageId(),
202
- error: error.stack
203
- });
204
- // Return a safe default with error indication
205
- return {
206
- isClean: true, // Let it pass if scanner fails (configure as desired)
207
- threatScore: 0,
208
- scannedElements: ['error'],
209
- timestamp: Date.now(),
210
- threatType: 'scan_error',
211
- threatDetails: `Scan error: ${error.message}`
212
- };
213
- }
214
- }
215
- /**
216
- * Generate a cache key from an email
217
- * @param email The email to generate a key for
218
- * @returns Cache key
219
- */
220
- generateCacheKey(email) {
221
- // Use message ID if available
222
- if (email.getMessageId()) {
223
- return `email:${email.getMessageId()}`;
224
- }
225
- // Fallback to a hash of key content
226
- const contentToHash = [
227
- email.from,
228
- email.subject || '',
229
- email.text?.substring(0, 1000) || '',
230
- email.html?.substring(0, 1000) || '',
231
- email.attachments?.length || 0
232
- ].join(':');
233
- return `email:${plugins.crypto.createHash('sha256').update(contentToHash).digest('hex')}`;
234
- }
235
- /**
236
- * Scan email subject for threats
237
- * @param subject The subject to scan
238
- * @param result The scan result to update
239
- */
240
- async scanSubject(subject, result) {
241
- result.scannedElements.push('subject');
242
- // Check against phishing patterns
243
- for (const pattern of ContentScanner.MALICIOUS_PATTERNS.phishing) {
244
- if (pattern.test(subject)) {
245
- result.threatScore += 25;
246
- result.threatType = ThreatCategory.PHISHING;
247
- result.threatDetails = `Subject contains potential phishing indicators: ${subject}`;
248
- return;
249
- }
250
- }
251
- // Check against spam patterns
252
- for (const pattern of ContentScanner.MALICIOUS_PATTERNS.spam) {
253
- if (pattern.test(subject)) {
254
- result.threatScore += 15;
255
- result.threatType = ThreatCategory.SPAM;
256
- result.threatDetails = `Subject contains potential spam indicators: ${subject}`;
257
- return;
258
- }
259
- }
260
- // Check custom rules
261
- for (const rule of this.options.customRules) {
262
- const pattern = rule.pattern instanceof RegExp ? rule.pattern : new RegExp(rule.pattern, 'i');
263
- if (pattern.test(subject)) {
264
- result.threatScore += rule.score;
265
- result.threatType = rule.type;
266
- result.threatDetails = rule.description;
267
- return;
268
- }
269
- }
270
- }
271
- /**
272
- * Scan plain text content for threats
273
- * @param text The text content to scan
274
- * @param result The scan result to update
275
- */
276
- async scanTextContent(text, result) {
277
- result.scannedElements.push('text');
278
- // Check suspicious links
279
- for (const pattern of ContentScanner.MALICIOUS_PATTERNS.suspiciousLinks) {
280
- if (pattern.test(text)) {
281
- result.threatScore += 20;
282
- if (!result.threatType || result.threatScore > (result.threatType === ThreatCategory.SUSPICIOUS_LINK ? 0 : 20)) {
283
- result.threatType = ThreatCategory.SUSPICIOUS_LINK;
284
- result.threatDetails = `Text contains suspicious links`;
285
- }
286
- }
287
- }
288
- // Check phishing
289
- for (const pattern of ContentScanner.MALICIOUS_PATTERNS.phishing) {
290
- if (pattern.test(text)) {
291
- result.threatScore += 25;
292
- if (!result.threatType || result.threatScore > (result.threatType === ThreatCategory.PHISHING ? 0 : 25)) {
293
- result.threatType = ThreatCategory.PHISHING;
294
- result.threatDetails = `Text contains potential phishing indicators`;
295
- }
296
- }
297
- }
298
- // Check spam
299
- for (const pattern of ContentScanner.MALICIOUS_PATTERNS.spam) {
300
- if (pattern.test(text)) {
301
- result.threatScore += 15;
302
- if (!result.threatType || result.threatScore > (result.threatType === ThreatCategory.SPAM ? 0 : 15)) {
303
- result.threatType = ThreatCategory.SPAM;
304
- result.threatDetails = `Text contains potential spam indicators`;
305
- }
306
- }
307
- }
308
- // Check malware indicators
309
- for (const pattern of ContentScanner.MALICIOUS_PATTERNS.malware) {
310
- if (pattern.test(text)) {
311
- result.threatScore += 30;
312
- if (!result.threatType || result.threatScore > (result.threatType === ThreatCategory.MALWARE ? 0 : 30)) {
313
- result.threatType = ThreatCategory.MALWARE;
314
- result.threatDetails = `Text contains potential malware indicators`;
315
- }
316
- }
317
- }
318
- // Check sensitive data
319
- for (const pattern of ContentScanner.MALICIOUS_PATTERNS.sensitiveData) {
320
- if (pattern.test(text)) {
321
- result.threatScore += 25;
322
- if (!result.threatType || result.threatScore > (result.threatType === ThreatCategory.SENSITIVE_DATA ? 0 : 25)) {
323
- result.threatType = ThreatCategory.SENSITIVE_DATA;
324
- result.threatDetails = `Text contains potentially sensitive data patterns`;
325
- }
326
- }
327
- }
328
- // Check custom rules
329
- for (const rule of this.options.customRules) {
330
- const pattern = rule.pattern instanceof RegExp ? rule.pattern : new RegExp(rule.pattern, 'i');
331
- if (pattern.test(text)) {
332
- result.threatScore += rule.score;
333
- if (!result.threatType || result.threatScore > 20) {
334
- result.threatType = rule.type;
335
- result.threatDetails = rule.description;
336
- }
337
- }
338
- }
339
- }
340
- /**
341
- * Scan HTML content for threats
342
- * @param html The HTML content to scan
343
- * @param result The scan result to update
344
- */
345
- async scanHtmlContent(html, result) {
346
- result.scannedElements.push('html');
347
- // Check for script injection
348
- for (const pattern of ContentScanner.MALICIOUS_PATTERNS.scriptInjection) {
349
- if (pattern.test(html)) {
350
- result.threatScore += 40;
351
- if (!result.threatType || result.threatType !== ThreatCategory.XSS) {
352
- result.threatType = ThreatCategory.XSS;
353
- result.threatDetails = `HTML contains potentially malicious script content`;
354
- }
355
- }
356
- }
357
- // Extract text content from HTML for further scanning
358
- const textContent = this.extractTextFromHtml(html);
359
- if (textContent) {
360
- // We'll leverage the text scanning but not double-count threat score
361
- const tempResult = {
362
- isClean: true,
363
- threatScore: 0,
364
- scannedElements: [],
365
- timestamp: Date.now()
366
- };
367
- await this.scanTextContent(textContent, tempResult);
368
- // Only add additional threat types if they're more severe
369
- if (tempResult.threatType && tempResult.threatScore > 0) {
370
- // Add half of the text content score to avoid double counting
371
- result.threatScore += Math.floor(tempResult.threatScore / 2);
372
- // Adopt the threat type if more severe or no existing type
373
- if (!result.threatType || tempResult.threatScore > result.threatScore) {
374
- result.threatType = tempResult.threatType;
375
- result.threatDetails = tempResult.threatDetails;
376
- }
377
- }
378
- }
379
- // Extract and check links from HTML
380
- const links = this.extractLinksFromHtml(html);
381
- if (links.length > 0) {
382
- // Check for suspicious links
383
- let suspiciousLinks = 0;
384
- for (const link of links) {
385
- for (const pattern of ContentScanner.MALICIOUS_PATTERNS.suspiciousLinks) {
386
- if (pattern.test(link)) {
387
- suspiciousLinks++;
388
- break;
389
- }
390
- }
391
- }
392
- if (suspiciousLinks > 0) {
393
- // Add score based on percentage of suspicious links
394
- const suspiciousPercentage = (suspiciousLinks / links.length) * 100;
395
- const additionalScore = Math.min(40, Math.floor(suspiciousPercentage / 2.5));
396
- result.threatScore += additionalScore;
397
- if (!result.threatType || additionalScore > 20) {
398
- result.threatType = ThreatCategory.SUSPICIOUS_LINK;
399
- result.threatDetails = `HTML contains ${suspiciousLinks} suspicious links out of ${links.length} total links`;
400
- }
401
- }
402
- }
403
- }
404
- /**
405
- * Scan an attachment for threats
406
- * @param attachment The attachment to scan
407
- * @param result The scan result to update
408
- */
409
- async scanAttachment(attachment, result) {
410
- const filename = attachment.filename.toLowerCase();
411
- result.scannedElements.push(`attachment:${filename}`);
412
- // Skip large attachments if configured
413
- if (attachment.content && attachment.content.length > this.options.maxAttachmentSizeToScan) {
414
- logger.log('info', `Skipping scan of large attachment: ${filename} (${attachment.content.length} bytes)`);
415
- return;
416
- }
417
- // Check filename for executable extensions
418
- if (this.options.blockExecutables) {
419
- for (const ext of ContentScanner.EXECUTABLE_EXTENSIONS) {
420
- if (filename.endsWith(ext)) {
421
- result.threatScore += 70; // High score for executable attachments
422
- result.threatType = ThreatCategory.EXECUTABLE;
423
- result.threatDetails = `Attachment has a potentially dangerous extension: ${filename}`;
424
- return; // No need to scan contents if filename already flagged
425
- }
426
- }
427
- }
428
- // Check for Office documents with macros
429
- if (this.options.blockMacros) {
430
- for (const ext of ContentScanner.MACRO_DOCUMENT_EXTENSIONS) {
431
- if (filename.endsWith(ext)) {
432
- // For Office documents, check if they contain macros
433
- // This is a simplified check - a real implementation would use specialized libraries
434
- // to detect macros in Office documents
435
- if (attachment.content && this.likelyContainsMacros(attachment)) {
436
- result.threatScore += 60;
437
- result.threatType = ThreatCategory.MALICIOUS_MACRO;
438
- result.threatDetails = `Attachment appears to contain macros: ${filename}`;
439
- return;
440
- }
441
- }
442
- }
443
- }
444
- // Perform basic content analysis if we have content buffer
445
- if (attachment.content) {
446
- // Convert to string for scanning, with a limit to prevent memory issues
447
- const textContent = this.extractTextFromBuffer(attachment.content);
448
- if (textContent) {
449
- // Scan for malicious patterns in attachment content
450
- for (const category in ContentScanner.MALICIOUS_PATTERNS) {
451
- const patterns = ContentScanner.MALICIOUS_PATTERNS[category];
452
- for (const pattern of patterns) {
453
- if (pattern.test(textContent)) {
454
- result.threatScore += 30;
455
- if (!result.threatType) {
456
- result.threatType = this.mapCategoryToThreatType(category);
457
- result.threatDetails = `Attachment content contains suspicious patterns: ${filename}`;
458
- }
459
- break;
460
- }
461
- }
462
- }
463
- }
464
- // Check for PE headers (Windows executables)
465
- if (attachment.content.length > 64 &&
466
- attachment.content[0] === 0x4D &&
467
- attachment.content[1] === 0x5A) { // 'MZ' header
468
- result.threatScore += 80;
469
- result.threatType = ThreatCategory.EXECUTABLE;
470
- result.threatDetails = `Attachment contains executable code: ${filename}`;
471
- }
472
- }
473
- }
474
- /**
475
- * Extract links from HTML content
476
- * @param html HTML content
477
- * @returns Array of extracted links
478
- */
479
- extractLinksFromHtml(html) {
480
- const links = [];
481
- // Simple regex-based extraction - a real implementation might use a proper HTML parser
482
- const matches = html.match(/href=["'](https?:\/\/[^"']+)["']/gi);
483
- if (matches) {
484
- for (const match of matches) {
485
- const linkMatch = match.match(/href=["'](https?:\/\/[^"']+)["']/i);
486
- if (linkMatch && linkMatch[1]) {
487
- links.push(linkMatch[1]);
488
- }
489
- }
490
- }
491
- return links;
492
- }
493
- /**
494
- * Extract plain text from HTML
495
- * @param html HTML content
496
- * @returns Extracted text
497
- */
498
- extractTextFromHtml(html) {
499
- // Remove HTML tags and decode entities - simplified version
500
- return html
501
- .replace(/<style[^>]*>.*?<\/style>/gs, '')
502
- .replace(/<script[^>]*>.*?<\/script>/gs, '')
503
- .replace(/<[^>]+>/g, ' ')
504
- .replace(/&nbsp;/g, ' ')
505
- .replace(/&lt;/g, '<')
506
- .replace(/&gt;/g, '>')
507
- .replace(/&amp;/g, '&')
508
- .replace(/&quot;/g, '"')
509
- .replace(/&apos;/g, "'")
510
- .replace(/\s+/g, ' ')
511
- .trim();
512
- }
513
- /**
514
- * Extract text from a binary buffer for scanning
515
- * @param buffer Binary content
516
- * @returns Extracted text (may be partial)
517
- */
518
- extractTextFromBuffer(buffer) {
519
- try {
520
- // Limit the amount we convert to avoid memory issues
521
- const sampleSize = Math.min(buffer.length, 100 * 1024); // 100KB max sample
522
- const sample = buffer.slice(0, sampleSize);
523
- // Try to convert to string, filtering out non-printable chars
524
- return sample.toString('utf8')
525
- .replace(/[\x00-\x09\x0B-\x1F\x7F-\x9F]/g, '') // Remove control chars
526
- .replace(/\uFFFD/g, ''); // Remove replacement char
527
- }
528
- catch (error) {
529
- logger.log('warn', `Error extracting text from buffer: ${error.message}`);
530
- return '';
531
- }
532
- }
533
- /**
534
- * Check if an Office document likely contains macros
535
- * This is a simplified check - real implementation would use specialized libraries
536
- * @param attachment The attachment to check
537
- * @returns Whether the file likely contains macros
538
- */
539
- likelyContainsMacros(attachment) {
540
- // Simple heuristic: look for VBA/macro related strings
541
- // This is a simplified approach and not comprehensive
542
- const content = this.extractTextFromBuffer(attachment.content);
543
- const macroIndicators = [
544
- /vbaProject\.bin/i,
545
- /Microsoft VBA/i,
546
- /\bVBA\b/,
547
- /Auto_Open/i,
548
- /AutoExec/i,
549
- /DocumentOpen/i,
550
- /AutoOpen/i,
551
- /\bExecute\(/i,
552
- /\bShell\(/i,
553
- /\bCreateObject\(/i
554
- ];
555
- for (const indicator of macroIndicators) {
556
- if (indicator.test(content)) {
557
- return true;
558
- }
559
- }
560
- return false;
561
- }
562
- /**
563
- * Map a pattern category to a threat type
564
- * @param category The pattern category
565
- * @returns The corresponding threat type
566
- */
567
- mapCategoryToThreatType(category) {
568
- switch (category) {
569
- case 'phishing': return ThreatCategory.PHISHING;
570
- case 'spam': return ThreatCategory.SPAM;
571
- case 'malware': return ThreatCategory.MALWARE;
572
- case 'suspiciousLinks': return ThreatCategory.SUSPICIOUS_LINK;
573
- case 'scriptInjection': return ThreatCategory.XSS;
574
- case 'sensitiveData': return ThreatCategory.SENSITIVE_DATA;
575
- default: return ThreatCategory.BLACKLISTED_CONTENT;
576
- }
577
- }
578
- /**
579
- * Log a high threat finding to the security logger
580
- * @param email The email containing the threat
581
- * @param result The scan result
582
- */
583
- logHighThreatFound(email, result) {
584
- SecurityLogger.getInstance().logEvent({
585
- level: SecurityLogLevel.ERROR,
586
- type: SecurityEventType.MALWARE,
587
- message: `High threat content detected in email from ${email.from} to ${email.to.join(', ')}`,
588
- details: {
589
- messageId: email.getMessageId(),
590
- threatType: result.threatType,
591
- threatDetails: result.threatDetails,
592
- threatScore: result.threatScore,
593
- scannedElements: result.scannedElements,
594
- subject: email.subject
595
- },
596
- success: false,
597
- domain: email.getFromDomain() ?? undefined
598
- });
599
- }
600
- /**
601
- * Log a threat finding to the security logger
602
- * @param email The email containing the threat
603
- * @param result The scan result
604
- */
605
- logThreatFound(email, result) {
606
- SecurityLogger.getInstance().logEvent({
607
- level: SecurityLogLevel.WARN,
608
- type: SecurityEventType.SPAM,
609
- message: `Suspicious content detected in email from ${email.from} to ${email.to.join(', ')}`,
610
- details: {
611
- messageId: email.getMessageId(),
612
- threatType: result.threatType,
613
- threatDetails: result.threatDetails,
614
- threatScore: result.threatScore,
615
- scannedElements: result.scannedElements,
616
- subject: email.subject
617
- },
618
- success: false,
619
- domain: email.getFromDomain() ?? undefined
620
- });
621
- }
622
- /**
623
- * Get threat level description based on score
624
- * @param score Threat score
625
- * @returns Threat level description
626
- */
627
- static getThreatLevel(score) {
628
- if (score < 20) {
629
- return 'none';
630
- }
631
- else if (score < 40) {
632
- return 'low';
633
- }
634
- else if (score < 70) {
635
- return 'medium';
636
- }
637
- else {
638
- return 'high';
639
- }
640
- }
641
- }
642
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5jb250ZW50c2Nhbm5lci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL3NlY3VyaXR5L2NsYXNzZXMuY29udGVudHNjYW5uZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxlQUFlLENBQUM7QUFDekMsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUN0QyxPQUFPLEVBQUUsS0FBSyxFQUFhLE1BQU0sc0JBQXNCLENBQUM7QUFFeEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxnQkFBZ0IsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ2xHLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFxQ3JDOztHQUVHO0FBQ0gsTUFBTSxDQUFOLElBQVksY0FXWDtBQVhELFdBQVksY0FBYztJQUN4QiwrQkFBYSxDQUFBO0lBQ2IsdUNBQXFCLENBQUE7SUFDckIscUNBQW1CLENBQUE7SUFDbkIsMkNBQXlCLENBQUE7SUFDekIscURBQW1DLENBQUE7SUFDbkMscURBQW1DLENBQUE7SUFDbkMsNkJBQVcsQ0FBQTtJQUNYLG1EQUFpQyxDQUFBO0lBQ2pDLDZEQUEyQyxDQUFBO0lBQzNDLDZDQUEyQixDQUFBO0FBQzdCLENBQUMsRUFYVyxjQUFjLEtBQWQsY0FBYyxRQVd6QjtBQUVEOztHQUVHO0FBQ0gsTUFBTSxPQUFPLGNBQWM7SUFDakIsTUFBTSxDQUFDLFFBQVEsQ0FBNkI7SUFDNUMsU0FBUyxDQUFnQztJQUN6QyxPQUFPLENBQW1DO0lBRWxELHlDQUF5QztJQUNqQyxNQUFNLENBQVUsa0JBQWtCLEdBQUc7UUFDM0Msb0JBQW9CO1FBQ3BCLFFBQVEsRUFBRTtZQUNSLGdFQUFnRTtZQUNoRSx3Q0FBd0M7WUFDeEMsNEVBQTRFO1lBQzVFLHNEQUFzRDtZQUN0RCx3REFBd0Q7U0FDekQ7UUFFRCxrQkFBa0I7UUFDbEIsSUFBSSxFQUFF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