@undefineds.co/xpod 0.3.31 → 0.3.33

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 (218) hide show
  1. package/dist/api/auth/AuthContext.d.ts +3 -2
  2. package/dist/api/auth/AuthContext.js +2 -1
  3. package/dist/api/auth/AuthContext.js.map +1 -1
  4. package/dist/api/auth/ClientCredentialsAuthenticator.d.ts +2 -12
  5. package/dist/api/auth/ClientCredentialsAuthenticator.js +4 -4
  6. package/dist/api/auth/ClientCredentialsAuthenticator.js.map +1 -1
  7. package/dist/api/auth/ServiceTokenAuthenticator.d.ts +2 -2
  8. package/dist/api/auth/ServiceTokenAuthenticator.js.map +1 -1
  9. package/dist/api/chatkit/pod-store.d.ts +3 -0
  10. package/dist/api/chatkit/pod-store.js +93 -59
  11. package/dist/api/chatkit/pod-store.js.map +1 -1
  12. package/dist/api/chatkit/schema.d.ts +5 -6
  13. package/dist/api/container/business-token.d.ts +1 -1
  14. package/dist/api/container/business-token.js +5 -1
  15. package/dist/api/container/business-token.js.map +1 -1
  16. package/dist/api/container/common.js +14 -10
  17. package/dist/api/container/common.js.map +1 -1
  18. package/dist/api/container/routes.js +16 -3
  19. package/dist/api/container/routes.js.map +1 -1
  20. package/dist/api/container/types.d.ts +2 -4
  21. package/dist/api/container/types.js.map +1 -1
  22. package/dist/api/handlers/ChatHandler.d.ts +1 -1
  23. package/dist/api/handlers/ChatHandler.js +1 -1
  24. package/dist/api/handlers/ChatHandler.js.map +1 -1
  25. package/dist/api/handlers/EdgeNodeSignalHandler.js +3 -1
  26. package/dist/api/handlers/EdgeNodeSignalHandler.js.map +1 -1
  27. package/dist/api/handlers/PodManagementHandler.d.ts +2 -0
  28. package/dist/api/handlers/PodManagementHandler.js +114 -12
  29. package/dist/api/handlers/PodManagementHandler.js.map +1 -1
  30. package/dist/api/handlers/ProvisionHandler.d.ts +27 -0
  31. package/dist/api/handlers/ProvisionHandler.js +339 -32
  32. package/dist/api/handlers/ProvisionHandler.js.map +1 -1
  33. package/dist/api/handlers/QuotaHandler.js +0 -12
  34. package/dist/api/handlers/QuotaHandler.js.map +1 -1
  35. package/dist/api/handlers/index.d.ts +0 -1
  36. package/dist/api/handlers/index.js +0 -1
  37. package/dist/api/handlers/index.js.map +1 -1
  38. package/dist/api/matrix/PodMatrixStore.js +26 -21
  39. package/dist/api/matrix/PodMatrixStore.js.map +1 -1
  40. package/dist/api/runs/InngestRunExecutionBackend.d.ts +2 -2
  41. package/dist/api/runs/schema.d.ts +5 -7
  42. package/dist/api/runs/store.js +6 -4
  43. package/dist/api/runs/store.js.map +1 -1
  44. package/dist/api/runtime.js +3 -3
  45. package/dist/api/runtime.js.map +1 -1
  46. package/dist/api/tasks/InngestTaskScheduler.d.ts +4 -4
  47. package/dist/api/tasks/schema.d.ts +17 -13
  48. package/dist/api/tasks/schema.js +7 -2
  49. package/dist/api/tasks/schema.js.map +1 -1
  50. package/dist/api/tasks/store.js +1 -2
  51. package/dist/api/tasks/store.js.map +1 -1
  52. package/dist/components/context.jsonld +12 -0
  53. package/dist/edge/EdgeNodeAgent.d.ts +1 -1
  54. package/dist/edge/EdgeNodeAgent.js +1 -1
  55. package/dist/edge/EdgeNodeAgent.js.map +1 -1
  56. package/dist/edge/EdgeNodeDnsCoordinator.d.ts +1 -0
  57. package/dist/edge/EdgeNodeDnsCoordinator.js +9 -3
  58. package/dist/edge/EdgeNodeDnsCoordinator.js.map +1 -1
  59. package/dist/edge/EdgeNodeDnsCoordinator.jsonld +4 -0
  60. package/dist/edge/EdgeNodeHealthProbeService.d.ts +3 -0
  61. package/dist/edge/EdgeNodeHealthProbeService.js +22 -2
  62. package/dist/edge/EdgeNodeHealthProbeService.js.map +1 -1
  63. package/dist/edge/EdgeNodeHealthProbeService.jsonld +12 -0
  64. package/dist/http/ClusterIngressRouter.js +6 -3
  65. package/dist/http/ClusterIngressRouter.js.map +1 -1
  66. package/dist/http/ClusterWebSocketConfigurator.js +6 -2
  67. package/dist/http/ClusterWebSocketConfigurator.js.map +1 -1
  68. package/dist/http/EdgeNodeDirectDebugHttpHandler.d.ts +2 -0
  69. package/dist/http/EdgeNodeDirectDebugHttpHandler.js +18 -3
  70. package/dist/http/EdgeNodeDirectDebugHttpHandler.js.map +1 -1
  71. package/dist/http/EdgeNodeDirectDebugHttpHandler.jsonld +8 -0
  72. package/dist/http/EdgeNodeProxyHttpHandler.js +6 -2
  73. package/dist/http/EdgeNodeProxyHttpHandler.js.map +1 -1
  74. package/dist/http/cluster/PodMigrationHttpHandler.d.ts +2 -2
  75. package/dist/http/cluster/PodMigrationHttpHandler.js +2 -2
  76. package/dist/http/cluster/PodMigrationHttpHandler.js.map +1 -1
  77. package/dist/http/quota/QuotaAdminHttpHandler.js +27 -21
  78. package/dist/http/quota/QuotaAdminHttpHandler.js.map +1 -1
  79. package/dist/http/search/SearchHttpHandler.js +2 -2
  80. package/dist/http/search/SearchHttpHandler.js.map +1 -1
  81. package/dist/identity/drizzle/AccountRepository.d.ts +4 -22
  82. package/dist/identity/drizzle/AccountRepository.js +9 -113
  83. package/dist/identity/drizzle/AccountRepository.js.map +1 -1
  84. package/dist/identity/drizzle/AccountRoleRepository.d.ts +5 -5
  85. package/dist/identity/drizzle/AccountRoleRepository.js +204 -97
  86. package/dist/identity/drizzle/AccountRoleRepository.js.map +1 -1
  87. package/dist/identity/drizzle/DdnsRepository.d.ts +5 -20
  88. package/dist/identity/drizzle/DdnsRepository.js +13 -49
  89. package/dist/identity/drizzle/DdnsRepository.js.map +1 -1
  90. package/dist/identity/drizzle/EdgeNodeRepository.d.ts +13 -6
  91. package/dist/identity/drizzle/EdgeNodeRepository.js +167 -66
  92. package/dist/identity/drizzle/EdgeNodeRepository.js.map +1 -1
  93. package/dist/identity/drizzle/PodLookupRepository.d.ts +7 -36
  94. package/dist/identity/drizzle/PodLookupRepository.js +103 -126
  95. package/dist/identity/drizzle/PodLookupRepository.js.map +1 -1
  96. package/dist/identity/drizzle/ServiceTokenRepository.d.ts +13 -1
  97. package/dist/identity/drizzle/ServiceTokenRepository.js +7 -0
  98. package/dist/identity/drizzle/ServiceTokenRepository.js.map +1 -1
  99. package/dist/identity/drizzle/db.d.ts +2 -1
  100. package/dist/identity/drizzle/db.js +173 -297
  101. package/dist/identity/drizzle/db.js.map +1 -1
  102. package/dist/identity/drizzle/schema.pg.d.ts +3 -11
  103. package/dist/identity/drizzle/schema.pg.js +10 -45
  104. package/dist/identity/drizzle/schema.pg.js.map +1 -1
  105. package/dist/identity/drizzle/schema.sqlite.d.ts +88 -531
  106. package/dist/identity/drizzle/schema.sqlite.js +13 -46
  107. package/dist/identity/drizzle/schema.sqlite.js.map +1 -1
  108. package/dist/identity/oidc/ScopedPickWebIdHandler.d.ts +3 -0
  109. package/dist/identity/oidc/ScopedPickWebIdHandler.js +18 -6
  110. package/dist/identity/oidc/ScopedPickWebIdHandler.js.map +1 -1
  111. package/dist/identity/oidc/ScopedPickWebIdHandler.jsonld +22 -0
  112. package/dist/provision/ProvisionCodeCodec.js +10 -1
  113. package/dist/provision/ProvisionCodeCodec.js.map +1 -1
  114. package/dist/provision/ProvisionPodCreator.d.ts +8 -2
  115. package/dist/provision/ProvisionPodCreator.js +134 -41
  116. package/dist/provision/ProvisionPodCreator.js.map +1 -1
  117. package/dist/provision/ProvisionPodCreator.jsonld +38 -3
  118. package/dist/quota/DrizzleQuotaService.d.ts +0 -4
  119. package/dist/quota/DrizzleQuotaService.js +1 -21
  120. package/dist/quota/DrizzleQuotaService.js.map +1 -1
  121. package/dist/quota/DrizzleQuotaService.jsonld +0 -16
  122. package/dist/quota/NoopQuotaService.d.ts +0 -4
  123. package/dist/quota/NoopQuotaService.js +0 -8
  124. package/dist/quota/NoopQuotaService.js.map +1 -1
  125. package/dist/quota/NoopQuotaService.jsonld +0 -16
  126. package/dist/quota/QuotaService.d.ts +0 -4
  127. package/dist/quota/QuotaService.js.map +1 -1
  128. package/dist/quota/QuotaService.jsonld +0 -16
  129. package/dist/service/EdgeNodeSignalClient.d.ts +0 -2
  130. package/dist/service/EdgeNodeSignalClient.js +0 -4
  131. package/dist/service/EdgeNodeSignalClient.js.map +1 -1
  132. package/dist/service/PodMigrationService.d.ts +2 -2
  133. package/dist/service/PodMigrationService.js +4 -4
  134. package/dist/service/PodMigrationService.js.map +1 -1
  135. package/dist/setup/LocalSetupServiceTokenRepository.d.ts +22 -0
  136. package/dist/setup/LocalSetupServiceTokenRepository.js +68 -0
  137. package/dist/setup/LocalSetupServiceTokenRepository.js.map +1 -0
  138. package/dist/storage/quota/PerAccountQuotaStrategy.js +2 -2
  139. package/dist/storage/quota/PerAccountQuotaStrategy.js.map +1 -1
  140. package/dist/storage/quota/UsageRepository.d.ts +10 -32
  141. package/dist/storage/quota/UsageRepository.js +84 -281
  142. package/dist/storage/quota/UsageRepository.js.map +1 -1
  143. package/dist/storage/vector/VectorIndexingListener.js +2 -2
  144. package/dist/storage/vector/VectorIndexingListener.js.map +1 -1
  145. package/dist/subdomain/SubdomainService.d.ts +1 -1
  146. package/dist/subdomain/SubdomainService.js +1 -1
  147. package/dist/subdomain/SubdomainService.js.map +1 -1
  148. package/dist/subdomain/SubdomainService.jsonld +1 -1
  149. package/node_modules/@undefineds.co/drizzle-solid/dist/core/exact-records.d.ts +21 -0
  150. package/node_modules/@undefineds.co/drizzle-solid/dist/core/exact-records.d.ts.map +1 -0
  151. package/node_modules/@undefineds.co/drizzle-solid/dist/core/exact-records.js +85 -0
  152. package/node_modules/@undefineds.co/drizzle-solid/dist/core/exact-records.js.map +1 -0
  153. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/default-id-template.d.ts +10 -0
  154. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/default-id-template.d.ts.map +1 -0
  155. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/default-id-template.js +365 -0
  156. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/default-id-template.js.map +1 -0
  157. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/index.d.ts +1 -0
  158. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/index.d.ts.map +1 -1
  159. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/index.js +3 -1
  160. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/index.js.map +1 -1
  161. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/insert-query-builder.d.ts.map +1 -1
  162. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/insert-query-builder.js +5 -1
  163. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/insert-query-builder.js.map +1 -1
  164. package/node_modules/@undefineds.co/drizzle-solid/dist/core/repository.d.ts +2 -0
  165. package/node_modules/@undefineds.co/drizzle-solid/dist/core/repository.d.ts.map +1 -1
  166. package/node_modules/@undefineds.co/drizzle-solid/dist/core/repository.js +2 -1
  167. package/node_modules/@undefineds.co/drizzle-solid/dist/core/repository.js.map +1 -1
  168. package/node_modules/@undefineds.co/drizzle-solid/dist/core/resource-reference.d.ts +18 -0
  169. package/node_modules/@undefineds.co/drizzle-solid/dist/core/resource-reference.d.ts.map +1 -1
  170. package/node_modules/@undefineds.co/drizzle-solid/dist/core/resource-reference.js +234 -10
  171. package/node_modules/@undefineds.co/drizzle-solid/dist/core/resource-reference.js.map +1 -1
  172. package/node_modules/@undefineds.co/drizzle-solid/dist/core/schema/pod-table.d.ts +13 -0
  173. package/node_modules/@undefineds.co/drizzle-solid/dist/core/schema/pod-table.d.ts.map +1 -1
  174. package/node_modules/@undefineds.co/drizzle-solid/dist/core/schema/pod-table.js +19 -0
  175. package/node_modules/@undefineds.co/drizzle-solid/dist/core/schema/pod-table.js.map +1 -1
  176. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/exact-records.d.ts +21 -0
  177. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/exact-records.d.ts.map +1 -0
  178. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/exact-records.js +78 -0
  179. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/exact-records.js.map +1 -0
  180. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/default-id-template.d.ts +10 -0
  181. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/default-id-template.d.ts.map +1 -0
  182. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/default-id-template.js +362 -0
  183. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/default-id-template.js.map +1 -0
  184. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/index.d.ts +1 -0
  185. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/index.d.ts.map +1 -1
  186. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/index.js +1 -0
  187. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/index.js.map +1 -1
  188. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/insert-query-builder.d.ts.map +1 -1
  189. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/insert-query-builder.js +5 -1
  190. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/insert-query-builder.js.map +1 -1
  191. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/repository.d.ts +2 -0
  192. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/repository.d.ts.map +1 -1
  193. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/repository.js +1 -0
  194. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/repository.js.map +1 -1
  195. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/resource-reference.d.ts +18 -0
  196. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/resource-reference.d.ts.map +1 -1
  197. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/resource-reference.js +225 -10
  198. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/resource-reference.js.map +1 -1
  199. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/schema/pod-table.d.ts +13 -0
  200. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/schema/pod-table.d.ts.map +1 -1
  201. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/schema/pod-table.js +19 -0
  202. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/schema/pod-table.js.map +1 -1
  203. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/index.d.ts +5 -4
  204. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/index.d.ts.map +1 -1
  205. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/index.js +4 -3
  206. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/index.js.map +1 -1
  207. package/node_modules/@undefineds.co/drizzle-solid/dist/index.d.ts +5 -4
  208. package/node_modules/@undefineds.co/drizzle-solid/dist/index.d.ts.map +1 -1
  209. package/node_modules/@undefineds.co/drizzle-solid/dist/index.js +20 -3
  210. package/node_modules/@undefineds.co/drizzle-solid/dist/index.js.map +1 -1
  211. package/node_modules/@undefineds.co/drizzle-solid/package.json +1 -1
  212. package/package.json +3 -3
  213. package/dist/api/handlers/ApiKeyHandler.d.ts +0 -15
  214. package/dist/api/handlers/ApiKeyHandler.js +0 -153
  215. package/dist/api/handlers/ApiKeyHandler.js.map +0 -1
  216. package/dist/api/store/DrizzleClientCredentialsStore.d.ts +0 -51
  217. package/dist/api/store/DrizzleClientCredentialsStore.js +0 -115
  218. package/dist/api/store/DrizzleClientCredentialsStore.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"PodLookupRepository.js","sourceRoot":"","sources":["../../../src/identity/drizzle/PodLookupRepository.ts"],"names":[],"mappings":"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","sourcesContent":["import { sql } from 'drizzle-orm';\nimport { type IdentityDatabase, executeQuery, executeStatement } from './db';\n\nexport interface PodLookupResult {\n podId: string;\n accountId: string;\n baseUrl: string;\n storageUrl?: string;\n webId?: string;\n webIds?: string[];\n nodeId?: string;\n edgeNodeId?: string;\n}\n\nexport interface PodMigrationStatus {\n podId: string;\n nodeId?: string;\n migrationStatus?: 'syncing' | 'done' | null;\n migrationTargetNode?: string;\n migrationProgress?: number;\n}\n\ninterface InternalKvRow {\n key?: string;\n value?: string;\n id?: string;\n account_id?: string;\n base_url?: string;\n storage_url?: string;\n node_id?: string;\n edge_node_id?: string;\n}\n\ninterface PodUsageRow {\n pod_id?: string;\n storage_url?: string | null;\n}\n\n/**\n * Repository for Pod lookup operations.\n *\n * Reads Pod data from CSS's internal_kv table where account data is stored.\n * CSS stores account data at key \"accounts/data/{accountId}\" with Pod info\n * nested in the \"**pod**\" field.\n */\nexport class PodLookupRepository {\n private readonly kvTableName: string;\n private readonly indexedStoreTableName: string;\n private readonly usageTableName: string;\n\n public constructor(\n private readonly db: IdentityDatabase,\n kvTableName?: string,\n ) {\n this.kvTableName = kvTableName ?? 'internal_kv';\n this.indexedStoreTableName = 'identity_store';\n this.usageTableName = 'identity_pod_usage';\n }\n\n /**\n * Find Pod by resource path (matches longest canonical storage/base URL prefix).\n */\n public async findByResourceIdentifier(resourcePath: string): Promise<PodLookupResult | undefined> {\n const pods = await this.getAllPods();\n\n let bestMatch: PodLookupResult | undefined;\n let bestLength = 0;\n\n for (const pod of pods) {\n const candidateBase = pod.storageUrl ?? pod.baseUrl;\n if (resourcePath.startsWith(candidateBase) && candidateBase.length > bestLength) {\n bestMatch = pod;\n bestLength = candidateBase.length;\n }\n }\n\n return bestMatch;\n }\n\n /**\n * Get Pod by ID.\n */\n public async findById(podId: string): Promise<PodLookupResult | undefined> {\n const pods = await this.getAllPods();\n return pods.find((p) => p.podId === podId);\n }\n\n /**\n * Find Pod by a linked WebID URL.\n *\n * CSS account data stores WebID links separately from Pod base URLs. This is\n * the precise lookup for IdP/SP split deployments where the WebID path does\n * not have to match the storage base URL.\n */\n public async findByWebId(webId: string): Promise<PodLookupResult | undefined> {\n return (await this.findAllByWebId(webId))[0];\n }\n\n /**\n * Find all Pods linked to a WebID.\n *\n * A Cloud WebID can legitimately back both a Cloud Pod and a Local SP Pod.\n * Callers that are scoped to a storage provider must inspect all candidates\n * instead of accepting the first account record returned by CSS storage.\n */\n public async findAllByWebId(webId: string): Promise<PodLookupResult[]> {\n const normalized = normalizeWebId(webId);\n if (!normalized) {\n return [];\n }\n\n const results: PodLookupResult[] = [];\n const pods = await this.getAllPods();\n for (const pod of pods) {\n const matchedWebId = getPodWebIds(pod).find((candidate) => normalizeWebId(candidate) === normalized);\n if (matchedWebId) {\n results.push({\n ...pod,\n webId: matchedWebId,\n });\n }\n }\n\n if (results.length > 0) {\n return results;\n }\n\n const indexed = await this.findByWebIdIndex(normalized);\n if (!indexed) {\n return [];\n }\n const usage = await this.getUsageByPodId();\n return [{\n ...indexed,\n storageUrl: indexed.storageUrl ?? usage.get(indexed.podId)?.storageUrl,\n }];\n }\n\n /**\n * Find Pods by linked WebID URLs in one scan.\n */\n public async findByWebIds(webIds: string[]): Promise<PodLookupResult[]> {\n const normalizedTargets = new Set(webIds.map(normalizeWebId).filter((value): value is string => Boolean(value)));\n if (normalizedTargets.size === 0) {\n return [];\n }\n\n const results: PodLookupResult[] = [];\n const pods = await this.getAllPods();\n for (const pod of pods) {\n const matchedWebId = getPodWebIds(pod).find((candidate) => {\n const normalized = normalizeWebId(candidate);\n return normalized ? normalizedTargets.has(normalized) : false;\n });\n if (!matchedWebId) {\n continue;\n }\n results.push({\n ...pod,\n webId: matchedWebId,\n });\n }\n if (results.length < normalizedTargets.size) {\n const seen = new Set(results.map((result) => normalizeWebId(result.webId)).filter(Boolean));\n for (const normalized of normalizedTargets) {\n if (seen.has(normalized)) {\n continue;\n }\n const indexed = await this.findByWebIdIndex(normalized);\n if (indexed) {\n const usage = await this.getUsageByPodId();\n results.push({\n ...indexed,\n storageUrl: indexed.storageUrl ?? usage.get(indexed.podId)?.storageUrl,\n });\n }\n }\n }\n return results;\n }\n\n /**\n * List Pods for a specific account.\n */\n public async listByAccountId(accountId: string): Promise<PodLookupResult[]> {\n const pods = await this.getAllPods();\n return pods.filter((pod) => pod.accountId === accountId);\n }\n\n /**\n * Set the canonical storage URL for a Pod in identity_pod_usage.\n */\n public async setStorageUrl(podId: string, accountId: string, storageUrl: string): Promise<void> {\n const tableId = sql.identifier([this.usageTableName]);\n await executeStatement(this.db, sql`\n INSERT INTO ${tableId} (pod_id, account_id, storage_url)\n VALUES (${podId}, ${accountId}, ${storageUrl})\n ON CONFLICT (pod_id) DO UPDATE SET\n account_id = ${accountId},\n storage_url = ${storageUrl}\n `);\n }\n\n /**\n * Get migration status for a Pod from identity_pod_usage table.\n */\n public async getMigrationStatus(podId: string): Promise<PodMigrationStatus | undefined> {\n try {\n const tableId = sql.identifier([this.usageTableName]);\n const result = await executeQuery<{\n pod_id?: string;\n id?: string;\n node_id?: string | null;\n migration_status?: string | null;\n migration_target_node?: string | null;\n migration_progress?: number | null;\n }>(this.db, sql`\n SELECT pod_id, node_id, migration_status, migration_target_node, migration_progress\n FROM ${tableId}\n WHERE pod_id = ${podId}\n LIMIT 1\n `);\n\n if (result.rows.length === 0) {\n return undefined;\n }\n const row = result.rows[0];\n return {\n podId: row.pod_id ?? row.id ?? podId,\n nodeId: row.node_id ?? undefined,\n migrationStatus: row.migration_status as 'syncing' | 'done' | null | undefined,\n migrationTargetNode: row.migration_target_node ?? undefined,\n migrationProgress: row.migration_progress ?? undefined,\n };\n } catch {\n // Table might not exist.\n return undefined;\n }\n }\n\n /**\n * Set the nodeId for a Pod in identity_pod_usage table.\n */\n public async setNodeId(podId: string, nodeId: string): Promise<void> {\n const tableId = sql.identifier([this.usageTableName]);\n await executeStatement(this.db, sql`\n INSERT INTO ${tableId} (pod_id, account_id, node_id)\n VALUES (${podId}, '', ${nodeId})\n ON CONFLICT (pod_id) DO UPDATE SET node_id = ${nodeId}\n `);\n }\n\n /**\n * Update migration status for a Pod in identity_pod_usage table.\n */\n public async setMigrationStatus(\n podId: string,\n status: 'syncing' | 'done' | null,\n targetNode?: string | null,\n progress?: number | null,\n ): Promise<void> {\n const tableId = sql.identifier([this.usageTableName]);\n await executeStatement(this.db, sql`\n INSERT INTO ${tableId} (pod_id, account_id, migration_status, migration_target_node, migration_progress)\n VALUES (${podId}, '', ${status}, ${targetNode ?? null}, ${progress ?? 0})\n ON CONFLICT (pod_id) DO UPDATE SET\n migration_status = ${status},\n migration_target_node = ${targetNode ?? null},\n migration_progress = ${progress ?? 0}\n `);\n }\n\n /**\n * List all pods.\n */\n public async listAllPods(): Promise<PodLookupResult[]> {\n return this.getAllPods();\n }\n\n /**\n * Extract all pods from CSS's internal_kv storage.\n *\n * It keeps backward compatibility with legacy rows that already expose\n * id/account_id/base_url columns (used by some unit tests and older schemas).\n */\n private async getAllPods(): Promise<PodLookupResult[]> {\n const kvTableId = sql.identifier([this.kvTableName]);\n\n const result = await executeQuery<InternalKvRow>(this.db, sql`\n SELECT key, value FROM ${kvTableId}\n WHERE key LIKE 'accounts/data/%'\n OR key LIKE '/.internal/accounts/data/%'\n `);\n const usageByPodId = await this.getUsageByPodId();\n\n const pods: PodLookupResult[] = [];\n\n for (const row of result?.rows ?? []) {\n if (row.id && row.account_id && row.base_url) {\n pods.push({\n podId: String(row.id),\n accountId: String(row.account_id),\n baseUrl: String(row.base_url),\n storageUrl: row.storage_url ? String(row.storage_url) : undefined,\n nodeId: row.node_id ? String(row.node_id) : undefined,\n edgeNodeId: row.edge_node_id ? String(row.edge_node_id) : undefined,\n });\n continue;\n }\n\n if (!row.key || row.value === undefined) {\n continue;\n }\n\n try {\n const accountId = extractAccountIdFromAccountDataKey(row.key);\n if (!accountId) {\n continue;\n }\n const data = unwrapStoredValue(typeof row.value === 'string' ? JSON.parse(row.value) : row.value);\n\n const podMap = (data as any)['**pod**'] || (data as any).pod || {};\n const webIds = extractAccountWebIds(data);\n\n for (const [podId, podData] of Object.entries(podMap)) {\n const pod = podData as Record<string, unknown>;\n if (pod.baseUrl && typeof pod.baseUrl === 'string') {\n const usage = usageByPodId.get(podId);\n const podWebIds = [\n typeof pod.webId === 'string' ? pod.webId : undefined,\n ...extractPodOwnerWebIds(pod),\n ...webIds,\n ].filter((value): value is string => typeof value === 'string');\n pods.push({\n podId,\n accountId,\n baseUrl: pod.baseUrl,\n storageUrl: stringValue(pod.storageUrl) ?? usage?.storageUrl,\n webId: dedupeStrings(podWebIds)[0],\n ...webIdsProperty(podWebIds),\n nodeId: typeof pod.nodeId === 'string' ? pod.nodeId : undefined,\n edgeNodeId: typeof pod.edgeNodeId === 'string' ? pod.edgeNodeId : undefined,\n });\n }\n }\n } catch {\n // Skip malformed entries.\n }\n }\n\n return mergePodLookupResults([\n ...pods,\n ...await this.getPodsFromIndexedStore(),\n ]);\n }\n\n private async getUsageByPodId(): Promise<Map<string, { storageUrl?: string }>> {\n const tableId = sql.identifier([this.usageTableName]);\n try {\n const result = await executeQuery<PodUsageRow>(this.db, sql`\n SELECT pod_id, storage_url FROM ${tableId}\n `);\n const byPodId = new Map<string, { storageUrl?: string }>();\n for (const row of result.rows) {\n if (!row.pod_id) {\n continue;\n }\n byPodId.set(row.pod_id, {\n storageUrl: row.storage_url ?? undefined,\n });\n }\n return byPodId;\n } catch {\n return new Map();\n }\n }\n\n /**\n * Fast path for CSS WrappedIndexedStorage. WebID indexes point to the root\n * account id, so a single indexed key plus account data row can resolve the\n * profile without scanning all account records.\n */\n private async findByWebIdIndex(webId: string): Promise<PodLookupResult | undefined> {\n const accountIds = await this.readStringArrayFromKv(`accounts/index/webIdLink/webId/${encodeURIComponent(webId)}`);\n for (const accountId of accountIds) {\n const account = await this.readAccountData(accountId);\n if (!account) {\n continue;\n }\n const pods = this.extractPodsFromAccountData(accountId, account);\n const match = pods.find((pod) => getPodWebIds(pod).some((candidate) => normalizeWebId(candidate) === webId));\n if (match) {\n return {\n ...match,\n webId,\n };\n }\n if (pods.length === 1) {\n return {\n ...pods[0],\n webId,\n ...webIdsProperty([webId, ...getPodWebIds(pods[0])]),\n };\n }\n }\n return undefined;\n }\n\n private async readAccountData(accountId: string): Promise<Record<string, unknown> | undefined> {\n for (const key of [`accounts/data/${accountId}`, `/.internal/accounts/data/${accountId}`]) {\n const value = await this.readKvValue(key);\n const record = parsePayloadRecord(value);\n if (record) {\n return record;\n }\n }\n return undefined;\n }\n\n private async readStringArrayFromKv(key: string): Promise<string[]> {\n const value = await this.readKvValue(key);\n return Array.isArray(value) ? value.filter((entry): entry is string => typeof entry === 'string') : [];\n }\n\n private async readKvValue(key: string): Promise<unknown> {\n const tableId = sql.identifier([this.kvTableName]);\n try {\n const result = await executeQuery<{ value?: unknown }>(this.db, sql`\n SELECT value FROM ${tableId}\n WHERE key = ${key}\n LIMIT 1\n `);\n if (result.rows.length === 0) {\n return undefined;\n }\n return parseStoredValue(result.rows[0].value);\n } catch {\n return undefined;\n }\n }\n\n private extractPodsFromAccountData(accountId: string, data: Record<string, unknown>): PodLookupResult[] {\n const podMap = (data as any)['**pod**'] || (data as any).pod || {};\n const webIds = extractAccountWebIds(data);\n const pods: PodLookupResult[] = [];\n\n for (const [podId, podData] of Object.entries(podMap)) {\n const pod = podData as Record<string, unknown>;\n if (pod.baseUrl && typeof pod.baseUrl === 'string') {\n const podWebIds = [\n typeof pod.webId === 'string' ? pod.webId : undefined,\n ...extractPodOwnerWebIds(pod),\n ...webIds,\n ].filter((value): value is string => typeof value === 'string');\n pods.push({\n podId,\n accountId,\n baseUrl: pod.baseUrl,\n storageUrl: stringValue(pod.storageUrl),\n webId: dedupeStrings(podWebIds)[0],\n ...webIdsProperty(podWebIds),\n nodeId: typeof pod.nodeId === 'string' ? pod.nodeId : undefined,\n edgeNodeId: typeof pod.edgeNodeId === 'string' ? pod.edgeNodeId : undefined,\n });\n }\n }\n\n return pods;\n }\n\n /**\n * Older Xpod/CSS deployments may have used the IndexedStorage-compatible\n * identity_store table instead of CSS's WrappedIndexedStorage JSON tree in\n * internal_kv. Keep this as a read-only compatibility source so hosted WebID\n * profile lookup still works after storage implementation changes.\n */\n private async getPodsFromIndexedStore(): Promise<PodLookupResult[]> {\n const storeTableId = sql.identifier([this.indexedStoreTableName]);\n let result: { rows?: Array<{ container?: string; id?: string; payload?: unknown }> } | undefined;\n try {\n result = await executeQuery(this.db, sql`\n SELECT container, id, payload FROM ${storeTableId}\n WHERE container IN ('pod', 'owner', 'webIdLink')\n `);\n } catch {\n return [];\n }\n\n const podPayloads = new Map<string, Record<string, unknown>>();\n const ownerWebIdsByPodId = new Map<string, string[]>();\n const webIdsByAccountId = new Map<string, string[]>();\n\n for (const row of result?.rows ?? []) {\n if (!row.id || !row.container) {\n continue;\n }\n const payload = parsePayloadRecord(row.payload);\n if (!payload) {\n continue;\n }\n\n if (row.container === 'pod') {\n podPayloads.set(row.id, payload);\n continue;\n }\n\n if (row.container === 'owner') {\n const podId = stringValue(payload.podId);\n const webId = stringValue(payload.webId);\n if (podId && webId) {\n appendMapValue(ownerWebIdsByPodId, podId, webId);\n }\n continue;\n }\n\n if (row.container === 'webIdLink') {\n const accountId = stringValue(payload.accountId);\n const webId = stringValue(payload.webId);\n if (accountId && webId) {\n appendMapValue(webIdsByAccountId, accountId, webId);\n }\n }\n }\n\n const pods: PodLookupResult[] = [];\n for (const [podId, pod] of podPayloads) {\n const baseUrl = stringValue(pod.baseUrl);\n const accountId = stringValue(pod.accountId);\n if (!baseUrl || !accountId) {\n continue;\n }\n const podWebIds = dedupeStrings([\n stringValue(pod.webId),\n ...(ownerWebIdsByPodId.get(podId) ?? []),\n ...(webIdsByAccountId.get(accountId) ?? []),\n ].filter((value): value is string => typeof value === 'string'));\n\n pods.push({\n podId,\n accountId,\n baseUrl,\n storageUrl: stringValue(pod.storageUrl),\n webId: podWebIds[0],\n ...webIdsProperty(podWebIds),\n nodeId: stringValue(pod.nodeId),\n edgeNodeId: stringValue(pod.edgeNodeId),\n });\n }\n\n return pods;\n }\n}\n\nfunction extractAccountIdFromAccountDataKey(key: string): string | undefined {\n const marker = 'accounts/data/';\n const index = key.indexOf(marker);\n if (index < 0) {\n return undefined;\n }\n const accountId = key.slice(index + marker.length).replace(/\\.json$/u, '');\n return accountId || undefined;\n}\n\nfunction extractAccountWebIds(data: unknown): string[] {\n if (!data || typeof data !== 'object') {\n return [];\n }\n\n const record = data as Record<string, unknown>;\n const linkMap = record['**webIdLink**'] || record.webIdLink || {};\n if (!linkMap || typeof linkMap !== 'object') {\n return [];\n }\n\n return Object.values(linkMap as Record<string, unknown>)\n .map((value) => {\n if (!value || typeof value !== 'object') {\n return undefined;\n }\n const webId = (value as Record<string, unknown>).webId;\n return typeof webId === 'string' ? webId : undefined;\n })\n .filter((value): value is string => typeof value === 'string');\n}\n\nfunction extractPodOwnerWebIds(pod: Record<string, unknown>): string[] {\n const ownerMap = pod['**owner**'] || pod.owner || {};\n if (!ownerMap || typeof ownerMap !== 'object') {\n return [];\n }\n\n return Object.values(ownerMap as Record<string, unknown>)\n .map((value) => {\n if (!value || typeof value !== 'object') {\n return undefined;\n }\n const webId = (value as Record<string, unknown>).webId;\n return typeof webId === 'string' ? webId : undefined;\n })\n .filter((value): value is string => typeof value === 'string');\n}\n\nfunction normalizeWebId(webId: string | undefined): string | undefined {\n if (!webId) {\n return undefined;\n }\n try {\n return new URL(webId).toString();\n } catch {\n return webId;\n }\n}\n\nfunction dedupeStrings(values: string[]): string[] {\n return [...new Set(values)];\n}\n\nfunction getPodWebIds(pod: PodLookupResult): string[] {\n return dedupeStrings([\n pod.webId,\n ...(pod.webIds ?? []),\n ].filter((value): value is string => typeof value === 'string' && value.length > 0));\n}\n\nfunction webIdsProperty(values: string[]): Pick<PodLookupResult, 'webIds'> {\n const webIds = dedupeStrings(values);\n return webIds.length > 1 ? { webIds } : {};\n}\n\nfunction mergePodLookupResults(values: PodLookupResult[]): PodLookupResult[] {\n const byPodId = new Map<string, PodLookupResult>();\n for (const value of values) {\n const existing = byPodId.get(value.podId);\n if (!existing) {\n byPodId.set(value.podId, value);\n continue;\n }\n\n const webIds = dedupeStrings([\n ...getPodWebIds(existing),\n ...getPodWebIds(value),\n ]);\n byPodId.set(value.podId, {\n ...existing,\n baseUrl: existing.baseUrl || value.baseUrl,\n storageUrl: existing.storageUrl ?? value.storageUrl,\n accountId: existing.accountId || value.accountId,\n webId: webIds[0],\n ...webIdsProperty(webIds),\n nodeId: existing.nodeId ?? value.nodeId,\n edgeNodeId: existing.edgeNodeId ?? value.edgeNodeId,\n });\n }\n return [...byPodId.values()];\n}\n\nfunction parsePayloadRecord(value: unknown): Record<string, unknown> | undefined {\n if (!value) {\n return undefined;\n }\n if (typeof value === 'string') {\n try {\n const parsed = JSON.parse(value) as unknown;\n const unwrapped = unwrapStoredValue(parsed);\n return unwrapped && typeof unwrapped === 'object' ? unwrapped as Record<string, unknown> : undefined;\n } catch {\n return undefined;\n }\n }\n const unwrapped = unwrapStoredValue(value);\n return typeof unwrapped === 'object' ? unwrapped as Record<string, unknown> : undefined;\n}\n\nfunction parseStoredValue(value: unknown): unknown {\n if (typeof value === 'string') {\n try {\n return unwrapStoredValue(JSON.parse(value));\n } catch {\n return undefined;\n }\n }\n return unwrapStoredValue(value);\n}\n\nfunction unwrapStoredValue(value: unknown): unknown {\n if (value && typeof value === 'object' && 'key' in value && 'payload' in value) {\n return (value as Record<string, unknown>).payload;\n }\n return value;\n}\n\nfunction stringValue(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n}\n\nfunction appendMapValue(map: Map<string, string[]>, key: string, value: string): void {\n const values = map.get(key) ?? [];\n values.push(value);\n map.set(key, values);\n}\n"]}
