@undefineds.co/xpod 0.3.25 → 0.3.27

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.
Files changed (89) hide show
  1. package/config/cloud.json +6 -5
  2. package/config/main.json +0 -3
  3. package/config/xpod.base.json +0 -32
  4. package/dist/api/container/index.js +3 -0
  5. package/dist/api/container/index.js.map +1 -1
  6. package/dist/api/container/routes.js +2 -0
  7. package/dist/api/container/routes.js.map +1 -1
  8. package/dist/api/container/types.d.ts +5 -0
  9. package/dist/api/container/types.js.map +1 -1
  10. package/dist/authorization/AuthMode.d.ts +8 -0
  11. package/dist/authorization/AuthMode.js +51 -0
  12. package/dist/authorization/AuthMode.js.map +1 -0
  13. package/dist/authorization/PodAuthorizationResources.d.ts +18 -0
  14. package/dist/authorization/PodAuthorizationResources.js +108 -0
  15. package/dist/authorization/PodAuthorizationResources.js.map +1 -0
  16. package/dist/cli/commands/start.js +11 -2
  17. package/dist/cli/commands/start.js.map +1 -1
  18. package/dist/components/components.jsonld +3 -2
  19. package/dist/components/context.jsonld +115 -14
  20. package/dist/index.d.ts +5 -3
  21. package/dist/index.js +6 -5
  22. package/dist/index.js.map +1 -1
  23. package/dist/main.js +11 -2
  24. package/dist/main.js.map +1 -1
  25. package/dist/provision/LocalPodProvisioningService.d.ts +6 -2
  26. package/dist/provision/LocalPodProvisioningService.js +36 -33
  27. package/dist/provision/LocalPodProvisioningService.js.map +1 -1
  28. package/dist/provision/LocalPodProvisioningService.jsonld +65 -8
  29. package/dist/runtime/XpodRuntime.js +0 -1
  30. package/dist/runtime/XpodRuntime.js.map +1 -1
  31. package/dist/runtime/bootstrap.d.ts +4 -2
  32. package/dist/runtime/bootstrap.js +43 -11
  33. package/dist/runtime/bootstrap.js.map +1 -1
  34. package/dist/runtime/css-process.d.ts +6 -1
  35. package/dist/runtime/css-process.js +18 -6
  36. package/dist/runtime/css-process.js.map +1 -1
  37. package/dist/runtime/lifecycle.d.ts +2 -3
  38. package/dist/runtime/lifecycle.js +2 -2
  39. package/dist/runtime/lifecycle.js.map +1 -1
  40. package/dist/runtime/runtime-types.d.ts +2 -1
  41. package/dist/runtime/runtime-types.js.map +1 -1
  42. package/dist/storage/accessors/SolidRdfDataAccessor.d.ts +2 -3
  43. package/dist/storage/accessors/SolidRdfDataAccessor.js +48 -42
  44. package/dist/storage/accessors/SolidRdfDataAccessor.js.map +1 -1
  45. package/dist/storage/accessors/SolidRdfDataAccessor.jsonld +1 -1
  46. package/dist/storage/keyvalue/BaseKeyValueStorage.d.ts +33 -0
  47. package/dist/storage/keyvalue/BaseKeyValueStorage.js +106 -0
  48. package/dist/storage/keyvalue/BaseKeyValueStorage.js.map +1 -0
  49. package/dist/storage/keyvalue/BaseKeyValueStorage.jsonld +177 -0
  50. package/dist/storage/keyvalue/PostgresKeyValueStorage.d.ts +9 -18
  51. package/dist/storage/keyvalue/PostgresKeyValueStorage.js +24 -96
  52. package/dist/storage/keyvalue/PostgresKeyValueStorage.js.map +1 -1
  53. package/dist/storage/keyvalue/PostgresKeyValueStorage.jsonld +15 -58
  54. package/dist/storage/keyvalue/SqliteKeyValueStorage.d.ts +9 -15
  55. package/dist/storage/keyvalue/SqliteKeyValueStorage.js +36 -104
  56. package/dist/storage/keyvalue/SqliteKeyValueStorage.js.map +1 -1
  57. package/dist/storage/keyvalue/SqliteKeyValueStorage.jsonld +21 -52
  58. package/dist/storage/quint/BaseQuintStore.d.ts +4 -1
  59. package/dist/storage/quint/BaseQuintStore.js +41 -52
  60. package/dist/storage/quint/BaseQuintStore.js.map +1 -1
  61. package/dist/storage/quint/PgQuintStore.d.ts +4 -3
  62. package/dist/storage/quint/PgQuintStore.js.map +1 -1
  63. package/dist/storage/quint/SqliteQuintStore.d.ts +43 -54
  64. package/dist/storage/quint/SqliteQuintStore.js +197 -520
  65. package/dist/storage/quint/SqliteQuintStore.js.map +1 -1
  66. package/dist/storage/quint/SqliteQuintStore.jsonld +38 -86
  67. package/dist/storage/rdf/PostgresRdfEngine.d.ts +118 -0
  68. package/dist/storage/rdf/PostgresRdfEngine.js +2609 -0
  69. package/dist/storage/rdf/PostgresRdfEngine.js.map +1 -0
  70. package/dist/storage/rdf/PostgresRdfEngine.jsonld +657 -0
  71. package/dist/storage/rdf/SolidRdfEngine.d.ts +2 -2
  72. package/dist/storage/rdf/SolidRdfEngine.js.map +1 -1
  73. package/dist/storage/rdf/SolidRdfEngine.jsonld +3 -0
  74. package/dist/storage/rdf/SolidRdfSparqlEngine.d.ts +3 -3
  75. package/dist/storage/rdf/SolidRdfSparqlEngine.js +20 -20
  76. package/dist/storage/rdf/SolidRdfSparqlEngine.js.map +1 -1
  77. package/dist/storage/rdf/SolidRdfSparqlEngine.jsonld +1 -1
  78. package/dist/storage/rdf/index.d.ts +2 -1
  79. package/dist/storage/rdf/index.js +3 -1
  80. package/dist/storage/rdf/index.js.map +1 -1
  81. package/dist/storage/rdf/types.d.ts +19 -0
  82. package/dist/storage/rdf/types.js.map +1 -1
  83. package/dist/storage/rdf/types.jsonld +115 -0
  84. package/package.json +2 -2
  85. package/config/runtime-open.json +0 -22
  86. package/dist/authorization/AuthModeSelector.d.ts +0 -10
  87. package/dist/authorization/AuthModeSelector.js +0 -27
  88. package/dist/authorization/AuthModeSelector.js.map +0 -1
  89. package/dist/authorization/AuthModeSelector.jsonld +0 -81
package/config/cloud.json CHANGED
@@ -169,14 +169,15 @@
169
169
  "autoBackfill_batchSize": 1000
170
170
  },
171
171
  {
172
- "comment": "RDF term-id query engine backed by the shared cloud RDF index.",
172
+ "comment": "RDF query engine backed by PostgreSQL facts plus PostgreSQL RDF-3X derived stats.",
173
173
  "@id": "urn:undefineds:xpod:SolidRdfEngine",
174
- "@type": "SolidRdfEngine",
175
- "index_path": {
176
- "@id": "urn:solid-server:default:variable:rdfIndexPath",
174
+ "@type": "PostgresRdfEngine",
175
+ "options_driver": "pg",
176
+ "options_connectionString": {
177
+ "@id": "urn:solid-server:default:variable:sparqlEndpoint",
177
178
  "@type": "Variable"
178
179
  },
179
- "autoOpen": true
180
+ "options_autoOpen": true
180
181
  },
181
182
  {
182
183
  "comment": "Compatibility SPARQL engine backed by the shadow store, so fallback writes update both indexes.",
package/config/main.json CHANGED
@@ -16,7 +16,6 @@
16
16
  "css:config/identity/ownership/token.json",
17
17
  "css:config/identity/pod/static.json",
18
18
  "css:config/ldp/authentication/dpop-bearer.json",
19
- "css:config/ldp/authorization/acp.json",
20
19
  "css:config/ldp/handler/default.json",
21
20
  "css:config/ldp/metadata-parser/default.json",
22
21
  "css:config/ldp/metadata-writer/default.json",
@@ -25,7 +24,6 @@
25
24
  "css:config/storage/key-value/resource-store.json",
26
25
  "css:config/storage/location/pod.json",
27
26
  "css:config/storage/middleware/default.json",
28
- "css:config/util/auxiliary/acr.json",
29
27
  "css:config/util/identifiers/suffix.json",
30
28
  "css:config/util/index/default.json",
31
29
  "css:config/util/logging/winston.json",
@@ -156,4 +154,3 @@
156
154
  }
157
155
  ]
158
156
  }
159
-
@@ -19,38 +19,6 @@
19
19
  "@id": "urn:solid-server:default:variable:edgeNodesEnabled",
20
20
  "@type": "Variable"
21
21
  },
