@wildo-ai/saas-backend-lib 1.1.12 → 1.1.13

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 (226) hide show
  1. package/dist/esm/base-classes/models/manual-controllers.backend.definition.d.ts.map +1 -1
  2. package/dist/esm/base-classes/models/manual-controllers.backend.definition.js +2 -0
  3. package/dist/esm/base-classes/models/manual-controllers.backend.definition.js.map +1 -1
  4. package/dist/esm/base-classes/services/repositories/stored-field-omission.backend.d.ts +4 -0
  5. package/dist/esm/base-classes/services/repositories/stored-field-omission.backend.d.ts.map +1 -1
  6. package/dist/esm/base-classes/services/repositories/stored-field-omission.backend.js +20 -5
  7. package/dist/esm/base-classes/services/repositories/stored-field-omission.backend.js.map +1 -1
  8. package/dist/esm/base-classes/services/services/resource-operation-custom-implementation-registry.backend.service.d.ts +3 -0
  9. package/dist/esm/base-classes/services/services/resource-operation-custom-implementation-registry.backend.service.d.ts.map +1 -1
  10. package/dist/esm/base-classes/services/services/resource-operation-custom-implementation-registry.backend.service.js +10 -1
  11. package/dist/esm/base-classes/services/services/resource-operation-custom-implementation-registry.backend.service.js.map +1 -1
  12. package/dist/esm/base-classes/services/services/resource-operation-custom-implementation.factory.backend.d.ts +22 -0
  13. package/dist/esm/base-classes/services/services/resource-operation-custom-implementation.factory.backend.d.ts.map +1 -1
  14. package/dist/esm/base-classes/services/services/resource-operation-custom-implementation.factory.backend.js +25 -1
  15. package/dist/esm/base-classes/services/services/resource-operation-custom-implementation.factory.backend.js.map +1 -1
  16. package/dist/esm/base-classes/services/services/resource-operation-transaction-persistence.backend.utils.d.ts +38 -3
  17. package/dist/esm/base-classes/services/services/resource-operation-transaction-persistence.backend.utils.d.ts.map +1 -1
  18. package/dist/esm/base-classes/services/services/resource-operation-transaction-persistence.backend.utils.js +68 -5
  19. package/dist/esm/base-classes/services/services/resource-operation-transaction-persistence.backend.utils.js.map +1 -1
  20. package/dist/esm/base-classes/services/services/resource-status-transition.custom-impl.backend.service.d.ts +2 -2
  21. package/dist/esm/base-classes/services/services/resource-status-transition.custom-impl.backend.service.d.ts.map +1 -1
  22. package/dist/esm/base-classes/services/services/resource-status-transition.custom-impl.backend.service.js +6 -3
  23. package/dist/esm/base-classes/services/services/resource-status-transition.custom-impl.backend.service.js.map +1 -1
  24. package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.d.ts +83 -0
  25. package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.d.ts.map +1 -1
  26. package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.js +217 -14
  27. package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.js.map +1 -1
  28. package/dist/esm/compliance/approval-seals/approval-seal-currency.backend.d.ts +32 -0
  29. package/dist/esm/compliance/approval-seals/approval-seal-currency.backend.d.ts.map +1 -0
  30. package/dist/esm/compliance/approval-seals/approval-seal-currency.backend.js +36 -0
  31. package/dist/esm/compliance/approval-seals/approval-seal-currency.backend.js.map +1 -0
  32. package/dist/esm/compliance/approval-seals/approval-seal-on-record.backend.d.ts +38 -0
  33. package/dist/esm/compliance/approval-seals/approval-seal-on-record.backend.d.ts.map +1 -0
  34. package/dist/esm/compliance/approval-seals/approval-seal-on-record.backend.js +83 -0
  35. package/dist/esm/compliance/approval-seals/approval-seal-on-record.backend.js.map +1 -0
  36. package/dist/esm/compliance/approval-seals/approval-seal-presentation-read.backend.d.ts +36 -0
  37. package/dist/esm/compliance/approval-seals/approval-seal-presentation-read.backend.d.ts.map +1 -0
  38. package/dist/esm/compliance/approval-seals/approval-seal-presentation-read.backend.js +51 -0
  39. package/dist/esm/compliance/approval-seals/approval-seal-presentation-read.backend.js.map +1 -0
  40. package/dist/esm/compliance/approval-seals/approval-seal-relay-store.backend.d.ts +46 -0
  41. package/dist/esm/compliance/approval-seals/approval-seal-relay-store.backend.d.ts.map +1 -1
  42. package/dist/esm/compliance/approval-seals/approval-seal-relay-store.backend.js +68 -0
  43. package/dist/esm/compliance/approval-seals/approval-seal-relay-store.backend.js.map +1 -1
  44. package/dist/esm/compliance/approval-seals/approval-seal-store.backend.d.ts +27 -0
  45. package/dist/esm/compliance/approval-seals/approval-seal-store.backend.d.ts.map +1 -1
  46. package/dist/esm/compliance/approval-seals/approval-seal-store.backend.js +42 -3
  47. package/dist/esm/compliance/approval-seals/approval-seal-store.backend.js.map +1 -1
  48. package/dist/esm/compliance/approval-seals/approval-seals-admin.backend.contracts.d.ts +26 -1
  49. package/dist/esm/compliance/approval-seals/approval-seals-admin.backend.contracts.d.ts.map +1 -1
  50. package/dist/esm/compliance/approval-seals/approval-seals-admin.backend.contracts.js +10 -0
  51. package/dist/esm/compliance/approval-seals/approval-seals-admin.backend.contracts.js.map +1 -1
  52. package/dist/esm/compliance/approval-seals/approval-seals-admin.backend.controller.d.ts +10 -1
  53. package/dist/esm/compliance/approval-seals/approval-seals-admin.backend.controller.d.ts.map +1 -1
  54. package/dist/esm/compliance/approval-seals/approval-seals-admin.backend.controller.js +60 -28
  55. package/dist/esm/compliance/approval-seals/approval-seals-admin.backend.controller.js.map +1 -1
  56. package/dist/esm/compliance/approval-seals/approval-seals-on-record.backend.controller.d.ts +90 -0
  57. package/dist/esm/compliance/approval-seals/approval-seals-on-record.backend.controller.d.ts.map +1 -0
  58. package/dist/esm/compliance/approval-seals/approval-seals-on-record.backend.controller.js +373 -0
  59. package/dist/esm/compliance/approval-seals/approval-seals-on-record.backend.controller.js.map +1 -0
  60. package/dist/esm/compliance/approval-seals/decision-presentation.backend.d.ts +29 -2
  61. package/dist/esm/compliance/approval-seals/decision-presentation.backend.d.ts.map +1 -1
  62. package/dist/esm/compliance/approval-seals/decision-presentation.backend.js +40 -3
  63. package/dist/esm/compliance/approval-seals/decision-presentation.backend.js.map +1 -1
  64. package/dist/esm/compliance/electronic-signatures/pdf-signature-structure.backend.d.ts.map +1 -1
  65. package/dist/esm/compliance/electronic-signatures/pdf-signature-structure.backend.js +34 -6
  66. package/dist/esm/compliance/electronic-signatures/pdf-signature-structure.backend.js.map +1 -1
  67. package/dist/esm/compliance/electronic-signatures/signature-request-evidence-files.backend.d.ts +30 -6
  68. package/dist/esm/compliance/electronic-signatures/signature-request-evidence-files.backend.d.ts.map +1 -1
  69. package/dist/esm/compliance/electronic-signatures/signature-request-evidence-files.backend.js +67 -22
  70. package/dist/esm/compliance/electronic-signatures/signature-request-evidence-files.backend.js.map +1 -1
  71. package/dist/esm/compliance/electronic-signatures/signature-request-poll.batch.backend.service.d.ts.map +1 -1
  72. package/dist/esm/compliance/electronic-signatures/signature-request-poll.batch.backend.service.js +18 -1
  73. package/dist/esm/compliance/electronic-signatures/signature-request-poll.batch.backend.service.js.map +1 -1
  74. package/dist/esm/compliance/electronic-signatures/signature-requests.backend.service.d.ts +66 -1
  75. package/dist/esm/compliance/electronic-signatures/signature-requests.backend.service.d.ts.map +1 -1
  76. package/dist/esm/compliance/electronic-signatures/signature-requests.backend.service.js +161 -14
  77. package/dist/esm/compliance/electronic-signatures/signature-requests.backend.service.js.map +1 -1
  78. package/dist/esm/compliance/electronic-signatures/signed-document-validation.backend.d.ts +47 -0
  79. package/dist/esm/compliance/electronic-signatures/signed-document-validation.backend.d.ts.map +1 -1
  80. package/dist/esm/compliance/electronic-signatures/signed-document-validation.backend.js.map +1 -1
  81. package/dist/esm/external-providers/services/content-safety.backend.service.d.ts +27 -2
  82. package/dist/esm/external-providers/services/content-safety.backend.service.d.ts.map +1 -1
  83. package/dist/esm/external-providers/services/content-safety.backend.service.js +46 -1
  84. package/dist/esm/external-providers/services/content-safety.backend.service.js.map +1 -1
  85. package/dist/esm/external-providers/services/embeddings.backend.service.d.ts.map +1 -1
  86. package/dist/esm/external-providers/services/embeddings.backend.service.js +2 -0
  87. package/dist/esm/external-providers/services/embeddings.backend.service.js.map +1 -1
  88. package/dist/esm/external-providers/services/external-providers-registry.backend.service.d.ts +11 -0
  89. package/dist/esm/external-providers/services/external-providers-registry.backend.service.d.ts.map +1 -1
  90. package/dist/esm/external-providers/services/external-providers-registry.backend.service.js +23 -0
  91. package/dist/esm/external-providers/services/external-providers-registry.backend.service.js.map +1 -1
  92. package/dist/esm/external-providers/services/provider-service-account-token.backend.d.ts +19 -1
  93. package/dist/esm/external-providers/services/provider-service-account-token.backend.d.ts.map +1 -1
  94. package/dist/esm/external-providers/services/provider-service-account-token.backend.js +41 -1
  95. package/dist/esm/external-providers/services/provider-service-account-token.backend.js.map +1 -1
  96. package/dist/esm/files/utils/file-parent-read-context.backend.d.ts +27 -2
  97. package/dist/esm/files/utils/file-parent-read-context.backend.d.ts.map +1 -1
  98. package/dist/esm/files/utils/file-parent-read-context.backend.js +23 -4
  99. package/dist/esm/files/utils/file-parent-read-context.backend.js.map +1 -1
  100. package/dist/esm/flows-actors/content-guardrails/classifier-availability.backend.utils.d.ts +26 -0
  101. package/dist/esm/flows-actors/content-guardrails/classifier-availability.backend.utils.d.ts.map +1 -1
  102. package/dist/esm/flows-actors/content-guardrails/classifier-availability.backend.utils.js +100 -8
  103. package/dist/esm/flows-actors/content-guardrails/classifier-availability.backend.utils.js.map +1 -1
  104. package/dist/esm/flows-actors/content-guardrails/record-owner-policy.backend.d.ts +3 -1
  105. package/dist/esm/flows-actors/content-guardrails/record-owner-policy.backend.d.ts.map +1 -1
  106. package/dist/esm/flows-actors/content-guardrails/record-owner-policy.backend.js +8 -2
  107. package/dist/esm/flows-actors/content-guardrails/record-owner-policy.backend.js.map +1 -1
  108. package/dist/esm/flows-actors/models/function-tools.backend.definitions.d.ts +43 -0
  109. package/dist/esm/flows-actors/models/function-tools.backend.definitions.d.ts.map +1 -1
  110. package/dist/esm/flows-actors/models/function-tools.backend.definitions.js +37 -0
  111. package/dist/esm/flows-actors/models/function-tools.backend.definitions.js.map +1 -1
  112. package/dist/esm/flows-actors/services/agent-work-decisions.backend.service.d.ts +7 -0
  113. package/dist/esm/flows-actors/services/agent-work-decisions.backend.service.d.ts.map +1 -1
  114. package/dist/esm/flows-actors/services/agent-work-decisions.backend.service.js +8 -3
  115. package/dist/esm/flows-actors/services/agent-work-decisions.backend.service.js.map +1 -1
  116. package/dist/esm/flows-actors/services/agents.backend.service.d.ts +31 -6
  117. package/dist/esm/flows-actors/services/agents.backend.service.d.ts.map +1 -1
  118. package/dist/esm/flows-actors/services/agents.backend.service.js +78 -30
  119. package/dist/esm/flows-actors/services/agents.backend.service.js.map +1 -1
  120. package/dist/esm/flows-actors/services/autonomous-agent-turn.backend.service.d.ts.map +1 -1
  121. package/dist/esm/flows-actors/services/autonomous-agent-turn.backend.service.js +4 -0
  122. package/dist/esm/flows-actors/services/autonomous-agent-turn.backend.service.js.map +1 -1
  123. package/dist/esm/flows-actors/services/conversational-execution.backend.service.d.ts +28 -2
  124. package/dist/esm/flows-actors/services/conversational-execution.backend.service.d.ts.map +1 -1
  125. package/dist/esm/flows-actors/services/conversational-execution.backend.service.js +132 -22
  126. package/dist/esm/flows-actors/services/conversational-execution.backend.service.js.map +1 -1
  127. package/dist/esm/flows-actors/services/flow-actor-executions.custom-impl.backend.service.d.ts.map +1 -1
  128. package/dist/esm/flows-actors/services/flow-actor-executions.custom-impl.backend.service.js +12 -8
  129. package/dist/esm/flows-actors/services/flow-actor-executions.custom-impl.backend.service.js.map +1 -1
  130. package/dist/esm/flows-actors/services/flows-actors-registry.service.d.ts +5 -0
  131. package/dist/esm/flows-actors/services/flows-actors-registry.service.d.ts.map +1 -1
  132. package/dist/esm/flows-actors/services/flows-actors-registry.service.js +18 -2
  133. package/dist/esm/flows-actors/services/flows-actors-registry.service.js.map +1 -1
  134. package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.d.ts +33 -0
  135. package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.d.ts.map +1 -1
  136. package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.js +58 -0
  137. package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.js.map +1 -1
  138. package/dist/esm/inbound/services/inbound-delivery-dispatch.backend.service.d.ts +12 -1
  139. package/dist/esm/inbound/services/inbound-delivery-dispatch.backend.service.d.ts.map +1 -1
  140. package/dist/esm/inbound/services/inbound-delivery-dispatch.backend.service.js +23 -4
  141. package/dist/esm/inbound/services/inbound-delivery-dispatch.backend.service.js.map +1 -1
  142. package/dist/esm/inbound/services/inbound-delivery-receiver.backend.service.d.ts +12 -1
  143. package/dist/esm/inbound/services/inbound-delivery-receiver.backend.service.d.ts.map +1 -1
  144. package/dist/esm/inbound/services/inbound-delivery-receiver.backend.service.js +55 -17
  145. package/dist/esm/inbound/services/inbound-delivery-receiver.backend.service.js.map +1 -1
  146. package/dist/esm/inbound/services/inbound-delivery-store.backend.service.d.ts +22 -1
  147. package/dist/esm/inbound/services/inbound-delivery-store.backend.service.d.ts.map +1 -1
  148. package/dist/esm/inbound/services/inbound-delivery-store.backend.service.js +52 -9
  149. package/dist/esm/inbound/services/inbound-delivery-store.backend.service.js.map +1 -1
  150. package/dist/esm/inbound/services/inbound-delivery-stored-body.backend.service.d.ts +79 -0
  151. package/dist/esm/inbound/services/inbound-delivery-stored-body.backend.service.d.ts.map +1 -0
  152. package/dist/esm/inbound/services/inbound-delivery-stored-body.backend.service.js +211 -0
  153. package/dist/esm/inbound/services/inbound-delivery-stored-body.backend.service.js.map +1 -0
  154. package/dist/esm/inbound/services/inbound-delivery-subject-erasure-severance.backend.d.ts +2 -2
  155. package/dist/esm/inbound/services/inbound-delivery-subject-erasure-severance.backend.d.ts.map +1 -1
  156. package/dist/esm/inbound/services/inbound-delivery-subject-erasure-severance.backend.js +9 -1
  157. package/dist/esm/inbound/services/inbound-delivery-subject-erasure-severance.backend.js.map +1 -1
  158. package/dist/esm/index.d.ts +1 -0
  159. package/dist/esm/index.d.ts.map +1 -1
  160. package/dist/esm/index.js +1 -0
  161. package/dist/esm/index.js.map +1 -1
  162. package/dist/esm/inject/models/container.d.ts.map +1 -1
  163. package/dist/esm/inject/models/container.js +6 -0
  164. package/dist/esm/inject/models/container.js.map +1 -1
  165. package/dist/esm/inject/models/service-types.d.ts +5 -0
  166. package/dist/esm/inject/models/service-types.d.ts.map +1 -1
  167. package/dist/esm/inject/models/service-types.js +3 -0
  168. package/dist/esm/inject/models/service-types.js.map +1 -1
  169. package/dist/esm/monitoring/observability/models/observability.backend.schemas.d.ts +5 -0
  170. package/dist/esm/monitoring/observability/models/observability.backend.schemas.d.ts.map +1 -1
  171. package/dist/esm/monitoring/observability/models/observability.backend.schemas.js.map +1 -1
  172. package/dist/esm/monitoring/observability/services/metrics.service.d.ts +34 -1
  173. package/dist/esm/monitoring/observability/services/metrics.service.d.ts.map +1 -1
  174. package/dist/esm/monitoring/observability/services/metrics.service.js +49 -0
  175. package/dist/esm/monitoring/observability/services/metrics.service.js.map +1 -1
  176. package/dist/esm/notifications/webhooks/controllers/webhook-auto-controller.backend.service.d.ts +6 -1
  177. package/dist/esm/notifications/webhooks/controllers/webhook-auto-controller.backend.service.d.ts.map +1 -1
  178. package/dist/esm/notifications/webhooks/controllers/webhook-auto-controller.backend.service.js +15 -4
  179. package/dist/esm/notifications/webhooks/controllers/webhook-auto-controller.backend.service.js.map +1 -1
  180. package/dist/esm/notifications/webhooks/outbound/services/m2m-webhook-delivery-log.custom-impl.backend.service.d.ts.map +1 -1
  181. package/dist/esm/notifications/webhooks/outbound/services/m2m-webhook-delivery-log.custom-impl.backend.service.js +3 -1
  182. package/dist/esm/notifications/webhooks/outbound/services/m2m-webhook-delivery-log.custom-impl.backend.service.js.map +1 -1
  183. package/dist/esm/runtime/services/http-server.backend.service.d.ts +3 -1
  184. package/dist/esm/runtime/services/http-server.backend.service.d.ts.map +1 -1
  185. package/dist/esm/runtime/services/http-server.backend.service.js +11 -3
  186. package/dist/esm/runtime/services/http-server.backend.service.js.map +1 -1
  187. package/dist/esm/runtime/services/utils/inbound-endpoint-raw-body.backend.utils.d.ts +22 -0
  188. package/dist/esm/runtime/services/utils/inbound-endpoint-raw-body.backend.utils.d.ts.map +1 -1
  189. package/dist/esm/runtime/services/utils/inbound-endpoint-raw-body.backend.utils.js +54 -0
  190. package/dist/esm/runtime/services/utils/inbound-endpoint-raw-body.backend.utils.js.map +1 -1
  191. package/dist/esm/security/authentications/services/auth-methods/auth-password-reset.backend.service.d.ts +51 -0
  192. package/dist/esm/security/authentications/services/auth-methods/auth-password-reset.backend.service.d.ts.map +1 -1
  193. package/dist/esm/security/authentications/services/auth-methods/auth-password-reset.backend.service.js +87 -15
  194. package/dist/esm/security/authentications/services/auth-methods/auth-password-reset.backend.service.js.map +1 -1
  195. package/dist/esm/security/authentications/services/custom-impls/siem-delivery-dlq.custom-impl.backend.service.d.ts.map +1 -1
  196. package/dist/esm/security/authentications/services/custom-impls/siem-delivery-dlq.custom-impl.backend.service.js +5 -2
  197. package/dist/esm/security/authentications/services/custom-impls/siem-delivery-dlq.custom-impl.backend.service.js.map +1 -1
  198. package/dist/esm/security/authentications/services/custom-impls/sso-config-domain-verification.custom-impl.backend.service.d.ts.map +1 -1
  199. package/dist/esm/security/authentications/services/custom-impls/sso-config-domain-verification.custom-impl.backend.service.js +65 -24
  200. package/dist/esm/security/authentications/services/custom-impls/sso-config-domain-verification.custom-impl.backend.service.js.map +1 -1
  201. package/dist/esm/security/authorizations/super-admin-floor.backend.utils.d.ts +64 -1
  202. package/dist/esm/security/authorizations/super-admin-floor.backend.utils.d.ts.map +1 -1
  203. package/dist/esm/security/authorizations/super-admin-floor.backend.utils.js +84 -2
  204. package/dist/esm/security/authorizations/super-admin-floor.backend.utils.js.map +1 -1
  205. package/dist/esm/security/oauth-clients/oauth-clients.custom-impl.backend.service.d.ts +14 -0
  206. package/dist/esm/security/oauth-clients/oauth-clients.custom-impl.backend.service.d.ts.map +1 -1
  207. package/dist/esm/security/oauth-clients/oauth-clients.custom-impl.backend.service.js +13 -5
  208. package/dist/esm/security/oauth-clients/oauth-clients.custom-impl.backend.service.js.map +1 -1
  209. package/dist/esm/users/services/anonymous-consent.custom-impl.backend.service.d.ts.map +1 -1
  210. package/dist/esm/users/services/anonymous-consent.custom-impl.backend.service.js +6 -2
  211. package/dist/esm/users/services/anonymous-consent.custom-impl.backend.service.js.map +1 -1
  212. package/dist/esm/users/services/user-force-password-reset.custom-impl.backend.service.d.ts +7 -0
  213. package/dist/esm/users/services/user-force-password-reset.custom-impl.backend.service.d.ts.map +1 -1
  214. package/dist/esm/users/services/user-force-password-reset.custom-impl.backend.service.js +65 -20
  215. package/dist/esm/users/services/user-force-password-reset.custom-impl.backend.service.js.map +1 -1
  216. package/dist/esm/users/services/user-role-administration.custom-impl.backend.service.d.ts.map +1 -1
  217. package/dist/esm/users/services/user-role-administration.custom-impl.backend.service.js +11 -4
  218. package/dist/esm/users/services/user-role-administration.custom-impl.backend.service.js.map +1 -1
  219. package/dist/esm/users/services/user-self-custom-implementations.backend.d.ts.map +1 -1
  220. package/dist/esm/users/services/user-self-custom-implementations.backend.js +4 -2
  221. package/dist/esm/users/services/user-self-custom-implementations.backend.js.map +1 -1
  222. package/dist/esm/users/services/user-super-admin-floor.custom-impl.backend.service.d.ts.map +1 -1
  223. package/dist/esm/users/services/user-super-admin-floor.custom-impl.backend.service.js +16 -0
  224. package/dist/esm/users/services/user-super-admin-floor.custom-impl.backend.service.js.map +1 -1
  225. package/dist/tsconfig.build.tsbuildinfo +1 -1
  226. package/package.json +10 -10
