@undefineds.co/xpod 0.3.49 → 0.3.50

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 (35) hide show
  1. package/dist/api/auth/MultiAuthenticator.js +2 -2
  2. package/dist/api/auth/MultiAuthenticator.js.map +1 -1
  3. package/dist/api/handlers/MatrixHandler.js +25 -1
  4. package/dist/api/handlers/MatrixHandler.js.map +1 -1
  5. package/dist/api/matrix/PodMatrixStore.js +11 -4
  6. package/dist/api/matrix/PodMatrixStore.js.map +1 -1
  7. package/dist/api/matrix/types.d.ts +2 -0
  8. package/dist/api/matrix/types.js.map +1 -1
  9. package/dist/api/middleware/AuthMiddleware.d.ts +1 -0
  10. package/dist/api/middleware/AuthMiddleware.js +13 -1
  11. package/dist/api/middleware/AuthMiddleware.js.map +1 -1
  12. package/dist/api/protocol-metadata.js +14 -4
  13. package/dist/api/protocol-metadata.js.map +1 -1
  14. package/dist/cli/lib/auth-context.js +10 -7
  15. package/dist/cli/lib/auth-context.js.map +1 -1
  16. package/dist/cli/lib/auth-helper.d.ts +8 -6
  17. package/dist/cli/lib/auth-helper.js +8 -6
  18. package/dist/cli/lib/auth-helper.js.map +1 -1
  19. package/dist/cli/lib/oidc-auth.d.ts +4 -0
  20. package/dist/cli/lib/oidc-auth.js +90 -0
  21. package/dist/cli/lib/oidc-auth.js.map +1 -0
  22. package/dist/cli/lib/oidc-session-storage.d.ts +3 -0
  23. package/dist/cli/lib/oidc-session-storage.js +41 -0
  24. package/dist/cli/lib/oidc-session-storage.js.map +1 -0
  25. package/dist/runtime/Proxy.d.ts +1 -0
  26. package/dist/runtime/Proxy.js +8 -1
  27. package/dist/runtime/Proxy.js.map +1 -1
  28. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/select-query-builder.d.ts.map +1 -1
  29. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/select-query-builder.js +19 -9
  30. package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/select-query-builder.js.map +1 -1
  31. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/select-query-builder.d.ts.map +1 -1
  32. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/select-query-builder.js +19 -9
  33. package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/select-query-builder.js.map +1 -1
  34. package/node_modules/@undefineds.co/drizzle-solid/package.json +1 -1
  35. package/package.json +4 -3
@@ -1 +1 @@
1
- {"version":3,"file":"AuthMiddleware.js","sourceRoot":"","sources":["../../../src/api/middleware/AuthMiddleware.ts"],"names":[],"mappings":";;;AACA,iEAAqD;AAmBrD;;GAEG;AACH,MAAa,cAAc;IAKzB,YAAmB,OAA8B;QAJhC,WAAM,GAAG,IAAA,oCAAY,EAAC,IAAI,CAAC,CAAC;QAK3C,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;QAC3C,IAAI,CAAC,WAAW,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;IACxD,CAAC;IAED;;OAEG;IACI,YAAY,CAAC,IAAY;QAC9B,0CAA0C;QAC1C,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1C,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAC9C,CAAC;IAED;;;OAGG;IACI,KAAK,CAAC,OAAO,CAAC,OAA6B,EAAE,QAAwB;QAC1E,iCAAiC;QACjC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;YACnC,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,yBAAyB,CAAC,CAAC;YAC3D,OAAO,KAAK,CAAC;QACf,CAAC;QAED,yBAAyB;QACzB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QAE9D,OAAO,CAAC,GAAG,CAAC,oBAAoB,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,eAAe,MAAM,CAAC,OAAO,YAAY,MAAM,CAAC,KAAK,cAAc,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAElK,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,CAAC,KAAK,IAAI,uBAAuB,CAAC,CAAC;YACzE,OAAO,KAAK,CAAC;QACf,CAAC;QAED,iCAAiC;QACjC,OAAO,CAAC,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,gBAAgB,CAAC,QAAwB,EAAE,OAAe;QAChE,QAAQ,CAAC,UAAU,GAAG,GAAG,CAAC;QAC1B,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;QACvD,QAAQ,CAAC,SAAS,CAAC,kBAAkB,EAAE,cAAc,CAAC,CAAC;QACvD,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;IACnE,CAAC;CACF;AAnDD,wCAmDC","sourcesContent":["import type { IncomingMessage, ServerResponse } from 'node:http';\nimport { getLoggerFor } from 'global-logger-factory';\nimport type { Authenticator } from '../auth/Authenticator';\nimport type { AuthContext } from '../auth/AuthContext';\n\n/**\n * Extended request with auth context\n */\nexport interface AuthenticatedRequest extends IncomingMessage {\n auth?: AuthContext;\n}\n\nexport interface AuthMiddlewareOptions {\n authenticator: Authenticator;\n /**\n * Paths that do not require authentication\n */\n publicPaths?: string[];\n}\n\n/**\n * Middleware that handles authentication for API requests\n */\nexport class AuthMiddleware {\n private readonly logger = getLoggerFor(this);\n private readonly authenticator: Authenticator;\n private readonly publicPaths: Set<string>;\n\n public constructor(options: AuthMiddlewareOptions) {\n this.authenticator = options.authenticator;\n this.publicPaths = new Set(options.publicPaths ?? []);\n }\n\n /**\n * Check if a path is public (does not require authentication)\n */\n public isPublicPath(path: string): boolean {\n // Normalize path by removing query string\n const normalizedPath = path.split('?')[0];\n return this.publicPaths.has(normalizedPath);\n }\n\n /**\n * Process the request, adding auth context if authenticated\n * Returns true if request should continue, false if response was sent\n */\n public async process(request: AuthenticatedRequest, response: ServerResponse): Promise<boolean> {\n // Check for authorization header\n if (!request.headers.authorization) {\n this.sendUnauthorized(response, 'Authentication required');\n return false;\n }\n\n // Attempt authentication\n const result = await this.authenticator.authenticate(request);\n\n console.log(`[AuthMiddleware] ${request.method} ${request.url} - success: ${result.success}, error: ${result.error}, context: ${JSON.stringify(result.context)}`);\n\n if (!result.success) {\n this.sendUnauthorized(response, result.error ?? 'Authentication failed');\n return false;\n }\n\n // Attach auth context to request\n request.auth = result.context;\n return true;\n }\n\n private sendUnauthorized(response: ServerResponse, message: string): void {\n response.statusCode = 401;\n response.setHeader('Content-Type', 'application/json');\n response.setHeader('WWW-Authenticate', 'Bearer, DPoP');\n response.end(JSON.stringify({ error: 'Unauthorized', message }));\n }\n}\n"]}
1
+ {"version":3,"file":"AuthMiddleware.js","sourceRoot":"","sources":["../../../src/api/middleware/AuthMiddleware.ts"],"names":[],"mappings":";;;AACA,iEAAqD;AAmBrD;;GAEG;AACH,MAAa,cAAc;IAKzB,YAAmB,OAA8B;QAJhC,WAAM,GAAG,IAAA,oCAAY,EAAC,IAAI,CAAC,CAAC;QAK3C,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;QAC3C,IAAI,CAAC,WAAW,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;IACxD,CAAC;IAED;;OAEG;IACI,YAAY,CAAC,IAAY;QAC9B,0CAA0C;QAC1C,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1C,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAC9C,CAAC;IAED;;;OAGG;IACI,KAAK,CAAC,OAAO,CAAC,OAA6B,EAAE,QAAwB;QAC1E,iCAAiC;QACjC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;YACnC,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,yBAAyB,CAAC,CAAC;YAC3D,OAAO,KAAK,CAAC;QACf,CAAC;QAED,yBAAyB;QACzB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QAE9D,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,QAAQ,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,YAAY,MAAM,CAAC,OAAO,EAAE;YACjE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9C,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAC7F,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,CAAC,KAAK,IAAI,uBAAuB,CAAC,CAAC;YACzE,OAAO,KAAK,CAAC;QACf,CAAC;QAED,iCAAiC;QACjC,OAAO,CAAC,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,gBAAgB,CAAC,QAAwB,EAAE,OAAe;QAChE,QAAQ,CAAC,UAAU,GAAG,GAAG,CAAC;QAC1B,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;QACvD,QAAQ,CAAC,SAAS,CAAC,kBAAkB,EAAE,cAAc,CAAC,CAAC;QACvD,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;IACnE,CAAC;IAEO,iBAAiB,CAAC,OAAoB;QAC5C,OAAO;YACL,IAAI,EAAG,OAAe,CAAC,IAAI;YAC3B,KAAK,EAAG,OAAe,CAAC,KAAK;YAC7B,SAAS,EAAG,OAAe,CAAC,SAAS;YACrC,QAAQ,EAAG,OAAe,CAAC,QAAQ;YACnC,SAAS,EAAG,OAAe,CAAC,SAAS;YACrC,SAAS,EAAG,OAAe,CAAC,SAAS;SACtC,CAAC;IACJ,CAAC;CACF;AAlED,wCAkEC","sourcesContent":["import type { IncomingMessage, ServerResponse } from 'node:http';\nimport { getLoggerFor } from 'global-logger-factory';\nimport type { Authenticator } from '../auth/Authenticator';\nimport type { AuthContext } from '../auth/AuthContext';\n\n/**\n * Extended request with auth context\n */\nexport interface AuthenticatedRequest extends IncomingMessage {\n auth?: AuthContext;\n}\n\nexport interface AuthMiddlewareOptions {\n authenticator: Authenticator;\n /**\n * Paths that do not require authentication\n */\n publicPaths?: string[];\n}\n\n/**\n * Middleware that handles authentication for API requests\n */\nexport class AuthMiddleware {\n private readonly logger = getLoggerFor(this);\n private readonly authenticator: Authenticator;\n private readonly publicPaths: Set<string>;\n\n public constructor(options: AuthMiddlewareOptions) {\n this.authenticator = options.authenticator;\n this.publicPaths = new Set(options.publicPaths ?? []);\n }\n\n /**\n * Check if a path is public (does not require authentication)\n */\n public isPublicPath(path: string): boolean {\n // Normalize path by removing query string\n const normalizedPath = path.split('?')[0];\n return this.publicPaths.has(normalizedPath);\n }\n\n /**\n * Process the request, adding auth context if authenticated\n * Returns true if request should continue, false if response was sent\n */\n public async process(request: AuthenticatedRequest, response: ServerResponse): Promise<boolean> {\n // Check for authorization header\n if (!request.headers.authorization) {\n this.sendUnauthorized(response, 'Authentication required');\n return false;\n }\n\n // Attempt authentication\n const result = await this.authenticator.authenticate(request);\n\n this.logger.debug(\n `Auth ${request.method} ${request.url} success=${result.success}` +\n (result.error ? ` error=${result.error}` : '') +\n (result.context ? ` context=${JSON.stringify(this.safeContextForLog(result.context))}` : ''),\n );\n\n if (!result.success) {\n this.sendUnauthorized(response, result.error ?? 'Authentication failed');\n return false;\n }\n\n // Attach auth context to request\n request.auth = result.context;\n return true;\n }\n\n private sendUnauthorized(response: ServerResponse, message: string): void {\n response.statusCode = 401;\n response.setHeader('Content-Type', 'application/json');\n response.setHeader('WWW-Authenticate', 'Bearer, DPoP');\n response.end(JSON.stringify({ error: 'Unauthorized', message }));\n }\n\n private safeContextForLog(context: AuthContext): Record<string, unknown> {\n return {\n type: (context as any).type,\n webId: (context as any).webId,\n accountId: (context as any).accountId,\n clientId: (context as any).clientId,\n tokenType: (context as any).tokenType,\n viaApiKey: (context as any).viaApiKey,\n };\n }\n}\n"]}
@@ -15,11 +15,21 @@ function getProtocolMetadata(metadata, namespace) {
15
15
  return undefined;
16
16
  }
17
17
  const protocols = metadata[PROTOCOL_METADATA_KEY];
18
- if (!isRecord(protocols)) {
19
- return undefined;
18
+ if (Array.isArray(protocols)) {
19
+ const merged = protocols.reduce((acc, entry) => {
20
+ if (!isRecord(entry)) {
21
+ return acc;
22
+ }
23
+ const namespaced = entry[namespace];
24
+ return isRecord(namespaced) ? { ...acc, ...namespaced } : acc;
25
+ }, {});
26
+ return Object.keys(merged).length > 0 ? merged : undefined;
27
+ }
28
+ if (isRecord(protocols)) {
29
+ const namespaced = protocols[namespace];
30
+ return isRecord(namespaced) ? namespaced : undefined;
20
31
  }
21
- const namespaced = protocols[namespace];
22
- return isRecord(namespaced) ? namespaced : undefined;
32
+ return undefined;
23
33
  }
