@undefineds.co/xpod 0.4.13 → 0.4.15
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/config/cloud.json +0 -3
- package/config/components-ignore.json +11 -7
- package/config/local.json +0 -3
- package/config/xpod.base.json +0 -24
- package/dist/api/ai-config/AiConfigStore.d.ts +2 -2
- package/dist/api/ai-config/AiConfigStore.js +4 -1
- package/dist/api/ai-gateway/auth/CallerPodAccess.d.ts +2 -5
- package/dist/api/ai-gateway/auth/CallerPodAccess.js +3 -42
- package/dist/api/ai-gateway/auth/GatewayApiKeyAuthenticator.d.ts +2 -1
- package/dist/api/ai-gateway/auth/GatewayApiKeyAuthenticator.js +1 -1
- package/dist/api/ai-gateway/auth/PodGatewayAccessKeyRepository.d.ts +3 -8
- package/dist/api/ai-gateway/auth/PodGatewayAccessKeyRepository.js +9 -32
- package/dist/api/ai-gateway/connect/index.d.ts +3 -3
- package/dist/api/ai-gateway/connect/index.js +9 -38
- package/dist/api/ai-gateway/errors.js +2 -1
- package/dist/api/ai-gateway/models/PodModelSelectionRepository.d.ts +3 -3
- package/dist/api/ai-gateway/models/PodModelSelectionRepository.js +7 -11
- package/dist/api/ai-gateway/pod/HostedPodRoute.d.ts +27 -0
- package/dist/api/ai-gateway/pod/HostedPodRoute.js +47 -0
- package/dist/api/ai-gateway/pod/OwnerPodAccess.d.ts +79 -0
- package/dist/api/ai-gateway/pod/OwnerPodAccess.js +192 -0
- package/dist/api/ai-gateway/pod/PodInterfaceKeyStore.d.ts +52 -0
- package/dist/api/ai-gateway/pod/PodInterfaceKeyStore.js +61 -0
- package/dist/api/ai-gateway/providers/ProviderRegistry.js +1 -1
- package/dist/api/ai-gateway/quota/ProviderQuotaAdapter.d.ts +3 -3
- package/dist/api/ai-gateway/quota/ProviderQuotaAdapter.js +7 -32
- package/dist/api/ai-gateway/service-access/AiConnectionsServiceAccess.d.ts +1 -1
- package/dist/api/ai-gateway/service-access/AiConnectionsServiceAccess.js +1 -1
- package/dist/api/auth/ClientCredentialsAuthenticator.js +5 -28
- package/dist/api/auth/TokenEndpointRoute.d.ts +18 -0
- package/dist/api/auth/TokenEndpointRoute.js +36 -0
- package/dist/api/chatkit/pod-store.d.ts +4 -4
- package/dist/api/chatkit/pod-store.js +24 -95
- package/dist/api/container/common.js +36 -23
- package/dist/api/container/index.js +1 -0
- package/dist/api/container/local.js +88 -37
- package/dist/api/container/routes.js +41 -7
- package/dist/api/container/types.d.ts +4 -2
- package/dist/api/handlers/AdminHandler.d.ts +17 -1
- package/dist/api/handlers/AdminHandler.js +40 -3
- package/dist/api/handlers/AiGatewayManagementHandler.d.ts +6 -0
- package/dist/api/handlers/AiGatewayManagementHandler.js +17 -4
- package/dist/api/handlers/EdgeNodeSignalHandler.js +10 -2
- package/dist/api/handlers/NetworkSettingsHandler.d.ts +44 -5
- package/dist/api/handlers/NetworkSettingsHandler.js +46 -11
- package/dist/api/handlers/PodSettingsHandler.d.ts +3 -3
- package/dist/api/handlers/PodSettingsHandler.js +3 -3
- package/dist/api/handlers/ProvisionHandler.d.ts +35 -1
- package/dist/api/handlers/ProvisionHandler.js +53 -2
- package/dist/api/handlers/ReachabilityHandler.d.ts +6 -0
- package/dist/api/handlers/ReachabilityHandler.js +25 -6
- package/dist/api/network/NetworkEnvironmentConfigurationStore.d.ts +6 -1
- package/dist/api/network/NetworkEnvironmentConfigurationStore.js +72 -16
- package/dist/api/runtime.d.ts +18 -0
- package/dist/api/runtime.js +28 -2
- package/dist/api/service/AiClientConfigurationService.d.ts +1 -1
- package/dist/api/service/AiClientConfigurationService.js +1 -1
- package/dist/cli/commands/start.d.ts +26 -1
- package/dist/cli/commands/start.js +69 -5
- package/dist/components/components.jsonld +1 -1
- package/dist/components/context.jsonld +35 -42
- package/dist/edge/EdgeNodeAgent.d.ts +16 -0
- package/dist/edge/EdgeNodeAgent.js +56 -1
- package/dist/edge/EdgeNodeAgent.jsonld +8 -0
- package/dist/edge/EdgeNodeAgentInitializer.d.ts +2 -0
- package/dist/edge/EdgeNodeAgentInitializer.js +1 -0
- package/dist/edge/EdgeNodeAgentInitializer.jsonld +19 -0
- package/dist/edge/EdgeNodeDnsCoordinator.d.ts +11 -1
- package/dist/edge/EdgeNodeDnsCoordinator.js +12 -2
- package/dist/edge/EdgeNodeHealthProbeService.d.ts +15 -0
- package/dist/edge/EdgeNodeHealthProbeService.js +44 -12
- package/dist/edge/EdgeNodeHealthProbeService.jsonld +77 -0
- package/dist/edge/ProbeTargetGuard.d.ts +35 -0
- package/dist/edge/ProbeTargetGuard.js +142 -0
- package/dist/edge/reachability/NodeAccessResolver.d.ts +16 -0
- package/dist/edge/reachability/NodeAccessResolver.js +30 -0
- package/dist/edge/reachability/ReachabilitySessionService.js +4 -1
- package/dist/edge/reachability/RouteSetBuilder.d.ts +18 -1
- package/dist/edge/reachability/RouteSetBuilder.js +47 -0
- package/dist/edge/reachability/RouteSetBuilder.jsonld +29 -0
- package/dist/edge/reachability/types.d.ts +8 -2
- package/dist/http/SubgraphSparqlHttpHandler.d.ts +1 -25
- package/dist/http/SubgraphSparqlHttpHandler.js +0 -100
- package/dist/http/SubgraphSparqlHttpHandler.jsonld +0 -8
- package/dist/identity/drizzle/PodInterfaceKeyRepository.d.ts +33 -0
- package/dist/identity/drizzle/PodInterfaceKeyRepository.js +78 -0
- package/dist/identity/drizzle/db.d.ts +7 -0
- package/dist/identity/drizzle/db.js +30 -0
- package/dist/identity/drizzle/schema.pg.d.ts +9 -0
- package/dist/identity/drizzle/schema.pg.js +16 -1
- package/dist/identity/drizzle/schema.sqlite.d.ts +106 -0
- package/dist/identity/drizzle/schema.sqlite.js +16 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +9 -5
- package/dist/main.js +7 -0
- package/dist/runtime/GatewayAdminProxyAuth.d.ts +1 -16
- package/dist/runtime/GatewayAdminProxyAuth.js +2 -71
- package/dist/runtime/Proxy.d.ts +32 -1
- package/dist/runtime/Proxy.js +125 -31
- package/dist/runtime/bootstrap.d.ts +21 -0
- package/dist/runtime/bootstrap.js +45 -1
- package/dist/runtime/css-process.d.ts +1 -0
- package/dist/runtime/css-process.js +1 -0
- package/dist/runtime/host/node/NodeRuntimeHost.js +6 -1
- package/dist/runtime/host/types.d.ts +6 -0
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.js +4 -1
- package/dist/runtime/js-runtime.js +10 -3
- package/dist/runtime/lifecycle.js +6 -4
- package/dist/runtime/port-finder.d.ts +26 -0
- package/dist/runtime/port-finder.js +64 -0
- package/dist/runtime/runner/node/NodeGatewayRuntimeRunner.js +1 -0
- package/dist/runtime/runner/types.d.ts +5 -0
- package/dist/runtime/runtime-types.d.ts +1 -0
- package/dist/test-utils/local-managed-client-p2p-e2e-smoke.js +1 -1
- package/dist/tunnel/AutoTunnelProvider.d.ts +56 -0
- package/dist/tunnel/AutoTunnelProvider.js +181 -0
- package/dist/tunnel/LocalTunnelProvider.d.ts +15 -0
- package/dist/tunnel/LocalTunnelProvider.js +87 -18
- package/dist/tunnel/LocalTunnelProvider.jsonld +27 -0
- package/dist/tunnel/NgrokTunnelProvider.d.ts +4 -0
- package/dist/tunnel/NgrokTunnelProvider.js +117 -43
- package/dist/tunnel/NgrokTunnelProvider.jsonld +4 -0
- package/dist/tunnel/SakuraFrpTunnelProvider.d.ts +65 -3
- package/dist/tunnel/SakuraFrpTunnelProvider.js +268 -25
- package/dist/tunnel/TunnelLifecycle.d.ts +14 -0
- package/dist/tunnel/TunnelLifecycle.js +34 -0
- package/dist/tunnel/TunnelProfiles.d.ts +33 -3
- package/dist/tunnel/TunnelProfiles.js +105 -78
- package/dist/tunnel/TunnelProvider.d.ts +15 -2
- package/dist/tunnel/TunnelProvider.jsonld +8 -0
- package/dist/tunnel/TunnelProviderCatalog.d.ts +62 -0
- package/dist/tunnel/TunnelProviderCatalog.js +130 -0
- package/dist/tunnel/index.d.ts +1 -0
- package/dist/tunnel/index.js +3 -1
- package/node_modules/@undefineds.co/ai-connections/dist/AiApiKeyPool.d.ts +1 -1
- package/node_modules/@undefineds.co/ai-connections/dist/AiApiKeyPool.js +1 -1
- package/node_modules/@undefineds.co/ai-connections/dist/AiAuthorizationActions.d.ts +1 -1
- package/node_modules/@undefineds.co/ai-connections/dist/AiClientConfigurationSection.d.ts +1 -1
- package/node_modules/@undefineds.co/ai-connections/dist/AiClientConfigurationSection.js +1 -1
- package/node_modules/@undefineds.co/ai-connections/dist/AiConnectDialog.d.ts +1 -1
- package/node_modules/@undefineds.co/ai-connections/dist/AiConnectionsPanel.d.ts +1 -1
- package/node_modules/@undefineds.co/ai-connections/dist/AiCredentialPoolSection.d.ts +1 -1
- package/node_modules/@undefineds.co/ai-connections/dist/AiCredentialRow.d.ts +1 -1
- package/node_modules/@undefineds.co/ai-connections/dist/AiCustomProviderDialog.d.ts +1 -1
- package/node_modules/@undefineds.co/ai-connections/dist/AiGatewayKeyRow.d.ts +1 -1
- package/node_modules/@undefineds.co/ai-connections/dist/AiGatewayKeysSection.d.ts +1 -1
- package/node_modules/@undefineds.co/ai-connections/dist/AiGatewayModelsSection.d.ts +1 -1
- package/node_modules/@undefineds.co/ai-connections/dist/AiOfferingDetails.d.ts +1 -1
- package/node_modules/@undefineds.co/ai-connections/dist/AiProviderCard.d.ts +1 -1
- package/node_modules/@undefineds.co/ai-connections/dist/AiQuotaCard.d.ts +1 -1
- package/node_modules/@undefineds.co/ai-connections/dist/AiSortableCredentialList.d.ts +1 -1
- package/node_modules/@undefineds.co/ai-connections/dist/authorization-methods.d.ts +1 -1
- package/node_modules/@undefineds.co/ai-connections/dist/collection-runtime.d.ts +1 -1
- package/node_modules/@undefineds.co/ai-connections/dist/collection-runtime.js +3 -3
- package/node_modules/@undefineds.co/ai-connections/dist/collections.d.ts +1 -1
- package/node_modules/@undefineds.co/ai-connections/dist/collections.js +3 -3
- package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/ai-connections-client.d.ts +1 -1
- package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/ai-connections-client.js +1 -1
- package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client-config/index.cjs +8 -8
- package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/index.d.ts +1 -1
- package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/index.js +1 -1
- package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/provider-catalog.cjs +3 -3
- package/node_modules/@undefineds.co/ai-connections/dist/controller.d.ts +1 -1
- package/node_modules/@undefineds.co/ai-connections/dist/controller.js +1 -1
- package/node_modules/@undefineds.co/ai-connections/dist/credential-labels.d.ts +1 -1
- package/node_modules/@undefineds.co/ai-connections/dist/display-wording.d.ts +1 -1
- package/node_modules/@undefineds.co/ai-connections/dist/error-wording.d.ts +1 -1
- package/node_modules/@undefineds.co/ai-connections/dist/error-wording.js +8 -3
- package/node_modules/@undefineds.co/ai-connections/dist/gateway-endpoints.js +1 -1
- package/node_modules/@undefineds.co/ai-connections/dist/offering-endpoints.d.ts +1 -1
- package/node_modules/@undefineds.co/ai-connections/dist/offering-label.d.ts +1 -1
- package/node_modules/@undefineds.co/ai-connections/dist/provider-visuals.d.ts +1 -1
- package/node_modules/@undefineds.co/ai-connections/dist/service-access.js +1 -1
- package/node_modules/@undefineds.co/ai-connections/dist/useAiConnectDialog.d.ts +1 -1
- package/node_modules/@undefineds.co/ai-connections/package.json +31 -1
- package/node_modules/@undefineds.co/solid-sdk/dist/access-route.cjs +230 -0
- package/node_modules/@undefineds.co/solid-sdk/dist/access-route.d.ts +76 -0
- package/node_modules/@undefineds.co/solid-sdk/dist/access-route.js +115 -0
- package/node_modules/@undefineds.co/solid-sdk/dist/index.cjs +89 -0
- package/node_modules/@undefineds.co/solid-sdk/dist/index.d.ts +1 -0
- package/node_modules/@undefineds.co/solid-sdk/dist/index.js +1 -0
- package/node_modules/@undefineds.co/solid-sdk/package.json +6 -1
- package/package.json +5 -6
- package/static/app/assets/inrupt-smoke.js +23 -23
- package/static/app/assets/main.css +1 -1
- package/static/auth-callback/assets/{AiConfigContext-DlFyEWy9.js → AiConfigContext-Bx0HCAW5.js} +1 -1
- package/static/auth-callback/assets/{AiConfigPage-CkYk-SFW.js → AiConfigPage-ChQImMbm.js} +1 -1
- package/static/auth-callback/assets/{DocumentProcessingPanel-CqIr3JqN.js → DocumentProcessingPanel-D830H4SH.js} +1 -1
- package/static/auth-callback/assets/{IndexLifecyclePanel-C1GKV3Vx.js → IndexLifecyclePanel-CnlkjMF8.js} +1 -1
- package/static/auth-callback/assets/{IndexSubjectPanel-ro9lC6XW.js → IndexSubjectPanel-CdEfg_CO.js} +1 -1
- package/static/auth-callback/assets/{ModelAssignmentsPanel-DxNdyKRJ.js → ModelAssignmentsPanel-D-8A8dZx.js} +1 -1
- package/static/auth-callback/assets/{ModelsPage-BVtWSPBU.js → ModelsPage-Cim7cubp.js} +3 -3
- package/static/auth-callback/assets/NetworkPage-CfK3x-pb.js +2 -0
- package/static/auth-callback/assets/{PaneListHeader-ByKw8ada.js → PaneListHeader-Bf_kEd4U.js} +1 -1
- package/static/auth-callback/assets/{SearchIndexingPanel-CulBKcYT.js → SearchIndexingPanel-4kD4RBEQ.js} +1 -1
- package/static/auth-callback/assets/{StatusSubjectPanel-VOcfrt8o.js → StatusSubjectPanel-Bw9AiTSf.js} +1 -1
- package/static/auth-callback/assets/{StatusWorkspace-Jsz6hAdE.js → StatusWorkspace-C-301H-0.js} +1 -1
- package/static/auth-callback/assets/{SystemSettingsPage-BFNvGAle.js → SystemSettingsPage-BbWn-eG6.js} +1 -1
- package/static/auth-callback/assets/{SystemSettingsSubjectPanel-DFRdrSfK.js → SystemSettingsSubjectPanel-DA4wvNSm.js} +1 -1
- package/static/auth-callback/assets/{XpodAiConnectionsPodStore-C6KpvHVg.js → XpodAiConnectionsPodStore-CohdyLoX.js} +1 -1
- package/static/auth-callback/assets/{activity-DnTlb9iM.js → activity-CCsb9Oam.js} +1 -1
- package/static/auth-callback/assets/ai-connections-DexTPyfC.js +1 -0
- package/static/auth-callback/assets/{auth-callback-D2UkK5Xj.js → auth-callback-Ds-c62W3.js} +5 -5
- package/static/auth-callback/assets/auth-callback-rk080mvG.css +1 -0
- package/static/auth-callback/assets/{badge-D7IJuuTM.js → badge-CQm5OyzR.js} +1 -1
- package/static/auth-callback/assets/{collection-runtime-wT1n4GS2.js → collection-runtime-DlAuU5TW.js} +1 -1
- package/static/auth-callback/assets/{dialog-DickLu5z.js → dialog-CnGzg5Ff.js} +1 -1
- package/static/auth-callback/assets/{download-kn8WnRu3.js → download-DwMONJvm.js} +1 -1
- package/static/auth-callback/assets/{external-link-B6B8jfSn.js → external-link-Bu5AGqCO.js} +1 -1
- package/static/auth-callback/assets/{index-DHF97YLP.js → index-B0T-1YO8.js} +1 -1
- package/static/auth-callback/assets/{index-Dz83EEHD.js → index-C8QZf_4W.js} +1 -1
- package/static/auth-callback/assets/index-DwIlrIDG.js +4 -0
- package/static/auth-callback/assets/{index-browser-CSghinyi.js → index-browser-lRsMcP_7.js} +1 -1
- package/static/auth-callback/assets/{key-round-ChkOx3E1.js → key-round-BDMtU57P.js} +1 -1
- package/static/auth-callback/assets/{rotate-ccw-B3hE-nyd.js → rotate-ccw-CoKIGCsQ.js} +1 -1
- package/static/auth-callback/assets/{skeleton-kEqR7tpI.js → skeleton-CPoSWHDr.js} +1 -1
- package/static/auth-callback/assets/{waypoints-D6Jo-SZa.js → waypoints-BeYHxqHv.js} +1 -1
- package/static/auth-callback/assets/{workspace-layout-BHwT_cHd.js → workspace-layout-xA5YxiK3.js} +1 -1
- package/static/auth-callback/auth-callback.html +2 -2
- package/static/dashboard/assets/{AiConfigContext-BfC3v-x2.js → AiConfigContext-rWx4TyiH.js} +1 -1
- package/static/dashboard/assets/{AiConfigPage-QNS3u7Ff.js → AiConfigPage-StVJpDFT.js} +1 -1
- package/static/dashboard/assets/{DocumentProcessingPanel-Dr4XLeT4.js → DocumentProcessingPanel-DJ5yul2O.js} +1 -1
- package/static/dashboard/assets/{IndexLifecyclePanel-KtM_gpeO.js → IndexLifecyclePanel-CpjtgezK.js} +1 -1
- package/static/dashboard/assets/{IndexSubjectPanel-DLaiKdLc.js → IndexSubjectPanel-BVKcot1_.js} +1 -1
- package/static/dashboard/assets/{ModelAssignmentsPanel-Bk7TvQRq.js → ModelAssignmentsPanel-BxVgWZPc.js} +1 -1
- package/static/dashboard/assets/{ModelsPage-Cci3vlos.js → ModelsPage-CECBwmeO.js} +3 -3
- package/static/dashboard/assets/NetworkPage-zQgFscEW.js +2 -0
- package/static/dashboard/assets/{PaneListHeader-qHME_s08.js → PaneListHeader-DIPe8pS6.js} +1 -1
- package/static/dashboard/assets/{SearchIndexingPanel-HZPKj8H9.js → SearchIndexingPanel-lalFJ3c8.js} +1 -1
- package/static/dashboard/assets/{StatusSubjectPanel-ij7IpI8d.js → StatusSubjectPanel-CpY_KU-G.js} +1 -1
- package/static/dashboard/assets/{StatusWorkspace-Cp02JcaN.js → StatusWorkspace-BwWCii3A.js} +1 -1
- package/static/dashboard/assets/{SystemSettingsPage-BSeuvb8X.js → SystemSettingsPage-BKZxX-_n.js} +1 -1
- package/static/dashboard/assets/{SystemSettingsSubjectPanel-CP4_luGS.js → SystemSettingsSubjectPanel-BZrqb2C5.js} +1 -1
- package/static/dashboard/assets/{XpodAiConnectionsPodStore-urO6zaHL.js → XpodAiConnectionsPodStore-Bbpx9dTN.js} +1 -1
- package/static/dashboard/assets/{activity-DxjgQNvr.js → activity-BJ15TLVP.js} +1 -1
- package/static/dashboard/assets/ai-connections-GG6qkTJt.js +1 -0
- package/static/dashboard/assets/{badge-53qCrRbl.js → badge-BBX5FlaB.js} +1 -1
- package/static/dashboard/assets/{collection-runtime-BPAmHG46.js → collection-runtime-UBbHBzdf.js} +1 -1
- package/static/dashboard/assets/{dashboard-BcT2ByXw.js → dashboard-7Y6BHyV9.js} +62 -62
- package/static/dashboard/assets/dashboard-rk080mvG.css +1 -0
- package/static/dashboard/assets/{dialog-B28YtNhS.js → dialog-QrOJ-hB0.js} +1 -1
- package/static/dashboard/assets/{download-DkLNceJ4.js → download-DK9x-VOP.js} +1 -1
- package/static/dashboard/assets/{external-link-D3TXnlo3.js → external-link-Cnkn87mJ.js} +1 -1
- package/static/dashboard/assets/index-B1z84it5.js +4 -0
- package/static/dashboard/assets/{index-CIiBu9mr.js → index-DzjauX3N.js} +1 -1
- package/static/dashboard/assets/{index-CFIenkeK.js → index-cIa8_efI.js} +1 -1
- package/static/dashboard/assets/{key-round-B5ccp6nx.js → key-round-BoS6UqKz.js} +1 -1
- package/static/dashboard/assets/{rotate-ccw-DUpfkNnk.js → rotate-ccw-BeWV76i0.js} +1 -1
- package/static/dashboard/assets/{skeleton-BRe19fO0.js → skeleton-CypcJL07.js} +1 -1
- package/static/dashboard/assets/{waypoints-BKDMxEvu.js → waypoints-zHOOqfhi.js} +1 -1
- package/static/dashboard/assets/{workspace-layout-ZTF7C16h.js → workspace-layout-DZ9JuxnM.js} +1 -1
- package/static/dashboard/dashboard.html +2 -2
- package/static/settings/assets/{AiConfigContext-DsyWgu2i.js → AiConfigContext-D3b1l_Kw.js} +1 -1
- package/static/settings/assets/{AiConfigPage-CSCBckKo.js → AiConfigPage-DYKw-atP.js} +1 -1
- package/static/settings/assets/{DocumentProcessingPanel-w9yQDbBe.js → DocumentProcessingPanel-DguRfsIV.js} +1 -1
- package/static/settings/assets/{IndexLifecyclePanel-CUUXI8mP.js → IndexLifecyclePanel-B85qJJA4.js} +1 -1
- package/static/settings/assets/{IndexSubjectPanel-BypAU5TJ.js → IndexSubjectPanel-CsN7IxaV.js} +1 -1
- package/static/settings/assets/{ModelAssignmentsPanel-BetgXw1G.js → ModelAssignmentsPanel-DEp9byI6.js} +1 -1
- package/static/settings/assets/{ModelsPage-DZpTlTZ3.js → ModelsPage-CzTnPs_G.js} +3 -3
- package/static/settings/assets/NetworkPage-BDVnmUU0.js +2 -0
- package/static/settings/assets/{PaneListHeader-BGOqGec4.js → PaneListHeader-Cpe39N76.js} +1 -1
- package/static/settings/assets/{SearchIndexingPanel-DYAbpZ_9.js → SearchIndexingPanel-DA9w8lLL.js} +1 -1
- package/static/settings/assets/{StatusSubjectPanel-CFgzeQ8Q.js → StatusSubjectPanel-BU0Aq0CS.js} +1 -1
- package/static/settings/assets/{StatusWorkspace-4Z6g4Jvv.js → StatusWorkspace-D1AC1i5N.js} +1 -1
- package/static/settings/assets/{SystemSettingsPage-C1tlrgvI.js → SystemSettingsPage-ChKvOioO.js} +1 -1
- package/static/settings/assets/{SystemSettingsSubjectPanel-CcURI-1L.js → SystemSettingsSubjectPanel-DyTpOnD2.js} +1 -1
- package/static/settings/assets/{XpodAiConnectionsPodStore-owBQc5nY.js → XpodAiConnectionsPodStore-VU5Bsz1a.js} +1 -1
- package/static/settings/assets/{activity-CtBc9cNy.js → activity-DGpLfsQB.js} +1 -1
- package/static/settings/assets/ai-connections-DexTPyfC.js +1 -0
- package/static/settings/assets/{badge--r-FDIhU.js → badge-_hCrrWRP.js} +1 -1
- package/static/settings/assets/{collection-runtime-CnhPmwAM.js → collection-runtime-E40TZ8Cl.js} +1 -1
- package/static/settings/assets/{dialog-B7ZRsjN7.js → dialog-DTr2JkHn.js} +1 -1
- package/static/settings/assets/{download-DgQ1F8QR.js → download-B_D21DDX.js} +1 -1
- package/static/settings/assets/{external-link-Bz7NckNO.js → external-link-BATYaM13.js} +1 -1
- package/static/settings/assets/index-BAlAVi-J.js +4 -0
- package/static/settings/assets/{index-CkGda_Pg.js → index-Ckh4h9jj.js} +1 -1
- package/static/settings/assets/{index-Vv-8Vslg.js → index-DOiwLF4B.js} +1 -1
- package/static/settings/assets/{index-browser-Dq7omlpY.js → index-browser-DFFWN3Kr.js} +1 -1
- package/static/settings/assets/{key-round-CvuhloKV.js → key-round-ZTVU_1O1.js} +1 -1
- package/static/settings/assets/{rotate-ccw-DgFKDaz7.js → rotate-ccw-DDdw8PTU.js} +1 -1
- package/static/settings/assets/{settings-BvqY7K96.js → settings-CyLnISOv.js} +62 -62
- package/static/settings/assets/settings-rk080mvG.css +1 -0
- package/static/settings/assets/{skeleton-D3OeFDF6.js → skeleton-DEzA3hc2.js} +1 -1
- package/static/settings/assets/{waypoints-C4WbspTb.js → waypoints-BSdfNvEb.js} +1 -1
- package/static/settings/assets/{workspace-layout-B9H1Tqrk.js → workspace-layout-BOQnl_3d.js} +1 -1
- package/static/settings/settings.html +2 -2
- package/dist/api/ai-gateway/pod/HostedPodDataAccess.d.ts +0 -31
- package/dist/api/ai-gateway/pod/HostedPodDataAccess.js +0 -330
- package/dist/http/InternalPodDataHttpHandler.d.ts +0 -57
- package/dist/http/InternalPodDataHttpHandler.js +0 -551
- package/dist/http/InternalPodDataHttpHandler.jsonld +0 -243
- package/node_modules/@undefineds.co/ai-connections-core/package.json +0 -61
- package/static/auth-callback/assets/NetworkPage-cEvxRMAl.js +0 -2
- package/static/auth-callback/assets/ai-connections-C6yaE6WQ.js +0 -1
- package/static/auth-callback/assets/auth-callback-Cx9D_1qj.css +0 -1
- package/static/auth-callback/assets/index-Cu0EguPo.js +0 -4
- package/static/dashboard/assets/NetworkPage-Ot4G2dX5.js +0 -2
- package/static/dashboard/assets/ai-connections-CXp5gd1J.js +0 -1
- package/static/dashboard/assets/dashboard-Cx9D_1qj.css +0 -1
- package/static/dashboard/assets/index-Gp3cLolR.js +0 -4
- package/static/settings/assets/NetworkPage-BVkasFGM.js +0 -2
- package/static/settings/assets/ai-connections-C6yaE6WQ.js +0 -1
- package/static/settings/assets/index-BdXwm8nh.js +0 -4
- package/static/settings/assets/settings-Cx9D_1qj.css +0 -1
- /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client/normalize.d.ts +0 -0
- /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client/normalize.js +0 -0
- /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client/request.d.ts +0 -0
- /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client/request.js +0 -0
- /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client/types.d.ts +0 -0
- /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client/types.js +0 -0
- /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client-config/base-adapter.d.ts +0 -0
- /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client-config/base-adapter.js +0 -0
- /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client-config/codex.d.ts +0 -0
- /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client-config/codex.js +0 -0
- /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client-config/index.d.ts +0 -0
- /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client-config/index.js +0 -0
- /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client-config/json-env-adapter.d.ts +0 -0
- /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client-config/json-env-adapter.js +0 -0
- /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client-config/pi.d.ts +0 -0
- /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client-config/pi.js +0 -0
- /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client-config/transaction.d.ts +0 -0
- /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client-config/transaction.js +0 -0
- /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client-config/types.d.ts +0 -0
- /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/client-config/types.js +0 -0
- /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/credential-storage.d.ts +0 -0
- /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/credential-storage.js +0 -0
- /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/endpoint-urls.d.ts +0 -0
- /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/endpoint-urls.js +0 -0
- /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/provider-catalog.d.ts +0 -0
- /package/node_modules/@undefineds.co/{ai-connections-core/dist → ai-connections/dist/contract}/provider-catalog.js +0 -0
|
@@ -40,7 +40,23 @@ export declare function createAdminServicesCapabilities(req: AuthenticatedReques
|
|
|
40
40
|
};
|
|
41
41
|
};
|
|
42
42
|
export declare function readDurableAdminEnvironment(): Record<string, string>;
|
|
43
|
-
|
|
43
|
+
/**
|
|
44
|
+
* Tunnel profiles exactly as the runtime resolved them.
|
|
45
|
+
*
|
|
46
|
+
* `credentialEnvKey` is the profile-scoped key when one is configured, so a caller can
|
|
47
|
+
* write a secret where the runtime will actually read it.
|
|
48
|
+
*/
|
|
49
|
+
export declare function projectTunnelProfiles(): Array<{
|
|
50
|
+
id: string;
|
|
51
|
+
provider: string;
|
|
52
|
+
label?: string;
|
|
53
|
+
publicUrl?: string;
|
|
54
|
+
credentialEnvKey?: string;
|
|
55
|
+
credentialConfigured: boolean;
|
|
56
|
+
active: boolean;
|
|
57
|
+
parameters?: Record<string, string>;
|
|
58
|
+
}>;
|
|
59
|
+
export declare function writeDurableAdminEnvironmentPatch(input: Record<string, string>, removals?: string[]): void;
|
|
44
60
|
/**
|
|
45
61
|
* Why a coordinated public domain cannot be served, or `null` when nothing
|
|
46
62
|
* rules it out.
|
|
@@ -15,6 +15,7 @@ exports.sanitizeLogMessage = sanitizeLogMessage;
|
|
|
15
15
|
exports.isAdminMutationAllowed = isAdminMutationAllowed;
|
|
16
16
|
exports.createAdminServicesCapabilities = createAdminServicesCapabilities;
|
|
17
17
|
exports.readDurableAdminEnvironment = readDurableAdminEnvironment;
|
|
18
|
+
exports.projectTunnelProfiles = projectTunnelProfiles;
|
|
18
19
|
exports.writeDurableAdminEnvironmentPatch = writeDurableAdminEnvironmentPatch;
|
|
19
20
|
exports.describeUnservedPublicRoute = describeUnservedPublicRoute;
|
|
20
21
|
exports.registerAdminRoutes = registerAdminRoutes;
|
|
@@ -25,6 +26,8 @@ const fs_2 = require("fs");
|
|
|
25
26
|
const readline_1 = require("readline");
|
|
26
27
|
const runtime_1 = require("../../runtime");
|
|
27
28
|
const log_file_1 = require("../../logging/log-file");
|
|
29
|
+
const TunnelProviderCatalog_1 = require("../../tunnel/TunnelProviderCatalog");
|
|
30
|
+
const TunnelProfiles_1 = require("../../tunnel/TunnelProfiles");
|
|
28
31
|
const GatewayAdminProxyAuth_1 = require("../../runtime/GatewayAdminProxyAuth");
|
|
29
32
|
const CONFIG_DIR = path_1.default.resolve(runtime_1.PACKAGE_ROOT, 'config');
|
|
30
33
|
function getEnvFilePath() {
|
|
@@ -110,7 +113,7 @@ function sanitizeEnvForRead(env) {
|
|
|
110
113
|
function createAllowedAdminConfigPatch(input) {
|
|
111
114
|
const patch = {};
|
|
112
115
|
for (const [key, value] of Object.entries(input)) {
|
|
113
|
-
if (!ALLOWED_ADMIN_CONFIG_KEY_SET.has(key)) {
|
|
116
|
+
if (!ALLOWED_ADMIN_CONFIG_KEY_SET.has(key) && !(0, TunnelProviderCatalog_1.isTunnelProfileCredentialEnvKey)(key)) {
|
|
114
117
|
continue;
|
|
115
118
|
}
|
|
116
119
|
if (isAdminSecretEnvKey(key) && !value) {
|
|
@@ -248,11 +251,40 @@ function writeEnvFile(filePath, config) {
|
|
|
248
251
|
function readDurableAdminEnvironment() {
|
|
249
252
|
return readEnvFile(getEnvFilePath());
|
|
250
253
|
}
|
|
251
|
-
|
|
254
|
+
/**
|
|
255
|
+
* Tunnel profiles exactly as the runtime resolved them.
|
|
256
|
+
*
|
|
257
|
+
* `credentialEnvKey` is the profile-scoped key when one is configured, so a caller can
|
|
258
|
+
* write a secret where the runtime will actually read it.
|
|
259
|
+
*/
|
|
260
|
+
function projectTunnelProfiles() {
|
|
261
|
+
const state = (0, TunnelProfiles_1.resolveTunnelProfileState)(process.env);
|
|
262
|
+
return state.profiles.map((profile) => ({
|
|
263
|
+
id: profile.id,
|
|
264
|
+
provider: profile.provider,
|
|
265
|
+
...(profile.label ? { label: profile.label } : {}),
|
|
266
|
+
...(profile.publicUrl ? { publicUrl: profile.publicUrl } : {}),
|
|
267
|
+
...(profile.credentialEnvKey ? { credentialEnvKey: profile.credentialEnvKey } : {}),
|
|
268
|
+
credentialConfigured: profile.credentialConfigured === true,
|
|
269
|
+
active: state.activeProfile?.id === profile.id,
|
|
270
|
+
// Served to the console so an edit there cannot silently erase parameters the settings
|
|
271
|
+
// page wrote.
|
|
272
|
+
...(profile.parameters ? { parameters: profile.parameters } : {}),
|
|
273
|
+
}));
|
|
274
|
+
}
|
|
275
|
+
function writeDurableAdminEnvironmentPatch(input, removals = []) {
|
|
252
276
|
const filePath = getEnvFilePath();
|
|
253
277
|
const current = readEnvFile(filePath);
|
|
254
278
|
const patch = createAllowedAdminConfigPatch(input);
|
|
255
|
-
|
|
279
|
+
const next = { ...current, ...patch };
|
|
280
|
+
// Deleting a profile has to delete its credential: an empty secret value is filtered
|
|
281
|
+
// out of the patch (see createAllowedAdminConfigPatch), so removals are explicit.
|
|
282
|
+
for (const key of removals) {
|
|
283
|
+
if (ALLOWED_ADMIN_CONFIG_KEY_SET.has(key) || (0, TunnelProviderCatalog_1.isTunnelProfileCredentialEnvKey)(key)) {
|
|
284
|
+
delete next[key];
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
writeEnvFile(filePath, next);
|
|
256
288
|
}
|
|
257
289
|
/**
|
|
258
290
|
* List available config files
|
|
@@ -411,6 +443,11 @@ function registerAdminRoutes(server, options = {}) {
|
|
|
411
443
|
sendJson(res, 200, {
|
|
412
444
|
...sanitizeEnvForRead(env),
|
|
413
445
|
configFiles: listConfigFiles(),
|
|
446
|
+
// Operator pages render the same provider axis the runtime honours.
|
|
447
|
+
providers: TunnelProviderCatalog_1.TUNNEL_PROVIDERS,
|
|
448
|
+
// Profiles as the runtime resolved them, including the credential key that belongs
|
|
449
|
+
// to each profile: the operator console must not invent its own key naming.
|
|
450
|
+
tunnelProfiles: projectTunnelProfiles(),
|
|
414
451
|
});
|
|
415
452
|
}
|
|
416
453
|
catch (error) {
|
|
@@ -6,6 +6,7 @@ import type { ProviderConnectService } from '../ai-gateway/connect';
|
|
|
6
6
|
import type { ProviderModelSelectionService } from '../ai-gateway/models/ProviderModelSelectionService';
|
|
7
7
|
import type { ProviderQuotaService } from '../ai-gateway/quota';
|
|
8
8
|
import { type ProviderCustomModelsService, type ProviderModelsService } from '../ai-gateway/models';
|
|
9
|
+
import type { PodInterfaceKeyGrant } from '../ai-gateway/pod/PodInterfaceKeyStore';
|
|
9
10
|
import type { AiConnectionsInvocationKeyIssuer } from '../ai-gateway/auth/AiConnectionsInvocationKeyIssuer';
|
|
10
11
|
import { type AiClientConfigurationCapabilityDescriptor } from '../service/AiClientConfigurationService';
|
|
11
12
|
export interface AiGatewayManagementHandlerOptions {
|
|
@@ -25,6 +26,11 @@ export interface AiGatewayManagementHandlerOptions {
|
|
|
25
26
|
gatewayAccessKeyRepository?: GatewayAccessKeyRepository;
|
|
26
27
|
/** Reuses the configured CSS authenticator; never trusts the claimed registration owner. */
|
|
27
28
|
validateClientCredential?: (apiKey: string) => Promise<AuthResult>;
|
|
29
|
+
/**
|
|
30
|
+
* Server-side Pod access for the owner. The wrapper being registered is the owner's own
|
|
31
|
+
* interface key, so registering it is also the moment Xpod is granted its use.
|
|
32
|
+
*/
|
|
33
|
+
podInterfaceKeys?: PodInterfaceKeyGrant;
|
|
28
34
|
aiClientConfiguration?: AiClientConfigurationCapabilityDescriptor;
|
|
29
35
|
aiConnectionInvocationKeyIssuer?: Pick<AiConnectionsInvocationKeyIssuer, 'issue' | 'issueClientConfiguration'>;
|
|
30
36
|
jsonBodyLimitBytes?: number;
|
|
@@ -5,8 +5,10 @@ const node_crypto_1 = require("node:crypto");
|
|
|
5
5
|
const global_logger_factory_1 = require("global-logger-factory");
|
|
6
6
|
const readBoundedJsonBody_1 = require("../http/readBoundedJsonBody");
|
|
7
7
|
const GatewayPrincipal_1 = require("../ai-gateway/auth/GatewayPrincipal");
|
|
8
|
+
const AuthContext_1 = require("../auth/AuthContext");
|
|
8
9
|
const models_1 = require("../ai-gateway/models");
|
|
9
10
|
const AiConnectionsServiceAccess_1 = require("../ai-gateway/service-access/AiConnectionsServiceAccess");
|
|
11
|
+
const OwnerPodAccess_1 = require("../ai-gateway/pod/OwnerPodAccess");
|
|
10
12
|
const AiClientConfigurationService_1 = require("../service/AiClientConfigurationService");
|
|
11
13
|
const errors_1 = require("../ai-gateway/errors");
|
|
12
14
|
const EmbeddingModelPolicy_1 = require("../../ai/service/EmbeddingModelPolicy");
|
|
@@ -117,6 +119,15 @@ function registerAiGatewayManagementRoutes(server, options) {
|
|
|
117
119
|
sendJson(response, 403, { error: 'CSS client credential belongs to another WebID' });
|
|
118
120
|
return;
|
|
119
121
|
}
|
|
122
|
+
if ((0, AuthContext_1.hasSolidClientCredentialsAuthority)(verified.context)) {
|
|
123
|
+
// Sealed before the record is written, because writing the record is the first thing
|
|
124
|
+
// that needs it: background components reach this Pod through the standard interface
|
|
125
|
+
// as the owner, never through the caller's network position.
|
|
126
|
+
await options.podInterfaceKeys?.saveKey(owner, {
|
|
127
|
+
clientId: verified.context.clientId,
|
|
128
|
+
clientSecret: verified.context.clientSecret,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
120
131
|
const name = normalizeOptionalString(body.name) ?? 'Xpod API Key';
|
|
121
132
|
const keyId = repository.createKeyId(owner, options.deployment);
|
|
122
133
|
const createdAt = new Date();
|
|
@@ -1329,7 +1340,7 @@ function sendCredentialPoolError(response, error) {
|
|
|
1329
1340
|
}
|
|
1330
1341
|
function sendGatewayAccessKeyError(response, error) {
|
|
1331
1342
|
const message = error instanceof Error ? error.message : String(error);
|
|
1332
|
-
if (
|
|
1343
|
+
if ((0, OwnerPodAccess_1.isPodAccessFailure)(message)) {
|
|
1333
1344
|
sendJson(response, 403, { error: 'service_access_missing' });
|
|
1334
1345
|
return;
|
|
1335
1346
|
}
|
|
@@ -1465,9 +1476,11 @@ function sendModelSelectionError(response, error) {
|
|
|
1465
1476
|
model_selection_exact_update_failed: { status: 409, error: 'model_selection_conflict' },
|
|
1466
1477
|
model_selection_provider_update_failed: { status: 409, error: 'model_selection_conflict' },
|
|
1467
1478
|
service_access_missing: { status: 403, error: 'service_access_missing' },
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1479
|
+
pod_interface_key_missing: { status: 403, error: 'service_access_missing' },
|
|
1480
|
+
pod_interface_key_rejected: { status: 403, error: 'service_access_missing' },
|
|
1481
|
+
caller_dpop_replay_unsupported: { status: 403, error: 'service_access_missing' },
|
|
1482
|
+
caller_owner_mismatch: { status: 403, error: 'pod_owner_mismatch' },
|
|
1483
|
+
caller_pod_access_unavailable: { status: 401, error: 'authentication_required' },
|
|
1471
1484
|
};
|
|
1472
1485
|
const mapped = stable[message];
|
|
1473
1486
|
if (mapped) {
|
|
@@ -44,8 +44,14 @@ function registerEdgeNodeSignalRoutes(server, options) {
|
|
|
44
44
|
let metadata = mergeMetadata(existing?.metadata ?? {}, payload, now);
|
|
45
45
|
// 从 DB connectivity 列注入 subdomain/ipv4,供 dnsCoordinator 使用
|
|
46
46
|
const connectivityInfo = await repo.getNodeConnectivityInfo(nodeId);
|
|
47
|
+
// The subdomain a node may publish is assigned by the control plane, never by the
|
|
48
|
+
// node itself: a heartbeat must not be able to retarget another node's record.
|
|
49
|
+
delete metadata.subdomain;
|
|
50
|
+
if (isRecord(metadata.dns)) {
|
|
51
|
+
metadata.dns = Object.fromEntries(Object.entries(metadata.dns).filter(([key]) => key !== 'subdomain'));
|
|
52
|
+
}
|
|
47
53
|
if (connectivityInfo) {
|
|
48
|
-
if (connectivityInfo.subdomain
|
|
54
|
+
if (connectivityInfo.subdomain) {
|
|
49
55
|
metadata.subdomain = connectivityInfo.subdomain;
|
|
50
56
|
}
|
|
51
57
|
if (connectivityInfo.ipv4 && !metadata.ipv4) {
|
|
@@ -78,7 +84,9 @@ function registerEdgeNodeSignalRoutes(server, options) {
|
|
|
78
84
|
}
|
|
79
85
|
}
|
|
80
86
|
if (dnsCoordinator) {
|
|
81
|
-
|
|
87
|
+
// The control plane decides which subdomain this node owns; the coordinator gets
|
|
88
|
+
// that assignment explicitly instead of reading it back out of node metadata.
|
|
89
|
+
await dnsCoordinator.synchronize(nodeId, metadata, { subdomain: connectivityInfo?.subdomain });
|
|
82
90
|
}
|
|
83
91
|
logger.debug(`Signal received from node ${nodeId}`);
|
|
84
92
|
sendJson(response, 200, {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { getLoggerFor } from 'global-logger-factory';
|
|
2
2
|
import type { ApiServer } from '../ApiServer';
|
|
3
3
|
import type { AuthContext } from '../auth/AuthContext';
|
|
4
|
+
import { type TunnelProviderDescriptor } from '../../tunnel/TunnelProviderCatalog';
|
|
4
5
|
export interface NetworkSettingsStatus {
|
|
5
6
|
endpoint: string;
|
|
6
7
|
addresses: {
|
|
@@ -22,6 +23,21 @@ export interface NetworkSettingsStatus {
|
|
|
22
23
|
renewCertificate: boolean;
|
|
23
24
|
};
|
|
24
25
|
configuration?: NetworkDesiredConfiguration;
|
|
26
|
+
/**
|
|
27
|
+
* The provider axis, served so the settings page renders the same declaration the
|
|
28
|
+
* runtime honours instead of keeping its own list.
|
|
29
|
+
*/
|
|
30
|
+
providers?: readonly TunnelProviderDescriptor[];
|
|
31
|
+
/**
|
|
32
|
+
* The address a remote tunnel must forward to.
|
|
33
|
+
*
|
|
34
|
+
* Remotely-managed tunnels dial a port the operator typed into a provider console, so the
|
|
35
|
+
* page shows this value to copy rather than making the operator guess it.
|
|
36
|
+
*/
|
|
37
|
+
ingress?: {
|
|
38
|
+
port: number;
|
|
39
|
+
originUrl: string;
|
|
40
|
+
};
|
|
25
41
|
}
|
|
26
42
|
export interface NetworkDesiredConfiguration {
|
|
27
43
|
domainDns: {
|
|
@@ -51,12 +67,17 @@ export interface NetworkDesiredConfiguration {
|
|
|
51
67
|
}
|
|
52
68
|
export interface NetworkTunnelProfile {
|
|
53
69
|
id: string;
|
|
54
|
-
provider:
|
|
70
|
+
provider: string;
|
|
55
71
|
label: string;
|
|
56
|
-
|
|
72
|
+
publicUrl?: string;
|
|
57
73
|
credentialConfigured: boolean;
|
|
58
74
|
parameters?: Record<string, string>;
|
|
59
75
|
}
|
|
76
|
+
/** `publicEndpoint` is the field older settings clients sent; `publicUrl` is canonical. */
|
|
77
|
+
export type NetworkTunnelProfilePatch = Omit<NetworkTunnelProfile, 'credentialConfigured'> & {
|
|
78
|
+
credential?: string;
|
|
79
|
+
publicEndpoint?: string;
|
|
80
|
+
};
|
|
60
81
|
export type NetworkConfigurationPatch = {
|
|
61
82
|
domainDns?: Partial<Omit<NetworkDesiredConfiguration['domainDns'], 'credentialConfigured'>> & {
|
|
62
83
|
credential?: string;
|
|
@@ -64,9 +85,7 @@ export type NetworkConfigurationPatch = {
|
|
|
64
85
|
https?: Partial<NetworkDesiredConfiguration['https']>;
|
|
65
86
|
tunnelProfiles?: {
|
|
66
87
|
activeProfileId?: string;
|
|
67
|
-
profiles?:
|
|
68
|
-
credential?: string;
|
|
69
|
-
}>;
|
|
88
|
+
profiles?: NetworkTunnelProfilePatch[];
|
|
70
89
|
};
|
|
71
90
|
p2p?: Partial<NetworkDesiredConfiguration['p2p']>;
|
|
72
91
|
};
|
|
@@ -77,6 +96,12 @@ export interface NetworkConfigurationStore {
|
|
|
77
96
|
export interface CapabilityStatus {
|
|
78
97
|
supported: boolean;
|
|
79
98
|
status: string;
|
|
99
|
+
/** Readiness stage of the provider, when the provider reports one. */
|
|
100
|
+
stage?: string;
|
|
101
|
+
/** Endpoint the provider actually observed; distinct from a declared/configured address. */
|
|
102
|
+
endpoint?: string;
|
|
103
|
+
/** Redacted reason for a non-active status; absent when there is nothing to explain. */
|
|
104
|
+
detail?: string;
|
|
80
105
|
}
|
|
81
106
|
export type DiagnosticStatus = 'ok' | 'warning' | 'error' | 'unsupported';
|
|
82
107
|
export interface NetworkDiagnosticCheckResult {
|
|
@@ -138,6 +163,20 @@ export interface NetworkSettingsHandlerOptions {
|
|
|
138
163
|
internalAdminAuthSecret?: string;
|
|
139
164
|
logger?: Pick<ReturnType<typeof getLoggerFor>, 'warn' | 'error'>;
|
|
140
165
|
}
|
|
166
|
+
/** The ingress address this runtime listens on, when it published one. */
|
|
167
|
+
/**
|
|
168
|
+
* The address a provider console is configured with: the Gateway's tunnel entry.
|
|
169
|
+
*
|
|
170
|
+
* It is the listener that never treats a caller as local, so a tunnel reaching the runtime
|
|
171
|
+
* through it cannot inherit local trust whatever headers it carries. The banner the user
|
|
172
|
+
* copies is this one number; the Gateway's own port is what they type in a browser.
|
|
173
|
+
*/
|
|
174
|
+
export declare function readIngressAddress(env?: NodeJS.ProcessEnv): {
|
|
175
|
+
ingress?: {
|
|
176
|
+
port: number;
|
|
177
|
+
originUrl: string;
|
|
178
|
+
};
|
|
179
|
+
};
|
|
141
180
|
export declare function registerNetworkSettingsRoutes(server: ApiServer, options: NetworkSettingsHandlerOptions): void;
|
|
142
181
|
export declare function createDeploymentNetworkSettingsAuthorizer(options?: NetworkSettingsIdentityAuthorizerOptions): NetworkSettingsAuthorizer;
|
|
143
182
|
export declare function createAddressReaders(input: {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.readIngressAddress = readIngressAddress;
|
|
3
4
|
exports.registerNetworkSettingsRoutes = registerNetworkSettingsRoutes;
|
|
4
5
|
exports.createDeploymentNetworkSettingsAuthorizer = createDeploymentNetworkSettingsAuthorizer;
|
|
5
6
|
exports.createAddressReaders = createAddressReaders;
|
|
@@ -13,6 +14,22 @@ const node_os_1 = require("node:os");
|
|
|
13
14
|
const global_logger_factory_1 = require("global-logger-factory");
|
|
14
15
|
const readBoundedJsonBody_1 = require("../http/readBoundedJsonBody");
|
|
15
16
|
const AdminHandler_1 = require("./AdminHandler");
|
|
17
|
+
const TunnelProviderCatalog_1 = require("../../tunnel/TunnelProviderCatalog");
|
|
18
|
+
/** The ingress address this runtime listens on, when it published one. */
|
|
19
|
+
/**
|
|
20
|
+
* The address a provider console is configured with: the Gateway's tunnel entry.
|
|
21
|
+
*
|
|
22
|
+
* It is the listener that never treats a caller as local, so a tunnel reaching the runtime
|
|
23
|
+
* through it cannot inherit local trust whatever headers it carries. The banner the user
|
|
24
|
+
* copies is this one number; the Gateway's own port is what they type in a browser.
|
|
25
|
+
*/
|
|
26
|
+
function readIngressAddress(env = process.env) {
|
|
27
|
+
const port = Number.parseInt(env.XPOD_GATEWAY_INGRESS_PORT ?? '', 10);
|
|
28
|
+
if (!Number.isInteger(port) || port <= 0 || port > 65535) {
|
|
29
|
+
return {};
|
|
30
|
+
}
|
|
31
|
+
return { ingress: { port, originUrl: `http://127.0.0.1:${port}` } };
|
|
32
|
+
}
|
|
16
33
|
function registerNetworkSettingsRoutes(server, options) {
|
|
17
34
|
const logger = options.logger ?? (0, global_logger_factory_1.getLoggerFor)('NetworkSettingsHandler');
|
|
18
35
|
const authorizer = options.authorizer ?? createDeploymentNetworkSettingsAuthorizer();
|
|
@@ -23,7 +40,12 @@ function registerNetworkSettingsRoutes(server, options) {
|
|
|
23
40
|
try {
|
|
24
41
|
const status = await readNetworkStatus(options, logger);
|
|
25
42
|
const configuration = await options.configurationStore?.read();
|
|
26
|
-
sendJson(response, 200,
|
|
43
|
+
sendJson(response, 200, {
|
|
44
|
+
...status,
|
|
45
|
+
providers: TunnelProviderCatalog_1.TUNNEL_PROVIDERS,
|
|
46
|
+
...readIngressAddress(),
|
|
47
|
+
...(configuration ? { configuration } : {}),
|
|
48
|
+
});
|
|
27
49
|
}
|
|
28
50
|
catch (error) {
|
|
29
51
|
logger.error(`Failed to read network settings status: ${redactSecretText(error)}`);
|
|
@@ -134,11 +156,16 @@ function parseNetworkConfigurationPatch(value) {
|
|
|
134
156
|
return value;
|
|
135
157
|
}
|
|
136
158
|
function validTunnelProfile(value) {
|
|
137
|
-
|
|
159
|
+
// `publicUrl` is canonical; `publicEndpoint` is what older clients sent.
|
|
160
|
+
if (!isPlainRecord(value) || hasUnknownKeys(value, ['id', 'provider', 'label', 'publicUrl', 'publicEndpoint', 'credential', 'parameters']))
|
|
138
161
|
return false;
|
|
139
162
|
if (typeof value.id !== 'string' || !value.id.trim() || typeof value.label !== 'string' || !value.label.trim())
|
|
140
163
|
return false;
|
|
141
|
-
if (!
|
|
164
|
+
if (!(0, TunnelProviderCatalog_1.isTunnelProviderId)(value.provider) || !optionalString(value.publicUrl) || !optionalString(value.publicEndpoint) || !optionalString(value.credential))
|
|
165
|
+
return false;
|
|
166
|
+
// A provider the local runtime cannot start must be refused here rather than stored and
|
|
167
|
+
// reported as "configured" while nothing can ever come up.
|
|
168
|
+
if ((0, TunnelProviderCatalog_1.tunnelProviderDescriptor)(value.provider)?.runtimeSupported === false)
|
|
142
169
|
return false;
|
|
143
170
|
return value.parameters === undefined || (isPlainRecord(value.parameters) && Object.values(value.parameters).every((item) => typeof item === 'string'));
|
|
144
171
|
}
|
|
@@ -205,16 +232,20 @@ function createTunnelStatusReader(tunnelProvider) {
|
|
|
205
232
|
return {
|
|
206
233
|
read: async () => {
|
|
207
234
|
const status = tunnelProvider.getStatus();
|
|
235
|
+
const detail = status.error ? redactSecretText(status.error) : undefined;
|
|
236
|
+
const observed = typeof status.endpoint === 'string' && status.endpoint ? { endpoint: status.endpoint } : {};
|
|
237
|
+
const stage = status.stage ? { stage: status.stage } : {};
|
|
208
238
|
if (status.connected) {
|
|
209
|
-
return { supported: true, status: 'active' };
|
|
239
|
+
return { supported: true, status: 'active', ...stage, ...observed };
|
|
210
240
|
}
|
|
211
241
|
if (status.running) {
|
|
212
|
-
|
|
242
|
+
// A running process is not a published proxy: say which stage it reached.
|
|
243
|
+
return { supported: true, status: 'starting', ...stage, ...observed };
|
|
213
244
|
}
|
|
214
|
-
if (
|
|
215
|
-
return { supported: true, status: 'error' };
|
|
245
|
+
if (detail) {
|
|
246
|
+
return { supported: true, status: 'error', ...stage, ...observed, detail };
|
|
216
247
|
}
|
|
217
|
-
return { supported: true, status: 'inactive' };
|
|
248
|
+
return { supported: true, status: 'inactive', ...observed };
|
|
218
249
|
},
|
|
219
250
|
};
|
|
220
251
|
}
|
|
@@ -302,11 +333,15 @@ function safeAddressList(reader, logger) {
|
|
|
302
333
|
function buildDefaultDiagnostics(options, logger) {
|
|
303
334
|
return [
|
|
304
335
|
{
|
|
305
|
-
|
|
306
|
-
|
|
336
|
+
// This check only proves that an address is configured. Reachability is a different
|
|
337
|
+
// fact and needs a real probe, so the result must not be rendered as one.
|
|
338
|
+
id: 'address-configuration',
|
|
339
|
+
label: 'Address configuration',
|
|
307
340
|
run: async () => {
|
|
308
341
|
const endpoint = normalizeEndpoint(resolveValue(options.endpoint));
|
|
309
|
-
return endpoint
|
|
342
|
+
return endpoint
|
|
343
|
+
? { status: 'ok', detail: `configured: ${endpoint}` }
|
|
344
|
+
: { status: 'unsupported', detail: 'endpoint_unavailable' };
|
|
310
345
|
},
|
|
311
346
|
},
|
|
312
347
|
{
|
|
@@ -2,7 +2,7 @@ import { getLoggerFor } from 'global-logger-factory';
|
|
|
2
2
|
import type { ApiServer } from '../ApiServer';
|
|
3
3
|
import type { PodLookupRepository } from '../../identity/drizzle/PodLookupRepository';
|
|
4
4
|
import type { UsageRepository } from '../../storage/quota/UsageRepository';
|
|
5
|
-
import type {
|
|
5
|
+
import type { PodAccessFetchProvider } from '../ai-gateway/pod/OwnerPodAccess';
|
|
6
6
|
export interface PodSettingsStatus {
|
|
7
7
|
identity: {
|
|
8
8
|
webId: string;
|
|
@@ -57,10 +57,10 @@ export interface PodSettingsHandlerOptions {
|
|
|
57
57
|
}
|
|
58
58
|
export declare function registerPodSettingsRoutes(server: ApiServer, options: PodSettingsHandlerOptions): void;
|
|
59
59
|
export declare class DrizzlePodAiConnectionsStatusReader implements PodAiConnectionsStatusReader {
|
|
60
|
-
private readonly
|
|
60
|
+
private readonly podAccess?;
|
|
61
61
|
private readonly deployment;
|
|
62
62
|
private readonly dbFactory;
|
|
63
|
-
constructor(
|
|
63
|
+
constructor(podAccess?: PodAccessFetchProvider | undefined, deployment?: string, dbFactory?: (input: {
|
|
64
64
|
webId: string;
|
|
65
65
|
podUrl: string;
|
|
66
66
|
fetch: typeof fetch;
|
|
@@ -77,13 +77,13 @@ async function readStorageStatus(usageRepo, pod) {
|
|
|
77
77
|
};
|
|
78
78
|
}
|
|
79
79
|
class DrizzlePodAiConnectionsStatusReader {
|
|
80
|
-
constructor(
|
|
81
|
-
this.
|
|
80
|
+
constructor(podAccess, deployment = 'local', dbFactory = createAiConnectionsStatusDb) {
|
|
81
|
+
this.podAccess = podAccess;
|
|
82
82
|
this.deployment = deployment;
|
|
83
83
|
this.dbFactory = dbFactory;
|
|
84
84
|
}
|
|
85
85
|
async read({ webId, podUrl }) {
|
|
86
|
-
const trustedFetch = await this.
|
|
86
|
+
const trustedFetch = await this.podAccess?.getPodFetch(webId);
|
|
87
87
|
if (!trustedFetch) {
|
|
88
88
|
return { status: 'unsupported', reason: 'not_configured' };
|
|
89
89
|
}
|
|
@@ -14,11 +14,12 @@
|
|
|
14
14
|
* 返回 SP 配置状态,供 Linx 查询
|
|
15
15
|
*/
|
|
16
16
|
import type { ApiServer } from '../ApiServer';
|
|
17
|
+
import type { AccessRoute } from '../../edge/reachability/types';
|
|
17
18
|
import type { EdgeNodeRepository } from '../../identity/drizzle/EdgeNodeRepository';
|
|
18
19
|
import type { ServiceTokenRepositoryPort } from '../../identity/drizzle/ServiceTokenRepository';
|
|
19
20
|
import type { DdnsRepository } from '../../identity/drizzle/DdnsRepository';
|
|
20
21
|
import type { DnsProvider } from '../../dns/DnsProvider';
|
|
21
|
-
import type { TunnelProvider } from '../../tunnel/TunnelProvider';
|
|
22
|
+
import type { TunnelProvider, TunnelConfig } from '../../tunnel/TunnelProvider';
|
|
22
23
|
export interface ProvisionHandlerOptions {
|
|
23
24
|
repository: EdgeNodeRepository;
|
|
24
25
|
ddnsRepo?: DdnsRepository;
|
|
@@ -38,6 +39,11 @@ export interface ProvisionHandlerOptions {
|
|
|
38
39
|
serviceTokenRepository?: ServiceTokenRepositoryPort;
|
|
39
40
|
}
|
|
40
41
|
export declare function registerProvisionRoutes(server: ApiServer, options: ProvisionHandlerOptions): void;
|
|
42
|
+
export declare function readManagedTunnelConfig(metadata: Record<string, unknown> | null): {
|
|
43
|
+
subdomain?: string;
|
|
44
|
+
localPort?: number;
|
|
45
|
+
config: TunnelConfig;
|
|
46
|
+
} | undefined;
|
|
41
47
|
/**
|
|
42
48
|
* Local 端 SP 状态查询路由
|
|
43
49
|
*/
|
|
@@ -62,6 +68,25 @@ export interface ProvisionStatusOptions {
|
|
|
62
68
|
cloudBaseUrl?: string;
|
|
63
69
|
/** provisionCode(可选,由环境变量传入) */
|
|
64
70
|
provisionCode?: string;
|
|
71
|
+
/**
|
|
72
|
+
* Live state of the public route, read per request.
|
|
73
|
+
*
|
|
74
|
+
* A configured tunnel is not the same thing as a reachable public route, and a
|
|
75
|
+
* node whose tunnel is down still owns a canonical URL that same-machine
|
|
76
|
+
* clients reach over the loopback access route (`docs/multi-channel-access.md`).
|
|
77
|
+
* Clients need to tell those apart before they decide whether a canonical
|
|
78
|
+
* request can leave the machine, so this is reported rather than implied.
|
|
79
|
+
*/
|
|
80
|
+
readPublicRoute?: () => PublicRouteStatus | Promise<PublicRouteStatus>;
|
|
81
|
+
/**
|
|
82
|
+
* Every access point this node can currently prove it offers, read per request.
|
|
83
|
+
*
|
|
84
|
+
* A canonical URL is one identity reachable over several physical paths, and
|
|
85
|
+
* only the client knows which path it is standing on, so the runtime reports
|
|
86
|
+
* the paths themselves (canonical public route, tunnel, ...) instead of picking
|
|
87
|
+
* one for the client (`docs/multi-channel-access.md`).
|
|
88
|
+
*/
|
|
89
|
+
readAccessRoutes?: () => AccessRoute[] | Promise<AccessRoute[]>;
|
|
65
90
|
/** Persist refreshed local-only setup state to the single local setup file. */
|
|
66
91
|
persistState?: (state: ProvisionStatusStateUpdate) => Promise<void> | void;
|
|
67
92
|
/** 测试/调试注入 */
|
|
@@ -69,6 +94,15 @@ export interface ProvisionStatusOptions {
|
|
|
69
94
|
now?: () => number;
|
|
70
95
|
refreshGraceSeconds?: number;
|
|
71
96
|
}
|
|
97
|
+
/** What a client can learn about reaching this node's canonical URL from outside. */
|
|
98
|
+
export interface PublicRouteStatus {
|
|
99
|
+
/** A tunnel provider is configured for this node. */
|
|
100
|
+
configured: boolean;
|
|
101
|
+
/** The provider confirmed a proxy-ready public route. */
|
|
102
|
+
available: boolean;
|
|
103
|
+
provider?: string;
|
|
104
|
+
endpoint?: string;
|
|
105
|
+
}
|
|
72
106
|
export interface ProvisionStatusStateUpdate {
|
|
73
107
|
nodeId: string;
|
|
74
108
|
nodeToken: string;
|
|
@@ -16,10 +16,12 @@
|
|
|
16
16
|
*/
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
18
|
exports.registerProvisionRoutes = registerProvisionRoutes;
|
|
19
|
+
exports.readManagedTunnelConfig = readManagedTunnelConfig;
|
|
19
20
|
exports.registerProvisionStatusRoute = registerProvisionStatusRoute;
|
|
20
21
|
exports.createLocalSetupProvisionStateWriter = createLocalSetupProvisionStateWriter;
|
|
21
22
|
const node_crypto_1 = require("node:crypto");
|
|
22
23
|
const global_logger_factory_1 = require("global-logger-factory");
|
|
24
|
+
const TunnelProviderCatalog_1 = require("../../tunnel/TunnelProviderCatalog");
|
|
23
25
|
const ProvisionCodeCodec_1 = require("../../provision/ProvisionCodeCodec");
|
|
24
26
|
const ServiceAccessTokenCodec_1 = require("../../provision/ServiceAccessTokenCodec");
|
|
25
27
|
const LocalProvisionState_1 = require("../../provision/LocalProvisionState");
|
|
@@ -421,7 +423,10 @@ function readManagedTunnelConfig(metadata) {
|
|
|
421
423
|
const tunnelId = value.tunnelId;
|
|
422
424
|
const subdomain = typeof value.subdomain === 'string' ? value.subdomain : undefined;
|
|
423
425
|
const localPort = typeof value.localPort === 'number' ? value.localPort : undefined;
|
|
424
|
-
|
|
426
|
+
// Provision callers historically spell Sakura with a hyphen; the catalogue owns the
|
|
427
|
+
// canonical id, so accept either spelling and store one.
|
|
428
|
+
const canonicalProvider = (0, TunnelProviderCatalog_1.parseTunnelProvider)(provider);
|
|
429
|
+
if ((canonicalProvider !== 'cloudflare' && canonicalProvider !== 'frp' && canonicalProvider !== 'sakura_frp')
|
|
425
430
|
|| typeof endpoint !== 'string') {
|
|
426
431
|
return undefined;
|
|
427
432
|
}
|
|
@@ -429,7 +434,7 @@ function readManagedTunnelConfig(metadata) {
|
|
|
429
434
|
subdomain,
|
|
430
435
|
localPort,
|
|
431
436
|
config: {
|
|
432
|
-
provider,
|
|
437
|
+
provider: canonicalProvider,
|
|
433
438
|
subdomain: subdomain ?? 'local',
|
|
434
439
|
endpoint,
|
|
435
440
|
tunnelId: typeof tunnelId === 'string' ? tunnelId : undefined,
|
|
@@ -437,6 +442,21 @@ function readManagedTunnelConfig(metadata) {
|
|
|
437
442
|
},
|
|
438
443
|
};
|
|
439
444
|
}
|
|
445
|
+
/**
|
|
446
|
+
* Only the facts a client needs to rank and use an access point are reported:
|
|
447
|
+
* where it points, how it is reached and whether it is currently known to work.
|
|
448
|
+
*/
|
|
449
|
+
function reportableAccessRoutes(routes) {
|
|
450
|
+
return (routes ?? []).map((route) => ({
|
|
451
|
+
id: route.id,
|
|
452
|
+
kind: route.kind,
|
|
453
|
+
targetUrl: route.targetUrl,
|
|
454
|
+
priority: route.priority,
|
|
455
|
+
requiresManagedClient: route.requiresManagedClient,
|
|
456
|
+
visibility: route.visibility,
|
|
457
|
+
health: route.health,
|
|
458
|
+
}));
|
|
459
|
+
}
|
|
440
460
|
function registerProvisionStatusRoute(server, options) {
|
|
441
461
|
const logger = (0, global_logger_factory_1.getLoggerFor)('ProvisionStatusHandler');
|
|
442
462
|
const fetchImpl = options.fetchImpl ?? fetch;
|
|
@@ -474,6 +494,37 @@ function registerProvisionStatusRoute(server, options) {
|
|
|
474
494
|
body.cloudUrl = options.cloudUrl;
|
|
475
495
|
body.oidcIssuer = normalizeUrl(options.cloudBaseUrl);
|
|
476
496
|
}
|
|
497
|
+
// Whether the canonical URL is reachable from outside is a separate fact
|
|
498
|
+
// from whether it exists. A failed read is reported as unavailable, never as
|
|
499
|
+
// available, because guessing here would send a same-machine client to a
|
|
500
|
+
// public route that does not answer.
|
|
501
|
+
if (options.readPublicRoute) {
|
|
502
|
+
let publicRoute;
|
|
503
|
+
try {
|
|
504
|
+
publicRoute = await options.readPublicRoute();
|
|
505
|
+
}
|
|
506
|
+
catch (error) {
|
|
507
|
+
logger.warn(`Failed to read public route state: ${error}`);
|
|
508
|
+
}
|
|
509
|
+
body.publicRoute = {
|
|
510
|
+
configured: Boolean(publicRoute?.configured),
|
|
511
|
+
available: Boolean(publicRoute?.available),
|
|
512
|
+
...(publicRoute?.provider ? { provider: publicRoute.provider } : {}),
|
|
513
|
+
...(publicRoute?.endpoint ? { endpoint: publicRoute.endpoint } : {}),
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
// Access points are reported as data: which one is best depends on where the
|
|
517
|
+
// client stands, which only the client knows.
|
|
518
|
+
if (options.readAccessRoutes) {
|
|
519
|
+
let routes;
|
|
520
|
+
try {
|
|
521
|
+
routes = await options.readAccessRoutes();
|
|
522
|
+
}
|
|
523
|
+
catch (error) {
|
|
524
|
+
logger.warn(`Failed to read access routes: ${error}`);
|
|
525
|
+
}
|
|
526
|
+
body.routes = reportableAccessRoutes(routes);
|
|
527
|
+
}
|
|
477
528
|
if (registered) {
|
|
478
529
|
const canRefresh = canRefreshProvisionStatus(options, state);
|
|
479
530
|
const currentNow = now();
|
|
@@ -9,5 +9,11 @@ export interface ReachabilityHandlerOptions {
|
|
|
9
9
|
maxActiveP2PSessionsPerNode?: number;
|
|
10
10
|
maxP2PCandidatesPerUpdate?: number;
|
|
11
11
|
maxP2PCandidatesPerSession?: number;
|
|
12
|
+
/**
|
|
13
|
+
* Whether a Solid principal may act on a node, e.g. through Pod ownership or an
|
|
14
|
+
* explicit grant. Absent means "cannot prove access", which denies instead of
|
|
15
|
+
* handing an unrelated WebID signaling access to the node.
|
|
16
|
+
*/
|
|
17
|
+
canAccessNode?: (nodeId: string, webId: string) => Promise<boolean> | boolean;
|
|
12
18
|
}
|
|
13
19
|
export declare function registerReachabilityRoutes(server: ApiServer, options: ReachabilityHandlerOptions): void;
|