1
+ {"version":3,"file":"PodLookupRepository.js","sourceRoot":"","sources":["../../../src/identity/drizzle/PodLookupRepository.ts"],"names":[],"mappings":"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","sourcesContent":["import { sql } from 'drizzle-orm';\nimport { type IdentityDatabase, executeQuery } from './db';\n\nexport interface PodLookupResult {\n podId: string;\n accountId: string;\n baseUrl: string;\n storageUrl?: string;\n webId?: string;\n webIds?: string[];\n nodeId?: string;\n edgeNodeId?: string;\n}\n\ninterface InternalKvRow {\n key?: string;\n value?: string;\n}\n\ninterface NodeAssignmentRow {\n node_id?: string | null;\n base_url?: string | null;\n}\n\n/**\n * Repository for Pod lookup operations.\n *\n * Reads Pod facts from the canonical identity_store table and from CSS\n * WrappedIndexedStorage rows when that storage backend is active.\n */\nexport class PodLookupRepository {\n private readonly kvTableName: string;\n private readonly indexedStoreTableName: string;\n\n public constructor(\n private readonly db: IdentityDatabase,\n kvTableName?: string,\n ) {\n this.kvTableName = kvTableName ?? 'internal_kv';\n this.indexedStoreTableName = 'identity_store';\n }\n\n /**\n * Find Pod by resource path (matches longest canonical storage/base URL prefix).\n */\n public async findByResourceIdentifier(resourcePath: string): Promise<PodLookupResult | undefined> {\n const pods = await this.getAllPods();\n\n let bestMatch: PodLookupResult | undefined;\n let bestLength = 0;\n\n for (const pod of pods) {\n const candidateBase = pod.storageUrl ?? pod.baseUrl;\n if (resourcePath.startsWith(candidateBase) && candidateBase.length > bestLength) {\n bestMatch = pod;\n bestLength = candidateBase.length;\n }\n }\n\n return bestMatch;\n }\n\n /**\n * Get Pod by ID.\n */\n public async findById(podId: string): Promise<PodLookupResult | undefined> {\n const pods = await this.getAllPods();\n return pods.find((p) => p.podId === podId);\n }\n\n /**\n * Find Pod by a linked WebID URL.\n *\n * CSS account data stores WebID links separately from Pod base URLs. This is\n * the precise lookup for IdP/SP split deployments where the WebID path does\n * not have to match the storage base URL.\n */\n public async findByWebId(webId: string): Promise<PodLookupResult | undefined> {\n return (await this.findAllByWebId(webId))[0];\n }\n\n /**\n * Find all Pods linked to a WebID.\n *\n * A Cloud WebID can legitimately back both a Cloud Pod and a Local SP Pod.\n * Callers that are scoped to a storage provider must inspect all candidates\n * instead of accepting the first account record returned by CSS storage.\n */\n public async findAllByWebId(webId: string): Promise<PodLookupResult[]> {\n const normalized = normalizeWebId(webId);\n if (!normalized) {\n return [];\n }\n\n const results: PodLookupResult[] = [];\n const pods = await this.getAllPods();\n for (const pod of pods) {\n const matchedWebId = getPodWebIds(pod).find((candidate) => normalizeWebId(candidate) === normalized);\n if (matchedWebId) {\n results.push({\n ...pod,\n webId: matchedWebId,\n });\n }\n }\n\n if (results.length > 0) {\n return results;\n }\n\n const indexed = await this.findByWebIdIndex(normalized);\n if (!indexed) {\n return [];\n }\n return [{\n ...indexed,\n }];\n }\n\n /**\n * Find Pods by linked WebID URLs in one scan.\n */\n public async findByWebIds(webIds: string[]): Promise<PodLookupResult[]> {\n const normalizedTargets = new Set(webIds.map(normalizeWebId).filter((value): value is string => Boolean(value)));\n if (normalizedTargets.size === 0) {\n return [];\n }\n\n const results: PodLookupResult[] = [];\n const pods = await this.getAllPods();\n for (const pod of pods) {\n const matchedWebId = getPodWebIds(pod).find((candidate) => {\n const normalized = normalizeWebId(candidate);\n return normalized ? normalizedTargets.has(normalized) : false;\n });\n if (!matchedWebId) {\n continue;\n }\n results.push({\n ...pod,\n webId: matchedWebId,\n });\n }\n if (results.length < normalizedTargets.size) {\n const seen = new Set(results.map((result) => normalizeWebId(result.webId)).filter(Boolean));\n for (const normalized of normalizedTargets) {\n if (seen.has(normalized)) {\n continue;\n }\n const indexed = await this.findByWebIdIndex(normalized);\n if (indexed) {\n results.push(indexed);\n }\n }\n }\n return results;\n }\n\n /**\n * List Pods for a specific account.\n */\n public async listByAccountId(accountId: string): Promise<PodLookupResult[]> {\n const pods = await this.getAllPods();\n return pods.filter((pod) => pod.accountId === accountId);\n }\n\n /**\n * List all pods.\n */\n public async listAllPods(): Promise<PodLookupResult[]> {\n return this.getAllPods();\n }\n\n /**\n * Extract all pods from the configured CSS identity storage.\n */\n private async getAllPods(): Promise<PodLookupResult[]> {\n const result = await this.getAccountRowsFromKv();\n const nodeAssignments = await this.getNodeAssignments();\n\n const pods: PodLookupResult[] = [];\n\n for (const row of result) {\n if (!row.key || row.value === undefined) {\n continue;\n }\n\n try {\n const accountId = extractAccountIdFromAccountDataKey(row.key);\n if (!accountId) {\n continue;\n }\n const data = unwrapStoredValue(typeof row.value === 'string' ? JSON.parse(row.value) : row.value);\n\n const podMap = (data as any)['**pod**'] || (data as any).pod || {};\n const webIds = extractAccountWebIds(data);\n\n for (const [podId, podData] of Object.entries(podMap)) {\n const pod = podData as Record<string, unknown>;\n if (pod.baseUrl && typeof pod.baseUrl === 'string') {\n const storageUrl = stringValue(pod.storageUrl) ?? stringValue(pod.storage);\n const podWebIds = [\n typeof pod.webId === 'string' ? pod.webId : undefined,\n ...extractPodOwnerWebIds(pod),\n ...webIds,\n ].filter((value): value is string => typeof value === 'string');\n pods.push({\n podId,\n accountId,\n baseUrl: pod.baseUrl,\n storageUrl,\n webId: dedupeStrings(podWebIds)[0],\n ...webIdsProperty(podWebIds),\n nodeId: typeof pod.nodeId === 'string' ? pod.nodeId : findNodeIdForPod(nodeAssignments, [storageUrl, pod.baseUrl]),\n edgeNodeId: typeof pod.edgeNodeId === 'string' ? pod.edgeNodeId : undefined,\n });\n }\n }\n } catch {\n // Skip malformed entries.\n }\n }\n\n return mergePodLookupResults([\n ...pods,\n ...await this.getPodsFromIndexedStore(nodeAssignments),\n ]);\n }\n\n private async getAccountRowsFromKv(): Promise<InternalKvRow[]> {\n const kvTableId = sql.identifier([this.kvTableName]);\n try {\n const result = await executeQuery<InternalKvRow>(this.db, sql`\n SELECT key, value FROM ${kvTableId}\n WHERE key LIKE 'accounts/data/%'\n OR key LIKE '/.internal/accounts/data/%'\n `);\n return result?.rows ?? [];\n } catch {\n return [];\n }\n }\n\n private async getNodeAssignments(): Promise<NodeAssignmentRow[]> {\n try {\n const tableId = sql.identifier(['cluster_node']);\n const result = await executeQuery<{ id?: string | null; pod_base_urls?: unknown }>(this.db, sql`\n SELECT id, pod_base_urls FROM ${tableId}\n WHERE pod_base_urls IS NOT NULL AND pod_base_urls <> ''\n `);\n return result.rows.flatMap((row) => {\n if (!row.id) {\n return [];\n }\n return parsePodBaseUrls(row.pod_base_urls).map((baseUrl) => ({\n node_id: row.id,\n base_url: baseUrl,\n }));\n });\n } catch {\n return [];\n }\n }\n\n /**\n * Fast path for CSS WrappedIndexedStorage. WebID indexes point to the root\n * account id, so a single indexed key plus account data row can resolve the\n * profile without scanning all account records.\n */\n private async findByWebIdIndex(webId: string): Promise<PodLookupResult | undefined> {\n const accountIds = await this.readStringArrayFromKv(`accounts/index/webIdLink/webId/${encodeURIComponent(webId)}`);\n for (const accountId of accountIds) {\n const account = await this.readAccountData(accountId);\n if (!account) {\n continue;\n }\n const pods = this.extractPodsFromAccountData(accountId, account);\n const match = pods.find((pod) => getPodWebIds(pod).some((candidate) => normalizeWebId(candidate) === webId));\n if (match) {\n return {\n ...match,\n webId,\n };\n }\n if (pods.length === 1) {\n return {\n ...pods[0],\n webId,\n ...webIdsProperty([webId, ...getPodWebIds(pods[0])]),\n };\n }\n }\n return undefined;\n }\n\n private async readAccountData(accountId: string): Promise<Record<string, unknown> | undefined> {\n for (const key of [`accounts/data/${accountId}`, `/.internal/accounts/data/${accountId}`]) {\n const value = await this.readKvValue(key);\n const record = parsePayloadRecord(value);\n if (record) {\n return record;\n }\n }\n return undefined;\n }\n\n private async readStringArrayFromKv(key: string): Promise<string[]> {\n const value = await this.readKvValue(key);\n return Array.isArray(value) ? value.filter((entry): entry is string => typeof entry === 'string') : [];\n }\n\n private async readKvValue(key: string): Promise<unknown> {\n const tableId = sql.identifier([this.kvTableName]);\n try {\n const result = await executeQuery<{ value?: unknown }>(this.db, sql`\n SELECT value FROM ${tableId}\n WHERE key = ${key}\n LIMIT 1\n `);\n if (result.rows.length === 0) {\n return undefined;\n }\n return parseStoredValue(result.rows[0].value);\n } catch {\n return undefined;\n }\n }\n\n private extractPodsFromAccountData(accountId: string, data: Record<string, unknown>): PodLookupResult[] {\n const podMap = (data as any)['**pod**'] || (data as any).pod || {};\n const webIds = extractAccountWebIds(data);\n const pods: PodLookupResult[] = [];\n\n for (const [podId, podData] of Object.entries(podMap)) {\n const pod = podData as Record<string, unknown>;\n if (pod.baseUrl && typeof pod.baseUrl === 'string') {\n const storageUrl = stringValue(pod.storageUrl) ?? stringValue(pod.storage);\n const podWebIds = [\n typeof pod.webId === 'string' ? pod.webId : undefined,\n ...extractPodOwnerWebIds(pod),\n ...webIds,\n ].filter((value): value is string => typeof value === 'string');\n pods.push({\n podId,\n accountId,\n baseUrl: pod.baseUrl,\n storageUrl,\n webId: dedupeStrings(podWebIds)[0],\n ...webIdsProperty(podWebIds),\n nodeId: typeof pod.nodeId === 'string' ? pod.nodeId : undefined,\n edgeNodeId: typeof pod.edgeNodeId === 'string' ? pod.edgeNodeId : undefined,\n });\n }\n }\n\n return pods;\n }\n\n /**\n * DrizzleIndexedStorage stores CSS identity facts as typed rows in\n * identity_store; this is the canonical clustered identity source.\n */\n private async getPodsFromIndexedStore(nodeAssignments: NodeAssignmentRow[] = []): Promise<PodLookupResult[]> {\n const storeTableId = sql.identifier([this.indexedStoreTableName]);\n let result: { rows?: Array<{ container?: string; id?: string; payload?: unknown }> } | undefined;\n try {\n result = await executeQuery(this.db, sql`\n SELECT container, id, payload FROM ${storeTableId}\n WHERE container IN ('pod', 'owner', 'webIdLink')\n `);\n } catch {\n return [];\n }\n\n const podPayloads = new Map<string, Record<string, unknown>>();\n const ownerWebIdsByPodId = new Map<string, string[]>();\n const webIdsByAccountId = new Map<string, string[]>();\n\n for (const row of result?.rows ?? []) {\n if (!row.id || !row.container) {\n continue;\n }\n const payload = parsePayloadRecord(row.payload);\n if (!payload) {\n continue;\n }\n\n if (row.container === 'pod') {\n podPayloads.set(row.id, payload);\n continue;\n }\n\n if (row.container === 'owner') {\n const podId = stringValue(payload.podId);\n const webId = stringValue(payload.webId);\n if (podId && webId) {\n appendMapValue(ownerWebIdsByPodId, podId, webId);\n }\n continue;\n }\n\n if (row.container === 'webIdLink') {\n const accountId = stringValue(payload.accountId);\n const webId = stringValue(payload.webId);\n if (accountId && webId) {\n appendMapValue(webIdsByAccountId, accountId, webId);\n }\n }\n }\n\n const pods: PodLookupResult[] = [];\n for (const [podId, pod] of podPayloads) {\n const baseUrl = stringValue(pod.baseUrl);\n const accountId = stringValue(pod.accountId);\n if (!baseUrl || !accountId) {\n continue;\n }\n const podWebIds = dedupeStrings([\n stringValue(pod.webId),\n ...(ownerWebIdsByPodId.get(podId) ?? []),\n ...(webIdsByAccountId.get(accountId) ?? []),\n ].filter((value): value is string => typeof value === 'string'));\n const storageUrl = stringValue(pod.storageUrl) ?? stringValue(pod.storage);\n\n pods.push({\n podId,\n accountId,\n baseUrl,\n storageUrl,\n webId: podWebIds[0],\n ...webIdsProperty(podWebIds),\n nodeId: stringValue(pod.nodeId) ?? findNodeIdForPod(nodeAssignments, [storageUrl, baseUrl]),\n edgeNodeId: stringValue(pod.edgeNodeId),\n });\n }\n\n return pods;\n }\n}\n\nfunction extractAccountIdFromAccountDataKey(key: string): string | undefined {\n const marker = 'accounts/data/';\n const index = key.indexOf(marker);\n if (index < 0) {\n return undefined;\n }\n const accountId = key.slice(index + marker.length).replace(/\\.json$/u, '');\n return accountId || undefined;\n}\n\nfunction extractAccountWebIds(data: unknown): string[] {\n if (!data || typeof data !== 'object') {\n return [];\n }\n\n const record = data as Record<string, unknown>;\n const linkMap = record['**webIdLink**'] || record.webIdLink || {};\n if (!linkMap || typeof linkMap !== 'object') {\n return [];\n }\n\n return Object.values(linkMap as Record<string, unknown>)\n .map((value) => {\n if (!value || typeof value !== 'object') {\n return undefined;\n }\n const webId = (value as Record<string, unknown>).webId;\n return typeof webId === 'string' ? webId : undefined;\n })\n .filter((value): value is string => typeof value === 'string');\n}\n\nfunction extractPodOwnerWebIds(pod: Record<string, unknown>): string[] {\n const ownerMap = pod['**owner**'] || pod.owner || {};\n if (!ownerMap || typeof ownerMap !== 'object') {\n return [];\n }\n\n return Object.values(ownerMap as Record<string, unknown>)\n .map((value) => {\n if (!value || typeof value !== 'object') {\n return undefined;\n }\n const webId = (value as Record<string, unknown>).webId;\n return typeof webId === 'string' ? webId : undefined;\n })\n .filter((value): value is string => typeof value === 'string');\n}\n\nfunction normalizeWebId(webId: string | undefined): string | undefined {\n if (!webId) {\n return undefined;\n }\n try {\n return new URL(webId).toString();\n } catch {\n return webId;\n }\n}\n\nfunction normalizeUrlRoot(url: string | undefined): string | undefined {\n if (!url) {\n return undefined;\n }\n try {\n const parsed = new URL(url);\n parsed.pathname = parsed.pathname.replace(/\\/+$/u, '') || '/';\n parsed.search = '';\n parsed.hash = '';\n return parsed.toString();\n } catch {\n return url;\n }\n}\n\nfunction dedupeStrings(values: string[]): string[] {\n return [...new Set(values)];\n}\n\nfunction getPodWebIds(pod: PodLookupResult): string[] {\n return dedupeStrings([\n pod.webId,\n ...(pod.webIds ?? []),\n ].filter((value): value is string => typeof value === 'string' && value.length > 0));\n}\n\nfunction webIdsProperty(values: string[]): Pick<PodLookupResult, 'webIds'> {\n const webIds = dedupeStrings(values);\n return webIds.length > 1 ? { webIds } : {};\n}\n\nfunction mergePodLookupResults(values: PodLookupResult[]): PodLookupResult[] {\n const byPodId = new Map<string, PodLookupResult>();\n for (const value of values) {\n const existing = byPodId.get(value.podId);\n if (!existing) {\n byPodId.set(value.podId, value);\n continue;\n }\n\n const webIds = dedupeStrings([\n ...getPodWebIds(existing),\n ...getPodWebIds(value),\n ]);\n byPodId.set(value.podId, {\n ...existing,\n baseUrl: existing.baseUrl || value.baseUrl,\n storageUrl: existing.storageUrl ?? value.storageUrl,\n accountId: existing.accountId || value.accountId,\n webId: webIds[0],\n ...webIdsProperty(webIds),\n nodeId: existing.nodeId ?? value.nodeId,\n edgeNodeId: existing.edgeNodeId ?? value.edgeNodeId,\n });\n }\n return [...byPodId.values()];\n}\n\nfunction parsePayloadRecord(value: unknown): Record<string, unknown> | undefined {\n if (!value) {\n return undefined;\n }\n if (typeof value === 'string') {\n try {\n const parsed = JSON.parse(value) as unknown;\n const unwrapped = unwrapStoredValue(parsed);\n return unwrapped && typeof unwrapped === 'object' ? unwrapped as Record<string, unknown> : undefined;\n } catch {\n return undefined;\n }\n }\n const unwrapped = unwrapStoredValue(value);\n return typeof unwrapped === 'object' ? unwrapped as Record<string, unknown> : undefined;\n}\n\nfunction parseStoredValue(value: unknown): unknown {\n if (typeof value === 'string') {\n try {\n return unwrapStoredValue(JSON.parse(value));\n } catch {\n return undefined;\n }\n }\n return unwrapStoredValue(value);\n}\n\nfunction unwrapStoredValue(value: unknown): unknown {\n if (value && typeof value === 'object' && 'key' in value && 'payload' in value) {\n return (value as Record<string, unknown>).payload;\n }\n return value;\n}\n\nfunction stringValue(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n}\n\nfunction appendMapValue(map: Map<string, string[]>, key: string, value: string): void {\n const values = map.get(key) ?? [];\n values.push(value);\n map.set(key, values);\n}\n\nfunction parsePodBaseUrls(value: unknown): string[] {\n if (Array.isArray(value)) {\n return dedupeStrings(value.filter((entry): entry is string => typeof entry === 'string' && entry.length > 0));\n }\n if (typeof value !== 'string' || value.length === 0) {\n return [];\n }\n try {\n const parsed = JSON.parse(value) as unknown;\n return Array.isArray(parsed)\n ? dedupeStrings(parsed.filter((entry): entry is string => typeof entry === 'string' && entry.length > 0))\n : [];\n } catch {\n return [];\n }\n}\n\nfunction findNodeIdForPod(assignments: NodeAssignmentRow[], urls: Array<string | undefined>): string | undefined {\n const normalizedUrls = urls.map(normalizeUrlRoot).filter((value): value is string => Boolean(value));\n if (normalizedUrls.length === 0) {\n return undefined;\n }\n\n let bestMatch: { nodeId: string; length: number } | undefined;\n for (const assignment of assignments) {\n if (!assignment.node_id || !assignment.base_url) {\n continue;\n }\n const assignedBase = normalizeUrlRoot(assignment.base_url);\n if (!assignedBase) {\n continue;\n }\n for (const url of normalizedUrls) {\n if (url.startsWith(assignedBase) && assignedBase.length > (bestMatch?.length ?? 0)) {\n bestMatch = {\n nodeId: assignment.node_id,\n length: assignedBase.length,\n };\n }\n }\n }\n\n return bestMatch?.nodeId;\n}\n"]}
@@ -14,10 +14,22 @@ export interface CreateServiceTokenOptions {
14
14
  scopes: string[];
15
15
  expiresAt?: Date | null;
16
16
  }