24
34
  function withProtocolMetadata(metadata, namespace, values) {
25
35
  const base = metadata ?? {};
@@ -1 +1 @@
1
- {"version":3,"file":"protocol-metadata.js","sourceRoot":"","sources":["../../src/api/protocol-metadata.ts"],"names":[],"mappings":";;AAcA,kDAeC;AAED,oDAwBC;AAED,sEAcC;AArED,MAAM,qBAAqB,GAAG,WAAW,CAAC;AAE1C,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,cAAc,CAAC,MAAwB;IAC9C,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAClE,CAAC;AACJ,CAAC;AAED,SAAgB,mBAAmB,CACjC,QAA6C,EAC7C,SAAiB;IAEjB,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,SAAS,GAAG,QAAQ,CAAC,qBAAqB,CAAC,CAAC;IAClD,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QACzB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,UAAU,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;IACxC,OAAO,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC;AACvD,CAAC;AAED,SAAgB,oBAAoB,CAClC,QAA6C,EAC7C,SAAiB,EACjB,MAAwB;IAExB,MAAM,IAAI,GAAG,QAAQ,IAAI,EAAE,CAAC;IAC5B,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QACrD,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAqB;QACjD,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,OAAO,GAAG,QAAQ,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QAC5C,CAAC,CAAC,SAAS,CAAC,SAAS,CAAqB;QAC1C,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,IAAI,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IAEpC,OAAO;QACL,GAAG,IAAI;QACP,CAAC,qBAAqB,CAAC,EAAE;YACvB,GAAG,SAAS;YACZ,CAAC,SAAS,CAAC,EAAE;gBACX,GAAG,OAAO;gBACV,GAAG,IAAI;aACR;SACF;KACF,CAAC;AACJ,CAAC;AAED,SAAgB,6BAA6B,CAC3C,QAA6C,EAC7C,IAAuB;IAEvB,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,MAAM,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;IAC/B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AAC7D,CAAC","sourcesContent":["export type ProtocolMetadata = Record<string, unknown>;\n\nconst PROTOCOL_METADATA_KEY = 'protocols';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction definedEntries(values: ProtocolMetadata): ProtocolMetadata {\n return Object.fromEntries(\n Object.entries(values).filter(([, value]) => value !== undefined),\n );\n}\n\nexport function getProtocolMetadata(\n metadata: ProtocolMetadata | null | undefined,\n namespace: string,\n): ProtocolMetadata | undefined {\n if (!metadata) {\n return undefined;\n }\n\n const protocols = metadata[PROTOCOL_METADATA_KEY];\n if (!isRecord(protocols)) {\n return undefined;\n }\n\n const namespaced = protocols[namespace];\n return isRecord(namespaced) ? namespaced : undefined;\n}\n\nexport function withProtocolMetadata(\n metadata: ProtocolMetadata | null | undefined,\n namespace: string,\n values: ProtocolMetadata,\n): ProtocolMetadata {\n const base = metadata ?? {};\n const protocols = isRecord(base[PROTOCOL_METADATA_KEY])\n ? base[PROTOCOL_METADATA_KEY] as ProtocolMetadata\n : {};\n const current = isRecord(protocols[namespace])\n ? protocols[namespace] as ProtocolMetadata\n : {};\n const next = definedEntries(values);\n\n return {\n ...base,\n [PROTOCOL_METADATA_KEY]: {\n ...protocols,\n [namespace]: {\n ...current,\n ...next,\n },\n },\n };\n}\n\nexport function withoutProtocolProjectionKeys(\n metadata: ProtocolMetadata | null | undefined,\n keys: readonly string[],\n): ProtocolMetadata | undefined {\n if (!metadata) {\n return undefined;\n }\n\n const result = { ...metadata };\n for (const key of keys) {\n delete result[key];\n }\n\n return Object.keys(result).length > 0 ? result : undefined;\n}\n"]}
1
+ {"version":3,"file":"protocol-metadata.js","sourceRoot":"","sources":["../../src/api/protocol-metadata.ts"],"names":[],"mappings":";;AAcA,kDA0BC;AAED,oDAwBC;AAED,sEAcC;AAhFD,MAAM,qBAAqB,GAAG,WAAW,CAAC;AAE1C,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,cAAc,CAAC,MAAwB;IAC9C,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAClE,CAAC;AACJ,CAAC;AAED,SAAgB,mBAAmB,CACjC,QAA6C,EAC7C,SAAiB;IAEjB,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,SAAS,GAAG,QAAQ,CAAC,qBAAqB,CAAC,CAAC;IAClD,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAmB,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;YAC/D,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBACrB,OAAO,GAAG,CAAC;YACb,CAAC;YACD,MAAM,UAAU,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;YACpC,OAAO,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,GAAG,UAAU,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;QAChE,CAAC,EAAE,EAAE,CAAC,CAAC;QACP,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;IAC7D,CAAC;IAED,IAAI,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QACxB,MAAM,UAAU,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;QACxC,OAAO,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC;IACvD,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAgB,oBAAoB,CAClC,QAA6C,EAC7C,SAAiB,EACjB,MAAwB;IAExB,MAAM,IAAI,GAAG,QAAQ,IAAI,EAAE,CAAC;IAC5B,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QACrD,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAqB;QACjD,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,OAAO,GAAG,QAAQ,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QAC5C,CAAC,CAAC,SAAS,CAAC,SAAS,CAAqB;QAC1C,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,IAAI,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IAEpC,OAAO;QACL,GAAG,IAAI;QACP,CAAC,qBAAqB,CAAC,EAAE;YACvB,GAAG,SAAS;YACZ,CAAC,SAAS,CAAC,EAAE;gBACX,GAAG,OAAO;gBACV,GAAG,IAAI;aACR;SACF;KACF,CAAC;AACJ,CAAC;AAED,SAAgB,6BAA6B,CAC3C,QAA6C,EAC7C,IAAuB;IAEvB,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,MAAM,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;IAC/B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AAC7D,CAAC","sourcesContent":["export type ProtocolMetadata = Record<string, unknown>;\n\nconst PROTOCOL_METADATA_KEY = 'protocols';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction definedEntries(values: ProtocolMetadata): ProtocolMetadata {\n return Object.fromEntries(\n Object.entries(values).filter(([, value]) => value !== undefined),\n );\n}\n\nexport function getProtocolMetadata(\n metadata: ProtocolMetadata | null | undefined,\n namespace: string,\n): ProtocolMetadata | undefined {\n if (!metadata) {\n return undefined;\n }\n\n const protocols = metadata[PROTOCOL_METADATA_KEY];\n if (Array.isArray(protocols)) {\n const merged = protocols.reduce<ProtocolMetadata>((acc, entry) => {\n if (!isRecord(entry)) {\n return acc;\n }\n const namespaced = entry[namespace];\n return isRecord(namespaced) ? { ...acc, ...namespaced } : acc;\n }, {});\n return Object.keys(merged).length > 0 ? merged : undefined;\n }\n\n if (isRecord(protocols)) {\n const namespaced = protocols[namespace];\n return isRecord(namespaced) ? namespaced : undefined;\n }\n\n return undefined;\n}\n\nexport function withProtocolMetadata(\n metadata: ProtocolMetadata | null | undefined,\n namespace: string,\n values: ProtocolMetadata,\n): ProtocolMetadata {\n const base = metadata ?? {};\n const protocols = isRecord(base[PROTOCOL_METADATA_KEY])\n ? base[PROTOCOL_METADATA_KEY] as ProtocolMetadata\n : {};\n const current = isRecord(protocols[namespace])\n ? protocols[namespace] as ProtocolMetadata\n : {};\n const next = definedEntries(values);\n\n return {\n ...base,\n [PROTOCOL_METADATA_KEY]: {\n ...protocols,\n [namespace]: {\n ...current,\n ...next,\n },\n },\n };\n}\n\nexport function withoutProtocolProjectionKeys(\n metadata: ProtocolMetadata | null | undefined,\n keys: readonly string[],\n): ProtocolMetadata | undefined {\n if (!metadata) {\n return undefined;\n }\n\n const result = { ...metadata };\n for (const key of keys) {\n delete result[key];\n }\n\n return Object.keys(result).length > 0 ? result : undefined;\n}\n"]}
@@ -7,6 +7,7 @@ exports.requireAuthContext = requireAuthContext;
7
7
  exports.authFetch = authFetch;
8
8
  const solid_auth_1 = require("./solid-auth");
9
9
  const credentials_store_1 = require("./credentials-store");
10
+ const oidc_auth_1 = require("./oidc-auth");
10
11
  const output_1 = require("./output");
11
12
  function normalizeBaseUrl(url) {
12
13
  return url.endsWith('/') ? url : `${url}/`;
@@ -45,13 +46,15 @@ async function requireAuthContext(options = {}) {
45
46
  if (!credentials) {
46
47
  throw new output_1.CliCommandError('auth_required', 'No credentials found. Run `xpod auth login` first.', 2);
47
48
  }
48
- const clientCredentials = (0, credentials_store_1.getClientCredentials)(credentials);
49
- if (!clientCredentials) {
50
- throw new output_1.CliCommandError('auth_unsupported', 'Stored OAuth credentials are not supported for CLI resource operations yet. Run `xpod auth login` to create client credentials.', 2);
51
- }
52
49
  const baseUrl = normalizeBaseUrl(options.url ?? credentials.url);
53
- const tokenResult = await (0, solid_auth_1.getAccessToken)(clientCredentials.clientId, clientCredentials.clientSecret, baseUrl);
54
- if (!tokenResult) {
50
+ const clientCredentials = (0, credentials_store_1.getClientCredentials)(credentials);
51
+ const oauthCredentials = (0, credentials_store_1.getOAuthCredentials)(credentials);
52
+ const accessToken = clientCredentials
53
+ ? (await (0, solid_auth_1.getAccessToken)(clientCredentials.clientId, clientCredentials.clientSecret, baseUrl))?.accessToken
54
+ : oauthCredentials
55
+ ? await (0, oidc_auth_1.getOidcAccessToken)(credentials)
56
+ : null;
57
+ if (!accessToken) {
55
58
  throw new output_1.CliCommandError('auth_failed', 'Failed to obtain an access token. Run `xpod auth login` again.', 2);
56
59
  }
57
60
  const podRoot = resolvePodRootFromWebId(credentials.webId);
@@ -60,7 +63,7 @@ async function requireAuthContext(options = {}) {
60
63
  webId: credentials.webId,
61
64
  podRoot,
62
65
  baseIri: podRoot,
63
- accessToken: tokenResult.accessToken,
66
+ accessToken,
64
67
  credentials,
65
68
  };
66
69
  }
@@ -1 +1 @@
1
- {"version":3,"file":"auth-context.js","sourceRoot":"","sources":["../../../src/cli/lib/auth-context.ts"],"names":[],"mappings":"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","sourcesContent":["import { getAccessToken, authenticatedFetch } from './solid-auth';\nimport {\n getClientCredentials,\n loadCredentials,\n type StoredCredentials,\n} from './credentials-store';\nimport { CliCommandError } from './output';\n\nexport interface CliAuthContext {\n baseUrl: string;\n webId: string;\n podRoot: string;\n baseIri: string;\n accessToken: string;\n credentials: StoredCredentials;\n}\n\nexport interface AuthStatus {\n authenticated: boolean;\n authType?: string;\n baseUrl?: string;\n webId?: string;\n podRoot?: string;\n}\n\nexport function normalizeBaseUrl(url: string): string {\n return url.endsWith('/') ? url : `${url}/`;\n}\n\nexport function resolvePodRootFromWebId(webId: string): string {\n const webIdUrl = new URL(webId);\n const path = webIdUrl.pathname;\n const profileSuffix = '/profile/card';\n if (path.endsWith(profileSuffix)) {\n const podPath = path.slice(0, -profileSuffix.length);\n return `${webIdUrl.origin}${podPath.endsWith('/') ? podPath : `${podPath}/`}`;\n }\n\n const pathParts = path.split('/').filter(Boolean);\n if (pathParts.length > 0) {\n return `${webIdUrl.origin}/${pathParts[0]}/`;\n }\n return `${webIdUrl.origin}/`;\n}\n\nexport function getStoredAuthStatus(urlOverride?: string): AuthStatus {\n const credentials = loadCredentials();\n if (!credentials) {\n return { authenticated: false };\n }\n\n const baseUrl = normalizeBaseUrl(urlOverride ?? credentials.url);\n const podRoot = resolvePodRootFromWebId(credentials.webId);\n return {\n authenticated: true,\n authType: credentials.authType,\n baseUrl,\n webId: credentials.webId,\n podRoot,\n };\n}\n\nexport async function requireAuthContext(options: {\n url?: string;\n json?: boolean;\n} = {}): Promise<CliAuthContext> {\n const credentials = loadCredentials();\n if (!credentials) {\n throw new CliCommandError(\n 'auth_required',\n 'No credentials found. Run `xpod auth login` first.',\n 2,\n );\n }\n\n const clientCredentials = getClientCredentials(credentials);\n if (!clientCredentials) {\n throw new CliCommandError(\n 'auth_unsupported',\n 'Stored OAuth credentials are not supported for CLI resource operations yet. Run `xpod auth login` to create client credentials.',\n 2,\n );\n }\n\n const baseUrl = normalizeBaseUrl(options.url ?? credentials.url);\n const tokenResult = await getAccessToken(\n clientCredentials.clientId,\n clientCredentials.clientSecret,\n baseUrl,\n );\n if (!tokenResult) {\n throw new CliCommandError(\n 'auth_failed',\n 'Failed to obtain an access token. Run `xpod auth login` again.',\n 2,\n );\n }\n\n const podRoot = resolvePodRootFromWebId(credentials.webId);\n return {\n baseUrl,\n webId: credentials.webId,\n podRoot,\n baseIri: podRoot,\n accessToken: tokenResult.accessToken,\n credentials,\n };\n}\n\nexport async function authFetch(\n context: CliAuthContext,\n url: string,\n init?: RequestInit,\n): Promise<Response> {\n return authenticatedFetch(url, context.accessToken, init);\n}\n"]}
1
+ {"version":3,"file":"auth-context.js","sourceRoot":"","sources":["../../../src/cli/lib/auth-context.ts"],"names":[],"mappings":"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","sourcesContent":["import { getAccessToken, authenticatedFetch } from './solid-auth';\nimport {\n getClientCredentials,\n getOAuthCredentials,\n loadCredentials,\n type StoredCredentials,\n} from './credentials-store';\nimport { getOidcAccessToken } from './oidc-auth';\nimport { CliCommandError } from './output';\n\nexport interface CliAuthContext {\n baseUrl: string;\n webId: string;\n podRoot: string;\n baseIri: string;\n accessToken: string;\n credentials: StoredCredentials;\n}\n\nexport interface AuthStatus {\n authenticated: boolean;\n authType?: string;\n baseUrl?: string;\n webId?: string;\n podRoot?: string;\n}\n\nexport function normalizeBaseUrl(url: string): string {\n return url.endsWith('/') ? url : `${url}/`;\n}\n\nexport function resolvePodRootFromWebId(webId: string): string {\n const webIdUrl = new URL(webId);\n const path = webIdUrl.pathname;\n const profileSuffix = '/profile/card';\n if (path.endsWith(profileSuffix)) {\n const podPath = path.slice(0, -profileSuffix.length);\n return `${webIdUrl.origin}${podPath.endsWith('/') ? podPath : `${podPath}/`}`;\n }\n\n const pathParts = path.split('/').filter(Boolean);\n if (pathParts.length > 0) {\n return `${webIdUrl.origin}/${pathParts[0]}/`;\n }\n return `${webIdUrl.origin}/`;\n}\n\nexport function getStoredAuthStatus(urlOverride?: string): AuthStatus {\n const credentials = loadCredentials();\n if (!credentials) {\n return { authenticated: false };\n }\n\n const baseUrl = normalizeBaseUrl(urlOverride ?? credentials.url);\n const podRoot = resolvePodRootFromWebId(credentials.webId);\n return {\n authenticated: true,\n authType: credentials.authType,\n baseUrl,\n webId: credentials.webId,\n podRoot,\n };\n}\n\nexport async function requireAuthContext(options: {\n url?: string;\n json?: boolean;\n} = {}): Promise<CliAuthContext> {\n const credentials = loadCredentials();\n if (!credentials) {\n throw new CliCommandError(\n 'auth_required',\n 'No credentials found. Run `xpod auth login` first.',\n 2,\n );\n }\n\n const baseUrl = normalizeBaseUrl(options.url ?? credentials.url);\n const clientCredentials = getClientCredentials(credentials);\n const oauthCredentials = getOAuthCredentials(credentials);\n const accessToken = clientCredentials\n ? (await getAccessToken(\n clientCredentials.clientId,\n clientCredentials.clientSecret,\n baseUrl,\n ))?.accessToken\n : oauthCredentials\n ? await getOidcAccessToken(credentials)\n : null;\n\n if (!accessToken) {\n throw new CliCommandError(\n 'auth_failed',\n 'Failed to obtain an access token. Run `xpod auth login` again.',\n 2,\n );\n }\n\n const podRoot = resolvePodRootFromWebId(credentials.webId);\n return {\n baseUrl,\n webId: credentials.webId,\n podRoot,\n baseIri: podRoot,\n accessToken,\n credentials,\n };\n}\n\nexport async function authFetch(\n context: CliAuthContext,\n url: string,\n init?: RequestInit,\n): Promise<Response> {\n return authenticatedFetch(url, context.accessToken, init);\n}\n"]}
@@ -1,17 +1,19 @@
1
1
  /**
2
- * CLI Authentication Helper
2
+ * Legacy client-credentials authentication helper.
3
3
  *
4
- * 统一的认证入口。所有 Solid app 只从 `$SOLID_HOME/auth/credentials.json`
5
- * 这一套 shared Solid auth source 恢复权限;`~/.xpod/config.json` /
6
- * `~/.xpod/secrets.json` 不是 Solid auth source。
4
+ * Descriptor/resource/rdf/secret CLI commands use `auth-context.ts`, which
5
+ * supports both shared Solid OAuth sessions and client credentials. Keep this
6
+ * helper only for legacy callers that explicitly need a Solid Node Session from
7
+ * client credentials.
7
8
  */
8
9
  import { type PodAuth } from './solid-auth';
9
10
  /**
10
- * 获取认证信息
11
+ * 获取 client-credentials 认证信息。
11
12
  *
12
13
  * 规则:
13
14
  * 1. 只读取 shared Solid auth source:$SOLID_HOME/auth/credentials.json
14
- * 2. 如果没有,提示用户先运行 `xpod auth create-credentials`
15
+ * 2. OAuth credentials intentionally return null here; use auth-context for
16
+ * resource operations.
15
17
  *
16
18
  * @returns PodAuth 或 null(如果没有保存的 credentials)
17
19
  */
@@ -1,10 +1,11 @@
1
1
  "use strict";
2
2
  /**
3
- * CLI Authentication Helper
3
+ * Legacy client-credentials authentication helper.
4
4
  *
5
- * 统一的认证入口。所有 Solid app 只从 `$SOLID_HOME/auth/credentials.json`
6
- * 这一套 shared Solid auth source 恢复权限;`~/.xpod/config.json` /
7
- * `~/.xpod/secrets.json` 不是 Solid auth source。
5
+ * Descriptor/resource/rdf/secret CLI commands use `auth-context.ts`, which
6
+ * supports both shared Solid OAuth sessions and client credentials. Keep this
7
+ * helper only for legacy callers that explicitly need a Solid Node Session from
8
+ * client credentials.
8
9
  */
9
10
  Object.defineProperty(exports, "__esModule", { value: true });
10
11
  exports.getAuth = getAuth;
@@ -12,11 +13,12 @@ exports.requireAuth = requireAuth;
12
13
  const solid_auth_1 = require("./solid-auth");
13
14
  const credentials_store_1 = require("./credentials-store");
14
15
  /**
15
- * 获取认证信息
16
+ * 获取 client-credentials 认证信息。
16
17
  *
17
18
  * 规则:
18
19
  * 1. 只读取 shared Solid auth source:$SOLID_HOME/auth/credentials.json
19
- * 2. 如果没有,提示用户先运行 `xpod auth create-credentials`
20
+ * 2. OAuth credentials intentionally return null here; use auth-context for
21
+ * resource operations.
20
22
  *
21
23
  * @returns PodAuth 或 null(如果没有保存的 credentials)
22
24
  */
@@ -1 +1 @@
1
- {"version":3,"file":"auth-helper.js","sourceRoot":"","sources":["../../../src/cli/lib/auth-helper.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAcH,0BA8BC;AAOD,kCAUC;AA3DD,6CAA0D;AAC1D,2DAA2E;AAE3E;;;;;;;;GAQG;AACI,KAAK,UAAU,OAAO;IAC3B,MAAM,KAAK,GAAG,IAAA,mCAAe,GAAE,CAAC;IAEhC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,CAAC;IACd,CAAC;IAED,2BAA2B;IAC3B,IAAI,CAAC,IAAA,uCAAmB,EAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QACxC,OAAO,CAAC,KAAK,CAAC,+CAA+C,CAAC,CAAC;QAC/D,OAAO,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAC1D,OAAO,IAAI,CAAC;IACd,CAAC;IAED,2BAA2B;IAC3B,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,KAAK,CAAC,GAAG,CAAC;QAC7B,MAAM,IAAI,GAAG,MAAM,IAAA,yBAAY,EAC7B,KAAK,CAAC,OAAO,CAAC,QAAQ,EACtB,KAAK,CAAC,OAAO,CAAC,YAAY,EAC1B,UAAU,CACX,CAAC;QAEF,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;QAC/C,OAAO,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;QAC7D,OAAO,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAC1D,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;GAIG;AACI,KAAK,UAAU,WAAW;IAC/B,MAAM,IAAI,GAAG,MAAM,OAAO,EAAE,CAAC;IAE7B,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACrD,OAAO,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAC;QACvE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["/**\n * CLI Authentication Helper\n *\n * 统一的认证入口。所有 Solid app 只从 `$SOLID_HOME/auth/credentials.json`\n * 这一套 shared Solid auth source 恢复权限;`~/.xpod/config.json` /\n * `~/.xpod/secrets.json` 不是 Solid auth source。\n */\n\nimport { authenticate, type PodAuth } from './solid-auth';\nimport { loadCredentials, isClientCredentials } from './credentials-store';\n\n/**\n * 获取认证信息\n *\n * 规则:\n * 1. 只读取 shared Solid auth source:$SOLID_HOME/auth/credentials.json\n * 2. 如果没有,提示用户先运行 `xpod auth create-credentials`\n *\n * @returns PodAuth 或 null(如果没有保存的 credentials)\n */\nexport async function getAuth(): Promise<PodAuth | null> {\n const creds = loadCredentials();\n\n if (!creds) {\n return null;\n }\n\n // 检查是否是 client credentials\n if (!isClientCredentials(creds.secrets)) {\n console.error('Saved credentials are not client credentials.');\n console.error('Please run: xpod auth create-credentials');\n return null;\n }\n\n // 使用 client credentials 认证\n try {\n const oidcIssuer = creds.url;\n const auth = await authenticate(\n creds.secrets.clientId,\n creds.secrets.clientSecret,\n oidcIssuer,\n );\n\n return auth;\n } catch (error) {\n console.error('Authentication failed:', error);\n console.error('Your credentials may be expired or invalid.');\n console.error('Please run: xpod auth create-credentials');\n return null;\n }\n}\n\n/**\n * 获取认证信息,如果失败则退出进程\n *\n * @returns PodAuth\n */\nexport async function requireAuth(): Promise<PodAuth> {\n const auth = await getAuth();\n\n if (!auth) {\n console.error('\\nNo credentials found. Please run:');\n console.error(' xpod auth create-credentials --email your@email.com');\n process.exit(1);\n }\n\n return auth;\n}\n"]}
1
+ {"version":3,"file":"auth-helper.js","sourceRoot":"","sources":["../../../src/cli/lib/auth-helper.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;AAeH,0BA8BC;AAOD,kCAUC;AA5DD,6CAA0D;AAC1D,2DAA2E;AAE3E;;;;;;;;;GASG;AACI,KAAK,UAAU,OAAO;IAC3B,MAAM,KAAK,GAAG,IAAA,mCAAe,GAAE,CAAC;IAEhC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,CAAC;IACd,CAAC;IAED,2BAA2B;IAC3B,IAAI,CAAC,IAAA,uCAAmB,EAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QACxC,OAAO,CAAC,KAAK,CAAC,+CAA+C,CAAC,CAAC;QAC/D,OAAO,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAC1D,OAAO,IAAI,CAAC;IACd,CAAC;IAED,2BAA2B;IAC3B,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,KAAK,CAAC,GAAG,CAAC;QAC7B,MAAM,IAAI,GAAG,MAAM,IAAA,yBAAY,EAC7B,KAAK,CAAC,OAAO,CAAC,QAAQ,EACtB,KAAK,CAAC,OAAO,CAAC,YAAY,EAC1B,UAAU,CACX,CAAC;QAEF,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;QAC/C,OAAO,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;QAC7D,OAAO,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAC1D,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;GAIG;AACI,KAAK,UAAU,WAAW;IAC/B,MAAM,IAAI,GAAG,MAAM,OAAO,EAAE,CAAC;IAE7B,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACrD,OAAO,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAC;QACvE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["/**\n * Legacy client-credentials authentication helper.\n *\n * Descriptor/resource/rdf/secret CLI commands use `auth-context.ts`, which\n * supports both shared Solid OAuth sessions and client credentials. Keep this\n * helper only for legacy callers that explicitly need a Solid Node Session from\n * client credentials.\n */\n\nimport { authenticate, type PodAuth } from './solid-auth';\nimport { loadCredentials, isClientCredentials } from './credentials-store';\n\n/**\n * 获取 client-credentials 认证信息。\n *\n * 规则:\n * 1. 只读取 shared Solid auth source:$SOLID_HOME/auth/credentials.json\n * 2. OAuth credentials intentionally return null here; use auth-context for\n * resource operations.\n *\n * @returns PodAuth 或 null(如果没有保存的 credentials)\n */\nexport async function getAuth(): Promise<PodAuth | null> {\n const creds = loadCredentials();\n\n if (!creds) {\n return null;\n }\n\n // 检查是否是 client credentials\n if (!isClientCredentials(creds.secrets)) {\n console.error('Saved credentials are not client credentials.');\n console.error('Please run: xpod auth create-credentials');\n return null;\n }\n\n // 使用 client credentials 认证\n try {\n const oidcIssuer = creds.url;\n const auth = await authenticate(\n creds.secrets.clientId,\n creds.secrets.clientSecret,\n oidcIssuer,\n );\n\n return auth;\n } catch (error) {\n console.error('Authentication failed:', error);\n console.error('Your credentials may be expired or invalid.');\n console.error('Please run: xpod auth create-credentials');\n return null;\n }\n}\n\n/**\n * 获取认证信息,如果失败则退出进程\n *\n * @returns PodAuth\n */\nexport async function requireAuth(): Promise<PodAuth> {\n const auth = await getAuth();\n\n if (!auth) {\n console.error('\\nNo credentials found. Please run:');\n console.error(' xpod auth create-credentials --email your@email.com');\n process.exit(1);\n }\n\n return auth;\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import { type StoredCredentials } from './credentials-store';
2
+ export declare function getOidcAccessToken(credentials: StoredCredentials, options?: {
3
+ forceRefresh?: boolean;
4
+ }): Promise<string | null>;
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getOidcAccessToken = getOidcAccessToken;
4
+ const solid_client_authn_node_1 = require("@inrupt/solid-client-authn-node");
5
+ const credentials_store_1 = require("./credentials-store");
6
+ const oidc_session_storage_1 = require("./oidc-session-storage");
7
+ const TOKEN_EXPIRY_SKEW_MS = 60_000;
8
+ async function getOidcAccessToken(credentials, options = {}) {
9
+ const secrets = (0, credentials_store_1.getOAuthCredentials)(credentials);
10
+ if (!secrets)
11
+ return null;
12
+ if (!options.forceRefresh && isUsableAccessToken(secrets)) {
13
+ return secrets.oidcAccessToken;
14
+ }
15
+ return refreshStoredOidcSession(credentials, secrets);
16
+ }
17
+ function isUsableAccessToken(secrets) {
18
+ if (!secrets.oidcAccessToken)
19
+ return false;
20
+ const expiresAt = new Date(secrets.oidcExpiresAt).getTime();
21
+ return Number.isFinite(expiresAt) && expiresAt > Date.now() + TOKEN_EXPIRY_SKEW_MS;
22
+ }
23
+ async function refreshStoredOidcSession(credentials, secrets) {
24
+ const storage = (0, oidc_session_storage_1.createOidcSessionStorage)();
25
+ const sessionId = await resolveStoredOidcSessionId(storage, credentials.webId, credentials.url);
26
+ if (!sessionId)
27
+ return null;
28
+ const session = await (0, solid_client_authn_node_1.getSessionFromStorage)(sessionId, {
29
+ storage,
30
+ refreshSession: false,
31
+ });
32
+ if (!session)
33
+ return null;
34
+ let refreshedTokenSet = null;
35
+ session.events.on(solid_client_authn_node_1.EVENTS.NEW_TOKENS, (tokenSet) => {
36
+ refreshedTokenSet = tokenSet;
37
+ });
38
+ await (0, solid_client_authn_node_1.refreshSession)(session, { storage });
39
+ const nextTokenSet = refreshedTokenSet;
40
+ if (!nextTokenSet?.accessToken)
41
+ return null;
42
+ secrets.oidcRefreshToken = nextTokenSet.refreshToken ?? secrets.oidcRefreshToken;
43
+ secrets.oidcAccessToken = nextTokenSet.accessToken;
44
+ secrets.oidcExpiresAt = nextTokenSet.expiresAt
45
+ ? new Date(nextTokenSet.expiresAt * 1000).toISOString()
46
+ : secrets.oidcExpiresAt;
47
+ secrets.oidcClientId = nextTokenSet.clientId ?? secrets.oidcClientId;
48
+ (0, credentials_store_1.saveCredentials)({
49
+ url: credentials.url,
50
+ webId: session.info.webId ?? credentials.webId,
51
+ authType: 'oidc_oauth',
52
+ secrets,
53
+ });
54
+ return nextTokenSet.accessToken;
55
+ }
56
+ async function resolveStoredOidcSessionId(storage, webId, issuerUrl) {
57
+ const raw = await storage.get('solidClientAuthn:registeredSessions');
58
+ if (!raw)
59
+ return null;
60
+ let sessionIds = [];
61
+ try {
62
+ const parsed = JSON.parse(raw);
63
+ if (Array.isArray(parsed)) {
64
+ sessionIds = parsed.filter((value) => typeof value === 'string');
65
+ }
66
+ }
67
+ catch {
68
+ return null;
69
+ }
70
+ const normalizedIssuer = issuerUrl.replace(/\/+$/u, '');
71
+ for (const sessionId of [...sessionIds].reverse()) {
72
+ const stored = await storage.get(`solidClientAuthenticationUser:${sessionId}`);
73
+ if (!stored)
74
+ continue;
75
+ try {
76
+ const parsed = JSON.parse(stored);
77
+ const sessionWebId = typeof parsed.webId === 'string' ? parsed.webId : null;
78
+ const sessionIssuer = typeof parsed.issuer === 'string' ? parsed.issuer.replace(/\/+$/u, '') : null;
79
+ const sessionUsesDpop = parsed.dpop === true || parsed.dpop === 'true';
80
+ if (sessionWebId === webId && sessionIssuer === normalizedIssuer && !sessionUsesDpop) {
81
+ return sessionId;
82
+ }
83
+ }
84
+ catch {
85
+ continue;
86
+ }
87
+ }
88
+ return null;
89
+ }
90
+ //# sourceMappingURL=oidc-auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oidc-auth.js","sourceRoot":"","sources":["../../../src/cli/lib/oidc-auth.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n EVENTS,\n getSessionFromStorage,\n refreshSession,\n type SessionTokenSet,\n} from '@inrupt/solid-client-authn-node';\nimport {\n getOAuthCredentials,\n saveCredentials,\n type OidcOAuthSecrets,\n type StoredCredentials,\n} from './credentials-store';\nimport { createOidcSessionStorage } from './oidc-session-storage';\n\nconst TOKEN_EXPIRY_SKEW_MS = 60_000;\n\nexport async function getOidcAccessToken(\n credentials: StoredCredentials,\n options: { forceRefresh?: boolean } = {},\n): Promise<string | null> {\n const secrets = getOAuthCredentials(credentials);\n if (!secrets) return null;\n\n if (!options.forceRefresh && isUsableAccessToken(secrets)) {\n return secrets.oidcAccessToken;\n }\n\n return refreshStoredOidcSession(credentials, secrets);\n}\n\nfunction isUsableAccessToken(secrets: OidcOAuthSecrets): boolean {\n if (!secrets.oidcAccessToken) return false;\n const expiresAt = new Date(secrets.oidcExpiresAt).getTime();\n return Number.isFinite(expiresAt) && expiresAt > Date.now() + TOKEN_EXPIRY_SKEW_MS;\n}\n\nasync function refreshStoredOidcSession(\n credentials: StoredCredentials,\n secrets: OidcOAuthSecrets,\n): Promise<string | null> {\n const storage = createOidcSessionStorage();\n const sessionId = await resolveStoredOidcSessionId(storage, credentials.webId, credentials.url);\n if (!sessionId) return null;\n\n const session = await getSessionFromStorage(sessionId, {\n storage,\n refreshSession: false,\n });\n if (!session) return null;\n\n let refreshedTokenSet: SessionTokenSet | null = null;\n session.events.on(EVENTS.NEW_TOKENS, (tokenSet) => {\n refreshedTokenSet = tokenSet;\n });\n\n await refreshSession(session, { storage });\n\n const nextTokenSet = refreshedTokenSet as SessionTokenSet | null;\n if (!nextTokenSet?.accessToken) return null;\n\n secrets.oidcRefreshToken = nextTokenSet.refreshToken ?? secrets.oidcRefreshToken;\n secrets.oidcAccessToken = nextTokenSet.accessToken;\n secrets.oidcExpiresAt = nextTokenSet.expiresAt\n ? new Date(nextTokenSet.expiresAt * 1000).toISOString()\n : secrets.oidcExpiresAt;\n secrets.oidcClientId = nextTokenSet.clientId ?? secrets.oidcClientId;\n\n saveCredentials({\n url: credentials.url,\n webId: session.info.webId ?? credentials.webId,\n authType: 'oidc_oauth',\n secrets,\n });\n\n return nextTokenSet.accessToken;\n}\n\nasync function resolveStoredOidcSessionId(\n storage: ReturnType<typeof createOidcSessionStorage>,\n webId: string,\n issuerUrl: string,\n): Promise<string | null> {\n const raw = await storage.get('solidClientAuthn:registeredSessions');\n if (!raw) return null;\n\n let sessionIds: string[] = [];\n try {\n const parsed = JSON.parse(raw) as unknown;\n if (Array.isArray(parsed)) {\n sessionIds = parsed.filter((value): value is string => typeof value === 'string');\n }\n } catch {\n return null;\n }\n\n const normalizedIssuer = issuerUrl.replace(/\\/+$/u, '');\n for (const sessionId of [...sessionIds].reverse()) {\n const stored = await storage.get(`solidClientAuthenticationUser:${sessionId}`);\n if (!stored) continue;\n\n try {\n const parsed = JSON.parse(stored) as { webId?: string; issuer?: string; dpop?: string | boolean };\n const sessionWebId = typeof parsed.webId === 'string' ? parsed.webId : null;\n const sessionIssuer = typeof parsed.issuer === 'string' ? parsed.issuer.replace(/\\/+$/u, '') : null;\n const sessionUsesDpop = parsed.dpop === true || parsed.dpop === 'true';\n if (sessionWebId === webId && sessionIssuer === normalizedIssuer && !sessionUsesDpop) {\n return sessionId;\n }\n } catch {\n continue;\n }\n }\n\n return null;\n}\n"]}
@@ -0,0 +1,3 @@
1
+ import type { IStorage } from '@inrupt/solid-client-authn-node';
2
+ export declare function createOidcSessionStorage(): IStorage;
3
+ export declare function clearOidcSessionStorage(): void;
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createOidcSessionStorage = createOidcSessionStorage;
4
+ exports.clearOidcSessionStorage = clearOidcSessionStorage;
5
+ const fs_1 = require("fs");
6
+ const path_1 = require("path");
7
+ const credentials_store_1 = require("./credentials-store");
8
+ function storageDir() {
9
+ return (0, path_1.join)((0, credentials_store_1.getSolidAuthDir)(), 'oidc-storage');
10
+ }
11
+ function keyPath(key) {
12
+ return (0, path_1.join)(storageDir(), encodeURIComponent(key));
13
+ }
14
+ function createOidcSessionStorage() {
15
+ return {
16
+ async get(key) {
17
+ const path = keyPath(key);
18
+ if (!(0, fs_1.existsSync)(path))
19
+ return undefined;
20
+ return (0, fs_1.readFileSync)(path, 'utf-8');
21
+ },
22
+ async set(key, value) {
23
+ (0, fs_1.mkdirSync)(storageDir(), { recursive: true });
24
+ const path = keyPath(key);
25
+ (0, fs_1.writeFileSync)(path, value, 'utf-8');
26
+ (0, fs_1.chmodSync)(path, 0o600);
27
+ },
28
+ async delete(key) {
29
+ const path = keyPath(key);
30
+ if ((0, fs_1.existsSync)(path))
31
+ (0, fs_1.unlinkSync)(path);
32
+ },
33
+ };
34
+ }
35
+ function clearOidcSessionStorage() {
36
+ const dir = storageDir();
37
+ if ((0, fs_1.existsSync)(dir)) {
38
+ (0, fs_1.rmSync)(dir, { recursive: true, force: true });
39
+ }
40
+ }
41
+ //# sourceMappingURL=oidc-session-storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oidc-session-storage.js","sourceRoot":"","sources":["../../../src/cli/lib/oidc-session-storage.ts"],"names":[],"mappings":";;AAaA,4DAkBC;AAED,0DAKC;AAtCD,2BAAuG;AACvG,+BAA4B;AAE5B,2DAAsD;AAEtD,SAAS,UAAU;IACjB,OAAO,IAAA,WAAI,EAAC,IAAA,mCAAe,GAAE,EAAE,cAAc,CAAC,CAAC;AACjD,CAAC;AAED,SAAS,OAAO,CAAC,GAAW;IAC1B,OAAO,IAAA,WAAI,EAAC,UAAU,EAAE,EAAE,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC;AACrD,CAAC;AAED,SAAgB,wBAAwB;IACtC,OAAO;QACL,KAAK,CAAC,GAAG,CAAC,GAAW;YACnB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;YAC1B,IAAI,CAAC,IAAA,eAAU,EAAC,IAAI,CAAC;gBAAE,OAAO,SAAS,CAAC;YACxC,OAAO,IAAA,iBAAY,EAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACrC,CAAC;QACD,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,KAAa;YAClC,IAAA,cAAS,EAAC,UAAU,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC7C,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;YAC1B,IAAA,kBAAa,EAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;YACpC,IAAA,cAAS,EAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACzB,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,GAAW;YACtB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;YAC1B,IAAI,IAAA,eAAU,EAAC,IAAI,CAAC;gBAAE,IAAA,eAAU,EAAC,IAAI,CAAC,CAAC;QACzC,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAgB,uBAAuB;IACrC,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;IACzB,IAAI,IAAA,eAAU,EAAC,GAAG,CAAC,EAAE,CAAC;QACpB,IAAA,WAAM,EAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC;AACH,CAAC","sourcesContent":["import { chmodSync, existsSync, mkdirSync, readFileSync, rmSync, unlinkSync, writeFileSync } from 'fs';\nimport { join } from 'path';\nimport type { IStorage } from '@inrupt/solid-client-authn-node';\nimport { getSolidAuthDir } from './credentials-store';\n\nfunction storageDir(): string {\n return join(getSolidAuthDir(), 'oidc-storage');\n}\n\nfunction keyPath(key: string): string {\n return join(storageDir(), encodeURIComponent(key));\n}\n\nexport function createOidcSessionStorage(): IStorage {\n return {\n async get(key: string): Promise<string | undefined> {\n const path = keyPath(key);\n if (!existsSync(path)) return undefined;\n return readFileSync(path, 'utf-8');\n },\n async set(key: string, value: string): Promise<void> {\n mkdirSync(storageDir(), { recursive: true });\n const path = keyPath(key);\n writeFileSync(path, value, 'utf-8');\n chmodSync(path, 0o600);\n },\n async delete(key: string): Promise<void> {\n const path = keyPath(key);\n if (existsSync(path)) unlinkSync(path);\n },\n };\n}\n\nexport function clearOidcSessionStorage(): void {\n const dir = storageDir();\n if (existsSync(dir)) {\n rmSync(dir, { recursive: true, force: true });\n }\n}\n"]}
@@ -19,6 +19,7 @@ export declare class GatewayProxy {
19
19
  start(): Promise<void>;
20
20
  stop(): Promise<void>;
21
21
  private handleRequest;
22
+ private shouldRouteToApi;
22
23
  private shouldInspectRootMutation;
23
24
  private shouldRejectRootResourceMutation;
24
25
  private writeRootMutationForbidden;
@@ -142,7 +142,7 @@ class GatewayProxy {
142
142
  this.proxy.web(req, res, { target: this.toProxyTarget(this.targets.api) });
143
143
  return;
144
144
  }
145
- if ((url.startsWith('/v1/') || url.startsWith('/api/') || url.startsWith('/provision/')) && this.targets.api) {
145
+ if (this.shouldRouteToApi(url) && this.targets.api) {
146
146
  this.proxy.web(req, res, { target: this.toProxyTarget(this.targets.api) });
147
147
  return;
148
148
  }
@@ -164,6 +164,13 @@ class GatewayProxy {
164
164
  res.end('CSS Service Not Available');
165
165
  }
166
166
  }
167
+ shouldRouteToApi(url) {
168
+ return url.startsWith('/v1/')
169
+ || url.startsWith('/api/')
170
+ || url.startsWith('/provision/')
171
+ || url === '/.well-known/matrix/client'
172
+ || url.startsWith('/_matrix/');
173
+ }
167
174
  shouldInspectRootMutation(req) {
168
175
  const method = (req.method ?? 'GET').toUpperCase();
169
176
  if (!['POST', 'PUT', 'PATCH', 'DELETE'].includes(method)) {
@@ -1 +1 @@
1
- {"version":3,"file":"Proxy.js","sourceRoot":"","sources":["../../src/runtime/Proxy.ts"],"names":[],"mappings":";;;;;;AAAA,4DAAmC;AACnC,gDAAwB;AACxB,iEAAqD;AAErD,iEAA8D;AAa9D,uDAAuD;AACvD,MAAM,WAAW,GAAG;IAClB,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC;IACrE,WAAW,EAAE,IAAI;IACjB,cAAc,EAAE;QACd,eAAe,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ;QAC3D,kBAAkB,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM;KAChE;IACD,cAAc,EAAE;QACd,cAAc,EAAE,aAAa,EAAE,YAAY,EAAE,OAAO,EAAE,eAAe;QACrE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa;QAC1D,WAAW,EAAE,kBAAkB,EAAE,cAAc;KAChD;CACF,CAAC;AAEF,MAAa,YAAY;IAWvB,YACE,IAAwB,EAChB,UAAsB,EAC9B,QAAQ,GAAG,SAAS,EACpB,UAA+B,EAAE;QAFzB,eAAU,GAAV,UAAU,CAAY;QAZf,WAAM,GAAG,IAAA,oCAAY,EAAC,IAAI,CAAC,CAAC;QAGrC,YAAO,GAA2D,EAAE,CAAC;QAa3E,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,iCAAe,CAAC;QAC1D,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,IAAI,CAAC,WAAW,CAAC,oBAAoB,CAAC;YACpF,IAAI;YACJ,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,OAAO,CAAC,UAAU;SAC/B,CAAC,CAAC;QACH,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,KAAK,CAAC;QAC9C,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;QAC/C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAC/B,IAAI,CAAC,KAAK,GAAG,oBAAS,CAAC,iBAAiB,CAAC;YACvC,IAAI,EAAE,IAAI;SACX,CAAC,CAAC;QAEH,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;YACxC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;YACvC,IAAI,GAAG,IAAI,WAAW,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;gBAClD,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;gBAC3D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,qBAAqB,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YAClF,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;YAC/C,IAAI,CAAC,4BAA4B,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;YACjD,MAAM,kBAAkB,GAAG,GAAyB,CAAC;YACrD,MAAM,QAAQ,GAAG,GAA0B,CAAC;YAC5C,IAAI,CAAC,kBAAkB,CAAC,yBAAyB,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC;gBACvF,OAAO;YACT,CAAC;YAED,MAAM,MAAM,GAAa,EAAE,CAAC;YAC5B,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;gBAC5B,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YACnE,CAAC,CAAC,CAAC;YACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;gBACtB,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBAC3C,MAAM,SAAS,GAAG,IAAI,CAAC,kCAAkC,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;gBAClF,QAAQ,CAAC,SAAS,CAAC,SAAS,CAAC,UAAU,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;gBAC5D,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAC/B,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,GAAG,cAAI,CAAC,YAAY,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAE/D,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE;YAC9C,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC;YAE3B,kDAAkD;YAClD,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;gBAC/C,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAQ,EAAE,CAAC,CAAC;YAC5F,CAAC;iBAAM,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;gBAC5B,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAQ,EAAE,CAAC,CAAC;YAC5F,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,UAAU,CAAC,OAAiF;QACjG,IAAI,CAAC,OAAO,GAAG;YACb,GAAG,EAAE,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC;YACtC,GAAG,EAAE,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC;SACvC,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,KAAK;QAChB,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAChE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,IAAI,CAAC,WAAW,CAAC,oBAAoB,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;IACjG,CAAC;IAEM,IAAI;QACT,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACnB,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;gBACjE,OAAO,EAAE,CAAC;YACZ,CAAC,EAAE,MAAM,CAAC,CAAC;QACb,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,aAAa,CAAC,GAAyB,EAAE,GAAwB;QACvE,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC;QAC3B,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC;QAElC,+DAA+D;QAC/D,MAAM,YAAY,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC;QAEtC,8CAA8C;QAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC;QAC/D,IAAI,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAChC,GAAG,CAAC,OAAO,CAAC,mBAAmB,CAAC,GAAG,OAAO,CAAC;QAC7C,CAAC;QAED,+DAA+D;QAC/D,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC;gBACH,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;gBACvC,GAAG,CAAC,OAAO,CAAC,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC;gBACtC,GAAG,CAAC,OAAO,CAAC,kBAAkB,CAAC,GAAG,aAAa,CAAC,IAAI,CAAC;YACvD,CAAC;YAAC,MAAM,CAAC;gBACP,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE,CAAC;oBACrC,GAAG,CAAC,OAAO,CAAC,kBAAkB,CAAC,GAAG,YAAY,CAAC;gBACjD,CAAC;YACH,CAAC;QACH,CAAC;aAAM,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE,CAAC;YAC5C,GAAG,CAAC,OAAO,CAAC,kBAAkB,CAAC,GAAG,YAAY,CAAC;QACjD,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,GAAG,GAAG,CAAC,MAAM,IAAI,GAAG,sBAAsB,GAAG,CAAC,OAAO,CAAC,mBAAmB,CAAC,qBAAqB,GAAG,CAAC,OAAO,CAAC,kBAAkB,CAAC,SAAS,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAC1J,CAAC;QAEF,gCAAgC;QAChC,IAAI,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAChC,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC7B,IAAI,CAAC,0BAA0B,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;gBAC7C,OAAO;YACT,CAAC;YACD,IAAI,MAAM,EAAE,CAAC;gBACX,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YACnC,CAAC;YACD,KAAK,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YACtC,OAAO;QACT,CAAC;QAED,sCAAsC;QAEtC,8DAA8D;QAC9D,IAAI,CAAC,GAAG,KAAK,YAAY,IAAI,GAAG,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;YAChF,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAQ,EAAE,CAAC,CAAC;YAClF,OAAO;QACT,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;YAC7G,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAQ,EAAE,CAAC,CAAC;YAClF,OAAO;QACT,CAAC;QAED,2BAA2B;QAC3B,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;YACrB,IAAI,IAAI,CAAC,gCAAgC,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC/C,IAAI,CAAC,0BAA0B,CAAC,GAAG,CAAC,CAAC;gBACrC,OAAO;YACT,CAAC;YAED,MAAM,kBAAkB,GAAG,GAAyB,CAAC;YACrD,kBAAkB,CAAC,yBAAyB,GAAG,IAAI,CAAC,yBAAyB,CAAC,GAAG,CAAC,CAAC;YACnF,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE;gBACvB,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAQ;gBACnD,GAAG,CAAC,kBAAkB,CAAC,yBAAyB,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC/E,CAAC,CAAC;QACZ,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YACnB,GAAG,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IAEO,yBAAyB,CAAC,GAAyB;QACzD,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;QACnD,IAAI,CAAC,CAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3D,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,kBAAkB,CAAC,CAAC,QAAQ,CAAC;QACtE,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACrD,OAAO,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAC/D,CAAC;IAEO,gCAAgC,CAAC,GAAyB;QAChE,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;QACnD,IAAI,CAAC,CAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3D,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,kBAAkB,CAAC,CAAC,QAAQ,CAAC;QACtE,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACrD,OAAO,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC1F,CAAC;IAEO,0BAA0B,CAAC,GAAwB;QACzD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,+BAA+B,EAAE,CAAC,CAAC,CAAC;QACjF,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;YACjB,cAAc,EAAE,kBAAkB;YAClC,gBAAgB,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC;SAC1C,CAAC,CAAC;QACH,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC;IAEO,kCAAkC,CACxC,QAA8B,EAC9B,IAAY;QAEZ,MAAM,OAAO,GAA6B,EAAE,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC;QAClE,MAAM,UAAU,GAAG,QAAQ,CAAC,UAAU,IAAI,GAAG,CAAC;QAC9C,MAAM,WAAW,GAAG,OAAO,QAAQ,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK,QAAQ;YACtE,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,cAAc,CAAC;YAClC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;gBAC/C,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;gBAC3C,CAAC,CAAC,EAAE,CAAC;QACT,MAAM,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAEvF,IACE,UAAU,KAAK,GAAG;YAClB,QAAQ,CAAC,QAAQ,CAAC,6BAA6B,CAAC;YAChD,QAAQ,CAAC,QAAQ,CAAC,gCAAgC,CAAC,EACnD,CAAC;YACD,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,+BAA+B,EAAE,CAAC,CAAC,CAAC;YAC3F,OAAO,OAAO,CAAC,gBAAgB,CAAC,CAAC;YACjC,OAAO,OAAO,CAAC,mBAAmB,CAAC,CAAC;YACpC,OAAO,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAC;YAC7C,OAAO,CAAC,gBAAgB,CAAC,GAAG,MAAM,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;YAC9D,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC;QAC5D,CAAC;QAED,OAAO,OAAO,CAAC,mBAAmB,CAAC,CAAC;QACpC,OAAO,CAAC,gBAAgB,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACpD,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IACvC,CAAC;IAEO,+BAA+B;QACrC,OAAO;YACL,IAAI,EAAE,oBAAoB;YAC1B,OAAO,EAAE,sCAAsC;YAC/C,UAAU,EAAE,GAAG;YACf,SAAS,EAAE,MAAM;YACjB,OAAO,EAAE,EAAE,KAAK,EAAE,sBAAsB,EAAE;SAC3C,CAAC;IACJ,CAAC;IAEO,4BAA4B,CAAC,GAAyB,EAAE,QAA8B;QAC5F,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;QACnD,MAAM,UAAU,GAAG,QAAQ,CAAC,UAAU,IAAI,GAAG,CAAC;QAC9C,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAwD,CAAC;QAClF,MAAM,gBAAgB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;QACtD,MAAM,mBAAmB,GAAG,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC;YACzD,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YAC3E,CAAC,CAAC,OAAO,gBAAgB,KAAK,QAAQ;gBACpC,CAAC,CAAC,gBAAgB,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;gBACpD,CAAC,CAAC,KAAK,CAAC;QAEZ,IAAI,MAAM,KAAK,MAAM,IAAI,UAAU,KAAK,GAAG,IAAI,UAAU,KAAK,GAAG,IAAI,CAAC,UAAU,IAAI,GAAG,IAAI,UAAU,GAAG,GAAG,CAAC,EAAE,CAAC;YAC7G,OAAO,OAAO,CAAC,mBAAmB,CAAC,CAAC;YACpC,OAAO;QACT,CAAC;QAED,IAAI,mBAAmB,IAAI,OAAO,CAAC,gBAAgB,CAAC,KAAK,SAAS,EAAE,CAAC;YACnE,OAAO,OAAO,CAAC,gBAAgB,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IAEO,0BAA0B,CAChC,GAAwB,EACxB,MAA0B;QAE1B,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACjC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QACnB,GAAG,CAAC,GAAG,EAAE,CAAC;IACZ,CAAC;IAED;;OAEG;IACK,cAAc,CAAC,GAAwB,EAAE,MAA0B;QACzE,GAAG,CAAC,SAAS,CAAC,6BAA6B,EAAE,MAAM,IAAI,GAAG,CAAC,CAAC;QAC5D,GAAG,CAAC,SAAS,CAAC,kCAAkC,EAAE,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC;QACnF,GAAG,CAAC,SAAS,CAAC,8BAA8B,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC9E,GAAG,CAAC,SAAS,CAAC,8BAA8B,EAAE,WAAW,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACrF,GAAG,CAAC,SAAS,CAAC,+BAA+B,EAAE,WAAW,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACxF,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAC,GAAyB,EAAE,GAAwB;QACjF,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC;YAC9B,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;YACnD,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;YAEjC,IAAI,QAAQ,KAAK,iBAAiB,EAAE,CAAC;gBACnC,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,CAAC;gBAC9C,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;gBACzC,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;gBAClC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;gBAC5D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;gBAChC,OAAO;YACT,CAAC;YAED,IAAI,QAAQ,KAAK,eAAe,EAAE,CAAC;gBACjC,MAAM,KAAK,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,SAAS,CAAC;gBAC5D,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,SAAS,CAAC;gBAC9D,MAAM,UAAU,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBACpD,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;gBAEhE,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;oBACnC,KAAK;oBACL,MAAM;oBACN,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,KAAe,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;iBAC5D,CAAC,CAAC;gBAEH,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;gBAC3D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;gBAC9B,OAAO;YACT,CAAC;YAED,IAAI,QAAQ,KAAK,eAAe,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;gBAC1D,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;gBAC3D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;gBACtC,YAAY,CAAC,GAAG,EAAE;oBAChB,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;oBAC3E,KAAK,QAAQ,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;wBACxB,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;4BACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;wBAClB,CAAC;oBACH,CAAC,CAAC,CAAC;gBACL,CAAC,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YAED,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YACnB,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACvB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,mCAAmC,EAAE,KAAK,CAAC,CAAC;YAC9D,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;gBACrB,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;YAC7D,CAAC;YACD,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,uBAAuB,EAAE,CAAC,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,UAAU;QACtB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;YACtB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,IAAI,CAAC,WAAW,CAAC,uBAAuB,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC3E,CAAC;IAEO,eAAe,CAAC,MAAoC;QAC1D,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC/B,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;QACzB,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,aAAa,CAAC,MAA0B;QAC9C,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACtB,OAAO;gBACL,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,QAAQ,EAAE,OAAO;aAClB,CAAC;QACJ,CAAC;QACD,OAAO,MAAM,CAAC,GAAI,CAAC;IACrB,CAAC;CACF;AAjXD,oCAiXC","sourcesContent":["import httpProxy from 'http-proxy';\nimport http from 'http';\nimport { getLoggerFor } from 'global-logger-factory';\nimport type { Supervisor } from '../supervisor/Supervisor';\nimport { nodeRuntimeHost } from './host/node/NodeRuntimeHost';\nimport type { RuntimeHost, RuntimeListenEndpoint } from './host/types';\n\ntype InterceptedRequest = http.IncomingMessage & { __xpodInspectRootMutation?: boolean };\n\ninterface RootMutationForbiddenBody {\n name: 'ForbiddenHttpError';\n message: string;\n statusCode: 403;\n errorCode: 'H403';\n details: { cause: 'root-container-write' };\n}\n\n// CORS configuration matching CSS CorsHandler defaults\nconst CORS_CONFIG = {\n methods: ['GET', 'HEAD', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE'],\n credentials: true,\n allowedHeaders: [\n 'Authorization', 'Content-Type', 'Accept', 'DPoP', 'Origin',\n 'X-Requested-With', 'If-Match', 'If-None-Match', 'Slug', 'Link',\n ],\n exposedHeaders: [\n 'Accept-Patch', 'Accept-Post', 'Accept-Put', 'Allow', 'Content-Range',\n 'ETag', 'Last-Modified', 'Link', 'Location', 'Updates-Via',\n 'WAC-Allow', 'Www-Authenticate', 'X-Request-Id',\n ],\n};\n\nexport class GatewayProxy {\n private readonly logger = getLoggerFor(this);\n private proxy: httpProxy;\n private server: http.Server;\n private targets: { css?: GatewayProxyTarget; api?: GatewayProxyTarget } = {};\n private readonly runtimeHost: RuntimeHost;\n private readonly listenEndpoint: RuntimeListenEndpoint;\n private readonly exitOnStop: boolean;\n private readonly shutdownHandler?: () => Promise<void>;\n private readonly baseUrl?: string;\n\n constructor(\n port: number | undefined,\n private supervisor: Supervisor,\n bindHost = '0.0.0.0',\n options: GatewayProxyOptions = {},\n ) {\n this.runtimeHost = options.runtimeHost ?? nodeRuntimeHost;\n this.listenEndpoint = options.listenEndpoint ?? this.runtimeHost.createListenEndpoint({\n port,\n host: bindHost,\n socketPath: options.socketPath,\n });\n this.exitOnStop = options.exitOnStop ?? false;\n this.shutdownHandler = options.shutdownHandler;\n this.baseUrl = options.baseUrl;\n this.proxy = httpProxy.createProxyServer({\n xfwd: true,\n });\n\n this.proxy.on('error', (err, _req, res) => {\n this.logger.error('Proxy error:', err);\n if (res && 'writeHead' in res && !res.headersSent) {\n res.writeHead(502, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: 'Service Unavailable', details: err.message }));\n }\n });\n\n this.proxy.on('proxyRes', (proxyRes, req, res) => {\n this.sanitizeProxyResponseHeaders(req, proxyRes);\n const interceptedRequest = req as InterceptedRequest;\n const outgoing = res as http.ServerResponse;\n if (!interceptedRequest.__xpodInspectRootMutation || !outgoing || outgoing.headersSent) {\n return;\n }\n\n const chunks: Buffer[] = [];\n proxyRes.on('data', (chunk) => {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n });\n proxyRes.on('end', () => {\n const originalBody = Buffer.concat(chunks);\n const rewritten = this.normalizeRootMutationProxyResponse(proxyRes, originalBody);\n outgoing.writeHead(rewritten.statusCode, rewritten.headers);\n outgoing.end(rewritten.body);\n });\n });\n\n this.server = http.createServer(this.handleRequest.bind(this));\n\n this.server.on('upgrade', (req, socket, head) => {\n const url = req.url ?? '/';\n\n // Route /ws/* WebSocket connections to API server\n if (url.startsWith('/ws/') && this.targets.api) {\n this.proxy.ws(req, socket, head, { target: this.toProxyTarget(this.targets.api) as any });\n } else if (this.targets.css) {\n this.proxy.ws(req, socket, head, { target: this.toProxyTarget(this.targets.css) as any });\n } else {\n socket.destroy();\n }\n });\n }\n\n public setTargets(targets: { css?: string | GatewayProxyTarget; api?: string | GatewayProxyTarget }): void {\n this.targets = {\n css: this.normalizeTarget(targets.css),\n api: this.normalizeTarget(targets.api),\n };\n }\n\n public async start(): Promise<void> {\n await this.runtimeHost.listen(this.server, this.listenEndpoint);\n this.logger.info(`Listening on ${this.runtimeHost.formatListenEndpoint(this.listenEndpoint)}`);\n }\n\n public stop(): Promise<void> {\n return new Promise((resolve, reject) => {\n this.proxy.close();\n this.runtimeHost.close(this.server, this.listenEndpoint).then(() => {\n resolve();\n }, reject);\n });\n }\n\n private handleRequest(req: http.IncomingMessage, res: http.ServerResponse): void {\n const url = req.url ?? '/';\n const origin = req.headers.origin;\n\n // Store original host for x-forwarded-host before any rewrites\n const originalHost = req.headers.host;\n\n // Set x-forwarded-proto based on CSS_BASE_URL\n const baseUrl = this.baseUrl ?? process.env.CSS_BASE_URL ?? '';\n if (baseUrl.startsWith('https')) {\n req.headers['x-forwarded-proto'] = 'https';\n }\n\n // Rewrite Host header to match CSS_BASE_URL for proper routing\n if (baseUrl) {\n try {\n const parsedBaseUrl = new URL(baseUrl);\n req.headers.host = parsedBaseUrl.host;\n req.headers['x-forwarded-host'] = parsedBaseUrl.host;\n } catch {\n if (!req.headers['x-forwarded-host']) {\n req.headers['x-forwarded-host'] = originalHost;\n }\n }\n } else if (!req.headers['x-forwarded-host']) {\n req.headers['x-forwarded-host'] = originalHost;\n }\n\n this.logger.debug(\n `${req.method} ${url} x-forwarded-proto=${req.headers['x-forwarded-proto']} x-forwarded-host=${req.headers['x-forwarded-host']} host=${req.headers.host}`,\n );\n\n // 1. Internal service endpoints\n if (url.startsWith('/service/')) {\n if (req.method === 'OPTIONS') {\n this.handleCorsPreflightRequest(res, origin);\n return;\n }\n if (origin) {\n this.addCorsHeaders(res, origin);\n }\n void this.handleInternalApi(req, res);\n return;\n }\n\n // 2. API Server Routing (/v1 or /api)\n\n // 2a. Dashboard UI is served by API server under /dashboard/*\n if ((url === '/dashboard' || url.startsWith('/dashboard/')) && this.targets.api) {\n this.proxy.web(req, res, { target: this.toProxyTarget(this.targets.api) as any });\n return;\n }\n\n if ((url.startsWith('/v1/') || url.startsWith('/api/') || url.startsWith('/provision/')) && this.targets.api) {\n this.proxy.web(req, res, { target: this.toProxyTarget(this.targets.api) as any });\n return;\n }\n\n // 3. CSS Routing (Default)\n if (this.targets.css) {\n if (this.shouldRejectRootResourceMutation(req)) {\n this.writeRootMutationForbidden(res);\n return;\n }\n\n const interceptedRequest = req as InterceptedRequest;\n interceptedRequest.__xpodInspectRootMutation = this.shouldInspectRootMutation(req);\n this.proxy.web(req, res, {\n target: this.toProxyTarget(this.targets.css) as any,\n ...(interceptedRequest.__xpodInspectRootMutation ? { selfHandleResponse: true } : {}),\n } as any);\n } else {\n res.writeHead(503);\n res.end('CSS Service Not Available');\n }\n }\n\n private shouldInspectRootMutation(req: http.IncomingMessage): boolean {\n const method = (req.method ?? 'GET').toUpperCase();\n if (![ 'POST', 'PUT', 'PATCH', 'DELETE' ].includes(method)) {\n return false;\n }\n\n const pathname = new URL(req.url ?? '/', 'http://localhost').pathname;\n const segments = pathname.split('/').filter(Boolean);\n return segments.length === 1 && !segments[0].startsWith('.');\n }\n\n private shouldRejectRootResourceMutation(req: http.IncomingMessage): boolean {\n const method = (req.method ?? 'GET').toUpperCase();\n if (![ 'POST', 'PUT', 'PATCH', 'DELETE' ].includes(method)) {\n return false;\n }\n\n const pathname = new URL(req.url ?? '/', 'http://localhost').pathname;\n const segments = pathname.split('/').filter(Boolean);\n return segments.length === 1 && !segments[0].startsWith('.') && !pathname.endsWith('/');\n }\n\n private writeRootMutationForbidden(res: http.ServerResponse): void {\n const body = Buffer.from(JSON.stringify(this.createRootMutationForbiddenBody()));\n res.writeHead(403, {\n 'Content-Type': 'application/json',\n 'Content-Length': String(body.byteLength),\n });\n res.end(body);\n }\n\n private normalizeRootMutationProxyResponse(\n proxyRes: http.IncomingMessage,\n body: Buffer,\n ): { statusCode: number; headers: http.OutgoingHttpHeaders; body: Buffer } {\n const headers: http.OutgoingHttpHeaders = { ...proxyRes.headers };\n const statusCode = proxyRes.statusCode ?? 500;\n const contentType = typeof proxyRes.headers['content-type'] === 'string'\n ? proxyRes.headers['content-type']\n : Array.isArray(proxyRes.headers['content-type'])\n ? proxyRes.headers['content-type'][0] ?? ''\n : '';\n const bodyText = contentType.includes('application/json') ? body.toString('utf8') : '';\n\n if (\n statusCode === 500 &&\n bodyText.includes('Cannot obtain the parent of') &&\n bodyText.includes('because it is a root container')\n ) {\n const normalizedBody = Buffer.from(JSON.stringify(this.createRootMutationForbiddenBody()));\n delete headers['content-length'];\n delete headers['transfer-encoding'];\n headers['content-type'] = 'application/json';\n headers['content-length'] = String(normalizedBody.byteLength);\n return { statusCode: 403, headers, body: normalizedBody };\n }\n\n delete headers['transfer-encoding'];\n headers['content-length'] = String(body.byteLength);\n return { statusCode, headers, body };\n }\n\n private createRootMutationForbiddenBody(): RootMutationForbiddenBody {\n return {\n name: 'ForbiddenHttpError',\n message: 'Write to server root is not allowed.',\n statusCode: 403,\n errorCode: 'H403',\n details: { cause: 'root-container-write' },\n };\n }\n\n private sanitizeProxyResponseHeaders(req: http.IncomingMessage, proxyRes: http.IncomingMessage): void {\n const method = (req.method ?? 'GET').toUpperCase();\n const statusCode = proxyRes.statusCode ?? 200;\n const headers = proxyRes.headers as Record<string, string | string[] | undefined>;\n const transferEncoding = headers['transfer-encoding'];\n const hasTransferEncoding = Array.isArray(transferEncoding)\n ? transferEncoding.some((value) => value.toLowerCase().includes('chunked'))\n : typeof transferEncoding === 'string'\n ? transferEncoding.toLowerCase().includes('chunked')\n : false;\n\n if (method === 'HEAD' || statusCode === 204 || statusCode === 304 || (statusCode >= 100 && statusCode < 200)) {\n delete headers['transfer-encoding'];\n return;\n }\n\n if (hasTransferEncoding && headers['content-length'] !== undefined) {\n delete headers['content-length'];\n }\n }\n\n private handleCorsPreflightRequest(\n res: http.ServerResponse,\n origin: string | undefined,\n ): void {\n this.addCorsHeaders(res, origin);\n res.writeHead(204);\n res.end();\n }\n\n /**\n * Add CORS headers matching CSS CorsHandler configuration\n */\n private addCorsHeaders(res: http.ServerResponse, origin: string | undefined): void {\n res.setHeader('Access-Control-Allow-Origin', origin || '*');\n res.setHeader('Access-Control-Allow-Credentials', String(CORS_CONFIG.credentials));\n res.setHeader('Access-Control-Allow-Methods', CORS_CONFIG.methods.join(', '));\n res.setHeader('Access-Control-Allow-Headers', CORS_CONFIG.allowedHeaders.join(', '));\n res.setHeader('Access-Control-Expose-Headers', CORS_CONFIG.exposedHeaders.join(', '));\n }\n\n private async handleInternalApi(req: http.IncomingMessage, res: http.ServerResponse): Promise<void> {\n try {\n const reqUrl = req.url ?? '/';\n const parsed = new URL(reqUrl, 'http://localhost');\n const pathname = parsed.pathname;\n\n if (pathname === '/service/status') {\n const status = this.supervisor.getAllStatus();\n const cssReady = await this.isCssReady();\n const code = cssReady ? 200 : 503;\n res.writeHead(code, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(status));\n return;\n }\n\n if (pathname === '/service/logs') {\n const level = parsed.searchParams.get('level') ?? undefined;\n const source = parsed.searchParams.get('source') ?? undefined;\n const limitValue = parsed.searchParams.get('limit');\n const limit = limitValue ? parseInt(limitValue, 10) : undefined;\n\n const logs = this.supervisor.getLogs({\n level,\n source,\n limit: Number.isFinite(limit as number) ? limit : undefined,\n });\n\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(logs));\n return;\n }\n\n if (pathname === '/service/stop' && req.method === 'POST') {\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ ok: true }));\n setImmediate(() => {\n const shutdown = this.shutdownHandler ?? (() => this.supervisor.stopAll());\n void shutdown().then(() => {\n if (this.exitOnStop) {\n process.exit(0);\n }\n });\n });\n return;\n }\n\n res.writeHead(404);\n res.end('Not Found');\n } catch (error) {\n this.logger.error('Internal service endpoint failed:', error);\n if (!res.headersSent) {\n res.writeHead(500, { 'Content-Type': 'application/json' });\n }\n res.end(JSON.stringify({ error: 'Internal Server Error' }));\n }\n }\n\n private async isCssReady(): Promise<boolean> {\n if (!this.targets.css) {\n return true;\n }\n\n return this.runtimeHost.isConnectionTargetReady(this.targets.css, 1_500);\n }\n\n private normalizeTarget(target?: string | GatewayProxyTarget): GatewayProxyTarget | undefined {\n if (!target) {\n return undefined;\n }\n if (typeof target === 'string') {\n return { url: target };\n }\n return target;\n }\n\n private toProxyTarget(target: GatewayProxyTarget): string | { socketPath: string; protocol: string } {\n if (target.socketPath) {\n return {\n socketPath: target.socketPath,\n protocol: 'http:',\n };\n }\n return target.url!;\n }\n}\n\nexport interface GatewayProxyTarget {\n url?: string;\n socketPath?: string;\n}\n\nexport interface GatewayProxyOptions {\n socketPath?: string;\n listenEndpoint?: RuntimeListenEndpoint;\n runtimeHost?: RuntimeHost;\n exitOnStop?: boolean;\n shutdownHandler?: () => Promise<void>;\n baseUrl?: string;\n}\n"]}
1
+ {"version":3,"file":"Proxy.js","sourceRoot":"","sources":["../../src/runtime/Proxy.ts"],"names":[],"mappings":"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","sourcesContent":["import httpProxy from 'http-proxy';\nimport http from 'http';\nimport { getLoggerFor } from 'global-logger-factory';\nimport type { Supervisor } from '../supervisor/Supervisor';\nimport { nodeRuntimeHost } from './host/node/NodeRuntimeHost';\nimport type { RuntimeHost, RuntimeListenEndpoint } from './host/types';\n\ntype InterceptedRequest = http.IncomingMessage & { __xpodInspectRootMutation?: boolean };\n\ninterface RootMutationForbiddenBody {\n name: 'ForbiddenHttpError';\n message: string;\n statusCode: 403;\n errorCode: 'H403';\n details: { cause: 'root-container-write' };\n}\n\n// CORS configuration matching CSS CorsHandler defaults\nconst CORS_CONFIG = {\n methods: ['GET', 'HEAD', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE'],\n credentials: true,\n allowedHeaders: [\n 'Authorization', 'Content-Type', 'Accept', 'DPoP', 'Origin',\n 'X-Requested-With', 'If-Match', 'If-None-Match', 'Slug', 'Link',\n ],\n exposedHeaders: [\n 'Accept-Patch', 'Accept-Post', 'Accept-Put', 'Allow', 'Content-Range',\n 'ETag', 'Last-Modified', 'Link', 'Location', 'Updates-Via',\n 'WAC-Allow', 'Www-Authenticate', 'X-Request-Id',\n ],\n};\n\nexport class GatewayProxy {\n private readonly logger = getLoggerFor(this);\n private proxy: httpProxy;\n private server: http.Server;\n private targets: { css?: GatewayProxyTarget; api?: GatewayProxyTarget } = {};\n private readonly runtimeHost: RuntimeHost;\n private readonly listenEndpoint: RuntimeListenEndpoint;\n private readonly exitOnStop: boolean;\n private readonly shutdownHandler?: () => Promise<void>;\n private readonly baseUrl?: string;\n\n constructor(\n port: number | undefined,\n private supervisor: Supervisor,\n bindHost = '0.0.0.0',\n options: GatewayProxyOptions = {},\n ) {\n this.runtimeHost = options.runtimeHost ?? nodeRuntimeHost;\n this.listenEndpoint = options.listenEndpoint ?? this.runtimeHost.createListenEndpoint({\n port,\n host: bindHost,\n socketPath: options.socketPath,\n });\n this.exitOnStop = options.exitOnStop ?? false;\n this.shutdownHandler = options.shutdownHandler;\n this.baseUrl = options.baseUrl;\n this.proxy = httpProxy.createProxyServer({\n xfwd: true,\n });\n\n this.proxy.on('error', (err, _req, res) => {\n this.logger.error('Proxy error:', err);\n if (res && 'writeHead' in res && !res.headersSent) {\n res.writeHead(502, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: 'Service Unavailable', details: err.message }));\n }\n });\n\n this.proxy.on('proxyRes', (proxyRes, req, res) => {\n this.sanitizeProxyResponseHeaders(req, proxyRes);\n const interceptedRequest = req as InterceptedRequest;\n const outgoing = res as http.ServerResponse;\n if (!interceptedRequest.__xpodInspectRootMutation || !outgoing || outgoing.headersSent) {\n return;\n }\n\n const chunks: Buffer[] = [];\n proxyRes.on('data', (chunk) => {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n });\n proxyRes.on('end', () => {\n const originalBody = Buffer.concat(chunks);\n const rewritten = this.normalizeRootMutationProxyResponse(proxyRes, originalBody);\n outgoing.writeHead(rewritten.statusCode, rewritten.headers);\n outgoing.end(rewritten.body);\n });\n });\n\n this.server = http.createServer(this.handleRequest.bind(this));\n\n this.server.on('upgrade', (req, socket, head) => {\n const url = req.url ?? '/';\n\n // Route /ws/* WebSocket connections to API server\n if (url.startsWith('/ws/') && this.targets.api) {\n this.proxy.ws(req, socket, head, { target: this.toProxyTarget(this.targets.api) as any });\n } else if (this.targets.css) {\n this.proxy.ws(req, socket, head, { target: this.toProxyTarget(this.targets.css) as any });\n } else {\n socket.destroy();\n }\n });\n }\n\n public setTargets(targets: { css?: string | GatewayProxyTarget; api?: string | GatewayProxyTarget }): void {\n this.targets = {\n css: this.normalizeTarget(targets.css),\n api: this.normalizeTarget(targets.api),\n };\n }\n\n public async start(): Promise<void> {\n await this.runtimeHost.listen(this.server, this.listenEndpoint);\n this.logger.info(`Listening on ${this.runtimeHost.formatListenEndpoint(this.listenEndpoint)}`);\n }\n\n public stop(): Promise<void> {\n return new Promise((resolve, reject) => {\n this.proxy.close();\n this.runtimeHost.close(this.server, this.listenEndpoint).then(() => {\n resolve();\n }, reject);\n });\n }\n\n private handleRequest(req: http.IncomingMessage, res: http.ServerResponse): void {\n const url = req.url ?? '/';\n const origin = req.headers.origin;\n\n // Store original host for x-forwarded-host before any rewrites\n const originalHost = req.headers.host;\n\n // Set x-forwarded-proto based on CSS_BASE_URL\n const baseUrl = this.baseUrl ?? process.env.CSS_BASE_URL ?? '';\n if (baseUrl.startsWith('https')) {\n req.headers['x-forwarded-proto'] = 'https';\n }\n\n // Rewrite Host header to match CSS_BASE_URL for proper routing\n if (baseUrl) {\n try {\n const parsedBaseUrl = new URL(baseUrl);\n req.headers.host = parsedBaseUrl.host;\n req.headers['x-forwarded-host'] = parsedBaseUrl.host;\n } catch {\n if (!req.headers['x-forwarded-host']) {\n req.headers['x-forwarded-host'] = originalHost;\n }\n }\n } else if (!req.headers['x-forwarded-host']) {\n req.headers['x-forwarded-host'] = originalHost;\n }\n\n this.logger.debug(\n `${req.method} ${url} x-forwarded-proto=${req.headers['x-forwarded-proto']} x-forwarded-host=${req.headers['x-forwarded-host']} host=${req.headers.host}`,\n );\n\n // 1. Internal service endpoints\n if (url.startsWith('/service/')) {\n if (req.method === 'OPTIONS') {\n this.handleCorsPreflightRequest(res, origin);\n return;\n }\n if (origin) {\n this.addCorsHeaders(res, origin);\n }\n void this.handleInternalApi(req, res);\n return;\n }\n\n // 2. API Server Routing (/v1 or /api)\n\n // 2a. Dashboard UI is served by API server under /dashboard/*\n if ((url === '/dashboard' || url.startsWith('/dashboard/')) && this.targets.api) {\n this.proxy.web(req, res, { target: this.toProxyTarget(this.targets.api) as any });\n return;\n }\n\n if (this.shouldRouteToApi(url) && this.targets.api) {\n this.proxy.web(req, res, { target: this.toProxyTarget(this.targets.api) as any });\n return;\n }\n\n // 3. CSS Routing (Default)\n if (this.targets.css) {\n if (this.shouldRejectRootResourceMutation(req)) {\n this.writeRootMutationForbidden(res);\n return;\n }\n\n const interceptedRequest = req as InterceptedRequest;\n interceptedRequest.__xpodInspectRootMutation = this.shouldInspectRootMutation(req);\n this.proxy.web(req, res, {\n target: this.toProxyTarget(this.targets.css) as any,\n ...(interceptedRequest.__xpodInspectRootMutation ? { selfHandleResponse: true } : {}),\n } as any);\n } else {\n res.writeHead(503);\n res.end('CSS Service Not Available');\n }\n }\n\n private shouldRouteToApi(url: string): boolean {\n return url.startsWith('/v1/')\n || url.startsWith('/api/')\n || url.startsWith('/provision/')\n || url === '/.well-known/matrix/client'\n || url.startsWith('/_matrix/');\n }\n\n private shouldInspectRootMutation(req: http.IncomingMessage): boolean {\n const method = (req.method ?? 'GET').toUpperCase();\n if (![ 'POST', 'PUT', 'PATCH', 'DELETE' ].includes(method)) {\n return false;\n }\n\n const pathname = new URL(req.url ?? '/', 'http://localhost').pathname;\n const segments = pathname.split('/').filter(Boolean);\n return segments.length === 1 && !segments[0].startsWith('.');\n }\n\n private shouldRejectRootResourceMutation(req: http.IncomingMessage): boolean {\n const method = (req.method ?? 'GET').toUpperCase();\n if (![ 'POST', 'PUT', 'PATCH', 'DELETE' ].includes(method)) {\n return false;\n }\n\n const pathname = new URL(req.url ?? '/', 'http://localhost').pathname;\n const segments = pathname.split('/').filter(Boolean);\n return segments.length === 1 && !segments[0].startsWith('.') && !pathname.endsWith('/');\n }\n\n private writeRootMutationForbidden(res: http.ServerResponse): void {\n const body = Buffer.from(JSON.stringify(this.createRootMutationForbiddenBody()));\n res.writeHead(403, {\n 'Content-Type': 'application/json',\n 'Content-Length': String(body.byteLength),\n });\n res.end(body);\n }\n\n private normalizeRootMutationProxyResponse(\n proxyRes: http.IncomingMessage,\n body: Buffer,\n ): { statusCode: number; headers: http.OutgoingHttpHeaders; body: Buffer } {\n const headers: http.OutgoingHttpHeaders = { ...proxyRes.headers };\n const statusCode = proxyRes.statusCode ?? 500;\n const contentType = typeof proxyRes.headers['content-type'] === 'string'\n ? proxyRes.headers['content-type']\n : Array.isArray(proxyRes.headers['content-type'])\n ? proxyRes.headers['content-type'][0] ?? ''\n : '';\n const bodyText = contentType.includes('application/json') ? body.toString('utf8') : '';\n\n if (\n statusCode === 500 &&\n bodyText.includes('Cannot obtain the parent of') &&\n bodyText.includes('because it is a root container')\n ) {\n const normalizedBody = Buffer.from(JSON.stringify(this.createRootMutationForbiddenBody()));\n delete headers['content-length'];\n delete headers['transfer-encoding'];\n headers['content-type'] = 'application/json';\n headers['content-length'] = String(normalizedBody.byteLength);\n return { statusCode: 403, headers, body: normalizedBody };\n }\n\n delete headers['transfer-encoding'];\n headers['content-length'] = String(body.byteLength);\n return { statusCode, headers, body };\n }\n\n private createRootMutationForbiddenBody(): RootMutationForbiddenBody {\n return {\n name: 'ForbiddenHttpError',\n message: 'Write to server root is not allowed.',\n statusCode: 403,\n errorCode: 'H403',\n details: { cause: 'root-container-write' },\n };\n }\n\n private sanitizeProxyResponseHeaders(req: http.IncomingMessage, proxyRes: http.IncomingMessage): void {\n const method = (req.method ?? 'GET').toUpperCase();\n const statusCode = proxyRes.statusCode ?? 200;\n const headers = proxyRes.headers as Record<string, string | string[] | undefined>;\n const transferEncoding = headers['transfer-encoding'];\n const hasTransferEncoding = Array.isArray(transferEncoding)\n ? transferEncoding.some((value) => value.toLowerCase().includes('chunked'))\n : typeof transferEncoding === 'string'\n ? transferEncoding.toLowerCase().includes('chunked')\n : false;\n\n if (method === 'HEAD' || statusCode === 204 || statusCode === 304 || (statusCode >= 100 && statusCode < 200)) {\n delete headers['transfer-encoding'];\n return;\n }\n\n if (hasTransferEncoding && headers['content-length'] !== undefined) {\n delete headers['content-length'];\n }\n }\n\n private handleCorsPreflightRequest(\n res: http.ServerResponse,\n origin: string | undefined,\n ): void {\n this.addCorsHeaders(res, origin);\n res.writeHead(204);\n res.end();\n }\n\n /**\n * Add CORS headers matching CSS CorsHandler configuration\n */\n private addCorsHeaders(res: http.ServerResponse, origin: string | undefined): void {\n res.setHeader('Access-Control-Allow-Origin', origin || '*');\n res.setHeader('Access-Control-Allow-Credentials', String(CORS_CONFIG.credentials));\n res.setHeader('Access-Control-Allow-Methods', CORS_CONFIG.methods.join(', '));\n res.setHeader('Access-Control-Allow-Headers', CORS_CONFIG.allowedHeaders.join(', '));\n res.setHeader('Access-Control-Expose-Headers', CORS_CONFIG.exposedHeaders.join(', '));\n }\n\n private async handleInternalApi(req: http.IncomingMessage, res: http.ServerResponse): Promise<void> {\n try {\n const reqUrl = req.url ?? '/';\n const parsed = new URL(reqUrl, 'http://localhost');\n const pathname = parsed.pathname;\n\n if (pathname === '/service/status') {\n const status = this.supervisor.getAllStatus();\n const cssReady = await this.isCssReady();\n const code = cssReady ? 200 : 503;\n res.writeHead(code, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(status));\n return;\n }\n\n if (pathname === '/service/logs') {\n const level = parsed.searchParams.get('level') ?? undefined;\n const source = parsed.searchParams.get('source') ?? undefined;\n const limitValue = parsed.searchParams.get('limit');\n const limit = limitValue ? parseInt(limitValue, 10) : undefined;\n\n const logs = this.supervisor.getLogs({\n level,\n source,\n limit: Number.isFinite(limit as number) ? limit : undefined,\n });\n\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(logs));\n return;\n }\n\n if (pathname === '/service/stop' && req.method === 'POST') {\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ ok: true }));\n setImmediate(() => {\n const shutdown = this.shutdownHandler ?? (() => this.supervisor.stopAll());\n void shutdown().then(() => {\n if (this.exitOnStop) {\n process.exit(0);\n }\n });\n });\n return;\n }\n\n res.writeHead(404);\n res.end('Not Found');\n } catch (error) {\n this.logger.error('Internal service endpoint failed:', error);\n if (!res.headersSent) {\n res.writeHead(500, { 'Content-Type': 'application/json' });\n }\n res.end(JSON.stringify({ error: 'Internal Server Error' }));\n }\n }\n\n private async isCssReady(): Promise<boolean> {\n if (!this.targets.css) {\n return true;\n }\n\n return this.runtimeHost.isConnectionTargetReady(this.targets.css, 1_500);\n }\n\n private normalizeTarget(target?: string | GatewayProxyTarget): GatewayProxyTarget | undefined {\n if (!target) {\n return undefined;\n }\n if (typeof target === 'string') {\n return { url: target };\n }\n return target;\n }\n\n private toProxyTarget(target: GatewayProxyTarget): string | { socketPath: string; protocol: string } {\n if (target.socketPath) {\n return {\n socketPath: target.socketPath,\n protocol: 'http:',\n };\n }\n return target.url!;\n }\n}\n\nexport interface GatewayProxyTarget {\n url?: string;\n socketPath?: string;\n}\n\nexport interface GatewayProxyOptions {\n socketPath?: string;\n listenEndpoint?: RuntimeListenEndpoint;\n runtimeHost?: RuntimeHost;\n exitOnStop?: boolean;\n shutdownHandler?: () => Promise<void>;\n baseUrl?: string;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"select-query-builder.d.ts","sourceRoot":"","sources":["../../../src/core/query-builders/select-query-builder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"select-query-builder.d.ts","sourceRoot":"","sources":["../../../src/core/query-builders/select-query-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,KAAK,oBAAoB,EAAE,KAAK,iBAAiB,EAAoB,MAAM,qBAAqB,CAAC;AAG1H,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EACQ,cAAc,EAAoD,gBAAgB,EAChG,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAuB,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC1E,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAI1D,qBAAa,kBAAkB,CAAC,MAAM,SAAS,QAAQ,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC;IA2BvD,OAAO,EAAE,gBAAgB;IA1B5C,MAAM,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,wBAAwB;IAE7C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7C,OAAO,CAAC,aAAa,CAAC,CAAiB;IAChC,GAAG,CAAC,EAAE,GAAG,CAAC;IACjB,OAAO,CAAC,KAAK,CAML;IACR,OAAO,CAAC,UAAU,CAAC,CAAS;IAC5B,OAAO,CAAC,WAAW,CAAC,CAAS;IAC7B,OAAO,CAAC,cAAc,CAA4D;IAClF,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,cAAc,CAAC,CAAiB;IACxC,OAAO,CAAC,YAAY,CAAoC;IACxD,OAAO,CAAC,YAAY,CAAoC;IACxD,OAAO,CAAC,UAAU,CAA6B;IAC/C,OAAO,CAAC,YAAY,CAAC,CAAS;IAC9B,OAAO,CAAC,WAAW,CAAwB;IAC3C,OAAO,CAAC,cAAc,CAAyB;IAC/C,OAAO,CAAC,eAAe,CAAC,CAAiB;gBAEtB,OAAO,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,cAAc;IAMrE,IAAI,CAAC,UAAU,SAAS,QAAQ,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,UAAU,GAAG,kBAAkB,CAAC,UAAU,CAAC;IAMzF,OAAO,CAAC,MAAM,EAAE,cAAc;IAK9B,OAAO,CAAC,iBAAiB;IAIzB;;;;;OAKG;IACH,KAAK,CAAC,UAAU,EAAE,iBAAiB,GAAG,GAAG,GAAG,oBAAoB;IAahE;;;;OAIG;IACH,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE;IAKjC,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,6BAA6B;IAgCrC,OAAO,CAAC,yBAAyB;IAqBjC,QAAQ,CAAC,UAAU,SAAS,QAAQ,CAAC,GAAG,CAAC,EACvC,KAAK,EAAE,UAAU,EACjB,SAAS,EAAE,GAAG,GACb,kBAAkB,CAAC,MAAM,CAAC;IAI7B,SAAS,CAAC,UAAU,SAAS,QAAQ,CAAC,GAAG,CAAC,EACxC,KAAK,EAAE,UAAU,EACjB,SAAS,EAAE,GAAG,GACb,kBAAkB,CAAC,MAAM,CAAC;IAI7B,SAAS,CAAC,UAAU,SAAS,QAAQ,CAAC,GAAG,CAAC,EACxC,KAAK,EAAE,UAAU,EACjB,SAAS,EAAE,GAAG,GACb,kBAAkB,CAAC,MAAM,CAAC;IAI7B,QAAQ,CAAC,UAAU,SAAS,QAAQ,CAAC,GAAG,CAAC,EACvC,KAAK,EAAE,UAAU,EACjB,SAAS,EAAE,GAAG,GACb,kBAAkB,CAAC,MAAM,CAAC;IAI7B,SAAS,CAAC,UAAU,SAAS,QAAQ,CAAC,GAAG,CAAC,EACxC,KAAK,EAAE,UAAU,GAChB,kBAAkB,CAAC,MAAM,CAAC;IAI7B,OAAO,CAAC,GAAG,MAAM,EAAE,KAAK,CAAC,aAAa,GAAG,MAAM,CAAC,GAAG,kBAAkB,CAAC,MAAM,CAAC;IAM7E,MAAM,CACJ,SAAS,EAAE,cAAc,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,KAAK,cAAc,CAAC,GACjG,kBAAkB,CAAC,MAAM,CAAC;IAO7B,OAAO,CAAC,0BAA0B;IAUlC,OAAO,CAAC,OAAO;IAyBf,OAAO,CAAC,mBAAmB;IAiB3B,OAAO,CAAC,qBAAqB;IA0B7B,OAAO,CAAC,8BAA8B;IA8BtC,OAAO,CAAC,2BAA2B;IAoBnC,OAAO,CAAC,sBAAsB;IA0B9B,OAAO,CAAC,0BAA0B;IASlC,OAAO,CAAC,kBAAkB;IAsB1B,OAAO,CAAC,qBAAqB;IAe7B,OAAO,CAAC,2BAA2B;IAKnC,OAAO,CAAC,wBAAwB;IAQzB,IAAI,IAAI,eAAe;IAK9B,OAAO,CAAC,cAAc;IAwCtB,KAAK,CAAC,KAAK,EAAE,MAAM;IAQnB,MAAM,CAAC,KAAK,EAAE,MAAM;IAQpB,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,aAAa,GAAG,MAAM,GAAG,iBAAiB,GAAG,KAAK,GAAG,MAAM,CAAC;IA+BnF,QAAQ,CAAC,MAAM,UAAO;IAMtB,OAAO,CAAC,gBAAgB;IA8BxB,QAAQ;IAIR,QAAQ;IAIF,OAAO,IAAI,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC;IA2HlD,OAAO,CAAC,kBAAkB;IAQ1B,OAAO,CAAC,eAAe;IAYvB,OAAO,CAAC,iBAAiB;IAoCzB,OAAO,CAAC,iBAAiB;IAuBzB,OAAO,CAAC,gBAAgB;IAQxB,OAAO,CAAC,uBAAuB;IA2B/B,OAAO,CAAC,qBAAqB;IAc7B,OAAO,CAAC,6BAA6B;IA0BrC,OAAO,CAAC,2BAA2B;IAkBnC,OAAO,CAAC,0BAA0B;IAqBlC,OAAO,CAAC,iBAAiB;IAgBzB,OAAO,CAAC,qBAAqB;IAyC7B,OAAO,CAAC,yBAAyB;IAwBjC,OAAO,CAAC,qBAAqB;IAqB7B,OAAO,CAAC,oBAAoB;IA6B5B,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,uBAAuB;IAwB/B,OAAO,CAAC,yBAAyB;IAsCjC,OAAO,CAAC,qBAAqB;IAsB7B,OAAO,CAAC,wBAAwB;IAYhC,OAAO,CAAC,qBAAqB;IAQ7B,OAAO,CAAC,0BAA0B;IAUlC,OAAO,CAAC,oBAAoB;IAI5B,OAAO,CAAC,mBAAmB;IAe3B,OAAO,CAAC,qBAAqB;IAoB7B,OAAO,CAAC,iBAAiB;YAuCX,oBAAoB;IAsIlC,OAAO,CAAC,2BAA2B;IAkBnC,OAAO,CAAC,0BAA0B;IASlC,OAAO,CAAC,kBAAkB;IAS1B,OAAO,CAAC,oBAAoB;IAsB5B,OAAO,CAAC,iBAAiB;IAmBzB,OAAO,CAAC,2BAA2B;IAWnC,OAAO,CAAC,eAAe;IAavB,OAAO,CAAC,oBAAoB;IAoB5B,OAAO,CAAC,kBAAkB;IAkF1B,OAAO,CAAC,4BAA4B;IAqBpC,OAAO,CAAC,oBAAoB;IAkB5B,OAAO,CAAC,oBAAoB;YAUd,iBAAiB;YAWjB,aAAa;IAyE3B,OAAO,CAAC,8BAA8B;IAmHtC,OAAO,CAAC,wBAAwB;IAehC,OAAO,CAAC,mCAAmC;IAsB3C,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,4BAA4B;IAgBpC,OAAO,CAAC,iBAAiB;IAiCzB,OAAO,CAAC,iBAAiB;IAqEzB,OAAO,CAAC,2BAA2B;IAkBnC,OAAO,CAAC,kBAAkB;IAU1B,OAAO,CAAC,gBAAgB;IAQxB,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,iBAAiB;IAazB,OAAO,CAAC,uBAAuB;IAqC/B,OAAO,CAAC,sBAAsB;IAwB9B,OAAO,CAAC,wBAAwB;IAYhC,OAAO,CAAC,4BAA4B;IAiBpC,OAAO,CAAC,sBAAsB;IAU9B,OAAO,CAAC,oBAAoB;IAU5B,OAAO,CAAC,8BAA8B;IAKtC,OAAO,CAAC,oBAAoB;IAU5B,OAAO,CAAC,oBAAoB;IA2C5B,OAAO,CAAC,gBAAgB;IAOlB,oBAAoB,CAAC,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAYzF,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,GAAG,KAAK,EAC1F,WAAW,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,GAAG,SAAS,GAAG,IAAI,EAC1I,UAAU,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,GAAG,KAAK,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,GAAG,SAAS,GAAG,IAAI,GAClF,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC;CAGhC"}