22
- {
23
- "comment": "ACP permission reader clone for auth mode switching.",
24
- "@id": "urn:undefineds:xpod:AcpPermissionReader",
25
- "@type": "CachedHandler",
26
- "fields": [
27
- "credentials",
28
- "requestedModes"
29
- ],
30
- "source": {
31
- "@id": "urn:solid-server:default:AuxiliaryReader"
32
- }
33
- },
34
- {
35
- "comment": "Override default permission reader so tests can switch auth mode with a parameter.",
36
- "@type": "Override",
37
- "overrideInstance": {
38
- "@id": "urn:solid-server:default:PermissionReader"
39
- },
40
- "overrideParameters": {
41
- "@type": "AuthModeSelector",
42
- "authMode": {
43
- "@id": "urn:solid-server:default:variable:authMode",
44
- "@type": "Variable"
45
- },
46
- "acpReader": {
47
- "@id": "urn:undefineds:xpod:AcpPermissionReader"
48
- },
49
- "aclReader": {
50
- "@id": "urn:undefineds:xpod:AcpPermissionReader"
51
- }
52
- }
53
- },
54
22
  {
55
23
  "comment": "An accessor for a Quadstore",
56
24
  "@type": "QuadstoreSparqlDataAccessor",
@@ -40,6 +40,7 @@ const cloud_1 = require("./cloud");
40
40
  const local_1 = require("./local");
41
41
  const business_token_1 = require("./business-token");
42
42
  const oidc_issuer_1 = require("../../runtime/oidc-issuer");
43
+ const AuthMode_1 = require("../../authorization/AuthMode");
43
44
  const OFFICIAL_CLOUD_IDENTITY_ORIGIN = 'https://id.undefineds.co';
44
45
  function ensureTrailingSlash(url) {
45
46
  return url.endsWith('/') ? url : `${url}/`;
@@ -94,6 +95,8 @@ function loadConfigFromEnv() {
94
95
  port: apiPort,
95
96
  host: process.env.API_HOST ?? '0.0.0.0',
96
97
  socketPath: process.env.API_SOCKET_PATH,
98
+ authMode: (0, AuthMode_1.resolveAuthModeFromEnv)(process.env),
99
+ rdfIndexPath: process.env.CSS_RDF_INDEX_PATH,
97
100
  databaseUrl: process.env.CSS_IDENTITY_DB_URL ?? process.env.DATABASE_URL ?? '',
98
101
  redisUrl: process.env.CSS_REDIS_CLIENT ?? process.env.REDIS_URL,
99
102
  corsOrigins: process.env.CORS_ORIGINS?.split(',').map(s => s.trim()) ?? ['*'],
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/api/container/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * API Container 入口\n *\n * 使用 Awilix 进行依赖注入,根据 edition 注册不同服务\n */\n\nimport { createContainer, asValue, InjectionMode, type AwilixContainer } from 'awilix';\nimport { randomUUID, createHash } from 'node:crypto';\nimport * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport type { ApiContainerCradle, ApiContainerConfig } from './types';\nimport { registerCommonServices } from './common';\nimport { registerCloudServices } from './cloud';\nimport { registerLocalServices } from './local';\nimport { registerBusinessToken } from './business-token';\nimport { resolveExternalOidcIssuer } from '../../runtime/oidc-issuer';\n\nexport type { ApiContainerCradle, ApiContainerConfig } from './types';\n\nconst OFFICIAL_CLOUD_IDENTITY_ORIGIN = 'https://id.undefineds.co';\n\nfunction ensureTrailingSlash(url: string): string {\n return url.endsWith('/') ? url : `${url}/`;\n}\n\nfunction resolveCssTokenEndpoint(): string {\n if (process.env.CSS_TOKEN_ENDPOINT) {\n return process.env.CSS_TOKEN_ENDPOINT;\n }\n\n if (process.env.CSS_BASE_URL) {\n return `${ensureTrailingSlash(process.env.CSS_BASE_URL)}.oidc/token`;\n }\n\n return 'http://localhost:3000/.oidc/token';\n}\n\n/**\n * 创建 API 容器\n */\nexport function createApiContainer(config: ApiContainerConfig): AwilixContainer<ApiContainerCradle> {\n const container = createContainer<ApiContainerCradle>({\n injectionMode: InjectionMode.PROXY,\n strict: true,\n });\n\n // 注册配置\n container.register({\n config: asValue(config),\n inngestRuntimeConfig: asValue(config.inngestRuntimeConfig),\n });\n\n // 注册共享服务\n registerCommonServices(container);\n\n // 根据 edition 注册专属服务\n if (config.edition === 'cloud') {\n registerCloudServices(container);\n } else {\n registerLocalServices(container);\n }\n\n // 注册 Business Token (如果配置了 XPOD_BUSINESS_TOKEN)\n registerBusinessToken(container);\n\n return container;\n}\n\n/**\n * 从环境变量读取配置\n */\nexport function loadConfigFromEnv(): ApiContainerConfig {\n const edition = (process.env.XPOD_EDITION ?? 'local') as 'cloud' | 'local';\n\n // Port auto-increment: API_PORT = CSS_PORT + 1 if not explicitly set\n const cssPort = parseInt(process.env.CSS_PORT ?? '3000', 10);\n const apiPort = process.env.API_PORT\n ? parseInt(process.env.API_PORT, 10)\n : cssPort + 1;\n\n return {\n edition,\n port: apiPort,\n host: process.env.API_HOST ?? '0.0.0.0',\n socketPath: process.env.API_SOCKET_PATH,\n databaseUrl: process.env.CSS_IDENTITY_DB_URL ?? process.env.DATABASE_URL ?? '',\n redisUrl: process.env.CSS_REDIS_CLIENT ?? process.env.REDIS_URL,\n corsOrigins: process.env.CORS_ORIGINS?.split(',').map(s => s.trim()) ?? ['*'],\n cssTokenEndpoint: resolveCssTokenEndpoint(),\n inngest: {\n enabled: process.env.XPOD_INNGEST_ENABLED !== 'false',\n mode: process.env.XPOD_INNGEST_MODE === 'spawn' || process.env.XPOD_INNGEST_MODE === 'managed'\n ? process.env.XPOD_INNGEST_MODE\n : undefined,\n port: process.env.XPOD_INNGEST_PORT ? parseInt(process.env.XPOD_INNGEST_PORT, 10) : undefined,\n host: process.env.XPOD_INNGEST_HOST ?? '127.0.0.1',\n baseUrl: process.env.XPOD_INNGEST_BASE_URL,\n eventKey: process.env.XPOD_INNGEST_EVENT_KEY ?? process.env.INNGEST_EVENT_KEY,\n signingKey: process.env.XPOD_INNGEST_SIGNING_KEY ?? process.env.INNGEST_SIGNING_KEY,\n binaryPath: process.env.XPOD_INNGEST_BIN,\n sqliteDir: process.env.XPOD_INNGEST_SQLITE_DIR,\n },\n\n // 子域名配置 (cloud 模式)\n subdomain: {\n baseStorageDomain: process.env.CSS_BASE_STORAGE_DOMAIN,\n cloudflareAccountId: process.env.CLOUDFLARE_ACCOUNT_ID,\n cloudflareApiToken: process.env.CLOUDFLARE_API_TOKEN,\n tencentDnsSecretId: process.env.TENCENT_DNS_SECRET_ID,\n tencentDnsSecretKey: process.env.TENCENT_DNS_SECRET_KEY,\n },\n\n // Local 托管式:连接 Cloud\n cloudApiEndpoint: process.env.XPOD_CLOUD_API_ENDPOINT,\n nodeId: loadOrGenerateDeviceId(process.env.XPOD_NODE_ID),\n nodeToken: process.env.XPOD_NODE_TOKEN,\n\n // OIDC Issuer (Local 托管式使用 Cloud IdP)\n // 如果配置了 XPOD_NODE_TOKEN,默认使用 Cloud IdP\n oidcIssuer: resolveExternalOidcIssuer(process.env) ?? (\n process.env.XPOD_NODE_TOKEN\n ? OFFICIAL_CLOUD_IDENTITY_ORIGIN\n : undefined\n ),\n\n // 隧道配置\n cloudflareTunnelToken: process.env.CLOUDFLARE_TUNNEL_TOKEN,\n // Prefer SAKURA_TUNNEL_TOKEN; keep SAKURA_TOKEN for backward compatibility.\n sakuraTunnelToken: process.env.SAKURA_TUNNEL_TOKEN ?? process.env.SAKURA_TOKEN,\n\n // Edge 节点管理 (cloud 模式)\n edgeNodesEnabled: process.env.XPOD_EDGE_NODES_ENABLED === 'true',\n };\n}\n\n/**\n * 获取设备首个非内部网卡的 MAC 地址。\n * 返回小写冒号分隔格式,如 \"aa:bb:cc:dd:ee:ff\"。\n * 容器/虚拟机中可能拿不到稳定 MAC,此时返回 undefined。\n */\nfunction getFirstMacAddress(): string | undefined {\n const interfaces = os.networkInterfaces();\n for (const name of Object.keys(interfaces)) {\n for (const iface of interfaces[name] ?? []) {\n if (!iface.internal && iface.mac && iface.mac !== '00:00:00:00:00:00') {\n return iface.mac.toLowerCase();\n }\n }\n }\n return undefined;\n}\n\n/**\n * 读取或生成设备 ID(持久化到 data/.device-id)。\n *\n * 优先级:\n * 1. 环境变量 XPOD_NODE_ID\n * 2. 已持久化的 data/.device-id\n * 3. 基于 MAC 地址的 SHA-256 哈希(截取前 32 位 hex)\n * 4. 随机 UUID(容器/虚拟机无稳定 MAC 时兜底)\n *\n * 生成后写入 data/.device-id,后续启动直接读取,保证同一设备 ID 稳定。\n */\nfunction loadOrGenerateDeviceId(envNodeId?: string): string | undefined {\n if (envNodeId) {\n return envNodeId;\n }\n\n const rootDir = process.env.CSS_ROOT_FILE_PATH || './data';\n const deviceIdPath = path.join(rootDir, '.device-id');\n\n // 尝试从文件读取\n try {\n if (fs.existsSync(deviceIdPath)) {\n const content = fs.readFileSync(deviceIdPath, 'utf-8').trim();\n if (content) {\n return content;\n }\n }\n } catch {\n // 读取失败,继续生成\n }\n\n // 优先用 MAC 哈希,拿不到则 UUID 兜底\n const mac = getFirstMacAddress();\n const deviceId = mac\n ? createHash('sha256').update(mac).digest('hex').slice(0, 32)\n : randomUUID();\n\n try {\n if (!fs.existsSync(rootDir)) {\n fs.mkdirSync(rootDir, { recursive: true });\n }\n fs.writeFileSync(deviceIdPath, deviceId, 'utf-8');\n } catch {\n // 写入失败不阻塞启动\n }\n\n return deviceId;\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/api/container/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * API Container 入口\n *\n * 使用 Awilix 进行依赖注入,根据 edition 注册不同服务\n */\n\nimport { createContainer, asValue, InjectionMode, type AwilixContainer } from 'awilix';\nimport { randomUUID, createHash } from 'node:crypto';\nimport * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport type { ApiContainerCradle, ApiContainerConfig } from './types';\nimport { registerCommonServices } from './common';\nimport { registerCloudServices } from './cloud';\nimport { registerLocalServices } from './local';\nimport { registerBusinessToken } from './business-token';\nimport { resolveExternalOidcIssuer } from '../../runtime/oidc-issuer';\nimport { resolveAuthModeFromEnv } from '../../authorization/AuthMode';\n\nexport type { ApiContainerCradle, ApiContainerConfig } from './types';\n\nconst OFFICIAL_CLOUD_IDENTITY_ORIGIN = 'https://id.undefineds.co';\n\nfunction ensureTrailingSlash(url: string): string {\n return url.endsWith('/') ? url : `${url}/`;\n}\n\nfunction resolveCssTokenEndpoint(): string {\n if (process.env.CSS_TOKEN_ENDPOINT) {\n return process.env.CSS_TOKEN_ENDPOINT;\n }\n\n if (process.env.CSS_BASE_URL) {\n return `${ensureTrailingSlash(process.env.CSS_BASE_URL)}.oidc/token`;\n }\n\n return 'http://localhost:3000/.oidc/token';\n}\n\n/**\n * 创建 API 容器\n */\nexport function createApiContainer(config: ApiContainerConfig): AwilixContainer<ApiContainerCradle> {\n const container = createContainer<ApiContainerCradle>({\n injectionMode: InjectionMode.PROXY,\n strict: true,\n });\n\n // 注册配置\n container.register({\n config: asValue(config),\n inngestRuntimeConfig: asValue(config.inngestRuntimeConfig),\n });\n\n // 注册共享服务\n registerCommonServices(container);\n\n // 根据 edition 注册专属服务\n if (config.edition === 'cloud') {\n registerCloudServices(container);\n } else {\n registerLocalServices(container);\n }\n\n // 注册 Business Token (如果配置了 XPOD_BUSINESS_TOKEN)\n registerBusinessToken(container);\n\n return container;\n}\n\n/**\n * 从环境变量读取配置\n */\nexport function loadConfigFromEnv(): ApiContainerConfig {\n const edition = (process.env.XPOD_EDITION ?? 'local') as 'cloud' | 'local';\n\n // Port auto-increment: API_PORT = CSS_PORT + 1 if not explicitly set\n const cssPort = parseInt(process.env.CSS_PORT ?? '3000', 10);\n const apiPort = process.env.API_PORT\n ? parseInt(process.env.API_PORT, 10)\n : cssPort + 1;\n\n return {\n edition,\n port: apiPort,\n host: process.env.API_HOST ?? '0.0.0.0',\n socketPath: process.env.API_SOCKET_PATH,\n authMode: resolveAuthModeFromEnv(process.env),\n rdfIndexPath: process.env.CSS_RDF_INDEX_PATH,\n databaseUrl: process.env.CSS_IDENTITY_DB_URL ?? process.env.DATABASE_URL ?? '',\n redisUrl: process.env.CSS_REDIS_CLIENT ?? process.env.REDIS_URL,\n corsOrigins: process.env.CORS_ORIGINS?.split(',').map(s => s.trim()) ?? ['*'],\n cssTokenEndpoint: resolveCssTokenEndpoint(),\n inngest: {\n enabled: process.env.XPOD_INNGEST_ENABLED !== 'false',\n mode: process.env.XPOD_INNGEST_MODE === 'spawn' || process.env.XPOD_INNGEST_MODE === 'managed'\n ? process.env.XPOD_INNGEST_MODE\n : undefined,\n port: process.env.XPOD_INNGEST_PORT ? parseInt(process.env.XPOD_INNGEST_PORT, 10) : undefined,\n host: process.env.XPOD_INNGEST_HOST ?? '127.0.0.1',\n baseUrl: process.env.XPOD_INNGEST_BASE_URL,\n eventKey: process.env.XPOD_INNGEST_EVENT_KEY ?? process.env.INNGEST_EVENT_KEY,\n signingKey: process.env.XPOD_INNGEST_SIGNING_KEY ?? process.env.INNGEST_SIGNING_KEY,\n binaryPath: process.env.XPOD_INNGEST_BIN,\n sqliteDir: process.env.XPOD_INNGEST_SQLITE_DIR,\n },\n\n // 子域名配置 (cloud 模式)\n subdomain: {\n baseStorageDomain: process.env.CSS_BASE_STORAGE_DOMAIN,\n cloudflareAccountId: process.env.CLOUDFLARE_ACCOUNT_ID,\n cloudflareApiToken: process.env.CLOUDFLARE_API_TOKEN,\n tencentDnsSecretId: process.env.TENCENT_DNS_SECRET_ID,\n tencentDnsSecretKey: process.env.TENCENT_DNS_SECRET_KEY,\n },\n\n // Local 托管式:连接 Cloud\n cloudApiEndpoint: process.env.XPOD_CLOUD_API_ENDPOINT,\n nodeId: loadOrGenerateDeviceId(process.env.XPOD_NODE_ID),\n nodeToken: process.env.XPOD_NODE_TOKEN,\n\n // OIDC Issuer (Local 托管式使用 Cloud IdP)\n // 如果配置了 XPOD_NODE_TOKEN,默认使用 Cloud IdP\n oidcIssuer: resolveExternalOidcIssuer(process.env) ?? (\n process.env.XPOD_NODE_TOKEN\n ? OFFICIAL_CLOUD_IDENTITY_ORIGIN\n : undefined\n ),\n\n // 隧道配置\n cloudflareTunnelToken: process.env.CLOUDFLARE_TUNNEL_TOKEN,\n // Prefer SAKURA_TUNNEL_TOKEN; keep SAKURA_TOKEN for backward compatibility.\n sakuraTunnelToken: process.env.SAKURA_TUNNEL_TOKEN ?? process.env.SAKURA_TOKEN,\n\n // Edge 节点管理 (cloud 模式)\n edgeNodesEnabled: process.env.XPOD_EDGE_NODES_ENABLED === 'true',\n };\n}\n\n/**\n * 获取设备首个非内部网卡的 MAC 地址。\n * 返回小写冒号分隔格式,如 \"aa:bb:cc:dd:ee:ff\"。\n * 容器/虚拟机中可能拿不到稳定 MAC,此时返回 undefined。\n */\nfunction getFirstMacAddress(): string | undefined {\n const interfaces = os.networkInterfaces();\n for (const name of Object.keys(interfaces)) {\n for (const iface of interfaces[name] ?? []) {\n if (!iface.internal && iface.mac && iface.mac !== '00:00:00:00:00:00') {\n return iface.mac.toLowerCase();\n }\n }\n }\n return undefined;\n}\n\n/**\n * 读取或生成设备 ID(持久化到 data/.device-id)。\n *\n * 优先级:\n * 1. 环境变量 XPOD_NODE_ID\n * 2. 已持久化的 data/.device-id\n * 3. 基于 MAC 地址的 SHA-256 哈希(截取前 32 位 hex)\n * 4. 随机 UUID(容器/虚拟机无稳定 MAC 时兜底)\n *\n * 生成后写入 data/.device-id,后续启动直接读取,保证同一设备 ID 稳定。\n */\nfunction loadOrGenerateDeviceId(envNodeId?: string): string | undefined {\n if (envNodeId) {\n return envNodeId;\n }\n\n const rootDir = process.env.CSS_ROOT_FILE_PATH || './data';\n const deviceIdPath = path.join(rootDir, '.device-id');\n\n // 尝试从文件读取\n try {\n if (fs.existsSync(deviceIdPath)) {\n const content = fs.readFileSync(deviceIdPath, 'utf-8').trim();\n if (content) {\n return content;\n }\n }\n } catch {\n // 读取失败,继续生成\n }\n\n // 优先用 MAC 哈希,拿不到则 UUID 兜底\n const mac = getFirstMacAddress();\n const deviceId = mac\n ? createHash('sha256').update(mac).digest('hex').slice(0, 32)\n : randomUUID();\n\n try {\n if (!fs.existsSync(rootDir)) {\n fs.mkdirSync(rootDir, { recursive: true });\n }\n fs.writeFileSync(deviceIdPath, deviceId, 'utf-8');\n } catch {\n // 写入失败不阻塞启动\n }\n\n return deviceId;\n}\n"]}
@@ -237,7 +237,9 @@ function registerLocalRoutes(container, server) {
237
237
  rootDir,
238
238
  sparqlEndpoint,
239
239
  identityDbUrl,
240
+ rdfIndexPath: config.rdfIndexPath,
240
241
  oidcIssuer: process.env.oidcIssuer ?? config.oidcIssuer,
242
+ authMode: config.authMode,
241
243
  })
242
244
  : undefined;
243
245
  (0, PodManagementHandler_1.registerPodManagementRoutes)(server, {
@@ -1 +1 @@
1
- {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../../src/api/container/routes.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * 路由注册\n *\n * 根据容器中的服务注册 API 路由\n */\n\nimport type { AwilixContainer } from 'awilix';\nimport type { ApiContainerCradle, ApiContainerConfig } from './types';\nimport type { ApiServer } from '../ApiServer';\n\nimport { registerEdgeNodeSignalRoutes } from '../handlers/EdgeNodeSignalHandler';\nimport { registerNodeRoutes } from '../handlers/NodeHandler';\nimport { registerChatRoutes } from '../handlers/ChatHandler';\nimport { registerApiKeyRoutes } from '../handlers/ApiKeyHandler';\nimport { registerSubdomainRoutes } from '../handlers/SubdomainHandler';\nimport { registerSubdomainClientRoutes } from '../handlers/SubdomainClientHandler';\nimport { registerDdnsRoutes } from '../handlers/DdnsHandler';\nimport { registerChatKitRoutes } from '../handlers/ChatKitHandler';\nimport { registerChatKitV1Routes } from '../handlers/ChatKitV1Handler';\nimport { registerInngestRoutes } from '../handlers/InngestHandler';\nimport { registerRunRoutes } from '../handlers/RunHandler';\nimport { registerMatrixRoutes } from '../handlers/MatrixHandler';\nimport { registerDashboardRoutes } from '../handlers/DashboardHandler';\nimport { registerAdminRoutes } from '../handlers/AdminHandler';\nimport { registerAdminDdnsRoutes } from '../handlers/AdminDdnsHandler';\nimport { registerLinxCapabilitiesRoutes } from '../handlers/LinxCapabilitiesHandler';\nimport { registerProvisionRoutes, registerProvisionStatusRoute } from '../handlers/ProvisionHandler';\nimport { registerPodManagementRoutes } from '../handlers/PodManagementHandler';\nimport { registerQuotaRoutes } from '../handlers/QuotaHandler';\nimport { registerUsageRoutes } from '../handlers/UsageHandler';\nimport type { EdgeNodeRepository } from '../../identity/drizzle/EdgeNodeRepository';\nimport type { DrizzleClientCredentialsStore } from '../store/DrizzleClientCredentialsStore';\nimport { UsageRepository } from '../../storage/quota/UsageRepository';\nimport { DrizzleQuotaService } from '../../quota/DrizzleQuotaService';\nimport { LocalPodProvisioningService } from '../../provision/LocalPodProvisioningService';\nimport * as path from 'node:path';\nimport { PACKAGE_ROOT } from '../../runtime';\n\n/**\n * 注册所有 API 路由\n */\nexport function registerRoutes(container: AwilixContainer<ApiContainerCradle>): void {\n const server = container.resolve('apiServer') as ApiServer;\n const config = container.resolve('config') as ApiContainerConfig;\n\n // 公共健康检查端点\n registerHealthRoutes(server);\n\n // 共享路由\n registerSharedRoutes(container, server);\n\n // 根据 edition 注册专属路由\n if (config.edition === 'cloud') {\n registerCloudRoutes(container, server);\n } else {\n registerLocalRoutes(container, server);\n }\n}\n\n/**\n * 健康检查路由\n */\nfunction registerHealthRoutes(server: ApiServer): void {\n server.get('/health', async (_req, res) => {\n res.statusCode = 200;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ status: 'ok' }));\n }, { public: true });\n\n server.get('/ready', async (_req, res) => {\n res.statusCode = 200;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ status: 'ready' }));\n }, { public: true });\n\n // Dashboard 静态资源\n const staticDir = path.resolve(PACKAGE_ROOT, 'static/dashboard');\n registerDashboardRoutes(server, { staticDir });\n}\n\n/**\n * 共享路由 (cloud 和 local 都有)\n */\nfunction registerSharedRoutes(\n container: AwilixContainer<ApiContainerCradle>,\n server: ApiServer,\n): void {\n const nodeRepo = container.resolve('nodeRepo') as EdgeNodeRepository;\n const apiKeyStore = container.resolve('apiKeyStore') as DrizzleClientCredentialsStore;\n const chatService = container.resolve('chatService');\n const chatKitService = container.resolve('chatKitService');\n const chatKitStore = container.resolve('chatKitStore');\n const runExecutionBackend = container.resolve('runExecutionBackend');\n const matrixStore = container.resolve('matrixStore');\n const inngestTaskScheduler = container.resolve('inngestTaskScheduler');\n const inngestRuntimeConfig = container.resolve('inngestRuntimeConfig');\n const config = container.resolve('config') as ApiContainerConfig;\n\n registerEdgeNodeSignalRoutes(server, {\n repository: nodeRepo,\n dnsCoordinator: container.resolve('dnsCoordinator', { allowUnregistered: true }) as any,\n healthProbeService: container.resolve('healthProbeService', { allowUnregistered: true }) as any,\n });\n registerNodeRoutes(server, { repository: nodeRepo });\n registerApiKeyRoutes(server, { store: apiKeyStore });\n registerChatRoutes(server, { chatService });\n registerChatKitRoutes(server, { chatKitService });\n registerChatKitV1Routes(server, { store: chatKitStore });\n registerRunRoutes(server, { runStore: chatKitStore });\n registerMatrixRoutes(server, { store: matrixStore });\n registerInngestRoutes(server, {\n backend: runExecutionBackend,\n taskScheduler: inngestTaskScheduler,\n runtimeConfig: inngestRuntimeConfig,\n });\n\n // Quota & Usage API (Business 对接)\n try {\n const quotaService = new DrizzleQuotaService({ identityDbUrl: config.databaseUrl });\n const usageRepo = new UsageRepository(container.resolve('db'));\n registerQuotaRoutes(server, { quotaService, usageRepo });\n registerUsageRoutes(server, { usageRepo });\n console.log('[Shared] Quota & Usage routes registered');\n } catch (error) {\n console.log(`[Shared] Quota & Usage routes not registered: ${error}`);\n }\n}\n\n/**\n * Cloud 模式专属路由\n */\nfunction registerCloudRoutes(\n container: AwilixContainer<ApiContainerCradle>,\n server: ApiServer,\n): void {\n // 子域名管理 API (需要 SubdomainService)\n try {\n const subdomainService = container.resolve('subdomainService') as ApiContainerCradle['subdomainService'];\n if (subdomainService) {\n registerSubdomainRoutes(server, { subdomainService });\n console.log('[Cloud] Subdomain routes registered');\n }\n } catch {\n console.log('[Cloud] Subdomain routes not registered (service not available)');\n }\n\n // DDNS 服务\n try {\n const ddnsRepo = container.resolve('ddnsRepo', { allowUnregistered: true });\n const dnsProvider = container.resolve('dnsProvider', { allowUnregistered: true });\n const config = container.resolve('config') as ApiContainerConfig;\n\n if (ddnsRepo) {\n const baseStorageDomain = config.subdomain?.baseStorageDomain;\n if (baseStorageDomain) {\n registerDdnsRoutes(server, {\n ddnsRepo: ddnsRepo as any,\n dnsProvider: dnsProvider as any,\n defaultDomain: baseStorageDomain,\n });\n console.log(`[Cloud] DDNS routes registered (domain: ${baseStorageDomain})`);\n } else {\n console.log('[Cloud] DDNS routes not registered (no CSS_BASE_STORAGE_DOMAIN)');\n }\n }\n } catch {\n console.log('[Cloud] DDNS routes not registered (repo not available)');\n }\n\n // SP Provision API (SP 注册)\n try {\n const nodeRepo = container.resolve('nodeRepo') as EdgeNodeRepository;\n const config = container.resolve('config') as ApiContainerConfig;\n const baseUrl = process.env.CSS_BASE_URL || 'http://localhost:3000/';\n const baseStorageDomain = config.subdomain?.baseStorageDomain;\n const ddnsRepo = container.resolve('ddnsRepo', { allowUnregistered: true }) as any;\n const dnsProvider = container.resolve('dnsProvider', { allowUnregistered: true }) as any;\n const tunnelProvider = container.resolve('tunnelProvider', { allowUnregistered: true }) as any;\n registerProvisionRoutes(server, {\n repository: nodeRepo,\n ddnsRepo,\n dnsProvider,\n tunnelProvider,\n baseUrl,\n baseStorageDomain,\n });\n console.log(`[Cloud] Provision routes registered${baseStorageDomain ? ` (baseStorageDomain: ${baseStorageDomain})` : ''}`);\n } catch {\n console.log('[Cloud] Provision routes not registered (dependencies not available)');\n }\n}\n\n/**\n * Local 模式专属路由\n */\nfunction registerLocalRoutes(\n container: AwilixContainer<ApiContainerCradle>,\n server: ApiServer,\n): void {\n registerLinxCapabilitiesRoutes(server);\n\n // Admin API (配置管理、重启)\n registerAdminRoutes(server);\n\n // DDNS status (托管式 Local 模式)\n try {\n const ddnsManager = container.resolve('ddnsManager', { allowUnregistered: true }) as any;\n registerAdminDdnsRoutes(server, { ddnsManager });\n } catch {\n // ignore\n }\n\n // 子域名客户端 API (通过 SubdomainClient 调用 Cloud)\n try {\n const subdomainClient = container.resolve('subdomainClient') as ApiContainerCradle['subdomainClient'];\n if (subdomainClient) {\n registerSubdomainClientRoutes(server, { subdomainClient });\n console.log('[Local] Subdomain client routes registered');\n }\n } catch {\n console.log('[Local] Subdomain client routes not registered (client not available)');\n }\n\n // Pod Provision API (SP 端,供 Cloud 回调创建 Pod)\n try {\n // rootDir: CSS 数据目录,默认 ./data\n const rootDir = process.env.CSS_ROOT_FILE_PATH || './data';\n // serviceToken 验证:从 SP 配置中读取\n const expectedServiceToken = process.env.XPOD_SERVICE_TOKEN;\n\n if (expectedServiceToken) {\n const config = container.resolve('config') as ApiContainerConfig;\n const baseUrl = process.env.CSS_BASE_URL || 'http://localhost:3000/';\n const sparqlEndpoint = process.env.CSS_SPARQL_ENDPOINT || process.env.SPARQL_ENDPOINT;\n const identityDbUrl = process.env.CSS_IDENTITY_DB_URL || process.env.DATABASE_URL;\n const provisioningService = sparqlEndpoint && identityDbUrl\n ? new LocalPodProvisioningService({\n baseUrl,\n rootDir,\n sparqlEndpoint,\n identityDbUrl,\n oidcIssuer: process.env.oidcIssuer ?? config.oidcIssuer,\n })\n : undefined;\n\n registerPodManagementRoutes(server, {\n rootDir,\n verifyServiceToken: async (token: string) => token === expectedServiceToken,\n provisioningService,\n podLookupRepository: container.resolve('podLookupRepo', { allowUnregistered: true }),\n });\n console.log(`[Local] Pod provision routes registered (/provision/pods, /provision/webids, ${provisioningService ? 'css-compatible' : 'directory-only'})`);\n } else {\n console.log('[Local] Pod provision routes not registered (XPOD_SERVICE_TOKEN not configured)');\n }\n } catch (error) {\n console.log(`[Local] Pod provision routes not registered: ${error}`);\n }\n\n // SP 状态查询 (供 Linx 查询 SP 配置状态)\n try {\n const config = container.resolve('config') as ApiContainerConfig;\n registerProvisionStatusRoute(server, {\n cloudUrl: config.cloudApiEndpoint,\n nodeId: config.nodeId,\n cloudBaseUrl: config.oidcIssuer || config.cloudApiEndpoint,\n });\n console.log('[Local] Provision status route registered (/provision/status)');\n } catch (error) {\n console.log(`[Local] Provision status route not registered: ${error}`);\n }\n}\n"]}
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../../src/api/container/routes.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * 路由注册\n *\n * 根据容器中的服务注册 API 路由\n */\n\nimport type { AwilixContainer } from 'awilix';\nimport type { ApiContainerCradle, ApiContainerConfig } from './types';\nimport type { ApiServer } from '../ApiServer';\n\nimport { registerEdgeNodeSignalRoutes } from '../handlers/EdgeNodeSignalHandler';\nimport { registerNodeRoutes } from '../handlers/NodeHandler';\nimport { registerChatRoutes } from '../handlers/ChatHandler';\nimport { registerApiKeyRoutes } from '../handlers/ApiKeyHandler';\nimport { registerSubdomainRoutes } from '../handlers/SubdomainHandler';\nimport { registerSubdomainClientRoutes } from '../handlers/SubdomainClientHandler';\nimport { registerDdnsRoutes } from '../handlers/DdnsHandler';\nimport { registerChatKitRoutes } from '../handlers/ChatKitHandler';\nimport { registerChatKitV1Routes } from '../handlers/ChatKitV1Handler';\nimport { registerInngestRoutes } from '../handlers/InngestHandler';\nimport { registerRunRoutes } from '../handlers/RunHandler';\nimport { registerMatrixRoutes } from '../handlers/MatrixHandler';\nimport { registerDashboardRoutes } from '../handlers/DashboardHandler';\nimport { registerAdminRoutes } from '../handlers/AdminHandler';\nimport { registerAdminDdnsRoutes } from '../handlers/AdminDdnsHandler';\nimport { registerLinxCapabilitiesRoutes } from '../handlers/LinxCapabilitiesHandler';\nimport { registerProvisionRoutes, registerProvisionStatusRoute } from '../handlers/ProvisionHandler';\nimport { registerPodManagementRoutes } from '../handlers/PodManagementHandler';\nimport { registerQuotaRoutes } from '../handlers/QuotaHandler';\nimport { registerUsageRoutes } from '../handlers/UsageHandler';\nimport type { EdgeNodeRepository } from '../../identity/drizzle/EdgeNodeRepository';\nimport type { DrizzleClientCredentialsStore } from '../store/DrizzleClientCredentialsStore';\nimport { UsageRepository } from '../../storage/quota/UsageRepository';\nimport { DrizzleQuotaService } from '../../quota/DrizzleQuotaService';\nimport { LocalPodProvisioningService } from '../../provision/LocalPodProvisioningService';\nimport * as path from 'node:path';\nimport { PACKAGE_ROOT } from '../../runtime';\n\n/**\n * 注册所有 API 路由\n */\nexport function registerRoutes(container: AwilixContainer<ApiContainerCradle>): void {\n const server = container.resolve('apiServer') as ApiServer;\n const config = container.resolve('config') as ApiContainerConfig;\n\n // 公共健康检查端点\n registerHealthRoutes(server);\n\n // 共享路由\n registerSharedRoutes(container, server);\n\n // 根据 edition 注册专属路由\n if (config.edition === 'cloud') {\n registerCloudRoutes(container, server);\n } else {\n registerLocalRoutes(container, server);\n }\n}\n\n/**\n * 健康检查路由\n */\nfunction registerHealthRoutes(server: ApiServer): void {\n server.get('/health', async (_req, res) => {\n res.statusCode = 200;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ status: 'ok' }));\n }, { public: true });\n\n server.get('/ready', async (_req, res) => {\n res.statusCode = 200;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ status: 'ready' }));\n }, { public: true });\n\n // Dashboard 静态资源\n const staticDir = path.resolve(PACKAGE_ROOT, 'static/dashboard');\n registerDashboardRoutes(server, { staticDir });\n}\n\n/**\n * 共享路由 (cloud 和 local 都有)\n */\nfunction registerSharedRoutes(\n container: AwilixContainer<ApiContainerCradle>,\n server: ApiServer,\n): void {\n const nodeRepo = container.resolve('nodeRepo') as EdgeNodeRepository;\n const apiKeyStore = container.resolve('apiKeyStore') as DrizzleClientCredentialsStore;\n const chatService = container.resolve('chatService');\n const chatKitService = container.resolve('chatKitService');\n const chatKitStore = container.resolve('chatKitStore');\n const runExecutionBackend = container.resolve('runExecutionBackend');\n const matrixStore = container.resolve('matrixStore');\n const inngestTaskScheduler = container.resolve('inngestTaskScheduler');\n const inngestRuntimeConfig = container.resolve('inngestRuntimeConfig');\n const config = container.resolve('config') as ApiContainerConfig;\n\n registerEdgeNodeSignalRoutes(server, {\n repository: nodeRepo,\n dnsCoordinator: container.resolve('dnsCoordinator', { allowUnregistered: true }) as any,\n healthProbeService: container.resolve('healthProbeService', { allowUnregistered: true }) as any,\n });\n registerNodeRoutes(server, { repository: nodeRepo });\n registerApiKeyRoutes(server, { store: apiKeyStore });\n registerChatRoutes(server, { chatService });\n registerChatKitRoutes(server, { chatKitService });\n registerChatKitV1Routes(server, { store: chatKitStore });\n registerRunRoutes(server, { runStore: chatKitStore });\n registerMatrixRoutes(server, { store: matrixStore });\n registerInngestRoutes(server, {\n backend: runExecutionBackend,\n taskScheduler: inngestTaskScheduler,\n runtimeConfig: inngestRuntimeConfig,\n });\n\n // Quota & Usage API (Business 对接)\n try {\n const quotaService = new DrizzleQuotaService({ identityDbUrl: config.databaseUrl });\n const usageRepo = new UsageRepository(container.resolve('db'));\n registerQuotaRoutes(server, { quotaService, usageRepo });\n registerUsageRoutes(server, { usageRepo });\n console.log('[Shared] Quota & Usage routes registered');\n } catch (error) {\n console.log(`[Shared] Quota & Usage routes not registered: ${error}`);\n }\n}\n\n/**\n * Cloud 模式专属路由\n */\nfunction registerCloudRoutes(\n container: AwilixContainer<ApiContainerCradle>,\n server: ApiServer,\n): void {\n // 子域名管理 API (需要 SubdomainService)\n try {\n const subdomainService = container.resolve('subdomainService') as ApiContainerCradle['subdomainService'];\n if (subdomainService) {\n registerSubdomainRoutes(server, { subdomainService });\n console.log('[Cloud] Subdomain routes registered');\n }\n } catch {\n console.log('[Cloud] Subdomain routes not registered (service not available)');\n }\n\n // DDNS 服务\n try {\n const ddnsRepo = container.resolve('ddnsRepo', { allowUnregistered: true });\n const dnsProvider = container.resolve('dnsProvider', { allowUnregistered: true });\n const config = container.resolve('config') as ApiContainerConfig;\n\n if (ddnsRepo) {\n const baseStorageDomain = config.subdomain?.baseStorageDomain;\n if (baseStorageDomain) {\n registerDdnsRoutes(server, {\n ddnsRepo: ddnsRepo as any,\n dnsProvider: dnsProvider as any,\n defaultDomain: baseStorageDomain,\n });\n console.log(`[Cloud] DDNS routes registered (domain: ${baseStorageDomain})`);\n } else {\n console.log('[Cloud] DDNS routes not registered (no CSS_BASE_STORAGE_DOMAIN)');\n }\n }\n } catch {\n console.log('[Cloud] DDNS routes not registered (repo not available)');\n }\n\n // SP Provision API (SP 注册)\n try {\n const nodeRepo = container.resolve('nodeRepo') as EdgeNodeRepository;\n const config = container.resolve('config') as ApiContainerConfig;\n const baseUrl = process.env.CSS_BASE_URL || 'http://localhost:3000/';\n const baseStorageDomain = config.subdomain?.baseStorageDomain;\n const ddnsRepo = container.resolve('ddnsRepo', { allowUnregistered: true }) as any;\n const dnsProvider = container.resolve('dnsProvider', { allowUnregistered: true }) as any;\n const tunnelProvider = container.resolve('tunnelProvider', { allowUnregistered: true }) as any;\n registerProvisionRoutes(server, {\n repository: nodeRepo,\n ddnsRepo,\n dnsProvider,\n tunnelProvider,\n baseUrl,\n baseStorageDomain,\n });\n console.log(`[Cloud] Provision routes registered${baseStorageDomain ? ` (baseStorageDomain: ${baseStorageDomain})` : ''}`);\n } catch {\n console.log('[Cloud] Provision routes not registered (dependencies not available)');\n }\n}\n\n/**\n * Local 模式专属路由\n */\nfunction registerLocalRoutes(\n container: AwilixContainer<ApiContainerCradle>,\n server: ApiServer,\n): void {\n registerLinxCapabilitiesRoutes(server);\n\n // Admin API (配置管理、重启)\n registerAdminRoutes(server);\n\n // DDNS status (托管式 Local 模式)\n try {\n const ddnsManager = container.resolve('ddnsManager', { allowUnregistered: true }) as any;\n registerAdminDdnsRoutes(server, { ddnsManager });\n } catch {\n // ignore\n }\n\n // 子域名客户端 API (通过 SubdomainClient 调用 Cloud)\n try {\n const subdomainClient = container.resolve('subdomainClient') as ApiContainerCradle['subdomainClient'];\n if (subdomainClient) {\n registerSubdomainClientRoutes(server, { subdomainClient });\n console.log('[Local] Subdomain client routes registered');\n }\n } catch {\n console.log('[Local] Subdomain client routes not registered (client not available)');\n }\n\n // Pod Provision API (SP 端,供 Cloud 回调创建 Pod)\n try {\n // rootDir: CSS 数据目录,默认 ./data\n const rootDir = process.env.CSS_ROOT_FILE_PATH || './data';\n // serviceToken 验证:从 SP 配置中读取\n const expectedServiceToken = process.env.XPOD_SERVICE_TOKEN;\n\n if (expectedServiceToken) {\n const config = container.resolve('config') as ApiContainerConfig;\n const baseUrl = process.env.CSS_BASE_URL || 'http://localhost:3000/';\n const sparqlEndpoint = process.env.CSS_SPARQL_ENDPOINT || process.env.SPARQL_ENDPOINT;\n const identityDbUrl = process.env.CSS_IDENTITY_DB_URL || process.env.DATABASE_URL;\n const provisioningService = sparqlEndpoint && identityDbUrl\n ? new LocalPodProvisioningService({\n baseUrl,\n rootDir,\n sparqlEndpoint,\n identityDbUrl,\n rdfIndexPath: config.rdfIndexPath,\n oidcIssuer: process.env.oidcIssuer ?? config.oidcIssuer,\n authMode: config.authMode,\n })\n : undefined;\n\n registerPodManagementRoutes(server, {\n rootDir,\n verifyServiceToken: async (token: string) => token === expectedServiceToken,\n provisioningService,\n podLookupRepository: container.resolve('podLookupRepo', { allowUnregistered: true }),\n });\n console.log(`[Local] Pod provision routes registered (/provision/pods, /provision/webids, ${provisioningService ? 'css-compatible' : 'directory-only'})`);\n } else {\n console.log('[Local] Pod provision routes not registered (XPOD_SERVICE_TOKEN not configured)');\n }\n } catch (error) {\n console.log(`[Local] Pod provision routes not registered: ${error}`);\n }\n\n // SP 状态查询 (供 Linx 查询 SP 配置状态)\n try {\n const config = container.resolve('config') as ApiContainerConfig;\n registerProvisionStatusRoute(server, {\n cloudUrl: config.cloudApiEndpoint,\n nodeId: config.nodeId,\n cloudBaseUrl: config.oidcIssuer || config.cloudApiEndpoint,\n });\n console.log('[Local] Provision status route registered (/provision/status)');\n } catch (error) {\n console.log(`[Local] Provision status route not registered: ${error}`);\n }\n}\n"]}
@@ -28,6 +28,7 @@ import type { EmbeddedInngestRuntimeConfig } from '../runs/EmbeddedInngestServic
28
28
  import type { RunAuthContextRegistry } from '../runs/RunAuthContextRegistry';
29
29
  import type { TaskAuthBindingService, TaskService, InngestTaskScheduler } from '../tasks';
30
30
  import type { PodMatrixStore } from '../matrix';
31
+ import type { AuthMode } from '../../authorization/AuthMode';
31
32
  /**
32
33
  * 容器配置
33
34
  */
@@ -42,6 +43,10 @@ export interface ApiContainerConfig {
42
43
  socketPath?: string;
43
44
  /** Runtime host implementation */
44
45
  runtimeHost?: RuntimeHost;
46
+ /** Solid authorization mode used by CSS and SP-local Pod provisioning. */
47
+ authMode: AuthMode;
48
+ /** RDF term-id index used by CSS LDP structured reads. */
49
+ rdfIndexPath?: string;
45
50
  /** 数据库连接 URL */
46
51
  databaseUrl: string;
47
52
  /** Redis connection URL, used by embedded infrastructure such as Inngest in cloud mode. */
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/api/container/types.ts"],"names":[],"mappings":";AAAA;;;;GAIG","sourcesContent":["/**\n * API Container 依赖类型定义\n *\n * 定义容器中注册的所有服务接口\n */\n\nimport type { ApiServer } from '../ApiServer';\nimport type { AuthMiddleware } from '../middleware/AuthMiddleware';\nimport type { Authenticator } from '../auth/Authenticator';\nimport type { EdgeNodeRepository } from '../../identity/drizzle/EdgeNodeRepository';\nimport type { ServiceTokenRepository } from '../../identity/drizzle/ServiceTokenRepository';\nimport type { DrizzleClientCredentialsStore } from '../store/DrizzleClientCredentialsStore';\nimport type { VercelChatService } from '../service/VercelChatService';\nimport type { SubdomainService } from '../../subdomain/SubdomainService';\nimport type { SubdomainClient } from '../../subdomain/SubdomainClient';\nimport type { DnsProvider } from '../../dns/DnsProvider';\nimport type { TunnelProvider } from '../../tunnel/TunnelProvider';\nimport type { IdentityDatabase } from '../../identity/drizzle/db';\nimport type { DdnsRepository } from '../../identity/drizzle/DdnsRepository';\nimport type { PodLookupRepository } from '../../identity/drizzle/PodLookupRepository';\nimport type { ChatKitService, AiProvider } from '../chatkit';\nimport type { StoreContext } from '../chatkit/store';\nimport type { PodChatKitStore } from '../chatkit/pod-store';\nimport type { RuntimeHost } from '../../runtime/host/types';\nimport type { ProviderRegistry, EmbeddingService } from '../../ai/service';\nimport type { VectorService } from '../service/VectorService';\nimport type { InngestRunExecutionBackend } from '../runs/InngestRunExecutionBackend';\nimport type { EmbeddedInngestRuntimeConfig } from '../runs/EmbeddedInngestService';\nimport type { RunAuthContextRegistry } from '../runs/RunAuthContextRegistry';\nimport type { TaskAuthBindingService, TaskService, InngestTaskScheduler } from '../tasks';\nimport type { PodMatrixStore } from '../matrix';\n\n/**\n * 容器配置\n */\nexport interface ApiContainerConfig {\n /** 运行模式: cloud 持有密钥, local 调用远程 */\n edition: 'cloud' | 'local';\n\n /** API Server 端口 */\n port: number;\n\n /** API Server 主机 */\n host: string;\n\n /** API Server Unix socket 路径 */\n socketPath?: string;\n\n /** Runtime host implementation */\n runtimeHost?: RuntimeHost;\n /** 数据库连接 URL */\n databaseUrl: string;\n\n /** Redis connection URL, used by embedded infrastructure such as Inngest in cloud mode. */\n redisUrl?: string;\n\n /** Embedded Inngest runtime configuration. */\n inngest?: {\n enabled: boolean;\n mode?: 'managed' | 'spawn';\n port?: number;\n host?: string;\n baseUrl?: string;\n eventKey?: string;\n signingKey?: string;\n binaryPath?: string;\n sqliteDir?: string;\n };\n\n /** Resolved runtime config passed from API bootstrap after starting/locating Inngest. */\n inngestRuntimeConfig?: EmbeddedInngestRuntimeConfig;\n\n /** CORS 允许的源 */\n corsOrigins: string[];\n\n /** CSS Token 端点 */\n cssTokenEndpoint: string;\n\n /** 子域名功能配置 (cloud 模式) */\n subdomain?: {\n /** 节点域名根域名 (如 undefineds.site),有值即启用子域名功能 */\n baseStorageDomain?: string;\n cloudflareAccountId?: string;\n cloudflareApiToken?: string;\n tencentDnsSecretId?: string;\n tencentDnsSecretKey?: string;\n };\n\n /** Cloud API 端点 (local 托管式,调用 cloud 的子域名 API) */\n cloudApiEndpoint?: string;\n\n /** 节点 ID (local 托管式) */\n nodeId?: string;\n\n /** 节点 Token (local 托管式,调用 Cloud API 的认证) */\n nodeToken?: string;\n\n /** OIDC Issuer URL (local 托管式,使用 Cloud IdP) */\n oidcIssuer?: string;\n\n /** Cloudflare Tunnel Token (local 托管式/自管式,启动 cloudflared) */\n cloudflareTunnelToken?: string;\n\n /** SakuraFRP Tunnel Token (SAKURA_TUNNEL_TOKEN;local 托管式/自管式,启动 frpc) */\n sakuraTunnelToken?: string;\n\n /** 是否接受 Edge 节点注册 (cloud 模式) */\n edgeNodesEnabled?: boolean;\n}\n\nimport { EdgeNodeDnsCoordinator } from '../../edge/EdgeNodeDnsCoordinator';\nimport { EdgeNodeHealthProbeService } from '../../edge/EdgeNodeHealthProbeService';\nimport { EdgeNodeCapabilityDetector } from '../../edge/EdgeNodeCapabilityDetector';\nimport { LocalNetworkManager } from '../../edge/LocalNetworkManager';\nimport { DdnsManager } from '../../edge/DdnsManager';\n\n/**\n * 容器中注册的所有服务\n */\nexport interface ApiContainerCradle {\n // 配置\n config: ApiContainerConfig;\n\n // 核心服务\n db: IdentityDatabase;\n apiServer: ApiServer;\n authMiddleware: AuthMiddleware;\n authenticator: Authenticator;\n\n // 仓库\n nodeRepo: EdgeNodeRepository;\n serviceTokenRepo: ServiceTokenRepository;\n apiKeyStore: DrizzleClientCredentialsStore;\n\n // 业务服务\n chatService: VercelChatService;\n\n // ChatKit 服务 (OpenAI ChatKit 协议)\n chatKitStore: PodChatKitStore;\n chatKitAiProvider: AiProvider;\n inngestRuntimeConfig: EmbeddedInngestRuntimeConfig | undefined;\n runAuthContextRegistry: RunAuthContextRegistry;\n runExecutionBackend: InngestRunExecutionBackend;\n taskAuthBindingService: TaskAuthBindingService<StoreContext>;\n taskService: TaskService<StoreContext>;\n inngestTaskScheduler: InngestTaskScheduler<StoreContext>;\n chatKitService: ChatKitService<StoreContext>;\n matrixStore: PodMatrixStore;\n providerRegistry: ProviderRegistry;\n embeddingService: EmbeddingService;\n vectorService: VectorService;\n\n // Cloud 模式: 身份服务\n ddnsRepo?: DdnsRepository;\n podLookupRepo?: PodLookupRepository;\n\n // 子域名相关 (可选,按 edition 注册)\n // Cloud 模式 或 Local 自管模式\n dnsProvider?: DnsProvider;\n dnsCoordinator?: EdgeNodeDnsCoordinator;\n healthProbeService?: EdgeNodeHealthProbeService;\n capabilityDetector?: EdgeNodeCapabilityDetector;\n localNetworkManager?: LocalNetworkManager;\n\n tunnelProvider?: TunnelProvider;\n subdomainService?: SubdomainService;\n // Local 托管式\n subdomainClient?: SubdomainClient;\n // Local 托管式 DDNS 管理\n ddnsManager?: DdnsManager;\n // Local 托管式/自管式 (启动 cloudflared)\n localTunnelProvider?: TunnelProvider;\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/api/container/types.ts"],"names":[],"mappings":";AAAA;;;;GAIG","sourcesContent":["/**\n * API Container 依赖类型定义\n *\n * 定义容器中注册的所有服务接口\n */\n\nimport type { ApiServer } from '../ApiServer';\nimport type { AuthMiddleware } from '../middleware/AuthMiddleware';\nimport type { Authenticator } from '../auth/Authenticator';\nimport type { EdgeNodeRepository } from '../../identity/drizzle/EdgeNodeRepository';\nimport type { ServiceTokenRepository } from '../../identity/drizzle/ServiceTokenRepository';\nimport type { DrizzleClientCredentialsStore } from '../store/DrizzleClientCredentialsStore';\nimport type { VercelChatService } from '../service/VercelChatService';\nimport type { SubdomainService } from '../../subdomain/SubdomainService';\nimport type { SubdomainClient } from '../../subdomain/SubdomainClient';\nimport type { DnsProvider } from '../../dns/DnsProvider';\nimport type { TunnelProvider } from '../../tunnel/TunnelProvider';\nimport type { IdentityDatabase } from '../../identity/drizzle/db';\nimport type { DdnsRepository } from '../../identity/drizzle/DdnsRepository';\nimport type { PodLookupRepository } from '../../identity/drizzle/PodLookupRepository';\nimport type { ChatKitService, AiProvider } from '../chatkit';\nimport type { StoreContext } from '../chatkit/store';\nimport type { PodChatKitStore } from '../chatkit/pod-store';\nimport type { RuntimeHost } from '../../runtime/host/types';\nimport type { ProviderRegistry, EmbeddingService } from '../../ai/service';\nimport type { VectorService } from '../service/VectorService';\nimport type { InngestRunExecutionBackend } from '../runs/InngestRunExecutionBackend';\nimport type { EmbeddedInngestRuntimeConfig } from '../runs/EmbeddedInngestService';\nimport type { RunAuthContextRegistry } from '../runs/RunAuthContextRegistry';\nimport type { TaskAuthBindingService, TaskService, InngestTaskScheduler } from '../tasks';\nimport type { PodMatrixStore } from '../matrix';\nimport type { AuthMode } from '../../authorization/AuthMode';\n\n/**\n * 容器配置\n */\nexport interface ApiContainerConfig {\n /** 运行模式: cloud 持有密钥, local 调用远程 */\n edition: 'cloud' | 'local';\n\n /** API Server 端口 */\n port: number;\n\n /** API Server 主机 */\n host: string;\n\n /** API Server Unix socket 路径 */\n socketPath?: string;\n\n /** Runtime host implementation */\n runtimeHost?: RuntimeHost;\n\n /** Solid authorization mode used by CSS and SP-local Pod provisioning. */\n authMode: AuthMode;\n\n /** RDF term-id index used by CSS LDP structured reads. */\n rdfIndexPath?: string;\n\n /** 数据库连接 URL */\n databaseUrl: string;\n\n /** Redis connection URL, used by embedded infrastructure such as Inngest in cloud mode. */\n redisUrl?: string;\n\n /** Embedded Inngest runtime configuration. */\n inngest?: {\n enabled: boolean;\n mode?: 'managed' | 'spawn';\n port?: number;\n host?: string;\n baseUrl?: string;\n eventKey?: string;\n signingKey?: string;\n binaryPath?: string;\n sqliteDir?: string;\n };\n\n /** Resolved runtime config passed from API bootstrap after starting/locating Inngest. */\n inngestRuntimeConfig?: EmbeddedInngestRuntimeConfig;\n\n /** CORS 允许的源 */\n corsOrigins: string[];\n\n /** CSS Token 端点 */\n cssTokenEndpoint: string;\n\n /** 子域名功能配置 (cloud 模式) */\n subdomain?: {\n /** 节点域名根域名 (如 undefineds.site),有值即启用子域名功能 */\n baseStorageDomain?: string;\n cloudflareAccountId?: string;\n cloudflareApiToken?: string;\n tencentDnsSecretId?: string;\n tencentDnsSecretKey?: string;\n };\n\n /** Cloud API 端点 (local 托管式,调用 cloud 的子域名 API) */\n cloudApiEndpoint?: string;\n\n /** 节点 ID (local 托管式) */\n nodeId?: string;\n\n /** 节点 Token (local 托管式,调用 Cloud API 的认证) */\n nodeToken?: string;\n\n /** OIDC Issuer URL (local 托管式,使用 Cloud IdP) */\n oidcIssuer?: string;\n\n /** Cloudflare Tunnel Token (local 托管式/自管式,启动 cloudflared) */\n cloudflareTunnelToken?: string;\n\n /** SakuraFRP Tunnel Token (SAKURA_TUNNEL_TOKEN;local 托管式/自管式,启动 frpc) */\n sakuraTunnelToken?: string;\n\n /** 是否接受 Edge 节点注册 (cloud 模式) */\n edgeNodesEnabled?: boolean;\n}\n\nimport { EdgeNodeDnsCoordinator } from '../../edge/EdgeNodeDnsCoordinator';\nimport { EdgeNodeHealthProbeService } from '../../edge/EdgeNodeHealthProbeService';\nimport { EdgeNodeCapabilityDetector } from '../../edge/EdgeNodeCapabilityDetector';\nimport { LocalNetworkManager } from '../../edge/LocalNetworkManager';\nimport { DdnsManager } from '../../edge/DdnsManager';\n\n/**\n * 容器中注册的所有服务\n */\nexport interface ApiContainerCradle {\n // 配置\n config: ApiContainerConfig;\n\n // 核心服务\n db: IdentityDatabase;\n apiServer: ApiServer;\n authMiddleware: AuthMiddleware;\n authenticator: Authenticator;\n\n // 仓库\n nodeRepo: EdgeNodeRepository;\n serviceTokenRepo: ServiceTokenRepository;\n apiKeyStore: DrizzleClientCredentialsStore;\n\n // 业务服务\n chatService: VercelChatService;\n\n // ChatKit 服务 (OpenAI ChatKit 协议)\n chatKitStore: PodChatKitStore;\n chatKitAiProvider: AiProvider;\n inngestRuntimeConfig: EmbeddedInngestRuntimeConfig | undefined;\n runAuthContextRegistry: RunAuthContextRegistry;\n runExecutionBackend: InngestRunExecutionBackend;\n taskAuthBindingService: TaskAuthBindingService<StoreContext>;\n taskService: TaskService<StoreContext>;\n inngestTaskScheduler: InngestTaskScheduler<StoreContext>;\n chatKitService: ChatKitService<StoreContext>;\n matrixStore: PodMatrixStore;\n providerRegistry: ProviderRegistry;\n embeddingService: EmbeddingService;\n vectorService: VectorService;\n\n // Cloud 模式: 身份服务\n ddnsRepo?: DdnsRepository;\n podLookupRepo?: PodLookupRepository;\n\n // 子域名相关 (可选,按 edition 注册)\n // Cloud 模式 或 Local 自管模式\n dnsProvider?: DnsProvider;\n dnsCoordinator?: EdgeNodeDnsCoordinator;\n healthProbeService?: EdgeNodeHealthProbeService;\n capabilityDetector?: EdgeNodeCapabilityDetector;\n localNetworkManager?: LocalNetworkManager;\n\n tunnelProvider?: TunnelProvider;\n subdomainService?: SubdomainService;\n // Local 托管式\n subdomainClient?: SubdomainClient;\n // Local 托管式 DDNS 管理\n ddnsManager?: DdnsManager;\n // Local 托管式/自管式 (启动 cloudflared)\n localTunnelProvider?: TunnelProvider;\n}\n"]}
@@ -0,0 +1,8 @@
1
+ export declare const DEFAULT_AUTH_MODE: "acp";
2
+ export declare const AUTH_MODE_ENV_KEY: "CSS_AUTH_MODE";
3
+ export type AuthMode = 'acp' | 'acl' | 'allow-all';
4
+ export declare function normalizeAuthMode(value: string | null | undefined, fallback?: AuthMode): AuthMode;
5
+ export declare function resolveAuthModeInput(value: AuthMode | string | null | undefined, env?: Record<string, string | undefined>): AuthMode;
6
+ export declare function resolveAuthModeFromEnv(env: Record<string, string | undefined>): AuthMode;
7
+ export declare function applyAuthModeEnv<T extends Record<string, string | undefined>>(env: T, mode: AuthMode): T & Record<typeof AUTH_MODE_ENV_KEY, AuthMode>;
8
+ export declare function isAuthModeEnvKey(key: string): boolean;
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AUTH_MODE_ENV_KEY = exports.DEFAULT_AUTH_MODE = void 0;
4
+ exports.normalizeAuthMode = normalizeAuthMode;
5
+ exports.resolveAuthModeInput = resolveAuthModeInput;
6
+ exports.resolveAuthModeFromEnv = resolveAuthModeFromEnv;
7
+ exports.applyAuthModeEnv = applyAuthModeEnv;
8
+ exports.isAuthModeEnvKey = isAuthModeEnvKey;
9
+ exports.DEFAULT_AUTH_MODE = 'acp';
10
+ exports.AUTH_MODE_ENV_KEY = 'CSS_AUTH_MODE';
11
+ const LEGACY_AUTH_MODE_ENV_KEY = 'XPOD_AUTH_MODE';
12
+ const AUTH_MODE_ALIASES = {
13
+ acp: 'acp',
14
+ acr: 'acp',
15
+ acl: 'acl',
16
+ wac: 'acl',
17
+ webacl: 'acl',
18
+ 'allow-all': 'allow-all',
19
+ allowall: 'allow-all',
20
+ };
21
+ const AUTH_MODE_LABEL = 'acp, acl, allow-all';
22
+ function normalizeAuthMode(value, fallback = exports.DEFAULT_AUTH_MODE) {
23
+ const normalized = value?.trim().toLowerCase();
24
+ if (!normalized) {
25
+ return fallback;
26
+ }
27
+ const mode = AUTH_MODE_ALIASES[normalized];
28
+ if (!mode) {
29
+ throw new Error(`Unsupported auth mode: ${value}. Expected one of: ${AUTH_MODE_LABEL}`);
30
+ }
31
+ return mode;
32
+ }
33
+ function resolveAuthModeInput(value, env = process.env) {
34
+ return normalizeAuthMode(value ?? env[exports.AUTH_MODE_ENV_KEY]);
35
+ }
36
+ function resolveAuthModeFromEnv(env) {
37
+ return resolveAuthModeInput(undefined, env);
38
+ }
39
+ function authModeToEnv(mode) {
40
+ return {
41
+ [exports.AUTH_MODE_ENV_KEY]: mode,
42
+ };
43
+ }
44
+ function applyAuthModeEnv(env, mode) {
45
+ delete env[LEGACY_AUTH_MODE_ENV_KEY];
46
+ return Object.assign(env, authModeToEnv(mode));
47
+ }
48
+ function isAuthModeEnvKey(key) {
49
+ return key === exports.AUTH_MODE_ENV_KEY;
50
+ }
51
+ //# sourceMappingURL=AuthMode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthMode.js","sourceRoot":"","sources":["../../src/authorization/AuthMode.ts"],"names":[],"mappings":";;;AAkBA,8CAWC;AAED,oDAKC;AAED,wDAEC;AAQD,4CAMC;AAED,4CAEC;AA1DY,QAAA,iBAAiB,GAAG,KAAc,CAAC;AACnC,QAAA,iBAAiB,GAAG,eAAwB,CAAC;AAC1D,MAAM,wBAAwB,GAAG,gBAAgB,CAAC;AAIlD,MAAM,iBAAiB,GAA6B;IAClD,GAAG,EAAE,KAAK;IACV,GAAG,EAAE,KAAK;IACV,GAAG,EAAE,KAAK;IACV,GAAG,EAAE,KAAK;IACV,MAAM,EAAE,KAAK;IACb,WAAW,EAAE,WAAW;IACxB,QAAQ,EAAE,WAAW;CACtB,CAAC;AAEF,MAAM,eAAe,GAAG,qBAAqB,CAAC;AAE9C,SAAgB,iBAAiB,CAAC,KAAgC,EAAE,WAAqB,yBAAiB;IACxG,MAAM,UAAU,GAAG,KAAK,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC/C,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,IAAI,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;IAC3C,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,0BAA0B,KAAK,sBAAsB,eAAe,EAAE,CAAC,CAAC;IAC1F,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAgB,oBAAoB,CAClC,KAA2C,EAC3C,MAA0C,OAAO,CAAC,GAAG;IAErD,OAAO,iBAAiB,CAAC,KAAK,IAAI,GAAG,CAAC,yBAAiB,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED,SAAgB,sBAAsB,CAAC,GAAuC;IAC5E,OAAO,oBAAoB,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;AAC9C,CAAC;AAED,SAAS,aAAa,CAAC,IAAc;IACnC,OAAO;QACL,CAAC,yBAAiB,CAAC,EAAE,IAAI;KAC1B,CAAC;AACJ,CAAC;AAED,SAAgB,gBAAgB,CAC9B,GAAM,EACN,IAAc;IAEd,OAAO,GAAG,CAAC,wBAAwB,CAAC,CAAC;IACrC,OAAO,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC;AACjD,CAAC;AAED,SAAgB,gBAAgB,CAAC,GAAW;IAC1C,OAAO,GAAG,KAAK,yBAAiB,CAAC;AACnC,CAAC","sourcesContent":["export const DEFAULT_AUTH_MODE = 'acp' as const;\nexport const AUTH_MODE_ENV_KEY = 'CSS_AUTH_MODE' as const;\nconst LEGACY_AUTH_MODE_ENV_KEY = 'XPOD_AUTH_MODE';\n\nexport type AuthMode = 'acp' | 'acl' | 'allow-all';\n\nconst AUTH_MODE_ALIASES: Record<string, AuthMode> = {\n acp: 'acp',\n acr: 'acp',\n acl: 'acl',\n wac: 'acl',\n webacl: 'acl',\n 'allow-all': 'allow-all',\n allowall: 'allow-all',\n};\n\nconst AUTH_MODE_LABEL = 'acp, acl, allow-all';\n\nexport function normalizeAuthMode(value: string | null | undefined, fallback: AuthMode = DEFAULT_AUTH_MODE): AuthMode {\n const normalized = value?.trim().toLowerCase();\n if (!normalized) {\n return fallback;\n }\n\n const mode = AUTH_MODE_ALIASES[normalized];\n if (!mode) {\n throw new Error(`Unsupported auth mode: ${value}. Expected one of: ${AUTH_MODE_LABEL}`);\n }\n return mode;\n}\n\nexport function resolveAuthModeInput(\n value: AuthMode | string | null | undefined,\n env: Record<string, string | undefined> = process.env,\n): AuthMode {\n return normalizeAuthMode(value ?? env[AUTH_MODE_ENV_KEY]);\n}\n\nexport function resolveAuthModeFromEnv(env: Record<string, string | undefined>): AuthMode {\n return resolveAuthModeInput(undefined, env);\n}\n\nfunction authModeToEnv(mode: AuthMode): Record<typeof AUTH_MODE_ENV_KEY, AuthMode> {\n return {\n [AUTH_MODE_ENV_KEY]: mode,\n };\n}\n\nexport function applyAuthModeEnv<T extends Record<string, string | undefined>>(\n env: T,\n mode: AuthMode,\n): T & Record<typeof AUTH_MODE_ENV_KEY, AuthMode> {\n delete env[LEGACY_AUTH_MODE_ENV_KEY];\n return Object.assign(env, authModeToEnv(mode));\n}\n\nexport function isAuthModeEnvKey(key: string): boolean {\n return key === AUTH_MODE_ENV_KEY;\n}\n"]}
@@ -0,0 +1,18 @@
1
+ import type { Quad } from '@rdfjs/types';
2
+ import type { AuthMode } from './AuthMode';
3
+ export type PodAuthorizationResourceKind = 'acp' | 'acl';
4
+ export interface PodAuthorizationResourceInput {
5
+ authMode: AuthMode | string | undefined;
6
+ podUrl: string;
7
+ cardUrl: string;
8
+ webId: string;
9
+ stableId: (input: string) => string;
10
+ iri: (base: string, relative: string) => string;
11
+ }
12
+ export interface PodAuthorizationResourceOutput {
13
+ kind: PodAuthorizationResourceKind;
14
+ rootResourceUrl: string;
15
+ cardResourceUrl: string;
16
+ quads: Quad[];
17
+ }
18
+ export declare function buildPodAuthorizationResources(input: PodAuthorizationResourceInput): PodAuthorizationResourceOutput;
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildPodAuthorizationResources = buildPodAuthorizationResources;
4
+ const n3_1 = require("n3");
5
+ const AuthMode_1 = require("./AuthMode");
6
+ const RDF = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
7
+ const FOAF = 'http://xmlns.com/foaf/0.1/';
8
+ const ACL = 'http://www.w3.org/ns/auth/acl#';
9
+ const ACP = 'http://www.w3.org/ns/solid/acp#';
10
+ const { blankNode, namedNode, quad } = n3_1.DataFactory;
11
+ function resourceKindForAuthMode(authMode) {
12
+ return authMode === 'acl' ? 'acl' : 'acp';
13
+ }
14
+ function buildPodAuthorizationResources(input) {
15
+ const authMode = (0, AuthMode_1.normalizeAuthMode)(input.authMode);
16
+ const kind = resourceKindForAuthMode(authMode);
17
+ const rootResourceUrl = input.iri(input.podUrl, kind === 'acl' ? '.acl' : '.acr');
18
+ const cardResourceUrl = input.iri(input.podUrl, kind === 'acl' ? 'profile/card.acl' : 'profile/card.acr');
19
+ const quads = kind === 'acl'
20
+ ? buildWebAclQuads(input, rootResourceUrl, cardResourceUrl)
21
+ : buildAcpQuads(input, rootResourceUrl, cardResourceUrl);
22
+ return {
23
+ kind,
24
+ rootResourceUrl,
25
+ cardResourceUrl,
26
+ quads,
27
+ };
28
+ }
29
+ function buildAcpQuads(input, rootAcrUrl, cardAcrUrl) {
30
+ const rootGraph = namedNode(rootAcrUrl);
31
+ const cardGraph = namedNode(cardAcrUrl);
32
+ const root = namedNode(`${rootAcrUrl}#root`);
33
+ const rootPublicRead = namedNode(`${rootAcrUrl}#publicReadAccess`);
34
+ const rootFullOwner = namedNode(`${rootAcrUrl}#fullOwnerAccess`);
35
+ const rootPublicPolicy = blankNode(`public-policy-${input.stableId(rootAcrUrl)}`);
36
+ const rootPublicMatcher = blankNode(`public-matcher-${input.stableId(rootAcrUrl)}`);
37
+ const rootOwnerPolicy = blankNode(`owner-policy-${input.stableId(rootAcrUrl)}`);
38
+ const rootOwnerMatcher = blankNode(`owner-matcher-${input.stableId(rootAcrUrl)}`);
39
+ const card = namedNode(`${cardAcrUrl}#card`);
40
+ const cardPublicRead = namedNode(`${cardAcrUrl}#publicReadAccess`);
41
+ const cardPolicy = blankNode(`card-policy-${input.stableId(cardAcrUrl)}`);
42
+ const cardMatcher = blankNode(`card-matcher-${input.stableId(cardAcrUrl)}`);
43
+ return [
44
+ quad(root, namedNode(`${RDF}type`), namedNode(`${ACP}AccessControlResource`), rootGraph),
45
+ quad(root, namedNode(`${ACP}resource`), namedNode(input.podUrl), rootGraph),
46
+ quad(root, namedNode(`${ACP}accessControl`), rootPublicRead, rootGraph),
47
+ quad(root, namedNode(`${ACP}accessControl`), rootFullOwner, rootGraph),
48
+ quad(root, namedNode(`${ACP}memberAccessControl`), rootFullOwner, rootGraph),
49
+ quad(rootPublicRead, namedNode(`${RDF}type`), namedNode(`${ACP}AccessControl`), rootGraph),
50
+ quad(rootPublicRead, namedNode(`${ACP}apply`), rootPublicPolicy, rootGraph),
51
+ quad(rootPublicPolicy, namedNode(`${RDF}type`), namedNode(`${ACP}Policy`), rootGraph),
52
+ quad(rootPublicPolicy, namedNode(`${ACP}allow`), namedNode(`${ACL}Read`), rootGraph),
53
+ quad(rootPublicPolicy, namedNode(`${ACP}anyOf`), rootPublicMatcher, rootGraph),
54
+ quad(rootPublicMatcher, namedNode(`${RDF}type`), namedNode(`${ACP}Matcher`), rootGraph),
55
+ quad(rootPublicMatcher, namedNode(`${ACP}agent`), namedNode(`${ACP}PublicAgent`), rootGraph),
56
+ quad(rootFullOwner, namedNode(`${RDF}type`), namedNode(`${ACP}AccessControl`), rootGraph),
57
+ quad(rootFullOwner, namedNode(`${ACP}apply`), rootOwnerPolicy, rootGraph),
58
+ quad(rootOwnerPolicy, namedNode(`${RDF}type`), namedNode(`${ACP}Policy`), rootGraph),
59
+ quad(rootOwnerPolicy, namedNode(`${ACP}allow`), namedNode(`${ACL}Read`), rootGraph),
60
+ quad(rootOwnerPolicy, namedNode(`${ACP}allow`), namedNode(`${ACL}Write`), rootGraph),
61
+ quad(rootOwnerPolicy, namedNode(`${ACP}allow`), namedNode(`${ACL}Control`), rootGraph),
62
+ quad(rootOwnerPolicy, namedNode(`${ACP}anyOf`), rootOwnerMatcher, rootGraph),
63
+ quad(rootOwnerMatcher, namedNode(`${RDF}type`), namedNode(`${ACP}Matcher`), rootGraph),
64
+ quad(rootOwnerMatcher, namedNode(`${ACP}agent`), namedNode(input.webId), rootGraph),
65
+ quad(card, namedNode(`${RDF}type`), namedNode(`${ACP}AccessControlResource`), cardGraph),
66
+ quad(card, namedNode(`${ACP}resource`), namedNode(input.cardUrl), cardGraph),
67
+ quad(card, namedNode(`${ACP}accessControl`), cardPublicRead, cardGraph),
68
+ quad(cardPublicRead, namedNode(`${RDF}type`), namedNode(`${ACP}AccessControl`), cardGraph),
69
+ quad(cardPublicRead, namedNode(`${ACP}apply`), cardPolicy, cardGraph),
70
+ quad(cardPolicy, namedNode(`${RDF}type`), namedNode(`${ACP}Policy`), cardGraph),
71
+ quad(cardPolicy, namedNode(`${ACP}allow`), namedNode(`${ACL}Read`), cardGraph),
72
+ quad(cardPolicy, namedNode(`${ACP}anyOf`), cardMatcher, cardGraph),
73
+ quad(cardMatcher, namedNode(`${RDF}type`), namedNode(`${ACP}Matcher`), cardGraph),
74
+ quad(cardMatcher, namedNode(`${ACP}agent`), namedNode(`${ACP}PublicAgent`), cardGraph),
75
+ ];
76
+ }
77
+ function buildWebAclQuads(input, rootAclUrl, cardAclUrl) {
78
+ const rootGraph = namedNode(rootAclUrl);
79
+ const cardGraph = namedNode(cardAclUrl);
80
+ const rootPublic = namedNode(`${rootAclUrl}#public`);
81
+ const rootOwner = namedNode(`${rootAclUrl}#owner`);
82
+ const cardPublic = namedNode(`${cardAclUrl}#public`);
83
+ const cardOwner = namedNode(`${cardAclUrl}#owner`);
84
+ return [
85
+ quad(rootPublic, namedNode(`${RDF}type`), namedNode(`${ACL}Authorization`), rootGraph),
86
+ quad(rootPublic, namedNode(`${ACL}agentClass`), namedNode(`${FOAF}Agent`), rootGraph),
87
+ quad(rootPublic, namedNode(`${ACL}accessTo`), namedNode(input.podUrl), rootGraph),
88
+ quad(rootPublic, namedNode(`${ACL}mode`), namedNode(`${ACL}Read`), rootGraph),
89
+ quad(rootOwner, namedNode(`${RDF}type`), namedNode(`${ACL}Authorization`), rootGraph),
90
+ quad(rootOwner, namedNode(`${ACL}agent`), namedNode(input.webId), rootGraph),
91
+ quad(rootOwner, namedNode(`${ACL}accessTo`), namedNode(input.podUrl), rootGraph),
92
+ quad(rootOwner, namedNode(`${ACL}default`), namedNode(input.podUrl), rootGraph),
93
+ quad(rootOwner, namedNode(`${ACL}mode`), namedNode(`${ACL}Read`), rootGraph),
94
+ quad(rootOwner, namedNode(`${ACL}mode`), namedNode(`${ACL}Write`), rootGraph),
95
+ quad(rootOwner, namedNode(`${ACL}mode`), namedNode(`${ACL}Control`), rootGraph),
96
+ quad(cardPublic, namedNode(`${RDF}type`), namedNode(`${ACL}Authorization`), cardGraph),
97
+ quad(cardPublic, namedNode(`${ACL}agentClass`), namedNode(`${FOAF}Agent`), cardGraph),
98
+ quad(cardPublic, namedNode(`${ACL}accessTo`), namedNode(input.cardUrl), cardGraph),
99
+ quad(cardPublic, namedNode(`${ACL}mode`), namedNode(`${ACL}Read`), cardGraph),
100
+ quad(cardOwner, namedNode(`${RDF}type`), namedNode(`${ACL}Authorization`), cardGraph),
101
+ quad(cardOwner, namedNode(`${ACL}agent`), namedNode(input.webId), cardGraph),
102
+ quad(cardOwner, namedNode(`${ACL}accessTo`), namedNode(input.cardUrl), cardGraph),
103
+ quad(cardOwner, namedNode(`${ACL}mode`), namedNode(`${ACL}Read`), cardGraph),
104
+ quad(cardOwner, namedNode(`${ACL}mode`), namedNode(`${ACL}Write`), cardGraph),
105
+ quad(cardOwner, namedNode(`${ACL}mode`), namedNode(`${ACL}Control`), cardGraph),
106
+ ];
107
+ }
108
+ //# sourceMappingURL=PodAuthorizationResources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PodAuthorizationResources.js","sourceRoot":"","sources":["../../src/authorization/PodAuthorizationResources.ts"],"names":[],"mappings":"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","sourcesContent":["import { DataFactory } from 'n3';\nimport type { Quad } from '@rdfjs/types';\nimport type { AuthMode } from './AuthMode';\nimport { normalizeAuthMode } from './AuthMode';\n\nconst RDF = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';\nconst FOAF = 'http://xmlns.com/foaf/0.1/';\nconst ACL = 'http://www.w3.org/ns/auth/acl#';\nconst ACP = 'http://www.w3.org/ns/solid/acp#';\n\nconst { blankNode, namedNode, quad } = DataFactory;\n\nexport type PodAuthorizationResourceKind = 'acp' | 'acl';\n\nexport interface PodAuthorizationResourceInput {\n authMode: AuthMode | string | undefined;\n podUrl: string;\n cardUrl: string;\n webId: string;\n stableId: (input: string) => string;\n iri: (base: string, relative: string) => string;\n}\n\nexport interface PodAuthorizationResourceOutput {\n kind: PodAuthorizationResourceKind;\n rootResourceUrl: string;\n cardResourceUrl: string;\n quads: Quad[];\n}\n\nfunction resourceKindForAuthMode(authMode: AuthMode): PodAuthorizationResourceKind {\n return authMode === 'acl' ? 'acl' : 'acp';\n}\n\nexport function buildPodAuthorizationResources(input: PodAuthorizationResourceInput): PodAuthorizationResourceOutput {\n const authMode = normalizeAuthMode(input.authMode);\n const kind = resourceKindForAuthMode(authMode);\n const rootResourceUrl = input.iri(input.podUrl, kind === 'acl' ? '.acl' : '.acr');\n const cardResourceUrl = input.iri(input.podUrl, kind === 'acl' ? 'profile/card.acl' : 'profile/card.acr');\n const quads = kind === 'acl'\n ? buildWebAclQuads(input, rootResourceUrl, cardResourceUrl)\n : buildAcpQuads(input, rootResourceUrl, cardResourceUrl);\n\n return {\n kind,\n rootResourceUrl,\n cardResourceUrl,\n quads,\n };\n}\n\nfunction buildAcpQuads(input: PodAuthorizationResourceInput, rootAcrUrl: string, cardAcrUrl: string): Quad[] {\n const rootGraph = namedNode(rootAcrUrl);\n const cardGraph = namedNode(cardAcrUrl);\n const root = namedNode(`${rootAcrUrl}#root`);\n const rootPublicRead = namedNode(`${rootAcrUrl}#publicReadAccess`);\n const rootFullOwner = namedNode(`${rootAcrUrl}#fullOwnerAccess`);\n const rootPublicPolicy = blankNode(`public-policy-${input.stableId(rootAcrUrl)}`);\n const rootPublicMatcher = blankNode(`public-matcher-${input.stableId(rootAcrUrl)}`);\n const rootOwnerPolicy = blankNode(`owner-policy-${input.stableId(rootAcrUrl)}`);\n const rootOwnerMatcher = blankNode(`owner-matcher-${input.stableId(rootAcrUrl)}`);\n const card = namedNode(`${cardAcrUrl}#card`);\n const cardPublicRead = namedNode(`${cardAcrUrl}#publicReadAccess`);\n const cardPolicy = blankNode(`card-policy-${input.stableId(cardAcrUrl)}`);\n const cardMatcher = blankNode(`card-matcher-${input.stableId(cardAcrUrl)}`);\n\n return [\n quad(root, namedNode(`${RDF}type`), namedNode(`${ACP}AccessControlResource`), rootGraph),\n quad(root, namedNode(`${ACP}resource`), namedNode(input.podUrl), rootGraph),\n quad(root, namedNode(`${ACP}accessControl`), rootPublicRead, rootGraph),\n quad(root, namedNode(`${ACP}accessControl`), rootFullOwner, rootGraph),\n quad(root, namedNode(`${ACP}memberAccessControl`), rootFullOwner, rootGraph),\n quad(rootPublicRead, namedNode(`${RDF}type`), namedNode(`${ACP}AccessControl`), rootGraph),\n quad(rootPublicRead, namedNode(`${ACP}apply`), rootPublicPolicy, rootGraph),\n quad(rootPublicPolicy, namedNode(`${RDF}type`), namedNode(`${ACP}Policy`), rootGraph),\n quad(rootPublicPolicy, namedNode(`${ACP}allow`), namedNode(`${ACL}Read`), rootGraph),\n quad(rootPublicPolicy, namedNode(`${ACP}anyOf`), rootPublicMatcher, rootGraph),\n quad(rootPublicMatcher, namedNode(`${RDF}type`), namedNode(`${ACP}Matcher`), rootGraph),\n quad(rootPublicMatcher, namedNode(`${ACP}agent`), namedNode(`${ACP}PublicAgent`), rootGraph),\n quad(rootFullOwner, namedNode(`${RDF}type`), namedNode(`${ACP}AccessControl`), rootGraph),\n quad(rootFullOwner, namedNode(`${ACP}apply`), rootOwnerPolicy, rootGraph),\n quad(rootOwnerPolicy, namedNode(`${RDF}type`), namedNode(`${ACP}Policy`), rootGraph),\n quad(rootOwnerPolicy, namedNode(`${ACP}allow`), namedNode(`${ACL}Read`), rootGraph),\n quad(rootOwnerPolicy, namedNode(`${ACP}allow`), namedNode(`${ACL}Write`), rootGraph),\n quad(rootOwnerPolicy, namedNode(`${ACP}allow`), namedNode(`${ACL}Control`), rootGraph),\n quad(rootOwnerPolicy, namedNode(`${ACP}anyOf`), rootOwnerMatcher, rootGraph),\n quad(rootOwnerMatcher, namedNode(`${RDF}type`), namedNode(`${ACP}Matcher`), rootGraph),\n quad(rootOwnerMatcher, namedNode(`${ACP}agent`), namedNode(input.webId), rootGraph),\n\n quad(card, namedNode(`${RDF}type`), namedNode(`${ACP}AccessControlResource`), cardGraph),\n quad(card, namedNode(`${ACP}resource`), namedNode(input.cardUrl), cardGraph),\n quad(card, namedNode(`${ACP}accessControl`), cardPublicRead, cardGraph),\n quad(cardPublicRead, namedNode(`${RDF}type`), namedNode(`${ACP}AccessControl`), cardGraph),\n quad(cardPublicRead, namedNode(`${ACP}apply`), cardPolicy, cardGraph),\n quad(cardPolicy, namedNode(`${RDF}type`), namedNode(`${ACP}Policy`), cardGraph),\n quad(cardPolicy, namedNode(`${ACP}allow`), namedNode(`${ACL}Read`), cardGraph),\n quad(cardPolicy, namedNode(`${ACP}anyOf`), cardMatcher, cardGraph),\n quad(cardMatcher, namedNode(`${RDF}type`), namedNode(`${ACP}Matcher`), cardGraph),\n quad(cardMatcher, namedNode(`${ACP}agent`), namedNode(`${ACP}PublicAgent`), cardGraph),\n ];\n}\n\nfunction buildWebAclQuads(input: PodAuthorizationResourceInput, rootAclUrl: string, cardAclUrl: string): Quad[] {\n const rootGraph = namedNode(rootAclUrl);\n const cardGraph = namedNode(cardAclUrl);\n const rootPublic = namedNode(`${rootAclUrl}#public`);\n const rootOwner = namedNode(`${rootAclUrl}#owner`);\n const cardPublic = namedNode(`${cardAclUrl}#public`);\n const cardOwner = namedNode(`${cardAclUrl}#owner`);\n\n return [\n quad(rootPublic, namedNode(`${RDF}type`), namedNode(`${ACL}Authorization`), rootGraph),\n quad(rootPublic, namedNode(`${ACL}agentClass`), namedNode(`${FOAF}Agent`), rootGraph),\n quad(rootPublic, namedNode(`${ACL}accessTo`), namedNode(input.podUrl), rootGraph),\n quad(rootPublic, namedNode(`${ACL}mode`), namedNode(`${ACL}Read`), rootGraph),\n quad(rootOwner, namedNode(`${RDF}type`), namedNode(`${ACL}Authorization`), rootGraph),\n quad(rootOwner, namedNode(`${ACL}agent`), namedNode(input.webId), rootGraph),\n quad(rootOwner, namedNode(`${ACL}accessTo`), namedNode(input.podUrl), rootGraph),\n quad(rootOwner, namedNode(`${ACL}default`), namedNode(input.podUrl), rootGraph),\n quad(rootOwner, namedNode(`${ACL}mode`), namedNode(`${ACL}Read`), rootGraph),\n quad(rootOwner, namedNode(`${ACL}mode`), namedNode(`${ACL}Write`), rootGraph),\n quad(rootOwner, namedNode(`${ACL}mode`), namedNode(`${ACL}Control`), rootGraph),\n\n quad(cardPublic, namedNode(`${RDF}type`), namedNode(`${ACL}Authorization`), cardGraph),\n quad(cardPublic, namedNode(`${ACL}agentClass`), namedNode(`${FOAF}Agent`), cardGraph),\n quad(cardPublic, namedNode(`${ACL}accessTo`), namedNode(input.cardUrl), cardGraph),\n quad(cardPublic, namedNode(`${ACL}mode`), namedNode(`${ACL}Read`), cardGraph),\n quad(cardOwner, namedNode(`${RDF}type`), namedNode(`${ACL}Authorization`), cardGraph),\n quad(cardOwner, namedNode(`${ACL}agent`), namedNode(input.webId), cardGraph),\n quad(cardOwner, namedNode(`${ACL}accessTo`), namedNode(input.cardUrl), cardGraph),\n quad(cardOwner, namedNode(`${ACL}mode`), namedNode(`${ACL}Read`), cardGraph),\n quad(cardOwner, namedNode(`${ACL}mode`), namedNode(`${ACL}Write`), cardGraph),\n quad(cardOwner, namedNode(`${ACL}mode`), namedNode(`${ACL}Control`), cardGraph),\n ];\n}\n"]}