17
- export declare class ServiceTokenRepository {
17
+ export interface ServiceTokenRepositoryPort {
18
+ createToken(options: CreateServiceTokenOptions): Promise<{
19
+ id: string;
20
+ token: string;
21
+ }>;
22
+ registerToken(token: string, options: CreateServiceTokenOptions): Promise<string>;
23
+ verifyToken(token: string): Promise<ServiceTokenRecord | undefined>;
24
+ findByService(serviceType: ServiceType, serviceId: string): Promise<ServiceTokenRecord | undefined>;
25
+ deleteToken(id: string): Promise<void>;
26
+ listTokens(): Promise<ServiceTokenRecord[]>;
27
+ }
28
+ export declare class ServiceTokenRepository implements ServiceTokenRepositoryPort {
18
29
  private readonly db;
19
30
  private readonly logger;
20
31
  private readonly schema;
32
+ private readonly ready;
21
33
  constructor(db: IdentityDatabase);
22
34
  /**
23
35
  * Create a new service token. Returns the plaintext token (only available at creation time).
@@ -10,11 +10,13 @@ class ServiceTokenRepository {
10
10
  this.db = db;
11
11
  this.logger = (0, global_logger_factory_1.getLoggerFor)(this);
12
12
  this.schema = (0, db_1.getSchema)(db);
13
+ this.ready = (0, db_1.ensureCloudClusterTables)(db);
13
14
  }
14
15
  /**
15
16
  * Create a new service token. Returns the plaintext token (only available at creation time).
16
17
  */
17
18
  async createToken(options) {
19
+ await this.ready;
18
20
  const id = (0, node_crypto_1.randomUUID)();
19
21
  const token = `svc-${(0, node_crypto_1.randomUUID)().replace(/-/g, '')}`;
20
22
  const tokenHash = this.hashToken(token);
@@ -35,6 +37,7 @@ class ServiceTokenRepository {
35
37
  * Upserts by serviceType + serviceId to avoid duplicates.
36
38
  */
37
39
  async registerToken(token, options) {
40
+ await this.ready;
38
41
  const tokenHash = this.hashToken(token);
39
42
  // Check if a token already exists for this service
40
43
  const existing = await this.findByService(options.serviceType, options.serviceId);
@@ -67,6 +70,7 @@ class ServiceTokenRepository {
67
70
  * Verify a plaintext token and return the matching record if valid.
68
71
  */
69
72
  async verifyToken(token) {
73
+ await this.ready;
70
74
  const tokenHash = this.hashToken(token);
71
75
  const rows = await this.db.select()
72
76
  .from(this.schema.serviceTokens)
@@ -90,6 +94,7 @@ class ServiceTokenRepository {
90
94
  * Find a token record by service type and service ID.
91
95
  */
92
96
  async findByService(serviceType, serviceId) {
97
+ await this.ready;
93
98
  const rows = await this.db.select()
94
99
  .from(this.schema.serviceTokens)
95
100
  .where((0, drizzle_orm_1.eq)(this.schema.serviceTokens.serviceType, serviceType));
@@ -100,6 +105,7 @@ class ServiceTokenRepository {
100
105
  * Delete a service token by ID.
101
106
  */
102
107
  async deleteToken(id) {
108
+ await this.ready;
103
109
  await this.db.delete(this.schema.serviceTokens).where((0, drizzle_orm_1.eq)(this.schema.serviceTokens.id, id));
104
110
  this.logger.info(`Deleted service token ${id}`);
105
111
  }
@@ -107,6 +113,7 @@ class ServiceTokenRepository {
107
113
  * List all service tokens (without hashes).
108
114
  */
109
115
  async listTokens() {
116
+ await this.ready;
110
117
  const rows = await this.db.select({
111
118
  id: this.schema.serviceTokens.id,
112
119
  serviceType: this.schema.serviceTokens.serviceType,
@@ -1 +1 @@
1
- {"version":3,"file":"ServiceTokenRepository.js","sourceRoot":"","sources":["../../../src/identity/drizzle/ServiceTokenRepository.ts"],"names":[],"mappings":";;;AAAA,6CAAqD;AACrD,6CAAiC;AACjC,iEAAqD;AAErD,6BAAiE;AAoBjE,MAAa,sBAAsB;IAIjC,YAAoC,EAAoB;QAApB,OAAE,GAAF,EAAE,CAAkB;QAHvC,WAAM,GAAG,IAAA,oCAAY,EAAC,IAAI,CAAC,CAAC;QAI3C,IAAI,CAAC,MAAM,GAAG,IAAA,cAAS,EAAC,EAAE,CAAC,CAAC;IAC9B,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,WAAW,CAAC,OAAkC;QACzD,MAAM,EAAE,GAAG,IAAA,wBAAU,GAAE,CAAC;QACxB,MAAM,KAAK,GAAG,OAAO,IAAA,wBAAU,GAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC;QACtD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAExC,MAAM,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC;YACrD,EAAE;YACF,SAAS;YACT,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC;YACtC,SAAS,EAAE,IAAA,kBAAa,EAAC,IAAI,CAAC,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC;YAC7C,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,IAAA,kBAAa,EAAC,IAAI,CAAC,EAAE,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI;SAChF,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,yBAAyB,EAAE,QAAQ,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;QAChG,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;IACvB,CAAC;IAED;;;OAGG;IACI,KAAK,CAAC,aAAa,CACxB,KAAa,EACb,OAAkC;QAElC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAExC,mDAAmD;QACnD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;QAClF,IAAI,QAAQ,EAAE,CAAC;YACb,4CAA4C;YAC5C,MAAM,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC;iBAC5C,GAAG,CAAC;gBACH,SAAS;gBACT,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC;gBACtC,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,IAAA,kBAAa,EAAC,IAAI,CAAC,EAAE,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI;aAChF,CAAC;iBACD,KAAK,CAAC,IAAA,gBAAE,EAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;YACxD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,yBAAyB,QAAQ,CAAC,EAAE,QAAQ,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;YACzG,OAAO,QAAQ,CAAC,EAAE,CAAC;QACrB,CAAC;QAED,MAAM,EAAE,GAAG,IAAA,wBAAU,GAAE,CAAC;QACxB,MAAM,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC;YACrD,EAAE;YACF,SAAS;YACT,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC;YACtC,SAAS,EAAE,IAAA,kBAAa,EAAC,IAAI,CAAC,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC;YAC7C,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,IAAA,kBAAa,EAAC,IAAI,CAAC,EAAE,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI;SAChF,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,4BAA4B,EAAE,QAAQ,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;QACnG,OAAO,EAAE,CAAC;IACZ,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,WAAW,CAAC,KAAa;QACpC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAExC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE;aAChC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC;aAC/B,KAAK,CAAC,IAAA,gBAAE,EAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC;QAE7D,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/B,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEpB,4DAA4D;QAC5D,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;YAClB,MAAM,cAAc,GAAG,IAAA,oBAAe,EAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACtD,MAAM,WAAW,GAAG,cAAc,EAAE,OAAO,EAAE,IAAI,MAAM,CAAC,GAAG,CAAC;YAC5D,IAAI,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;gBAC7B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,GAAG,CAAC,EAAE,cAAc,CAAC,CAAC;gBACzD,OAAO,SAAS,CAAC;YACnB,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,aAAa,CAAC,WAAwB,EAAE,SAAiB;QACpE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE;aAChC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC;aAC/B,KAAK,CAAC,IAAA,gBAAE,EAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC;QAEjE,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC;QAC/D,OAAO,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAClD,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,WAAW,CAAC,EAAU;QACjC,MAAM,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,KAAK,CAAC,IAAA,gBAAE,EAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QAC5F,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,yBAAyB,EAAE,EAAE,CAAC,CAAC;IAClD,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,UAAU;QACrB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC;YAChC,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE;YAChC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,WAAW;YAClD,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,SAAS;YAC9C,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM;YACxC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,SAAS;YAC9C,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,SAAS;SAC/C,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;QAEnC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,CAAC;IAEO,SAAS,CAAC,KAAa;QAC7B,OAAO,IAAA,wBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC1D,CAAC;IAEO,QAAQ,CAAC,GAAQ;QACvB,IAAI,MAAgB,CAAC;QACrB,IAAI,CAAC;YACH,MAAM,GAAG,OAAO,GAAG,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC;QAChF,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,GAAG,EAAE,CAAC;QACd,CAAC;QAED,OAAO;YACL,EAAE,EAAE,GAAG,CAAC,EAAE;YACV,WAAW,EAAE,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,YAAY;YAChD,SAAS,EAAE,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,UAAU;YAC1C,MAAM;YACN,SAAS,EAAE,IAAA,oBAAe,EAAC,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC;YAC1E,SAAS,EAAE,IAAA,oBAAe,EAAC,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,IAAI;SACpE,CAAC;IACJ,CAAC;CACF;AA5JD,wDA4JC","sourcesContent":["import { randomUUID, createHash } from 'node:crypto';\nimport { eq } from 'drizzle-orm';\nimport { getLoggerFor } from 'global-logger-factory';\nimport type { IdentityDatabase } from './db';\nimport { getSchema, toDbTimestamp, fromDbTimestamp } from './db';\n\nexport type ServiceType = 'local' | 'business' | 'cloud' | 'compute';\n\nexport interface ServiceTokenRecord {\n id: string;\n serviceType: ServiceType;\n serviceId: string;\n scopes: string[];\n createdAt: Date;\n expiresAt: Date | null;\n}\n\nexport interface CreateServiceTokenOptions {\n serviceType: ServiceType;\n serviceId: string;\n scopes: string[];\n expiresAt?: Date | null;\n}\n\nexport class ServiceTokenRepository {\n private readonly logger = getLoggerFor(this);\n private readonly schema: ReturnType<typeof getSchema>;\n\n public constructor(private readonly db: IdentityDatabase) {\n this.schema = getSchema(db);\n }\n\n /**\n * Create a new service token. Returns the plaintext token (only available at creation time).\n */\n public async createToken(options: CreateServiceTokenOptions): Promise<{ id: string; token: string }> {\n const id = randomUUID();\n const token = `svc-${randomUUID().replace(/-/g, '')}`;\n const tokenHash = this.hashToken(token);\n\n await this.db.insert(this.schema.serviceTokens).values({\n id,\n tokenHash,\n serviceType: options.serviceType,\n serviceId: options.serviceId,\n scopes: JSON.stringify(options.scopes),\n createdAt: toDbTimestamp(this.db, new Date()),\n expiresAt: options.expiresAt ? toDbTimestamp(this.db, options.expiresAt) : null,\n });\n\n this.logger.info(`Created service token ${id} for ${options.serviceType}:${options.serviceId}`);\n return { id, token };\n }\n\n /**\n * Register a token from a known plaintext value (e.g. XPOD_BUSINESS_TOKEN env var).\n * Upserts by serviceType + serviceId to avoid duplicates.\n */\n public async registerToken(\n token: string,\n options: CreateServiceTokenOptions,\n ): Promise<string> {\n const tokenHash = this.hashToken(token);\n\n // Check if a token already exists for this service\n const existing = await this.findByService(options.serviceType, options.serviceId);\n if (existing) {\n // Update the hash in case the token changed\n await this.db.update(this.schema.serviceTokens)\n .set({\n tokenHash,\n scopes: JSON.stringify(options.scopes),\n expiresAt: options.expiresAt ? toDbTimestamp(this.db, options.expiresAt) : null,\n })\n .where(eq(this.schema.serviceTokens.id, existing.id));\n this.logger.info(`Updated service token ${existing.id} for ${options.serviceType}:${options.serviceId}`);\n return existing.id;\n }\n\n const id = randomUUID();\n await this.db.insert(this.schema.serviceTokens).values({\n id,\n tokenHash,\n serviceType: options.serviceType,\n serviceId: options.serviceId,\n scopes: JSON.stringify(options.scopes),\n createdAt: toDbTimestamp(this.db, new Date()),\n expiresAt: options.expiresAt ? toDbTimestamp(this.db, options.expiresAt) : null,\n });\n\n this.logger.info(`Registered service token ${id} for ${options.serviceType}:${options.serviceId}`);\n return id;\n }\n\n /**\n * Verify a plaintext token and return the matching record if valid.\n */\n public async verifyToken(token: string): Promise<ServiceTokenRecord | undefined> {\n const tokenHash = this.hashToken(token);\n\n const rows = await this.db.select()\n .from(this.schema.serviceTokens)\n .where(eq(this.schema.serviceTokens.tokenHash, tokenHash));\n\n if (!rows || rows.length === 0) {\n return undefined;\n }\n\n const row = rows[0];\n\n // Check expiration (expiresAt is Unix timestamp in seconds)\n if (row.expiresAt) {\n const expiresAtValue = fromDbTimestamp(row.expiresAt);\n const expiresAtMs = expiresAtValue?.getTime() ?? Number.NaN;\n if (expiresAtMs < Date.now()) {\n this.logger.debug(`Service token ${row.id} has expired`);\n return undefined;\n }\n }\n\n return this.toRecord(row);\n }\n\n /**\n * Find a token record by service type and service ID.\n */\n public async findByService(serviceType: ServiceType, serviceId: string): Promise<ServiceTokenRecord | undefined> {\n const rows = await this.db.select()\n .from(this.schema.serviceTokens)\n .where(eq(this.schema.serviceTokens.serviceType, serviceType));\n\n const match = rows.find((r: any) => r.serviceId === serviceId);\n return match ? this.toRecord(match) : undefined;\n }\n\n /**\n * Delete a service token by ID.\n */\n public async deleteToken(id: string): Promise<void> {\n await this.db.delete(this.schema.serviceTokens).where(eq(this.schema.serviceTokens.id, id));\n this.logger.info(`Deleted service token ${id}`);\n }\n\n /**\n * List all service tokens (without hashes).\n */\n public async listTokens(): Promise<ServiceTokenRecord[]> {\n const rows = await this.db.select({\n id: this.schema.serviceTokens.id,\n serviceType: this.schema.serviceTokens.serviceType,\n serviceId: this.schema.serviceTokens.serviceId,\n scopes: this.schema.serviceTokens.scopes,\n createdAt: this.schema.serviceTokens.createdAt,\n expiresAt: this.schema.serviceTokens.expiresAt,\n }).from(this.schema.serviceTokens);\n\n return rows.map((r: any) => this.toRecord(r));\n }\n\n private hashToken(token: string): string {\n return createHash('sha256').update(token).digest('hex');\n }\n\n private toRecord(row: any): ServiceTokenRecord {\n let scopes: string[];\n try {\n scopes = typeof row.scopes === 'string' ? JSON.parse(row.scopes) : row.scopes;\n } catch {\n scopes = [];\n }\n\n return {\n id: row.id,\n serviceType: row.serviceType ?? row.service_type,\n serviceId: row.serviceId ?? row.service_id,\n scopes,\n createdAt: fromDbTimestamp(row.createdAt ?? row.created_at) ?? new Date(0),\n expiresAt: fromDbTimestamp(row.expiresAt ?? row.expires_at) ?? null,\n };\n }\n}\n"]}
1
+ {"version":3,"file":"ServiceTokenRepository.js","sourceRoot":"","sources":["../../../src/identity/drizzle/ServiceTokenRepository.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID, createHash } from 'node:crypto';\nimport { eq } from 'drizzle-orm';\nimport { getLoggerFor } from 'global-logger-factory';\nimport type { IdentityDatabase } from './db';\nimport { ensureCloudClusterTables, getSchema, toDbTimestamp, fromDbTimestamp } from './db';\n\nexport type ServiceType = 'local' | 'business' | 'cloud' | 'compute';\n\nexport interface ServiceTokenRecord {\n id: string;\n serviceType: ServiceType;\n serviceId: string;\n scopes: string[];\n createdAt: Date;\n expiresAt: Date | null;\n}\n\nexport interface CreateServiceTokenOptions {\n serviceType: ServiceType;\n serviceId: string;\n scopes: string[];\n expiresAt?: Date | null;\n}\n\nexport interface ServiceTokenRepositoryPort {\n createToken(options: CreateServiceTokenOptions): Promise<{ id: string; token: string }>;\n registerToken(token: string, options: CreateServiceTokenOptions): Promise<string>;\n verifyToken(token: string): Promise<ServiceTokenRecord | undefined>;\n findByService(serviceType: ServiceType, serviceId: string): Promise<ServiceTokenRecord | undefined>;\n deleteToken(id: string): Promise<void>;\n listTokens(): Promise<ServiceTokenRecord[]>;\n}\n\nexport class ServiceTokenRepository implements ServiceTokenRepositoryPort {\n private readonly logger = getLoggerFor(this);\n private readonly schema: ReturnType<typeof getSchema>;\n private readonly ready: Promise<void>;\n\n public constructor(private readonly db: IdentityDatabase) {\n this.schema = getSchema(db);\n this.ready = ensureCloudClusterTables(db);\n }\n\n /**\n * Create a new service token. Returns the plaintext token (only available at creation time).\n */\n public async createToken(options: CreateServiceTokenOptions): Promise<{ id: string; token: string }> {\n await this.ready;\n const id = randomUUID();\n const token = `svc-${randomUUID().replace(/-/g, '')}`;\n const tokenHash = this.hashToken(token);\n\n await this.db.insert(this.schema.serviceTokens).values({\n id,\n tokenHash,\n serviceType: options.serviceType,\n serviceId: options.serviceId,\n scopes: JSON.stringify(options.scopes),\n createdAt: toDbTimestamp(this.db, new Date()),\n expiresAt: options.expiresAt ? toDbTimestamp(this.db, options.expiresAt) : null,\n });\n\n this.logger.info(`Created service token ${id} for ${options.serviceType}:${options.serviceId}`);\n return { id, token };\n }\n\n /**\n * Register a token from a known plaintext value (e.g. XPOD_BUSINESS_TOKEN env var).\n * Upserts by serviceType + serviceId to avoid duplicates.\n */\n public async registerToken(\n token: string,\n options: CreateServiceTokenOptions,\n ): Promise<string> {\n await this.ready;\n const tokenHash = this.hashToken(token);\n\n // Check if a token already exists for this service\n const existing = await this.findByService(options.serviceType, options.serviceId);\n if (existing) {\n // Update the hash in case the token changed\n await this.db.update(this.schema.serviceTokens)\n .set({\n tokenHash,\n scopes: JSON.stringify(options.scopes),\n expiresAt: options.expiresAt ? toDbTimestamp(this.db, options.expiresAt) : null,\n })\n .where(eq(this.schema.serviceTokens.id, existing.id));\n this.logger.info(`Updated service token ${existing.id} for ${options.serviceType}:${options.serviceId}`);\n return existing.id;\n }\n\n const id = randomUUID();\n await this.db.insert(this.schema.serviceTokens).values({\n id,\n tokenHash,\n serviceType: options.serviceType,\n serviceId: options.serviceId,\n scopes: JSON.stringify(options.scopes),\n createdAt: toDbTimestamp(this.db, new Date()),\n expiresAt: options.expiresAt ? toDbTimestamp(this.db, options.expiresAt) : null,\n });\n\n this.logger.info(`Registered service token ${id} for ${options.serviceType}:${options.serviceId}`);\n return id;\n }\n\n /**\n * Verify a plaintext token and return the matching record if valid.\n */\n public async verifyToken(token: string): Promise<ServiceTokenRecord | undefined> {\n await this.ready;\n const tokenHash = this.hashToken(token);\n\n const rows = await this.db.select()\n .from(this.schema.serviceTokens)\n .where(eq(this.schema.serviceTokens.tokenHash, tokenHash));\n\n if (!rows || rows.length === 0) {\n return undefined;\n }\n\n const row = rows[0];\n\n // Check expiration (expiresAt is Unix timestamp in seconds)\n if (row.expiresAt) {\n const expiresAtValue = fromDbTimestamp(row.expiresAt);\n const expiresAtMs = expiresAtValue?.getTime() ?? Number.NaN;\n if (expiresAtMs < Date.now()) {\n this.logger.debug(`Service token ${row.id} has expired`);\n return undefined;\n }\n }\n\n return this.toRecord(row);\n }\n\n /**\n * Find a token record by service type and service ID.\n */\n public async findByService(serviceType: ServiceType, serviceId: string): Promise<ServiceTokenRecord | undefined> {\n await this.ready;\n const rows = await this.db.select()\n .from(this.schema.serviceTokens)\n .where(eq(this.schema.serviceTokens.serviceType, serviceType));\n\n const match = rows.find((r: any) => r.serviceId === serviceId);\n return match ? this.toRecord(match) : undefined;\n }\n\n /**\n * Delete a service token by ID.\n */\n public async deleteToken(id: string): Promise<void> {\n await this.ready;\n await this.db.delete(this.schema.serviceTokens).where(eq(this.schema.serviceTokens.id, id));\n this.logger.info(`Deleted service token ${id}`);\n }\n\n /**\n * List all service tokens (without hashes).\n */\n public async listTokens(): Promise<ServiceTokenRecord[]> {\n await this.ready;\n const rows = await this.db.select({\n id: this.schema.serviceTokens.id,\n serviceType: this.schema.serviceTokens.serviceType,\n serviceId: this.schema.serviceTokens.serviceId,\n scopes: this.schema.serviceTokens.scopes,\n createdAt: this.schema.serviceTokens.createdAt,\n expiresAt: this.schema.serviceTokens.expiresAt,\n }).from(this.schema.serviceTokens);\n\n return rows.map((r: any) => this.toRecord(r));\n }\n\n private hashToken(token: string): string {\n return createHash('sha256').update(token).digest('hex');\n }\n\n private toRecord(row: any): ServiceTokenRecord {\n let scopes: string[];\n try {\n scopes = typeof row.scopes === 'string' ? JSON.parse(row.scopes) : row.scopes;\n } catch {\n scopes = [];\n }\n\n return {\n id: row.id,\n serviceType: row.serviceType ?? row.service_type,\n serviceId: row.serviceId ?? row.service_id,\n scopes,\n createdAt: fromDbTimestamp(row.createdAt ?? row.created_at) ?? new Date(0),\n expiresAt: fromDbTimestamp(row.expiresAt ?? row.expires_at) ?? null,\n };\n }\n}\n"]}
@@ -9,7 +9,7 @@ export type IdentitySchema = typeof pgSchema | typeof sqliteSchema;
9
9
  *
10
10
  * @example
11
11
  * const schema = getSchema(db);
12
- * await db.select().from(schema.accountUsage).where(eq(schema.accountUsage.accountId, id));
12
+ * await db.select().from(schema.usage).where(eq(schema.usage.scopeId, id));
13
13
  */
14
14
  export declare function getSchema(db: IdentityDatabase): typeof pgSchema | typeof sqliteSchema;
15
15
  /**
@@ -57,6 +57,7 @@ export declare function executeQuery<T = Record<string, unknown>>(db: IdentityDa
57
57
  * Works uniformly across PostgreSQL and SQLite.
58
58
  */
59
59
  export declare function executeStatement(db: IdentityDatabase, query: SQL): Promise<void>;
60
+ export declare function ensureCloudClusterTables(db: IdentityDatabase): Promise<void>;
60
61
  /**
61
62
  * Convert a Date to a value suitable for the database.
62
63
  * SQLite uses Unix timestamps (seconds), PostgreSQL uses Date objects.