@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
|
@@ -1,349 +0,0 @@
|
|
|
1
|
-
import * as plugins from '../plugins.js';
|
|
2
|
-
import { logger } from '../logger.js';
|
|
3
|
-
import { TargetProfileDoc, VpnClientDoc } from '../db/index.js';
|
|
4
|
-
/**
|
|
5
|
-
* Manages TargetProfiles (target-side: what can be accessed).
|
|
6
|
-
* TargetProfiles define what resources a VPN client can reach:
|
|
7
|
-
* domains, specific IP:port targets, and/or direct route references.
|
|
8
|
-
*/
|
|
9
|
-
export class TargetProfileManager {
|
|
10
|
-
profiles = new Map();
|
|
11
|
-
// =========================================================================
|
|
12
|
-
// Lifecycle
|
|
13
|
-
// =========================================================================
|
|
14
|
-
async initialize() {
|
|
15
|
-
await this.loadProfiles();
|
|
16
|
-
}
|
|
17
|
-
// =========================================================================
|
|
18
|
-
// CRUD
|
|
19
|
-
// =========================================================================
|
|
20
|
-
async createProfile(data) {
|
|
21
|
-
// Enforce unique profile names
|
|
22
|
-
for (const existing of this.profiles.values()) {
|
|
23
|
-
if (existing.name === data.name) {
|
|
24
|
-
throw new Error(`Target profile with name '${data.name}' already exists (id: ${existing.id})`);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
const id = plugins.uuid.v4();
|
|
28
|
-
const now = Date.now();
|
|
29
|
-
const profile = {
|
|
30
|
-
id,
|
|
31
|
-
name: data.name,
|
|
32
|
-
description: data.description,
|
|
33
|
-
domains: data.domains,
|
|
34
|
-
targets: data.targets,
|
|
35
|
-
routeRefs: data.routeRefs,
|
|
36
|
-
createdAt: now,
|
|
37
|
-
updatedAt: now,
|
|
38
|
-
createdBy: data.createdBy,
|
|
39
|
-
};
|
|
40
|
-
this.profiles.set(id, profile);
|
|
41
|
-
await this.persistProfile(profile);
|
|
42
|
-
logger.log('info', `Created target profile '${profile.name}' (${id})`);
|
|
43
|
-
return id;
|
|
44
|
-
}
|
|
45
|
-
async updateProfile(id, patch) {
|
|
46
|
-
const profile = this.profiles.get(id);
|
|
47
|
-
if (!profile) {
|
|
48
|
-
throw new Error(`Target profile '${id}' not found`);
|
|
49
|
-
}
|
|
50
|
-
if (patch.name !== undefined)
|
|
51
|
-
profile.name = patch.name;
|
|
52
|
-
if (patch.description !== undefined)
|
|
53
|
-
profile.description = patch.description;
|
|
54
|
-
if (patch.domains !== undefined)
|
|
55
|
-
profile.domains = patch.domains;
|
|
56
|
-
if (patch.targets !== undefined)
|
|
57
|
-
profile.targets = patch.targets;
|
|
58
|
-
if (patch.routeRefs !== undefined)
|
|
59
|
-
profile.routeRefs = patch.routeRefs;
|
|
60
|
-
profile.updatedAt = Date.now();
|
|
61
|
-
await this.persistProfile(profile);
|
|
62
|
-
logger.log('info', `Updated target profile '${profile.name}' (${id})`);
|
|
63
|
-
}
|
|
64
|
-
async deleteProfile(id, force) {
|
|
65
|
-
const profile = this.profiles.get(id);
|
|
66
|
-
if (!profile) {
|
|
67
|
-
return { success: false, message: `Target profile '${id}' not found` };
|
|
68
|
-
}
|
|
69
|
-
// Check if any VPN clients reference this profile
|
|
70
|
-
const clients = await VpnClientDoc.findAll();
|
|
71
|
-
const referencingClients = clients.filter((c) => c.targetProfileIds?.includes(id));
|
|
72
|
-
if (referencingClients.length > 0 && !force) {
|
|
73
|
-
return {
|
|
74
|
-
success: false,
|
|
75
|
-
message: `Profile '${profile.name}' is in use by ${referencingClients.length} VPN client(s). Use force=true to delete.`,
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
// Delete from DB
|
|
79
|
-
const doc = await TargetProfileDoc.findById(id);
|
|
80
|
-
if (doc)
|
|
81
|
-
await doc.delete();
|
|
82
|
-
this.profiles.delete(id);
|
|
83
|
-
if (referencingClients.length > 0) {
|
|
84
|
-
// Remove profile ref from clients
|
|
85
|
-
for (const client of referencingClients) {
|
|
86
|
-
client.targetProfileIds = client.targetProfileIds?.filter((pid) => pid !== id);
|
|
87
|
-
client.updatedAt = Date.now();
|
|
88
|
-
await client.save();
|
|
89
|
-
}
|
|
90
|
-
logger.log('warn', `Force-deleted target profile '${profile.name}'; removed refs from ${referencingClients.length} client(s)`);
|
|
91
|
-
}
|
|
92
|
-
else {
|
|
93
|
-
logger.log('info', `Deleted target profile '${profile.name}' (${id})`);
|
|
94
|
-
}
|
|
95
|
-
return { success: true };
|
|
96
|
-
}
|
|
97
|
-
getProfile(id) {
|
|
98
|
-
return this.profiles.get(id);
|
|
99
|
-
}
|
|
100
|
-
listProfiles() {
|
|
101
|
-
return [...this.profiles.values()];
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Get which VPN clients reference a target profile.
|
|
105
|
-
*/
|
|
106
|
-
async getProfileUsage(profileId) {
|
|
107
|
-
const clients = await VpnClientDoc.findAll();
|
|
108
|
-
return clients
|
|
109
|
-
.filter((c) => c.targetProfileIds?.includes(profileId))
|
|
110
|
-
.map((c) => ({ clientId: c.clientId, description: c.description }));
|
|
111
|
-
}
|
|
112
|
-
// =========================================================================
|
|
113
|
-
// Direct target IPs (bypass SmartProxy)
|
|
114
|
-
// =========================================================================
|
|
115
|
-
/**
|
|
116
|
-
* For a set of target profile IDs, collect all explicit target IPs.
|
|
117
|
-
* These IPs bypass the SmartProxy forceTarget rewrite — VPN clients can
|
|
118
|
-
* connect to them directly through the tunnel.
|
|
119
|
-
*/
|
|
120
|
-
getDirectTargetIps(targetProfileIds) {
|
|
121
|
-
const ips = new Set();
|
|
122
|
-
for (const profileId of targetProfileIds) {
|
|
123
|
-
const profile = this.profiles.get(profileId);
|
|
124
|
-
if (!profile?.targets?.length)
|
|
125
|
-
continue;
|
|
126
|
-
for (const t of profile.targets) {
|
|
127
|
-
ips.add(t.ip);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
return [...ips];
|
|
131
|
-
}
|
|
132
|
-
// =========================================================================
|
|
133
|
-
// Core matching: route → client IPs
|
|
134
|
-
// =========================================================================
|
|
135
|
-
/**
|
|
136
|
-
* For a vpnOnly route, find all enabled VPN clients whose assigned TargetProfile
|
|
137
|
-
* matches the route. Returns IP allow entries for injection into ipAllowList.
|
|
138
|
-
*
|
|
139
|
-
* Entries are domain-scoped when a profile matches via specific domains that are
|
|
140
|
-
* a subset of the route's wildcard. Plain IPs are returned for routeRef/target matches
|
|
141
|
-
* or when profile domains exactly equal the route's domains.
|
|
142
|
-
*/
|
|
143
|
-
getMatchingClientIps(route, routeId, clients) {
|
|
144
|
-
const entries = [];
|
|
145
|
-
const routeDomains = route.match?.domains || [];
|
|
146
|
-
for (const client of clients) {
|
|
147
|
-
if (!client.enabled || !client.assignedIp)
|
|
148
|
-
continue;
|
|
149
|
-
if (!client.targetProfileIds?.length)
|
|
150
|
-
continue;
|
|
151
|
-
// Collect scoped domains from all matching profiles for this client
|
|
152
|
-
let fullAccess = false;
|
|
153
|
-
const scopedDomains = new Set();
|
|
154
|
-
for (const profileId of client.targetProfileIds) {
|
|
155
|
-
const profile = this.profiles.get(profileId);
|
|
156
|
-
if (!profile)
|
|
157
|
-
continue;
|
|
158
|
-
const matchResult = this.routeMatchesProfileDetailed(route, routeId, profile, routeDomains);
|
|
159
|
-
if (matchResult === 'full') {
|
|
160
|
-
fullAccess = true;
|
|
161
|
-
break; // No need to check more profiles
|
|
162
|
-
}
|
|
163
|
-
if (matchResult !== 'none') {
|
|
164
|
-
for (const d of matchResult.domains)
|
|
165
|
-
scopedDomains.add(d);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
if (fullAccess) {
|
|
169
|
-
entries.push(client.assignedIp);
|
|
170
|
-
}
|
|
171
|
-
else if (scopedDomains.size > 0) {
|
|
172
|
-
entries.push({ ip: client.assignedIp, domains: [...scopedDomains] });
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
return entries;
|
|
176
|
-
}
|
|
177
|
-
/**
|
|
178
|
-
* For a given client (by its targetProfileIds), compute the set of
|
|
179
|
-
* domains and target IPs it can access. Used for WireGuard AllowedIPs.
|
|
180
|
-
*/
|
|
181
|
-
getClientAccessSpec(targetProfileIds, allRoutes) {
|
|
182
|
-
const domains = new Set();
|
|
183
|
-
const targetIps = new Set();
|
|
184
|
-
// Collect all access specifiers from assigned profiles
|
|
185
|
-
for (const profileId of targetProfileIds) {
|
|
186
|
-
const profile = this.profiles.get(profileId);
|
|
187
|
-
if (!profile)
|
|
188
|
-
continue;
|
|
189
|
-
// Direct domain entries
|
|
190
|
-
if (profile.domains?.length) {
|
|
191
|
-
for (const d of profile.domains) {
|
|
192
|
-
domains.add(d);
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
// Direct target IP entries
|
|
196
|
-
if (profile.targets?.length) {
|
|
197
|
-
for (const t of profile.targets) {
|
|
198
|
-
targetIps.add(t.ip);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
// Route references: scan all routes
|
|
202
|
-
for (const [routeId, route] of allRoutes) {
|
|
203
|
-
if (!route.enabled)
|
|
204
|
-
continue;
|
|
205
|
-
if (this.routeMatchesProfile(route.route, routeId, profile)) {
|
|
206
|
-
const routeDomains = route.route.match?.domains;
|
|
207
|
-
if (Array.isArray(routeDomains)) {
|
|
208
|
-
for (const d of routeDomains) {
|
|
209
|
-
domains.add(d);
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
return {
|
|
216
|
-
domains: [...domains],
|
|
217
|
-
targetIps: [...targetIps],
|
|
218
|
-
};
|
|
219
|
-
}
|
|
220
|
-
// =========================================================================
|
|
221
|
-
// Private: matching logic
|
|
222
|
-
// =========================================================================
|
|
223
|
-
/**
|
|
224
|
-
* Check if a route matches a profile (boolean convenience wrapper).
|
|
225
|
-
*/
|
|
226
|
-
routeMatchesProfile(route, routeId, profile) {
|
|
227
|
-
const routeDomains = route.match?.domains || [];
|
|
228
|
-
const result = this.routeMatchesProfileDetailed(route, routeId, profile, routeDomains);
|
|
229
|
-
return result !== 'none';
|
|
230
|
-
}
|
|
231
|
-
/**
|
|
232
|
-
* Detailed match: returns 'full' (plain IP, entire route), 'scoped' (domain-limited),
|
|
233
|
-
* or 'none' (no match).
|
|
234
|
-
*
|
|
235
|
-
* - routeRefs / target matches → 'full' (explicit reference = full access)
|
|
236
|
-
* - domain match where profile domains are a subset of route wildcard → 'scoped'
|
|
237
|
-
* - domain match where domains are identical or profile is a wildcard → 'full'
|
|
238
|
-
*/
|
|
239
|
-
routeMatchesProfileDetailed(route, routeId, profile, routeDomains) {
|
|
240
|
-
// 1. Route reference match → full access
|
|
241
|
-
if (profile.routeRefs?.length) {
|
|
242
|
-
if (routeId && profile.routeRefs.includes(routeId))
|
|
243
|
-
return 'full';
|
|
244
|
-
if (route.name && profile.routeRefs.includes(route.name))
|
|
245
|
-
return 'full';
|
|
246
|
-
}
|
|
247
|
-
// 2. Domain match
|
|
248
|
-
if (profile.domains?.length && routeDomains.length) {
|
|
249
|
-
const matchedProfileDomains = [];
|
|
250
|
-
for (const profileDomain of profile.domains) {
|
|
251
|
-
for (const routeDomain of routeDomains) {
|
|
252
|
-
if (this.domainMatchesPattern(routeDomain, profileDomain) ||
|
|
253
|
-
this.domainMatchesPattern(profileDomain, routeDomain)) {
|
|
254
|
-
matchedProfileDomains.push(profileDomain);
|
|
255
|
-
break; // This profileDomain matched, move to the next
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
if (matchedProfileDomains.length > 0) {
|
|
260
|
-
// Check if profile domains cover the route entirely (same wildcards = full access)
|
|
261
|
-
const isFullCoverage = routeDomains.every((rd) => matchedProfileDomains.some((pd) => rd === pd || this.domainMatchesPattern(rd, pd)));
|
|
262
|
-
if (isFullCoverage)
|
|
263
|
-
return 'full';
|
|
264
|
-
// Profile domains are a subset → scoped access to those specific domains
|
|
265
|
-
return { type: 'scoped', domains: matchedProfileDomains };
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
// 3. Target match (host + port) → full access (precise by nature)
|
|
269
|
-
if (profile.targets?.length) {
|
|
270
|
-
const routeTargets = route.action?.targets;
|
|
271
|
-
if (Array.isArray(routeTargets)) {
|
|
272
|
-
for (const profileTarget of profile.targets) {
|
|
273
|
-
for (const routeTarget of routeTargets) {
|
|
274
|
-
const routeHost = routeTarget.host;
|
|
275
|
-
const routePort = routeTarget.port;
|
|
276
|
-
if (routeHost === profileTarget.ip && routePort === profileTarget.port) {
|
|
277
|
-
return 'full';
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
return 'none';
|
|
284
|
-
}
|
|
285
|
-
/**
|
|
286
|
-
* Check if a domain matches a pattern.
|
|
287
|
-
* - '*.example.com' matches 'sub.example.com', 'a.b.example.com'
|
|
288
|
-
* - 'example.com' matches only 'example.com'
|
|
289
|
-
*/
|
|
290
|
-
domainMatchesPattern(domain, pattern) {
|
|
291
|
-
if (pattern === domain)
|
|
292
|
-
return true;
|
|
293
|
-
if (pattern.startsWith('*.')) {
|
|
294
|
-
const suffix = pattern.slice(1); // '.example.com'
|
|
295
|
-
return domain.endsWith(suffix) && domain.length > suffix.length;
|
|
296
|
-
}
|
|
297
|
-
return false;
|
|
298
|
-
}
|
|
299
|
-
// =========================================================================
|
|
300
|
-
// Private: persistence
|
|
301
|
-
// =========================================================================
|
|
302
|
-
async loadProfiles() {
|
|
303
|
-
const docs = await TargetProfileDoc.findAll();
|
|
304
|
-
for (const doc of docs) {
|
|
305
|
-
if (doc.id) {
|
|
306
|
-
this.profiles.set(doc.id, {
|
|
307
|
-
id: doc.id,
|
|
308
|
-
name: doc.name,
|
|
309
|
-
description: doc.description,
|
|
310
|
-
domains: doc.domains,
|
|
311
|
-
targets: doc.targets,
|
|
312
|
-
routeRefs: doc.routeRefs,
|
|
313
|
-
createdAt: doc.createdAt,
|
|
314
|
-
updatedAt: doc.updatedAt,
|
|
315
|
-
createdBy: doc.createdBy,
|
|
316
|
-
});
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
if (this.profiles.size > 0) {
|
|
320
|
-
logger.log('info', `Loaded ${this.profiles.size} target profile(s) from storage`);
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
async persistProfile(profile) {
|
|
324
|
-
const existingDoc = await TargetProfileDoc.findById(profile.id);
|
|
325
|
-
if (existingDoc) {
|
|
326
|
-
existingDoc.name = profile.name;
|
|
327
|
-
existingDoc.description = profile.description;
|
|
328
|
-
existingDoc.domains = profile.domains;
|
|
329
|
-
existingDoc.targets = profile.targets;
|
|
330
|
-
existingDoc.routeRefs = profile.routeRefs;
|
|
331
|
-
existingDoc.updatedAt = profile.updatedAt;
|
|
332
|
-
await existingDoc.save();
|
|
333
|
-
}
|
|
334
|
-
else {
|
|
335
|
-
const doc = new TargetProfileDoc();
|
|
336
|
-
doc.id = profile.id;
|
|
337
|
-
doc.name = profile.name;
|
|
338
|
-
doc.description = profile.description;
|
|
339
|
-
doc.domains = profile.domains;
|
|
340
|
-
doc.targets = profile.targets;
|
|
341
|
-
doc.routeRefs = profile.routeRefs;
|
|
342
|
-
doc.createdAt = profile.createdAt;
|
|
343
|
-
doc.updatedAt = profile.updatedAt;
|
|
344
|
-
doc.createdBy = profile.createdBy;
|
|
345
|
-
await doc.save();
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy50YXJnZXQtcHJvZmlsZS1tYW5hZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvY29uZmlnL2NsYXNzZXMudGFyZ2V0LXByb2ZpbGUtbWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGVBQWUsQ0FBQztBQUN6QyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3RDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUtoRTs7OztHQUlHO0FBQ0gsTUFBTSxPQUFPLG9CQUFvQjtJQUN2QixRQUFRLEdBQUcsSUFBSSxHQUFHLEVBQTBCLENBQUM7SUFFckQsNEVBQTRFO0lBQzVFLFlBQVk7SUFDWiw0RUFBNEU7SUFFckUsS0FBSyxDQUFDLFVBQVU7UUFDckIsTUFBTSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDNUIsQ0FBQztJQUVELDRFQUE0RTtJQUM1RSxPQUFPO0lBQ1AsNEVBQTRFO0lBRXJFLEtBQUssQ0FBQyxhQUFhLENBQUMsSUFPMUI7UUFDQywrQkFBK0I7UUFDL0IsS0FBSyxNQUFNLFFBQVEsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUM7WUFDOUMsSUFBSSxRQUFRLENBQUMsSUFBSSxLQUFLLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDaEMsTUFBTSxJQUFJLEtBQUssQ0FBQyw2QkFBNkIsSUFBSSxDQUFDLElBQUkseUJBQXlCLFFBQVEsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQ2pHLENBQUM7UUFDSCxDQUFDO1FBRUQsTUFBTSxFQUFFLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUM3QixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7UUFFdkIsTUFBTSxPQUFPLEdBQW1C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
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export * from './validator.js';
|
|
2
|
-
export { RouteConfigManager } from './classes.route-config-manager.js';
|
|
3
|
-
export { ApiTokenManager } from './classes.api-token-manager.js';
|
|
4
|
-
export { ReferenceResolver } from './classes.reference-resolver.js';
|
|
5
|
-
export { DbSeeder } from './classes.db-seeder.js';
|
|
6
|
-
export { TargetProfileManager } from './classes.target-profile-manager.js';
|
package/dist_ts/config/index.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
// Export validation tools only
|
|
2
|
-
export * from './validator.js';
|
|
3
|
-
export { RouteConfigManager } from './classes.route-config-manager.js';
|
|
4
|
-
export { ApiTokenManager } from './classes.api-token-manager.js';
|
|
5
|
-
export { ReferenceResolver } from './classes.reference-resolver.js';
|
|
6
|
-
export { DbSeeder } from './classes.db-seeder.js';
|
|
7
|
-
export { TargetProfileManager } from './classes.target-profile-manager.js';
|
|
8
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9jb25maWcvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0JBQStCO0FBQy9CLGNBQWMsZ0JBQWdCLENBQUM7QUFDL0IsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDdkUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ2pFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ3BFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQyJ9
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Validation result
|
|
3
|
-
*/
|
|
4
|
-
export interface IValidationResult {
|
|
5
|
-
/**
|
|
6
|
-
* Whether the validation passed
|
|
7
|
-
*/
|
|
8
|
-
valid: boolean;
|
|
9
|
-
/**
|
|
10
|
-
* Validation errors if any
|
|
11
|
-
*/
|
|
12
|
-
errors?: string[];
|
|
13
|
-
/**
|
|
14
|
-
* Validated configuration (may include defaults)
|
|
15
|
-
*/
|
|
16
|
-
config?: any;
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Validation schema types
|
|
20
|
-
*/
|
|
21
|
-
export type ValidationSchema = Record<string, {
|
|
22
|
-
/**
|
|
23
|
-
* Type of the value
|
|
24
|
-
*/
|
|
25
|
-
type: 'string' | 'number' | 'boolean' | 'object' | 'array';
|
|
26
|
-
/**
|
|
27
|
-
* Whether the field is required
|
|
28
|
-
*/
|
|
29
|
-
required?: boolean;
|
|
30
|
-
/**
|
|
31
|
-
* Default value if not specified
|
|
32
|
-
*/
|
|
33
|
-
default?: any;
|
|
34
|
-
/**
|
|
35
|
-
* Minimum value (for numbers)
|
|
36
|
-
*/
|
|
37
|
-
min?: number;
|
|
38
|
-
/**
|
|
39
|
-
* Maximum value (for numbers)
|
|
40
|
-
*/
|
|
41
|
-
max?: number;
|
|
42
|
-
/**
|
|
43
|
-
* Minimum length (for strings or arrays)
|
|
44
|
-
*/
|
|
45
|
-
minLength?: number;
|
|
46
|
-
/**
|
|
47
|
-
* Maximum length (for strings or arrays)
|
|
48
|
-
*/
|
|
49
|
-
maxLength?: number;
|
|
50
|
-
/**
|
|
51
|
-
* Pattern to match (for strings)
|
|
52
|
-
*/
|
|
53
|
-
pattern?: RegExp;
|
|
54
|
-
/**
|
|
55
|
-
* Allowed values (for strings, numbers)
|
|
56
|
-
*/
|
|
57
|
-
enum?: any[];
|
|
58
|
-
/**
|
|
59
|
-
* Nested schema (for objects)
|
|
60
|
-
*/
|
|
61
|
-
schema?: ValidationSchema;
|
|
62
|
-
/**
|
|
63
|
-
* Item schema (for arrays)
|
|
64
|
-
*/
|
|
65
|
-
items?: {
|
|
66
|
-
type: 'string' | 'number' | 'boolean' | 'object';
|
|
67
|
-
schema?: ValidationSchema;
|
|
68
|
-
};
|
|
69
|
-
/**
|
|
70
|
-
* Custom validation function
|
|
71
|
-
*/
|
|
72
|
-
validate?: (value: any) => boolean | string;
|
|
73
|
-
}>;
|
|
74
|
-
/**
|
|
75
|
-
* Configuration validator
|
|
76
|
-
* Validates configuration objects against schemas and provides default values
|
|
77
|
-
*/
|
|
78
|
-
export declare class ConfigValidator {
|
|
79
|
-
/**
|
|
80
|
-
* Validate a configuration object against a schema
|
|
81
|
-
*
|
|
82
|
-
* @param config Configuration object to validate
|
|
83
|
-
* @param schema Validation schema
|
|
84
|
-
* @returns Validation result
|
|
85
|
-
*/
|
|
86
|
-
static validate<T>(config: T, schema: ValidationSchema): IValidationResult;
|
|
87
|
-
/**
|
|
88
|
-
* Apply defaults to a configuration object based on a schema
|
|
89
|
-
*
|
|
90
|
-
* @param config Configuration object to apply defaults to
|
|
91
|
-
* @param schema Validation schema with defaults
|
|
92
|
-
* @returns Configuration with defaults applied
|
|
93
|
-
*/
|
|
94
|
-
static applyDefaults<T>(config: T, schema: ValidationSchema): T;
|
|
95
|
-
/**
|
|
96
|
-
* Throw a validation error if the configuration is invalid
|
|
97
|
-
*
|
|
98
|
-
* @param config Configuration to validate
|
|
99
|
-
* @param schema Validation schema
|
|
100
|
-
* @returns Validated configuration with defaults
|
|
101
|
-
* @throws ValidationError if validation fails
|
|
102
|
-
*/
|
|
103
|
-
static validateOrThrow<T>(config: T, schema: ValidationSchema): T;
|
|
104
|
-
}
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
import * as plugins from '../plugins.js';
|
|
2
|
-
import { ValidationError } from '../errors/base.errors.js';
|
|
3
|
-
/**
|
|
4
|
-
* Configuration validator
|
|
5
|
-
* Validates configuration objects against schemas and provides default values
|
|
6
|
-
*/
|
|
7
|
-
export class ConfigValidator {
|
|
8
|
-
/**
|
|
9
|
-
* Validate a configuration object against a schema
|
|
10
|
-
*
|
|
11
|
-
* @param config Configuration object to validate
|
|
12
|
-
* @param schema Validation schema
|
|
13
|
-
* @returns Validation result
|
|
14
|
-
*/
|
|
15
|
-
static validate(config, schema) {
|
|
16
|
-
const errors = [];
|
|
17
|
-
const validatedConfig = { ...config };
|
|
18
|
-
// Validate each field against the schema
|
|
19
|
-
for (const [key, rules] of Object.entries(schema)) {
|
|
20
|
-
const value = config[key];
|
|
21
|
-
// Check if required
|
|
22
|
-
if (rules.required && (value === undefined || value === null)) {
|
|
23
|
-
errors.push(`${key} is required`);
|
|
24
|
-
continue;
|
|
25
|
-
}
|
|
26
|
-
// If not present and not required, apply default if available
|
|
27
|
-
if ((value === undefined || value === null)) {
|
|
28
|
-
if (rules.default !== undefined) {
|
|
29
|
-
validatedConfig[key] = rules.default;
|
|
30
|
-
}
|
|
31
|
-
continue;
|
|
32
|
-
}
|
|
33
|
-
// Type validation
|
|
34
|
-
if (value !== undefined && value !== null) {
|
|
35
|
-
const valueType = Array.isArray(value) ? 'array' : typeof value;
|
|
36
|
-
if (valueType !== rules.type) {
|
|
37
|
-
errors.push(`${key} must be of type ${rules.type}, got ${valueType}`);
|
|
38
|
-
continue;
|
|
39
|
-
}
|
|
40
|
-
// Type-specific validations
|
|
41
|
-
switch (rules.type) {
|
|
42
|
-
case 'number':
|
|
43
|
-
if (rules.min !== undefined && value < rules.min) {
|
|
44
|
-
errors.push(`${key} must be at least ${rules.min}`);
|
|
45
|
-
}
|
|
46
|
-
if (rules.max !== undefined && value > rules.max) {
|
|
47
|
-
errors.push(`${key} must be at most ${rules.max}`);
|
|
48
|
-
}
|
|
49
|
-
break;
|
|
50
|
-
case 'string':
|
|
51
|
-
if (rules.minLength !== undefined && value.length < rules.minLength) {
|
|
52
|
-
errors.push(`${key} must be at least ${rules.minLength} characters`);
|
|
53
|
-
}
|
|
54
|
-
if (rules.maxLength !== undefined && value.length > rules.maxLength) {
|
|
55
|
-
errors.push(`${key} must be at most ${rules.maxLength} characters`);
|
|
56
|
-
}
|
|
57
|
-
if (rules.pattern && !rules.pattern.test(value)) {
|
|
58
|
-
errors.push(`${key} must match pattern ${rules.pattern}`);
|
|
59
|
-
}
|
|
60
|
-
break;
|
|
61
|
-
case 'array':
|
|
62
|
-
if (rules.minLength !== undefined && value.length < rules.minLength) {
|
|
63
|
-
errors.push(`${key} must have at least ${rules.minLength} items`);
|
|
64
|
-
}
|
|
65
|
-
if (rules.maxLength !== undefined && value.length > rules.maxLength) {
|
|
66
|
-
errors.push(`${key} must have at most ${rules.maxLength} items`);
|
|
67
|
-
}
|
|
68
|
-
if (rules.items && value.length > 0) {
|
|
69
|
-
for (let i = 0; i < value.length; i++) {
|
|
70
|
-
const itemType = Array.isArray(value[i]) ? 'array' : typeof value[i];
|
|
71
|
-
if (itemType !== rules.items.type) {
|
|
72
|
-
errors.push(`${key}[${i}] must be of type ${rules.items.type}, got ${itemType}`);
|
|
73
|
-
}
|
|
74
|
-
else if (rules.items.schema && itemType === 'object') {
|
|
75
|
-
const itemResult = this.validate(value[i], rules.items.schema);
|
|
76
|
-
if (!itemResult.valid) {
|
|
77
|
-
errors.push(...itemResult.errors.map(err => `${key}[${i}].${err}`));
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
break;
|
|
83
|
-
case 'object':
|
|
84
|
-
if (rules.schema) {
|
|
85
|
-
const nestedResult = this.validate(value, rules.schema);
|
|
86
|
-
if (!nestedResult.valid) {
|
|
87
|
-
errors.push(...nestedResult.errors.map(err => `${key}.${err}`));
|
|
88
|
-
}
|
|
89
|
-
validatedConfig[key] = nestedResult.config;
|
|
90
|
-
}
|
|
91
|
-
break;
|
|
92
|
-
}
|
|
93
|
-
// Enum validation
|
|
94
|
-
if (rules.enum && !rules.enum.includes(value)) {
|
|
95
|
-
errors.push(`${key} must be one of [${rules.enum.join(', ')}]`);
|
|
96
|
-
}
|
|
97
|
-
// Custom validation
|
|
98
|
-
if (rules.validate) {
|
|
99
|
-
const result = rules.validate(value);
|
|
100
|
-
if (result !== true) {
|
|
101
|
-
errors.push(typeof result === 'string' ? result : `${key} failed custom validation`);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
return {
|
|
107
|
-
valid: errors.length === 0,
|
|
108
|
-
errors: errors.length > 0 ? errors : undefined,
|
|
109
|
-
config: validatedConfig
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* Apply defaults to a configuration object based on a schema
|
|
114
|
-
*
|
|
115
|
-
* @param config Configuration object to apply defaults to
|
|
116
|
-
* @param schema Validation schema with defaults
|
|
117
|
-
* @returns Configuration with defaults applied
|
|
118
|
-
*/
|
|
119
|
-
static applyDefaults(config, schema) {
|
|
120
|
-
const result = { ...config };
|
|
121
|
-
for (const [key, rules] of Object.entries(schema)) {
|
|
122
|
-
if (result[key] === undefined && rules.default !== undefined) {
|
|
123
|
-
result[key] = rules.default;
|
|
124
|
-
}
|
|
125
|
-
// Apply defaults to nested objects
|
|
126
|
-
if (result[key] && rules.type === 'object' && rules.schema) {
|
|
127
|
-
result[key] = this.applyDefaults(result[key], rules.schema);
|
|
128
|
-
}
|
|
129
|
-
// Apply defaults to array items
|
|
130
|
-
if (result[key] && rules.type === 'array' && rules.items && rules.items.schema) {
|
|
131
|
-
result[key] = result[key].map(item => typeof item === 'object' ? this.applyDefaults(item, rules.items.schema) : item);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
return result;
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Throw a validation error if the configuration is invalid
|
|
138
|
-
*
|
|
139
|
-
* @param config Configuration to validate
|
|
140
|
-
* @param schema Validation schema
|
|
141
|
-
* @returns Validated configuration with defaults
|
|
142
|
-
* @throws ValidationError if validation fails
|
|
143
|
-
*/
|
|
144
|
-
static validateOrThrow(config, schema) {
|
|
145
|
-
const result = this.validate(config, schema);
|
|
146
|
-
if (!result.valid) {
|
|
147
|
-
throw new ValidationError(`Configuration validation failed: ${result.errors.join(', ')}`, 'CONFIG_VALIDATION_ERROR', { data: { errors: result.errors } });
|
|
148
|
-
}
|
|
149
|
-
return result.config;
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvY29uZmlnL3ZhbGlkYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGVBQWUsQ0FBQztBQUN6QyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUEwRjNEOzs7R0FHRztBQUNILE1BQU0sT0FBTyxlQUFlO0lBRTFCOzs7Ozs7T0FNRztJQUNJLE1BQU0sQ0FBQyxRQUFRLENBQUksTUFBUyxFQUFFLE1BQXdCO1FBQzNELE1BQU0sTUFBTSxHQUFhLEVBQUUsQ0FBQztRQUM1QixNQUFNLGVBQWUsR0FBRyxFQUFFLEdBQUcsTUFBTSxFQUFFLENBQUM7UUFFdEMseUNBQXlDO1FBQ3pDLEtBQUssTUFBTSxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7WUFDbEQsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBRTFCLG9CQUFvQjtZQUNwQixJQUFJLEtBQUssQ0FBQyxRQUFRLElBQUksQ0FBQyxLQUFLLEtBQUssU0FBUyxJQUFJLEtBQUssS0FBSyxJQUFJLENBQUMsRUFBRSxDQUFDO2dCQUM5RCxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxjQUFjLENBQUMsQ0FBQztnQkFDbEMsU0FBUztZQUNYLENBQUM7WUFFRCw4REFBOEQ7WUFDOUQsSUFBSSxDQUFDLEtBQUssS0FBSyxTQUFTLElBQUksS0FBSyxLQUFLLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQzVDLElBQUksS0FBSyxDQUFDLE9BQU8sS0FBSyxTQUFTLEVBQUUsQ0FBQztvQkFDaEMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUM7Z0JBQ3ZDLENBQUM7Z0JBQ0QsU0FBUztZQUNYLENBQUM7WUFFRCxr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
|