@@ -1 +1 @@
1
- {"version":3,"file":"http-server.backend.service.js","sourceRoot":"","sources":["../../../../src/runtime/services/http-server.backend.service.ts"],"names":[],"mappings":"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","sourcesContent":["import 'reflect-metadata';\nimport { injectable, inject, optional } from 'inversify';\nimport express, { Express, Request, Response, NextFunction, Router } from 'express';\nimport cors from 'cors';\nimport { createCorsOriginDecider } from '~wildo-backend-lib/organizations/custom-domains/custom-domain-origin-admission.backend.utils';\nimport type { CustomDomainHostResolverBackendService } from '~wildo-backend-lib/organizations/custom-domains/custom-domain-host-resolver.backend.service';\nimport { buildTraefikDynamicConfiguration, isInternalEdgeRequest, type CustomDomainEdgeBackendService } from '~wildo-backend-lib/organizations/custom-domains/custom-domain-edge.backend.service';\nimport cookieParser from 'cookie-parser';\nimport helmet from 'helmet';\nimport compression from 'compression';\nimport { Server } from 'http';\nimport type { Server as NetServer } from 'net';\nimport { z } from 'zod';\nimport { HttpServerEnvKey, parseTrustedProxyHops } from '@wildo-ai/platform-core-shared';\n\nimport { SAAS_SERVICE_TYPES } from '~wildo-backend-lib/inject/models/service-types';\nimport { LoggerService } from '~wildo-backend-lib/monitoring/logger/services/logger.service';\nimport { AppConfigurationService } from '~wildo-backend-lib/config/services/app-configuration.backend.service';\nimport { ControllersRegistryHandlerBackendService } from '~wildo-backend-lib/base-classes/services/controllers/controllers-registry-handler.backend.service';\nimport {\n AbstractControllerBackendService,\n CustomControllerMountPhase,\n} from '~wildo-backend-lib/base-classes/services/controllers/abstract-controller.backend.service';\nimport { ErrorBuilderBackendService } from '~wildo-backend-lib/errors/services/error-builder.backend.service';\nimport { ErrorHandlerService } from '~wildo-backend-lib/errors/services/error-handler.backend.service';\nimport { relaxAbuseThrottleMaxForEnvironment } from '~wildo-backend-lib/errors/utils/rate-limit-environment-relaxation.backend.utils';\nimport { projectCaughtErrorLogFields } from '~wildo-backend-lib/errors/utils/error-log-level-classification.backend.utils';\nimport { applyOAuthBodyCap } from '~wildo-backend-lib/runtime/services/utils/oauth-body-cap.backend.utils';\nimport { applyCspViolationReportBodyCap } from '~wildo-backend-lib/monitoring/csp-violation-reports/csp-violation-report-body-cap.backend.utils';\nimport { ENGINE_CORS_ALLOWED_REQUEST_HEADERS, ENGINE_CORS_EXPOSED_RESPONSE_HEADERS } from '~wildo-backend-lib/runtime/services/utils/engine-cors-headers.backend.utils';\nimport { applyInboundApplicationEndpointRawBody, retainRawBodyUnder, translateOversizedInboundBody } from '~wildo-backend-lib/runtime/services/utils/inbound-endpoint-raw-body.backend.utils';\nimport { describeUnusableContainerHostGatewayListenHost, openContainerHostGatewayListener } from '~wildo-backend-lib/runtime/services/utils/container-host-gateway-listener.backend.utils';\nimport { RuntimeConfig, RuntimeConfigurationSchema } from '~wildo-backend-lib/runtime/models/runtime.backend.schemas';\nimport { AppConfiguration } from '~wildo-backend-lib/config/models/app-config.backend.schemas';\nimport { BackendApiType, ClientInstanceIdScope, ErrorRequestOutcome, ErrorSeverity, ErrorType, ErrorCustomMessageReference, isAppConfigurationNotInitializedError, WildoHeaderKeys, ENGINE_ROOT_ROUTES, EngineRootRouteKey, MAIN_API_BASE_PATH, MANUAL_CONTROLLER_ROUTES_URLS, ManualControllerRouteKey, rfc8414AuthorizationServerMetadataPath, rfc9728ProtectedResourceMetadataPath, ResourceSerializationUtils, COMPOSE_EDGE_CERT_RESOLVER, COMPOSE_EDGE_SECURE_ENTRYPOINT, type CustomDomainEdgeList } from '@wildo-ai/saas-models';\nimport { WebSocketService } from '~wildo-backend-lib/requests/service/websocket.service';\nimport { HealthControllerBackendService } from '~wildo-backend-lib/runtime/controllers/health-controller.backend.service';\nimport { RedisService } from '~wildo-backend-lib/databases/services/redis.service';\nimport { AuthControllerUtils } from '~wildo-backend-lib/security/authentications/services/utils/auth-controller.utils';\nimport { runWithRequestContext, buildRequestContextFrame, setClientInstanceIdIngestPolicy } from '~wildo-backend-lib/runtime/models/request-context.als.backend';\nimport { getClientIpFromRequest } from '~wildo-backend-lib/runtime/utils/request-client-ip.utils';\nimport { analyzeRouteTable, collectMountedRoutes, MountedRouteOrigin, type MountedRoute } from '~wildo-backend-lib/runtime/services/utils/route-shadowing.backend.utils';\n\n/**\n * HTTP Server Backend Service\n *\n * Orchestrates the Express HTTP server startup with complete configuration\n * management, middleware setup, and route registration.\n *\n * Features:\n * - Express server with configurable middleware stack\n * - CORS, security headers, compression, rate limiting\n * - Integration with ControllersRegistryHandlerBackendService\n * - Support for additional custom controllers\n * - Configuration-driven server setup\n * - Graceful shutdown handling\n * - Health check endpoints\n * - Request logging and error handling\n *\n * Configuration Sources:\n * - AppConfigurationService (platform + admin managed config)\n * - RuntimeConfigurationSchema (HTTP server specific settings)\n * - Environment variables (PORT, HOST overrides)\n */\n/**\n * How long the perimeter limiter stays in its in-memory fallback before the degradation\n * signal is REPEATED (the first request of any outage always signals immediately).\n *\n * Deliberately a fixed wall-clock interval and NOT derived from the configured\n * `rateLimiting.windowMs`: the signal is about the shared counter's OUTAGE, not about the\n * rate-limit window, and an application authoring an hour-long window would otherwise hide\n * an hour of degradation behind a single line. One minute keeps a sustained outage legible\n * to a human tailing logs while staying far away from one line per request.\n */\nexport const SHARED_RATE_LIMIT_COUNTER_DEGRADATION_SIGNAL_INTERVAL_MS: number = 60_000;\n\n/**\n * Stable, greppable identifiers stamped into the `degradation` log field so an operator (or\n * a log-search alert) can select these two lines without matching on prose. Exported so the\n * pinning test asserts the SAME identifier the runtime emits rather than a copied literal —\n * a second copy of a machine-readable code is a second authority that silently drifts.\n */\nexport const PERIMETER_RATE_LIMIT_DEGRADED_SIGNAL: string = 'perimeter_rate_limit_shared_counter_unavailable';\nexport const PERIMETER_RATE_LIMIT_RECOVERED_SIGNAL: string = 'perimeter_rate_limit_shared_counter_recovered';\n\n/**\n * Options for HTTP server initialization\n */\nexport interface HttpServerInitOptions {\n /**\n * Skip WebSocket/Socket.IO initialization.\n * Use this for platform microservices that don't need real-time browser connections.\n * Default: false\n */\n skipWebSocket?: boolean;\n\n /**\n * Skip CORS middleware configuration.\n * Use this for platform microservices that only receive backend-to-backend requests\n * and don't need browser CORS headers.\n * Default: false\n */\n skipCors?: boolean;\n}\n\n@injectable()\nexport class HttpServerBackendService {\n\n private readonly app: Express;\n private server: Server | null = null;\n /**\n * The second listener on the host's Docker bridge gateway (#3387), feeding {@link server}. Opened only when the native\n * LOCAL lane wrote `CONTAINER_HOST_GATEWAY_LISTEN_HOST`; see `container-host-gateway-listener.backend.utils`.\n */\n private containerHostGatewayListener: NetServer | null = null;\n private baseUrl: string | null = null;\n private readonly customControllers: Map<string, AbstractControllerBackendService> = new Map();\n /**\n * Every route this server mounts, in MOUNT ORDER — the order Express tries them in. Recorded at each mount site because\n * Express 5 does not keep the path a router was mounted at; read once, by {@link assertRouteTableInvariant} (#2200).\n */\n private readonly mountedRoutes: MountedRoute[] = [];\n private isInitialized = false;\n private initOptions: HttpServerInitOptions = {};\n\n /**\n * Route prefixes whose handlers require the EXACT original request bytes\n * (not a re-serialized copy). The global `express.json` `verify` hook retains\n * `req.rawBody` ONLY for requests matching one of these prefixes; for all\n * other traffic the raw buffer is GC-eligible the moment `JSON.parse`\n * returns, exactly as before — so normal API calls pay no retained-memory\n * cost, only a cheap `startsWith` check.\n *\n * Today the sole raw-body-in surface is inbound webhook signature\n * verification, for JSON and form bodies alike (`retainRawBodyUnder`): `WebhookAutoControllerBackendService` registers\n * `POST /webhooks/{provider}/{endpoint}` under the master router at\n * `MAIN_API_BASE_PATH`, so the live prefix is `${MAIN_API_BASE_PATH}/webhooks/`.\n * Add to this list if another surface ever needs byte-faithful bodies.\n */\n private readonly rawBodyRequiredPrefixes: readonly string[] = [\n `${MAIN_API_BASE_PATH}/webhooks/`,\n ];\n\n protected readonly logDebug: (message: string, context?: Record<string, unknown>) => void;\n\n constructor(\n @inject(SAAS_SERVICE_TYPES.Logger) private readonly logger: LoggerService,\n @inject(SAAS_SERVICE_TYPES.AppConfigService) private readonly appConfigService: AppConfigurationService,\n @inject(SAAS_SERVICE_TYPES.ControllersRegistryHandlerService) private readonly controllersRegistry: ControllersRegistryHandlerBackendService,\n @inject(SAAS_SERVICE_TYPES.ErrorBuilderService) private readonly errorBuilder: ErrorBuilderBackendService,\n @inject(SAAS_SERVICE_TYPES.ErrorHandlerService) private readonly errorHandler: ErrorHandlerService,\n @inject(SAAS_SERVICE_TYPES.WebSocketService) private readonly webSocketService: WebSocketService,\n @inject(SAAS_SERVICE_TYPES.HealthController) private readonly healthController: HealthControllerBackendService,\n @inject(SAAS_SERVICE_TYPES.RedisService) private readonly redisService: RedisService,\n // #2974: which organization a custom domain answers for. Optional: a platform service binds none, and then only\n // the configured frontends are admitted.\n @inject(SAAS_SERVICE_TYPES.CustomDomainHostResolverService) @optional()\n private readonly customDomainHostResolver?: Pick<CustomDomainHostResolverBackendService, 'resolveOrigin'>,\n // #2974: what the deployment's edge must route for the served custom domains.\n @inject(SAAS_SERVICE_TYPES.CustomDomainEdgeService) @optional()\n private readonly customDomainEdge?: Pick<CustomDomainEdgeBackendService, 'servedDomains'>,\n ) {\n\n this.app = express();\n\n this.logDebug = this.logger.debugByType('HttpServer');\n this.logger.setDebugTypeLogging('HttpServer', false);\n\n this.logDebug('HTTP server service created');\n }\n\n public async initialize(options?: HttpServerInitOptions): Promise<void> {\n if (this.isInitialized) {\n this.logDebug('HTTP server already initialized');\n return;\n }\n\n // Store options for use in startServer()\n this.initOptions = options || {};\n\n try {\n this.logDebug('🚀 Initializing HTTP server...');\n\n // Get app configuration\n // Note: AppConfigurationService should be initialized before HTTP server in normal flow\n // but we check gracefully to provide better error messages\n const appConfig = this.appConfigService.isInitialized()\n ? this.appConfigService.config\n : null;\n\n if (!appConfig) {\n this.logger.error('HTTP server initialization attempted before app config initialized');\n throw this.errorBuilder.buildError(\n ErrorType.CONFIGURATION,\n undefined,\n {\n customMessageReference: ErrorCustomMessageReference.CONFIGURATION,\n context: {\n message: 'Application configuration must be initialized before starting HTTP server',\n service: 'HttpServerBackendService',\n operation: 'initialize'\n }\n }\n );\n }\n\n const runtimeConfig = this.extractRuntimeConfig(appConfig);\n\n // Setup Express application\n try {\n await this.setupExpressApp(runtimeConfig);\n } catch (error: any) {\n if (isAppConfigurationNotInitializedError(error)) {\n throw this.errorBuilder.buildError(ErrorType.INFRASTRUCTURE, undefined, {\n customMessageReference: ErrorCustomMessageReference.HTTP_SERVER_INITIALIZATION_FAILED,\n context: { step: 'setupExpressApp', message: error.context.message },\n stack: error.stack,\n });\n }\n throw error;\n }\n\n // Register all routes\n try {\n await this.registerRoutes();\n } catch (error: any) {\n if (isAppConfigurationNotInitializedError(error)) {\n throw this.errorBuilder.buildError(ErrorType.INFRASTRUCTURE, undefined, {\n customMessageReference: ErrorCustomMessageReference.HTTP_SERVER_INITIALIZATION_FAILED,\n context: { step: 'registerRoutes', message: error.context.message },\n stack: error.stack,\n });\n }\n throw error;\n }\n\n // Setup error handling\n try {\n this.setupErrorHandling();\n } catch (error: any) {\n if (isAppConfigurationNotInitializedError(error)) {\n throw this.errorBuilder.buildError(ErrorType.INFRASTRUCTURE, undefined, {\n customMessageReference: ErrorCustomMessageReference.HTTP_SERVER_INITIALIZATION_FAILED,\n context: { step: 'setupErrorHandling', message: error.context.message },\n stack: error.stack,\n });\n }\n throw error;\n }\n\n // Start the server\n try {\n await this.startServer();\n } catch (error: any) {\n if (isAppConfigurationNotInitializedError(error)) {\n throw this.errorBuilder.buildError(ErrorType.INFRASTRUCTURE, undefined, {\n customMessageReference: ErrorCustomMessageReference.HTTP_SERVER_INITIALIZATION_FAILED,\n context: { step: 'startServer', message: error.context.message },\n stack: error.stack,\n });\n }\n throw error;\n }\n\n this.isInitialized = true;\n this.logDebug('✅ HTTP server initialized successfully at ' + this.getServerInfo());\n\n } catch (error) {\n // Initialization failures are propagated to the runtime host, which owns\n // the single structured startup-failure record.\n throw error;\n }\n }\n\n /**\n * Register a custom controller\n */\n public registerCustomController(controller: AbstractControllerBackendService): void {\n const controllerName = controller.getControllerName();\n const mountPhase = controller.getCustomControllerMountPhase();\n\n if (this.customControllers.has(controllerName)) {\n const error = this.errorBuilder.buildError(\n ErrorType.VALIDATION,\n undefined,\n {\n customMessageReference: ErrorCustomMessageReference.HTTP_SERVER_INITIALIZATION_FAILED,\n context: {\n controllerName\n }\n }\n );\n throw error;\n }\n\n if (this.isInitialized && mountPhase !== CustomControllerMountPhase.STANDARD) {\n throw this.errorBuilder.buildError(\n ErrorType.VALIDATION,\n undefined,\n {\n customMessageReference: ErrorCustomMessageReference.HTTP_SERVER_INITIALIZATION_FAILED,\n context: {\n controllerName,\n mountPhase,\n reason: 'Early-phase custom controllers must be registered before HTTP server initialization',\n },\n },\n );\n }\n\n this.customControllers.set(controllerName, controller);\n\n this.logDebug('Custom controller registered', {\n controllerName,\n mountPhase,\n totalCustomControllers: this.customControllers.size\n });\n\n // Only STANDARD controllers can reach this late-registration path. An\n // early phase is a strict ordering contract and is refused above rather\n // than silently mounted after the middleware it must precede.\n if (this.isInitialized) {\n this.mountCustomController(controller);\n }\n }\n\n /**\n * Get the Express application instance\n */\n public getApp(): Express {\n return this.app;\n }\n\n /**\n * Check if server is running\n */\n public isRunning(): boolean {\n return this.server !== null && this.server.listening;\n }\n\n /**\n * Get server listening information\n */\n public getServerInfo(): string | null {\n if (!this.server || !this.server.listening) {\n return null;\n }\n return this.baseUrl;\n }\n\n /**\n * Gracefully shutdown the server\n */\n public async shutdown(): Promise<void> {\n if (!this.server) {\n return;\n }\n\n // Cleanup WebSocket service first\n await this.webSocketService.cleanup();\n this.logDebug('WebSocket service cleaned up');\n\n // Stop accepting through the bridge gateway before the server itself closes (#3387).\n if (this.containerHostGatewayListener) {\n const listener = this.containerHostGatewayListener;\n this.containerHostGatewayListener = null;\n await new Promise<void>((resolve) => listener.close(() => resolve()));\n }\n\n return new Promise((resolve, reject) => {\n this.logDebug('🔄 Shutting down HTTP server...');\n\n this.server!.close((error) => {\n if (error) {\n this.logger.error('❌ HTTP server shutdown failed:', error);\n reject(error);\n } else {\n this.logDebug('✅ HTTP server shutdown completed');\n this.server = null;\n this.isInitialized = false;\n resolve();\n }\n });\n });\n }\n\n // ================================\n // Private Setup Methods\n // ================================\n\n /**\n * Extract runtime configuration with defaults.\n *\n * Reads the optional `runtime.httpServerConfiguration` partial override\n * declared on `AppConfiguration_RuntimeSchema` (see\n * `appConfiguration_Backend_RuntimeSchemaBuilder` in `app-config.backend.schemas.ts`)\n * and feeds it through `RuntimeConfigurationSchema.parse` so any missing\n * fields fall back to the framework defaults (`requestTimeout: 300_000`,\n * `headersTimeout: 60_000`, etc.).\n *\n * App authors generally do not author this surface. The dev companion\n * sets `requestTimeout` and `headersTimeout` to ~30 min because its\n * LLM-bound endpoints legitimately exceed the 5-min default.\n */\n private extractRuntimeConfig(appConfig: AppConfiguration): RuntimeConfig {\n try {\n const runtimeData = appConfig.runtime.httpServerConfiguration ?? {};\n return RuntimeConfigurationSchema.parse({\n httpServerConfiguration: runtimeData,\n });\n } catch (error) {\n this.logger.warn('Using default runtime configuration due to validation error:', error);\n return RuntimeConfigurationSchema.parse({ httpServerConfiguration: {} });\n }\n }\n\n /**\n * Setup Express application with middleware\n *\n * IMPORTANT: Middleware ordering matters!\n * 1. Security headers are installed before every custom route.\n * 2. PRE_REQUEST_TRANSFORM controllers mount before CORS/preflight and parsers.\n * 3. RAW_REQUEST_STREAM controllers mount after CORS/rate limiting but before body parsing.\n * 4. Body parsing middleware is applied.\n * 5. STANDARD controllers mount through registerRoutes().\n *\n * This ensures streaming controllers receive raw request streams\n * while regular controllers get parsed request bodies.\n */\n /**\n * Trust exactly the reverse proxies the DEPLOYMENT put in front of this process (#1788).\n *\n * The hop count is rendered into the environment by the lane that placed the proxy, like HOST and PORT,\n * because an application cannot know how it is fronted. Until this, a boolean in the application config\n * chose it, nothing ever set it, and behind an ingress every client shared the ingress's address — one\n * bucket for every per-IP lockout and rate limit. Zero (the default) trusts no proxy: a hop that is not\n * really there would let a client choose its own address through `X-Forwarded-For`. A malformed value\n * refuses to start, since both of the silent readings are wrong.\n */\n private applyTrustedProxyHops(env: NodeJS.ProcessEnv): void {\n const trustedProxyHops = parseTrustedProxyHops(env[HttpServerEnvKey.HTTP_TRUSTED_PROXY_HOPS]);\n if (trustedProxyHops > 0) {\n this.app.set('trust proxy', trustedProxyHops);\n }\n }\n\n private async setupExpressApp(runtimeConfig: RuntimeConfig): Promise<void> {\n const httpConfig = runtimeConfig.httpServerConfiguration;\n\n this.applyTrustedProxyHops(process.env);\n\n // Disable ETag if configured\n if (!httpConfig.etag) {\n this.app.set('etag', false);\n }\n\n // Defense-in-depth for bigint-safe `res.json`. The primary mechanism is the\n // type-level `BigInt.prototype.toJSON` (bigint → decimal string) installed at\n // the `@wildo-ai/zod-decorators` bootstrap (`installBigIntJsonEncoding`), which\n // makes EVERY JSON boundary bigint-safe the way `Date.prototype.toJSON` does.\n // This app-level `json replacer` is a zero-cost belt-and-suspenders that keeps\n // `res.json` safe even if that bootstrap ever fails to run before the first\n // response. `z_money` amounts are `bigint`; without either, a money-bearing\n // response (prices, invoices, promotions, …) 500s with \"Do not know how to\n // serialize a BigInt\". Encoding as a decimal STRING (not `number`) is the\n // documented wire contract — lossless round-trip; the frontend coerces it back\n // to `bigint` on receive. The replacer runs inside Express's own\n // `JSON.stringify` and composes idempotently with the prototype `toJSON`.\n this.app.set('json replacer', ResourceSerializationUtils.bigIntSafeJsonReplacer);\n\n // Security headers protect every route, including controllers that must own\n // their method contract before CORS preflight or body parsing can terminate.\n this.setupSecurity(httpConfig.headers);\n\n // Enter the request-context ALS as early as possible — right after security headers and before any\n // controller, CORS, body parsing, routing, or the error handler — so the ENTIRE async continuation\n // of the request (including deep, un-threaded service errors) carries the correlation id.\n // Install the client-install ingest policy BEFORE the first frame can be built, so no request is\n // ever served under the uninitialized resolver. (The resolver itself also fails closed, making\n // this ordering belt-and-braces rather than load-bearing.)\n this.installClientInstanceIdIngestPolicy();\n this.setupRequestContext();\n\n this.mountCustomControllersForPhase(CustomControllerMountPhase.PRE_REQUEST_TRANSFORM);\n\n // Setup CORS (skip for platform microservices that only receive backend-to-backend requests)\n if (this.initOptions.skipCors) {\n this.logDebug('CORS middleware skipped (platform service mode)');\n } else {\n this.setupCORS(httpConfig.cors);\n }\n\n // Setup compression\n if (httpConfig.compression) {\n this.app.use(compression() as any);\n }\n\n // Setup rate limiting\n this.setupRateLimit(httpConfig.rateLimiting);\n\n // True streaming controllers still receive raw request streams, while\n // retaining the ordinary CORS and rate-limiting boundary.\n this.mountCustomControllersForPhase(CustomControllerMountPhase.RAW_REQUEST_STREAM);\n\n // Body parsing middleware - only affects routes registered AFTER this point\n this.setupBodyParsing(httpConfig);\n\n // Setup request logging\n this.setupRequestLogging();\n\n this.logDebug('Express middleware setup completed');\n }\n\n /** Mount all custom controllers assigned to one exact middleware phase. */\n private mountCustomControllersForPhase(phase: CustomControllerMountPhase): void {\n const controllers = [...this.customControllers.values()].filter((controller) => controller.getCustomControllerMountPhase() === phase);\n for (const controller of controllers) {\n this.mountCustomController(controller);\n }\n if (controllers.length > 0) {\n this.logDebug('Custom controllers mounted for middleware phase', {\n phase,\n count: controllers.length,\n controllers: controllers.map((controller) => controller.getControllerName()),\n });\n }\n }\n\n /**\n * Setup CORS middleware\n *\n * Derives allowed origins from app config's runtime.endPoints (frontend app URLs)\n * to properly support credentials (cookies/tokens) which require explicit origins.\n *\n * For platform services that don't serve frontends (e.g., crontabs-batches-manager),\n * CORS is configured permissively since they only receive internal backend requests.\n *\n * IMPORTANT: When credentials are enabled, origin CANNOT be '*' per CORS spec.\n */\n private setupCORS(corsConfig: RuntimeConfig['httpServerConfiguration']['cors']): void {\n // The engine floors live in `engine-cors-headers.backend.utils.ts`, where a test holds them against the headers the\n // engine's own browser code sends and reads (#3171).\n const mergedExposedHeaders = [\n ...ENGINE_CORS_EXPOSED_RESPONSE_HEADERS,\n ...(corsConfig.exposedHeaders ?? []),\n ];\n const mergedAllowedHeaders = [\n ...ENGINE_CORS_ALLOWED_REQUEST_HEADERS,\n ...(corsConfig.allowedHeaders ?? []),\n ];\n\n // Derive CORS origins from app config (same logic as WebSocketService)\n const allowedOrigins = this.deriveCorsOrigins();\n\n // If no frontend URLs are configured, use permissive CORS (for platform services)\n // Platform services like crontabs-batches-manager only receive internal backend requests,\n // not browser requests, so CORS doesn't apply. We use permissive config to avoid errors.\n if (allowedOrigins.length === 0) {\n this.logger.info('📝 No frontend URLs configured - using permissive CORS (platform/internal service mode)', {\n availableEndpoints: Object.keys(this.appConfigService.config?.runtime?.endPoints || {}),\n note: 'This is expected for platform services that only receive backend-to-backend requests'\n });\n\n this.app.use(cors({\n origin: '*', // Permissive for internal services\n credentials: false, // No credentials with wildcard origin\n methods: corsConfig.methods,\n allowedHeaders: mergedAllowedHeaders,\n exposedHeaders: mergedExposedHeaders,\n maxAge: corsConfig.maxAge,\n preflightContinue: corsConfig.preflightContinue,\n optionsSuccessStatus: corsConfig.optionsSuccessStatus\n }));\n\n this.logger.info('✅ CORS middleware configured (permissive mode for internal service)', {\n origin: '*',\n credentials: false\n });\n return;\n }\n\n this.app.use(cors({\n // The configured frontends, then any organization's served custom domain (#2974), decided per request.\n origin: createCorsOriginDecider({ configuredOrigins: allowedOrigins, resolver: this.customDomainHostResolver }),\n credentials: true,\n methods: corsConfig.methods,\n allowedHeaders: mergedAllowedHeaders,\n exposedHeaders: mergedExposedHeaders,\n maxAge: corsConfig.maxAge,\n preflightContinue: corsConfig.preflightContinue,\n optionsSuccessStatus: corsConfig.optionsSuccessStatus\n }));\n\n this.logger.info('✅ CORS middleware configured successfully', {\n allowedOrigins,\n credentials: true\n });\n }\n\n /**\n * Derive CORS origins from app config (frontend application URLs).\n * Reads the configured `frontendServices` to know which frontend surfaces exist,\n * then looks up their publicUrl from `runtime.endPoints`.\n *\n * @returns Array of frontend URLs, or empty array if not configured\n */\n private deriveCorsOrigins(): string[] {\n const config = this.appConfigService.config;\n const frontendServices = Object.keys(config.frontendServices ?? {});\n return frontendServices.map((frontendServiceName) => {\n const url = config.runtime?.endPoints?.[frontendServiceName]?.publicUrl;\n if (!url) {\n throw this.errorBuilder.buildError(ErrorType.CONFIGURATION, undefined, {\n context: {\n message:\n `Missing runtime.endPoints.${frontendServiceName}.publicUrl for declared frontend service \"${frontendServiceName}\". ` +\n `CORS cannot be derived safely from an incomplete runtime topology.`,\n frontendServiceName,\n },\n });\n }\n return AuthControllerUtils.stripTrailingSlash(url);\n });\n }\n\n /**\n * Setup security headers\n */\n private setupSecurity(headersConfig: RuntimeConfig['httpServerConfiguration']['headers']): void {\n const helmetOptions: any = {\n // M16: CSP now defaults to a sensible baseline via schema default. Empty string explicitly disables.\n // C2 fix: Trim whitespace to treat \" \" as empty (disabled), not as a truthy but invalid CSP.\n contentSecurityPolicy: headersConfig.contentSecurityPolicy.trim() ? {\n directives: this.parseCSP(headersConfig.contentSecurityPolicy.trim()),\n } : false,\n hsts: headersConfig.hsts ? {\n maxAge: headersConfig.hstsMaxAge,\n includeSubDomains: true,\n preload: true\n } : false,\n noSniff: headersConfig.noSniff,\n referrerPolicy: { policy: headersConfig.referrerPolicy }\n };\n\n this.app.use(helmet(helmetOptions));\n\n this.logDebug('Security middleware configured', { headersConfig });\n }\n\n /**\n * Setup rate limiting.\n *\n * M17: Uses Redis-backed atomic INCR+EXPIRE for distributed rate limiting.\n * Falls back to in-memory Map when Redis is unavailable (single-instance dev mode).\n *\n * Entering and leaving that fallback are both SIGNALLED (debounced `warn` lines carrying\n * `degradation: PERIMETER_RATE_LIMIT_{DEGRADED,RECOVERED}_SIGNAL`) — see the long comment\n * beside the signal state below for the destination, level and debounce reasoning. The\n * fallback silently converted a deployment-wide ceiling into a per-replica one, and the\n * one-time boot line at the end of this method cannot tell an operator whether it is in\n * effect right now.\n */\n private setupRateLimit(rateLimitConfig: RuntimeConfig['httpServerConfiguration']['rateLimiting']): void {\n const windowSeconds = Math.ceil(rateLimitConfig.windowMs / 1000);\n // In-memory fallback for when Redis is down\n const fallbackRequests = new Map<string, { count: number; resetTime: number }>();\n\n // Non-production relaxation of the perimeter ceiling (shared seam — see\n // `rate-limit-environment-relaxation.backend.utils`). Resolved ONCE here rather than\n // per-request: `setupRateLimit` runs inside `initialize()`, which has already refused\n // to proceed unless `AppConfigurationService` is initialized, so `applicationEnv` is\n // guaranteed readable at this point and a per-request read would only add cost.\n //\n // This limiter keys on the raw client IP by construction, which is exactly why a dev\n // machine needs the relaxation: every local process (frontend, e2e driver, companion,\n // client-integration-app) presents as `127.0.0.1` and shares one bucket, so the\n // authored per-client ceiling behaves as a per-MACHINE ceiling locally.\n const effectiveMaxRequests = relaxAbuseThrottleMaxForEnvironment(\n rateLimitConfig.maxRequests,\n this.appConfigService.applicationEnv,\n );\n\n // ---------------------------------------------------------------------------------\n // Shared-counter degradation signal.\n //\n // The in-memory fallback below is DELIBERATE and stays. The perimeter limiter is a\n // noisy-neighbour preventer, not the security boundary — that is the per-endpoint\n // `RateLimitBackendService`, which fail-CLOSES and propagates `ErrorType.DATABASE`\n // when the shared counter is unavailable (see its file docstring, which names this\n // limiter as the deliberate fail-OPEN exception). So a Redis outage must not take the\n // application off the air.\n //\n // What was missing is any way for an operator to learn that it engaged, and the\n // consequence is not cosmetic: once every replica counts in its own process memory,\n // an authored ceiling of N is enforced N × replicas times globally, and it resets on\n // every restart. A deployment can therefore sit at several times its stated cap\n // indefinitely with nothing anywhere to read.\n //\n // DESTINATION — the logger, and only the logger. It is the one channel that provably\n // works while the shared counter is down: pino writes to stdout and, through the\n // OTLP log bridge wired in `otel-preload`, on to the collector — with no dependency\n // on Redis, on a repository, or on any other service. Rejected:\n // · an audit/SIEM row — a persisted write on the perimeter hot path, requiring a\n // SECOND subsystem to be healthy for a signal whose whole premise is that a\n // subsystem is not; and this is an infrastructure diagnostic, not a\n // security-authority decision;\n // · a readiness contribution — readiness is a REFUSAL. Turning a fallback that\n // exists to keep serving into a 503 gets the process respawned by the\n // supervisor, which is strictly worse than the degradation it reports;\n // · `this.logDebug` — this service ships with `HttpServer` debug logging OFF, so\n // the signal would be invisible in exactly the deployments that need it.\n //\n // LEVEL — `warn` for BOTH the degradation and the recovery. The cap is still enforced,\n // only its scope narrowed, and a single-instance development stack with no Redis\n // legitimately runs here from its first request; an `error` on every dev boot is how\n // a channel stops being read. Recovery shares the level on purpose: emitting it any\n // lower would let a `warn` threshold show an operator the degradation and never its\n // end, which is worse than not signalling at all.\n //\n // DEBOUNCE — one line on the first fallback request of an outage, then at most one more\n // per `SHARED_RATE_LIMIT_COUNTER_DEGRADATION_SIGNAL_INTERVAL_MS`, each carrying how\n // many requests the fallback served since the previous line so the VOLUME stays\n // legible without a line per request. A new outage always signals immediately, even\n // if the previous outage's line is only seconds old — otherwise a flapping counter\n // would be reported once and then muted.\n // ---------------------------------------------------------------------------------\n let sharedCounterDegradedSince: number | null = null;\n let degradationSignalLastEmittedAt = 0;\n // Two counters, because the two lines answer different questions. The degradation line\n // answers \"how loud is this right now\" (volume BETWEEN lines, so it resets on every\n // emit); the recovery line answers \"how much traffic was actually capped per replica\"\n // (the whole outage, so it resets only at the transitions).\n let fallbackRequestsSinceLastSignal = 0;\n let fallbackRequestsThisOutage = 0;\n\n const noteSharedCounterUnavailable = (now: number, cause: unknown): void => {\n // Both count the CURRENT request, so the first line of an outage reports 1.\n fallbackRequestsSinceLastSignal++;\n fallbackRequestsThisOutage++;\n\n const isFirstRequestOfThisOutage = sharedCounterDegradedSince === null;\n if (isFirstRequestOfThisOutage) {\n sharedCounterDegradedSince = now;\n } else if (now - degradationSignalLastEmittedAt < SHARED_RATE_LIMIT_COUNTER_DEGRADATION_SIGNAL_INTERVAL_MS) {\n return;\n }\n\n // Debounce state is advanced BEFORE the emit, and the emit itself cannot throw out of\n // here. Both halves matter and neither is defensive habit:\n // · this runs inside the limiter's own `try`, whose `catch` calls `next(error)` — so\n // a logger that throws (a closed stdout, an EPIPE on a detached process) would turn\n // every request into a 500 for the duration of a Redis outage. A diagnostic must\n // never be able to refuse the traffic it is describing;\n // · advancing the state first means a throwing logger degrades to SILENCE with the\n // debounce intact, rather than re-attempting the same throwing call on every\n // subsequent request.\n const requestsCoveredByThisSignal = fallbackRequestsSinceLastSignal;\n const degradedForMs = now - sharedCounterDegradedSince;\n degradationSignalLastEmittedAt = now;\n fallbackRequestsSinceLastSignal = 0;\n\n try {\n this.logger.warn(\n 'Perimeter rate limiting degraded to per-replica in-memory counting: the shared counter is unavailable, '\n + 'so the configured ceiling is enforced per process instead of across the deployment and resets on restart.',\n {\n degradation: PERIMETER_RATE_LIMIT_DEGRADED_SIGNAL,\n effectiveMaxRequests,\n windowMs: rateLimitConfig.windowMs,\n enforcementScope: 'per-replica-in-memory',\n degradedForMs,\n fallbackRequestsSinceLastSignal: requestsCoveredByThisSignal,\n nextSignalNotBeforeMs: SHARED_RATE_LIMIT_COUNTER_DEGRADATION_SIGNAL_INTERVAL_MS,\n ...projectCaughtErrorLogFields(cause),\n },\n );\n } catch {\n // Nothing to escalate to: the logger IS the escalation channel.\n }\n };\n\n const noteSharedCounterAvailable = (now: number): void => {\n // The happy path pays one null check per request; everything below runs once per\n // recovery, at the transition only.\n if (sharedCounterDegradedSince === null) return;\n\n // Same ordering and same guard as the degradation emit above, for the same two\n // reasons: state first so a throwing logger cannot re-attempt on every later request,\n // and no throw out of a diagnostic sitting on the request path.\n const degradedForMs = now - sharedCounterDegradedSince;\n const fallbackRequestsServedDuringOutage = fallbackRequestsThisOutage;\n sharedCounterDegradedSince = null;\n degradationSignalLastEmittedAt = 0;\n fallbackRequestsSinceLastSignal = 0;\n fallbackRequestsThisOutage = 0;\n\n try {\n this.logger.warn(\n 'Perimeter rate limiting recovered: the shared counter answered again, so the configured ceiling is '\n + 'once more enforced across the deployment.',\n {\n degradation: PERIMETER_RATE_LIMIT_RECOVERED_SIGNAL,\n effectiveMaxRequests,\n enforcementScope: 'shared-counter',\n degradedForMs,\n fallbackRequestsServedDuringOutage,\n },\n );\n } catch {\n // Nothing to escalate to: the logger IS the escalation channel.\n }\n };\n\n const limiter = async (req: Request, res: Response, next: NextFunction) => {\n try {\n const clientId = req.ip || 'unknown';\n const now = Date.now();\n\n let count: number;\n let retryAfterSeconds: number;\n\n try {\n // M17: Redis-backed rate limiting — works across multiple instances\n const identifier = `http_rate_limit:${clientId}`;\n count = await this.redisService.incrementRateLimit(\n identifier,\n windowSeconds,\n );\n // The shared counter answered. If we were in the fallback, this is the recovery\n // transition — signalled here rather than after the TTL lookup below, because a\n // failing TTL degrades only the accuracy of `Retry-After`; the COUNTER, which is\n // what makes the cap deployment-wide, is demonstrably back.\n noteSharedCounterAvailable(now);\n try {\n const ttl = await this.redisService.getRateLimitTtl(identifier);\n retryAfterSeconds = ttl >= 0 ? ttl : windowSeconds;\n } catch {\n retryAfterSeconds = windowSeconds;\n }\n } catch (sharedCounterError) {\n // Fallback to in-memory when Redis is unavailable.\n // Mirrors Redis INCR+EXPIRE fixed-window: window starts on first request,\n // resets after windowMs elapses (not a sliding window).\n //\n // The caught value is bound (this was a bare `catch {}`) so the degradation\n // signal can carry WHY the shared counter refused — a connection refusal, a\n // timeout and an auth failure need different operator responses, and without the\n // cause the line only says that something is wrong.\n noteSharedCounterUnavailable(now, sharedCounterError);\n\n for (const [key, value] of fallbackRequests.entries()) {\n if (now >= value.resetTime) fallbackRequests.delete(key);\n }\n let record = fallbackRequests.get(clientId);\n if (!record || now >= record.resetTime) {\n record = { count: 0, resetTime: now + rateLimitConfig.windowMs };\n fallbackRequests.set(clientId, record);\n }\n record.count++;\n count = record.count;\n retryAfterSeconds = Math.max(0, Math.ceil((record.resetTime - now) / 1000));\n }\n\n if (count > effectiveMaxRequests) {\n res.set('Retry-After', retryAfterSeconds.toString());\n\n if (rateLimitConfig.standardHeaders) {\n res.set({\n [WildoHeaderKeys.RATE_LIMIT_LIMIT]: effectiveMaxRequests.toString(),\n [WildoHeaderKeys.RATE_LIMIT_REMAINING]: '0',\n [WildoHeaderKeys.RATE_LIMIT_RESET]: retryAfterSeconds.toString(),\n });\n }\n\n return res.status(429).json({\n error: {\n type: ErrorType.RATE_LIMIT,\n severity: ErrorSeverity.MEDIUM,\n message: ErrorCustomMessageReference.RATE_LIMIT,\n customMessage: ErrorCustomMessageReference.RATE_LIMIT,\n customMessageReference: ErrorCustomMessageReference.RATE_LIMIT,\n timestamp: new Date(now).toISOString(),\n // The perimeter limiter answers before any route runs: nothing was applied, so a client may resend (#3004).\n requestOutcome: ErrorRequestOutcome.NOT_APPLIED,\n details: {\n message: rateLimitConfig.message,\n retryAfterSeconds,\n },\n },\n });\n }\n\n if (rateLimitConfig.standardHeaders) {\n res.set({\n [WildoHeaderKeys.RATE_LIMIT_LIMIT]: effectiveMaxRequests.toString(),\n [WildoHeaderKeys.RATE_LIMIT_REMAINING]: (effectiveMaxRequests - count).toString(),\n [WildoHeaderKeys.RATE_LIMIT_RESET]: retryAfterSeconds.toString(),\n });\n }\n\n next();\n } catch (error) {\n // Express 4 doesn't handle async middleware errors — forward to error handler\n next(error);\n }\n };\n\n this.app.use(limiter);\n\n this.logDebug('Rate limiting configured (Redis-backed with in-memory fallback)', { rateLimitConfig });\n }\n\n /**\n * Setup body parsing middleware.\n *\n * IMPORTANT: PRE_REQUEST_TRANSFORM and RAW_REQUEST_STREAM controllers are\n * mounted before this middleware, so they never see body parsing.\n */\n private setupBodyParsing(httpConfig: RuntimeConfig['httpServerConfiguration']): void {\n // Capture the raw, unparsed request bytes into `req.rawBody` during JSON\n // parsing. Handlers that need the EXACT original payload — inbound webhook\n // HMAC signature verification (Stripe et al.), which must hash the\n // provider's literal bytes, not a re-serialized copy — read `req.rawBody`.\n //\n // This is express.json's canonical `verify` extension point: it runs\n // synchronously with a reference to the buffer express is about to parse,\n // so it adds no extra read and retains the buffer only for the request's\n // lifetime.\n //\n // WHY the single global parse point is the correct home (not per-route):\n // this global `express.json` runs BEFORE the main controllers registry\n // mounts (see `registerRoutes` → `MAIN_API_BASE_PATH`). It therefore always\n // parses the body and sets `req._body = true`, which turns any downstream\n // per-route `express.raw()` into a silent no-op. Non-streaming controllers\n // (e.g. the auto-registered webhook routes, which reach Express via the\n // master router — NOT a `RAW_REQUEST_STREAM` controller phase) can only\n // obtain byte-faithful bodies from this hook.\n //\n // PERF: retention is SCOPED to `rawBodyRequiredPrefixes` (webhooks only).\n // On every other route the raw buffer is not referenced, so it stays\n // GC-eligible the moment `JSON.parse` returns — normal API traffic pays\n // only a cheap `startsWith` check, never a retained copy of its own body.\n // Tight, prefix-scoped body cap for the OAuth credential/token endpoints + a translator that reports an\n // over-limit / malformed body as a clean 4xx instead of an INTERNAL 500. Registered BEFORE the global\n // parsers so its 32 KB limit governs `/oauth/*` (the scoped parser sets `req._body`, the global one then\n // skips the already-parsed body). Extracted for isolated testing — see `applyOAuthBodyCap` + its tests.\n applyOAuthBodyCap(this.app, MAIN_API_BASE_PATH);\n // Application inbound endpoints take their body raw, so the receiver audits a malformed one (#1596).\n applyInboundApplicationEndpointRawBody(this.app, MAIN_API_BASE_PATH);\n // The CSP violation collector's 64 KiB cap, and the only parser of `application/csp-report` (#2867): unauthenticated,\n // so it is bounded before the global parser's multi-megabyte limit can apply.\n applyCspViolationReportBodyCap(this.app, MAIN_API_BASE_PATH);\n this.app.use(express.json({\n limit: httpConfig.bodyParserLimit,\n // Parse `application/json` AND any structured-syntax-suffix JSON media type\n // (RFC 6839 `+json`) — notably SCIM's mandated `application/scim+json`\n // (RFC 7644 §3.1). Without this, SCIM POST/PUT/PATCH bodies arrive unparsed\n // (`req.body` undefined) and the /scim/v2/* create/update handlers 500.\n type: ['application/json', 'application/*+json'],\n verify: retainRawBodyUnder(this.rawBodyRequiredPrefixes),\n }));\n // The same capture for form bodies (#2659): Slack signs the raw bytes of its interactions and slash commands,\n // which arrive `application/x-www-form-urlencoded`, and a re-encoding of the parsed fields is not what it signed.\n this.app.use(express.urlencoded({ extended: true, limit: httpConfig.urlEncodedLimit, verify: retainRawBodyUnder(this.rawBodyRequiredPrefixes) }));\n // A provider webhook over either parser's limit reaches its receiver as a flag, which answers an AUDITED 413 (#3395):\n // a pushed email over the limit is a message refused, and must leave a record rather than a generic parser error.\n for (const prefix of this.rawBodyRequiredPrefixes) this.app.use(prefix, translateOversizedInboundBody);\n // Auth-hardening Slice A — `__wildo_refresh` `HttpOnly` cookie carries the\n // refresh token on `/api/v1/auth/*` routes. `cookie-parser` populates `req.cookies`\n // so `AuthControllerUtils.extractRefreshTokenFromCookie` can pick the cookie\n // up (post A-Step 6 the helper is cookie-only — no body fallback).\n // Cookie-parser is a no-op for routes that never read cookies, so mounting\n // it globally has no side-effects on non-auth controllers.\n this.app.use(cookieParser());\n\n this.logDebug('Body parsing middleware configured');\n }\n\n /**\n * Enter the request-scoped correlation ALS for every inbound request, wrapping the ENTIRE async\n * continuation (`runWithRequestContext(frame, () => next())`). Mounted first (after security headers)\n * so correlation is available to every downstream middleware, controller, service, and — critically —\n * the error handler, letting even un-threaded deep errors carry the correlation id.\n *\n * The frame reuses a SAFE inbound `x-correlation-id` (cross-service / cross-hop chaining) or mints a\n * fresh id, and captures the frontend surface (`x-frontend-service-name`). The per-request\n * `ExecutionContext` later adopts this frame's id (R13), so the EC, logs, and audit share one id.\n *\n * `x-client-instance-id` is simply forwarded: whether it is ADMITTED is decided by the ingest policy\n * installed via `setClientInstanceIdIngestPolicy` (see {@link installClientInstanceIdIngestPolicy}),\n * which every frame construction consults — so the opt-in holds for this seam, the WebSocket\n * handshake, and any future transport without each having to re-apply it.\n */\n private setupRequestContext(): void {\n this.app.use((req: Request, _res: Response, next: NextFunction) => {\n const frame = buildRequestContextFrame({\n inboundCorrelationId: req.get(WildoHeaderKeys.CORRELATION_ID),\n frontendServiceName: req.get(WildoHeaderKeys.FRONTEND_SERVICE_NAME),\n clientInstanceId: req.get(WildoHeaderKeys.CLIENT_INSTANCE_ID),\n // Read only by recorders that must describe the request's client (#2317); never logged.\n requestOrigin: { ipAddress: getClientIpFromRequest(req), userAgent: req.get(WildoHeaderKeys.USER_AGENT) },\n });\n runWithRequestContext(frame, () => next());\n });\n }\n\n /**\n * Install the application's client-install ingest policy into the request-context chokepoint.\n *\n * Fail-closed by construction: an unresolved configuration, an absent `compliance` block, and an\n * explicit `DISABLED` all answer `false`, so the only way to admit the identifier is an application\n * that deliberately authored `SESSION` or `PERSISTENT`. The SCOPE (session vs persistent) governs\n * the CLIENT's storage lifetime, not the server's admission — either non-disabled value admits it.\n *\n * Passed as a closure (evaluated per request) rather than a snapshot boolean so a configuration\n * reload takes effect immediately and pre-configuration requests still fail closed.\n *\n * assurance-control: WILDO.PRIVACY.DATA_MINIMIZATION — binds collection of the device-stored\n * client-install identifier to an explicit, application-authored policy; absent policy = no collection.\n */\n private installClientInstanceIdIngestPolicy(): void {\n setClientInstanceIdIngestPolicy(() => {\n // TOTAL by construction: this resolver runs on the request path, inside frame construction, so an\n // exception here would not merely mis-answer the policy — it would fail the REQUEST. (Proven, not\n // theoretical: an earlier revision dereferenced `appConfigService` directly and turned every\n // request into a 500 wherever that dependency was absent.) Any failure to determine the policy is\n // therefore answered `false`, which is also the correct privacy default: when in doubt, collect\n // nothing.\n try {\n if (!this.appConfigService?.isInitialized()) {\n return false;\n }\n const scope = this.appConfigService.config?.compliance?.clientInstanceIdScope;\n return scope !== undefined && scope !== ClientInstanceIdScope.DISABLED;\n } catch {\n return false;\n }\n });\n }\n\n /**\n * Setup request logging middleware\n * Skips logging successful health check requests to reduce noise\n */\n private setupRequestLogging(): void {\n this.app.use((req: Request, res: Response, next: NextFunction) => {\n const startTime = Date.now();\n\n res.on('finish', () => {\n // Skip logging successful health check requests (only log failures)\n const isHealthCheck = req.path === ENGINE_ROOT_ROUTES[EngineRootRouteKey.HEALTH_LIVENESS]\n || req.path === ENGINE_ROOT_ROUTES[EngineRootRouteKey.HEALTH_READINESS]\n || req.path === ENGINE_ROOT_ROUTES[EngineRootRouteKey.HEALTH_TIME];\n const isSuccessful = res.statusCode === 200;\n\n if (isHealthCheck && isSuccessful) {\n return; // Skip logging successful health checks\n }\n\n const duration = Date.now() - startTime;\n this.logDebug('HTTP Request', {\n method: req.method,\n path: req.path,\n statusCode: res.statusCode,\n duration: `${duration}ms`,\n userAgent: req.get(WildoHeaderKeys.USER_AGENT),\n ip: req.ip\n });\n });\n\n next();\n });\n }\n\n /**\n * Register all routes from controllers registry and custom controllers.\n *\n * Note: early-phase controllers are already mounted by setupExpressApp().\n * This method mounts only ordinary post-middleware controllers.\n */\n private async registerRoutes(): Promise<void> {\n // Mount health controller at root level (for Kubernetes probes)\n const healthBasePath = this.healthController.getCustomMountBasePath();\n this.app.use(healthBasePath, this.healthController.getRouter());\n this.mountedRoutes.push(...collectMountedRoutes(this.healthController.getRouter(), healthBasePath, 'controller health', MountedRouteOrigin.CONTROLLER));\n this.logDebug('Health controller mounted at root level', { basePath: healthBasePath });\n\n // CRDT clock synchronization endpoint (root-level like health probes)\n this.app.get(ENGINE_ROOT_ROUTES[EngineRootRouteKey.HEALTH_TIME], (_req, res) => {\n const now = Date.now();\n res.setHeader('Cache-Control', 'no-store');\n res.setHeader(WildoHeaderKeys.X_SERVER_TIME, String(now));\n res.json({ serverTime: now });\n });\n this.mountedRoutes.push({ owner: 'engine clock', origin: MountedRouteOrigin.CONTROLLER, path: ENGINE_ROOT_ROUTES[EngineRootRouteKey.HEALTH_TIME], methods: ['get'] });\n\n // #2974: the served custom domains, for the deployment's edge. INTERNAL-ONLY (no forwarding header) and 404\n // otherwise, so the edge never routes a stranger to the list of which tenants use which domain.\n if (this.customDomainEdge) {\n const edge = this.customDomainEdge;\n const internalOnly = (handler: (res: express.Response) => Promise<void>) => (req: express.Request, res: express.Response, next: express.NextFunction) => {\n if (!isInternalEdgeRequest(req.headers)) {\n res.status(404).end();\n return;\n }\n res.setHeader('Cache-Control', 'no-store');\n handler(res).catch(next);\n };\n this.app.get(ENGINE_ROOT_ROUTES[EngineRootRouteKey.EDGE_CUSTOM_DOMAINS], internalOnly(async (res) => {\n // The frontend a custom domain serves, by its endpoint key (= its k8s Service name). Without one nothing is routed.\n const frontendServiceName = this.appConfigService.resolveDefaultFrontendServiceName();\n const answer: CustomDomainEdgeList = { domains: frontendServiceName ? await edge.servedDomains() : [], frontendServiceName };\n res.json(answer);\n }));\n this.app.get(ENGINE_ROOT_ROUTES[EngineRootRouteKey.EDGE_CUSTOM_DOMAINS_TRAEFIK], internalOnly(async (res) => {\n const hostOf = (url: string | undefined) => { try { return url ? new URL(url).hostname : undefined; } catch { return undefined; } };\n const config = this.appConfigService.config;\n const defaultFrontend = this.appConfigService.resolveDefaultFrontendServiceName();\n const backendHost = hostOf(config.runtime?.endPoints?.main_backend_api?.publicUrl);\n const frontendHost = hostOf(defaultFrontend ? config.runtime?.endPoints?.[defaultFrontend]?.publicUrl : undefined);\n // Without both hosts there is no service to route to: an empty configuration serves nothing (fail closed).\n const domains = backendHost && frontendHost ? await edge.servedDomains() : [];\n res.json(buildTraefikDynamicConfiguration(domains, {\n backendHost: backendHost ?? '', frontendHost: frontendHost ?? '', certResolver: COMPOSE_EDGE_CERT_RESOLVER, entryPoint: COMPOSE_EDGE_SECURE_ENTRYPOINT,\n }));\n }));\n for (const key of [EngineRootRouteKey.EDGE_CUSTOM_DOMAINS, EngineRootRouteKey.EDGE_CUSTOM_DOMAINS_TRAEFIK]) {\n this.mountedRoutes.push({ owner: 'custom-domain edge', origin: MountedRouteOrigin.CONTROLLER, path: ENGINE_ROOT_ROUTES[key], methods: ['get'] });\n }\n }\n\n // Mount the main controllers registry at the shared MAIN_API_BASE_PATH\n // (`/api/v1`). This is the single source of truth for the prefix — the\n // frontend HTTP client and the refresh-token cookie `Path` derive from\n // the same constant so the served auth routes and the cookie scope can\n // never drift apart (see MAIN_API_BASE_PATH / REFRESH_TOKEN_COOKIE_PATH).\n const mainRouter = this.controllersRegistry.getMasterRouter();\n this.app.use(MAIN_API_BASE_PATH, mainRouter);\n // The master router tries every resource controller, then every manual controller, in registration order.\n for (const [resourceType, controller] of this.controllersRegistry.getAllResourceControllers()) {\n this.mountedRoutes.push(...collectMountedRoutes(controller.getRouter(), MAIN_API_BASE_PATH, `resource ${String(resourceType)}`, MountedRouteOrigin.RESOURCE));\n }\n for (const [name, controller] of this.controllersRegistry.getAllCustomControllers()) {\n this.mountedRoutes.push(...collectMountedRoutes(controller.getRouter(), MAIN_API_BASE_PATH, `controller ${name}`, MountedRouteOrigin.CONTROLLER));\n }\n\n this.logDebug('Main controllers registry mounted', { basePath: MAIN_API_BASE_PATH });\n\n /**\n * RFC 8414 authorization-server metadata, at the location the RFC actually specifies.\n *\n * Our issuer carries a path (`https://<host>/api/v1`), and for a path-bearing issuer the\n * well-known segment goes BETWEEN the host and the path — not after it:\n *\n * \"If the issuer identifier value contains a path component, any terminating \"/\" MUST be\n * removed before inserting \"/.well-known/\" and the well-known URI suffix between the host\n * component and the path component.\"\n *\n * with the RFC's own example resolving issuer `https://example.com/issuer1` to\n * `GET /.well-known/oauth-authorization-server/issuer1`.\n * spec-cite: RFC 8414 § 3 (Obtaining Authorization Server Metadata), fetched 2026-08-11.\n *\n * The controller already serves the document at `<issuer>/.well-known/oauth-authorization-server`\n * — the OIDC Discovery convention (issuer + suffix), which is correct for\n * `/.well-known/openid-configuration` and WRONG for this one. So a client that followed RFC 8414\n * asked for `/.well-known/oauth-authorization-server/api/v1`, which is OUTSIDE the API mount, and\n * received the SPA shell: HTML where it expected JSON. It could not discover the authorization\n * server, so it never opened a login window — the failure looked like a silent no-op rather than a\n * 404, which is why it survived twelve lanes and two real-client sessions.\n *\n * Delegating to `mainRouter` rather than re-registering the handler keeps ONE implementation:\n * the document, its CORS posture and its cache headers cannot drift between the two locations.\n * The router is mounted at `MAIN_API_BASE_PATH`, so it matches on the path RELATIVE to that mount.\n */\n const rfc8414MetadataPath = rfc8414AuthorizationServerMetadataPath(MAIN_API_BASE_PATH);\n const mountRelativeMetadataPath = MANUAL_CONTROLLER_ROUTES_URLS[ManualControllerRouteKey.OAUTH_PROVIDER_AS_METADATA];\n this.mountedRoutes.push({ owner: 'engine RFC 8414 alias', origin: MountedRouteOrigin.CONTROLLER, path: rfc8414MetadataPath, methods: ['get'] });\n this.app.get(rfc8414MetadataPath, (req, res, next) => {\n req.url = mountRelativeMetadataPath;\n mainRouter(req, res, next);\n });\n this.logDebug('RFC 8414 authorization-server metadata alias mounted', {\n rfc8414Path: rfc8414MetadataPath,\n servesSameDocumentAs: `${MAIN_API_BASE_PATH}${mountRelativeMetadataPath}`,\n });\n\n /**\n * RFC 9728 § 3 protected-resource metadata, at the location a client DERIVES from the resource\n * identifier — the same insertion rule as RFC 8414 above, applied to the MCP resource.\n *\n * Both MCP resource shapes are aliased, because the derivation follows the identifier and the\n * identifier grows a segment for a named instance\n * (`resolveResourceServerAudience(MCP, ref)` → `<apiAudience>/mcp/<ref>`):\n *\n * resource `<origin>/api/v1/mcp` → `/.well-known/oauth-protected-resource/api/v1/mcp`\n * resource `<origin>/api/v1/mcp/<ref>` → `/.well-known/oauth-protected-resource/api/v1/mcp/<ref>`\n *\n * Aliasing only the default would leave every NAMED instance underivable while looking fixed — the\n * shape of defect this codebase has now paid for repeatedly, so both are mounted together.\n *\n * Unlike the RFC 8414 case this closes a LATENT gap rather than a live outage: the 401 challenge\n * names `resource_metadata` explicitly and MCP directs clients to follow it, which is the route a\n * real client was observed taking. A deriving client — which RFC 9728 § 5.1 equally permits — was\n * receiving the SPA shell.\n * spec-cite: RFC 9728 § 3 (Protected Resource Metadata Request), fetched 2026-08-12.\n *\n * Delegation to `mainRouter` is the same trick and for the same reason: one handler, so the\n * document, its `resource`, its cache headers and its 404-on-unknown-instance behaviour cannot\n * drift between the derived and the advertised location.\n */\n const mcpMountPath = MANUAL_CONTROLLER_ROUTES_URLS[ManualControllerRouteKey.MCP_ENDPOINT];\n const mountRelativePrmPath = MANUAL_CONTROLLER_ROUTES_URLS[ManualControllerRouteKey.MCP_PROTECTED_RESOURCE_METADATA];\n const rfc9728DefaultPath = rfc9728ProtectedResourceMetadataPath(`${MAIN_API_BASE_PATH}${mcpMountPath}`);\n this.mountedRoutes.push(\n { owner: 'engine RFC 9728 alias', origin: MountedRouteOrigin.CONTROLLER, path: rfc9728DefaultPath, methods: ['get'] },\n { owner: 'engine RFC 9728 alias', origin: MountedRouteOrigin.CONTROLLER, path: `${rfc9728DefaultPath}/:instanceRef`, methods: ['get'] },\n );\n this.app.get(rfc9728DefaultPath, (req, res, next) => {\n req.url = mountRelativePrmPath;\n mainRouter(req, res, next);\n });\n this.app.get(`${rfc9728DefaultPath}/:instanceRef`, (req, res, next) => {\n // Re-enter through the router's OWN named-instance route so `:instanceRef` is parsed, validated\n // and 404'd by the one handler that knows the instance registry — never resolved here.\n req.url = `${mcpMountPath}/${encodeURIComponent(req.params['instanceRef'] ?? '')}${mountRelativePrmPath}`;\n mainRouter(req, res, next);\n });\n this.logDebug('RFC 9728 protected-resource metadata aliases mounted', {\n rfc9728DefaultPath,\n rfc9728InstancePath: `${rfc9728DefaultPath}/:instanceRef`,\n servesSameDocumentAs: `${MAIN_API_BASE_PATH}${mountRelativePrmPath}`,\n });\n\n // Mount ordinary custom controllers (early phases are already mounted).\n let standardControllerCount = 0;\n this.customControllers.forEach((controller) => {\n if (controller.getCustomControllerMountPhase() === CustomControllerMountPhase.STANDARD) {\n this.mountCustomController(controller);\n standardControllerCount++;\n }\n });\n\n this.logDebug('Routes registration completed', {\n totalCustomControllers: this.customControllers.size,\n standardControllers: standardControllerCount\n });\n\n this.assertRouteTableInvariant();\n }\n\n /**\n * Refuse to start unless every request URL reaches exactly one route, deterministically (#2200).\n *\n * Express answers with the first matching route in mount order, so the table this server mounted is checked as a\n * whole, in that order (`analyzeRouteTable`): no two routes for the same method and pattern, no pair where each is\n * more specific in a different segment, no specific route mounted after a general one that captures it, and no\n * application resource route sharing any URL with an engine route. The refusal names every conflicting pair; the\n * remedy is renaming a route, which needs nothing running, so a boot refusal is the right place. A route whose\n * pattern cannot be compared segment by segment is reported, never guessed at.\n */\n private assertRouteTableInvariant(): void {\n const analysis = analyzeRouteTable(this.mountedRoutes);\n if (analysis.undecidable.length > 0) {\n this.logger.warn('Routes the route-table invariant cannot compare (wildcard, optional group or RegExp patterns)', {\n routes: analysis.undecidable.map((route) => `${route.owner}: ${route.path}`),\n });\n }\n if (analysis.conflicts.length === 0) return;\n throw this.errorBuilder.buildError(ErrorType.CONFIGURATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.CONTROLLER_ROUTE_TABLE_CONFLICT,\n context: {\n message: 'Two mounted routes answer the same URL and method in a way mount order cannot resolve, so one of them '\n + 'would be unreachable or answer by accident. Rename one of the routes.',\n conflicts: analysis.conflicts.map((conflict) => ({\n kind: conflict.kind,\n methods: conflict.methods,\n mountedFirst: `${conflict.first.owner}: ${conflict.first.path}`,\n mountedSecond: `${conflict.second.owner}: ${conflict.second.path}`,\n })),\n },\n });\n }\n\n /**\n * Mount a custom controller\n */\n private mountCustomController(controller: AbstractControllerBackendService): void {\n const controllerName = controller.getControllerName();\n const router = controller.getRouter();\n const basePath = this.getControllerBasePath(controller);\n\n this.app.use(basePath, router);\n this.mountedRoutes.push(...collectMountedRoutes(router, basePath, `controller ${controllerName}`, MountedRouteOrigin.CONTROLLER));\n\n this.logDebug('Custom controller mounted', {\n controllerName,\n basePath,\n mountPhase: controller.getCustomControllerMountPhase()\n });\n }\n\n /**\n * Get the base path for a controller.\n * Uses custom path if provided, otherwise falls back to /api/custom/<kebab-case-name>\n */\n private getControllerBasePath(controller: AbstractControllerBackendService): string {\n const maybeCustomBasePath = (controller as any)?.getCustomMountBasePath?.();\n return typeof maybeCustomBasePath === 'string' && maybeCustomBasePath.startsWith('/')\n ? maybeCustomBasePath\n : `/api/custom/${this.kebabCase(controller.getControllerName())}`;\n }\n\n /**\n * Setup error handling middleware\n */\n private setupErrorHandling(): void {\n // 404 handler\n this.app.use((req: Request, res: Response, next: NextFunction) => {\n res.status(404).json({\n error: {\n message: 'Route not found',\n path: req.originalUrl,\n method: req.method,\n timestamp: new Date().toISOString()\n }\n });\n });\n\n // Global error handler - use ErrorHandlerService for proper error responses\n this.app.use(this.errorHandler.expressErrorHandler());\n\n this.logDebug('Error handling middleware configured');\n }\n\n /**\n * Start the HTTP server\n */\n private async startServer(): Promise<void> {\n return new Promise(async (resolve, reject) => {\n try {\n const appConfig = this.appConfigService.config;\n\n // Build server base URL from endpoint string, with env overrides\n let endpointString: string | undefined = undefined;\n const svcName = this.appConfigService.serviceName;\n\n if (svcName) {\n endpointString = (appConfig as any)?.runtime?.endPoints?.[svcName]?.internalUrl;\n }\n\n let urlProtocol: 'http:' | 'https:' = 'http:';\n let host = 'localhost';\n let port = 4000;\n\n try {\n const urlString = endpointString && endpointString.includes('://')\n ? endpointString\n : `http://${endpointString || 'localhost:4000'}`;\n const url = new URL(urlString);\n urlProtocol = (url.protocol === 'https:' ? 'https:' : 'http:');\n host = url.hostname || host;\n if (url.port) {\n port = parseInt(url.port, 10);\n } else if (url.protocol === 'https:') {\n port = 443;\n } else if (url.protocol === 'http:') {\n port = 80;\n }\n } catch {}\n\n if (process.env.HOST) host = process.env.HOST;\n if (process.env.PORT) port = parseInt(process.env.PORT, 10);\n\n this.baseUrl = `${urlProtocol}//${host}:${port}`;\n\n // Configure server options\n this.app.set('port', port);\n\n // Set server timeouts (before starting server)\n const runtimeConfig = this.extractRuntimeConfig(appConfig);\n const httpConfig = runtimeConfig.httpServerConfiguration;\n\n // Start listening\n this.server = this.app.listen(port, host, async () => {\n try {\n // Set server timeouts after server is created\n this.server!.timeout = httpConfig.requestTimeout;\n this.server!.keepAliveTimeout = httpConfig.keepAliveTimeout;\n this.server!.headersTimeout = httpConfig.headersTimeout;\n\n if (httpConfig.maxConnections) {\n this.server!.maxConnections = httpConfig.maxConnections;\n }\n\n // After the timeouts and the connection cap, which the bridge listener copies (#3387).\n await this.openContainerHostGatewayListenerIfDeclared(host, port);\n\n this.logDebug('🌐 HTTP Server started successfully', {\n environment: process.env.APPLICATION_ENV || process.env.NODE_ENV || 'development',\n url: this.baseUrl\n });\n\n // Initialize WebSocket service AFTER server is ready\n // Skip for platform microservices that don't need real-time browser connections\n if (this.initOptions.skipWebSocket) {\n this.logDebug('WebSocket initialization skipped (platform service mode)');\n } else {\n // Note: CORS origins are derived internally by WebSocketService.getCorsOrigins()\n await this.webSocketService.initialize(this.server!);\n this.logDebug('WebSocket service initialized');\n }\n\n resolve();\n } catch (error) {\n reject(error);\n }\n });\n\n // Handle server errors\n this.server.on('error', (error: any) => {\n if (error.code === 'EADDRINUSE') {\n const message = `Port ${port} is already in use`;\n this.logger.error(message);\n /*\n * The code and the port travel ON the error (#3214): the start record classifies the failure from them as a\n * DEV-STACK problem (another process holds the port), which the build lane must not blame on a task.\n */\n reject(Object.assign(new Error(message), { code: 'EADDRINUSE', port }));\n } else {\n this.logger.error('HTTP Server error:', error);\n reject(error);\n }\n });\n\n } catch (error) {\n reject(error);\n }\n });\n }\n\n\n /**\n * Open the second listener on the host's Docker bridge gateway when the native LOCAL lane declared one (#3387), so a\n * compose minion or worker on Docker Engine for Linux reaches this backend through `host.docker.internal`.\n *\n * Never fatal: the loopback listener serves everything on the host, and a missing bridge (Docker stopped after the\n * `.env` was written) or an unusable value must not stop the backend from starting. Each is logged with the address\n * and the reason, so a minion's refused connection leads straight here.\n */\n private async openContainerHostGatewayListenerIfDeclared(primaryListenHost: string, port: number): Promise<void> {\n const gatewayHost = process.env[HttpServerEnvKey.CONTAINER_HOST_GATEWAY_LISTEN_HOST]?.trim();\n if (!gatewayHost || !this.server) return;\n const unusable = describeUnusableContainerHostGatewayListenHost(gatewayHost, primaryListenHost);\n if (unusable !== null) {\n this.logger.warn(`${HttpServerEnvKey.CONTAINER_HOST_GATEWAY_LISTEN_HOST} ignored: ${unusable}. Compose runtimes on a Linux Docker host will not reach this backend.`);\n return;\n }\n try {\n this.containerHostGatewayListener = await openContainerHostGatewayListener(this.server, gatewayHost, port);\n this.logDebug('HTTP server also listening on the Docker bridge gateway', { host: gatewayHost, port });\n } catch (error) {\n const code = (error as { code?: unknown } | null)?.code;\n this.logger.warn(\n `Could not listen on the Docker bridge gateway ${gatewayHost}:${port}${typeof code === 'string' ? ` (${code})` : ''}. ` +\n 'Compose runtimes on a Linux Docker host will not reach this backend until it restarts with the bridge present; ' +\n 'regenerate the environment files if the bridge address changed.',\n );\n }\n }\n\n // ================================\n // Utility Methods\n // ================================\n\n /**\n * Parse CSP string into helmet format\n */\n private parseCSP(csp: string): Record<string, string[]> {\n // Simple CSP parser - can be enhanced as needed\n const directives: Record<string, string[]> = {};\n\n csp.split(';').forEach(directive => {\n const [key, ...values] = directive.trim().split(' ');\n if (key && values.length > 0) {\n directives[key.replace(/-([a-z])/g, (g) => g[1].toUpperCase())] = values;\n }\n });\n\n return directives;\n }\n\n /**\n * Convert string to kebab case\n */\n private kebabCase(str: string): string {\n return str\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .replace(/[\\s_]+/g, '-')\n .toLowerCase();\n }\n\n}\n"]}
1
+ {"version":3,"file":"http-server.backend.service.js","sourceRoot":"","sources":["../../../../src/runtime/services/http-server.backend.service.ts"],"names":[],"mappings":"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","sourcesContent":["import 'reflect-metadata';\nimport { injectable, inject, optional } from 'inversify';\nimport express, { Express, Request, Response, NextFunction, Router } from 'express';\nimport cors from 'cors';\nimport { createCorsOriginDecider } from '~wildo-backend-lib/organizations/custom-domains/custom-domain-origin-admission.backend.utils';\nimport type { CustomDomainHostResolverBackendService } from '~wildo-backend-lib/organizations/custom-domains/custom-domain-host-resolver.backend.service';\nimport { buildTraefikDynamicConfiguration, isInternalEdgeRequest, type CustomDomainEdgeBackendService } from '~wildo-backend-lib/organizations/custom-domains/custom-domain-edge.backend.service';\nimport cookieParser from 'cookie-parser';\nimport helmet from 'helmet';\nimport compression from 'compression';\nimport { Server } from 'http';\nimport type { Server as NetServer } from 'net';\nimport { z } from 'zod';\nimport { HttpServerEnvKey, parseTrustedProxyHops } from '@wildo-ai/platform-core-shared';\n\nimport { SAAS_SERVICE_TYPES } from '~wildo-backend-lib/inject/models/service-types';\nimport { LoggerService } from '~wildo-backend-lib/monitoring/logger/services/logger.service';\nimport { AppConfigurationService } from '~wildo-backend-lib/config/services/app-configuration.backend.service';\nimport { ControllersRegistryHandlerBackendService } from '~wildo-backend-lib/base-classes/services/controllers/controllers-registry-handler.backend.service';\nimport {\n AbstractControllerBackendService,\n CustomControllerMountPhase,\n} from '~wildo-backend-lib/base-classes/services/controllers/abstract-controller.backend.service';\nimport { ErrorBuilderBackendService } from '~wildo-backend-lib/errors/services/error-builder.backend.service';\nimport { ErrorHandlerService } from '~wildo-backend-lib/errors/services/error-handler.backend.service';\nimport { relaxAbuseThrottleMaxForEnvironment } from '~wildo-backend-lib/errors/utils/rate-limit-environment-relaxation.backend.utils';\nimport { projectCaughtErrorLogFields } from '~wildo-backend-lib/errors/utils/error-log-level-classification.backend.utils';\nimport { applyOAuthBodyCap } from '~wildo-backend-lib/runtime/services/utils/oauth-body-cap.backend.utils';\nimport { applyCspViolationReportBodyCap } from '~wildo-backend-lib/monitoring/csp-violation-reports/csp-violation-report-body-cap.backend.utils';\nimport { ENGINE_CORS_ALLOWED_REQUEST_HEADERS, ENGINE_CORS_EXPOSED_RESPONSE_HEADERS } from '~wildo-backend-lib/runtime/services/utils/engine-cors-headers.backend.utils';\nimport { applyInboundApplicationEndpointRawBody, applyInboundLargeBodyProviderEndpoints, retainRawBodyUnder, translateOversizedInboundBody, type InboundLargeBodyRoutesBackendService } from '~wildo-backend-lib/runtime/services/utils/inbound-endpoint-raw-body.backend.utils';\nimport { describeUnusableContainerHostGatewayListenHost, openContainerHostGatewayListener } from '~wildo-backend-lib/runtime/services/utils/container-host-gateway-listener.backend.utils';\nimport { RuntimeConfig, RuntimeConfigurationSchema } from '~wildo-backend-lib/runtime/models/runtime.backend.schemas';\nimport { AppConfiguration } from '~wildo-backend-lib/config/models/app-config.backend.schemas';\nimport { BackendApiType, ClientInstanceIdScope, ErrorRequestOutcome, ErrorSeverity, ErrorType, ErrorCustomMessageReference, isAppConfigurationNotInitializedError, WildoHeaderKeys, ENGINE_ROOT_ROUTES, EngineRootRouteKey, MAIN_API_BASE_PATH, MANUAL_CONTROLLER_ROUTES_URLS, ManualControllerRouteKey, rfc8414AuthorizationServerMetadataPath, rfc9728ProtectedResourceMetadataPath, ResourceSerializationUtils, COMPOSE_EDGE_CERT_RESOLVER, COMPOSE_EDGE_SECURE_ENTRYPOINT, type CustomDomainEdgeList } from '@wildo-ai/saas-models';\nimport { WebSocketService } from '~wildo-backend-lib/requests/service/websocket.service';\nimport { HealthControllerBackendService } from '~wildo-backend-lib/runtime/controllers/health-controller.backend.service';\nimport { RedisService } from '~wildo-backend-lib/databases/services/redis.service';\nimport { AuthControllerUtils } from '~wildo-backend-lib/security/authentications/services/utils/auth-controller.utils';\nimport { runWithRequestContext, buildRequestContextFrame, setClientInstanceIdIngestPolicy } from '~wildo-backend-lib/runtime/models/request-context.als.backend';\nimport { getClientIpFromRequest } from '~wildo-backend-lib/runtime/utils/request-client-ip.utils';\nimport { analyzeRouteTable, collectMountedRoutes, MountedRouteOrigin, type MountedRoute } from '~wildo-backend-lib/runtime/services/utils/route-shadowing.backend.utils';\n\n/**\n * HTTP Server Backend Service\n *\n * Orchestrates the Express HTTP server startup with complete configuration\n * management, middleware setup, and route registration.\n *\n * Features:\n * - Express server with configurable middleware stack\n * - CORS, security headers, compression, rate limiting\n * - Integration with ControllersRegistryHandlerBackendService\n * - Support for additional custom controllers\n * - Configuration-driven server setup\n * - Graceful shutdown handling\n * - Health check endpoints\n * - Request logging and error handling\n *\n * Configuration Sources:\n * - AppConfigurationService (platform + admin managed config)\n * - RuntimeConfigurationSchema (HTTP server specific settings)\n * - Environment variables (PORT, HOST overrides)\n */\n/**\n * How long the perimeter limiter stays in its in-memory fallback before the degradation\n * signal is REPEATED (the first request of any outage always signals immediately).\n *\n * Deliberately a fixed wall-clock interval and NOT derived from the configured\n * `rateLimiting.windowMs`: the signal is about the shared counter's OUTAGE, not about the\n * rate-limit window, and an application authoring an hour-long window would otherwise hide\n * an hour of degradation behind a single line. One minute keeps a sustained outage legible\n * to a human tailing logs while staying far away from one line per request.\n */\nexport const SHARED_RATE_LIMIT_COUNTER_DEGRADATION_SIGNAL_INTERVAL_MS: number = 60_000;\n\n/**\n * Stable, greppable identifiers stamped into the `degradation` log field so an operator (or\n * a log-search alert) can select these two lines without matching on prose. Exported so the\n * pinning test asserts the SAME identifier the runtime emits rather than a copied literal —\n * a second copy of a machine-readable code is a second authority that silently drifts.\n */\nexport const PERIMETER_RATE_LIMIT_DEGRADED_SIGNAL: string = 'perimeter_rate_limit_shared_counter_unavailable';\nexport const PERIMETER_RATE_LIMIT_RECOVERED_SIGNAL: string = 'perimeter_rate_limit_shared_counter_recovered';\n\n/**\n * Options for HTTP server initialization\n */\nexport interface HttpServerInitOptions {\n /**\n * Skip WebSocket/Socket.IO initialization.\n * Use this for platform microservices that don't need real-time browser connections.\n * Default: false\n */\n skipWebSocket?: boolean;\n\n /**\n * Skip CORS middleware configuration.\n * Use this for platform microservices that only receive backend-to-backend requests\n * and don't need browser CORS headers.\n * Default: false\n */\n skipCors?: boolean;\n}\n\n@injectable()\nexport class HttpServerBackendService {\n\n private readonly app: Express;\n private server: Server | null = null;\n /**\n * The second listener on the host's Docker bridge gateway (#3387), feeding {@link server}. Opened only when the native\n * LOCAL lane wrote `CONTAINER_HOST_GATEWAY_LISTEN_HOST`; see `container-host-gateway-listener.backend.utils`.\n */\n private containerHostGatewayListener: NetServer | null = null;\n private baseUrl: string | null = null;\n private readonly customControllers: Map<string, AbstractControllerBackendService> = new Map();\n /**\n * Every route this server mounts, in MOUNT ORDER — the order Express tries them in. Recorded at each mount site because\n * Express 5 does not keep the path a router was mounted at; read once, by {@link assertRouteTableInvariant} (#2200).\n */\n private readonly mountedRoutes: MountedRoute[] = [];\n private isInitialized = false;\n private initOptions: HttpServerInitOptions = {};\n\n /**\n * Route prefixes whose handlers require the EXACT original request bytes\n * (not a re-serialized copy). The global `express.json` `verify` hook retains\n * `req.rawBody` ONLY for requests matching one of these prefixes; for all\n * other traffic the raw buffer is GC-eligible the moment `JSON.parse`\n * returns, exactly as before — so normal API calls pay no retained-memory\n * cost, only a cheap `startsWith` check.\n *\n * Today the sole raw-body-in surface is inbound webhook signature\n * verification, for JSON and form bodies alike (`retainRawBodyUnder`): `WebhookAutoControllerBackendService` registers\n * `POST /webhooks/{provider}/{endpoint}` under the master router at\n * `MAIN_API_BASE_PATH`, so the live prefix is `${MAIN_API_BASE_PATH}/webhooks/`.\n * Add to this list if another surface ever needs byte-faithful bodies.\n */\n private readonly rawBodyRequiredPrefixes: readonly string[] = [\n `${MAIN_API_BASE_PATH}/webhooks/`,\n ];\n\n protected readonly logDebug: (message: string, context?: Record<string, unknown>) => void;\n\n constructor(\n @inject(SAAS_SERVICE_TYPES.Logger) private readonly logger: LoggerService,\n @inject(SAAS_SERVICE_TYPES.AppConfigService) private readonly appConfigService: AppConfigurationService,\n @inject(SAAS_SERVICE_TYPES.ControllersRegistryHandlerService) private readonly controllersRegistry: ControllersRegistryHandlerBackendService,\n @inject(SAAS_SERVICE_TYPES.ErrorBuilderService) private readonly errorBuilder: ErrorBuilderBackendService,\n @inject(SAAS_SERVICE_TYPES.ErrorHandlerService) private readonly errorHandler: ErrorHandlerService,\n @inject(SAAS_SERVICE_TYPES.WebSocketService) private readonly webSocketService: WebSocketService,\n @inject(SAAS_SERVICE_TYPES.HealthController) private readonly healthController: HealthControllerBackendService,\n @inject(SAAS_SERVICE_TYPES.RedisService) private readonly redisService: RedisService,\n // #2974: which organization a custom domain answers for. Optional: a platform service binds none, and then only\n // the configured frontends are admitted.\n @inject(SAAS_SERVICE_TYPES.CustomDomainHostResolverService) @optional()\n private readonly customDomainHostResolver?: Pick<CustomDomainHostResolverBackendService, 'resolveOrigin'>,\n // #2974: what the deployment's edge must route for the served custom domains.\n @inject(SAAS_SERVICE_TYPES.CustomDomainEdgeService) @optional()\n private readonly customDomainEdge?: Pick<CustomDomainEdgeBackendService, 'servedDomains'>,\n // #3395: the provider endpoints that read a body larger than the global parsers do, declared by the webhook controller.\n @inject(SAAS_SERVICE_TYPES.InboundLargeBodyRoutes) @optional()\n private readonly inboundLargeBodyRoutes?: Pick<InboundLargeBodyRoutesBackendService, 'limitFor'>,\n ) {\n\n this.app = express();\n\n this.logDebug = this.logger.debugByType('HttpServer');\n this.logger.setDebugTypeLogging('HttpServer', false);\n\n this.logDebug('HTTP server service created');\n }\n\n public async initialize(options?: HttpServerInitOptions): Promise<void> {\n if (this.isInitialized) {\n this.logDebug('HTTP server already initialized');\n return;\n }\n\n // Store options for use in startServer()\n this.initOptions = options || {};\n\n try {\n this.logDebug('🚀 Initializing HTTP server...');\n\n // Get app configuration\n // Note: AppConfigurationService should be initialized before HTTP server in normal flow\n // but we check gracefully to provide better error messages\n const appConfig = this.appConfigService.isInitialized()\n ? this.appConfigService.config\n : null;\n\n if (!appConfig) {\n this.logger.error('HTTP server initialization attempted before app config initialized');\n throw this.errorBuilder.buildError(\n ErrorType.CONFIGURATION,\n undefined,\n {\n customMessageReference: ErrorCustomMessageReference.CONFIGURATION,\n context: {\n message: 'Application configuration must be initialized before starting HTTP server',\n service: 'HttpServerBackendService',\n operation: 'initialize'\n }\n }\n );\n }\n\n const runtimeConfig = this.extractRuntimeConfig(appConfig);\n\n // Setup Express application\n try {\n await this.setupExpressApp(runtimeConfig);\n } catch (error: any) {\n if (isAppConfigurationNotInitializedError(error)) {\n throw this.errorBuilder.buildError(ErrorType.INFRASTRUCTURE, undefined, {\n customMessageReference: ErrorCustomMessageReference.HTTP_SERVER_INITIALIZATION_FAILED,\n context: { step: 'setupExpressApp', message: error.context.message },\n stack: error.stack,\n });\n }\n throw error;\n }\n\n // Register all routes\n try {\n await this.registerRoutes();\n } catch (error: any) {\n if (isAppConfigurationNotInitializedError(error)) {\n throw this.errorBuilder.buildError(ErrorType.INFRASTRUCTURE, undefined, {\n customMessageReference: ErrorCustomMessageReference.HTTP_SERVER_INITIALIZATION_FAILED,\n context: { step: 'registerRoutes', message: error.context.message },\n stack: error.stack,\n });\n }\n throw error;\n }\n\n // Setup error handling\n try {\n this.setupErrorHandling();\n } catch (error: any) {\n if (isAppConfigurationNotInitializedError(error)) {\n throw this.errorBuilder.buildError(ErrorType.INFRASTRUCTURE, undefined, {\n customMessageReference: ErrorCustomMessageReference.HTTP_SERVER_INITIALIZATION_FAILED,\n context: { step: 'setupErrorHandling', message: error.context.message },\n stack: error.stack,\n });\n }\n throw error;\n }\n\n // Start the server\n try {\n await this.startServer();\n } catch (error: any) {\n if (isAppConfigurationNotInitializedError(error)) {\n throw this.errorBuilder.buildError(ErrorType.INFRASTRUCTURE, undefined, {\n customMessageReference: ErrorCustomMessageReference.HTTP_SERVER_INITIALIZATION_FAILED,\n context: { step: 'startServer', message: error.context.message },\n stack: error.stack,\n });\n }\n throw error;\n }\n\n this.isInitialized = true;\n this.logDebug('✅ HTTP server initialized successfully at ' + this.getServerInfo());\n\n } catch (error) {\n // Initialization failures are propagated to the runtime host, which owns\n // the single structured startup-failure record.\n throw error;\n }\n }\n\n /**\n * Register a custom controller\n */\n public registerCustomController(controller: AbstractControllerBackendService): void {\n const controllerName = controller.getControllerName();\n const mountPhase = controller.getCustomControllerMountPhase();\n\n if (this.customControllers.has(controllerName)) {\n const error = this.errorBuilder.buildError(\n ErrorType.VALIDATION,\n undefined,\n {\n customMessageReference: ErrorCustomMessageReference.HTTP_SERVER_INITIALIZATION_FAILED,\n context: {\n controllerName\n }\n }\n );\n throw error;\n }\n\n if (this.isInitialized && mountPhase !== CustomControllerMountPhase.STANDARD) {\n throw this.errorBuilder.buildError(\n ErrorType.VALIDATION,\n undefined,\n {\n customMessageReference: ErrorCustomMessageReference.HTTP_SERVER_INITIALIZATION_FAILED,\n context: {\n controllerName,\n mountPhase,\n reason: 'Early-phase custom controllers must be registered before HTTP server initialization',\n },\n },\n );\n }\n\n this.customControllers.set(controllerName, controller);\n\n this.logDebug('Custom controller registered', {\n controllerName,\n mountPhase,\n totalCustomControllers: this.customControllers.size\n });\n\n // Only STANDARD controllers can reach this late-registration path. An\n // early phase is a strict ordering contract and is refused above rather\n // than silently mounted after the middleware it must precede.\n if (this.isInitialized) {\n this.mountCustomController(controller);\n }\n }\n\n /**\n * Get the Express application instance\n */\n public getApp(): Express {\n return this.app;\n }\n\n /**\n * Check if server is running\n */\n public isRunning(): boolean {\n return this.server !== null && this.server.listening;\n }\n\n /**\n * Get server listening information\n */\n public getServerInfo(): string | null {\n if (!this.server || !this.server.listening) {\n return null;\n }\n return this.baseUrl;\n }\n\n /**\n * Gracefully shutdown the server\n */\n public async shutdown(): Promise<void> {\n if (!this.server) {\n return;\n }\n\n // Cleanup WebSocket service first\n await this.webSocketService.cleanup();\n this.logDebug('WebSocket service cleaned up');\n\n // Stop accepting through the bridge gateway before the server itself closes (#3387).\n if (this.containerHostGatewayListener) {\n const listener = this.containerHostGatewayListener;\n this.containerHostGatewayListener = null;\n await new Promise<void>((resolve) => listener.close(() => resolve()));\n }\n\n return new Promise((resolve, reject) => {\n this.logDebug('🔄 Shutting down HTTP server...');\n\n this.server!.close((error) => {\n if (error) {\n this.logger.error('❌ HTTP server shutdown failed:', error);\n reject(error);\n } else {\n this.logDebug('✅ HTTP server shutdown completed');\n this.server = null;\n this.isInitialized = false;\n resolve();\n }\n });\n });\n }\n\n // ================================\n // Private Setup Methods\n // ================================\n\n /**\n * Extract runtime configuration with defaults.\n *\n * Reads the optional `runtime.httpServerConfiguration` partial override\n * declared on `AppConfiguration_RuntimeSchema` (see\n * `appConfiguration_Backend_RuntimeSchemaBuilder` in `app-config.backend.schemas.ts`)\n * and feeds it through `RuntimeConfigurationSchema.parse` so any missing\n * fields fall back to the framework defaults (`requestTimeout: 300_000`,\n * `headersTimeout: 60_000`, etc.).\n *\n * App authors generally do not author this surface. The dev companion\n * sets `requestTimeout` and `headersTimeout` to ~30 min because its\n * LLM-bound endpoints legitimately exceed the 5-min default.\n */\n private extractRuntimeConfig(appConfig: AppConfiguration): RuntimeConfig {\n try {\n const runtimeData = appConfig.runtime.httpServerConfiguration ?? {};\n return RuntimeConfigurationSchema.parse({\n httpServerConfiguration: runtimeData,\n });\n } catch (error) {\n this.logger.warn('Using default runtime configuration due to validation error:', error);\n return RuntimeConfigurationSchema.parse({ httpServerConfiguration: {} });\n }\n }\n\n /**\n * Setup Express application with middleware\n *\n * IMPORTANT: Middleware ordering matters!\n * 1. Security headers are installed before every custom route.\n * 2. PRE_REQUEST_TRANSFORM controllers mount before CORS/preflight and parsers.\n * 3. RAW_REQUEST_STREAM controllers mount after CORS/rate limiting but before body parsing.\n * 4. Body parsing middleware is applied.\n * 5. STANDARD controllers mount through registerRoutes().\n *\n * This ensures streaming controllers receive raw request streams\n * while regular controllers get parsed request bodies.\n */\n /**\n * Trust exactly the reverse proxies the DEPLOYMENT put in front of this process (#1788).\n *\n * The hop count is rendered into the environment by the lane that placed the proxy, like HOST and PORT,\n * because an application cannot know how it is fronted. Until this, a boolean in the application config\n * chose it, nothing ever set it, and behind an ingress every client shared the ingress's address — one\n * bucket for every per-IP lockout and rate limit. Zero (the default) trusts no proxy: a hop that is not\n * really there would let a client choose its own address through `X-Forwarded-For`. A malformed value\n * refuses to start, since both of the silent readings are wrong.\n */\n private applyTrustedProxyHops(env: NodeJS.ProcessEnv): void {\n const trustedProxyHops = parseTrustedProxyHops(env[HttpServerEnvKey.HTTP_TRUSTED_PROXY_HOPS]);\n if (trustedProxyHops > 0) {\n this.app.set('trust proxy', trustedProxyHops);\n }\n }\n\n private async setupExpressApp(runtimeConfig: RuntimeConfig): Promise<void> {\n const httpConfig = runtimeConfig.httpServerConfiguration;\n\n this.applyTrustedProxyHops(process.env);\n\n // Disable ETag if configured\n if (!httpConfig.etag) {\n this.app.set('etag', false);\n }\n\n // Defense-in-depth for bigint-safe `res.json`. The primary mechanism is the\n // type-level `BigInt.prototype.toJSON` (bigint → decimal string) installed at\n // the `@wildo-ai/zod-decorators` bootstrap (`installBigIntJsonEncoding`), which\n // makes EVERY JSON boundary bigint-safe the way `Date.prototype.toJSON` does.\n // This app-level `json replacer` is a zero-cost belt-and-suspenders that keeps\n // `res.json` safe even if that bootstrap ever fails to run before the first\n // response. `z_money` amounts are `bigint`; without either, a money-bearing\n // response (prices, invoices, promotions, …) 500s with \"Do not know how to\n // serialize a BigInt\". Encoding as a decimal STRING (not `number`) is the\n // documented wire contract — lossless round-trip; the frontend coerces it back\n // to `bigint` on receive. The replacer runs inside Express's own\n // `JSON.stringify` and composes idempotently with the prototype `toJSON`.\n this.app.set('json replacer', ResourceSerializationUtils.bigIntSafeJsonReplacer);\n\n // Security headers protect every route, including controllers that must own\n // their method contract before CORS preflight or body parsing can terminate.\n this.setupSecurity(httpConfig.headers);\n\n // Enter the request-context ALS as early as possible — right after security headers and before any\n // controller, CORS, body parsing, routing, or the error handler — so the ENTIRE async continuation\n // of the request (including deep, un-threaded service errors) carries the correlation id.\n // Install the client-install ingest policy BEFORE the first frame can be built, so no request is\n // ever served under the uninitialized resolver. (The resolver itself also fails closed, making\n // this ordering belt-and-braces rather than load-bearing.)\n this.installClientInstanceIdIngestPolicy();\n this.setupRequestContext();\n\n this.mountCustomControllersForPhase(CustomControllerMountPhase.PRE_REQUEST_TRANSFORM);\n\n // Setup CORS (skip for platform microservices that only receive backend-to-backend requests)\n if (this.initOptions.skipCors) {\n this.logDebug('CORS middleware skipped (platform service mode)');\n } else {\n this.setupCORS(httpConfig.cors);\n }\n\n // Setup compression\n if (httpConfig.compression) {\n this.app.use(compression() as any);\n }\n\n // Setup rate limiting\n this.setupRateLimit(httpConfig.rateLimiting);\n\n // True streaming controllers still receive raw request streams, while\n // retaining the ordinary CORS and rate-limiting boundary.\n this.mountCustomControllersForPhase(CustomControllerMountPhase.RAW_REQUEST_STREAM);\n\n // Body parsing middleware - only affects routes registered AFTER this point\n this.setupBodyParsing(httpConfig);\n\n // Setup request logging\n this.setupRequestLogging();\n\n this.logDebug('Express middleware setup completed');\n }\n\n /** Mount all custom controllers assigned to one exact middleware phase. */\n private mountCustomControllersForPhase(phase: CustomControllerMountPhase): void {\n const controllers = [...this.customControllers.values()].filter((controller) => controller.getCustomControllerMountPhase() === phase);\n for (const controller of controllers) {\n this.mountCustomController(controller);\n }\n if (controllers.length > 0) {\n this.logDebug('Custom controllers mounted for middleware phase', {\n phase,\n count: controllers.length,\n controllers: controllers.map((controller) => controller.getControllerName()),\n });\n }\n }\n\n /**\n * Setup CORS middleware\n *\n * Derives allowed origins from app config's runtime.endPoints (frontend app URLs)\n * to properly support credentials (cookies/tokens) which require explicit origins.\n *\n * For platform services that don't serve frontends (e.g., crontabs-batches-manager),\n * CORS is configured permissively since they only receive internal backend requests.\n *\n * IMPORTANT: When credentials are enabled, origin CANNOT be '*' per CORS spec.\n */\n private setupCORS(corsConfig: RuntimeConfig['httpServerConfiguration']['cors']): void {\n // The engine floors live in `engine-cors-headers.backend.utils.ts`, where a test holds them against the headers the\n // engine's own browser code sends and reads (#3171).\n const mergedExposedHeaders = [\n ...ENGINE_CORS_EXPOSED_RESPONSE_HEADERS,\n ...(corsConfig.exposedHeaders ?? []),\n ];\n const mergedAllowedHeaders = [\n ...ENGINE_CORS_ALLOWED_REQUEST_HEADERS,\n ...(corsConfig.allowedHeaders ?? []),\n ];\n\n // Derive CORS origins from app config (same logic as WebSocketService)\n const allowedOrigins = this.deriveCorsOrigins();\n\n // If no frontend URLs are configured, use permissive CORS (for platform services)\n // Platform services like crontabs-batches-manager only receive internal backend requests,\n // not browser requests, so CORS doesn't apply. We use permissive config to avoid errors.\n if (allowedOrigins.length === 0) {\n this.logger.info('📝 No frontend URLs configured - using permissive CORS (platform/internal service mode)', {\n availableEndpoints: Object.keys(this.appConfigService.config?.runtime?.endPoints || {}),\n note: 'This is expected for platform services that only receive backend-to-backend requests'\n });\n\n this.app.use(cors({\n origin: '*', // Permissive for internal services\n credentials: false, // No credentials with wildcard origin\n methods: corsConfig.methods,\n allowedHeaders: mergedAllowedHeaders,\n exposedHeaders: mergedExposedHeaders,\n maxAge: corsConfig.maxAge,\n preflightContinue: corsConfig.preflightContinue,\n optionsSuccessStatus: corsConfig.optionsSuccessStatus\n }));\n\n this.logger.info('✅ CORS middleware configured (permissive mode for internal service)', {\n origin: '*',\n credentials: false\n });\n return;\n }\n\n this.app.use(cors({\n // The configured frontends, then any organization's served custom domain (#2974), decided per request.\n origin: createCorsOriginDecider({ configuredOrigins: allowedOrigins, resolver: this.customDomainHostResolver }),\n credentials: true,\n methods: corsConfig.methods,\n allowedHeaders: mergedAllowedHeaders,\n exposedHeaders: mergedExposedHeaders,\n maxAge: corsConfig.maxAge,\n preflightContinue: corsConfig.preflightContinue,\n optionsSuccessStatus: corsConfig.optionsSuccessStatus\n }));\n\n this.logger.info('✅ CORS middleware configured successfully', {\n allowedOrigins,\n credentials: true\n });\n }\n\n /**\n * Derive CORS origins from app config (frontend application URLs).\n * Reads the configured `frontendServices` to know which frontend surfaces exist,\n * then looks up their publicUrl from `runtime.endPoints`.\n *\n * @returns Array of frontend URLs, or empty array if not configured\n */\n private deriveCorsOrigins(): string[] {\n const config = this.appConfigService.config;\n const frontendServices = Object.keys(config.frontendServices ?? {});\n return frontendServices.map((frontendServiceName) => {\n const url = config.runtime?.endPoints?.[frontendServiceName]?.publicUrl;\n if (!url) {\n throw this.errorBuilder.buildError(ErrorType.CONFIGURATION, undefined, {\n context: {\n message:\n `Missing runtime.endPoints.${frontendServiceName}.publicUrl for declared frontend service \"${frontendServiceName}\". ` +\n `CORS cannot be derived safely from an incomplete runtime topology.`,\n frontendServiceName,\n },\n });\n }\n return AuthControllerUtils.stripTrailingSlash(url);\n });\n }\n\n /**\n * Setup security headers\n */\n private setupSecurity(headersConfig: RuntimeConfig['httpServerConfiguration']['headers']): void {\n const helmetOptions: any = {\n // M16: CSP now defaults to a sensible baseline via schema default. Empty string explicitly disables.\n // C2 fix: Trim whitespace to treat \" \" as empty (disabled), not as a truthy but invalid CSP.\n contentSecurityPolicy: headersConfig.contentSecurityPolicy.trim() ? {\n directives: this.parseCSP(headersConfig.contentSecurityPolicy.trim()),\n } : false,\n hsts: headersConfig.hsts ? {\n maxAge: headersConfig.hstsMaxAge,\n includeSubDomains: true,\n preload: true\n } : false,\n noSniff: headersConfig.noSniff,\n referrerPolicy: { policy: headersConfig.referrerPolicy }\n };\n\n this.app.use(helmet(helmetOptions));\n\n this.logDebug('Security middleware configured', { headersConfig });\n }\n\n /**\n * Setup rate limiting.\n *\n * M17: Uses Redis-backed atomic INCR+EXPIRE for distributed rate limiting.\n * Falls back to in-memory Map when Redis is unavailable (single-instance dev mode).\n *\n * Entering and leaving that fallback are both SIGNALLED (debounced `warn` lines carrying\n * `degradation: PERIMETER_RATE_LIMIT_{DEGRADED,RECOVERED}_SIGNAL`) — see the long comment\n * beside the signal state below for the destination, level and debounce reasoning. The\n * fallback silently converted a deployment-wide ceiling into a per-replica one, and the\n * one-time boot line at the end of this method cannot tell an operator whether it is in\n * effect right now.\n */\n private setupRateLimit(rateLimitConfig: RuntimeConfig['httpServerConfiguration']['rateLimiting']): void {\n const windowSeconds = Math.ceil(rateLimitConfig.windowMs / 1000);\n // In-memory fallback for when Redis is down\n const fallbackRequests = new Map<string, { count: number; resetTime: number }>();\n\n // Non-production relaxation of the perimeter ceiling (shared seam — see\n // `rate-limit-environment-relaxation.backend.utils`). Resolved ONCE here rather than\n // per-request: `setupRateLimit` runs inside `initialize()`, which has already refused\n // to proceed unless `AppConfigurationService` is initialized, so `applicationEnv` is\n // guaranteed readable at this point and a per-request read would only add cost.\n //\n // This limiter keys on the raw client IP by construction, which is exactly why a dev\n // machine needs the relaxation: every local process (frontend, e2e driver, companion,\n // client-integration-app) presents as `127.0.0.1` and shares one bucket, so the\n // authored per-client ceiling behaves as a per-MACHINE ceiling locally.\n const effectiveMaxRequests = relaxAbuseThrottleMaxForEnvironment(\n rateLimitConfig.maxRequests,\n this.appConfigService.applicationEnv,\n );\n\n // ---------------------------------------------------------------------------------\n // Shared-counter degradation signal.\n //\n // The in-memory fallback below is DELIBERATE and stays. The perimeter limiter is a\n // noisy-neighbour preventer, not the security boundary — that is the per-endpoint\n // `RateLimitBackendService`, which fail-CLOSES and propagates `ErrorType.DATABASE`\n // when the shared counter is unavailable (see its file docstring, which names this\n // limiter as the deliberate fail-OPEN exception). So a Redis outage must not take the\n // application off the air.\n //\n // What was missing is any way for an operator to learn that it engaged, and the\n // consequence is not cosmetic: once every replica counts in its own process memory,\n // an authored ceiling of N is enforced N × replicas times globally, and it resets on\n // every restart. A deployment can therefore sit at several times its stated cap\n // indefinitely with nothing anywhere to read.\n //\n // DESTINATION — the logger, and only the logger. It is the one channel that provably\n // works while the shared counter is down: pino writes to stdout and, through the\n // OTLP log bridge wired in `otel-preload`, on to the collector — with no dependency\n // on Redis, on a repository, or on any other service. Rejected:\n // · an audit/SIEM row — a persisted write on the perimeter hot path, requiring a\n // SECOND subsystem to be healthy for a signal whose whole premise is that a\n // subsystem is not; and this is an infrastructure diagnostic, not a\n // security-authority decision;\n // · a readiness contribution — readiness is a REFUSAL. Turning a fallback that\n // exists to keep serving into a 503 gets the process respawned by the\n // supervisor, which is strictly worse than the degradation it reports;\n // · `this.logDebug` — this service ships with `HttpServer` debug logging OFF, so\n // the signal would be invisible in exactly the deployments that need it.\n //\n // LEVEL — `warn` for BOTH the degradation and the recovery. The cap is still enforced,\n // only its scope narrowed, and a single-instance development stack with no Redis\n // legitimately runs here from its first request; an `error` on every dev boot is how\n // a channel stops being read. Recovery shares the level on purpose: emitting it any\n // lower would let a `warn` threshold show an operator the degradation and never its\n // end, which is worse than not signalling at all.\n //\n // DEBOUNCE — one line on the first fallback request of an outage, then at most one more\n // per `SHARED_RATE_LIMIT_COUNTER_DEGRADATION_SIGNAL_INTERVAL_MS`, each carrying how\n // many requests the fallback served since the previous line so the VOLUME stays\n // legible without a line per request. A new outage always signals immediately, even\n // if the previous outage's line is only seconds old — otherwise a flapping counter\n // would be reported once and then muted.\n // ---------------------------------------------------------------------------------\n let sharedCounterDegradedSince: number | null = null;\n let degradationSignalLastEmittedAt = 0;\n // Two counters, because the two lines answer different questions. The degradation line\n // answers \"how loud is this right now\" (volume BETWEEN lines, so it resets on every\n // emit); the recovery line answers \"how much traffic was actually capped per replica\"\n // (the whole outage, so it resets only at the transitions).\n let fallbackRequestsSinceLastSignal = 0;\n let fallbackRequestsThisOutage = 0;\n\n const noteSharedCounterUnavailable = (now: number, cause: unknown): void => {\n // Both count the CURRENT request, so the first line of an outage reports 1.\n fallbackRequestsSinceLastSignal++;\n fallbackRequestsThisOutage++;\n\n const isFirstRequestOfThisOutage = sharedCounterDegradedSince === null;\n if (isFirstRequestOfThisOutage) {\n sharedCounterDegradedSince = now;\n } else if (now - degradationSignalLastEmittedAt < SHARED_RATE_LIMIT_COUNTER_DEGRADATION_SIGNAL_INTERVAL_MS) {\n return;\n }\n\n // Debounce state is advanced BEFORE the emit, and the emit itself cannot throw out of\n // here. Both halves matter and neither is defensive habit:\n // · this runs inside the limiter's own `try`, whose `catch` calls `next(error)` — so\n // a logger that throws (a closed stdout, an EPIPE on a detached process) would turn\n // every request into a 500 for the duration of a Redis outage. A diagnostic must\n // never be able to refuse the traffic it is describing;\n // · advancing the state first means a throwing logger degrades to SILENCE with the\n // debounce intact, rather than re-attempting the same throwing call on every\n // subsequent request.\n const requestsCoveredByThisSignal = fallbackRequestsSinceLastSignal;\n const degradedForMs = now - sharedCounterDegradedSince;\n degradationSignalLastEmittedAt = now;\n fallbackRequestsSinceLastSignal = 0;\n\n try {\n this.logger.warn(\n 'Perimeter rate limiting degraded to per-replica in-memory counting: the shared counter is unavailable, '\n + 'so the configured ceiling is enforced per process instead of across the deployment and resets on restart.',\n {\n degradation: PERIMETER_RATE_LIMIT_DEGRADED_SIGNAL,\n effectiveMaxRequests,\n windowMs: rateLimitConfig.windowMs,\n enforcementScope: 'per-replica-in-memory',\n degradedForMs,\n fallbackRequestsSinceLastSignal: requestsCoveredByThisSignal,\n nextSignalNotBeforeMs: SHARED_RATE_LIMIT_COUNTER_DEGRADATION_SIGNAL_INTERVAL_MS,\n ...projectCaughtErrorLogFields(cause),\n },\n );\n } catch {\n // Nothing to escalate to: the logger IS the escalation channel.\n }\n };\n\n const noteSharedCounterAvailable = (now: number): void => {\n // The happy path pays one null check per request; everything below runs once per\n // recovery, at the transition only.\n if (sharedCounterDegradedSince === null) return;\n\n // Same ordering and same guard as the degradation emit above, for the same two\n // reasons: state first so a throwing logger cannot re-attempt on every later request,\n // and no throw out of a diagnostic sitting on the request path.\n const degradedForMs = now - sharedCounterDegradedSince;\n const fallbackRequestsServedDuringOutage = fallbackRequestsThisOutage;\n sharedCounterDegradedSince = null;\n degradationSignalLastEmittedAt = 0;\n fallbackRequestsSinceLastSignal = 0;\n fallbackRequestsThisOutage = 0;\n\n try {\n this.logger.warn(\n 'Perimeter rate limiting recovered: the shared counter answered again, so the configured ceiling is '\n + 'once more enforced across the deployment.',\n {\n degradation: PERIMETER_RATE_LIMIT_RECOVERED_SIGNAL,\n effectiveMaxRequests,\n enforcementScope: 'shared-counter',\n degradedForMs,\n fallbackRequestsServedDuringOutage,\n },\n );\n } catch {\n // Nothing to escalate to: the logger IS the escalation channel.\n }\n };\n\n const limiter = async (req: Request, res: Response, next: NextFunction) => {\n try {\n const clientId = req.ip || 'unknown';\n const now = Date.now();\n\n let count: number;\n let retryAfterSeconds: number;\n\n try {\n // M17: Redis-backed rate limiting — works across multiple instances\n const identifier = `http_rate_limit:${clientId}`;\n count = await this.redisService.incrementRateLimit(\n identifier,\n windowSeconds,\n );\n // The shared counter answered. If we were in the fallback, this is the recovery\n // transition — signalled here rather than after the TTL lookup below, because a\n // failing TTL degrades only the accuracy of `Retry-After`; the COUNTER, which is\n // what makes the cap deployment-wide, is demonstrably back.\n noteSharedCounterAvailable(now);\n try {\n const ttl = await this.redisService.getRateLimitTtl(identifier);\n retryAfterSeconds = ttl >= 0 ? ttl : windowSeconds;\n } catch {\n retryAfterSeconds = windowSeconds;\n }\n } catch (sharedCounterError) {\n // Fallback to in-memory when Redis is unavailable.\n // Mirrors Redis INCR+EXPIRE fixed-window: window starts on first request,\n // resets after windowMs elapses (not a sliding window).\n //\n // The caught value is bound (this was a bare `catch {}`) so the degradation\n // signal can carry WHY the shared counter refused — a connection refusal, a\n // timeout and an auth failure need different operator responses, and without the\n // cause the line only says that something is wrong.\n noteSharedCounterUnavailable(now, sharedCounterError);\n\n for (const [key, value] of fallbackRequests.entries()) {\n if (now >= value.resetTime) fallbackRequests.delete(key);\n }\n let record = fallbackRequests.get(clientId);\n if (!record || now >= record.resetTime) {\n record = { count: 0, resetTime: now + rateLimitConfig.windowMs };\n fallbackRequests.set(clientId, record);\n }\n record.count++;\n count = record.count;\n retryAfterSeconds = Math.max(0, Math.ceil((record.resetTime - now) / 1000));\n }\n\n if (count > effectiveMaxRequests) {\n res.set('Retry-After', retryAfterSeconds.toString());\n\n if (rateLimitConfig.standardHeaders) {\n res.set({\n [WildoHeaderKeys.RATE_LIMIT_LIMIT]: effectiveMaxRequests.toString(),\n [WildoHeaderKeys.RATE_LIMIT_REMAINING]: '0',\n [WildoHeaderKeys.RATE_LIMIT_RESET]: retryAfterSeconds.toString(),\n });\n }\n\n return res.status(429).json({\n error: {\n type: ErrorType.RATE_LIMIT,\n severity: ErrorSeverity.MEDIUM,\n message: ErrorCustomMessageReference.RATE_LIMIT,\n customMessage: ErrorCustomMessageReference.RATE_LIMIT,\n customMessageReference: ErrorCustomMessageReference.RATE_LIMIT,\n timestamp: new Date(now).toISOString(),\n // The perimeter limiter answers before any route runs: nothing was applied, so a client may resend (#3004).\n requestOutcome: ErrorRequestOutcome.NOT_APPLIED,\n details: {\n message: rateLimitConfig.message,\n retryAfterSeconds,\n },\n },\n });\n }\n\n if (rateLimitConfig.standardHeaders) {\n res.set({\n [WildoHeaderKeys.RATE_LIMIT_LIMIT]: effectiveMaxRequests.toString(),\n [WildoHeaderKeys.RATE_LIMIT_REMAINING]: (effectiveMaxRequests - count).toString(),\n [WildoHeaderKeys.RATE_LIMIT_RESET]: retryAfterSeconds.toString(),\n });\n }\n\n next();\n } catch (error) {\n // Express 4 doesn't handle async middleware errors — forward to error handler\n next(error);\n }\n };\n\n this.app.use(limiter);\n\n this.logDebug('Rate limiting configured (Redis-backed with in-memory fallback)', { rateLimitConfig });\n }\n\n /**\n * Setup body parsing middleware.\n *\n * IMPORTANT: PRE_REQUEST_TRANSFORM and RAW_REQUEST_STREAM controllers are\n * mounted before this middleware, so they never see body parsing.\n */\n private setupBodyParsing(httpConfig: RuntimeConfig['httpServerConfiguration']): void {\n // Capture the raw, unparsed request bytes into `req.rawBody` during JSON\n // parsing. Handlers that need the EXACT original payload — inbound webhook\n // HMAC signature verification (Stripe et al.), which must hash the\n // provider's literal bytes, not a re-serialized copy — read `req.rawBody`.\n //\n // This is express.json's canonical `verify` extension point: it runs\n // synchronously with a reference to the buffer express is about to parse,\n // so it adds no extra read and retains the buffer only for the request's\n // lifetime.\n //\n // WHY the single global parse point is the correct home (not per-route):\n // this global `express.json` runs BEFORE the main controllers registry\n // mounts (see `registerRoutes` → `MAIN_API_BASE_PATH`). It therefore always\n // parses the body and sets `req._body = true`, which turns any downstream\n // per-route `express.raw()` into a silent no-op. Non-streaming controllers\n // (e.g. the auto-registered webhook routes, which reach Express via the\n // master router — NOT a `RAW_REQUEST_STREAM` controller phase) can only\n // obtain byte-faithful bodies from this hook.\n //\n // PERF: retention is SCOPED to `rawBodyRequiredPrefixes` (webhooks only).\n // On every other route the raw buffer is not referenced, so it stays\n // GC-eligible the moment `JSON.parse` returns — normal API traffic pays\n // only a cheap `startsWith` check, never a retained copy of its own body.\n // Tight, prefix-scoped body cap for the OAuth credential/token endpoints + a translator that reports an\n // over-limit / malformed body as a clean 4xx instead of an INTERNAL 500. Registered BEFORE the global\n // parsers so its 32 KB limit governs `/oauth/*` (the scoped parser sets `req._body`, the global one then\n // skips the already-parsed body). Extracted for isolated testing — see `applyOAuthBodyCap` + its tests.\n applyOAuthBodyCap(this.app, MAIN_API_BASE_PATH);\n // Application inbound endpoints take their body raw, so the receiver audits a malformed one (#1596).\n applyInboundApplicationEndpointRawBody(this.app, MAIN_API_BASE_PATH);\n // A provider endpoint that may receive more than the global parsers read (a pushed email, #3395) takes its body raw,\n // up to its own declared limit. The routes are declared by the webhook controller when it mounts them.\n if (this.inboundLargeBodyRoutes) applyInboundLargeBodyProviderEndpoints(this.app, this.inboundLargeBodyRoutes, MAIN_API_BASE_PATH);\n // The CSP violation collector's 64 KiB cap, and the only parser of `application/csp-report` (#2867): unauthenticated,\n // so it is bounded before the global parser's multi-megabyte limit can apply.\n applyCspViolationReportBodyCap(this.app, MAIN_API_BASE_PATH);\n this.app.use(express.json({\n limit: httpConfig.bodyParserLimit,\n // Parse `application/json` AND any structured-syntax-suffix JSON media type\n // (RFC 6839 `+json`) — notably SCIM's mandated `application/scim+json`\n // (RFC 7644 §3.1). Without this, SCIM POST/PUT/PATCH bodies arrive unparsed\n // (`req.body` undefined) and the /scim/v2/* create/update handlers 500.\n type: ['application/json', 'application/*+json'],\n verify: retainRawBodyUnder(this.rawBodyRequiredPrefixes),\n }));\n // The same capture for form bodies (#2659): Slack signs the raw bytes of its interactions and slash commands,\n // which arrive `application/x-www-form-urlencoded`, and a re-encoding of the parsed fields is not what it signed.\n this.app.use(express.urlencoded({ extended: true, limit: httpConfig.urlEncodedLimit, verify: retainRawBodyUnder(this.rawBodyRequiredPrefixes) }));\n // A provider webhook over either parser's limit reaches its receiver as a flag, which answers an AUDITED 413 (#3395):\n // a pushed email over the limit is a message refused, and must leave a record rather than a generic parser error.\n for (const prefix of this.rawBodyRequiredPrefixes) this.app.use(prefix, translateOversizedInboundBody);\n // Auth-hardening Slice A — `__wildo_refresh` `HttpOnly` cookie carries the\n // refresh token on `/api/v1/auth/*` routes. `cookie-parser` populates `req.cookies`\n // so `AuthControllerUtils.extractRefreshTokenFromCookie` can pick the cookie\n // up (post A-Step 6 the helper is cookie-only — no body fallback).\n // Cookie-parser is a no-op for routes that never read cookies, so mounting\n // it globally has no side-effects on non-auth controllers.\n this.app.use(cookieParser());\n\n this.logDebug('Body parsing middleware configured');\n }\n\n /**\n * Enter the request-scoped correlation ALS for every inbound request, wrapping the ENTIRE async\n * continuation (`runWithRequestContext(frame, () => next())`). Mounted first (after security headers)\n * so correlation is available to every downstream middleware, controller, service, and — critically —\n * the error handler, letting even un-threaded deep errors carry the correlation id.\n *\n * The frame reuses a SAFE inbound `x-correlation-id` (cross-service / cross-hop chaining) or mints a\n * fresh id, and captures the frontend surface (`x-frontend-service-name`). The per-request\n * `ExecutionContext` later adopts this frame's id (R13), so the EC, logs, and audit share one id.\n *\n * `x-client-instance-id` is simply forwarded: whether it is ADMITTED is decided by the ingest policy\n * installed via `setClientInstanceIdIngestPolicy` (see {@link installClientInstanceIdIngestPolicy}),\n * which every frame construction consults — so the opt-in holds for this seam, the WebSocket\n * handshake, and any future transport without each having to re-apply it.\n */\n private setupRequestContext(): void {\n this.app.use((req: Request, _res: Response, next: NextFunction) => {\n const frame = buildRequestContextFrame({\n inboundCorrelationId: req.get(WildoHeaderKeys.CORRELATION_ID),\n frontendServiceName: req.get(WildoHeaderKeys.FRONTEND_SERVICE_NAME),\n clientInstanceId: req.get(WildoHeaderKeys.CLIENT_INSTANCE_ID),\n // Read only by recorders that must describe the request's client (#2317); never logged.\n requestOrigin: { ipAddress: getClientIpFromRequest(req), userAgent: req.get(WildoHeaderKeys.USER_AGENT) },\n });\n runWithRequestContext(frame, () => next());\n });\n }\n\n /**\n * Install the application's client-install ingest policy into the request-context chokepoint.\n *\n * Fail-closed by construction: an unresolved configuration, an absent `compliance` block, and an\n * explicit `DISABLED` all answer `false`, so the only way to admit the identifier is an application\n * that deliberately authored `SESSION` or `PERSISTENT`. The SCOPE (session vs persistent) governs\n * the CLIENT's storage lifetime, not the server's admission — either non-disabled value admits it.\n *\n * Passed as a closure (evaluated per request) rather than a snapshot boolean so a configuration\n * reload takes effect immediately and pre-configuration requests still fail closed.\n *\n * assurance-control: WILDO.PRIVACY.DATA_MINIMIZATION — binds collection of the device-stored\n * client-install identifier to an explicit, application-authored policy; absent policy = no collection.\n */\n private installClientInstanceIdIngestPolicy(): void {\n setClientInstanceIdIngestPolicy(() => {\n // TOTAL by construction: this resolver runs on the request path, inside frame construction, so an\n // exception here would not merely mis-answer the policy — it would fail the REQUEST. (Proven, not\n // theoretical: an earlier revision dereferenced `appConfigService` directly and turned every\n // request into a 500 wherever that dependency was absent.) Any failure to determine the policy is\n // therefore answered `false`, which is also the correct privacy default: when in doubt, collect\n // nothing.\n try {\n if (!this.appConfigService?.isInitialized()) {\n return false;\n }\n const scope = this.appConfigService.config?.compliance?.clientInstanceIdScope;\n return scope !== undefined && scope !== ClientInstanceIdScope.DISABLED;\n } catch {\n return false;\n }\n });\n }\n\n /**\n * Setup request logging middleware\n * Skips logging successful health check requests to reduce noise\n */\n private setupRequestLogging(): void {\n this.app.use((req: Request, res: Response, next: NextFunction) => {\n const startTime = Date.now();\n\n res.on('finish', () => {\n // Skip logging successful health check requests (only log failures)\n const isHealthCheck = req.path === ENGINE_ROOT_ROUTES[EngineRootRouteKey.HEALTH_LIVENESS]\n || req.path === ENGINE_ROOT_ROUTES[EngineRootRouteKey.HEALTH_READINESS]\n || req.path === ENGINE_ROOT_ROUTES[EngineRootRouteKey.HEALTH_TIME];\n const isSuccessful = res.statusCode === 200;\n\n if (isHealthCheck && isSuccessful) {\n return; // Skip logging successful health checks\n }\n\n const duration = Date.now() - startTime;\n this.logDebug('HTTP Request', {\n method: req.method,\n path: req.path,\n statusCode: res.statusCode,\n duration: `${duration}ms`,\n userAgent: req.get(WildoHeaderKeys.USER_AGENT),\n ip: req.ip\n });\n });\n\n next();\n });\n }\n\n /**\n * Register all routes from controllers registry and custom controllers.\n *\n * Note: early-phase controllers are already mounted by setupExpressApp().\n * This method mounts only ordinary post-middleware controllers.\n */\n private async registerRoutes(): Promise<void> {\n // Mount health controller at root level (for Kubernetes probes)\n const healthBasePath = this.healthController.getCustomMountBasePath();\n this.app.use(healthBasePath, this.healthController.getRouter());\n this.mountedRoutes.push(...collectMountedRoutes(this.healthController.getRouter(), healthBasePath, 'controller health', MountedRouteOrigin.CONTROLLER));\n this.logDebug('Health controller mounted at root level', { basePath: healthBasePath });\n\n // CRDT clock synchronization endpoint (root-level like health probes)\n this.app.get(ENGINE_ROOT_ROUTES[EngineRootRouteKey.HEALTH_TIME], (_req, res) => {\n const now = Date.now();\n res.setHeader('Cache-Control', 'no-store');\n res.setHeader(WildoHeaderKeys.X_SERVER_TIME, String(now));\n res.json({ serverTime: now });\n });\n this.mountedRoutes.push({ owner: 'engine clock', origin: MountedRouteOrigin.CONTROLLER, path: ENGINE_ROOT_ROUTES[EngineRootRouteKey.HEALTH_TIME], methods: ['get'] });\n\n // #2974: the served custom domains, for the deployment's edge. INTERNAL-ONLY (no forwarding header) and 404\n // otherwise, so the edge never routes a stranger to the list of which tenants use which domain.\n if (this.customDomainEdge) {\n const edge = this.customDomainEdge;\n const internalOnly = (handler: (res: express.Response) => Promise<void>) => (req: express.Request, res: express.Response, next: express.NextFunction) => {\n if (!isInternalEdgeRequest(req.headers)) {\n res.status(404).end();\n return;\n }\n res.setHeader('Cache-Control', 'no-store');\n handler(res).catch(next);\n };\n this.app.get(ENGINE_ROOT_ROUTES[EngineRootRouteKey.EDGE_CUSTOM_DOMAINS], internalOnly(async (res) => {\n // The frontend a custom domain serves, by its endpoint key (= its k8s Service name). Without one nothing is routed.\n const frontendServiceName = this.appConfigService.resolveDefaultFrontendServiceName();\n const answer: CustomDomainEdgeList = { domains: frontendServiceName ? await edge.servedDomains() : [], frontendServiceName };\n res.json(answer);\n }));\n this.app.get(ENGINE_ROOT_ROUTES[EngineRootRouteKey.EDGE_CUSTOM_DOMAINS_TRAEFIK], internalOnly(async (res) => {\n const hostOf = (url: string | undefined) => { try { return url ? new URL(url).hostname : undefined; } catch { return undefined; } };\n const config = this.appConfigService.config;\n const defaultFrontend = this.appConfigService.resolveDefaultFrontendServiceName();\n const backendHost = hostOf(config.runtime?.endPoints?.main_backend_api?.publicUrl);\n const frontendHost = hostOf(defaultFrontend ? config.runtime?.endPoints?.[defaultFrontend]?.publicUrl : undefined);\n // Without both hosts there is no service to route to: an empty configuration serves nothing (fail closed).\n const domains = backendHost && frontendHost ? await edge.servedDomains() : [];\n res.json(buildTraefikDynamicConfiguration(domains, {\n backendHost: backendHost ?? '', frontendHost: frontendHost ?? '', certResolver: COMPOSE_EDGE_CERT_RESOLVER, entryPoint: COMPOSE_EDGE_SECURE_ENTRYPOINT,\n }));\n }));\n for (const key of [EngineRootRouteKey.EDGE_CUSTOM_DOMAINS, EngineRootRouteKey.EDGE_CUSTOM_DOMAINS_TRAEFIK]) {\n this.mountedRoutes.push({ owner: 'custom-domain edge', origin: MountedRouteOrigin.CONTROLLER, path: ENGINE_ROOT_ROUTES[key], methods: ['get'] });\n }\n }\n\n // Mount the main controllers registry at the shared MAIN_API_BASE_PATH\n // (`/api/v1`). This is the single source of truth for the prefix — the\n // frontend HTTP client and the refresh-token cookie `Path` derive from\n // the same constant so the served auth routes and the cookie scope can\n // never drift apart (see MAIN_API_BASE_PATH / REFRESH_TOKEN_COOKIE_PATH).\n const mainRouter = this.controllersRegistry.getMasterRouter();\n this.app.use(MAIN_API_BASE_PATH, mainRouter);\n // The master router tries every resource controller, then every manual controller, in registration order.\n for (const [resourceType, controller] of this.controllersRegistry.getAllResourceControllers()) {\n this.mountedRoutes.push(...collectMountedRoutes(controller.getRouter(), MAIN_API_BASE_PATH, `resource ${String(resourceType)}`, MountedRouteOrigin.RESOURCE));\n }\n for (const [name, controller] of this.controllersRegistry.getAllCustomControllers()) {\n this.mountedRoutes.push(...collectMountedRoutes(controller.getRouter(), MAIN_API_BASE_PATH, `controller ${name}`, MountedRouteOrigin.CONTROLLER));\n }\n\n this.logDebug('Main controllers registry mounted', { basePath: MAIN_API_BASE_PATH });\n\n /**\n * RFC 8414 authorization-server metadata, at the location the RFC actually specifies.\n *\n * Our issuer carries a path (`https://<host>/api/v1`), and for a path-bearing issuer the\n * well-known segment goes BETWEEN the host and the path — not after it:\n *\n * \"If the issuer identifier value contains a path component, any terminating \"/\" MUST be\n * removed before inserting \"/.well-known/\" and the well-known URI suffix between the host\n * component and the path component.\"\n *\n * with the RFC's own example resolving issuer `https://example.com/issuer1` to\n * `GET /.well-known/oauth-authorization-server/issuer1`.\n * spec-cite: RFC 8414 § 3 (Obtaining Authorization Server Metadata), fetched 2026-08-11.\n *\n * The controller already serves the document at `<issuer>/.well-known/oauth-authorization-server`\n * — the OIDC Discovery convention (issuer + suffix), which is correct for\n * `/.well-known/openid-configuration` and WRONG for this one. So a client that followed RFC 8414\n * asked for `/.well-known/oauth-authorization-server/api/v1`, which is OUTSIDE the API mount, and\n * received the SPA shell: HTML where it expected JSON. It could not discover the authorization\n * server, so it never opened a login window — the failure looked like a silent no-op rather than a\n * 404, which is why it survived twelve lanes and two real-client sessions.\n *\n * Delegating to `mainRouter` rather than re-registering the handler keeps ONE implementation:\n * the document, its CORS posture and its cache headers cannot drift between the two locations.\n * The router is mounted at `MAIN_API_BASE_PATH`, so it matches on the path RELATIVE to that mount.\n */\n const rfc8414MetadataPath = rfc8414AuthorizationServerMetadataPath(MAIN_API_BASE_PATH);\n const mountRelativeMetadataPath = MANUAL_CONTROLLER_ROUTES_URLS[ManualControllerRouteKey.OAUTH_PROVIDER_AS_METADATA];\n this.mountedRoutes.push({ owner: 'engine RFC 8414 alias', origin: MountedRouteOrigin.CONTROLLER, path: rfc8414MetadataPath, methods: ['get'] });\n this.app.get(rfc8414MetadataPath, (req, res, next) => {\n req.url = mountRelativeMetadataPath;\n mainRouter(req, res, next);\n });\n this.logDebug('RFC 8414 authorization-server metadata alias mounted', {\n rfc8414Path: rfc8414MetadataPath,\n servesSameDocumentAs: `${MAIN_API_BASE_PATH}${mountRelativeMetadataPath}`,\n });\n\n /**\n * RFC 9728 § 3 protected-resource metadata, at the location a client DERIVES from the resource\n * identifier — the same insertion rule as RFC 8414 above, applied to the MCP resource.\n *\n * Both MCP resource shapes are aliased, because the derivation follows the identifier and the\n * identifier grows a segment for a named instance\n * (`resolveResourceServerAudience(MCP, ref)` → `<apiAudience>/mcp/<ref>`):\n *\n * resource `<origin>/api/v1/mcp` → `/.well-known/oauth-protected-resource/api/v1/mcp`\n * resource `<origin>/api/v1/mcp/<ref>` → `/.well-known/oauth-protected-resource/api/v1/mcp/<ref>`\n *\n * Aliasing only the default would leave every NAMED instance underivable while looking fixed — the\n * shape of defect this codebase has now paid for repeatedly, so both are mounted together.\n *\n * Unlike the RFC 8414 case this closes a LATENT gap rather than a live outage: the 401 challenge\n * names `resource_metadata` explicitly and MCP directs clients to follow it, which is the route a\n * real client was observed taking. A deriving client — which RFC 9728 § 5.1 equally permits — was\n * receiving the SPA shell.\n * spec-cite: RFC 9728 § 3 (Protected Resource Metadata Request), fetched 2026-08-12.\n *\n * Delegation to `mainRouter` is the same trick and for the same reason: one handler, so the\n * document, its `resource`, its cache headers and its 404-on-unknown-instance behaviour cannot\n * drift between the derived and the advertised location.\n */\n const mcpMountPath = MANUAL_CONTROLLER_ROUTES_URLS[ManualControllerRouteKey.MCP_ENDPOINT];\n const mountRelativePrmPath = MANUAL_CONTROLLER_ROUTES_URLS[ManualControllerRouteKey.MCP_PROTECTED_RESOURCE_METADATA];\n const rfc9728DefaultPath = rfc9728ProtectedResourceMetadataPath(`${MAIN_API_BASE_PATH}${mcpMountPath}`);\n this.mountedRoutes.push(\n { owner: 'engine RFC 9728 alias', origin: MountedRouteOrigin.CONTROLLER, path: rfc9728DefaultPath, methods: ['get'] },\n { owner: 'engine RFC 9728 alias', origin: MountedRouteOrigin.CONTROLLER, path: `${rfc9728DefaultPath}/:instanceRef`, methods: ['get'] },\n );\n this.app.get(rfc9728DefaultPath, (req, res, next) => {\n req.url = mountRelativePrmPath;\n mainRouter(req, res, next);\n });\n this.app.get(`${rfc9728DefaultPath}/:instanceRef`, (req, res, next) => {\n // Re-enter through the router's OWN named-instance route so `:instanceRef` is parsed, validated\n // and 404'd by the one handler that knows the instance registry — never resolved here.\n req.url = `${mcpMountPath}/${encodeURIComponent(req.params['instanceRef'] ?? '')}${mountRelativePrmPath}`;\n mainRouter(req, res, next);\n });\n this.logDebug('RFC 9728 protected-resource metadata aliases mounted', {\n rfc9728DefaultPath,\n rfc9728InstancePath: `${rfc9728DefaultPath}/:instanceRef`,\n servesSameDocumentAs: `${MAIN_API_BASE_PATH}${mountRelativePrmPath}`,\n });\n\n // Mount ordinary custom controllers (early phases are already mounted).\n let standardControllerCount = 0;\n this.customControllers.forEach((controller) => {\n if (controller.getCustomControllerMountPhase() === CustomControllerMountPhase.STANDARD) {\n this.mountCustomController(controller);\n standardControllerCount++;\n }\n });\n\n this.logDebug('Routes registration completed', {\n totalCustomControllers: this.customControllers.size,\n standardControllers: standardControllerCount\n });\n\n this.assertRouteTableInvariant();\n }\n\n /**\n * Refuse to start unless every request URL reaches exactly one route, deterministically (#2200).\n *\n * Express answers with the first matching route in mount order, so the table this server mounted is checked as a\n * whole, in that order (`analyzeRouteTable`): no two routes for the same method and pattern, no pair where each is\n * more specific in a different segment, no specific route mounted after a general one that captures it, and no\n * application resource route sharing any URL with an engine route. The refusal names every conflicting pair; the\n * remedy is renaming a route, which needs nothing running, so a boot refusal is the right place. A route whose\n * pattern cannot be compared segment by segment is reported, never guessed at.\n */\n private assertRouteTableInvariant(): void {\n const analysis = analyzeRouteTable(this.mountedRoutes);\n if (analysis.undecidable.length > 0) {\n this.logger.warn('Routes the route-table invariant cannot compare (wildcard, optional group or RegExp patterns)', {\n routes: analysis.undecidable.map((route) => `${route.owner}: ${route.path}`),\n });\n }\n if (analysis.conflicts.length === 0) return;\n throw this.errorBuilder.buildError(ErrorType.CONFIGURATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.CONTROLLER_ROUTE_TABLE_CONFLICT,\n context: {\n message: 'Two mounted routes answer the same URL and method in a way mount order cannot resolve, so one of them '\n + 'would be unreachable or answer by accident. Rename one of the routes.',\n conflicts: analysis.conflicts.map((conflict) => ({\n kind: conflict.kind,\n methods: conflict.methods,\n mountedFirst: `${conflict.first.owner}: ${conflict.first.path}`,\n mountedSecond: `${conflict.second.owner}: ${conflict.second.path}`,\n })),\n },\n });\n }\n\n /**\n * Mount a custom controller\n */\n private mountCustomController(controller: AbstractControllerBackendService): void {\n const controllerName = controller.getControllerName();\n const router = controller.getRouter();\n const basePath = this.getControllerBasePath(controller);\n\n this.app.use(basePath, router);\n this.mountedRoutes.push(...collectMountedRoutes(router, basePath, `controller ${controllerName}`, MountedRouteOrigin.CONTROLLER));\n\n this.logDebug('Custom controller mounted', {\n controllerName,\n basePath,\n mountPhase: controller.getCustomControllerMountPhase()\n });\n }\n\n /**\n * Get the base path for a controller.\n * Uses custom path if provided, otherwise falls back to /api/custom/<kebab-case-name>\n */\n private getControllerBasePath(controller: AbstractControllerBackendService): string {\n const maybeCustomBasePath = (controller as any)?.getCustomMountBasePath?.();\n return typeof maybeCustomBasePath === 'string' && maybeCustomBasePath.startsWith('/')\n ? maybeCustomBasePath\n : `/api/custom/${this.kebabCase(controller.getControllerName())}`;\n }\n\n /**\n * Setup error handling middleware\n */\n private setupErrorHandling(): void {\n // 404 handler\n this.app.use((req: Request, res: Response, next: NextFunction) => {\n res.status(404).json({\n error: {\n message: 'Route not found',\n path: req.originalUrl,\n method: req.method,\n timestamp: new Date().toISOString()\n }\n });\n });\n\n // Global error handler - use ErrorHandlerService for proper error responses\n this.app.use(this.errorHandler.expressErrorHandler());\n\n this.logDebug('Error handling middleware configured');\n }\n\n /**\n * Start the HTTP server\n */\n private async startServer(): Promise<void> {\n return new Promise(async (resolve, reject) => {\n try {\n const appConfig = this.appConfigService.config;\n\n // Build server base URL from endpoint string, with env overrides\n let endpointString: string | undefined = undefined;\n const svcName = this.appConfigService.serviceName;\n\n if (svcName) {\n endpointString = (appConfig as any)?.runtime?.endPoints?.[svcName]?.internalUrl;\n }\n\n let urlProtocol: 'http:' | 'https:' = 'http:';\n let host = 'localhost';\n let port = 4000;\n\n try {\n const urlString = endpointString && endpointString.includes('://')\n ? endpointString\n : `http://${endpointString || 'localhost:4000'}`;\n const url = new URL(urlString);\n urlProtocol = (url.protocol === 'https:' ? 'https:' : 'http:');\n host = url.hostname || host;\n if (url.port) {\n port = parseInt(url.port, 10);\n } else if (url.protocol === 'https:') {\n port = 443;\n } else if (url.protocol === 'http:') {\n port = 80;\n }\n } catch {}\n\n if (process.env.HOST) host = process.env.HOST;\n if (process.env.PORT) port = parseInt(process.env.PORT, 10);\n\n this.baseUrl = `${urlProtocol}//${host}:${port}`;\n\n // Configure server options\n this.app.set('port', port);\n\n // Set server timeouts (before starting server)\n const runtimeConfig = this.extractRuntimeConfig(appConfig);\n const httpConfig = runtimeConfig.httpServerConfiguration;\n\n // Start listening\n this.server = this.app.listen(port, host, async () => {\n try {\n // Set server timeouts after server is created\n this.server!.timeout = httpConfig.requestTimeout;\n this.server!.keepAliveTimeout = httpConfig.keepAliveTimeout;\n this.server!.headersTimeout = httpConfig.headersTimeout;\n\n if (httpConfig.maxConnections) {\n this.server!.maxConnections = httpConfig.maxConnections;\n }\n\n // After the timeouts and the connection cap, which the bridge listener copies (#3387).\n await this.openContainerHostGatewayListenerIfDeclared(host, port);\n\n this.logDebug('🌐 HTTP Server started successfully', {\n environment: process.env.APPLICATION_ENV || process.env.NODE_ENV || 'development',\n url: this.baseUrl\n });\n\n // Initialize WebSocket service AFTER server is ready\n // Skip for platform microservices that don't need real-time browser connections\n if (this.initOptions.skipWebSocket) {\n this.logDebug('WebSocket initialization skipped (platform service mode)');\n } else {\n // Note: CORS origins are derived internally by WebSocketService.getCorsOrigins()\n await this.webSocketService.initialize(this.server!);\n this.logDebug('WebSocket service initialized');\n }\n\n resolve();\n } catch (error) {\n reject(error);\n }\n });\n\n // Handle server errors\n this.server.on('error', (error: any) => {\n if (error.code === 'EADDRINUSE') {\n const message = `Port ${port} is already in use`;\n this.logger.error(message);\n /*\n * The code and the port travel ON the error (#3214): the start record classifies the failure from them as a\n * DEV-STACK problem (another process holds the port), which the build lane must not blame on a task.\n */\n reject(Object.assign(new Error(message), { code: 'EADDRINUSE', port }));\n } else {\n this.logger.error('HTTP Server error:', error);\n reject(error);\n }\n });\n\n } catch (error) {\n reject(error);\n }\n });\n }\n\n\n /**\n * Open the second listener on the host's Docker bridge gateway when the native LOCAL lane declared one (#3387), so a\n * compose minion or worker on Docker Engine for Linux reaches this backend through `host.docker.internal`.\n *\n * Never fatal: the loopback listener serves everything on the host, and a missing bridge (Docker stopped after the\n * `.env` was written) or an unusable value must not stop the backend from starting. Each is logged with the address\n * and the reason, so a minion's refused connection leads straight here.\n */\n private async openContainerHostGatewayListenerIfDeclared(primaryListenHost: string, port: number): Promise<void> {\n const gatewayHost = process.env[HttpServerEnvKey.CONTAINER_HOST_GATEWAY_LISTEN_HOST]?.trim();\n if (!gatewayHost || !this.server) return;\n const unusable = describeUnusableContainerHostGatewayListenHost(gatewayHost, primaryListenHost);\n if (unusable !== null) {\n this.logger.warn(`${HttpServerEnvKey.CONTAINER_HOST_GATEWAY_LISTEN_HOST} ignored: ${unusable}. Compose runtimes on a Linux Docker host will not reach this backend.`);\n return;\n }\n try {\n this.containerHostGatewayListener = await openContainerHostGatewayListener(this.server, gatewayHost, port);\n this.logDebug('HTTP server also listening on the Docker bridge gateway', { host: gatewayHost, port });\n } catch (error) {\n const code = (error as { code?: unknown } | null)?.code;\n this.logger.warn(\n `Could not listen on the Docker bridge gateway ${gatewayHost}:${port}${typeof code === 'string' ? ` (${code})` : ''}. ` +\n 'Compose runtimes on a Linux Docker host will not reach this backend until it restarts with the bridge present; ' +\n 'regenerate the environment files if the bridge address changed.',\n );\n }\n }\n\n // ================================\n // Utility Methods\n // ================================\n\n /**\n * Parse CSP string into helmet format\n */\n private parseCSP(csp: string): Record<string, string[]> {\n // Simple CSP parser - can be enhanced as needed\n const directives: Record<string, string[]> = {};\n\n csp.split(';').forEach(directive => {\n const [key, ...values] = directive.trim().split(' ');\n if (key && values.length > 0) {\n directives[key.replace(/-([a-z])/g, (g) => g[1].toUpperCase())] = values;\n }\n });\n\n return directives;\n }\n\n /**\n * Convert string to kebab case\n */\n private kebabCase(str: string): string {\n return str\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .replace(/[\\s_]+/g, '-')\n .toLowerCase();\n }\n\n}\n"]}
@@ -36,4 +36,26 @@ export declare function retainRawBodyUnder(prefixes: readonly string[]): (req: I
36
36
  * remaining stream a second time.
37
37
  */
38
38
  export declare function translateOversizedInboundBody(err: unknown, req: Request, _res: Response, next: NextFunction): void;
39
+ /**
40
+ * The provider endpoints whose body may be larger than the global parsers read (#3395), by full route path: a vendor that
41
+ * pushes a whole email in its webhook (Postmark, Mailgun) declares a `maxBodyBytes` past the 10 MB the global JSON parser
42
+ * reads, and the delivery stores such a body outside its row. One instance per backend: the webhook controller declares
43
+ * the routes it mounts, and the body parser mounted before the global parsers reads them at request time.
44
+ */
45
+ export declare class InboundLargeBodyRoutesBackendService {
46
+ private readonly limits;
47
+ /** The route at `fullPath` (`/api/v1/webhooks/{provider}/{endpoint}`) reads bodies up to `limitBytes`. */
48
+ declare(fullPath: string, limitBytes: number): void;
49
+ /** The body limit of the route a request arrived on, or undefined when the global parsers read it. */
50
+ limitFor(requestUrl: string | undefined): number | undefined;
51
+ }
52
+ /**
53
+ * Read the body of a large-body provider endpoint RAW, with that endpoint's own limit (#3395), before the global parsers
54
+ * (whose 10 MB limit would refuse it). Mounted on the webhook prefix; every other request passes through untouched. The
55
+ * bytes land in `req.rawBody` (verification needs them exactly), the body is marked parsed so the global parsers skip
56
+ * it, and a body over the endpoint's limit reaches the receiver as the same flag the global parsers' refusal sets, so it
57
+ * is answered with the receiver's audited 413. The limit is the endpoint's own, so the server never buffers more than the
58
+ * endpoint may accept.
59
+ */
60
+ export declare function applyInboundLargeBodyProviderEndpoints(app: Express, routes: Pick<InboundLargeBodyRoutesBackendService, 'limitFor'>, basePath?: string): void;
39
61
  //# sourceMappingURL=inbound-endpoint-raw-body.backend.utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"inbound-endpoint-raw-body.backend.utils.d.ts","sourceRoot":"","sources":["../../../../../src/runtime/services/utils/inbound-endpoint-raw-body.backend.utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACjE,OAAgB,EAAE,KAAK,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,SAAS,CAAC;AAKhG;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,sCAAsC,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,GAAE,MAA2B,GAAG,IAAI,CAUhH;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAOhI;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CAQlH"}
1
+ {"version":3,"file":"inbound-endpoint-raw-body.backend.utils.d.ts","sourceRoot":"","sources":["../../../../../src/runtime/services/utils/inbound-endpoint-raw-body.backend.utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACjE,OAAgB,EAAE,KAAK,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,SAAS,CAAC;AAKhG;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,sCAAsC,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,GAAE,MAA2B,GAAG,IAAI,CAUhH;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAOhI;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CAQlH;AAED;;;;;GAKG;AACH,qBAAa,oCAAoC;IAC/C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA6B;IAEpD,0GAA0G;IAC1G,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAInD,sGAAsG;IACtG,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS;CAI7D;AAED;;;;;;;GAOG;AACH,wBAAgB,sCAAsC,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,oCAAoC,EAAE,UAAU,CAAC,EAAE,QAAQ,GAAE,MAA2B,GAAG,IAAI,CA6BhL"}