@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.
- package/dist_serve/bundle.js +729 -721
- package/package.json +2 -2
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/monitoring/classes.metricsmanager.ts +43 -34
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/elements/network/ops-view-network-activity.ts +2 -1
- package/ts_web/elements/network/ops-view-routes.ts +24 -8
- package/dist_ts/00_commitinfo_data.d.ts +0 -8
- package/dist_ts/00_commitinfo_data.js +0 -9
- package/dist_ts/acme/index.d.ts +0 -1
- package/dist_ts/acme/index.js +0 -2
- package/dist_ts/acme/manager.acme-config.d.ts +0 -48
- package/dist_ts/acme/manager.acme-config.js +0 -156
- package/dist_ts/classes.cert-provision-scheduler.d.ts +0 -52
- package/dist_ts/classes.cert-provision-scheduler.js +0 -138
- package/dist_ts/classes.dcrouter.d.ts +0 -401
- package/dist_ts/classes.dcrouter.js +0 -1852
- package/dist_ts/classes.storage-cert-manager.d.ts +0 -15
- package/dist_ts/classes.storage-cert-manager.js +0 -53
- package/dist_ts/config/classes.api-token-manager.d.ts +0 -44
- package/dist_ts/config/classes.api-token-manager.js +0 -180
- package/dist_ts/config/classes.db-seeder.d.ts +0 -25
- package/dist_ts/config/classes.db-seeder.js +0 -69
- package/dist_ts/config/classes.reference-resolver.d.ts +0 -80
- package/dist_ts/config/classes.reference-resolver.js +0 -483
- package/dist_ts/config/classes.route-config-manager.d.ts +0 -54
- package/dist_ts/config/classes.route-config-manager.js +0 -370
- package/dist_ts/config/classes.target-profile-manager.d.ts +0 -82
- package/dist_ts/config/classes.target-profile-manager.js +0 -349
- package/dist_ts/config/index.d.ts +0 -6
- package/dist_ts/config/index.js +0 -8
- package/dist_ts/config/validator.d.ts +0 -104
- package/dist_ts/config/validator.js +0 -152
- package/dist_ts/db/classes.cache.cleaner.d.ts +0 -47
- package/dist_ts/db/classes.cache.cleaner.js +0 -130
- package/dist_ts/db/classes.cached.document.d.ts +0 -76
- package/dist_ts/db/classes.cached.document.js +0 -100
- package/dist_ts/db/classes.dcrouter-db.d.ts +0 -70
- package/dist_ts/db/classes.dcrouter-db.js +0 -146
- package/dist_ts/db/documents/classes.accounting-session.doc.d.ts +0 -32
- package/dist_ts/db/documents/classes.accounting-session.doc.js +0 -214
- package/dist_ts/db/documents/classes.acme-cert.doc.d.ts +0 -13
- package/dist_ts/db/documents/classes.acme-cert.doc.js +0 -109
- package/dist_ts/db/documents/classes.acme-config.doc.d.ts +0 -22
- package/dist_ts/db/documents/classes.acme-config.doc.js +0 -121
- package/dist_ts/db/documents/classes.api-token.doc.d.ts +0 -18
- package/dist_ts/db/documents/classes.api-token.doc.js +0 -127
- package/dist_ts/db/documents/classes.cached.email.d.ts +0 -125
- package/dist_ts/db/documents/classes.cached.email.js +0 -337
- package/dist_ts/db/documents/classes.cached.ip.reputation.d.ts +0 -119
- package/dist_ts/db/documents/classes.cached.ip.reputation.js +0 -323
- package/dist_ts/db/documents/classes.cert-backoff.doc.d.ts +0 -11
- package/dist_ts/db/documents/classes.cert-backoff.doc.js +0 -97
- package/dist_ts/db/documents/classes.dns-provider.doc.d.ts +0 -22
- package/dist_ts/db/documents/classes.dns-provider.doc.js +0 -134
- package/dist_ts/db/documents/classes.dns-record.doc.d.ts +0 -21
- package/dist_ts/db/documents/classes.dns-record.doc.js +0 -143
- package/dist_ts/db/documents/classes.domain.doc.d.ts +0 -22
- package/dist_ts/db/documents/classes.domain.doc.js +0 -146
- package/dist_ts/db/documents/classes.email-domain.doc.d.ts +0 -17
- package/dist_ts/db/documents/classes.email-domain.doc.js +0 -124
- package/dist_ts/db/documents/classes.network-target.doc.d.ts +0 -15
- package/dist_ts/db/documents/classes.network-target.doc.js +0 -118
- package/dist_ts/db/documents/classes.proxy-cert.doc.d.ts +0 -12
- package/dist_ts/db/documents/classes.proxy-cert.doc.js +0 -103
- package/dist_ts/db/documents/classes.remote-ingress-edge.doc.d.ts +0 -17
- package/dist_ts/db/documents/classes.remote-ingress-edge.doc.js +0 -130
- package/dist_ts/db/documents/classes.route.doc.d.ts +0 -18
- package/dist_ts/db/documents/classes.route.doc.js +0 -121
- package/dist_ts/db/documents/classes.source-profile.doc.d.ts +0 -15
- package/dist_ts/db/documents/classes.source-profile.doc.js +0 -115
- package/dist_ts/db/documents/classes.target-profile.doc.d.ts +0 -16
- package/dist_ts/db/documents/classes.target-profile.doc.js +0 -121
- package/dist_ts/db/documents/classes.vlan-mappings.doc.d.ts +0 -15
- package/dist_ts/db/documents/classes.vlan-mappings.doc.js +0 -77
- package/dist_ts/db/documents/classes.vpn-client.doc.d.ts +0 -23
- package/dist_ts/db/documents/classes.vpn-client.doc.js +0 -172
- package/dist_ts/db/documents/classes.vpn-server-keys.doc.d.ts +0 -10
- package/dist_ts/db/documents/classes.vpn-server-keys.doc.js +0 -94
- package/dist_ts/db/documents/index.d.ts +0 -20
- package/dist_ts/db/documents/index.js +0 -30
- package/dist_ts/db/index.d.ts +0 -4
- package/dist_ts/db/index.js +0 -9
- package/dist_ts/dns/index.d.ts +0 -2
- package/dist_ts/dns/index.js +0 -3
- package/dist_ts/dns/manager.dns.d.ts +0 -267
- package/dist_ts/dns/manager.dns.js +0 -906
- package/dist_ts/dns/providers/cloudflare.provider.d.ts +0 -21
- package/dist_ts/dns/providers/cloudflare.provider.js +0 -106
- package/dist_ts/dns/providers/factory.d.ts +0 -23
- package/dist_ts/dns/providers/factory.js +0 -47
- package/dist_ts/dns/providers/index.d.ts +0 -3
- package/dist_ts/dns/providers/index.js +0 -4
- package/dist_ts/dns/providers/interfaces.d.ts +0 -54
- package/dist_ts/dns/providers/interfaces.js +0 -2
- package/dist_ts/email/classes.email-domain.manager.d.ts +0 -46
- package/dist_ts/email/classes.email-domain.manager.js +0 -276
- package/dist_ts/email/index.d.ts +0 -1
- package/dist_ts/email/index.js +0 -2
- package/dist_ts/errors/base.errors.d.ts +0 -224
- package/dist_ts/errors/base.errors.js +0 -320
- package/dist_ts/errors/error-handler.d.ts +0 -98
- package/dist_ts/errors/error-handler.js +0 -282
- package/dist_ts/errors/error.codes.d.ts +0 -115
- package/dist_ts/errors/error.codes.js +0 -136
- package/dist_ts/errors/index.d.ts +0 -54
- package/dist_ts/errors/index.js +0 -136
- package/dist_ts/errors/reputation.errors.d.ts +0 -183
- package/dist_ts/errors/reputation.errors.js +0 -292
- package/dist_ts/http3/http3-route-augmentation.d.ts +0 -50
- package/dist_ts/http3/http3-route-augmentation.js +0 -98
- package/dist_ts/http3/index.d.ts +0 -1
- package/dist_ts/http3/index.js +0 -2
- package/dist_ts/index.d.ts +0 -8
- package/dist_ts/index.js +0 -29
- package/dist_ts/logger.d.ts +0 -21
- package/dist_ts/logger.js +0 -81
- package/dist_ts/monitoring/classes.metricscache.d.ts +0 -32
- package/dist_ts/monitoring/classes.metricscache.js +0 -63
- package/dist_ts/monitoring/classes.metricsmanager.d.ts +0 -233
- package/dist_ts/monitoring/classes.metricsmanager.js +0 -897
- package/dist_ts/monitoring/index.d.ts +0 -1
- package/dist_ts/monitoring/index.js +0 -2
- package/dist_ts/opsserver/classes.opsserver.d.ts +0 -47
- package/dist_ts/opsserver/classes.opsserver.js +0 -105
- package/dist_ts/opsserver/handlers/acme-config.handler.d.ts +0 -16
- package/dist_ts/opsserver/handlers/acme-config.handler.js +0 -77
- package/dist_ts/opsserver/handlers/admin.handler.d.ts +0 -40
- package/dist_ts/opsserver/handlers/admin.handler.js +0 -191
- package/dist_ts/opsserver/handlers/api-token.handler.d.ts +0 -6
- package/dist_ts/opsserver/handlers/api-token.handler.js +0 -62
- package/dist_ts/opsserver/handlers/certificate.handler.d.ts +0 -77
- package/dist_ts/opsserver/handlers/certificate.handler.js +0 -574
- package/dist_ts/opsserver/handlers/config.handler.d.ts +0 -7
- package/dist_ts/opsserver/handlers/config.handler.js +0 -200
- package/dist_ts/opsserver/handlers/dns-provider.handler.d.ts +0 -16
- package/dist_ts/opsserver/handlers/dns-provider.handler.js +0 -156
- package/dist_ts/opsserver/handlers/dns-record.handler.d.ts +0 -13
- package/dist_ts/opsserver/handlers/dns-record.handler.js +0 -98
- package/dist_ts/opsserver/handlers/domain.handler.d.ts +0 -13
- package/dist_ts/opsserver/handlers/domain.handler.js +0 -137
- package/dist_ts/opsserver/handlers/email-domain.handler.d.ts +0 -16
- package/dist_ts/opsserver/handlers/email-domain.handler.js +0 -150
- package/dist_ts/opsserver/handlers/email-ops.handler.d.ts +0 -30
- package/dist_ts/opsserver/handlers/email-ops.handler.js +0 -227
- package/dist_ts/opsserver/handlers/index.d.ts +0 -21
- package/dist_ts/opsserver/handlers/index.js +0 -22
- package/dist_ts/opsserver/handlers/logs.handler.d.ts +0 -25
- package/dist_ts/opsserver/handlers/logs.handler.js +0 -264
- package/dist_ts/opsserver/handlers/network-target.handler.d.ts +0 -10
- package/dist_ts/opsserver/handlers/network-target.handler.js +0 -117
- package/dist_ts/opsserver/handlers/radius.handler.d.ts +0 -6
- package/dist_ts/opsserver/handlers/radius.handler.js +0 -295
- package/dist_ts/opsserver/handlers/remoteingress.handler.d.ts +0 -6
- package/dist_ts/opsserver/handlers/remoteingress.handler.js +0 -156
- package/dist_ts/opsserver/handlers/route-management.handler.d.ts +0 -14
- package/dist_ts/opsserver/handlers/route-management.handler.js +0 -98
- package/dist_ts/opsserver/handlers/security.handler.d.ts +0 -9
- package/dist_ts/opsserver/handlers/security.handler.js +0 -237
- package/dist_ts/opsserver/handlers/source-profile.handler.d.ts +0 -10
- package/dist_ts/opsserver/handlers/source-profile.handler.js +0 -119
- package/dist_ts/opsserver/handlers/stats.handler.d.ts +0 -11
- package/dist_ts/opsserver/handlers/stats.handler.js +0 -461
- package/dist_ts/opsserver/handlers/target-profile.handler.d.ts +0 -10
- package/dist_ts/opsserver/handlers/target-profile.handler.js +0 -117
- package/dist_ts/opsserver/handlers/users.handler.d.ts +0 -12
- package/dist_ts/opsserver/handlers/users.handler.js +0 -24
- package/dist_ts/opsserver/handlers/vpn.handler.d.ts +0 -6
- package/dist_ts/opsserver/handlers/vpn.handler.js +0 -262
- package/dist_ts/opsserver/helpers/guards.d.ts +0 -27
- package/dist_ts/opsserver/helpers/guards.js +0 -43
- package/dist_ts/opsserver/index.d.ts +0 -1
- package/dist_ts/opsserver/index.js +0 -2
- package/dist_ts/paths.d.ts +0 -25
- package/dist_ts/paths.js +0 -44
- package/dist_ts/plugins.d.ts +0 -81
- package/dist_ts/plugins.js +0 -115
- package/dist_ts/radius/classes.accounting.manager.d.ts +0 -223
- package/dist_ts/radius/classes.accounting.manager.js +0 -449
- package/dist_ts/radius/classes.radius.server.d.ts +0 -169
- package/dist_ts/radius/classes.radius.server.js +0 -384
- package/dist_ts/radius/classes.vlan.manager.d.ts +0 -124
- package/dist_ts/radius/classes.vlan.manager.js +0 -272
- package/dist_ts/radius/index.d.ts +0 -13
- package/dist_ts/radius/index.js +0 -14
- package/dist_ts/remoteingress/classes.remoteingress-manager.d.ts +0 -92
- package/dist_ts/remoteingress/classes.remoteingress-manager.js +0 -291
- package/dist_ts/remoteingress/classes.tunnel-manager.d.ts +0 -59
- package/dist_ts/remoteingress/classes.tunnel-manager.js +0 -165
- package/dist_ts/remoteingress/index.d.ts +0 -2
- package/dist_ts/remoteingress/index.js +0 -3
- package/dist_ts/security/classes.contentscanner.d.ts +0 -164
- package/dist_ts/security/classes.contentscanner.js +0 -642
- package/dist_ts/security/classes.ipreputationchecker.d.ts +0 -145
- package/dist_ts/security/classes.ipreputationchecker.js +0 -458
- package/dist_ts/security/classes.securitylogger.d.ts +0 -144
- package/dist_ts/security/classes.securitylogger.js +0 -235
- package/dist_ts/security/index.d.ts +0 -3
- package/dist_ts/security/index.js +0 -4
- package/dist_ts/sms/classes.smsservice.d.ts +0 -15
- package/dist_ts/sms/classes.smsservice.js +0 -72
- package/dist_ts/sms/config/sms.config.d.ts +0 -93
- package/dist_ts/sms/config/sms.config.js +0 -2
- package/dist_ts/sms/config/sms.schema.d.ts +0 -5
- package/dist_ts/sms/config/sms.schema.js +0 -121
- package/dist_ts/sms/index.d.ts +0 -1
- package/dist_ts/sms/index.js +0 -2
- package/dist_ts/vpn/classes.vpn-manager.d.ts +0 -159
- package/dist_ts/vpn/classes.vpn-manager.js +0 -459
- package/dist_ts/vpn/index.d.ts +0 -1
- package/dist_ts/vpn/index.js +0 -2
- package/dist_ts_apiclient/classes.apitoken.d.ts +0 -41
- package/dist_ts_apiclient/classes.apitoken.js +0 -115
- package/dist_ts_apiclient/classes.certificate.d.ts +0 -57
- package/dist_ts_apiclient/classes.certificate.js +0 -69
- package/dist_ts_apiclient/classes.config.d.ts +0 -7
- package/dist_ts_apiclient/classes.config.js +0 -11
- package/dist_ts_apiclient/classes.dcrouterapiclient.d.ts +0 -41
- package/dist_ts_apiclient/classes.dcrouterapiclient.js +0 -81
- package/dist_ts_apiclient/classes.email.d.ts +0 -30
- package/dist_ts_apiclient/classes.email.js +0 -52
- package/dist_ts_apiclient/classes.logs.d.ts +0 -21
- package/dist_ts_apiclient/classes.logs.js +0 -14
- package/dist_ts_apiclient/classes.radius.d.ts +0 -59
- package/dist_ts_apiclient/classes.radius.js +0 -95
- package/dist_ts_apiclient/classes.remoteingress.d.ts +0 -54
- package/dist_ts_apiclient/classes.remoteingress.js +0 -136
- package/dist_ts_apiclient/classes.route.d.ts +0 -39
- package/dist_ts_apiclient/classes.route.js +0 -125
- package/dist_ts_apiclient/classes.stats.d.ts +0 -47
- package/dist_ts_apiclient/classes.stats.js +0 -38
- package/dist_ts_apiclient/index.d.ts +0 -10
- package/dist_ts_apiclient/index.js +0 -14
- package/dist_ts_apiclient/plugins.d.ts +0 -3
- package/dist_ts_apiclient/plugins.js +0 -5
- package/dist_ts_interfaces/data/acme-config.d.ts +0 -25
- package/dist_ts_interfaces/data/acme-config.js +0 -2
- package/dist_ts_interfaces/data/auth.d.ts +0 -8
- package/dist_ts_interfaces/data/auth.js +0 -2
- package/dist_ts_interfaces/data/dns-provider.d.ts +0 -136
- package/dist_ts_interfaces/data/dns-provider.js +0 -41
- package/dist_ts_interfaces/data/dns-record.d.ts +0 -42
- package/dist_ts_interfaces/data/dns-record.js +0 -2
- package/dist_ts_interfaces/data/domain.d.ts +0 -35
- package/dist_ts_interfaces/data/domain.js +0 -2
- package/dist_ts_interfaces/data/email-domain.d.ts +0 -70
- package/dist_ts_interfaces/data/email-domain.js +0 -2
- package/dist_ts_interfaces/data/index.d.ts +0 -11
- package/dist_ts_interfaces/data/index.js +0 -12
- package/dist_ts_interfaces/data/remoteingress.d.ts +0 -60
- package/dist_ts_interfaces/data/remoteingress.js +0 -2
- package/dist_ts_interfaces/data/route-management.d.ts +0 -110
- package/dist_ts_interfaces/data/route-management.js +0 -2
- package/dist_ts_interfaces/data/stats.d.ts +0 -238
- package/dist_ts_interfaces/data/stats.js +0 -2
- package/dist_ts_interfaces/data/target-profile.d.ts +0 -28
- package/dist_ts_interfaces/data/target-profile.js +0 -2
- package/dist_ts_interfaces/data/vpn.d.ts +0 -61
- package/dist_ts_interfaces/data/vpn.js +0 -2
- package/dist_ts_interfaces/index.d.ts +0 -5
- package/dist_ts_interfaces/index.js +0 -8
- package/dist_ts_interfaces/plugins.d.ts +0 -2
- package/dist_ts_interfaces/plugins.js +0 -4
- package/dist_ts_interfaces/requests/acme-config.d.ts +0 -42
- package/dist_ts_interfaces/requests/acme-config.js +0 -2
- package/dist_ts_interfaces/requests/admin.d.ts +0 -31
- package/dist_ts_interfaces/requests/admin.js +0 -3
- package/dist_ts_interfaces/requests/api-tokens.d.ts +0 -79
- package/dist_ts_interfaces/requests/api-tokens.js +0 -2
- package/dist_ts_interfaces/requests/certificate.d.ts +0 -111
- package/dist_ts_interfaces/requests/certificate.js +0 -3
- package/dist_ts_interfaces/requests/combined.stats.d.ts +0 -28
- package/dist_ts_interfaces/requests/combined.stats.js +0 -2
- package/dist_ts_interfaces/requests/config.d.ts +0 -90
- package/dist_ts_interfaces/requests/config.js +0 -3
- package/dist_ts_interfaces/requests/dns-providers.d.ts +0 -117
- package/dist_ts_interfaces/requests/dns-providers.js +0 -2
- package/dist_ts_interfaces/requests/dns-records.d.ts +0 -89
- package/dist_ts_interfaces/requests/dns-records.js +0 -2
- package/dist_ts_interfaces/requests/domains.d.ts +0 -142
- package/dist_ts_interfaces/requests/domains.js +0 -2
- package/dist_ts_interfaces/requests/email-domains.d.ts +0 -142
- package/dist_ts_interfaces/requests/email-domains.js +0 -2
- package/dist_ts_interfaces/requests/email-ops.d.ts +0 -82
- package/dist_ts_interfaces/requests/email-ops.js +0 -3
- package/dist_ts_interfaces/requests/index.d.ts +0 -21
- package/dist_ts_interfaces/requests/index.js +0 -22
- package/dist_ts_interfaces/requests/logs.d.ts +0 -41
- package/dist_ts_interfaces/requests/logs.js +0 -4
- package/dist_ts_interfaces/requests/network-targets.d.ts +0 -102
- package/dist_ts_interfaces/requests/network-targets.js +0 -2
- package/dist_ts_interfaces/requests/radius.d.ts +0 -268
- package/dist_ts_interfaces/requests/radius.js +0 -3
- package/dist_ts_interfaces/requests/remoteingress.d.ts +0 -108
- package/dist_ts_interfaces/requests/remoteingress.js +0 -3
- package/dist_ts_interfaces/requests/route-management.d.ts +0 -85
- package/dist_ts_interfaces/requests/route-management.js +0 -2
- package/dist_ts_interfaces/requests/source-profiles.d.ts +0 -102
- package/dist_ts_interfaces/requests/source-profiles.js +0 -2
- package/dist_ts_interfaces/requests/stats.d.ts +0 -177
- package/dist_ts_interfaces/requests/stats.js +0 -4
- package/dist_ts_interfaces/requests/target-profiles.d.ts +0 -103
- package/dist_ts_interfaces/requests/target-profiles.js +0 -2
- package/dist_ts_interfaces/requests/users.d.ts +0 -19
- package/dist_ts_interfaces/requests/users.js +0 -3
- package/dist_ts_interfaces/requests/vpn.d.ts +0 -177
- package/dist_ts_interfaces/requests/vpn.js +0 -3
- package/dist_ts_migrations/index.d.ts +0 -28
- package/dist_ts_migrations/index.js +0 -82
- package/dist_ts_oci_container/index.d.ts +0 -8
- package/dist_ts_oci_container/index.js +0 -110
- package/dist_ts_oci_container/plugins.d.ts +0 -3
- package/dist_ts_oci_container/plugins.js +0 -4
- package/dist_ts_web/00_commitinfo_data.d.ts +0 -8
- package/dist_ts_web/00_commitinfo_data.js +0 -9
- package/dist_ts_web/appstate.d.ts +0 -478
- package/dist_ts_web/appstate.js +0 -1968
- package/dist_ts_web/elements/access/index.d.ts +0 -2
- package/dist_ts_web/elements/access/index.js +0 -3
- package/dist_ts_web/elements/access/ops-view-apitokens.d.ts +0 -13
- package/dist_ts_web/elements/access/ops-view-apitokens.js +0 -372
- package/dist_ts_web/elements/access/ops-view-users.d.ts +0 -11
- package/dist_ts_web/elements/access/ops-view-users.js +0 -190
- package/dist_ts_web/elements/domains/dns-provider-form.d.ts +0 -60
- package/dist_ts_web/elements/domains/dns-provider-form.js +0 -259
- package/dist_ts_web/elements/domains/index.d.ts +0 -5
- package/dist_ts_web/elements/domains/index.js +0 -6
- package/dist_ts_web/elements/domains/ops-view-certificates.d.ts +0 -25
- package/dist_ts_web/elements/domains/ops-view-certificates.js +0 -669
- package/dist_ts_web/elements/domains/ops-view-dns.d.ts +0 -17
- package/dist_ts_web/elements/domains/ops-view-dns.js +0 -305
- package/dist_ts_web/elements/domains/ops-view-domains.d.ts +0 -19
- package/dist_ts_web/elements/domains/ops-view-domains.js +0 -456
- package/dist_ts_web/elements/domains/ops-view-providers.d.ts +0 -21
- package/dist_ts_web/elements/domains/ops-view-providers.js +0 -330
- package/dist_ts_web/elements/email/index.d.ts +0 -3
- package/dist_ts_web/elements/email/index.js +0 -4
- package/dist_ts_web/elements/email/ops-view-email-domains.d.ts +0 -19
- package/dist_ts_web/elements/email/ops-view-email-domains.js +0 -410
- package/dist_ts_web/elements/email/ops-view-email-security.d.ts +0 -14
- package/dist_ts_web/elements/email/ops-view-email-security.js +0 -178
- package/dist_ts_web/elements/email/ops-view-emails.d.ts +0 -21
- package/dist_ts_web/elements/email/ops-view-emails.js +0 -165
- package/dist_ts_web/elements/index.d.ts +0 -9
- package/dist_ts_web/elements/index.js +0 -10
- package/dist_ts_web/elements/network/index.d.ts +0 -7
- package/dist_ts_web/elements/network/index.js +0 -8
- package/dist_ts_web/elements/network/ops-view-network-activity.d.ts +0 -60
- package/dist_ts_web/elements/network/ops-view-network-activity.js +0 -753
- package/dist_ts_web/elements/network/ops-view-networktargets.d.ts +0 -17
- package/dist_ts_web/elements/network/ops-view-networktargets.js +0 -255
- package/dist_ts_web/elements/network/ops-view-remoteingress.d.ts +0 -20
- package/dist_ts_web/elements/network/ops-view-remoteingress.js +0 -497
- package/dist_ts_web/elements/network/ops-view-routes.d.ts +0 -16
- package/dist_ts_web/elements/network/ops-view-routes.js +0 -674
- package/dist_ts_web/elements/network/ops-view-sourceprofiles.d.ts +0 -17
- package/dist_ts_web/elements/network/ops-view-sourceprofiles.js +0 -278
- package/dist_ts_web/elements/network/ops-view-targetprofiles.d.ts +0 -21
- package/dist_ts_web/elements/network/ops-view-targetprofiles.js +0 -420
- package/dist_ts_web/elements/network/ops-view-vpn.d.ts +0 -31
- package/dist_ts_web/elements/network/ops-view-vpn.js +0 -873
- package/dist_ts_web/elements/ops-dashboard.d.ts +0 -31
- package/dist_ts_web/elements/ops-dashboard.js +0 -405
- package/dist_ts_web/elements/ops-view-logs.d.ts +0 -13
- package/dist_ts_web/elements/ops-view-logs.js +0 -159
- package/dist_ts_web/elements/overview/index.d.ts +0 -2
- package/dist_ts_web/elements/overview/index.js +0 -3
- package/dist_ts_web/elements/overview/ops-view-config.d.ts +0 -19
- package/dist_ts_web/elements/overview/ops-view-config.js +0 -339
- package/dist_ts_web/elements/overview/ops-view-overview.d.ts +0 -24
- package/dist_ts_web/elements/overview/ops-view-overview.js +0 -545
- package/dist_ts_web/elements/security/index.d.ts +0 -3
- package/dist_ts_web/elements/security/index.js +0 -4
- package/dist_ts_web/elements/security/ops-view-security-authentication.d.ts +0 -13
- package/dist_ts_web/elements/security/ops-view-security-authentication.js +0 -157
- package/dist_ts_web/elements/security/ops-view-security-blocked.d.ts +0 -15
- package/dist_ts_web/elements/security/ops-view-security-blocked.js +0 -153
- package/dist_ts_web/elements/security/ops-view-security-overview.d.ts +0 -16
- package/dist_ts_web/elements/security/ops-view-security-overview.js +0 -205
- package/dist_ts_web/elements/shared/css.d.ts +0 -1
- package/dist_ts_web/elements/shared/css.js +0 -10
- package/dist_ts_web/elements/shared/index.d.ts +0 -1
- package/dist_ts_web/elements/shared/index.js +0 -2
- package/dist_ts_web/index.d.ts +0 -1
- package/dist_ts_web/index.js +0 -10
- package/dist_ts_web/plugins.d.ts +0 -7
- package/dist_ts_web/plugins.js +0 -13
- package/dist_ts_web/router.d.ts +0 -21
- package/dist_ts_web/router.js +0 -151
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@serve.zone/dcrouter",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "13.
|
|
4
|
+
"version": "13.17.0",
|
|
5
5
|
"description": "A multifaceted routing service handling mail and SMS delivery functions.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"exports": {
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"@push.rocks/smartnetwork": "^4.5.2",
|
|
55
55
|
"@push.rocks/smartpath": "^6.0.0",
|
|
56
56
|
"@push.rocks/smartpromise": "^4.2.3",
|
|
57
|
-
"@push.rocks/smartproxy": "^27.
|
|
57
|
+
"@push.rocks/smartproxy": "^27.6.0",
|
|
58
58
|
"@push.rocks/smartradius": "^1.1.1",
|
|
59
59
|
"@push.rocks/smartrequest": "^5.0.1",
|
|
60
60
|
"@push.rocks/smartrx": "^3.0.10",
|
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -560,7 +560,7 @@ export class MetricsManager {
|
|
|
560
560
|
requestsPerSecond: 0,
|
|
561
561
|
requestsTotal: 0,
|
|
562
562
|
backends: [] as Array<any>,
|
|
563
|
-
domainActivity: [] as Array<{ domain: string; bytesInPerSecond: number; bytesOutPerSecond: number; activeConnections: number; routeCount: number }>,
|
|
563
|
+
domainActivity: [] as Array<{ domain: string; bytesInPerSecond: number; bytesOutPerSecond: number; activeConnections: number; routeCount: number; requestCount: number }>,
|
|
564
564
|
};
|
|
565
565
|
}
|
|
566
566
|
|
|
@@ -720,11 +720,20 @@ export class MetricsManager {
|
|
|
720
720
|
.slice(0, 10)
|
|
721
721
|
.map(([ip, data]) => ({ ip, count: data.count, bwIn: data.bwIn, bwOut: data.bwOut }));
|
|
722
722
|
|
|
723
|
-
// Build domain activity
|
|
723
|
+
// Build domain activity using per-IP domain request counts from Rust engine
|
|
724
724
|
const connectionsByRoute = proxyMetrics.connections.byRoute();
|
|
725
725
|
const throughputByRoute = proxyMetrics.throughput.byRoute();
|
|
726
726
|
|
|
727
|
-
//
|
|
727
|
+
// Aggregate per-IP domain request counts into per-domain totals
|
|
728
|
+
const domainRequestTotals = new Map<string, number>();
|
|
729
|
+
const domainRequestsByIP = proxyMetrics.connections.domainRequestsByIP();
|
|
730
|
+
for (const [, domainMap] of domainRequestsByIP) {
|
|
731
|
+
for (const [domain, count] of domainMap) {
|
|
732
|
+
domainRequestTotals.set(domain, (domainRequestTotals.get(domain) || 0) + count);
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
// Map route name → domains from route config
|
|
728
737
|
const routeDomains = new Map<string, string[]>();
|
|
729
738
|
if (this.dcRouter.smartProxy) {
|
|
730
739
|
for (const route of this.dcRouter.smartProxy.routeManager.getRoutes()) {
|
|
@@ -738,34 +747,26 @@ export class MetricsManager {
|
|
|
738
747
|
}
|
|
739
748
|
}
|
|
740
749
|
|
|
741
|
-
//
|
|
742
|
-
const
|
|
743
|
-
const domainToBackend = new Map<string, string>(); // domain → host:port
|
|
750
|
+
// Resolve wildcards using domains seen in request metrics
|
|
751
|
+
const allKnownDomains = new Set<string>(domainRequestTotals.keys());
|
|
744
752
|
for (const entry of protocolCache) {
|
|
745
|
-
if (entry.domain)
|
|
746
|
-
activeDomains.add(entry.domain);
|
|
747
|
-
domainToBackend.set(entry.domain, `${entry.host}:${entry.port}`);
|
|
748
|
-
}
|
|
753
|
+
if (entry.domain) allKnownDomains.add(entry.domain);
|
|
749
754
|
}
|
|
750
755
|
|
|
751
|
-
// Build reverse map: domain → route name(s)
|
|
752
|
-
// For concrete domains: direct lookup from route config
|
|
753
|
-
// For wildcard patterns: match active domains from protocol cache
|
|
756
|
+
// Build reverse map: concrete domain → route name(s)
|
|
754
757
|
const domainToRoutes = new Map<string, string[]>();
|
|
755
758
|
for (const [routeName, domains] of routeDomains) {
|
|
756
759
|
for (const pattern of domains) {
|
|
757
760
|
if (pattern.includes('*')) {
|
|
758
|
-
// Wildcard pattern — match against active domains from protocol cache
|
|
759
761
|
const regex = new RegExp('^' + pattern.replace(/\./g, '\\.').replace(/\*/g, '[^.]+') + '$');
|
|
760
|
-
for (const
|
|
761
|
-
if (regex.test(
|
|
762
|
-
const existing = domainToRoutes.get(
|
|
762
|
+
for (const knownDomain of allKnownDomains) {
|
|
763
|
+
if (regex.test(knownDomain)) {
|
|
764
|
+
const existing = domainToRoutes.get(knownDomain);
|
|
763
765
|
if (existing) { existing.push(routeName); }
|
|
764
|
-
else { domainToRoutes.set(
|
|
766
|
+
else { domainToRoutes.set(knownDomain, [routeName]); }
|
|
765
767
|
}
|
|
766
768
|
}
|
|
767
769
|
} else {
|
|
768
|
-
// Concrete domain
|
|
769
770
|
const existing = domainToRoutes.get(pattern);
|
|
770
771
|
if (existing) { existing.push(routeName); }
|
|
771
772
|
else { domainToRoutes.set(pattern, [routeName]); }
|
|
@@ -773,20 +774,28 @@ export class MetricsManager {
|
|
|
773
774
|
}
|
|
774
775
|
}
|
|
775
776
|
|
|
776
|
-
//
|
|
777
|
-
//
|
|
778
|
-
|
|
777
|
+
// For each route, compute the total request count across all its resolved domains
|
|
778
|
+
// so we can distribute throughput/connections proportionally
|
|
779
|
+
const routeTotalRequests = new Map<string, number>();
|
|
780
|
+
for (const [domain, routeNames] of domainToRoutes) {
|
|
781
|
+
const reqs = domainRequestTotals.get(domain) || 0;
|
|
782
|
+
for (const routeName of routeNames) {
|
|
783
|
+
routeTotalRequests.set(routeName, (routeTotalRequests.get(routeName) || 0) + reqs);
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
// Aggregate metrics per domain using request-count-proportional splitting
|
|
779
788
|
const domainAgg = new Map<string, {
|
|
780
789
|
activeConnections: number;
|
|
781
790
|
bytesInPerSec: number;
|
|
782
791
|
bytesOutPerSec: number;
|
|
783
792
|
routeCount: number;
|
|
793
|
+
requestCount: number;
|
|
784
794
|
}>();
|
|
785
|
-
|
|
786
|
-
// Track which routes are accounted for
|
|
787
795
|
const accountedRoutes = new Set<string>();
|
|
788
796
|
|
|
789
797
|
for (const [domain, routeNames] of domainToRoutes) {
|
|
798
|
+
const domainReqs = domainRequestTotals.get(domain) || 0;
|
|
790
799
|
let totalConns = 0;
|
|
791
800
|
let totalIn = 0;
|
|
792
801
|
let totalOut = 0;
|
|
@@ -795,15 +804,12 @@ export class MetricsManager {
|
|
|
795
804
|
accountedRoutes.add(routeName);
|
|
796
805
|
const conns = connectionsByRoute.get(routeName) || 0;
|
|
797
806
|
const tp = throughputByRoute.get(routeName) || { in: 0, out: 0 };
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
totalConns += conns / share;
|
|
805
|
-
totalIn += tp.in / share;
|
|
806
|
-
totalOut += tp.out / share;
|
|
807
|
+
const routeTotal = routeTotalRequests.get(routeName) || 0;
|
|
808
|
+
|
|
809
|
+
const share = routeTotal > 0 ? domainReqs / routeTotal : 0;
|
|
810
|
+
totalConns += conns * share;
|
|
811
|
+
totalIn += tp.in * share;
|
|
812
|
+
totalOut += tp.out * share;
|
|
807
813
|
}
|
|
808
814
|
|
|
809
815
|
domainAgg.set(domain, {
|
|
@@ -811,13 +817,14 @@ export class MetricsManager {
|
|
|
811
817
|
bytesInPerSec: totalIn,
|
|
812
818
|
bytesOutPerSec: totalOut,
|
|
813
819
|
routeCount: routeNames.length,
|
|
820
|
+
requestCount: domainReqs,
|
|
814
821
|
});
|
|
815
822
|
}
|
|
816
823
|
|
|
817
824
|
// Include routes with no domain config (fallback: use route name)
|
|
818
825
|
for (const [routeName, activeConns] of connectionsByRoute) {
|
|
819
826
|
if (accountedRoutes.has(routeName)) continue;
|
|
820
|
-
if (routeDomains.has(routeName)) continue;
|
|
827
|
+
if (routeDomains.has(routeName)) continue;
|
|
821
828
|
const tp = throughputByRoute.get(routeName) || { in: 0, out: 0 };
|
|
822
829
|
if (activeConns === 0 && tp.in === 0 && tp.out === 0) continue;
|
|
823
830
|
const existing = domainAgg.get(routeName);
|
|
@@ -832,6 +839,7 @@ export class MetricsManager {
|
|
|
832
839
|
bytesInPerSec: tp.in,
|
|
833
840
|
bytesOutPerSec: tp.out,
|
|
834
841
|
routeCount: 1,
|
|
842
|
+
requestCount: 0,
|
|
835
843
|
});
|
|
836
844
|
}
|
|
837
845
|
}
|
|
@@ -843,6 +851,7 @@ export class MetricsManager {
|
|
|
843
851
|
bytesOutPerSecond: data.bytesOutPerSec,
|
|
844
852
|
activeConnections: data.activeConnections,
|
|
845
853
|
routeCount: data.routeCount,
|
|
854
|
+
requestCount: data.requestCount,
|
|
846
855
|
}))
|
|
847
856
|
.sort((a, b) => (b.bytesInPerSecond + b.bytesOutPerSecond) - (a.bytesInPerSecond + a.bytesOutPerSecond));
|
|
848
857
|
|
|
@@ -560,11 +560,12 @@ export class OpsViewNetworkActivity extends DeesElement {
|
|
|
560
560
|
'Throughput Out': this.formatBitsPerSecond(item.bytesOutPerSecond),
|
|
561
561
|
'Transferred / min': this.formatBytes(totalBytesPerMin),
|
|
562
562
|
'Connections': item.activeConnections,
|
|
563
|
+
'Requests': item.requestCount?.toLocaleString() ?? '0',
|
|
563
564
|
'Routes': item.routeCount,
|
|
564
565
|
};
|
|
565
566
|
}}
|
|
566
567
|
heading1="Domain Activity"
|
|
567
|
-
heading2="Per-domain network activity
|
|
568
|
+
heading2="Per-domain network activity from request-level metrics"
|
|
568
569
|
searchable
|
|
569
570
|
.showColumnFilters=${true}
|
|
570
571
|
.pagination=${false}
|
|
@@ -49,6 +49,8 @@ function setupTlsVisibility(formEl: any) {
|
|
|
49
49
|
|
|
50
50
|
@customElement('ops-view-routes')
|
|
51
51
|
export class OpsViewRoutes extends DeesElement {
|
|
52
|
+
@state() accessor routeFilter: 'User Routes' | 'System Routes' = 'User Routes';
|
|
53
|
+
|
|
52
54
|
@state() accessor routeState: appstate.IRouteManagementState = {
|
|
53
55
|
mergedRoutes: [],
|
|
54
56
|
warnings: [],
|
|
@@ -156,20 +158,20 @@ export class OpsViewRoutes extends DeesElement {
|
|
|
156
158
|
},
|
|
157
159
|
{
|
|
158
160
|
id: 'configRoutes',
|
|
159
|
-
title: '
|
|
161
|
+
title: 'System Routes',
|
|
160
162
|
type: 'number',
|
|
161
163
|
value: configCount,
|
|
162
164
|
icon: 'lucide:settings',
|
|
163
|
-
description: '
|
|
165
|
+
description: 'From config, email, and DNS',
|
|
164
166
|
color: '#8b5cf6',
|
|
165
167
|
},
|
|
166
168
|
{
|
|
167
169
|
id: 'apiRoutes',
|
|
168
|
-
title: '
|
|
170
|
+
title: 'User Routes',
|
|
169
171
|
type: 'number',
|
|
170
172
|
value: apiCount,
|
|
171
173
|
icon: 'lucide:code',
|
|
172
|
-
description: '
|
|
174
|
+
description: 'Created via API',
|
|
173
175
|
color: '#0ea5e9',
|
|
174
176
|
},
|
|
175
177
|
{
|
|
@@ -183,8 +185,14 @@ export class OpsViewRoutes extends DeesElement {
|
|
|
183
185
|
},
|
|
184
186
|
];
|
|
185
187
|
|
|
186
|
-
//
|
|
187
|
-
const
|
|
188
|
+
// Filter routes based on selected tab
|
|
189
|
+
const isUserRoutes = this.routeFilter === 'User Routes';
|
|
190
|
+
const filteredRoutes = mergedRoutes.filter((mr) =>
|
|
191
|
+
isUserRoutes ? mr.origin === 'api' : mr.origin !== 'api'
|
|
192
|
+
);
|
|
193
|
+
|
|
194
|
+
// Map filtered routes to sz-route-list-view format
|
|
195
|
+
const szRoutes = filteredRoutes.map((mr) => {
|
|
188
196
|
const tags = [...(mr.route.tags || [])];
|
|
189
197
|
tags.push(mr.origin);
|
|
190
198
|
if (!mr.enabled) tags.push('disabled');
|
|
@@ -218,6 +226,13 @@ export class OpsViewRoutes extends DeesElement {
|
|
|
218
226
|
]}
|
|
219
227
|
></dees-statsgrid>
|
|
220
228
|
|
|
229
|
+
<dees-input-multitoggle
|
|
230
|
+
.type=${'single'}
|
|
231
|
+
.options=${['User Routes', 'System Routes']}
|
|
232
|
+
.selectedOption=${this.routeFilter}
|
|
233
|
+
@change=${(e: any) => { this.routeFilter = e.target.value || e.target.selectedOption; }}
|
|
234
|
+
></dees-input-multitoggle>
|
|
235
|
+
|
|
221
236
|
${warnings.length > 0
|
|
222
237
|
? html`
|
|
223
238
|
<div class="warnings-bar">
|
|
@@ -237,6 +252,7 @@ export class OpsViewRoutes extends DeesElement {
|
|
|
237
252
|
? html`
|
|
238
253
|
<sz-route-list-view
|
|
239
254
|
.routes=${szRoutes}
|
|
255
|
+
.showActionsFilter=${isUserRoutes ? () => true : () => false}
|
|
240
256
|
@route-click=${(e: CustomEvent) => this.handleRouteClick(e)}
|
|
241
257
|
@route-edit=${(e: CustomEvent) => this.handleRouteEdit(e)}
|
|
242
258
|
@route-delete=${(e: CustomEvent) => this.handleRouteDelete(e)}
|
|
@@ -244,8 +260,8 @@ export class OpsViewRoutes extends DeesElement {
|
|
|
244
260
|
`
|
|
245
261
|
: html`
|
|
246
262
|
<div class="empty-state">
|
|
247
|
-
<p>No routes
|
|
248
|
-
<p
|
|
263
|
+
<p>No ${isUserRoutes ? 'user' : 'system'} routes</p>
|
|
264
|
+
<p>${isUserRoutes ? 'Add a route to get started.' : 'System routes are generated from config, email, and DNS settings.'}</p>
|
|
249
265
|
</div>
|
|
250
266
|
`}
|
|
251
267
|
</div>
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* autocreated commitinfo by @push.rocks/commitinfo
|
|
3
|
-
*/
|
|
4
|
-
export const commitinfo = {
|
|
5
|
-
name: '@serve.zone/dcrouter',
|
|
6
|
-
version: '13.16.0',
|
|
7
|
-
description: 'A multifaceted routing service handling mail and SMS delivery functions.'
|
|
8
|
-
};
|
|
9
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxzQkFBc0I7SUFDNUIsT0FBTyxFQUFFLFNBQVM7SUFDbEIsV0FBVyxFQUFFLDBFQUEwRTtDQUN4RixDQUFBIn0=
|
package/dist_ts/acme/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './manager.acme-config.js';
|
package/dist_ts/acme/index.js
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import type { IDcRouterOptions } from '../classes.dcrouter.js';
|
|
2
|
-
import type { IAcmeConfig } from '../../dist_ts_interfaces/data/acme-config.js';
|
|
3
|
-
/**
|
|
4
|
-
* AcmeConfigManager — owns the singleton ACME configuration in the DB.
|
|
5
|
-
*
|
|
6
|
-
* Lifecycle:
|
|
7
|
-
* - `start()` — loads from the DB; if empty, seeds from legacy constructor
|
|
8
|
-
* fields (`tls.contactEmail`, `smartProxyConfig.acme.*`) on first boot.
|
|
9
|
-
* - `getConfig()` — returns the in-memory cached `IAcmeConfig` (or null)
|
|
10
|
-
* - `updateConfig(args, updatedBy)` — upserts and refreshes the cache
|
|
11
|
-
*
|
|
12
|
-
* Reload semantics: updates take effect on the next dcrouter restart because
|
|
13
|
-
* `SmartAcme` is instantiated once in `setupSmartProxy()`. `renewThresholdDays`
|
|
14
|
-
* applies immediately to the next renewal check. See
|
|
15
|
-
* `ts_web/elements/domains/ops-view-certificates.ts` for the UI warning.
|
|
16
|
-
*/
|
|
17
|
-
export declare class AcmeConfigManager {
|
|
18
|
-
private options;
|
|
19
|
-
private cached;
|
|
20
|
-
constructor(options: IDcRouterOptions);
|
|
21
|
-
start(): Promise<void>;
|
|
22
|
-
stop(): Promise<void>;
|
|
23
|
-
/**
|
|
24
|
-
* Returns the current ACME config, or null if not configured.
|
|
25
|
-
* In-memory — does not hit the DB.
|
|
26
|
-
*/
|
|
27
|
-
getConfig(): IAcmeConfig | null;
|
|
28
|
-
/**
|
|
29
|
-
* True if there is an enabled ACME config. Used by `setupSmartProxy()` to
|
|
30
|
-
* decide whether to instantiate SmartAcme.
|
|
31
|
-
*/
|
|
32
|
-
hasEnabledConfig(): boolean;
|
|
33
|
-
/**
|
|
34
|
-
* Upsert the ACME config. All fields are optional; missing fields are
|
|
35
|
-
* preserved from the existing row (or defaulted if there is no row yet).
|
|
36
|
-
*/
|
|
37
|
-
updateConfig(args: Partial<Omit<IAcmeConfig, 'updatedAt' | 'updatedBy'>>, updatedBy: string): Promise<IAcmeConfig>;
|
|
38
|
-
/**
|
|
39
|
-
* Build a seed object from the legacy constructor fields. Returns null
|
|
40
|
-
* if the user has not provided any of them.
|
|
41
|
-
*
|
|
42
|
-
* Supports BOTH `tls.contactEmail` (short form) and `smartProxyConfig.acme`
|
|
43
|
-
* (full form). `smartProxyConfig.acme` wins when both are present.
|
|
44
|
-
*/
|
|
45
|
-
private deriveSeedFromOptions;
|
|
46
|
-
private createSeedDoc;
|
|
47
|
-
private toPlain;
|
|
48
|
-
}
|
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
import { logger } from '../logger.js';
|
|
2
|
-
import { AcmeConfigDoc } from '../db/documents/index.js';
|
|
3
|
-
/**
|
|
4
|
-
* AcmeConfigManager — owns the singleton ACME configuration in the DB.
|
|
5
|
-
*
|
|
6
|
-
* Lifecycle:
|
|
7
|
-
* - `start()` — loads from the DB; if empty, seeds from legacy constructor
|
|
8
|
-
* fields (`tls.contactEmail`, `smartProxyConfig.acme.*`) on first boot.
|
|
9
|
-
* - `getConfig()` — returns the in-memory cached `IAcmeConfig` (or null)
|
|
10
|
-
* - `updateConfig(args, updatedBy)` — upserts and refreshes the cache
|
|
11
|
-
*
|
|
12
|
-
* Reload semantics: updates take effect on the next dcrouter restart because
|
|
13
|
-
* `SmartAcme` is instantiated once in `setupSmartProxy()`. `renewThresholdDays`
|
|
14
|
-
* applies immediately to the next renewal check. See
|
|
15
|
-
* `ts_web/elements/domains/ops-view-certificates.ts` for the UI warning.
|
|
16
|
-
*/
|
|
17
|
-
export class AcmeConfigManager {
|
|
18
|
-
options;
|
|
19
|
-
cached = null;
|
|
20
|
-
constructor(options) {
|
|
21
|
-
this.options = options;
|
|
22
|
-
}
|
|
23
|
-
async start() {
|
|
24
|
-
logger.log('info', 'AcmeConfigManager: starting');
|
|
25
|
-
let doc = await AcmeConfigDoc.load();
|
|
26
|
-
if (!doc) {
|
|
27
|
-
// First-boot path: seed from legacy constructor fields if present.
|
|
28
|
-
const seed = this.deriveSeedFromOptions();
|
|
29
|
-
if (seed) {
|
|
30
|
-
doc = await this.createSeedDoc(seed);
|
|
31
|
-
logger.log('info', `AcmeConfigManager: seeded from constructor legacy fields (accountEmail=${seed.accountEmail}, useProduction=${seed.useProduction})`);
|
|
32
|
-
}
|
|
33
|
-
else {
|
|
34
|
-
logger.log('info', 'AcmeConfigManager: no AcmeConfig in DB and no legacy constructor fields — ACME disabled until configured via Domains > Certificates > Settings.');
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
else if (this.deriveSeedFromOptions()) {
|
|
38
|
-
logger.log('warn', 'AcmeConfigManager: ignoring constructor tls.contactEmail / smartProxyConfig.acme — DB already has AcmeConfigDoc. Manage via Domains > Certificates > Settings.');
|
|
39
|
-
}
|
|
40
|
-
this.cached = doc ? this.toPlain(doc) : null;
|
|
41
|
-
if (this.cached) {
|
|
42
|
-
logger.log('info', `AcmeConfigManager: loaded ACME config (accountEmail=${this.cached.accountEmail}, enabled=${this.cached.enabled}, useProduction=${this.cached.useProduction})`);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
async stop() {
|
|
46
|
-
this.cached = null;
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Returns the current ACME config, or null if not configured.
|
|
50
|
-
* In-memory — does not hit the DB.
|
|
51
|
-
*/
|
|
52
|
-
getConfig() {
|
|
53
|
-
return this.cached;
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* True if there is an enabled ACME config. Used by `setupSmartProxy()` to
|
|
57
|
-
* decide whether to instantiate SmartAcme.
|
|
58
|
-
*/
|
|
59
|
-
hasEnabledConfig() {
|
|
60
|
-
return this.cached !== null && this.cached.enabled;
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Upsert the ACME config. All fields are optional; missing fields are
|
|
64
|
-
* preserved from the existing row (or defaulted if there is no row yet).
|
|
65
|
-
*/
|
|
66
|
-
async updateConfig(args, updatedBy) {
|
|
67
|
-
let doc = await AcmeConfigDoc.load();
|
|
68
|
-
const now = Date.now();
|
|
69
|
-
if (!doc) {
|
|
70
|
-
doc = new AcmeConfigDoc();
|
|
71
|
-
doc.configId = 'acme-config';
|
|
72
|
-
doc.accountEmail = args.accountEmail ?? '';
|
|
73
|
-
doc.enabled = args.enabled ?? true;
|
|
74
|
-
doc.useProduction = args.useProduction ?? true;
|
|
75
|
-
doc.autoRenew = args.autoRenew ?? true;
|
|
76
|
-
doc.renewThresholdDays = args.renewThresholdDays ?? 30;
|
|
77
|
-
}
|
|
78
|
-
else {
|
|
79
|
-
if (args.accountEmail !== undefined)
|
|
80
|
-
doc.accountEmail = args.accountEmail;
|
|
81
|
-
if (args.enabled !== undefined)
|
|
82
|
-
doc.enabled = args.enabled;
|
|
83
|
-
if (args.useProduction !== undefined)
|
|
84
|
-
doc.useProduction = args.useProduction;
|
|
85
|
-
if (args.autoRenew !== undefined)
|
|
86
|
-
doc.autoRenew = args.autoRenew;
|
|
87
|
-
if (args.renewThresholdDays !== undefined)
|
|
88
|
-
doc.renewThresholdDays = args.renewThresholdDays;
|
|
89
|
-
}
|
|
90
|
-
doc.updatedAt = now;
|
|
91
|
-
doc.updatedBy = updatedBy;
|
|
92
|
-
await doc.save();
|
|
93
|
-
this.cached = this.toPlain(doc);
|
|
94
|
-
return this.cached;
|
|
95
|
-
}
|
|
96
|
-
// ==========================================================================
|
|
97
|
-
// Internal helpers
|
|
98
|
-
// ==========================================================================
|
|
99
|
-
/**
|
|
100
|
-
* Build a seed object from the legacy constructor fields. Returns null
|
|
101
|
-
* if the user has not provided any of them.
|
|
102
|
-
*
|
|
103
|
-
* Supports BOTH `tls.contactEmail` (short form) and `smartProxyConfig.acme`
|
|
104
|
-
* (full form). `smartProxyConfig.acme` wins when both are present.
|
|
105
|
-
*/
|
|
106
|
-
deriveSeedFromOptions() {
|
|
107
|
-
const acme = this.options.smartProxyConfig?.acme;
|
|
108
|
-
const tls = this.options.tls;
|
|
109
|
-
// Prefer the explicit smartProxyConfig.acme block if present.
|
|
110
|
-
if (acme?.accountEmail) {
|
|
111
|
-
return {
|
|
112
|
-
accountEmail: acme.accountEmail,
|
|
113
|
-
enabled: acme.enabled !== false,
|
|
114
|
-
useProduction: acme.useProduction !== false,
|
|
115
|
-
autoRenew: acme.autoRenew !== false,
|
|
116
|
-
renewThresholdDays: acme.renewThresholdDays ?? 30,
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
// Fall back to the short tls.contactEmail form.
|
|
120
|
-
if (tls?.contactEmail) {
|
|
121
|
-
return {
|
|
122
|
-
accountEmail: tls.contactEmail,
|
|
123
|
-
enabled: true,
|
|
124
|
-
useProduction: true,
|
|
125
|
-
autoRenew: true,
|
|
126
|
-
renewThresholdDays: 30,
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
return null;
|
|
130
|
-
}
|
|
131
|
-
async createSeedDoc(seed) {
|
|
132
|
-
const doc = new AcmeConfigDoc();
|
|
133
|
-
doc.configId = 'acme-config';
|
|
134
|
-
doc.accountEmail = seed.accountEmail;
|
|
135
|
-
doc.enabled = seed.enabled;
|
|
136
|
-
doc.useProduction = seed.useProduction;
|
|
137
|
-
doc.autoRenew = seed.autoRenew;
|
|
138
|
-
doc.renewThresholdDays = seed.renewThresholdDays;
|
|
139
|
-
doc.updatedAt = Date.now();
|
|
140
|
-
doc.updatedBy = 'seed';
|
|
141
|
-
await doc.save();
|
|
142
|
-
return doc;
|
|
143
|
-
}
|
|
144
|
-
toPlain(doc) {
|
|
145
|
-
return {
|
|
146
|
-
accountEmail: doc.accountEmail,
|
|
147
|
-
enabled: doc.enabled,
|
|
148
|
-
useProduction: doc.useProduction,
|
|
149
|
-
autoRenew: doc.autoRenew,
|
|
150
|
-
renewThresholdDays: doc.renewThresholdDays,
|
|
151
|
-
updatedAt: doc.updatedAt,
|
|
152
|
-
updatedBy: doc.updatedBy,
|
|
153
|
-
};
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFuYWdlci5hY21lLWNvbmZpZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL2FjbWUvbWFuYWdlci5hY21lLWNvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3RDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUl6RDs7Ozs7Ozs7Ozs7OztHQWFHO0FBQ0gsTUFBTSxPQUFPLGlCQUFpQjtJQUdSO0lBRlosTUFBTSxHQUF1QixJQUFJLENBQUM7SUFFMUMsWUFBb0IsT0FBeUI7UUFBekIsWUFBTyxHQUFQLE9BQU8sQ0FBa0I7SUFBRyxDQUFDO0lBRTFDLEtBQUssQ0FBQyxLQUFLO1FBQ2hCLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLDZCQUE2QixDQUFDLENBQUM7UUFDbEQsSUFBSSxHQUFHLEdBQUcsTUFBTSxhQUFhLENBQUMsSUFBSSxFQUFFLENBQUM7UUFFckMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQ1QsbUVBQW1FO1lBQ25FLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1lBQzFDLElBQUksSUFBSSxFQUFFLENBQUM7Z0JBQ1QsR0FBRyxHQUFHLE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDckMsTUFBTSxDQUFDLEdBQUcsQ0FDUixNQUFNLEVBQ04sMEVBQTBFLElBQUksQ0FBQyxZQUFZLG1CQUFtQixJQUFJLENBQUMsYUFBYSxHQUFHLENBQ3BJLENBQUM7WUFDSixDQUFDO2lCQUFNLENBQUM7Z0JBQ04sTUFBTSxDQUFDLEdBQUcsQ0FDUixNQUFNLEVBQ04saUpBQWlKLENBQ2xKLENBQUM7WUFDSixDQUFDO1FBQ0gsQ0FBQzthQUFNLElBQUksSUFBSSxDQUFDLHFCQUFxQixFQUFFLEVBQUUsQ0FBQztZQUN4QyxNQUFNLENBQUMs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
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Manages certificate provisioning scheduling with:
|
|
3
|
-
* - Per-domain exponential backoff persisted via CertBackoffDoc
|
|
4
|
-
*
|
|
5
|
-
* Note: Serial stagger queue was removed — smartacme v9 handles
|
|
6
|
-
* concurrency, per-domain dedup, and rate limiting internally.
|
|
7
|
-
*/
|
|
8
|
-
export declare class CertProvisionScheduler {
|
|
9
|
-
private maxBackoffHours;
|
|
10
|
-
private backoffCache;
|
|
11
|
-
constructor(options?: {
|
|
12
|
-
maxBackoffHours?: number;
|
|
13
|
-
});
|
|
14
|
-
/**
|
|
15
|
-
* Sanitized domain key for storage lookups
|
|
16
|
-
*/
|
|
17
|
-
private sanitizeDomain;
|
|
18
|
-
/**
|
|
19
|
-
* Load backoff entry from database (with in-memory cache)
|
|
20
|
-
*/
|
|
21
|
-
private loadBackoff;
|
|
22
|
-
/**
|
|
23
|
-
* Save backoff entry to both cache and database
|
|
24
|
-
*/
|
|
25
|
-
private saveBackoff;
|
|
26
|
-
/**
|
|
27
|
-
* Check if a domain is currently in backoff.
|
|
28
|
-
* Expired entries are pruned from the cache to prevent unbounded growth.
|
|
29
|
-
*/
|
|
30
|
-
isInBackoff(domain: string): Promise<boolean>;
|
|
31
|
-
/**
|
|
32
|
-
* Record a provisioning failure for a domain.
|
|
33
|
-
* Sets exponential backoff: min(failures^2 * 1h, maxBackoffHours)
|
|
34
|
-
*/
|
|
35
|
-
recordFailure(domain: string, error?: string): Promise<void>;
|
|
36
|
-
/**
|
|
37
|
-
* Clear backoff for a domain (on success or manual override)
|
|
38
|
-
*/
|
|
39
|
-
clearBackoff(domain: string): Promise<void>;
|
|
40
|
-
/**
|
|
41
|
-
* Clear all in-memory backoff cache entries
|
|
42
|
-
*/
|
|
43
|
-
clear(): void;
|
|
44
|
-
/**
|
|
45
|
-
* Get backoff info for UI display
|
|
46
|
-
*/
|
|
47
|
-
getBackoffInfo(domain: string): Promise<{
|
|
48
|
-
failures: number;
|
|
49
|
-
retryAfter?: string;
|
|
50
|
-
lastError?: string;
|
|
51
|
-
} | null>;
|
|
52
|
-
}
|