@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
|
@@ -42,7 +42,7 @@ function registerReachabilityRoutes(server, options) {
|
|
|
42
42
|
}
|
|
43
43
|
}, { optionalAuth: true });
|
|
44
44
|
server.post('/v1/signal/nodes/:nodeId/sessions', async (request, response, params) => {
|
|
45
|
-
const access = resolveSessionAccess(request, params.nodeId);
|
|
45
|
+
const access = await resolveSessionAccess(request, params.nodeId, options, 'node');
|
|
46
46
|
if (!access.allowed) {
|
|
47
47
|
sendJson(response, access.status, { error: access.error });
|
|
48
48
|
return;
|
|
@@ -119,7 +119,7 @@ function registerReachabilityRoutes(server, options) {
|
|
|
119
119
|
sendJson(response, 400, { error: 'kind must be p2p or relay' });
|
|
120
120
|
});
|
|
121
121
|
server.get('/v1/signal/nodes/:nodeId/sessions', async (request, response, params) => {
|
|
122
|
-
const access = resolveSessionAccess(request, params.nodeId);
|
|
122
|
+
const access = await resolveSessionAccess(request, params.nodeId, options, 'node');
|
|
123
123
|
if (!access.allowed) {
|
|
124
124
|
sendJson(response, access.status, { error: access.error });
|
|
125
125
|
return;
|
|
@@ -137,7 +137,7 @@ function registerReachabilityRoutes(server, options) {
|
|
|
137
137
|
}
|
|
138
138
|
});
|
|
139
139
|
server.get('/v1/signal/nodes/:nodeId/sessions/:sessionId', async (request, response, params) => {
|
|
140
|
-
const access = resolveSessionAccess(request, params.nodeId);
|
|
140
|
+
const access = await resolveSessionAccess(request, params.nodeId, options, 'session');
|
|
141
141
|
if (!access.allowed) {
|
|
142
142
|
sendJson(response, access.status, { error: access.error });
|
|
143
143
|
return;
|
|
@@ -155,7 +155,7 @@ function registerReachabilityRoutes(server, options) {
|
|
|
155
155
|
}
|
|
156
156
|
});
|
|
157
157
|
server.post('/v1/signal/nodes/:nodeId/sessions/:sessionId/candidates', async (request, response, params) => {
|
|
158
|
-
const access = resolveSessionAccess(request, params.nodeId);
|
|
158
|
+
const access = await resolveSessionAccess(request, params.nodeId, options, 'session');
|
|
159
159
|
if (!access.allowed) {
|
|
160
160
|
sendJson(response, access.status, { error: access.error });
|
|
161
161
|
return;
|
|
@@ -214,14 +214,16 @@ function resolveAccess(request, nodeId) {
|
|
|
214
214
|
if (auth.nodeId !== nodeId) {
|
|
215
215
|
return { allowed: false, status: 403, error: 'Node token cannot access another node' };
|
|
216
216
|
}
|
|
217
|
-
|
|
217
|
+
// The node asking about itself stands on its own host, which is the one place its
|
|
218
|
+
// `local-only` loopback access point is usable (`docs/multi-channel-access.md`).
|
|
219
|
+
return { allowed: true, audience: 'local' };
|
|
218
220
|
}
|
|
219
221
|
if ((0, AuthContext_1.isServiceAuth)(auth)) {
|
|
220
222
|
return { allowed: true, audience: 'managed' };
|
|
221
223
|
}
|
|
222
224
|
return { allowed: true, audience: 'public' };
|
|
223
225
|
}
|
|
224
|
-
function resolveSessionAccess(request, nodeId) {
|
|
226
|
+
async function resolveSessionAccess(request, nodeId, options, target) {
|
|
225
227
|
const auth = request.auth;
|
|
226
228
|
if (!auth) {
|
|
227
229
|
return { allowed: false, status: 401, error: 'Authentication required' };
|
|
@@ -233,9 +235,26 @@ function resolveSessionAccess(request, nodeId) {
|
|
|
233
235
|
return { allowed: true, kind: 'node', nodeId: auth.nodeId };
|
|
234
236
|
}
|
|
235
237
|
if ((0, AuthContext_1.isServiceAuth)(auth)) {
|
|
238
|
+
// Service principals act for the deployment, so they must carry the scope that
|
|
239
|
+
// covers reachability sessions instead of being trusted by principal type alone.
|
|
240
|
+
if (!(0, AuthContext_1.hasScope)(auth, 'network:write')) {
|
|
241
|
+
return { allowed: false, status: 403, error: 'Creating a reachability session requires network:write' };
|
|
242
|
+
}
|
|
236
243
|
return { allowed: true, kind: 'service' };
|
|
237
244
|
}
|
|
238
245
|
if ((0, AuthContext_1.isSolidAuth)(auth)) {
|
|
246
|
+
// Node-wide operations need a resolvable relationship to the node (Pod ownership or
|
|
247
|
+
// an explicit grant): being logged in says nothing about this node. Operations on one
|
|
248
|
+
// session are gated by session ownership instead, so the owner keeps access to their
|
|
249
|
+
// own session even when node-wide discovery is not available to them.
|
|
250
|
+
if (target === 'node') {
|
|
251
|
+
const permitted = options.canAccessNode
|
|
252
|
+
? await options.canAccessNode(nodeId, auth.webId)
|
|
253
|
+
: false;
|
|
254
|
+
if (!permitted) {
|
|
255
|
+
return { allowed: false, status: 403, error: 'WebID is not authorized for this node' };
|
|
256
|
+
}
|
|
257
|
+
}
|
|
239
258
|
return { allowed: true, kind: 'solid', webId: auth.webId };
|
|
240
259
|
}
|
|
241
260
|
return { allowed: false, status: 403, error: 'Unsupported reachability session credentials' };
|
|
@@ -2,7 +2,12 @@ import type { NetworkConfigurationPatch, NetworkConfigurationStore, NetworkDesir
|
|
|
2
2
|
type Env = Record<string, string | undefined>;
|
|
3
3
|
export interface NetworkEnvironmentConfigurationStoreOptions {
|
|
4
4
|
read(): Env | Promise<Env>;
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Persists a patch. `removals` lists keys that must be deleted from the environment
|
|
7
|
+
* instead of overwritten — deleting a profile has to take its credential with it,
|
|
8
|
+
* otherwise the leftover secret rebuilds the tunnel the user just closed.
|
|
9
|
+
*/
|
|
10
|
+
write(patch: Record<string, string>, removals?: string[]): void | Promise<void>;
|
|
6
11
|
}
|
|
7
12
|
export declare class NetworkEnvironmentConfigurationStore implements NetworkConfigurationStore {
|
|
8
13
|
private readonly options;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.NetworkEnvironmentConfigurationStore = void 0;
|
|
4
|
+
const TunnelProfiles_1 = require("../../tunnel/TunnelProfiles");
|
|
5
|
+
const TunnelProviderCatalog_1 = require("../../tunnel/TunnelProviderCatalog");
|
|
4
6
|
class NetworkEnvironmentConfigurationStore {
|
|
5
7
|
constructor(options) {
|
|
6
8
|
this.options = options;
|
|
@@ -10,9 +12,13 @@ class NetworkEnvironmentConfigurationStore {
|
|
|
10
12
|
}
|
|
11
13
|
async update(patch) {
|
|
12
14
|
const current = await this.options.read();
|
|
13
|
-
const envPatch = environmentPatch(patch, current);
|
|
14
|
-
await this.options.write(envPatch);
|
|
15
|
-
|
|
15
|
+
const { envPatch, removals } = environmentPatch(patch, current);
|
|
16
|
+
await this.options.write(envPatch, removals);
|
|
17
|
+
const next = { ...current, ...envPatch };
|
|
18
|
+
for (const key of removals) {
|
|
19
|
+
delete next[key];
|
|
20
|
+
}
|
|
21
|
+
return configurationFromEnv(next);
|
|
16
22
|
}
|
|
17
23
|
}
|
|
18
24
|
exports.NetworkEnvironmentConfigurationStore = NetworkEnvironmentConfigurationStore;
|
|
@@ -35,7 +41,12 @@ function configurationFromEnv(env) {
|
|
|
35
41
|
...(env.XPOD_HTTPS_KEY_PATH ? { certificateKeyPath: env.XPOD_HTTPS_KEY_PATH } : {}),
|
|
36
42
|
renewBeforeDays: positiveInteger(env.XPOD_ACME_RENEW_BEFORE_DAYS, 30),
|
|
37
43
|
},
|
|
38
|
-
tunnelProfiles: {
|
|
44
|
+
tunnelProfiles: {
|
|
45
|
+
activeProfileId: env.XPOD_TUNNEL_ACTIVE_PROFILE_ID !== undefined
|
|
46
|
+
? (env.XPOD_TUNNEL_ACTIVE_PROFILE_ID.trim() || TunnelProfiles_1.TUNNEL_ACTIVE_PROFILE_NONE)
|
|
47
|
+
: '',
|
|
48
|
+
profiles,
|
|
49
|
+
},
|
|
39
50
|
p2p: {
|
|
40
51
|
enabled: env.XPOD_P2P_ENABLED === 'true',
|
|
41
52
|
signalService: env.XPOD_P2P_SIGNAL_SERVICE ?? '',
|
|
@@ -45,6 +56,7 @@ function configurationFromEnv(env) {
|
|
|
45
56
|
}
|
|
46
57
|
function environmentPatch(patch, current) {
|
|
47
58
|
const output = {};
|
|
59
|
+
const removals = new Set();
|
|
48
60
|
if (patch.domainDns) {
|
|
49
61
|
assign(output, 'XPOD_DNS_DOMAIN', patch.domainDns.domain);
|
|
50
62
|
assign(output, 'XPOD_DDNS_ENABLED', boolString(patch.domainDns.ddnsEnabled));
|
|
@@ -57,8 +69,10 @@ function environmentPatch(patch, current) {
|
|
|
57
69
|
assign(output, 'XPOD_HTTPS_MODE', patch.https.enabled === undefined ? undefined : patch.https.enabled ? 'acme' : 'off');
|
|
58
70
|
assign(output, 'XPOD_ACME_EMAIL', patch.https.acmeEmail);
|
|
59
71
|
assign(output, 'XPOD_ACME_DOMAINS', patch.https.domains?.join(','));
|
|
60
|
-
|
|
61
|
-
|
|
72
|
+
// The runtime reads the ACME key names; the settings page used to write
|
|
73
|
+
// XPOD_HTTPS_* which nothing consumed.
|
|
74
|
+
assign(output, 'XPOD_ACME_CERTIFICATE_PATH', patch.https.certificatePath);
|
|
75
|
+
assign(output, 'XPOD_ACME_CERTIFICATE_KEY_PATH', patch.https.certificateKeyPath);
|
|
62
76
|
assign(output, 'XPOD_ACME_RENEW_BEFORE_DAYS', numberString(patch.https.renewBeforeDays));
|
|
63
77
|
}
|
|
64
78
|
if (patch.p2p) {
|
|
@@ -67,19 +81,38 @@ function environmentPatch(patch, current) {
|
|
|
67
81
|
assign(output, 'XPOD_P2P_FALLBACK_POLICY', patch.p2p.fallbackPolicy);
|
|
68
82
|
}
|
|
69
83
|
if (patch.tunnelProfiles) {
|
|
70
|
-
|
|
84
|
+
// An empty selection is the explicit off decision, stored as its own value so the
|
|
85
|
+
// runtime can tell it apart from "never configured".
|
|
86
|
+
assign(output, 'XPOD_TUNNEL_ACTIVE_PROFILE_ID', patch.tunnelProfiles.activeProfileId === ''
|
|
87
|
+
? TunnelProfiles_1.TUNNEL_ACTIVE_PROFILE_NONE
|
|
88
|
+
: patch.tunnelProfiles.activeProfileId);
|
|
71
89
|
if (patch.tunnelProfiles.profiles) {
|
|
72
|
-
const serialized = patch.tunnelProfiles.profiles.map(({ credential, ...profile }) =>
|
|
90
|
+
const serialized = patch.tunnelProfiles.profiles.map(({ credential, publicEndpoint, ...profile }) => ({
|
|
91
|
+
...profile,
|
|
92
|
+
// Canonical field name: the runtime reads publicUrl.
|
|
93
|
+
...(profile.publicUrl ?? publicEndpoint ? { publicUrl: profile.publicUrl ?? publicEndpoint } : {}),
|
|
94
|
+
}));
|
|
73
95
|
output.XPOD_TUNNEL_PROFILES = JSON.stringify(serialized);
|
|
74
|
-
for (const profile of patch.tunnelProfiles.profiles)
|
|
75
|
-
if (profile.credential !== undefined)
|
|
76
|
-
output[
|
|
96
|
+
for (const profile of patch.tunnelProfiles.profiles) {
|
|
97
|
+
if (profile.credential !== undefined && profile.credential !== '') {
|
|
98
|
+
output[(0, TunnelProfiles_1.tunnelProfileCredentialEnvKey)(profile.id)] = profile.credential;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// Credentials of profiles that are gone must go with them.
|
|
102
|
+
for (const key of Object.keys(current)) {
|
|
103
|
+
if (!(0, TunnelProviderCatalog_1.isTunnelProfileCredentialEnvKey)(key)) {
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
if (!patch.tunnelProfiles.profiles.some((profile) => (0, TunnelProfiles_1.tunnelProfileCredentialEnvKey)(profile.id) === key)) {
|
|
107
|
+
removals.add(key);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
77
110
|
}
|
|
78
111
|
}
|
|
79
|
-
return output;
|
|
112
|
+
return { envPatch: output, removals: [...removals] };
|
|
80
113
|
}
|
|
81
114
|
function parseProfiles(raw, env) {
|
|
82
|
-
if (
|
|
115
|
+
if (raw === undefined)
|
|
83
116
|
return [];
|
|
84
117
|
try {
|
|
85
118
|
const values = JSON.parse(raw);
|
|
@@ -89,21 +122,44 @@ function parseProfiles(raw, env) {
|
|
|
89
122
|
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
90
123
|
return [];
|
|
91
124
|
const item = value;
|
|
92
|
-
if (typeof item.id !== 'string' || typeof item.label !== 'string' || !
|
|
125
|
+
if (typeof item.id !== 'string' || typeof item.label !== 'string' || !(0, TunnelProviderCatalog_1.isTunnelProviderId)(item.provider))
|
|
93
126
|
return [];
|
|
94
127
|
const provider = item.provider;
|
|
95
|
-
|
|
128
|
+
const publicUrl = firstString(item.publicUrl, item.publicEndpoint);
|
|
129
|
+
const credentialKey = resolveCredentialKey(item.id, provider, env);
|
|
130
|
+
return [{
|
|
131
|
+
id: item.id,
|
|
132
|
+
provider,
|
|
133
|
+
label: item.label,
|
|
134
|
+
...(publicUrl ? { publicUrl } : {}),
|
|
135
|
+
credentialConfigured: Boolean(env[credentialKey]),
|
|
136
|
+
...(plainStringRecord(item.parameters) ? { parameters: item.parameters } : {}),
|
|
137
|
+
}];
|
|
96
138
|
});
|
|
97
139
|
}
|
|
98
140
|
catch {
|
|
99
141
|
return [];
|
|
100
142
|
}
|
|
101
143
|
}
|
|
144
|
+
/** Profile-scoped credential first; a provider-global key still serves legacy setups. */
|
|
145
|
+
function resolveCredentialKey(profileId, provider, env) {
|
|
146
|
+
const scopedKey = (0, TunnelProfiles_1.tunnelProfileCredentialEnvKey)(profileId);
|
|
147
|
+
if (env[scopedKey])
|
|
148
|
+
return scopedKey;
|
|
149
|
+
const legacyKey = (0, TunnelProviderCatalog_1.tunnelProviderDescriptor)(provider)?.legacyCredentialEnvKey;
|
|
150
|
+
return legacyKey && env[legacyKey] ? legacyKey : scopedKey;
|
|
151
|
+
}
|
|
152
|
+
function firstString(...values) {
|
|
153
|
+
for (const value of values) {
|
|
154
|
+
if (typeof value === 'string' && value.trim())
|
|
155
|
+
return value.trim();
|
|
156
|
+
}
|
|
157
|
+
return undefined;
|
|
158
|
+
}
|
|
102
159
|
function splitList(value) { return value?.split(',').map((item) => item.trim()).filter(Boolean) ?? []; }
|
|
103
160
|
function positiveInteger(value, fallback) { const parsed = Number(value); return Number.isInteger(parsed) && parsed > 0 ? parsed : fallback; }
|
|
104
161
|
function dnsCredential(env, provider) { return env[dnsCredentialKey(provider)]; }
|
|
105
162
|
function dnsCredentialKey(provider) { return provider === 'tencent' ? 'XPOD_TENCENT_DNS_TOKEN' : provider === 'cloudflare' ? 'CLOUDFLARE_API_TOKEN' : 'XPOD_DNS_PROVIDER_TOKEN'; }
|
|
106
|
-
function tunnelCredentialKey(provider) { return provider === 'ngrok' ? 'NGROK_AUTHTOKEN' : provider === 'cloudflare' ? 'CLOUDFLARE_TUNNEL_TOKEN' : 'FRP_TUNNEL_TOKEN'; }
|
|
107
163
|
function p2pFallback(value) { return value === 'never' || value === 'prefer-p2p' ? value : 'when-direct-unavailable'; }
|
|
108
164
|
function plainStringRecord(value) { return Boolean(value) && typeof value === 'object' && !Array.isArray(value) && Object.values(value).every((item) => typeof item === 'string'); }
|
|
109
165
|
function boolString(value) { return value === undefined ? undefined : String(value); }
|
package/dist/api/runtime.d.ts
CHANGED
|
@@ -18,4 +18,22 @@ export interface ApiServiceHandle {
|
|
|
18
18
|
stop: () => Promise<void>;
|
|
19
19
|
}
|
|
20
20
|
export declare function autoProvisionFirstRunLocal(config: ApiContainerConfig, logger: ReturnType<typeof getLoggerFor>): Promise<ApiContainerConfig>;
|
|
21
|
+
/**
|
|
22
|
+
* Port a managed tunnel forwards to.
|
|
23
|
+
*
|
|
24
|
+
* It must be the Gateway's ingress listener rather than the gateway port itself:
|
|
25
|
+
* a tunnel terminating on the gateway port reaches the Gateway from loopback and
|
|
26
|
+
* would let forwarded remote requests inherit local trust. Falls back to the
|
|
27
|
+
* historical gateway port only when no ingress listener was provisioned.
|
|
28
|
+
*/
|
|
29
|
+
/**
|
|
30
|
+
* The port a remote tunnel forwards to: the Gateway's tunnel entry.
|
|
31
|
+
*
|
|
32
|
+
* The runtime records the listener it actually bound in `XPOD_GATEWAY_INGRESS_PORT`, and the
|
|
33
|
+
* Gateway's own port is only the fallback for an embedding that started no tunnel entry. The
|
|
34
|
+
* gate is structural - anything arriving on that listener is remote whatever it claims - so a
|
|
35
|
+
* tunnel pointed at the Gateway port by mistake still has the forwarding-header check behind
|
|
36
|
+
* it rather than inheriting local trust.
|
|
37
|
+
*/
|
|
38
|
+
export declare function resolveTunnelIngressPort(env?: NodeJS.ProcessEnv): number;
|
|
21
39
|
export declare function startApiService(options?: StartApiServiceOptions): Promise<ApiServiceHandle>;
|
package/dist/api/runtime.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.autoProvisionFirstRunLocal = autoProvisionFirstRunLocal;
|
|
4
|
+
exports.resolveTunnelIngressPort = resolveTunnelIngressPort;
|
|
4
5
|
exports.startApiService = startApiService;
|
|
5
6
|
const awilix_1 = require("awilix");
|
|
6
7
|
const global_logger_factory_1 = require("global-logger-factory");
|
|
@@ -314,6 +315,32 @@ async function reconcileLocalOwnerRoles(container, config, logger) {
|
|
|
314
315
|
logger.error(`Failed to reconcile local owner roles: ${error}`);
|
|
315
316
|
}
|
|
316
317
|
}
|
|
318
|
+
/**
|
|
319
|
+
* Port a managed tunnel forwards to.
|
|
320
|
+
*
|
|
321
|
+
* It must be the Gateway's ingress listener rather than the gateway port itself:
|
|
322
|
+
* a tunnel terminating on the gateway port reaches the Gateway from loopback and
|
|
323
|
+
* would let forwarded remote requests inherit local trust. Falls back to the
|
|
324
|
+
* historical gateway port only when no ingress listener was provisioned.
|
|
325
|
+
*/
|
|
326
|
+
/**
|
|
327
|
+
* The port a remote tunnel forwards to: the Gateway's tunnel entry.
|
|
328
|
+
*
|
|
329
|
+
* The runtime records the listener it actually bound in `XPOD_GATEWAY_INGRESS_PORT`, and the
|
|
330
|
+
* Gateway's own port is only the fallback for an embedding that started no tunnel entry. The
|
|
331
|
+
* gate is structural - anything arriving on that listener is remote whatever it claims - so a
|
|
332
|
+
* tunnel pointed at the Gateway port by mistake still has the forwarding-header check behind
|
|
333
|
+
* it rather than inheriting local trust.
|
|
334
|
+
*/
|
|
335
|
+
function resolveTunnelIngressPort(env = process.env) {
|
|
336
|
+
for (const value of [env.XPOD_GATEWAY_INGRESS_PORT, env.XPOD_MAIN_PORT, env.XPOD_PORT, env.PORT]) {
|
|
337
|
+
const parsed = Number.parseInt(value ?? '', 10);
|
|
338
|
+
if (Number.isFinite(parsed) && parsed > 0) {
|
|
339
|
+
return parsed;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
return 3000;
|
|
343
|
+
}
|
|
317
344
|
async function startBackgroundServices(container, logger) {
|
|
318
345
|
try {
|
|
319
346
|
const localNetworkManager = container.resolve('localNetworkManager', { allowUnregistered: true });
|
|
@@ -338,10 +365,9 @@ async function startBackgroundServices(container, logger) {
|
|
|
338
365
|
const localTunnelProvider = container.resolve('localTunnelProvider', { allowUnregistered: true });
|
|
339
366
|
if (localTunnelProvider) {
|
|
340
367
|
logger.info('Starting local tunnel provider...');
|
|
341
|
-
const localPort = Number.parseInt(process.env.XPOD_MAIN_PORT ?? process.env.CSS_PORT ?? process.env.PORT ?? '3000', 10);
|
|
342
368
|
const config = await localTunnelProvider.setup({
|
|
343
369
|
subdomain: 'local',
|
|
344
|
-
localPort:
|
|
370
|
+
localPort: resolveTunnelIngressPort(),
|
|
345
371
|
localProtocol: 'http',
|
|
346
372
|
});
|
|
347
373
|
await localTunnelProvider.start(config);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AiClientModelReference } from '@undefineds.co/ai-connections
|
|
1
|
+
import { type AiClientModelReference } from '@undefineds.co/ai-connections/client-config';
|
|
2
2
|
import type { AuthContext } from '../auth/AuthContext';
|
|
3
3
|
export type AiClientId = 'codex' | 'claude-code' | 'pi' | 'codebuddy';
|
|
4
4
|
export interface AiClientConfigurationCapabilityDescriptor {
|
|
@@ -10,7 +10,7 @@ const node_crypto_1 = require("node:crypto");
|
|
|
10
10
|
const node_path_1 = __importDefault(require("node:path"));
|
|
11
11
|
const node_fs_1 = require("node:fs");
|
|
12
12
|
const node_child_process_1 = require("node:child_process");
|
|
13
|
-
const client_config_1 = require("@undefineds.co/ai-connections
|
|
13
|
+
const client_config_1 = require("@undefineds.co/ai-connections/client-config");
|
|
14
14
|
const PLAN_SECRET_PLACEHOLDER = '[redacted]';
|
|
15
15
|
const MANUAL_INSTRUCTIONS = 'Manual client setup is available when this host cannot safely write local coding-client files.';
|
|
16
16
|
const CLIENT_LABELS = {
|
|
@@ -10,12 +10,37 @@ interface StartArgs {
|
|
|
10
10
|
seedConfig?: string;
|
|
11
11
|
}
|
|
12
12
|
export declare const startCommand: CommandModule<object, StartArgs>;
|
|
13
|
+
/**
|
|
14
|
+
* Where remote-forwarded traffic lands on this machine.
|
|
15
|
+
*
|
|
16
|
+
* Order: explicit `XPOD_GATEWAY_INGRESS_PORT` → the active SakuraFrp tunnel's assigned local
|
|
17
|
+
* port → an OS-assigned loopback port. The first two are strict, because a tunnel that
|
|
18
|
+
* forwards to a specific port cannot follow us somewhere else.
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* The port a remote tunnel forwards to: the Gateway's tunnel entry.
|
|
22
|
+
*
|
|
23
|
+
* It is derived from the Gateway port by the same rule the runtime uses, so the CLI can hand
|
|
24
|
+
* it to the managed edge agent before the runtime binds it. A console that forwards somewhere
|
|
25
|
+
* else is a mismatch the tunnel provider reports from its own read-back - the runtime never
|
|
26
|
+
* moves its gate to match a console.
|
|
27
|
+
*/
|
|
28
|
+
export declare function resolveIngressPort(provisionedConfig: {
|
|
29
|
+
tunnelProfiles?: Array<{
|
|
30
|
+
id: string;
|
|
31
|
+
provider: string;
|
|
32
|
+
credentialEnvKey?: string;
|
|
33
|
+
}>;
|
|
34
|
+
tunnelActiveProfileId?: string;
|
|
35
|
+
}, mainPort: number): Promise<number>;
|
|
13
36
|
export declare function resolveCliOidcIssuer(env: Record<string, string | undefined>, provisionedIssuer?: string, edition?: string): string | undefined;
|
|
14
|
-
export declare function resolveManagedEdgeAgentConfig(config: Pick<ReturnType<typeof loadConfigFromEnv>, 'cloudApiEndpoint' | 'nodeId' | 'nodeToken'>, gatewayPort: number): {
|
|
37
|
+
export declare function resolveManagedEdgeAgentConfig(config: Pick<ReturnType<typeof loadConfigFromEnv>, 'cloudApiEndpoint' | 'nodeId' | 'nodeToken'>, gatewayPort: number, ingressPort?: number, runtimeEnv?: Record<string, string | undefined>): {
|
|
15
38
|
signalEndpoint: string;
|
|
16
39
|
nodeId: string;
|
|
17
40
|
nodeToken: string;
|
|
18
41
|
targetBaseUrl: string;
|
|
42
|
+
lanBaseUrl: string;
|
|
43
|
+
p2pEnabled: boolean;
|
|
19
44
|
} | undefined;
|
|
20
45
|
export declare function resolveChildDatabaseUrl(value: string, childCwd: string): string;
|
|
21
46
|
export declare function resolveCanonicalRuntimeBaseUrl(provisionedPublicUrl: string | undefined, configuredBaseUrl: string | undefined, localFallbackUrl: string): string;
|
|
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.startCommand = void 0;
|
|
7
|
+
exports.resolveIngressPort = resolveIngressPort;
|
|
7
8
|
exports.resolveCliOidcIssuer = resolveCliOidcIssuer;
|
|
8
9
|
exports.resolveManagedEdgeAgentConfig = resolveManagedEdgeAgentConfig;
|
|
9
10
|
exports.resolveChildDatabaseUrl = resolveChildDatabaseUrl;
|
|
@@ -15,6 +16,7 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
15
16
|
const global_logger_factory_1 = require("global-logger-factory");
|
|
16
17
|
const supervisor_1 = require("../../supervisor");
|
|
17
18
|
const runtime_1 = require("../../runtime");
|
|
19
|
+
const SakuraFrpTunnelProvider_1 = require("../../tunnel/SakuraFrpTunnelProvider");
|
|
18
20
|
const css_process_1 = require("../../runtime/css-process");
|
|
19
21
|
const oidc_issuer_1 = require("../../runtime/oidc-issuer");
|
|
20
22
|
const AuthMode_1 = require("../../authorization/AuthMode");
|
|
@@ -70,6 +72,10 @@ exports.startCommand = {
|
|
|
70
72
|
process.env[key] ??= value;
|
|
71
73
|
}
|
|
72
74
|
process.env.XPOD_ENV_FILE = envPath;
|
|
75
|
+
// The settings API persists to XPOD_ENV_PATH (falling back to `<cwd>/.env.local`).
|
|
76
|
+
// Without this, a deployment started with `-e custom.env` saved its configuration
|
|
77
|
+
// into a file the runtime never reads.
|
|
78
|
+
process.env.XPOD_ENV_PATH ??= envPath;
|
|
73
79
|
}
|
|
74
80
|
else if (argv.env || process.env.XPOD_ENV_FILE) {
|
|
75
81
|
console.warn(`Env file not found: ${envPath}`);
|
|
@@ -101,6 +107,19 @@ exports.startCommand = {
|
|
|
101
107
|
const cssPort = await (0, runtime_1.getFreePortForWildcard)(requestedCssPort);
|
|
102
108
|
const requestedApiPort = resolveServicePort(process.env.API_PORT, cssPort + 1, new Set([mainPort, cssPort]));
|
|
103
109
|
const apiPort = await (0, runtime_1.getFreePortForWildcard)(requestedApiPort);
|
|
110
|
+
// Remote forwarding (managed tunnels, P2P data plane) terminates on this machine, so
|
|
111
|
+
// its origin is a dedicated ingress port instead of the gateway port: the Gateway
|
|
112
|
+
// never treats requests accepted there as local. An explicit override is honoured;
|
|
113
|
+
// otherwise the OS assigns a loopback port, because neighbouring ports may already
|
|
114
|
+
// belong to another service this deployment planned.
|
|
115
|
+
// The port is a fact of whichever tunnel forwards to us: an explicit override pins it,
|
|
116
|
+
// and the SakuraFrp console's own 本地端口 is read back from the provider, so the
|
|
117
|
+
// operator never types the same number twice. Only an unmanaged ingress is ephemeral.
|
|
118
|
+
// A pinned port is taken as-is: silently moving it would leave the tunnel pointing at a
|
|
119
|
+
// port nobody listens on.
|
|
120
|
+
const ingressPort = await resolveIngressPort(provisionedConfig, mainPort);
|
|
121
|
+
// Published so the API can tell the operator which address a tunnel must forward to.
|
|
122
|
+
process.env.XPOD_GATEWAY_INGRESS_PORT = String(ingressPort);
|
|
104
123
|
const runtimeRoot = path_1.default.join(process.cwd(), '.xpod/runtime/legacy-css');
|
|
105
124
|
const identityDbUrl = resolveChildDatabaseUrl(process.env.CSS_IDENTITY_DB_URL ?? process.env.DATABASE_URL ?? 'sqlite:./data/identity.sqlite', runtimeRoot);
|
|
106
125
|
process.env.CSS_IDENTITY_DB_URL = identityDbUrl;
|
|
@@ -135,7 +154,7 @@ exports.startCommand = {
|
|
|
135
154
|
authMode,
|
|
136
155
|
externalOidcIssuer,
|
|
137
156
|
});
|
|
138
|
-
const managedEdge = resolveManagedEdgeAgentConfig(provisionedConfig, mainPort);
|
|
157
|
+
const managedEdge = resolveManagedEdgeAgentConfig(provisionedConfig, mainPort, ingressPort, process.env);
|
|
139
158
|
const cssArgs = (0, css_process_1.buildCssArgs)({
|
|
140
159
|
cssBinary: '__internal-css',
|
|
141
160
|
configPath: cssRuntimeConfig.configPath,
|
|
@@ -169,6 +188,7 @@ exports.startCommand = {
|
|
|
169
188
|
apiPort,
|
|
170
189
|
mainPort,
|
|
171
190
|
cssPort,
|
|
191
|
+
ingressPort,
|
|
172
192
|
baseUrl,
|
|
173
193
|
rdfIndexPath,
|
|
174
194
|
authMode,
|
|
@@ -180,6 +200,7 @@ exports.startCommand = {
|
|
|
180
200
|
exitOnStop: true,
|
|
181
201
|
baseUrl,
|
|
182
202
|
internalAdminAuthSecret: gatewayAdminProxyAuthSecret,
|
|
203
|
+
ingressPort,
|
|
183
204
|
});
|
|
184
205
|
proxy.setTargets({
|
|
185
206
|
css: `http://localhost:${cssPort}`,
|
|
@@ -195,8 +216,9 @@ exports.startCommand = {
|
|
|
195
216
|
nodeToken: managedEdge.nodeToken,
|
|
196
217
|
baseUrl,
|
|
197
218
|
p2p: {
|
|
198
|
-
enabled:
|
|
219
|
+
enabled: managedEdge.p2pEnabled,
|
|
199
220
|
targetBaseUrl: managedEdge.targetBaseUrl,
|
|
221
|
+
lanBaseUrl: managedEdge.lanBaseUrl,
|
|
200
222
|
},
|
|
201
223
|
});
|
|
202
224
|
}
|
|
@@ -210,20 +232,62 @@ exports.startCommand = {
|
|
|
210
232
|
process.on('SIGINT', () => shutdown('SIGINT'));
|
|
211
233
|
},
|
|
212
234
|
};
|
|
235
|
+
/**
|
|
236
|
+
* Where remote-forwarded traffic lands on this machine.
|
|
237
|
+
*
|
|
238
|
+
* Order: explicit `XPOD_GATEWAY_INGRESS_PORT` → the active SakuraFrp tunnel's assigned local
|
|
239
|
+
* port → an OS-assigned loopback port. The first two are strict, because a tunnel that
|
|
240
|
+
* forwards to a specific port cannot follow us somewhere else.
|
|
241
|
+
*/
|
|
242
|
+
/**
|
|
243
|
+
* The port a remote tunnel forwards to: the Gateway's tunnel entry.
|
|
244
|
+
*
|
|
245
|
+
* It is derived from the Gateway port by the same rule the runtime uses, so the CLI can hand
|
|
246
|
+
* it to the managed edge agent before the runtime binds it. A console that forwards somewhere
|
|
247
|
+
* else is a mismatch the tunnel provider reports from its own read-back - the runtime never
|
|
248
|
+
* moves its gate to match a console.
|
|
249
|
+
*/
|
|
250
|
+
async function resolveIngressPort(provisionedConfig, mainPort) {
|
|
251
|
+
const port = await (0, runtime_1.findGatewayIngressPort)(mainPort);
|
|
252
|
+
const active = provisionedConfig.tunnelProfiles?.find((profile) => profile.id === provisionedConfig.tunnelActiveProfileId) ?? provisionedConfig.tunnelProfiles?.find((profile) => profile.provider === 'sakura_frp');
|
|
253
|
+
if (active?.provider === 'sakura_frp') {
|
|
254
|
+
const credential = active.credentialEnvKey
|
|
255
|
+
? process.env[active.credentialEnvKey] ?? process.env.SAKURA_TUNNEL_TOKEN
|
|
256
|
+
: process.env.SAKURA_TUNNEL_TOKEN;
|
|
257
|
+
const assigned = await (0, SakuraFrpTunnelProvider_1.resolveSakuraAssignedLocalPort)(credential);
|
|
258
|
+
if (assigned !== undefined && assigned !== port) {
|
|
259
|
+
(0, global_logger_factory_1.getLoggerFor)('XpodStart').warn(`The Sakura console forwards to local port ${assigned}, but this runtime's tunnel entry is ${port}; `
|
|
260
|
+
+ `update the tunnel's local port in the console to ${port}`);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return port;
|
|
264
|
+
}
|
|
213
265
|
function resolveCliOidcIssuer(env, provisionedIssuer, edition) {
|
|
214
266
|
return (0, oidc_issuer_1.resolveExternalOidcIssuer)(env)
|
|
215
267
|
?? (0, oidc_issuer_1.resolveExternalOidcIssuer)({ SOLID_OIDC_ISSUER: provisionedIssuer })
|
|
216
268
|
?? (edition === 'local' ? oidc_issuer_1.DEFAULT_LOCAL_OIDC_ISSUER : undefined);
|
|
217
269
|
}
|
|
218
|
-
function resolveManagedEdgeAgentConfig(config, gatewayPort) {
|
|
270
|
+
function resolveManagedEdgeAgentConfig(config, gatewayPort, ingressPort, runtimeEnv = {}) {
|
|
219
271
|
if (!config.cloudApiEndpoint || !config.nodeId || !config.nodeToken) {
|
|
220
272
|
return undefined;
|
|
221
273
|
}
|
|
274
|
+
const gatewayBaseUrl = `http://127.0.0.1:${gatewayPort}/`;
|
|
275
|
+
// The settings page owns these two decisions; the managed node identity only supplies
|
|
276
|
+
// the signal endpoint they run against.
|
|
277
|
+
const declaredSignalService = runtimeEnv.XPOD_P2P_SIGNAL_SERVICE?.trim();
|
|
278
|
+
const p2pDisabled = runtimeEnv.XPOD_P2P_ENABLED?.trim().toLowerCase() === 'false';
|
|
222
279
|
return {
|
|
223
|
-
signalEndpoint:
|
|
280
|
+
signalEndpoint: declaredSignalService
|
|
281
|
+
|| new URL('/v1/signal', config.cloudApiEndpoint).toString(),
|
|
224
282
|
nodeId: config.nodeId,
|
|
225
283
|
nodeToken: config.nodeToken,
|
|
226
|
-
|
|
284
|
+
// Forwarded peer traffic enters through the ingress listener, which never counts
|
|
285
|
+
// as local. LAN clients keep addressing the gateway listener, which they can reach.
|
|
286
|
+
targetBaseUrl: ingressPort === undefined ? gatewayBaseUrl : `http://127.0.0.1:${ingressPort}/`,
|
|
287
|
+
lanBaseUrl: gatewayBaseUrl,
|
|
288
|
+
// Peer-to-peer transport is off by default unless the deployment asked for it; an
|
|
289
|
+
// explicit false must actually stop it.
|
|
290
|
+
p2pEnabled: !p2pDisabled && runtimeEnv.XPOD_P2P_ENABLED?.trim().toLowerCase() === 'true',
|
|
227
291
|
};
|
|
228
292
|
}
|
|
229
293
|
function resolveChildDatabaseUrl(value, childCwd) {
|
|
@@ -31,7 +31,6 @@
|
|
|
31
31
|
"undefineds:dist/logging/ConfigurableLoggerFactory.jsonld",
|
|
32
32
|
"undefineds:dist/storage/SparqlUpdateResourceStore.jsonld",
|
|
33
33
|
"undefineds:dist/http/SubgraphSparqlHttpHandler.jsonld",
|
|
34
|
-
"undefineds:dist/http/InternalPodDataHttpHandler.jsonld",
|
|
35
34
|
"undefineds:dist/http/quota/QuotaAdminHttpHandler.jsonld",
|
|
36
35
|
"undefineds:dist/http/ClusterIngressRouter.jsonld",
|
|
37
36
|
"undefineds:dist/http/ClusterWebSocketConfigurator.jsonld",
|
|
@@ -134,6 +133,7 @@
|
|
|
134
133
|
"undefineds:dist/api/reconciler/WakeAgentQueue.jsonld",
|
|
135
134
|
"undefineds:dist/api/reconciler/ServerGroupReconcilerService.jsonld",
|
|
136
135
|
"undefineds:dist/edge/reachability/types.jsonld",
|
|
136
|
+
"undefineds:dist/edge/reachability/RouteSetBuilder.jsonld",
|
|
137
137
|
"undefineds:dist/edge/reachability/ReachabilitySessionService.jsonld",
|
|
138
138
|
"undefineds:dist/edge/reachability/ManagedRouteSelector.jsonld",
|
|
139
139
|
"undefineds:dist/edge/reachability/CanonicalFetch.jsonld",
|