@serve.zone/dcrouter 13.17.0 → 13.17.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/dist_serve/bundle.js +3 -3
- package/dist_ts/00_commitinfo_data.d.ts +8 -0
- package/dist_ts/00_commitinfo_data.js +9 -0
- package/dist_ts/acme/index.d.ts +1 -0
- package/dist_ts/acme/index.js +2 -0
- package/dist_ts/acme/manager.acme-config.d.ts +48 -0
- package/dist_ts/acme/manager.acme-config.js +156 -0
- package/dist_ts/classes.cert-provision-scheduler.d.ts +52 -0
- package/dist_ts/classes.cert-provision-scheduler.js +138 -0
- package/dist_ts/classes.dcrouter.d.ts +401 -0
- package/dist_ts/classes.dcrouter.js +1852 -0
- package/dist_ts/classes.storage-cert-manager.d.ts +15 -0
- package/dist_ts/classes.storage-cert-manager.js +53 -0
- package/dist_ts/config/classes.api-token-manager.d.ts +44 -0
- package/dist_ts/config/classes.api-token-manager.js +180 -0
- package/dist_ts/config/classes.db-seeder.d.ts +25 -0
- package/dist_ts/config/classes.db-seeder.js +69 -0
- package/dist_ts/config/classes.reference-resolver.d.ts +80 -0
- package/dist_ts/config/classes.reference-resolver.js +483 -0
- package/dist_ts/config/classes.route-config-manager.d.ts +54 -0
- package/dist_ts/config/classes.route-config-manager.js +370 -0
- package/dist_ts/config/classes.target-profile-manager.d.ts +82 -0
- package/dist_ts/config/classes.target-profile-manager.js +349 -0
- package/dist_ts/config/index.d.ts +6 -0
- package/dist_ts/config/index.js +8 -0
- package/dist_ts/config/validator.d.ts +104 -0
- package/dist_ts/config/validator.js +152 -0
- package/dist_ts/db/classes.cache.cleaner.d.ts +47 -0
- package/dist_ts/db/classes.cache.cleaner.js +130 -0
- package/dist_ts/db/classes.cached.document.d.ts +76 -0
- package/dist_ts/db/classes.cached.document.js +100 -0
- package/dist_ts/db/classes.dcrouter-db.d.ts +70 -0
- package/dist_ts/db/classes.dcrouter-db.js +146 -0
- package/dist_ts/db/documents/classes.accounting-session.doc.d.ts +32 -0
- package/dist_ts/db/documents/classes.accounting-session.doc.js +214 -0
- package/dist_ts/db/documents/classes.acme-cert.doc.d.ts +13 -0
- package/dist_ts/db/documents/classes.acme-cert.doc.js +109 -0
- package/dist_ts/db/documents/classes.acme-config.doc.d.ts +22 -0
- package/dist_ts/db/documents/classes.acme-config.doc.js +121 -0
- package/dist_ts/db/documents/classes.api-token.doc.d.ts +18 -0
- package/dist_ts/db/documents/classes.api-token.doc.js +127 -0
- package/dist_ts/db/documents/classes.cached.email.d.ts +125 -0
- package/dist_ts/db/documents/classes.cached.email.js +337 -0
- package/dist_ts/db/documents/classes.cached.ip.reputation.d.ts +119 -0
- package/dist_ts/db/documents/classes.cached.ip.reputation.js +323 -0
- package/dist_ts/db/documents/classes.cert-backoff.doc.d.ts +11 -0
- package/dist_ts/db/documents/classes.cert-backoff.doc.js +97 -0
- package/dist_ts/db/documents/classes.dns-provider.doc.d.ts +22 -0
- package/dist_ts/db/documents/classes.dns-provider.doc.js +134 -0
- package/dist_ts/db/documents/classes.dns-record.doc.d.ts +21 -0
- package/dist_ts/db/documents/classes.dns-record.doc.js +143 -0
- package/dist_ts/db/documents/classes.domain.doc.d.ts +22 -0
- package/dist_ts/db/documents/classes.domain.doc.js +146 -0
- package/dist_ts/db/documents/classes.email-domain.doc.d.ts +17 -0
- package/dist_ts/db/documents/classes.email-domain.doc.js +124 -0
- package/dist_ts/db/documents/classes.network-target.doc.d.ts +15 -0
- package/dist_ts/db/documents/classes.network-target.doc.js +118 -0
- package/dist_ts/db/documents/classes.proxy-cert.doc.d.ts +12 -0
- package/dist_ts/db/documents/classes.proxy-cert.doc.js +103 -0
- package/dist_ts/db/documents/classes.remote-ingress-edge.doc.d.ts +17 -0
- package/dist_ts/db/documents/classes.remote-ingress-edge.doc.js +130 -0
- package/dist_ts/db/documents/classes.route.doc.d.ts +18 -0
- package/dist_ts/db/documents/classes.route.doc.js +121 -0
- package/dist_ts/db/documents/classes.source-profile.doc.d.ts +15 -0
- package/dist_ts/db/documents/classes.source-profile.doc.js +115 -0
- package/dist_ts/db/documents/classes.target-profile.doc.d.ts +16 -0
- package/dist_ts/db/documents/classes.target-profile.doc.js +121 -0
- package/dist_ts/db/documents/classes.vlan-mappings.doc.d.ts +15 -0
- package/dist_ts/db/documents/classes.vlan-mappings.doc.js +77 -0
- package/dist_ts/db/documents/classes.vpn-client.doc.d.ts +23 -0
- package/dist_ts/db/documents/classes.vpn-client.doc.js +172 -0
- package/dist_ts/db/documents/classes.vpn-server-keys.doc.d.ts +10 -0
- package/dist_ts/db/documents/classes.vpn-server-keys.doc.js +94 -0
- package/dist_ts/db/documents/index.d.ts +20 -0
- package/dist_ts/db/documents/index.js +30 -0
- package/dist_ts/db/index.d.ts +4 -0
- package/dist_ts/db/index.js +9 -0
- package/dist_ts/dns/index.d.ts +2 -0
- package/dist_ts/dns/index.js +3 -0
- package/dist_ts/dns/manager.dns.d.ts +267 -0
- package/dist_ts/dns/manager.dns.js +906 -0
- package/dist_ts/dns/providers/cloudflare.provider.d.ts +21 -0
- package/dist_ts/dns/providers/cloudflare.provider.js +106 -0
- package/dist_ts/dns/providers/factory.d.ts +23 -0
- package/dist_ts/dns/providers/factory.js +47 -0
- package/dist_ts/dns/providers/index.d.ts +3 -0
- package/dist_ts/dns/providers/index.js +4 -0
- package/dist_ts/dns/providers/interfaces.d.ts +54 -0
- package/dist_ts/dns/providers/interfaces.js +2 -0
- package/dist_ts/email/classes.email-domain.manager.d.ts +46 -0
- package/dist_ts/email/classes.email-domain.manager.js +276 -0
- package/dist_ts/email/index.d.ts +1 -0
- package/dist_ts/email/index.js +2 -0
- package/dist_ts/errors/base.errors.d.ts +224 -0
- package/dist_ts/errors/base.errors.js +320 -0
- package/dist_ts/errors/error-handler.d.ts +98 -0
- package/dist_ts/errors/error-handler.js +282 -0
- package/dist_ts/errors/error.codes.d.ts +115 -0
- package/dist_ts/errors/error.codes.js +136 -0
- package/dist_ts/errors/index.d.ts +54 -0
- package/dist_ts/errors/index.js +136 -0
- package/dist_ts/errors/reputation.errors.d.ts +183 -0
- package/dist_ts/errors/reputation.errors.js +292 -0
- package/dist_ts/http3/http3-route-augmentation.d.ts +50 -0
- package/dist_ts/http3/http3-route-augmentation.js +98 -0
- package/dist_ts/http3/index.d.ts +1 -0
- package/dist_ts/http3/index.js +2 -0
- package/dist_ts/index.d.ts +8 -0
- package/dist_ts/index.js +29 -0
- package/dist_ts/logger.d.ts +21 -0
- package/dist_ts/logger.js +81 -0
- package/dist_ts/monitoring/classes.metricscache.d.ts +32 -0
- package/dist_ts/monitoring/classes.metricscache.js +63 -0
- package/dist_ts/monitoring/classes.metricsmanager.d.ts +235 -0
- package/dist_ts/monitoring/classes.metricsmanager.js +875 -0
- package/dist_ts/monitoring/index.d.ts +1 -0
- package/dist_ts/monitoring/index.js +2 -0
- package/dist_ts/opsserver/classes.opsserver.d.ts +47 -0
- package/dist_ts/opsserver/classes.opsserver.js +105 -0
- package/dist_ts/opsserver/handlers/acme-config.handler.d.ts +16 -0
- package/dist_ts/opsserver/handlers/acme-config.handler.js +77 -0
- package/dist_ts/opsserver/handlers/admin.handler.d.ts +40 -0
- package/dist_ts/opsserver/handlers/admin.handler.js +191 -0
- package/dist_ts/opsserver/handlers/api-token.handler.d.ts +6 -0
- package/dist_ts/opsserver/handlers/api-token.handler.js +62 -0
- package/dist_ts/opsserver/handlers/certificate.handler.d.ts +77 -0
- package/dist_ts/opsserver/handlers/certificate.handler.js +574 -0
- package/dist_ts/opsserver/handlers/config.handler.d.ts +7 -0
- package/dist_ts/opsserver/handlers/config.handler.js +200 -0
- package/dist_ts/opsserver/handlers/dns-provider.handler.d.ts +16 -0
- package/dist_ts/opsserver/handlers/dns-provider.handler.js +156 -0
- package/dist_ts/opsserver/handlers/dns-record.handler.d.ts +13 -0
- package/dist_ts/opsserver/handlers/dns-record.handler.js +98 -0
- package/dist_ts/opsserver/handlers/domain.handler.d.ts +13 -0
- package/dist_ts/opsserver/handlers/domain.handler.js +137 -0
- package/dist_ts/opsserver/handlers/email-domain.handler.d.ts +16 -0
- package/dist_ts/opsserver/handlers/email-domain.handler.js +150 -0
- package/dist_ts/opsserver/handlers/email-ops.handler.d.ts +30 -0
- package/dist_ts/opsserver/handlers/email-ops.handler.js +227 -0
- package/dist_ts/opsserver/handlers/index.d.ts +21 -0
- package/dist_ts/opsserver/handlers/index.js +22 -0
- package/dist_ts/opsserver/handlers/logs.handler.d.ts +25 -0
- package/dist_ts/opsserver/handlers/logs.handler.js +264 -0
- package/dist_ts/opsserver/handlers/network-target.handler.d.ts +10 -0
- package/dist_ts/opsserver/handlers/network-target.handler.js +117 -0
- package/dist_ts/opsserver/handlers/radius.handler.d.ts +6 -0
- package/dist_ts/opsserver/handlers/radius.handler.js +295 -0
- package/dist_ts/opsserver/handlers/remoteingress.handler.d.ts +6 -0
- package/dist_ts/opsserver/handlers/remoteingress.handler.js +156 -0
- package/dist_ts/opsserver/handlers/route-management.handler.d.ts +14 -0
- package/dist_ts/opsserver/handlers/route-management.handler.js +98 -0
- package/dist_ts/opsserver/handlers/security.handler.d.ts +9 -0
- package/dist_ts/opsserver/handlers/security.handler.js +237 -0
- package/dist_ts/opsserver/handlers/source-profile.handler.d.ts +10 -0
- package/dist_ts/opsserver/handlers/source-profile.handler.js +119 -0
- package/dist_ts/opsserver/handlers/stats.handler.d.ts +11 -0
- package/dist_ts/opsserver/handlers/stats.handler.js +461 -0
- package/dist_ts/opsserver/handlers/target-profile.handler.d.ts +10 -0
- package/dist_ts/opsserver/handlers/target-profile.handler.js +117 -0
- package/dist_ts/opsserver/handlers/users.handler.d.ts +12 -0
- package/dist_ts/opsserver/handlers/users.handler.js +24 -0
- package/dist_ts/opsserver/handlers/vpn.handler.d.ts +6 -0
- package/dist_ts/opsserver/handlers/vpn.handler.js +262 -0
- package/dist_ts/opsserver/helpers/guards.d.ts +27 -0
- package/dist_ts/opsserver/helpers/guards.js +43 -0
- package/dist_ts/opsserver/index.d.ts +1 -0
- package/dist_ts/opsserver/index.js +2 -0
- package/dist_ts/paths.d.ts +25 -0
- package/dist_ts/paths.js +44 -0
- package/dist_ts/plugins.d.ts +81 -0
- package/dist_ts/plugins.js +115 -0
- package/dist_ts/radius/classes.accounting.manager.d.ts +223 -0
- package/dist_ts/radius/classes.accounting.manager.js +449 -0
- package/dist_ts/radius/classes.radius.server.d.ts +169 -0
- package/dist_ts/radius/classes.radius.server.js +384 -0
- package/dist_ts/radius/classes.vlan.manager.d.ts +124 -0
- package/dist_ts/radius/classes.vlan.manager.js +272 -0
- package/dist_ts/radius/index.d.ts +13 -0
- package/dist_ts/radius/index.js +14 -0
- package/dist_ts/remoteingress/classes.remoteingress-manager.d.ts +92 -0
- package/dist_ts/remoteingress/classes.remoteingress-manager.js +291 -0
- package/dist_ts/remoteingress/classes.tunnel-manager.d.ts +59 -0
- package/dist_ts/remoteingress/classes.tunnel-manager.js +165 -0
- package/dist_ts/remoteingress/index.d.ts +2 -0
- package/dist_ts/remoteingress/index.js +3 -0
- package/dist_ts/security/classes.contentscanner.d.ts +164 -0
- package/dist_ts/security/classes.contentscanner.js +642 -0
- package/dist_ts/security/classes.ipreputationchecker.d.ts +145 -0
- package/dist_ts/security/classes.ipreputationchecker.js +458 -0
- package/dist_ts/security/classes.securitylogger.d.ts +144 -0
- package/dist_ts/security/classes.securitylogger.js +235 -0
- package/dist_ts/security/index.d.ts +3 -0
- package/dist_ts/security/index.js +4 -0
- package/dist_ts/sms/classes.smsservice.d.ts +15 -0
- package/dist_ts/sms/classes.smsservice.js +72 -0
- package/dist_ts/sms/config/sms.config.d.ts +93 -0
- package/dist_ts/sms/config/sms.config.js +2 -0
- package/dist_ts/sms/config/sms.schema.d.ts +5 -0
- package/dist_ts/sms/config/sms.schema.js +121 -0
- package/dist_ts/sms/index.d.ts +1 -0
- package/dist_ts/sms/index.js +2 -0
- package/dist_ts/vpn/classes.vpn-manager.d.ts +159 -0
- package/dist_ts/vpn/classes.vpn-manager.js +459 -0
- package/dist_ts/vpn/index.d.ts +1 -0
- package/dist_ts/vpn/index.js +2 -0
- package/dist_ts_apiclient/classes.apitoken.d.ts +41 -0
- package/dist_ts_apiclient/classes.apitoken.js +115 -0
- package/dist_ts_apiclient/classes.certificate.d.ts +57 -0
- package/dist_ts_apiclient/classes.certificate.js +69 -0
- package/dist_ts_apiclient/classes.config.d.ts +7 -0
- package/dist_ts_apiclient/classes.config.js +11 -0
- package/dist_ts_apiclient/classes.dcrouterapiclient.d.ts +41 -0
- package/dist_ts_apiclient/classes.dcrouterapiclient.js +81 -0
- package/dist_ts_apiclient/classes.email.d.ts +30 -0
- package/dist_ts_apiclient/classes.email.js +52 -0
- package/dist_ts_apiclient/classes.logs.d.ts +21 -0
- package/dist_ts_apiclient/classes.logs.js +14 -0
- package/dist_ts_apiclient/classes.radius.d.ts +59 -0
- package/dist_ts_apiclient/classes.radius.js +95 -0
- package/dist_ts_apiclient/classes.remoteingress.d.ts +54 -0
- package/dist_ts_apiclient/classes.remoteingress.js +136 -0
- package/dist_ts_apiclient/classes.route.d.ts +39 -0
- package/dist_ts_apiclient/classes.route.js +125 -0
- package/dist_ts_apiclient/classes.stats.d.ts +47 -0
- package/dist_ts_apiclient/classes.stats.js +38 -0
- package/dist_ts_apiclient/index.d.ts +10 -0
- package/dist_ts_apiclient/index.js +14 -0
- package/dist_ts_apiclient/plugins.d.ts +3 -0
- package/dist_ts_apiclient/plugins.js +5 -0
- package/dist_ts_interfaces/data/acme-config.d.ts +25 -0
- package/dist_ts_interfaces/data/acme-config.js +2 -0
- package/dist_ts_interfaces/data/auth.d.ts +8 -0
- package/dist_ts_interfaces/data/auth.js +2 -0
- package/dist_ts_interfaces/data/dns-provider.d.ts +136 -0
- package/dist_ts_interfaces/data/dns-provider.js +41 -0
- package/dist_ts_interfaces/data/dns-record.d.ts +42 -0
- package/dist_ts_interfaces/data/dns-record.js +2 -0
- package/dist_ts_interfaces/data/domain.d.ts +35 -0
- package/dist_ts_interfaces/data/domain.js +2 -0
- package/dist_ts_interfaces/data/email-domain.d.ts +70 -0
- package/dist_ts_interfaces/data/email-domain.js +2 -0
- package/dist_ts_interfaces/data/index.d.ts +11 -0
- package/dist_ts_interfaces/data/index.js +12 -0
- package/dist_ts_interfaces/data/remoteingress.d.ts +60 -0
- package/dist_ts_interfaces/data/remoteingress.js +2 -0
- package/dist_ts_interfaces/data/route-management.d.ts +110 -0
- package/dist_ts_interfaces/data/route-management.js +2 -0
- package/dist_ts_interfaces/data/stats.d.ts +239 -0
- package/dist_ts_interfaces/data/stats.js +2 -0
- package/dist_ts_interfaces/data/target-profile.d.ts +28 -0
- package/dist_ts_interfaces/data/target-profile.js +2 -0
- package/dist_ts_interfaces/data/vpn.d.ts +61 -0
- package/dist_ts_interfaces/data/vpn.js +2 -0
- package/dist_ts_interfaces/index.d.ts +5 -0
- package/dist_ts_interfaces/index.js +8 -0
- package/dist_ts_interfaces/plugins.d.ts +2 -0
- package/dist_ts_interfaces/plugins.js +4 -0
- package/dist_ts_interfaces/requests/acme-config.d.ts +42 -0
- package/dist_ts_interfaces/requests/acme-config.js +2 -0
- package/dist_ts_interfaces/requests/admin.d.ts +31 -0
- package/dist_ts_interfaces/requests/admin.js +3 -0
- package/dist_ts_interfaces/requests/api-tokens.d.ts +79 -0
- package/dist_ts_interfaces/requests/api-tokens.js +2 -0
- package/dist_ts_interfaces/requests/certificate.d.ts +111 -0
- package/dist_ts_interfaces/requests/certificate.js +3 -0
- package/dist_ts_interfaces/requests/combined.stats.d.ts +28 -0
- package/dist_ts_interfaces/requests/combined.stats.js +2 -0
- package/dist_ts_interfaces/requests/config.d.ts +90 -0
- package/dist_ts_interfaces/requests/config.js +3 -0
- package/dist_ts_interfaces/requests/dns-providers.d.ts +117 -0
- package/dist_ts_interfaces/requests/dns-providers.js +2 -0
- package/dist_ts_interfaces/requests/dns-records.d.ts +89 -0
- package/dist_ts_interfaces/requests/dns-records.js +2 -0
- package/dist_ts_interfaces/requests/domains.d.ts +142 -0
- package/dist_ts_interfaces/requests/domains.js +2 -0
- package/dist_ts_interfaces/requests/email-domains.d.ts +142 -0
- package/dist_ts_interfaces/requests/email-domains.js +2 -0
- package/dist_ts_interfaces/requests/email-ops.d.ts +82 -0
- package/dist_ts_interfaces/requests/email-ops.js +3 -0
- package/dist_ts_interfaces/requests/index.d.ts +21 -0
- package/dist_ts_interfaces/requests/index.js +22 -0
- package/dist_ts_interfaces/requests/logs.d.ts +41 -0
- package/dist_ts_interfaces/requests/logs.js +4 -0
- package/dist_ts_interfaces/requests/network-targets.d.ts +102 -0
- package/dist_ts_interfaces/requests/network-targets.js +2 -0
- package/dist_ts_interfaces/requests/radius.d.ts +268 -0
- package/dist_ts_interfaces/requests/radius.js +3 -0
- package/dist_ts_interfaces/requests/remoteingress.d.ts +108 -0
- package/dist_ts_interfaces/requests/remoteingress.js +3 -0
- package/dist_ts_interfaces/requests/route-management.d.ts +85 -0
- package/dist_ts_interfaces/requests/route-management.js +2 -0
- package/dist_ts_interfaces/requests/source-profiles.d.ts +102 -0
- package/dist_ts_interfaces/requests/source-profiles.js +2 -0
- package/dist_ts_interfaces/requests/stats.d.ts +177 -0
- package/dist_ts_interfaces/requests/stats.js +4 -0
- package/dist_ts_interfaces/requests/target-profiles.d.ts +103 -0
- package/dist_ts_interfaces/requests/target-profiles.js +2 -0
- package/dist_ts_interfaces/requests/users.d.ts +19 -0
- package/dist_ts_interfaces/requests/users.js +3 -0
- package/dist_ts_interfaces/requests/vpn.d.ts +177 -0
- package/dist_ts_interfaces/requests/vpn.js +3 -0
- package/dist_ts_migrations/index.d.ts +28 -0
- package/dist_ts_migrations/index.js +82 -0
- package/dist_ts_oci_container/index.d.ts +8 -0
- package/dist_ts_oci_container/index.js +110 -0
- package/dist_ts_oci_container/plugins.d.ts +3 -0
- package/dist_ts_oci_container/plugins.js +4 -0
- package/dist_ts_web/00_commitinfo_data.d.ts +8 -0
- package/dist_ts_web/00_commitinfo_data.js +9 -0
- package/dist_ts_web/appstate.d.ts +478 -0
- package/dist_ts_web/appstate.js +1968 -0
- package/dist_ts_web/elements/access/index.d.ts +2 -0
- package/dist_ts_web/elements/access/index.js +3 -0
- package/dist_ts_web/elements/access/ops-view-apitokens.d.ts +13 -0
- package/dist_ts_web/elements/access/ops-view-apitokens.js +372 -0
- package/dist_ts_web/elements/access/ops-view-users.d.ts +11 -0
- package/dist_ts_web/elements/access/ops-view-users.js +190 -0
- package/dist_ts_web/elements/domains/dns-provider-form.d.ts +60 -0
- package/dist_ts_web/elements/domains/dns-provider-form.js +259 -0
- package/dist_ts_web/elements/domains/index.d.ts +5 -0
- package/dist_ts_web/elements/domains/index.js +6 -0
- package/dist_ts_web/elements/domains/ops-view-certificates.d.ts +25 -0
- package/dist_ts_web/elements/domains/ops-view-certificates.js +669 -0
- package/dist_ts_web/elements/domains/ops-view-dns.d.ts +17 -0
- package/dist_ts_web/elements/domains/ops-view-dns.js +305 -0
- package/dist_ts_web/elements/domains/ops-view-domains.d.ts +19 -0
- package/dist_ts_web/elements/domains/ops-view-domains.js +456 -0
- package/dist_ts_web/elements/domains/ops-view-providers.d.ts +21 -0
- package/dist_ts_web/elements/domains/ops-view-providers.js +330 -0
- package/dist_ts_web/elements/email/index.d.ts +3 -0
- package/dist_ts_web/elements/email/index.js +4 -0
- package/dist_ts_web/elements/email/ops-view-email-domains.d.ts +19 -0
- package/dist_ts_web/elements/email/ops-view-email-domains.js +410 -0
- package/dist_ts_web/elements/email/ops-view-email-security.d.ts +14 -0
- package/dist_ts_web/elements/email/ops-view-email-security.js +178 -0
- package/dist_ts_web/elements/email/ops-view-emails.d.ts +21 -0
- package/dist_ts_web/elements/email/ops-view-emails.js +165 -0
- package/dist_ts_web/elements/index.d.ts +9 -0
- package/dist_ts_web/elements/index.js +10 -0
- package/dist_ts_web/elements/network/index.d.ts +7 -0
- package/dist_ts_web/elements/network/index.js +8 -0
- package/dist_ts_web/elements/network/ops-view-network-activity.d.ts +60 -0
- package/dist_ts_web/elements/network/ops-view-network-activity.js +754 -0
- package/dist_ts_web/elements/network/ops-view-networktargets.d.ts +17 -0
- package/dist_ts_web/elements/network/ops-view-networktargets.js +255 -0
- package/dist_ts_web/elements/network/ops-view-remoteingress.d.ts +20 -0
- package/dist_ts_web/elements/network/ops-view-remoteingress.js +497 -0
- package/dist_ts_web/elements/network/ops-view-routes.d.ts +17 -0
- package/dist_ts_web/elements/network/ops-view-routes.js +700 -0
- package/dist_ts_web/elements/network/ops-view-sourceprofiles.d.ts +17 -0
- package/dist_ts_web/elements/network/ops-view-sourceprofiles.js +278 -0
- package/dist_ts_web/elements/network/ops-view-targetprofiles.d.ts +21 -0
- package/dist_ts_web/elements/network/ops-view-targetprofiles.js +420 -0
- package/dist_ts_web/elements/network/ops-view-vpn.d.ts +31 -0
- package/dist_ts_web/elements/network/ops-view-vpn.js +873 -0
- package/dist_ts_web/elements/ops-dashboard.d.ts +31 -0
- package/dist_ts_web/elements/ops-dashboard.js +405 -0
- package/dist_ts_web/elements/ops-view-logs.d.ts +13 -0
- package/dist_ts_web/elements/ops-view-logs.js +159 -0
- package/dist_ts_web/elements/overview/index.d.ts +2 -0
- package/dist_ts_web/elements/overview/index.js +3 -0
- package/dist_ts_web/elements/overview/ops-view-config.d.ts +19 -0
- package/dist_ts_web/elements/overview/ops-view-config.js +339 -0
- package/dist_ts_web/elements/overview/ops-view-overview.d.ts +24 -0
- package/dist_ts_web/elements/overview/ops-view-overview.js +545 -0
- package/dist_ts_web/elements/security/index.d.ts +3 -0
- package/dist_ts_web/elements/security/index.js +4 -0
- package/dist_ts_web/elements/security/ops-view-security-authentication.d.ts +13 -0
- package/dist_ts_web/elements/security/ops-view-security-authentication.js +157 -0
- package/dist_ts_web/elements/security/ops-view-security-blocked.d.ts +15 -0
- package/dist_ts_web/elements/security/ops-view-security-blocked.js +153 -0
- package/dist_ts_web/elements/security/ops-view-security-overview.d.ts +16 -0
- package/dist_ts_web/elements/security/ops-view-security-overview.js +205 -0
- package/dist_ts_web/elements/shared/css.d.ts +1 -0
- package/dist_ts_web/elements/shared/css.js +10 -0
- package/dist_ts_web/elements/shared/index.d.ts +1 -0
- package/dist_ts_web/elements/shared/index.js +2 -0
- package/dist_ts_web/index.d.ts +1 -0
- package/dist_ts_web/index.js +10 -0
- package/dist_ts_web/plugins.d.ts +7 -0
- package/dist_ts_web/plugins.js +13 -0
- package/dist_ts_web/router.d.ts +21 -0
- package/dist_ts_web/router.js +151 -0
- package/package.json +1 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/monitoring/classes.metricsmanager.ts +0 -25
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/elements/network/ops-view-routes.ts +9 -1
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reputation check result information
|
|
3
|
+
*/
|
|
4
|
+
export interface IReputationResult {
|
|
5
|
+
score: number;
|
|
6
|
+
isSpam: boolean;
|
|
7
|
+
isProxy: boolean;
|
|
8
|
+
isTor: boolean;
|
|
9
|
+
isVPN: boolean;
|
|
10
|
+
country?: string;
|
|
11
|
+
asn?: string;
|
|
12
|
+
org?: string;
|
|
13
|
+
blacklists?: string[];
|
|
14
|
+
timestamp: number;
|
|
15
|
+
error?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Reputation threshold scores
|
|
19
|
+
*/
|
|
20
|
+
export declare enum ReputationThreshold {
|
|
21
|
+
HIGH_RISK = 20,// Score below this is considered high risk
|
|
22
|
+
MEDIUM_RISK = 50,// Score below this is considered medium risk
|
|
23
|
+
LOW_RISK = 80
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* IP type classifications
|
|
27
|
+
*/
|
|
28
|
+
export declare enum IPType {
|
|
29
|
+
RESIDENTIAL = "residential",
|
|
30
|
+
DATACENTER = "datacenter",
|
|
31
|
+
PROXY = "proxy",
|
|
32
|
+
TOR = "tor",
|
|
33
|
+
VPN = "vpn",
|
|
34
|
+
UNKNOWN = "unknown"
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Options for the IP Reputation Checker
|
|
38
|
+
*/
|
|
39
|
+
export interface IIPReputationOptions {
|
|
40
|
+
maxCacheSize?: number;
|
|
41
|
+
cacheTTL?: number;
|
|
42
|
+
dnsblServers?: string[];
|
|
43
|
+
highRiskThreshold?: number;
|
|
44
|
+
mediumRiskThreshold?: number;
|
|
45
|
+
lowRiskThreshold?: number;
|
|
46
|
+
enableLocalCache?: boolean;
|
|
47
|
+
enableDNSBL?: boolean;
|
|
48
|
+
enableIPInfo?: boolean;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Class for checking IP reputation of inbound email senders
|
|
52
|
+
*/
|
|
53
|
+
export declare class IPReputationChecker {
|
|
54
|
+
private static instance;
|
|
55
|
+
private reputationCache;
|
|
56
|
+
private options;
|
|
57
|
+
private static readonly DEFAULT_DNSBL_SERVERS;
|
|
58
|
+
private static readonly DEFAULT_OPTIONS;
|
|
59
|
+
/**
|
|
60
|
+
* Constructor for IPReputationChecker
|
|
61
|
+
* @param options Configuration options
|
|
62
|
+
*/
|
|
63
|
+
constructor(options?: IIPReputationOptions);
|
|
64
|
+
/**
|
|
65
|
+
* Get the singleton instance of the checker
|
|
66
|
+
* @param options Configuration options
|
|
67
|
+
* @returns Singleton instance
|
|
68
|
+
*/
|
|
69
|
+
static getInstance(options?: IIPReputationOptions): IPReputationChecker;
|
|
70
|
+
/**
|
|
71
|
+
* Reset the singleton instance (for shutdown/testing)
|
|
72
|
+
*/
|
|
73
|
+
static resetInstance(): void;
|
|
74
|
+
/**
|
|
75
|
+
* Check an IP address's reputation
|
|
76
|
+
* @param ip IP address to check
|
|
77
|
+
* @returns Reputation check result
|
|
78
|
+
*/
|
|
79
|
+
checkReputation(ip: string): Promise<IReputationResult>;
|
|
80
|
+
/**
|
|
81
|
+
* Check an IP against DNS blacklists
|
|
82
|
+
* @param ip IP address to check
|
|
83
|
+
* @returns DNSBL check results
|
|
84
|
+
*/
|
|
85
|
+
private checkDNSBL;
|
|
86
|
+
/**
|
|
87
|
+
* Get information about an IP address
|
|
88
|
+
* @param ip IP address to check
|
|
89
|
+
* @returns IP information
|
|
90
|
+
*/
|
|
91
|
+
private getIPInfo;
|
|
92
|
+
/**
|
|
93
|
+
* Simplified method to determine country from IP
|
|
94
|
+
* In a real implementation, this would use a geolocation database or service
|
|
95
|
+
* @param ip IP address
|
|
96
|
+
* @returns Country code
|
|
97
|
+
*/
|
|
98
|
+
private determineCountry;
|
|
99
|
+
/**
|
|
100
|
+
* Simplified method to determine organization from IP
|
|
101
|
+
* In a real implementation, this would use an IP-to-org database or service
|
|
102
|
+
* @param ip IP address
|
|
103
|
+
* @returns Organization name
|
|
104
|
+
*/
|
|
105
|
+
private determineOrg;
|
|
106
|
+
/**
|
|
107
|
+
* Reverse an IP address for DNSBL lookups (e.g., 1.2.3.4 -> 4.3.2.1)
|
|
108
|
+
* @param ip IP address to reverse
|
|
109
|
+
* @returns Reversed IP for DNSBL queries
|
|
110
|
+
*/
|
|
111
|
+
private reverseIP;
|
|
112
|
+
/**
|
|
113
|
+
* Create an error result for when reputation check fails
|
|
114
|
+
* @param ip IP address
|
|
115
|
+
* @param errorMessage Error message
|
|
116
|
+
* @returns Error result
|
|
117
|
+
*/
|
|
118
|
+
private createErrorResult;
|
|
119
|
+
/**
|
|
120
|
+
* Validate IP address format
|
|
121
|
+
* @param ip IP address to validate
|
|
122
|
+
* @returns Whether the IP is valid
|
|
123
|
+
*/
|
|
124
|
+
private isValidIPAddress;
|
|
125
|
+
/**
|
|
126
|
+
* Log reputation check to security logger
|
|
127
|
+
* @param ip IP address
|
|
128
|
+
* @param result Reputation result
|
|
129
|
+
*/
|
|
130
|
+
private logReputationCheck;
|
|
131
|
+
/**
|
|
132
|
+
* Persist a single IP reputation result to the database via CachedIPReputation
|
|
133
|
+
*/
|
|
134
|
+
private persistReputationToDb;
|
|
135
|
+
/**
|
|
136
|
+
* Load persisted reputations from CachedIPReputation documents into the in-memory LRU cache
|
|
137
|
+
*/
|
|
138
|
+
private loadCacheFromDb;
|
|
139
|
+
/**
|
|
140
|
+
* Get the risk level for a reputation score
|
|
141
|
+
* @param score Reputation score (0-100)
|
|
142
|
+
* @returns Risk level description
|
|
143
|
+
*/
|
|
144
|
+
static getRiskLevel(score: number): 'high' | 'medium' | 'low' | 'trusted';
|
|
145
|
+
}
|
|
@@ -0,0 +1,458 @@
|
|
|
1
|
+
import * as plugins from '../plugins.js';
|
|
2
|
+
import { logger } from '../logger.js';
|
|
3
|
+
import { SecurityLogger, SecurityLogLevel, SecurityEventType } from './classes.securitylogger.js';
|
|
4
|
+
import { LRUCache } from 'lru-cache';
|
|
5
|
+
import { CachedIPReputation } from '../db/documents/classes.cached.ip.reputation.js';
|
|
6
|
+
/**
|
|
7
|
+
* Reputation threshold scores
|
|
8
|
+
*/
|
|
9
|
+
export var ReputationThreshold;
|
|
10
|
+
(function (ReputationThreshold) {
|
|
11
|
+
ReputationThreshold[ReputationThreshold["HIGH_RISK"] = 20] = "HIGH_RISK";
|
|
12
|
+
ReputationThreshold[ReputationThreshold["MEDIUM_RISK"] = 50] = "MEDIUM_RISK";
|
|
13
|
+
ReputationThreshold[ReputationThreshold["LOW_RISK"] = 80] = "LOW_RISK"; // Score below this is considered low risk (but not trusted)
|
|
14
|
+
})(ReputationThreshold || (ReputationThreshold = {}));
|
|
15
|
+
/**
|
|
16
|
+
* IP type classifications
|
|
17
|
+
*/
|
|
18
|
+
export var IPType;
|
|
19
|
+
(function (IPType) {
|
|
20
|
+
IPType["RESIDENTIAL"] = "residential";
|
|
21
|
+
IPType["DATACENTER"] = "datacenter";
|
|
22
|
+
IPType["PROXY"] = "proxy";
|
|
23
|
+
IPType["TOR"] = "tor";
|
|
24
|
+
IPType["VPN"] = "vpn";
|
|
25
|
+
IPType["UNKNOWN"] = "unknown";
|
|
26
|
+
})(IPType || (IPType = {}));
|
|
27
|
+
/**
|
|
28
|
+
* Class for checking IP reputation of inbound email senders
|
|
29
|
+
*/
|
|
30
|
+
export class IPReputationChecker {
|
|
31
|
+
static instance;
|
|
32
|
+
reputationCache;
|
|
33
|
+
options;
|
|
34
|
+
// Default DNSBL servers
|
|
35
|
+
static DEFAULT_DNSBL_SERVERS = [
|
|
36
|
+
'zen.spamhaus.org', // Spamhaus
|
|
37
|
+
'bl.spamcop.net', // SpamCop
|
|
38
|
+
'b.barracudacentral.org', // Barracuda
|
|
39
|
+
'spam.dnsbl.sorbs.net', // SORBS
|
|
40
|
+
'dnsbl.sorbs.net', // SORBS (expanded)
|
|
41
|
+
'cbl.abuseat.org', // Composite Blocking List
|
|
42
|
+
'xbl.spamhaus.org', // Spamhaus XBL
|
|
43
|
+
'pbl.spamhaus.org', // Spamhaus PBL
|
|
44
|
+
'dnsbl-1.uceprotect.net', // UCEPROTECT
|
|
45
|
+
'psbl.surriel.com' // PSBL
|
|
46
|
+
];
|
|
47
|
+
// Default options
|
|
48
|
+
static DEFAULT_OPTIONS = {
|
|
49
|
+
maxCacheSize: 10000,
|
|
50
|
+
cacheTTL: 24 * 60 * 60 * 1000, // 24 hours
|
|
51
|
+
dnsblServers: IPReputationChecker.DEFAULT_DNSBL_SERVERS,
|
|
52
|
+
highRiskThreshold: ReputationThreshold.HIGH_RISK,
|
|
53
|
+
mediumRiskThreshold: ReputationThreshold.MEDIUM_RISK,
|
|
54
|
+
lowRiskThreshold: ReputationThreshold.LOW_RISK,
|
|
55
|
+
enableLocalCache: true,
|
|
56
|
+
enableDNSBL: true,
|
|
57
|
+
enableIPInfo: true
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Constructor for IPReputationChecker
|
|
61
|
+
* @param options Configuration options
|
|
62
|
+
*/
|
|
63
|
+
constructor(options = {}) {
|
|
64
|
+
// Merge with default options
|
|
65
|
+
this.options = {
|
|
66
|
+
...IPReputationChecker.DEFAULT_OPTIONS,
|
|
67
|
+
...options
|
|
68
|
+
};
|
|
69
|
+
// Initialize reputation cache
|
|
70
|
+
this.reputationCache = new LRUCache({
|
|
71
|
+
max: this.options.maxCacheSize,
|
|
72
|
+
ttl: this.options.cacheTTL, // Cache TTL
|
|
73
|
+
});
|
|
74
|
+
// Load persisted reputations into in-memory cache
|
|
75
|
+
if (this.options.enableLocalCache) {
|
|
76
|
+
this.loadCacheFromDb().catch((error) => {
|
|
77
|
+
logger.log('error', `Failed to load IP reputation cache during initialization: ${error.message}`);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Get the singleton instance of the checker
|
|
83
|
+
* @param options Configuration options
|
|
84
|
+
* @returns Singleton instance
|
|
85
|
+
*/
|
|
86
|
+
static getInstance(options = {}) {
|
|
87
|
+
if (!IPReputationChecker.instance) {
|
|
88
|
+
IPReputationChecker.instance = new IPReputationChecker(options);
|
|
89
|
+
}
|
|
90
|
+
return IPReputationChecker.instance;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Reset the singleton instance (for shutdown/testing)
|
|
94
|
+
*/
|
|
95
|
+
static resetInstance() {
|
|
96
|
+
IPReputationChecker.instance = undefined;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Check an IP address's reputation
|
|
100
|
+
* @param ip IP address to check
|
|
101
|
+
* @returns Reputation check result
|
|
102
|
+
*/
|
|
103
|
+
async checkReputation(ip) {
|
|
104
|
+
try {
|
|
105
|
+
// Validate IP address format
|
|
106
|
+
if (!this.isValidIPAddress(ip)) {
|
|
107
|
+
logger.log('warn', `Invalid IP address format: ${ip}`);
|
|
108
|
+
return this.createErrorResult(ip, 'Invalid IP address format');
|
|
109
|
+
}
|
|
110
|
+
// Check in-memory LRU cache first (fast path)
|
|
111
|
+
const cachedResult = this.reputationCache.get(ip);
|
|
112
|
+
if (cachedResult) {
|
|
113
|
+
logger.log('info', `Using cached reputation data for IP ${ip}`, {
|
|
114
|
+
score: cachedResult.score,
|
|
115
|
+
isSpam: cachedResult.isSpam
|
|
116
|
+
});
|
|
117
|
+
return cachedResult;
|
|
118
|
+
}
|
|
119
|
+
// Initialize empty result
|
|
120
|
+
const result = {
|
|
121
|
+
score: 100, // Start with perfect score
|
|
122
|
+
isSpam: false,
|
|
123
|
+
isProxy: false,
|
|
124
|
+
isTor: false,
|
|
125
|
+
isVPN: false,
|
|
126
|
+
timestamp: Date.now()
|
|
127
|
+
};
|
|
128
|
+
// Check IP against DNS blacklists if enabled
|
|
129
|
+
if (this.options.enableDNSBL) {
|
|
130
|
+
const dnsblResult = await this.checkDNSBL(ip);
|
|
131
|
+
// Update result with DNSBL information
|
|
132
|
+
result.score -= dnsblResult.listCount * 10; // Subtract 10 points per blacklist
|
|
133
|
+
result.isSpam = dnsblResult.listCount > 0;
|
|
134
|
+
result.blacklists = dnsblResult.lists;
|
|
135
|
+
}
|
|
136
|
+
// Get additional IP information if enabled
|
|
137
|
+
if (this.options.enableIPInfo) {
|
|
138
|
+
const ipInfo = await this.getIPInfo(ip);
|
|
139
|
+
// Update result with IP info
|
|
140
|
+
result.country = ipInfo.country;
|
|
141
|
+
result.asn = ipInfo.asn;
|
|
142
|
+
result.org = ipInfo.org;
|
|
143
|
+
// Adjust score based on IP type
|
|
144
|
+
if (ipInfo.type === IPType.PROXY || ipInfo.type === IPType.TOR || ipInfo.type === IPType.VPN) {
|
|
145
|
+
result.score -= 30; // Subtract 30 points for proxies, Tor, VPNs
|
|
146
|
+
// Set proxy flags
|
|
147
|
+
result.isProxy = ipInfo.type === IPType.PROXY;
|
|
148
|
+
result.isTor = ipInfo.type === IPType.TOR;
|
|
149
|
+
result.isVPN = ipInfo.type === IPType.VPN;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// Ensure score is between 0 and 100
|
|
153
|
+
result.score = Math.max(0, Math.min(100, result.score));
|
|
154
|
+
// Update in-memory LRU cache
|
|
155
|
+
this.reputationCache.set(ip, result);
|
|
156
|
+
// Persist to database if enabled (fire and forget)
|
|
157
|
+
if (this.options.enableLocalCache) {
|
|
158
|
+
this.persistReputationToDb(ip, result).catch((error) => {
|
|
159
|
+
logger.log('error', `Failed to persist IP reputation for ${ip}: ${error.message}`);
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
// Log the reputation check
|
|
163
|
+
this.logReputationCheck(ip, result);
|
|
164
|
+
return result;
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
logger.log('error', `Error checking IP reputation for ${ip}: ${error.message}`, {
|
|
168
|
+
ip,
|
|
169
|
+
stack: error.stack
|
|
170
|
+
});
|
|
171
|
+
return this.createErrorResult(ip, error.message);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Check an IP against DNS blacklists
|
|
176
|
+
* @param ip IP address to check
|
|
177
|
+
* @returns DNSBL check results
|
|
178
|
+
*/
|
|
179
|
+
async checkDNSBL(ip) {
|
|
180
|
+
try {
|
|
181
|
+
// Reverse the IP for DNSBL queries
|
|
182
|
+
const reversedIP = this.reverseIP(ip);
|
|
183
|
+
const results = await Promise.allSettled(this.options.dnsblServers.map(async (server) => {
|
|
184
|
+
try {
|
|
185
|
+
const lookupDomain = `${reversedIP}.${server}`;
|
|
186
|
+
await plugins.dns.promises.resolve(lookupDomain);
|
|
187
|
+
return server; // IP is listed in this DNSBL
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
if (error.code === 'ENOTFOUND') {
|
|
191
|
+
return null; // IP is not listed in this DNSBL
|
|
192
|
+
}
|
|
193
|
+
throw error; // Other error
|
|
194
|
+
}
|
|
195
|
+
}));
|
|
196
|
+
// Extract successful lookups (listed in DNSBL)
|
|
197
|
+
const lists = results
|
|
198
|
+
.filter((result) => result.status === 'fulfilled' && result.value !== null)
|
|
199
|
+
.map(result => result.value);
|
|
200
|
+
return {
|
|
201
|
+
listCount: lists.length,
|
|
202
|
+
lists
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
catch (error) {
|
|
206
|
+
logger.log('error', `Error checking DNSBL for ${ip}: ${error.message}`);
|
|
207
|
+
return {
|
|
208
|
+
listCount: 0,
|
|
209
|
+
lists: []
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Get information about an IP address
|
|
215
|
+
* @param ip IP address to check
|
|
216
|
+
* @returns IP information
|
|
217
|
+
*/
|
|
218
|
+
async getIPInfo(ip) {
|
|
219
|
+
try {
|
|
220
|
+
// In a real implementation, this would use an IP data service API
|
|
221
|
+
// For this implementation, we'll use a simplified approach
|
|
222
|
+
// Check if it's a known Tor exit node (simplified)
|
|
223
|
+
const isTor = ip.startsWith('171.25.') || ip.startsWith('185.220.') || ip.startsWith('95.216.');
|
|
224
|
+
// Check if it's a known VPN (simplified)
|
|
225
|
+
const isVPN = ip.startsWith('185.156.') || ip.startsWith('37.120.');
|
|
226
|
+
// Check if it's a known proxy (simplified)
|
|
227
|
+
const isProxy = ip.startsWith('34.92.') || ip.startsWith('34.206.');
|
|
228
|
+
// Determine IP type
|
|
229
|
+
let type = IPType.UNKNOWN;
|
|
230
|
+
if (isTor) {
|
|
231
|
+
type = IPType.TOR;
|
|
232
|
+
}
|
|
233
|
+
else if (isVPN) {
|
|
234
|
+
type = IPType.VPN;
|
|
235
|
+
}
|
|
236
|
+
else if (isProxy) {
|
|
237
|
+
type = IPType.PROXY;
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
// Simple datacenters detection (major cloud providers)
|
|
241
|
+
if (ip.startsWith('13.') || // AWS
|
|
242
|
+
ip.startsWith('35.') || // Google Cloud
|
|
243
|
+
ip.startsWith('52.') || // AWS
|
|
244
|
+
ip.startsWith('34.') || // Google Cloud
|
|
245
|
+
ip.startsWith('104.') // Various providers
|
|
246
|
+
) {
|
|
247
|
+
type = IPType.DATACENTER;
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
type = IPType.RESIDENTIAL;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
// Return the information
|
|
254
|
+
return {
|
|
255
|
+
country: this.determineCountry(ip), // Simplified, would use geolocation service
|
|
256
|
+
asn: 'AS12345', // Simplified, would look up real ASN
|
|
257
|
+
org: this.determineOrg(ip), // Simplified, would use real org data
|
|
258
|
+
type
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
logger.log('error', `Error getting IP info for ${ip}: ${error.message}`);
|
|
263
|
+
return {
|
|
264
|
+
type: IPType.UNKNOWN
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Simplified method to determine country from IP
|
|
270
|
+
* In a real implementation, this would use a geolocation database or service
|
|
271
|
+
* @param ip IP address
|
|
272
|
+
* @returns Country code
|
|
273
|
+
*/
|
|
274
|
+
determineCountry(ip) {
|
|
275
|
+
// Simplified mapping for demo purposes
|
|
276
|
+
if (ip.startsWith('13.') || ip.startsWith('52.'))
|
|
277
|
+
return 'US';
|
|
278
|
+
if (ip.startsWith('35.') || ip.startsWith('34.'))
|
|
279
|
+
return 'US';
|
|
280
|
+
if (ip.startsWith('185.'))
|
|
281
|
+
return 'NL';
|
|
282
|
+
if (ip.startsWith('171.'))
|
|
283
|
+
return 'DE';
|
|
284
|
+
return 'XX'; // Unknown
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Simplified method to determine organization from IP
|
|
288
|
+
* In a real implementation, this would use an IP-to-org database or service
|
|
289
|
+
* @param ip IP address
|
|
290
|
+
* @returns Organization name
|
|
291
|
+
*/
|
|
292
|
+
determineOrg(ip) {
|
|
293
|
+
// Simplified mapping for demo purposes
|
|
294
|
+
if (ip.startsWith('13.') || ip.startsWith('52.'))
|
|
295
|
+
return 'Amazon AWS';
|
|
296
|
+
if (ip.startsWith('35.') || ip.startsWith('34.'))
|
|
297
|
+
return 'Google Cloud';
|
|
298
|
+
if (ip.startsWith('185.156.'))
|
|
299
|
+
return 'NordVPN';
|
|
300
|
+
if (ip.startsWith('37.120.'))
|
|
301
|
+
return 'ExpressVPN';
|
|
302
|
+
if (ip.startsWith('185.220.'))
|
|
303
|
+
return 'Tor Exit Node';
|
|
304
|
+
return 'Unknown';
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Reverse an IP address for DNSBL lookups (e.g., 1.2.3.4 -> 4.3.2.1)
|
|
308
|
+
* @param ip IP address to reverse
|
|
309
|
+
* @returns Reversed IP for DNSBL queries
|
|
310
|
+
*/
|
|
311
|
+
reverseIP(ip) {
|
|
312
|
+
return ip.split('.').reverse().join('.');
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Create an error result for when reputation check fails
|
|
316
|
+
* @param ip IP address
|
|
317
|
+
* @param errorMessage Error message
|
|
318
|
+
* @returns Error result
|
|
319
|
+
*/
|
|
320
|
+
createErrorResult(ip, errorMessage) {
|
|
321
|
+
return {
|
|
322
|
+
score: 50, // Neutral score for errors
|
|
323
|
+
isSpam: false,
|
|
324
|
+
isProxy: false,
|
|
325
|
+
isTor: false,
|
|
326
|
+
isVPN: false,
|
|
327
|
+
timestamp: Date.now(),
|
|
328
|
+
error: errorMessage
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Validate IP address format
|
|
333
|
+
* @param ip IP address to validate
|
|
334
|
+
* @returns Whether the IP is valid
|
|
335
|
+
*/
|
|
336
|
+
isValidIPAddress(ip) {
|
|
337
|
+
// IPv4 regex pattern
|
|
338
|
+
const ipv4Pattern = /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
|
|
339
|
+
return ipv4Pattern.test(ip);
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Log reputation check to security logger
|
|
343
|
+
* @param ip IP address
|
|
344
|
+
* @param result Reputation result
|
|
345
|
+
*/
|
|
346
|
+
logReputationCheck(ip, result) {
|
|
347
|
+
// Determine log level based on reputation score
|
|
348
|
+
let logLevel = SecurityLogLevel.INFO;
|
|
349
|
+
if (result.score < this.options.highRiskThreshold) {
|
|
350
|
+
logLevel = SecurityLogLevel.WARN;
|
|
351
|
+
}
|
|
352
|
+
else if (result.score < this.options.mediumRiskThreshold) {
|
|
353
|
+
logLevel = SecurityLogLevel.INFO;
|
|
354
|
+
}
|
|
355
|
+
// Log the check
|
|
356
|
+
SecurityLogger.getInstance().logEvent({
|
|
357
|
+
level: logLevel,
|
|
358
|
+
type: SecurityEventType.IP_REPUTATION,
|
|
359
|
+
message: `IP reputation check ${result.isSpam ? 'flagged spam' : 'completed'} for ${ip}`,
|
|
360
|
+
ipAddress: ip,
|
|
361
|
+
details: {
|
|
362
|
+
score: result.score,
|
|
363
|
+
isSpam: result.isSpam,
|
|
364
|
+
isProxy: result.isProxy,
|
|
365
|
+
isTor: result.isTor,
|
|
366
|
+
isVPN: result.isVPN,
|
|
367
|
+
country: result.country,
|
|
368
|
+
blacklists: result.blacklists
|
|
369
|
+
},
|
|
370
|
+
success: !result.isSpam
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Persist a single IP reputation result to the database via CachedIPReputation
|
|
375
|
+
*/
|
|
376
|
+
async persistReputationToDb(ip, result) {
|
|
377
|
+
try {
|
|
378
|
+
const data = {
|
|
379
|
+
score: result.score,
|
|
380
|
+
isSpam: result.isSpam,
|
|
381
|
+
isProxy: result.isProxy,
|
|
382
|
+
isTor: result.isTor,
|
|
383
|
+
isVPN: result.isVPN,
|
|
384
|
+
country: result.country,
|
|
385
|
+
asn: result.asn,
|
|
386
|
+
org: result.org,
|
|
387
|
+
blacklists: result.blacklists,
|
|
388
|
+
};
|
|
389
|
+
const existing = await CachedIPReputation.findByIP(ip);
|
|
390
|
+
if (existing) {
|
|
391
|
+
existing.updateReputation(data);
|
|
392
|
+
await existing.save();
|
|
393
|
+
}
|
|
394
|
+
else {
|
|
395
|
+
const doc = CachedIPReputation.fromReputationData(ip, data);
|
|
396
|
+
await doc.save();
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
catch (error) {
|
|
400
|
+
logger.log('error', `Failed to persist IP reputation for ${ip}: ${error.message}`);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Load persisted reputations from CachedIPReputation documents into the in-memory LRU cache
|
|
405
|
+
*/
|
|
406
|
+
async loadCacheFromDb() {
|
|
407
|
+
try {
|
|
408
|
+
const docs = await CachedIPReputation.getInstances({});
|
|
409
|
+
let loadedCount = 0;
|
|
410
|
+
for (const doc of docs) {
|
|
411
|
+
// Skip expired documents
|
|
412
|
+
if (doc.isExpired()) {
|
|
413
|
+
continue;
|
|
414
|
+
}
|
|
415
|
+
const result = {
|
|
416
|
+
score: doc.score,
|
|
417
|
+
isSpam: doc.isSpam,
|
|
418
|
+
isProxy: doc.isProxy,
|
|
419
|
+
isTor: doc.isTor,
|
|
420
|
+
isVPN: doc.isVPN,
|
|
421
|
+
country: doc.country || undefined,
|
|
422
|
+
asn: doc.asn || undefined,
|
|
423
|
+
org: doc.org || undefined,
|
|
424
|
+
blacklists: doc.blacklists || [],
|
|
425
|
+
timestamp: doc.lastAccessedAt?.getTime() ?? doc.createdAt?.getTime() ?? Date.now(),
|
|
426
|
+
};
|
|
427
|
+
this.reputationCache.set(doc.ipAddress, result);
|
|
428
|
+
loadedCount++;
|
|
429
|
+
}
|
|
430
|
+
if (loadedCount > 0) {
|
|
431
|
+
logger.log('info', `Loaded ${loadedCount} IP reputation cache entries from database`);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
catch (error) {
|
|
435
|
+
logger.log('error', `Failed to load IP reputation cache from database: ${error.message}`);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Get the risk level for a reputation score
|
|
440
|
+
* @param score Reputation score (0-100)
|
|
441
|
+
* @returns Risk level description
|
|
442
|
+
*/
|
|
443
|
+
static getRiskLevel(score) {
|
|
444
|
+
if (score < ReputationThreshold.HIGH_RISK) {
|
|
445
|
+
return 'high';
|
|
446
|
+
}
|
|
447
|
+
else if (score < ReputationThreshold.MEDIUM_RISK) {
|
|
448
|
+
return 'medium';
|
|
449
|
+
}
|
|
450
|
+
else if (score < ReputationThreshold.LOW_RISK) {
|
|
451
|
+
return 'low';
|
|
452
|
+
}
|
|
453
|
+
else {
|
|
454
|
+
return 'trusted';
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5pcHJlcHV0YXRpb25jaGVja2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvc2VjdXJpdHkvY2xhc3Nlcy5pcHJlcHV0YXRpb25jaGVja2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDdEMsT0FBTyxFQUFFLGNBQWMsRUFBRSxnQkFBZ0IsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ2xHLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDckMsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0saURBQWlELENBQUM7QUFtQnJGOztHQUVHO0FBQ0gsTUFBTSxDQUFOLElBQVksbUJBSVg7QUFKRCxXQUFZLG1CQUFtQjtJQUM3Qix3RUFBYyxDQUFBO0lBQ2QsNEVBQWdCLENBQUE7SUFDaEIsc0VBQWEsQ0FBQSxDQUFRLDREQUE0RDtBQUNuRixDQUFDLEVBSlcsbUJBQW1CLEtBQW5CLG1CQUFtQixRQUk5QjtBQUVEOztHQUVHO0FBQ0gsTUFBTSxDQUFOLElBQVksTUFPWDtBQVBELFdBQVksTUFBTTtJQUNoQixxQ0FBMkIsQ0FBQTtJQUMzQixtQ0FBeUIsQ0FBQTtJQUN6Qix5QkFBZSxDQUFBO0lBQ2YscUJBQVcsQ0FBQTtJQUNYLHFCQUFXLENBQUE7SUFDWCw2QkFBbUIsQ0FBQTtBQUNyQixDQUFDLEVBUFcsTUFBTSxLQUFOLE1BQU0sUUFPakI7QUFpQkQ7O0dBRUc7QUFDSCxNQUFNLE9BQU8sbUJBQW1CO0lBQ3RCLE1BQU0sQ0FBQyxRQUFRLENBQWtDO0lBQ2pELGVBQWUsQ0FBc0M7SUFDckQsT0FBTyxDQUFpQztJQUVoRCx3QkFBd0I7SUFDaEIsTUFBTSxDQUFVLHFCQUFxQixHQUFHO1FBQzlDLGtCQUFrQixFQUFVLFdBQVc7UUFD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
|