@undefineds.co/xpod 0.4.14 → 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/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/quota/ProviderQuotaAdapter.d.ts +3 -3
- package/dist/api/ai-gateway/quota/ProviderQuotaAdapter.js +7 -32
- 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/local.js +62 -29
- package/dist/api/container/routes.js +39 -7
- package/dist/api/container/types.d.ts +2 -2
- package/dist/api/handlers/AiGatewayManagementHandler.d.ts +6 -0
- package/dist/api/handlers/AiGatewayManagementHandler.js +17 -4
- package/dist/api/handlers/NetworkSettingsHandler.d.ts +7 -0
- package/dist/api/handlers/NetworkSettingsHandler.js +7 -0
- package/dist/api/handlers/PodSettingsHandler.d.ts +3 -3
- package/dist/api/handlers/PodSettingsHandler.js +3 -3
- package/dist/api/handlers/ProvisionHandler.d.ts +29 -0
- package/dist/api/handlers/ProvisionHandler.js +46 -0
- package/dist/api/handlers/ReachabilityHandler.js +3 -1
- package/dist/api/runtime.d.ts +9 -0
- package/dist/api/runtime.js +16 -3
- package/dist/cli/commands/start.d.ts +9 -2
- package/dist/cli/commands/start.js +15 -17
- package/dist/components/components.jsonld +1 -1
- package/dist/components/context.jsonld +5 -42
- package/dist/edge/EdgeNodeAgent.d.ts +10 -0
- package/dist/edge/EdgeNodeAgent.js +55 -0
- package/dist/edge/EdgeNodeAgent.jsonld +8 -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 +1 -2
- package/dist/index.js +3 -5
- package/dist/runtime/GatewayAdminProxyAuth.d.ts +1 -16
- package/dist/runtime/GatewayAdminProxyAuth.js +2 -71
- package/dist/runtime/Proxy.d.ts +10 -1
- package/dist/runtime/Proxy.js +95 -28
- package/dist/runtime/bootstrap.d.ts +10 -0
- package/dist/runtime/bootstrap.js +24 -0
- package/dist/runtime/host/node/NodeRuntimeHost.js +5 -3
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.js +2 -3
- package/dist/runtime/js-runtime.js +10 -3
- package/dist/runtime/lifecycle.js +5 -4
- package/dist/runtime/port-finder.d.ts +9 -13
- package/dist/runtime/port-finder.js +18 -37
- package/dist/tunnel/AutoTunnelProvider.d.ts +56 -0
- package/dist/tunnel/AutoTunnelProvider.js +181 -0
- package/dist/tunnel/index.d.ts +1 -0
- package/dist/tunnel/index.js +3 -1
- package/node_modules/@undefineds.co/ai-connections/dist/error-wording.js +7 -2
- 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 +2 -2
- package/static/app/assets/inrupt-smoke.js +23 -23
- package/static/auth-callback/assets/{AiConfigContext-DCXpjzpj.js → AiConfigContext-Bx0HCAW5.js} +1 -1
- package/static/auth-callback/assets/{AiConfigPage-fe-xMIXa.js → AiConfigPage-ChQImMbm.js} +1 -1
- package/static/auth-callback/assets/{DocumentProcessingPanel-BGnkfMuU.js → DocumentProcessingPanel-D830H4SH.js} +1 -1
- package/static/auth-callback/assets/{IndexLifecyclePanel-42Jups0j.js → IndexLifecyclePanel-CnlkjMF8.js} +1 -1
- package/static/auth-callback/assets/{IndexSubjectPanel-CYyLOlQU.js → IndexSubjectPanel-CdEfg_CO.js} +1 -1
- package/static/auth-callback/assets/{ModelAssignmentsPanel-BOvUH4yr.js → ModelAssignmentsPanel-D-8A8dZx.js} +1 -1
- package/static/auth-callback/assets/{ModelsPage-DwyITxt7.js → ModelsPage-Cim7cubp.js} +3 -3
- package/static/auth-callback/assets/{NetworkPage-CG9RelJA.js → NetworkPage-CfK3x-pb.js} +2 -2
- package/static/auth-callback/assets/{PaneListHeader-yvd5ohs6.js → PaneListHeader-Bf_kEd4U.js} +1 -1
- package/static/auth-callback/assets/{SearchIndexingPanel-2_a6ezzj.js → SearchIndexingPanel-4kD4RBEQ.js} +1 -1
- package/static/auth-callback/assets/{StatusSubjectPanel-8qtVxnzC.js → StatusSubjectPanel-Bw9AiTSf.js} +1 -1
- package/static/auth-callback/assets/{StatusWorkspace-CBdRahCF.js → StatusWorkspace-C-301H-0.js} +1 -1
- package/static/auth-callback/assets/{SystemSettingsPage-BZJ6vWkg.js → SystemSettingsPage-BbWn-eG6.js} +1 -1
- package/static/auth-callback/assets/{SystemSettingsSubjectPanel-xm08UhXP.js → SystemSettingsSubjectPanel-DA4wvNSm.js} +1 -1
- package/static/auth-callback/assets/{XpodAiConnectionsPodStore-V6vgGfuw.js → XpodAiConnectionsPodStore-CohdyLoX.js} +1 -1
- package/static/auth-callback/assets/{activity-CeM7xly8.js → activity-CCsb9Oam.js} +1 -1
- package/static/auth-callback/assets/ai-connections-DexTPyfC.js +1 -0
- package/static/auth-callback/assets/{auth-callback-DTG8cSj7.js → auth-callback-Ds-c62W3.js} +5 -5
- package/static/auth-callback/assets/{badge-qJo2Zr4d.js → badge-CQm5OyzR.js} +1 -1
- package/static/auth-callback/assets/{collection-runtime-Bztsz31a.js → collection-runtime-DlAuU5TW.js} +1 -1
- package/static/auth-callback/assets/{dialog-D-h6x5x0.js → dialog-CnGzg5Ff.js} +1 -1
- package/static/auth-callback/assets/{download-C2ir4lmR.js → download-DwMONJvm.js} +1 -1
- package/static/auth-callback/assets/{external-link-THLDL4On.js → external-link-Bu5AGqCO.js} +1 -1
- package/static/auth-callback/assets/{index-BlVZb9A7.js → index-B0T-1YO8.js} +1 -1
- package/static/auth-callback/assets/{index-BRpv4yO3.js → index-C8QZf_4W.js} +1 -1
- package/static/auth-callback/assets/{index-D983R1FV.js → index-DwIlrIDG.js} +1 -1
- package/static/auth-callback/assets/{index-browser-3FvR0aaf.js → index-browser-lRsMcP_7.js} +1 -1
- package/static/auth-callback/assets/{key-round-C9U5j1Ly.js → key-round-BDMtU57P.js} +1 -1
- package/static/auth-callback/assets/{rotate-ccw-DP45cD4o.js → rotate-ccw-CoKIGCsQ.js} +1 -1
- package/static/auth-callback/assets/{skeleton-Dn4EiSCS.js → skeleton-CPoSWHDr.js} +1 -1
- package/static/auth-callback/assets/{waypoints-uqFQ3uEG.js → waypoints-BeYHxqHv.js} +1 -1
- package/static/auth-callback/assets/{workspace-layout-DLYK0Wwu.js → workspace-layout-xA5YxiK3.js} +1 -1
- package/static/auth-callback/auth-callback.html +1 -1
- package/static/dashboard/assets/{AiConfigContext-DJcMECNw.js → AiConfigContext-rWx4TyiH.js} +1 -1
- package/static/dashboard/assets/{AiConfigPage-BvE7dOTy.js → AiConfigPage-StVJpDFT.js} +1 -1
- package/static/dashboard/assets/{DocumentProcessingPanel-D9780krf.js → DocumentProcessingPanel-DJ5yul2O.js} +1 -1
- package/static/dashboard/assets/{IndexLifecyclePanel-SjsUcnbM.js → IndexLifecyclePanel-CpjtgezK.js} +1 -1
- package/static/dashboard/assets/{IndexSubjectPanel-C-ym2Tqi.js → IndexSubjectPanel-BVKcot1_.js} +1 -1
- package/static/dashboard/assets/{ModelAssignmentsPanel-BRjZ-arB.js → ModelAssignmentsPanel-BxVgWZPc.js} +1 -1
- package/static/dashboard/assets/{ModelsPage-BtTU6du3.js → ModelsPage-CECBwmeO.js} +3 -3
- package/static/dashboard/assets/{NetworkPage-CV9qpkDg.js → NetworkPage-zQgFscEW.js} +2 -2
- package/static/dashboard/assets/{PaneListHeader-KyPTTBsv.js → PaneListHeader-DIPe8pS6.js} +1 -1
- package/static/dashboard/assets/{SearchIndexingPanel-DolHGawg.js → SearchIndexingPanel-lalFJ3c8.js} +1 -1
- package/static/dashboard/assets/{StatusSubjectPanel-_YZvKiYi.js → StatusSubjectPanel-CpY_KU-G.js} +1 -1
- package/static/dashboard/assets/{StatusWorkspace-Dlbh_G40.js → StatusWorkspace-BwWCii3A.js} +1 -1
- package/static/dashboard/assets/{SystemSettingsPage-Be7QSIoz.js → SystemSettingsPage-BKZxX-_n.js} +1 -1
- package/static/dashboard/assets/{SystemSettingsSubjectPanel-DBp0gja7.js → SystemSettingsSubjectPanel-BZrqb2C5.js} +1 -1
- package/static/dashboard/assets/{XpodAiConnectionsPodStore-ClpSjzpP.js → XpodAiConnectionsPodStore-Bbpx9dTN.js} +1 -1
- package/static/dashboard/assets/{activity-lsNbTXJu.js → activity-BJ15TLVP.js} +1 -1
- package/static/dashboard/assets/ai-connections-GG6qkTJt.js +1 -0
- package/static/dashboard/assets/{badge-CVatKjaG.js → badge-BBX5FlaB.js} +1 -1
- package/static/dashboard/assets/{collection-runtime-Ec4UnY28.js → collection-runtime-UBbHBzdf.js} +1 -1
- package/static/dashboard/assets/{dashboard-BEzsRsvF.js → dashboard-7Y6BHyV9.js} +62 -62
- package/static/dashboard/assets/{dialog-BuyelQ4V.js → dialog-QrOJ-hB0.js} +1 -1
- package/static/dashboard/assets/{download-B4Nf678F.js → download-DK9x-VOP.js} +1 -1
- package/static/dashboard/assets/{external-link-PYv9CvKL.js → external-link-Cnkn87mJ.js} +1 -1
- package/static/dashboard/assets/{index-C9XPE-mI.js → index-B1z84it5.js} +1 -1
- package/static/dashboard/assets/{index-awr7ulur.js → index-DzjauX3N.js} +1 -1
- package/static/dashboard/assets/{index-Cx69bTNh.js → index-cIa8_efI.js} +1 -1
- package/static/dashboard/assets/{key-round-VsY80U1Z.js → key-round-BoS6UqKz.js} +1 -1
- package/static/dashboard/assets/{rotate-ccw-Cz1K4vE9.js → rotate-ccw-BeWV76i0.js} +1 -1
- package/static/dashboard/assets/{skeleton-BhNv_8tO.js → skeleton-CypcJL07.js} +1 -1
- package/static/dashboard/assets/{waypoints-DYS9XFYV.js → waypoints-zHOOqfhi.js} +1 -1
- package/static/dashboard/assets/{workspace-layout-OZJAFx5V.js → workspace-layout-DZ9JuxnM.js} +1 -1
- package/static/dashboard/dashboard.html +1 -1
- package/static/settings/assets/{AiConfigContext-B8JS3MXF.js → AiConfigContext-D3b1l_Kw.js} +1 -1
- package/static/settings/assets/{AiConfigPage-C3Zl8LUl.js → AiConfigPage-DYKw-atP.js} +1 -1
- package/static/settings/assets/{DocumentProcessingPanel-DpDZAQvf.js → DocumentProcessingPanel-DguRfsIV.js} +1 -1
- package/static/settings/assets/{IndexLifecyclePanel-Ec1XF88t.js → IndexLifecyclePanel-B85qJJA4.js} +1 -1
- package/static/settings/assets/{IndexSubjectPanel-BulT9BmO.js → IndexSubjectPanel-CsN7IxaV.js} +1 -1
- package/static/settings/assets/{ModelAssignmentsPanel-BcGSmYjb.js → ModelAssignmentsPanel-DEp9byI6.js} +1 -1
- package/static/settings/assets/{ModelsPage-CvTCKy1T.js → ModelsPage-CzTnPs_G.js} +3 -3
- package/static/settings/assets/{NetworkPage-DQF5u9Bn.js → NetworkPage-BDVnmUU0.js} +2 -2
- package/static/settings/assets/{PaneListHeader-D40hqcVl.js → PaneListHeader-Cpe39N76.js} +1 -1
- package/static/settings/assets/{SearchIndexingPanel-iCUPOx_0.js → SearchIndexingPanel-DA9w8lLL.js} +1 -1
- package/static/settings/assets/{StatusSubjectPanel-E--ZHSql.js → StatusSubjectPanel-BU0Aq0CS.js} +1 -1
- package/static/settings/assets/{StatusWorkspace-YjDAx1II.js → StatusWorkspace-D1AC1i5N.js} +1 -1
- package/static/settings/assets/{SystemSettingsPage-CDdV3mC9.js → SystemSettingsPage-ChKvOioO.js} +1 -1
- package/static/settings/assets/{SystemSettingsSubjectPanel-Br8WazDq.js → SystemSettingsSubjectPanel-DyTpOnD2.js} +1 -1
- package/static/settings/assets/{XpodAiConnectionsPodStore-CLr38P_Z.js → XpodAiConnectionsPodStore-VU5Bsz1a.js} +1 -1
- package/static/settings/assets/{activity-C5DAHHTE.js → activity-DGpLfsQB.js} +1 -1
- package/static/settings/assets/ai-connections-DexTPyfC.js +1 -0
- package/static/settings/assets/{badge-D8eIyxKt.js → badge-_hCrrWRP.js} +1 -1
- package/static/settings/assets/{collection-runtime-DLc9zil8.js → collection-runtime-E40TZ8Cl.js} +1 -1
- package/static/settings/assets/{dialog-CyuR7Va4.js → dialog-DTr2JkHn.js} +1 -1
- package/static/settings/assets/{download-c0oxZrCz.js → download-B_D21DDX.js} +1 -1
- package/static/settings/assets/{external-link-D3Z34fP_.js → external-link-BATYaM13.js} +1 -1
- package/static/settings/assets/{index-CSr3-2Cj.js → index-BAlAVi-J.js} +1 -1
- package/static/settings/assets/{index-ComidxAm.js → index-Ckh4h9jj.js} +1 -1
- package/static/settings/assets/{index-CKGbRFlc.js → index-DOiwLF4B.js} +1 -1
- package/static/settings/assets/{index-browser-CAscEbae.js → index-browser-DFFWN3Kr.js} +1 -1
- package/static/settings/assets/{key-round-DyjLmXuB.js → key-round-ZTVU_1O1.js} +1 -1
- package/static/settings/assets/{rotate-ccw-679HF_ec.js → rotate-ccw-DDdw8PTU.js} +1 -1
- package/static/settings/assets/{settings-DKknqu4C.js → settings-CyLnISOv.js} +62 -62
- package/static/settings/assets/{skeleton-CkopNkPB.js → skeleton-DEzA3hc2.js} +1 -1
- package/static/settings/assets/{waypoints-CrqfAftE.js → waypoints-BSdfNvEb.js} +1 -1
- package/static/settings/assets/{workspace-layout-UN6c4qTG.js → workspace-layout-BOQnl_3d.js} +1 -1
- package/static/settings/settings.html +1 -1
- 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/static/auth-callback/assets/ai-connections-C6yaE6WQ.js +0 -1
- package/static/dashboard/assets/ai-connections-CXp5gd1J.js +0 -1
- package/static/settings/assets/ai-connections-C6yaE6WQ.js +0 -1
package/config/cloud.json
CHANGED
package/config/local.json
CHANGED
package/config/xpod.base.json
CHANGED
|
@@ -404,30 +404,6 @@
|
|
|
404
404
|
"value": 0
|
|
405
405
|
}
|
|
406
406
|
},
|
|
407
|
-
{
|
|
408
|
-
"comment": "Loopback-only runtime-signed hosted Pod data channel for AI Connection resources.",
|
|
409
|
-
"@type": "https://linkedsoftwaredependencies.org/bundles/npm/@undefineds.co/xpod/^0.0.0/dist/http/InternalPodDataHttpHandler.jsonld#InternalPodDataHttpHandler",
|
|
410
|
-
"@id": "urn:undefineds:xpod:InternalPodDataHttpHandler",
|
|
411
|
-
"@context": {
|
|
412
|
-
"resourceStore": "https://linkedsoftwaredependencies.org/bundles/npm/@undefineds.co/xpod/^0.0.0/dist/http/InternalPodDataHttpHandler.jsonld#InternalPodDataHttpHandler_options_resourceStore",
|
|
413
|
-
"patchBodyParser": "https://linkedsoftwaredependencies.org/bundles/npm/@undefineds.co/xpod/^0.0.0/dist/http/InternalPodDataHttpHandler.jsonld#InternalPodDataHttpHandler_options_patchBodyParser",
|
|
414
|
-
"sparqlHandler": "https://linkedsoftwaredependencies.org/bundles/npm/@undefineds.co/xpod/^0.0.0/dist/http/InternalPodDataHttpHandler.jsonld#InternalPodDataHttpHandler_options_sparqlHandler",
|
|
415
|
-
"baseUrl": "https://linkedsoftwaredependencies.org/bundles/npm/@undefineds.co/xpod/^0.0.0/dist/http/InternalPodDataHttpHandler.jsonld#InternalPodDataHttpHandler_options_baseUrl"
|
|
416
|
-
},
|
|
417
|
-
"resourceStore": {
|
|
418
|
-
"@id": "urn:solid-server:default:ResourceStore"
|
|
419
|
-
},
|
|
420
|
-
"patchBodyParser": {
|
|
421
|
-
"@id": "urn:solid-server:default:PatchBodyParser"
|
|
422
|
-
},
|
|
423
|
-
"sparqlHandler": {
|
|
424
|
-
"@id": "urn:undefineds:xpod:SubgraphSparqlHttpHandler"
|
|
425
|
-
},
|
|
426
|
-
"baseUrl": {
|
|
427
|
-
"@id": "urn:solid-server:default:variable:baseUrl",
|
|
428
|
-
"@type": "Variable"
|
|
429
|
-
}
|
|
430
|
-
},
|
|
431
407
|
{
|
|
432
408
|
"comment": "Tracing handler for request ID and logging. Added to CSS Middleware.",
|
|
433
409
|
"@id": "urn:undefineds:xpod:TracingHandler",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { SolidAuthContext } from '../auth/AuthContext';
|
|
2
|
-
import type {
|
|
2
|
+
import type { PodAccessFetchProvider } from '../ai-gateway/pod/OwnerPodAccess';
|
|
3
3
|
import type { AiConfigPolicy, AiConfigPolicyPatch, AiConfigPolicyStore } from '../handlers/AiConfigHandler';
|
|
4
4
|
interface AiConfigDb {
|
|
5
5
|
init?: (...resources: unknown[]) => Promise<void>;
|
|
@@ -12,7 +12,7 @@ interface AiConfigDb {
|
|
|
12
12
|
};
|
|
13
13
|
}
|
|
14
14
|
export interface DrizzlePodAiConfigStoreOptions {
|
|
15
|
-
|
|
15
|
+
podAccess?: PodAccessFetchProvider;
|
|
16
16
|
dbFactory?: (input: {
|
|
17
17
|
webId: string;
|
|
18
18
|
podUrl: string;
|
|
@@ -34,7 +34,10 @@ class DrizzlePodAiConfigStore {
|
|
|
34
34
|
return mergedPolicy;
|
|
35
35
|
}
|
|
36
36
|
async open(input) {
|
|
37
|
-
const trustedFetch = await this.options.
|
|
37
|
+
const trustedFetch = await this.options.podAccess?.getPodFetch(input.webId, {
|
|
38
|
+
...(input.auth ? { auth: input.auth } : {}),
|
|
39
|
+
podBaseUrl: input.podUrl,
|
|
40
|
+
});
|
|
38
41
|
if (!trustedFetch)
|
|
39
42
|
throw new Error('service_access_missing');
|
|
40
43
|
const db = await this.dbFactory({ ...input, fetch: trustedFetch });
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import type { AuthContext } from '../../auth/AuthContext';
|
|
2
|
+
import { type HostedPodRoute } from '../pod/HostedPodRoute';
|
|
2
3
|
export declare const CALLER_POD_ACCESS_UNAVAILABLE = "caller_pod_access_unavailable";
|
|
3
4
|
export declare const CALLER_DPOP_REPLAY_UNSUPPORTED = "caller_dpop_replay_unsupported";
|
|
4
5
|
export declare const CALLER_OWNER_MISMATCH = "caller_owner_mismatch";
|
|
5
|
-
export declare function createCallerAuthenticatedPodFetch(owner: string, auth?: AuthContext, upstream?: typeof fetch): typeof fetch | undefined;
|
|
6
|
-
export declare function callerPodAccessError(owner: string, auth?: AuthContext): string;
|
|
7
|
-
export declare function isInternalPodAccessAllowed(auth?: AuthContext, options?: {
|
|
8
|
-
explicitInternalAccess?: boolean;
|
|
9
|
-
}): boolean;
|
|
6
|
+
export declare function createCallerAuthenticatedPodFetch(owner: string, auth?: AuthContext, upstream?: typeof fetch, route?: HostedPodRoute): typeof fetch | undefined;
|
|
@@ -2,12 +2,11 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CALLER_OWNER_MISMATCH = exports.CALLER_DPOP_REPLAY_UNSUPPORTED = exports.CALLER_POD_ACCESS_UNAVAILABLE = void 0;
|
|
4
4
|
exports.createCallerAuthenticatedPodFetch = createCallerAuthenticatedPodFetch;
|
|
5
|
-
|
|
6
|
-
exports.isInternalPodAccessAllowed = isInternalPodAccessAllowed;
|
|
5
|
+
const HostedPodRoute_1 = require("../pod/HostedPodRoute");
|
|
7
6
|
exports.CALLER_POD_ACCESS_UNAVAILABLE = 'caller_pod_access_unavailable';
|
|
8
7
|
exports.CALLER_DPOP_REPLAY_UNSUPPORTED = 'caller_dpop_replay_unsupported';
|
|
9
8
|
exports.CALLER_OWNER_MISMATCH = 'caller_owner_mismatch';
|
|
10
|
-
function createCallerAuthenticatedPodFetch(owner, auth, upstream = fetch) {
|
|
9
|
+
function createCallerAuthenticatedPodFetch(owner, auth, upstream = fetch, route) {
|
|
11
10
|
if (!auth
|
|
12
11
|
|| auth.type !== 'solid'
|
|
13
12
|
|| auth.webId !== owner
|
|
@@ -30,51 +29,13 @@ function createCallerAuthenticatedPodFetch(owner, auth, upstream = fetch) {
|
|
|
30
29
|
headers,
|
|
31
30
|
});
|
|
32
31
|
};
|
|
33
|
-
const route = localHostedPodRoute();
|
|
34
32
|
if (!route) {
|
|
35
33
|
return authenticatedFetch;
|
|
36
34
|
}
|
|
37
|
-
// The API runtime is CommonJS while solid-sdk is intentionally ESM-only.
|
|
38
|
-
// Keep the package boundary and load the SDK lazily without TypeScript
|
|
39
|
-
// lowering import() to require().
|
|
40
35
|
let routedFetch;
|
|
41
36
|
return async (input, init) => {
|
|
42
|
-
routedFetch ??=
|
|
37
|
+
routedFetch ??= (0, HostedPodRoute_1.createHostedPodRouteTransport)(authenticatedFetch, route);
|
|
43
38
|
return (await routedFetch)(input, init);
|
|
44
39
|
};
|
|
45
40
|
}
|
|
46
|
-
async function importSolidLocalRouteFetch() {
|
|
47
|
-
const dynamicImport = new Function('specifier', 'return import(specifier)');
|
|
48
|
-
return dynamicImport('@undefineds.co/solid-sdk/local-route-fetch');
|
|
49
|
-
}
|
|
50
|
-
function localHostedPodRoute() {
|
|
51
|
-
const canonicalBaseUrl = process.env.CSS_BASE_URL?.trim();
|
|
52
|
-
const mainPort = process.env.XPOD_MAIN_PORT?.trim();
|
|
53
|
-
if (!canonicalBaseUrl || !mainPort || !/^\d+$/u.test(mainPort)) {
|
|
54
|
-
return undefined;
|
|
55
|
-
}
|
|
56
|
-
return {
|
|
57
|
-
canonicalBaseUrl,
|
|
58
|
-
localBaseUrl: `http://127.0.0.1:${mainPort}/`,
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
function callerPodAccessError(owner, auth) {
|
|
62
|
-
if (!auth || auth.type !== 'solid') {
|
|
63
|
-
return exports.CALLER_POD_ACCESS_UNAVAILABLE;
|
|
64
|
-
}
|
|
65
|
-
if (auth.webId !== owner) {
|
|
66
|
-
return exports.CALLER_OWNER_MISMATCH;
|
|
67
|
-
}
|
|
68
|
-
if (auth.tokenType === 'DPoP' || typeof auth.dpopProof === 'string') {
|
|
69
|
-
return exports.CALLER_DPOP_REPLAY_UNSUPPORTED;
|
|
70
|
-
}
|
|
71
|
-
return exports.CALLER_POD_ACCESS_UNAVAILABLE;
|
|
72
|
-
}
|
|
73
|
-
function isInternalPodAccessAllowed(auth, options = {}) {
|
|
74
|
-
return options.explicitInternalAccess === true
|
|
75
|
-
|| (auth?.type === 'solid' && (auth.viaApiKey === true
|
|
76
|
-
||
|
|
77
|
-
auth.internalInvocation === true
|
|
78
|
-
|| (auth.viaGatewayApiKey === true && auth.gatewayRuntimeAccess === true)));
|
|
79
|
-
}
|
|
80
41
|
//# sourceMappingURL=CallerPodAccess.js.map
|
|
@@ -30,7 +30,8 @@ export declare const LEGACY_GATEWAY_KEY_AUTHENTICATION = "legacy-gateway-key-aut
|
|
|
30
30
|
export type GatewayAccessKeyRepositoryInternalAccessReason = typeof LEGACY_GATEWAY_KEY_AUTHENTICATION | 'gateway-key-verifier';
|
|
31
31
|
export interface GatewayAccessKeyRepositoryContext {
|
|
32
32
|
auth?: AuthContext;
|
|
33
|
-
|
|
33
|
+
/** Set when the gateway itself is verifying a key, rather than serving an owner request. */
|
|
34
|
+
gatewayKeyVerification?: {
|
|
34
35
|
reason: GatewayAccessKeyRepositoryInternalAccessReason;
|
|
35
36
|
};
|
|
36
37
|
}
|
|
@@ -44,7 +44,7 @@ class GatewayApiKeyAuthenticator {
|
|
|
44
44
|
return infrastructureError(new Error('Gateway API key repository is not configured'));
|
|
45
45
|
}
|
|
46
46
|
const repositoryContext = {
|
|
47
|
-
|
|
47
|
+
gatewayKeyVerification: { reason: 'gateway-key-verifier' },
|
|
48
48
|
};
|
|
49
49
|
let record;
|
|
50
50
|
try {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { credentialResource, gatewayAccessKeyResource, type GatewayAccessKeyRow } from '@undefineds.co/models';
|
|
2
2
|
import type { AuthContext } from '../../auth/AuthContext';
|
|
3
|
+
import { type PodAccessFetchProvider } from '../pod/OwnerPodAccess';
|
|
3
4
|
import { type PodBaseUrlResolver } from '../pod/PodBaseUrlResolver';
|
|
4
5
|
import { type GatewayKeyLocatorCodec } from './GatewayKeyLocatorCodec';
|
|
5
6
|
import { type GatewayAccessKeyRecord, type GatewayAccessKeyRepository, type GatewayAccessKeyRepositoryContext } from './GatewayApiKeyAuthenticator';
|
|
@@ -29,7 +30,7 @@ type GatewayAccessKeyDb = {
|
|
|
29
30
|
type GatewayAccessKeyResource = typeof gatewayAccessKeyResource;
|
|
30
31
|
export interface PodGatewayAccessKeyRepositoryOptions {
|
|
31
32
|
locatorCodec: GatewayKeyLocatorCodec;
|
|
32
|
-
|
|
33
|
+
podAccess?: PodAccessFetchProvider;
|
|
33
34
|
podBaseUrlResolver?: PodBaseUrlResolver;
|
|
34
35
|
dbFactory?: (input: {
|
|
35
36
|
owner: string;
|
|
@@ -41,16 +42,10 @@ export interface PodGatewayAccessKeyRepositoryOptions {
|
|
|
41
42
|
credentialListResource?: typeof credentialResource;
|
|
42
43
|
}) => Promise<GatewayAccessKeyDb>;
|
|
43
44
|
}
|
|
44
|
-
export interface InternalPodAccessTokenProvider {
|
|
45
|
-
getTrustedFetch(owner: string, auth?: AuthContext, context?: {
|
|
46
|
-
reason?: string;
|
|
47
|
-
podBaseUrl?: string;
|
|
48
|
-
}): Promise<typeof fetch | undefined>;
|
|
49
|
-
}
|
|
50
45
|
export declare class PodGatewayAccessKeyRepository implements GatewayAccessKeyRepository {
|
|
51
46
|
private readonly dbFactory;
|
|
52
47
|
private readonly locatorCodec;
|
|
53
|
-
private readonly
|
|
48
|
+
private readonly podAccess?;
|
|
54
49
|
private readonly podBaseUrlResolver?;
|
|
55
50
|
private readonly usesDefaultDbFactory;
|
|
56
51
|
constructor(options: PodGatewayAccessKeyRepositoryOptions);
|
|
@@ -4,14 +4,14 @@ exports.PodGatewayAccessKeyRepository = void 0;
|
|
|
4
4
|
exports.clientCredentialProviderId = clientCredentialProviderId;
|
|
5
5
|
const drizzle_solid_1 = require("@undefineds.co/drizzle-solid");
|
|
6
6
|
const models_1 = require("@undefineds.co/models");
|
|
7
|
-
const
|
|
7
|
+
const OwnerPodAccess_1 = require("../pod/OwnerPodAccess");
|
|
8
8
|
const AiConnectionsServiceAccess_1 = require("../service-access/AiConnectionsServiceAccess");
|
|
9
9
|
const PodBaseUrlResolver_1 = require("../pod/PodBaseUrlResolver");
|
|
10
10
|
const GatewayKeyLocatorCodec_1 = require("./GatewayKeyLocatorCodec");
|
|
11
11
|
class PodGatewayAccessKeyRepository {
|
|
12
12
|
constructor(options) {
|
|
13
13
|
this.locatorCodec = options.locatorCodec;
|
|
14
|
-
this.
|
|
14
|
+
this.podAccess = options.podAccess;
|
|
15
15
|
this.podBaseUrlResolver = options.podBaseUrlResolver;
|
|
16
16
|
this.usesDefaultDbFactory = options.dbFactory === undefined;
|
|
17
17
|
this.dbFactory = options.dbFactory ?? createDefaultGatewayAccessKeyDb;
|
|
@@ -48,7 +48,7 @@ class PodGatewayAccessKeyRepository {
|
|
|
48
48
|
const { db, resource } = await this.dbForOwner(locator.owner, context);
|
|
49
49
|
// Authentication uses only the legacy RDF verifier rows; issued client
|
|
50
50
|
// credentials are owner-authorized management records.
|
|
51
|
-
if (!context?.
|
|
51
|
+
if (!context?.gatewayKeyVerification) {
|
|
52
52
|
const credential = await db.findById(models_1.credentialResource, clientCredentialStorageId(id));
|
|
53
53
|
if (credential)
|
|
54
54
|
return clientCredentialRecord(id, locator, credential);
|
|
@@ -136,10 +136,7 @@ class PodGatewayAccessKeyRepository {
|
|
|
136
136
|
if (!locator) {
|
|
137
137
|
return;
|
|
138
138
|
}
|
|
139
|
-
const { db, resource } = await this.dbForOwner(locator.owner,
|
|
140
|
-
...context,
|
|
141
|
-
internalPodAccess: context?.internalPodAccess ? { reason: 'gateway-key-verifier' } : undefined,
|
|
142
|
-
});
|
|
139
|
+
const { db, resource } = await this.dbForOwner(locator.owner, context);
|
|
143
140
|
const credentialStorageId = clientCredentialStorageId(id);
|
|
144
141
|
if (await db.findById(models_1.credentialResource, credentialStorageId)) {
|
|
145
142
|
await db.updateById(models_1.credentialResource, credentialStorageId, { lastUsedAt });
|
|
@@ -171,32 +168,12 @@ class PodGatewayAccessKeyRepository {
|
|
|
171
168
|
}
|
|
172
169
|
async resolveTrustedFetch(owner, podUrl, context) {
|
|
173
170
|
const auth = context?.auth;
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
// The hosted adapter verifies the same owner and signs a resource-scoped
|
|
179
|
-
// loopback intent; it never forwards the browser's token or proof.
|
|
180
|
-
if (auth?.type === 'solid' && (auth.tokenType === 'DPoP' || auth.dpopProof)) {
|
|
181
|
-
const hostedFetch = await this.internalPodAccess?.getTrustedFetch(owner, auth, { podBaseUrl: podUrl });
|
|
182
|
-
if (hostedFetch) {
|
|
183
|
-
return this.wrapPodFetch(hostedFetch);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
const callerFetch = (0, CallerPodAccess_1.createCallerAuthenticatedPodFetch)(owner, auth);
|
|
187
|
-
if (callerFetch) {
|
|
188
|
-
return this.wrapPodFetch(callerFetch);
|
|
189
|
-
}
|
|
190
|
-
if (!(0, CallerPodAccess_1.isInternalPodAccessAllowed)(auth, {
|
|
191
|
-
explicitInternalAccess: Boolean(context?.internalPodAccess?.reason),
|
|
192
|
-
})) {
|
|
193
|
-
throw new Error((0, CallerPodAccess_1.callerPodAccessError)(owner, auth));
|
|
194
|
-
}
|
|
195
|
-
const trustedFetch = await this.internalPodAccess?.getTrustedFetch(owner, auth, context?.internalPodAccess?.reason === 'gateway-key-verifier'
|
|
196
|
-
? { reason: 'gateway-key-verifier', podBaseUrl: podUrl }
|
|
197
|
-
: { podBaseUrl: podUrl });
|
|
171
|
+
const trustedFetch = await this.podAccess?.getPodFetch(owner, {
|
|
172
|
+
...(auth ? { auth } : {}),
|
|
173
|
+
podBaseUrl: podUrl,
|
|
174
|
+
});
|
|
198
175
|
if (!trustedFetch) {
|
|
199
|
-
throw new Error(
|
|
176
|
+
throw new Error((0, OwnerPodAccess_1.podAccessError)(owner, auth));
|
|
200
177
|
}
|
|
201
178
|
return this.wrapPodFetch(trustedFetch);
|
|
202
179
|
}
|
|
@@ -5,7 +5,7 @@ import type { GatewayDeployment } from '../auth/InvocationTokenCodec';
|
|
|
5
5
|
import { type ProviderOfferingEndpointDescriptor, type ProviderCapabilities, type ProviderRegistry } from '../providers/ProviderRegistry';
|
|
6
6
|
import type { OfferingAuthorizationMethod } from '../providers/OfferingAuthorization';
|
|
7
7
|
import type { AuthContext } from '../../auth/AuthContext';
|
|
8
|
-
import type
|
|
8
|
+
import { type PodAccessFetchProvider } from '../pod/OwnerPodAccess';
|
|
9
9
|
import { type PodBaseUrlResolver } from '../pod/PodBaseUrlResolver';
|
|
10
10
|
import type { AuthorizationCodeCallbackReceiver } from './LoopbackAuthorizationCallbackReceiver';
|
|
11
11
|
import type { AuthorizationCodeOAuthIntegration, DeviceCodeOAuthIntegration, OAuthConnectMode } from './DeviceCodeProtocol';
|
|
@@ -223,7 +223,7 @@ type ConnectedCredentialDb = {
|
|
|
223
223
|
};
|
|
224
224
|
};
|
|
225
225
|
export interface PodConnectedCredentialRepositoryOptions {
|
|
226
|
-
|
|
226
|
+
podAccess?: PodAccessFetchProvider;
|
|
227
227
|
podBaseUrlResolver?: PodBaseUrlResolver;
|
|
228
228
|
providerIds?: string[];
|
|
229
229
|
dbFactory?: (input: {
|
|
@@ -238,7 +238,7 @@ export interface PodConnectedCredentialRepositoryOptions {
|
|
|
238
238
|
}
|
|
239
239
|
export declare class PodConnectedCredentialRepository implements PodCredentialRepository {
|
|
240
240
|
private readonly dbFactory;
|
|
241
|
-
private readonly
|
|
241
|
+
private readonly podAccess?;
|
|
242
242
|
private readonly podBaseUrlResolver?;
|
|
243
243
|
private readonly providerIds;
|
|
244
244
|
private readonly credentialTemplate;
|
|
@@ -7,7 +7,7 @@ const drizzle_solid_1 = require("@undefineds.co/drizzle-solid");
|
|
|
7
7
|
const models_1 = require("@undefineds.co/models");
|
|
8
8
|
const errors_1 = require("../errors");
|
|
9
9
|
const ProviderRegistry_1 = require("../providers/ProviderRegistry");
|
|
10
|
-
const
|
|
10
|
+
const OwnerPodAccess_1 = require("../pod/OwnerPodAccess");
|
|
11
11
|
const PodBaseUrlResolver_1 = require("../pod/PodBaseUrlResolver");
|
|
12
12
|
const OAuthConnectAdapter_1 = require("./OAuthConnectAdapter");
|
|
13
13
|
const provider_http_transport_1 = require("../../service/provider-http-transport");
|
|
@@ -25,7 +25,7 @@ const CREDENTIAL_COLLECTION_QUERY_UNSUPPORTED = 'credential_collection_query_uns
|
|
|
25
25
|
const credentialUpdateLocks = new Map();
|
|
26
26
|
class PodConnectedCredentialRepository {
|
|
27
27
|
constructor(options = {}) {
|
|
28
|
-
this.
|
|
28
|
+
this.podAccess = options.podAccess;
|
|
29
29
|
this.podBaseUrlResolver = options.podBaseUrlResolver;
|
|
30
30
|
this.providerIds = options.providerIds
|
|
31
31
|
?? ProviderRegistry_1.DEFAULT_PROVIDER_DESCRIPTORS.map((provider) => provider.id);
|
|
@@ -383,43 +383,14 @@ class PodConnectedCredentialRepository {
|
|
|
383
383
|
return { db, credential, aiProvider, aiModel, fetch: trustedFetch };
|
|
384
384
|
}
|
|
385
385
|
async resolveTrustedFetch(owner, auth, podBaseUrl) {
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
&& auth.webId === owner
|
|
393
|
-
&& auth.viaApiKey === true
|
|
394
|
-
&& typeof auth.clientId === 'string'
|
|
395
|
-
&& typeof auth.clientSecret === 'string') {
|
|
396
|
-
const hostedFetch = await this.internalPodAccess?.getTrustedFetch(owner, auth, { podBaseUrl });
|
|
397
|
-
if (hostedFetch) {
|
|
398
|
-
return this.wrapPodFetch(hostedFetch);
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
const callerFetch = (0, CallerPodAccess_1.createCallerAuthenticatedPodFetch)(owner, auth);
|
|
402
|
-
if (callerFetch) {
|
|
403
|
-
return this.wrapPodFetch(callerFetch);
|
|
404
|
-
}
|
|
405
|
-
// Browser DPoP proves the management caller but is bound to that request
|
|
406
|
-
// URL. Never replay it against the Pod; use the same-owner hosted route.
|
|
407
|
-
if (auth?.type === 'solid'
|
|
408
|
-
&& auth.webId === owner
|
|
409
|
-
&& (auth.tokenType === 'DPoP' || typeof auth.dpopProof === 'string')) {
|
|
410
|
-
const hostedFetch = await this.internalPodAccess?.getTrustedFetch(owner, auth, { podBaseUrl });
|
|
411
|
-
if (hostedFetch) {
|
|
412
|
-
return this.wrapPodFetch(hostedFetch);
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
if (!(0, CallerPodAccess_1.isInternalPodAccessAllowed)(auth)) {
|
|
416
|
-
throw new Error((0, CallerPodAccess_1.callerPodAccessError)(owner, auth));
|
|
417
|
-
}
|
|
418
|
-
const trustedFetch = await this.internalPodAccess?.getTrustedFetch(owner, auth, { podBaseUrl });
|
|
419
|
-
if (!trustedFetch) {
|
|
420
|
-
throw new Error('AI Connection service identity is not configured');
|
|
386
|
+
const podFetch = await this.podAccess?.getPodFetch(owner, {
|
|
387
|
+
...(auth ? { auth } : {}),
|
|
388
|
+
podBaseUrl,
|
|
389
|
+
});
|
|
390
|
+
if (!podFetch) {
|
|
391
|
+
throw new Error((0, OwnerPodAccess_1.podAccessError)(owner, auth));
|
|
421
392
|
}
|
|
422
|
-
return this.wrapPodFetch(
|
|
393
|
+
return this.wrapPodFetch(podFetch);
|
|
423
394
|
}
|
|
424
395
|
wrapPodFetch(trustedFetch) {
|
|
425
396
|
return async (input, init) => {
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.GatewayProtocolError = void 0;
|
|
4
4
|
exports.normalizeGatewayError = normalizeGatewayError;
|
|
5
|
+
const OwnerPodAccess_1 = require("./pod/OwnerPodAccess");
|
|
5
6
|
class GatewayProtocolError extends Error {
|
|
6
7
|
constructor(message, options = {}) {
|
|
7
8
|
super(message);
|
|
@@ -26,7 +27,7 @@ function normalizeGatewayError(error) {
|
|
|
26
27
|
},
|
|
27
28
|
};
|
|
28
29
|
}
|
|
29
|
-
if (error instanceof Error && error.message
|
|
30
|
+
if (error instanceof Error && (0, OwnerPodAccess_1.isPodAccessFailure)(error.message)) {
|
|
30
31
|
return {
|
|
31
32
|
error: {
|
|
32
33
|
code: 'service_access_missing',
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { aiModelResource, aiProviderResource } from '@undefineds.co/models';
|
|
2
2
|
import type { AuthContext } from '../../auth/AuthContext';
|
|
3
|
-
import type
|
|
3
|
+
import { type PodAccessFetchProvider } from '../pod/OwnerPodAccess';
|
|
4
4
|
import { type PodBaseUrlResolver } from '../pod/PodBaseUrlResolver';
|
|
5
5
|
export type PodSelectedModelStatus = 'active' | 'inactive';
|
|
6
6
|
export interface PodSelectedModel {
|
|
@@ -40,7 +40,7 @@ export interface PodModelSelectionDb {
|
|
|
40
40
|
transaction?<T>(transaction: (tx: PodModelSelectionDb) => Promise<T>): Promise<T>;
|
|
41
41
|
}
|
|
42
42
|
export interface PodModelSelectionRepositoryOptions {
|
|
43
|
-
|
|
43
|
+
podAccess?: PodAccessFetchProvider;
|
|
44
44
|
podBaseUrlResolver?: PodBaseUrlResolver;
|
|
45
45
|
dbFactory?: (input: {
|
|
46
46
|
owner: string;
|
|
@@ -82,7 +82,7 @@ export declare const DEFAULT_MODEL_SELECTION_PROVIDERS: readonly ["openai", "ant
|
|
|
82
82
|
*/
|
|
83
83
|
export declare class PodModelSelectionRepository {
|
|
84
84
|
private readonly dbFactory;
|
|
85
|
-
private readonly
|
|
85
|
+
private readonly podAccess?;
|
|
86
86
|
private readonly podBaseUrlResolver?;
|
|
87
87
|
private readonly providerIds;
|
|
88
88
|
private readonly now;
|
|
@@ -5,7 +5,7 @@ exports.computeSelectionVersion = computeSelectionVersion;
|
|
|
5
5
|
const node_crypto_1 = require("node:crypto");
|
|
6
6
|
const drizzle_solid_1 = require("@undefineds.co/drizzle-solid");
|
|
7
7
|
const models_1 = require("@undefineds.co/models");
|
|
8
|
-
const
|
|
8
|
+
const OwnerPodAccess_1 = require("../pod/OwnerPodAccess");
|
|
9
9
|
const PodBaseUrlResolver_1 = require("../pod/PodBaseUrlResolver");
|
|
10
10
|
const REMOVED_MODEL_STATUS = 'removed';
|
|
11
11
|
exports.DEFAULT_MODEL_SELECTION_PROVIDERS = [
|
|
@@ -25,7 +25,7 @@ const modelSelectionLocks = new Map();
|
|
|
25
25
|
class PodModelSelectionRepository {
|
|
26
26
|
constructor(options = {}) {
|
|
27
27
|
this.dbFactory = options.dbFactory ?? createDefaultModelSelectionDb;
|
|
28
|
-
this.
|
|
28
|
+
this.podAccess = options.podAccess;
|
|
29
29
|
this.podBaseUrlResolver = options.podBaseUrlResolver;
|
|
30
30
|
this.providerIds = dedupeProviders(options.providerIds ?? exports.DEFAULT_MODEL_SELECTION_PROVIDERS);
|
|
31
31
|
this.now = options.now ?? (() => new Date());
|
|
@@ -314,16 +314,12 @@ class PodModelSelectionRepository {
|
|
|
314
314
|
assertOwnerWebId(owner);
|
|
315
315
|
assertAuthOwner(owner, auth);
|
|
316
316
|
const podUrl = await (0, PodBaseUrlResolver_1.resolveOwnerPodBaseUrl)(owner, this.podBaseUrlResolver);
|
|
317
|
-
const
|
|
318
|
-
?
|
|
319
|
-
:
|
|
320
|
-
|
|
321
|
-
const trustedFetch = hostedFetch ?? callerFetch
|
|
322
|
-
?? await this.internalPodAccess?.getTrustedFetch(owner, auth, { podBaseUrl: podUrl });
|
|
317
|
+
const trustedFetch = await this.podAccess?.getPodFetch(owner, {
|
|
318
|
+
...(auth ? { auth } : {}),
|
|
319
|
+
podBaseUrl: podUrl,
|
|
320
|
+
});
|
|
323
321
|
if (!trustedFetch) {
|
|
324
|
-
throw new Error((0,
|
|
325
|
-
? 'AI Connection service identity is not configured'
|
|
326
|
-
: (0, CallerPodAccess_1.callerPodAccessError)(owner, auth));
|
|
322
|
+
throw new Error((0, OwnerPodAccess_1.podAccessError)(owner, auth));
|
|
327
323
|
}
|
|
328
324
|
const podFetch = async (input, init) => {
|
|
329
325
|
let response;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface HostedPodRoute {
|
|
2
|
+
/** Canonical Pod/container URL used for RDF identity and public access. */
|
|
3
|
+
canonicalBaseUrl: string;
|
|
4
|
+
/** Same resource tree exposed by the local Xpod Gateway. */
|
|
5
|
+
localBaseUrl: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* The route that reaches this deployment's hosted Pods from inside the API sidecar.
|
|
9
|
+
*
|
|
10
|
+
* The inputs are resolved where they are known - when the runtime builds its services - and not
|
|
11
|
+
* read from the environment per request: the runtime restores the environment it borrowed once
|
|
12
|
+
* its services are up, so a lazy lookup would silently find nothing and address the Pod's
|
|
13
|
+
* canonical URL instead of the route that is actually reachable.
|
|
14
|
+
*/
|
|
15
|
+
export declare function resolveHostedPodRoute(input: {
|
|
16
|
+
canonicalBaseUrl?: string;
|
|
17
|
+
gatewayHost?: string;
|
|
18
|
+
gatewayPort?: string | number;
|
|
19
|
+
}): HostedPodRoute | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* Wrap a transport so canonical Pod URLs are sent over the gateway route.
|
|
22
|
+
*
|
|
23
|
+
* This belongs *under* a DPoP signer, never wrapped around an authenticated fetch: the proof is
|
|
24
|
+
* made for the canonical URL, and this layer only replaces the wire target, so a DPoP-bound
|
|
25
|
+
* request stays bound to the URL the caller named.
|
|
26
|
+
*/
|
|
27
|
+
export declare function createHostedPodRouteTransport(transport: typeof fetch, route: HostedPodRoute | undefined): Promise<typeof fetch>;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveHostedPodRoute = resolveHostedPodRoute;
|
|
4
|
+
exports.createHostedPodRouteTransport = createHostedPodRouteTransport;
|
|
5
|
+
const bootstrap_1 = require("../../../runtime/bootstrap");
|
|
6
|
+
/**
|
|
7
|
+
* The route that reaches this deployment's hosted Pods from inside the API sidecar.
|
|
8
|
+
*
|
|
9
|
+
* The inputs are resolved where they are known - when the runtime builds its services - and not
|
|
10
|
+
* read from the environment per request: the runtime restores the environment it borrowed once
|
|
11
|
+
* its services are up, so a lazy lookup would silently find nothing and address the Pod's
|
|
12
|
+
* canonical URL instead of the route that is actually reachable.
|
|
13
|
+
*/
|
|
14
|
+
function resolveHostedPodRoute(input) {
|
|
15
|
+
const canonicalBaseUrl = input.canonicalBaseUrl?.trim();
|
|
16
|
+
const gatewayPort = String(input.gatewayPort ?? '').trim();
|
|
17
|
+
if (!canonicalBaseUrl || !/^\d+$/u.test(gatewayPort)) {
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
canonicalBaseUrl,
|
|
22
|
+
// The gateway has to be reached on the address it actually bound: `localhost` may be
|
|
23
|
+
// IPv6-only, and a wildcard bind is not connectable on every platform.
|
|
24
|
+
localBaseUrl: `${(0, bootstrap_1.localServiceUrl)(input.gatewayHost, Number(gatewayPort))}/`,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Wrap a transport so canonical Pod URLs are sent over the gateway route.
|
|
29
|
+
*
|
|
30
|
+
* This belongs *under* a DPoP signer, never wrapped around an authenticated fetch: the proof is
|
|
31
|
+
* made for the canonical URL, and this layer only replaces the wire target, so a DPoP-bound
|
|
32
|
+
* request stays bound to the URL the caller named.
|
|
33
|
+
*/
|
|
34
|
+
async function createHostedPodRouteTransport(transport, route) {
|
|
35
|
+
if (!route) {
|
|
36
|
+
return transport;
|
|
37
|
+
}
|
|
38
|
+
const { createSolidLocalRouteFetch } = await importSolidLocalRouteFetch();
|
|
39
|
+
return createSolidLocalRouteFetch({ fetch: transport, routes: () => [route] });
|
|
40
|
+
}
|
|
41
|
+
async function importSolidLocalRouteFetch() {
|
|
42
|
+
// The API runtime is CommonJS while solid-sdk is intentionally ESM-only. Keep the package
|
|
43
|
+
// boundary and load the SDK without TypeScript lowering import() to require().
|
|
44
|
+
const dynamicImport = new Function('specifier', 'return import(specifier)');
|
|
45
|
+
return dynamicImport('@undefineds.co/solid-sdk/local-route-fetch');
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=HostedPodRoute.js.map
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { type AuthContext } from '../../auth/AuthContext';
|
|
2
|
+
import { type HostedPodRoute } from './HostedPodRoute';
|
|
3
|
+
import type { PodInterfaceCredential, PodInterfaceKeyAccess, PodInterfaceKeyGrant } from './PodInterfaceKeyStore';
|
|
4
|
+
/** No usable Pod credential is on file for this owner; the user has to grant one. */
|
|
5
|
+
export declare const POD_INTERFACE_KEY_MISSING = "pod_interface_key_missing";
|
|
6
|
+
/** The owner's stored credential was refused by the Pod; it has to be granted again. */
|
|
7
|
+
export declare const POD_INTERFACE_KEY_REJECTED = "pod_interface_key_rejected";
|
|
8
|
+
export interface PodAccessRequestContext {
|
|
9
|
+
/** The authenticated caller, when the request carries one. */
|
|
10
|
+
auth?: AuthContext;
|
|
11
|
+
/** Physical Pod root when the identity WebID is hosted by a separate IdP. */
|
|
12
|
+
podBaseUrl?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Source of a fetch that reaches an owner's Pod through its standard interface.
|
|
16
|
+
*
|
|
17
|
+
* `undefined` means no credential is on file, which is a state the caller reports to the user
|
|
18
|
+
* rather than papers over.
|
|
19
|
+
*/
|
|
20
|
+
export interface PodAccessFetchProvider {
|
|
21
|
+
getPodFetch(owner: string, context?: PodAccessRequestContext): Promise<typeof fetch | undefined>;
|
|
22
|
+
}
|
|
23
|
+
export interface OwnerPodAccessOptions {
|
|
24
|
+
keys: PodInterfaceKeyAccess;
|
|
25
|
+
/** Token endpoint of this deployment's Solid interface. */
|
|
26
|
+
tokenEndpoint: string;
|
|
27
|
+
/** Canonical base URL of that interface, used to keep the DPoP proof canonical. */
|
|
28
|
+
publicBaseUrl?: string;
|
|
29
|
+
/** Route this deployment exposes for its own hosted Pods, when one is needed. */
|
|
30
|
+
route?: HostedPodRoute;
|
|
31
|
+
fetch?: typeof fetch;
|
|
32
|
+
now?: () => number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Reaches a Pod as its owner over the standard Solid interface.
|
|
36
|
+
*
|
|
37
|
+
* Three credentials can prove the owner, and all three are the owner's own interface key:
|
|
38
|
+
* the caller's key, when the caller presented one; the caller's reusable token, when it holds
|
|
39
|
+
* one; and the key the owner granted this deployment for work no caller is attached to.
|
|
40
|
+
*
|
|
41
|
+
* What never happens is asking the Solid server to trust the caller's network position. Every
|
|
42
|
+
* request carries a credential for the owner and addresses the Pod's own URLs, so the Pod's own
|
|
43
|
+
* authorization decides - exactly as it does for the browser.
|
|
44
|
+
*/
|
|
45
|
+
export declare class OwnerPodAccess implements PodAccessFetchProvider, PodInterfaceKeyGrant {
|
|
46
|
+
private readonly logger;
|
|
47
|
+
private readonly keys;
|
|
48
|
+
private readonly fetchImpl;
|
|
49
|
+
private readonly now;
|
|
50
|
+
private readonly tokenRoute;
|
|
51
|
+
private readonly route?;
|
|
52
|
+
private readonly podFetches;
|
|
53
|
+
constructor(options: OwnerPodAccessOptions);
|
|
54
|
+
/** Grant, or rotate, the owner's Pod interface key. */
|
|
55
|
+
saveKey(owner: string, credential: PodInterfaceCredential): Promise<void>;
|
|
56
|
+
forgetKey(owner: string): Promise<void>;
|
|
57
|
+
hasKey(owner: string): Promise<boolean>;
|
|
58
|
+
getPodFetch(owner: string, context?: PodAccessRequestContext): Promise<typeof fetch | undefined>;
|
|
59
|
+
private storedKeyFetch;
|
|
60
|
+
private credentialFetch;
|
|
61
|
+
private exchange;
|
|
62
|
+
private invalidateOnUnauthorized;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Reason an owner's Pod is out of reach, as a stable code the caller and the UI can act on.
|
|
66
|
+
*
|
|
67
|
+
* A same-owner caller is the ordinary case: Xpod knows who the user is, but holds nothing it can
|
|
68
|
+
* present to the Pod on the user's behalf. A browser session explains why its own credential was
|
|
69
|
+
* not enough - its proof is bound to the URL it was made for - while a bearer session simply has
|
|
70
|
+
* no Pod credential at all. Either way the fix is the same: grant the interface key.
|
|
71
|
+
*/
|
|
72
|
+
export declare function podAccessError(owner: string, auth?: AuthContext): string;
|
|
73
|
+
/**
|
|
74
|
+
* Whether a failure means Xpod had no usable way into the owner's Pod.
|
|
75
|
+
*
|
|
76
|
+
* The stable wire code for this is `service_access_missing`, which callers already report; the
|
|
77
|
+
* codes below are the reason behind it, kept distinct so the UI can ask for the right fix.
|
|
78
|
+
*/
|
|
79
|
+
export declare function isPodAccessFailure(message: string): boolean;
|