@wildo-ai/saas-backend-lib 1.1.3 → 1.1.4

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 (1056) hide show
  1. package/dist/esm/__tests__/fixture-deep-partial.d.ts.map +1 -1
  2. package/dist/esm/__tests__/integration/redis-integration-gate.d.ts.map +1 -1
  3. package/dist/esm/__tests__/setup.d.ts.map +1 -1
  4. package/dist/esm/__tests__/test-container.d.ts.map +1 -1
  5. package/dist/esm/applications/models/applications.backend.schemas.d.ts.map +1 -1
  6. package/dist/esm/applications/seeds/application-metadata-defaults.seeds.d.ts.map +1 -1
  7. package/dist/esm/applications/services/worker-remote-client-factory.backend.service.d.ts.map +1 -1
  8. package/dist/esm/applications/services/worker-remote-client-factory.backend.service.js.map +1 -1
  9. package/dist/esm/base-classes/models/manual-controllers.backend.definition.d.ts.map +1 -1
  10. package/dist/esm/base-classes/models/manual-controllers.backend.definition.js.map +1 -1
  11. package/dist/esm/base-classes/models/repositories.backend.schemas.d.ts.map +1 -1
  12. package/dist/esm/base-classes/services/__tests__/mock-resource-operation-helper.service.d.ts +1 -1
  13. package/dist/esm/base-classes/services/__tests__/mock-resource-operation-helper.service.d.ts.map +1 -1
  14. package/dist/esm/base-classes/services/batches/batches-cronjobs-custom-execution.service.d.ts.map +1 -1
  15. package/dist/esm/base-classes/services/batches/batches-cronjobs-executor.backend.service.d.ts.map +1 -1
  16. package/dist/esm/base-classes/services/batches/batches-cronjobs-resource-execution.backend.service.d.ts.map +1 -1
  17. package/dist/esm/base-classes/services/batches/child-lifecycle-teardown.batch.backend.service.d.ts.map +1 -1
  18. package/dist/esm/base-classes/services/batches/child-lifecycle-teardown.batch.backend.service.js.map +1 -1
  19. package/dist/esm/base-classes/services/batches/credential-expiry-sweep.batch.backend.service.d.ts.map +1 -1
  20. package/dist/esm/base-classes/services/batches/credential-expiry-sweep.batch.backend.service.js +12 -1
  21. package/dist/esm/base-classes/services/batches/credential-expiry-sweep.batch.backend.service.js.map +1 -1
  22. package/dist/esm/base-classes/services/batches/engine-custom-batch-manifests.d.ts.map +1 -1
  23. package/dist/esm/base-classes/services/batches/engine-custom-batch-manifests.js.map +1 -1
  24. package/dist/esm/base-classes/services/batches/resource-retention-sweep.batch.backend.service.d.ts.map +1 -1
  25. package/dist/esm/base-classes/services/batches/suspension-reactivation-sweep.batch.backend.service.d.ts.map +1 -1
  26. package/dist/esm/base-classes/services/controllers/abstract-controller.backend.service.d.ts.map +1 -1
  27. package/dist/esm/base-classes/services/controllers/controller-resource.backend.service.d.ts.map +1 -1
  28. package/dist/esm/base-classes/services/controllers/controller-resource.backend.service.js.map +1 -1
  29. package/dist/esm/base-classes/services/controllers/controllers-registry-handler.backend.service.d.ts.map +1 -1
  30. package/dist/esm/base-classes/services/controllers/controllers-registry-handler.backend.service.js.map +1 -1
  31. package/dist/esm/base-classes/services/controllers/utils/audit-access-fields.backend.utils.d.ts.map +1 -1
  32. package/dist/esm/base-classes/services/controllers/utils/operation-response-serializer.backend.utils.d.ts.map +1 -1
  33. package/dist/esm/base-classes/services/controllers/validate-field-handler.backend.service.d.ts.map +1 -1
  34. package/dist/esm/base-classes/services/repositories/__tests__/method-span-scan.guard-helpers.d.ts.map +1 -1
  35. package/dist/esm/base-classes/services/repositories/__tests__/mock-repositories-registry-handler.service.d.ts.map +1 -1
  36. package/dist/esm/base-classes/services/repositories/field-clearing-partition.backend.d.ts.map +1 -1
  37. package/dist/esm/base-classes/services/repositories/http-api/http-api-filter-translation.backend.d.ts.map +1 -1
  38. package/dist/esm/base-classes/services/repositories/http-api/http-api-provider-access.backend.d.ts.map +1 -1
  39. package/dist/esm/base-classes/services/repositories/http-api/http-api-provider-access.backend.js +13 -4
  40. package/dist/esm/base-classes/services/repositories/http-api/http-api-provider-access.backend.js.map +1 -1
  41. package/dist/esm/base-classes/services/repositories/http-api/http-api-query.backend.d.ts.map +1 -1
  42. package/dist/esm/base-classes/services/repositories/http-api/http-api-read-client.backend.d.ts.map +1 -1
  43. package/dist/esm/base-classes/services/repositories/http-api/http-api-read-client.backend.js +17 -0
  44. package/dist/esm/base-classes/services/repositories/http-api/http-api-read-client.backend.js.map +1 -1
  45. package/dist/esm/base-classes/services/repositories/http-api/http-api-resource-repository.backend.service.d.ts.map +1 -1
  46. package/dist/esm/base-classes/services/repositories/http-api/http-api-resource-repository.backend.service.js.map +1 -1
  47. package/dist/esm/base-classes/services/repositories/http-api/http-api-rest-operation-reference.backend.d.ts.map +1 -1
  48. package/dist/esm/base-classes/services/repositories/http-api/http-api-rest-operation-reference.backend.js.map +1 -1
  49. package/dist/esm/base-classes/services/repositories/http-api/http-api-row-projection.backend.d.ts.map +1 -1
  50. package/dist/esm/base-classes/services/repositories/http-api/http-api-subject-erasure-effect.backend.d.ts.map +1 -1
  51. package/dist/esm/base-classes/services/repositories/http-api/http-api-transport.backend.d.ts.map +1 -1
  52. package/dist/esm/base-classes/services/repositories/http-api/http-api-transport.backend.js.map +1 -1
  53. package/dist/esm/base-classes/services/repositories/http-api/odata-query-compiler.backend.d.ts.map +1 -1
  54. package/dist/esm/base-classes/services/repositories/http-api/odoo-jsonrpc-compiler.backend.d.ts.map +1 -1
  55. package/dist/esm/base-classes/services/repositories/http-api/rest-json-query-compiler.backend.d.ts.map +1 -1
  56. package/dist/esm/base-classes/services/repositories/infrastructure-tier-contract.backend.d.ts.map +1 -1
  57. package/dist/esm/base-classes/services/repositories/infrastructure-tier-contract.backend.js.map +1 -1
  58. package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-repository.backend.service.d.ts.map +1 -1
  59. package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-source.backend.port.d.ts.map +1 -1
  60. package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.d.ts +57 -0
  61. package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.d.ts.map +1 -1
  62. package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.js +95 -2
  63. package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.js.map +1 -1
  64. package/dist/esm/base-classes/services/repositories/repositories-registry-handler.backend.service.d.ts.map +1 -1
  65. package/dist/esm/base-classes/services/repositories/repositories-registry-handler.backend.service.js.map +1 -1
  66. package/dist/esm/base-classes/services/repositories/repository-guarded-mutation.backend.types.d.ts.map +1 -1
  67. package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.d.ts +5 -2
  68. package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.d.ts.map +1 -1
  69. package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.js +14 -3
  70. package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.js.map +1 -1
  71. package/dist/esm/base-classes/services/repositories/repository-version-metadata.backend.utils.d.ts.map +1 -1
  72. package/dist/esm/base-classes/services/repositories/resource-write-integrity.backend.d.ts.map +1 -1
  73. package/dist/esm/base-classes/services/repositories/seed-row-default-materialization.backend.d.ts +72 -0
  74. package/dist/esm/base-classes/services/repositories/seed-row-default-materialization.backend.d.ts.map +1 -0
  75. package/dist/esm/base-classes/services/repositories/seed-row-default-materialization.backend.js +88 -0
  76. package/dist/esm/base-classes/services/repositories/seed-row-default-materialization.backend.js.map +1 -0
  77. package/dist/esm/base-classes/services/repositories/unique-constraint-conflict-reference.backend.d.ts.map +1 -1
  78. package/dist/esm/base-classes/services/resource-operations-helper.backend.service.d.ts.map +1 -1
  79. package/dist/esm/base-classes/services/services/__tests__/mock-services-registry-handler.service.d.ts.map +1 -1
  80. package/dist/esm/base-classes/services/services/__tests__/mock-system-access.service.d.ts.map +1 -1
  81. package/dist/esm/base-classes/services/services/read-only-field-change.backend.utils.d.ts.map +1 -1
  82. package/dist/esm/base-classes/services/services/resource-operation-audit-emission.backend.utils.d.ts.map +1 -1
  83. package/dist/esm/base-classes/services/services/resource-operation-custom-implementation-base.backend.service.d.ts.map +1 -1
  84. package/dist/esm/base-classes/services/services/resource-operation-custom-implementation-base.backend.service.js.map +1 -1
  85. package/dist/esm/base-classes/services/services/resource-operation-custom-implementation-registry.backend.service.d.ts.map +1 -1
  86. package/dist/esm/base-classes/services/services/resource-operation-custom-implementation.factory.backend.d.ts.map +1 -1
  87. package/dist/esm/base-classes/services/services/resource-operation-implementation-coverage.backend.utils.d.ts.map +1 -1
  88. package/dist/esm/base-classes/services/services/resource-operation-server-injected-fields.backend.utils.d.ts.map +1 -1
  89. package/dist/esm/base-classes/services/services/resource-operation-transaction-persistence.backend.utils.d.ts.map +1 -1
  90. package/dist/esm/base-classes/services/services/resource-status-transition.custom-impl.backend.service.d.ts.map +1 -1
  91. package/dist/esm/base-classes/services/services/resource-status-transition.custom-impl.backend.service.js.map +1 -1
  92. package/dist/esm/base-classes/services/services/resource-status-transition.definitions.backend.d.ts.map +1 -1
  93. package/dist/esm/base-classes/services/services/resource-status-transition.definitions.backend.js.map +1 -1
  94. package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.d.ts.map +1 -1
  95. package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.js +44 -6
  96. package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.js.map +1 -1
  97. package/dist/esm/base-classes/services/services/system-access.backend.service.d.ts.map +1 -1
  98. package/dist/esm/base-classes/services/services/system-access.backend.service.js.map +1 -1
  99. package/dist/esm/base-classes/utils/backend-type-utils.d.ts.map +1 -1
  100. package/dist/esm/base-classes/utils/single-subject-addressing.backend.utils.d.ts.map +1 -1
  101. package/dist/esm/billing/batches/billing-reconciliation.batch.backend.service.d.ts.map +1 -1
  102. package/dist/esm/billing/batches/billing-reconciliation.batch.backend.service.js.map +1 -1
  103. package/dist/esm/billing/batches/usage-flush.batch.backend.service.d.ts.map +1 -1
  104. package/dist/esm/billing/batches/usage-flush.batch.backend.service.js.map +1 -1
  105. package/dist/esm/billing/models/billing-provider-event-settlement.backend.schemas.d.ts.map +1 -1
  106. package/dist/esm/billing/models/billing-provider-event-settlement.backend.schemas.js.map +1 -1
  107. package/dist/esm/billing/services/back-office/abstract-billing.backend.service.d.ts.map +1 -1
  108. package/dist/esm/billing/services/back-office/billing-feature-sync.backend.service.d.ts.map +1 -1
  109. package/dist/esm/billing/services/back-office/billing-reconciliation.backend.service.d.ts +1 -1
  110. package/dist/esm/billing/services/back-office/billing-reconciliation.backend.service.d.ts.map +1 -1
  111. package/dist/esm/billing/services/back-office/billing-reconciliation.backend.service.js +5 -4
  112. package/dist/esm/billing/services/back-office/billing-reconciliation.backend.service.js.map +1 -1
  113. package/dist/esm/billing/services/back-office/billing-state.backend.service.d.ts.map +1 -1
  114. package/dist/esm/billing/services/back-office/billing-state.backend.service.js +11 -1
  115. package/dist/esm/billing/services/back-office/billing-state.backend.service.js.map +1 -1
  116. package/dist/esm/billing/services/back-office/billing-subject-erasure-effect.backend.d.ts.map +1 -1
  117. package/dist/esm/billing/services/back-office/product-catalog-sync.backend.service.d.ts.map +1 -1
  118. package/dist/esm/billing/services/back-office/product-catalog-sync.backend.service.js.map +1 -1
  119. package/dist/esm/billing/services/back-office/usage-metering.backend.service.d.ts.map +1 -1
  120. package/dist/esm/billing/services/back-office/usage-metering.backend.service.js.map +1 -1
  121. package/dist/esm/billing/services/billing-adapter-registry.backend.d.ts.map +1 -1
  122. package/dist/esm/billing/services/billing-adapter-registry.backend.js.map +1 -1
  123. package/dist/esm/billing/services/billing-checkout-metadata.backend.utils.d.ts.map +1 -1
  124. package/dist/esm/billing/services/billing-checkout-metadata.backend.utils.js.map +1 -1
  125. package/dist/esm/billing/services/billing.utils.d.ts.map +1 -1
  126. package/dist/esm/billing/services/custom-impl/billing-account.mutations.custom-impl.backend.service.d.ts.map +1 -1
  127. package/dist/esm/billing/services/custom-impl/billing-account.mutations.custom-impl.backend.service.js.map +1 -1
  128. package/dist/esm/billing/services/custom-impl/billing-custom-impl-utils.backend.d.ts +32 -0
  129. package/dist/esm/billing/services/custom-impl/billing-custom-impl-utils.backend.d.ts.map +1 -1
  130. package/dist/esm/billing/services/custom-impl/billing-custom-impl-utils.backend.js +32 -1
  131. package/dist/esm/billing/services/custom-impl/billing-custom-impl-utils.backend.js.map +1 -1
  132. package/dist/esm/billing/services/custom-impl/billing-custom-implementations.backend.d.ts.map +1 -1
  133. package/dist/esm/billing/services/custom-impl/billing-custom-implementations.backend.js.map +1 -1
  134. package/dist/esm/billing/services/custom-impl/credit-pool.custom-ops.custom-impl.backend.service.d.ts.map +1 -1
  135. package/dist/esm/billing/services/custom-impl/promotion.custom-ops.custom-impl.backend.service.d.ts.map +1 -1
  136. package/dist/esm/billing/services/custom-impl/promotion.custom-ops.custom-impl.backend.service.js.map +1 -1
  137. package/dist/esm/billing/services/custom-impl/subscription.mutations.custom-impl.backend.service.d.ts.map +1 -1
  138. package/dist/esm/billing/services/custom-impl/subscription.mutations.custom-impl.backend.service.js.map +1 -1
  139. package/dist/esm/billing/services/stripe-standard-billing-provider.backend.service.d.ts +9 -6
  140. package/dist/esm/billing/services/stripe-standard-billing-provider.backend.service.d.ts.map +1 -1
  141. package/dist/esm/billing/services/stripe-standard-billing-provider.backend.service.js +9 -6
  142. package/dist/esm/billing/services/stripe-standard-billing-provider.backend.service.js.map +1 -1
  143. package/dist/esm/billing/services/webhooks/__tests__/settlement-ledger.test-double.d.ts.map +1 -1
  144. package/dist/esm/billing/services/webhooks/__tests__/settlement-ledger.test-double.js.map +1 -1
  145. package/dist/esm/billing/services/webhooks/billing-webhook-adapter.backend.service.d.ts.map +1 -1
  146. package/dist/esm/billing/services/webhooks/billing-webhook-capability-handler.backend.service.d.ts.map +1 -1
  147. package/dist/esm/billing/services/webhooks/billing-webhook-event-router.backend.service.d.ts.map +1 -1
  148. package/dist/esm/billing/services/webhooks/billing-webhook-event-router.backend.service.js +50 -3
  149. package/dist/esm/billing/services/webhooks/billing-webhook-event-router.backend.service.js.map +1 -1
  150. package/dist/esm/billing/testing/billing-test-fixtures.d.ts.map +1 -1
  151. package/dist/esm/billing/testing/mock-billing-provider.d.ts.map +1 -1
  152. package/dist/esm/billing/testing/mock-billing-provider.js.map +1 -1
  153. package/dist/esm/charts/controllers/chart.backend.controller.d.ts.map +1 -1
  154. package/dist/esm/charts/services/chart-registry.backend.service.d.ts +80 -7
  155. package/dist/esm/charts/services/chart-registry.backend.service.d.ts.map +1 -1
  156. package/dist/esm/charts/services/chart-registry.backend.service.js +115 -8
  157. package/dist/esm/charts/services/chart-registry.backend.service.js.map +1 -1
  158. package/dist/esm/companion-exports.d.ts.map +1 -1
  159. package/dist/esm/compliance/audit-trails/audit-logs.custom-impl.backend.service.d.ts.map +1 -1
  160. package/dist/esm/compliance/audit-trails/batches/audit-logs-archive.batch.backend.service.d.ts.map +1 -1
  161. package/dist/esm/compliance/audit-trails/batches/audit-logs-archive.batch.backend.service.js.map +1 -1
  162. package/dist/esm/compliance/audit-trails/batches/immudb-audit-reconcile.batch.backend.service.d.ts.map +1 -1
  163. package/dist/esm/compliance/audit-trails/batches/siem-webhook-delivery.batch.backend.service.d.ts.map +1 -1
  164. package/dist/esm/compliance/audit-trails/services/__tests__/mock-audit-logs.service.d.ts.map +1 -1
  165. package/dist/esm/compliance/audit-trails/services/audit-event-dispatcher.backend.service.d.ts.map +1 -1
  166. package/dist/esm/compliance/audit-trails/services/audit-event-dispatcher.backend.service.js.map +1 -1
  167. package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.d.ts +107 -4
  168. package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.d.ts.map +1 -1
  169. package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.js +176 -5
  170. package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.js.map +1 -1
  171. package/dist/esm/compliance/audit-trails/services/composite-audit-log-sink.backend.d.ts.map +1 -1
  172. package/dist/esm/compliance/audit-trails/services/composite-audit-log-sink.backend.js.map +1 -1
  173. package/dist/esm/compliance/audit-trails/services/siem-export-config-cache-invalidation.custom-impl.backend.service.d.ts.map +1 -1
  174. package/dist/esm/compliance/audit-trails/services/siem-export-config-cache-invalidation.custom-impl.backend.service.js.map +1 -1
  175. package/dist/esm/compliance/audit-trails/services/siem-webhook-delivery.backend.service.d.ts.map +1 -1
  176. package/dist/esm/compliance/audit-trails/services/siem-webhook-delivery.backend.service.js.map +1 -1
  177. package/dist/esm/compliance/audit-trails/services/utils/leased-value-cache.backend.utils.d.ts.map +1 -1
  178. package/dist/esm/compliance/audit-trails/services/utils/leased-value-cache.backend.utils.js.map +1 -1
  179. package/dist/esm/compliance/audit-trails/services/utils/ocsf-activity-mapping.backend.utils.d.ts.map +1 -1
  180. package/dist/esm/compliance/audit-trails/services/utils/ocsf-activity-mapping.backend.utils.js +21 -0
  181. package/dist/esm/compliance/audit-trails/services/utils/ocsf-activity-mapping.backend.utils.js.map +1 -1
  182. package/dist/esm/compliance/audit-trails/services/utils/ocsf-class-mapping.backend.utils.d.ts.map +1 -1
  183. package/dist/esm/compliance/audit-trails/services/utils/siem-dictionary.backend.utils.d.ts.map +1 -1
  184. package/dist/esm/compliance/audit-trails/services/utils/siem-ocsf-projection.backend.utils.d.ts.map +1 -1
  185. package/dist/esm/compliance/audit-trails/services/utils/siem-projection-contract.backend.utils.d.ts.map +1 -1
  186. package/dist/esm/compliance/audit-trails/utils/audit-actor.backend.utils.d.ts.map +1 -1
  187. package/dist/esm/compliance/audit-trails/utils/layer2-audit-provider-boot-diagnostic.backend.utils.d.ts.map +1 -1
  188. package/dist/esm/compliance/index.d.ts.map +1 -1
  189. package/dist/esm/compliance/privacy/retention-hide-predicate.backend.d.ts.map +1 -1
  190. package/dist/esm/compliance/privacy/services/subject-erasure-external-effects.backend.service.d.ts.map +1 -1
  191. package/dist/esm/compliance/privacy/services/subject-session-revocation.backend.service.d.ts.map +1 -1
  192. package/dist/esm/config/bootstrap/application-runtime-profile.backend.d.ts.map +1 -1
  193. package/dist/esm/config/bootstrap/application-runtime-profile.backend.js.map +1 -1
  194. package/dist/esm/config/bootstrap/minion-initialization-projection.backend.d.ts.map +1 -1
  195. package/dist/esm/config/bootstrap/runtime-principal-attestation.backend.service.d.ts.map +1 -1
  196. package/dist/esm/config/bootstrap/runtime-principal-attestation.backend.service.js +3 -0
  197. package/dist/esm/config/bootstrap/runtime-principal-attestation.backend.service.js.map +1 -1
  198. package/dist/esm/config/bootstrap/runtime-principal.backend.service.d.ts.map +1 -1
  199. package/dist/esm/config/custom/application-config-controller.backend.service.d.ts.map +1 -1
  200. package/dist/esm/config/models/app-config-secrets.backend.schemas.d.ts.map +1 -1
  201. package/dist/esm/config/models/app-config.backend-authored.definitions.d.ts.map +1 -1
  202. package/dist/esm/config/models/app-config.backend.schemas.d.ts +4 -4
  203. package/dist/esm/config/models/app-config.backend.schemas.d.ts.map +1 -1
  204. package/dist/esm/config/models/app-config.backend.schemas.js.map +1 -1
  205. package/dist/esm/config/models/app-env-config.backend.schemas.d.ts.map +1 -1
  206. package/dist/esm/config/models/apps-manager-transport.backend.definitions.d.ts +36 -0
  207. package/dist/esm/config/models/apps-manager-transport.backend.definitions.d.ts.map +1 -0
  208. package/dist/esm/config/models/apps-manager-transport.backend.definitions.js +36 -0
  209. package/dist/esm/config/models/apps-manager-transport.backend.definitions.js.map +1 -0
  210. package/dist/esm/config/models/config-mutation-boundary.utils.d.ts.map +1 -1
  211. package/dist/esm/config/models/postgresql-env-config.backend.schemas.d.ts.map +1 -1
  212. package/dist/esm/config/models/provider-runtime-artifact.backend.schemas.d.ts.map +1 -1
  213. package/dist/esm/config/models/provider-runtime-artifact.backend.schemas.js.map +1 -1
  214. package/dist/esm/config/models/runtime-topology.backend.contracts.d.ts.map +1 -1
  215. package/dist/esm/config/services/__tests__/mock-app-configuration.service.d.ts.map +1 -1
  216. package/dist/esm/config/services/app-configuration-loader.backend.service.d.ts.map +1 -1
  217. package/dist/esm/config/services/app-configuration-loader.backend.service.js +3 -0
  218. package/dist/esm/config/services/app-configuration-loader.backend.service.js.map +1 -1
  219. package/dist/esm/config/services/app-configuration.backend.service.d.ts.map +1 -1
  220. package/dist/esm/config/services/app-configuration.backend.service.js.map +1 -1
  221. package/dist/esm/config/services/app-configuration.backend.utils.d.ts.map +1 -1
  222. package/dist/esm/config/services/app-configuration.backend.utils.js.map +1 -1
  223. package/dist/esm/config/services/application-startup-config-validator.backend.service.d.ts +12 -0
  224. package/dist/esm/config/services/application-startup-config-validator.backend.service.d.ts.map +1 -1
  225. package/dist/esm/config/services/application-startup-config-validator.backend.service.js +28 -0
  226. package/dist/esm/config/services/application-startup-config-validator.backend.service.js.map +1 -1
  227. package/dist/esm/data-seeding/batches/data-seeding-run-cleanup.batch.backend.service.d.ts.map +1 -1
  228. package/dist/esm/data-seeding/batches/data-seeding-scheduled-rerun.batch.backend.service.d.ts.map +1 -1
  229. package/dist/esm/data-seeding/controllers/data-seeding-admin.backend.contracts.d.ts.map +1 -1
  230. package/dist/esm/data-seeding/controllers/data-seeding-admin.backend.controller.d.ts.map +1 -1
  231. package/dist/esm/data-seeding/data-seeding-models.d.ts.map +1 -1
  232. package/dist/esm/data-seeding/models/business-key-resolver.shared.utils.d.ts.map +1 -1
  233. package/dist/esm/data-seeding/models/data-seed-execution-context.shared.types.d.ts.map +1 -1
  234. package/dist/esm/data-seeding/models/data-seed-migrator-runner.shared.utils.d.ts.map +1 -1
  235. package/dist/esm/data-seeding/models/data-seed-reconciler.shared.utils.d.ts.map +1 -1
  236. package/dist/esm/data-seeding/models/data-seed-row-metadata.shared.schemas.d.ts.map +1 -1
  237. package/dist/esm/data-seeding/models/data-seed-row-metadata.shared.utils.d.ts.map +1 -1
  238. package/dist/esm/data-seeding/models/data-seed-run.shared.resources-config.schemas.d.ts.map +1 -1
  239. package/dist/esm/data-seeding/models/data-seed-run.shared.schemas.d.ts.map +1 -1
  240. package/dist/esm/data-seeding/models/data-seed-trigger-mode-matrix.shared.utils.d.ts.map +1 -1
  241. package/dist/esm/data-seeding/models/data-seed.shared.schemas.d.ts.map +1 -1
  242. package/dist/esm/data-seeding/services/data-seed-application-bootstrap.backend.d.ts.map +1 -1
  243. package/dist/esm/data-seeding/services/data-seed-dispatcher.backend.service.d.ts.map +1 -1
  244. package/dist/esm/data-seeding/services/data-seed-registry.backend.service.d.ts.map +1 -1
  245. package/dist/esm/data-seeding/services/data-seed-scope-resolver-registry.backend.service.d.ts.map +1 -1
  246. package/dist/esm/data-seeding/services/engines/additive-seed-engine.backend.service.d.ts.map +1 -1
  247. package/dist/esm/data-seeding/services/engines/lazy-seed-engine.backend.service.d.ts.map +1 -1
  248. package/dist/esm/data-seeding/services/engines/manual-seed-engine.backend.service.d.ts.map +1 -1
  249. package/dist/esm/data-seeding/services/engines/sync-seed-engine.backend.service.d.ts.map +1 -1
  250. package/dist/esm/data-seeding/services/engines/upgrade-seed-engine.backend.service.d.ts.map +1 -1
  251. package/dist/esm/data-seeding/services/shared/data-seed-business-key.shared.utils.d.ts.map +1 -1
  252. package/dist/esm/data-seeding/services/shared/data-seed-error.shared.utils.d.ts.map +1 -1
  253. package/dist/esm/data-seeding/services/shared/data-seed-run-counters.shared.types.d.ts.map +1 -1
  254. package/dist/esm/data-seeding/services/shared/data-seed-run-ledger.backend.d.ts.map +1 -1
  255. package/dist/esm/data-seeding/services/shared/data-seed-scope-anchor.shared.types.d.ts.map +1 -1
  256. package/dist/esm/data-seeding/services/shared/data-seed-scope-iteration.shared.utils.d.ts.map +1 -1
  257. package/dist/esm/data-seeding/services/shared/data-seed-scope-resolution.backend.d.ts.map +1 -1
  258. package/dist/esm/databases/models/aggregation.backend.schemas.d.ts.map +1 -1
  259. package/dist/esm/databases/models/databases.backend.schemas.d.ts.map +1 -1
  260. package/dist/esm/databases/models/filter.backend.schemas.d.ts.map +1 -1
  261. package/dist/esm/databases/models/resolve-persistence-adapter.backend.utils.d.ts.map +1 -1
  262. package/dist/esm/databases/models/sql.backend.schemas.d.ts.map +1 -1
  263. package/dist/esm/databases/models/transaction.shared.schemas.d.ts.map +1 -1
  264. package/dist/esm/databases/services/__tests__/mock-mongo-transaction-registry.service.d.ts.map +1 -1
  265. package/dist/esm/databases/services/__tests__/mock-mongodb.service.d.ts.map +1 -1
  266. package/dist/esm/databases/services/__tests__/mock-mongoose-model.service.d.ts.map +1 -1
  267. package/dist/esm/databases/services/__tests__/mock-redis.service.d.ts.map +1 -1
  268. package/dist/esm/databases/services/__tests__/mock-zod-mongoose-schema-convertor.service.d.ts.map +1 -1
  269. package/dist/esm/databases/services/aggregation/aggregation-authorization.backend.service.d.ts.map +1 -1
  270. package/dist/esm/databases/services/aggregation/aggregation-query.backend.service.d.ts.map +1 -1
  271. package/dist/esm/databases/services/aggregation/computed-measure-evaluator.backend.service.d.ts.map +1 -1
  272. package/dist/esm/databases/services/aggregation/field-access-validator.backend.service.d.ts.map +1 -1
  273. package/dist/esm/databases/services/aggregation/time-series-densifier.backend.service.d.ts.map +1 -1
  274. package/dist/esm/databases/services/aggregation/topn-processor.backend.service.d.ts.map +1 -1
  275. package/dist/esm/databases/services/aggregation/window-function-processor.backend.service.d.ts.map +1 -1
  276. package/dist/esm/databases/services/db-utils.d.ts.map +1 -1
  277. package/dist/esm/databases/services/mongo-aggregation.backend.service.d.ts.map +1 -1
  278. package/dist/esm/databases/services/mongodb.service.d.ts.map +1 -1
  279. package/dist/esm/databases/services/postgresql-aggregation.backend.service.d.ts.map +1 -1
  280. package/dist/esm/databases/services/postgresql-database.backend.service.d.ts.map +1 -1
  281. package/dist/esm/databases/services/postgresql-development-provisioning.backend.d.ts.map +1 -1
  282. package/dist/esm/databases/services/postgresql-filter.backend.service.d.ts.map +1 -1
  283. package/dist/esm/databases/services/postgresql-migration-runner.backend.d.ts.map +1 -1
  284. package/dist/esm/databases/services/postgresql-schema-ddl.backend.d.ts.map +1 -1
  285. package/dist/esm/databases/services/postgresql-schema-migration-sql.backend.d.ts.map +1 -1
  286. package/dist/esm/databases/services/postgresql-schema-plan-diff.backend.d.ts.map +1 -1
  287. package/dist/esm/databases/services/postgresql-schema-plan-diff.backend.js.map +1 -1
  288. package/dist/esm/databases/services/postgresql-schema-plan-lockfile.backend.d.ts.map +1 -1
  289. package/dist/esm/databases/services/redis.service.d.ts.map +1 -1
  290. package/dist/esm/databases/services/resource-persistence-unit-of-work.backend.service.d.ts.map +1 -1
  291. package/dist/esm/databases/services/schema-planning-standalone.backend.d.ts.map +1 -1
  292. package/dist/esm/databases/services/zod-to-mongoose-schema-convertor.backend.service.d.ts.map +1 -1
  293. package/dist/esm/databases/services/zod-to-sql-hybrid-schema.planner.d.ts.map +1 -1
  294. package/dist/esm/databases/utils/postgresql-identifier.backend.utils.d.ts.map +1 -1
  295. package/dist/esm/errors/services/__tests__/mock-error-builder.service.d.ts.map +1 -1
  296. package/dist/esm/errors/services/error-builder.backend.service.d.ts.map +1 -1
  297. package/dist/esm/errors/services/error-builder.backend.service.js.map +1 -1
  298. package/dist/esm/errors/services/error-handler.backend.service.d.ts.map +1 -1
  299. package/dist/esm/errors/services/error-handler.backend.service.js.map +1 -1
  300. package/dist/esm/errors/services/rate-limit.backend.service.d.ts.map +1 -1
  301. package/dist/esm/errors/services/rate-limit.backend.service.js.map +1 -1
  302. package/dist/esm/errors/utils/error-log-level-classification.backend.utils.d.ts.map +1 -1
  303. package/dist/esm/errors/utils/error-log-level-classification.backend.utils.js.map +1 -1
  304. package/dist/esm/errors/utils/rate-limit-environment-relaxation.backend.utils.d.ts.map +1 -1
  305. package/dist/esm/errors/utils/rate-limit-environment-relaxation.backend.utils.js.map +1 -1
  306. package/dist/esm/external-data/batches/external-data-pipeline-scheduled-run.batch.backend.service.d.ts.map +1 -1
  307. package/dist/esm/external-data/controllers/external-data-admin.backend.contracts.d.ts.map +1 -1
  308. package/dist/esm/external-data/controllers/external-data-admin.backend.controller.d.ts.map +1 -1
  309. package/dist/esm/external-data/external-data-extraction-source.backend.d.ts.map +1 -1
  310. package/dist/esm/external-data/external-data-models.exports.d.ts.map +1 -1
  311. package/dist/esm/external-data/external-data-pipeline-run.backend.service.d.ts.map +1 -1
  312. package/dist/esm/external-data/external-data-pipeline-run.backend.service.js.map +1 -1
  313. package/dist/esm/external-data/external-data-transform.backend.d.ts.map +1 -1
  314. package/dist/esm/external-data/models/external-data-pipeline-state.backend.schemas.d.ts.map +1 -1
  315. package/dist/esm/external-providers/models/external-providers.backend.schemas.d.ts.map +1 -1
  316. package/dist/esm/external-providers/models/provider-selection-resolution-evidence.backend.definitions.d.ts.map +1 -1
  317. package/dist/esm/external-providers/models/provider-selection-resolution-evidence.backend.definitions.js.map +1 -1
  318. package/dist/esm/external-providers/operations/provider-operation-executor.backend.service.d.ts +102 -52
  319. package/dist/esm/external-providers/operations/provider-operation-executor.backend.service.d.ts.map +1 -1
  320. package/dist/esm/external-providers/operations/provider-operation-executor.backend.service.js +117 -71
  321. package/dist/esm/external-providers/operations/provider-operation-executor.backend.service.js.map +1 -1
  322. package/dist/esm/external-providers/operations/provider-operation-request.backend.d.ts.map +1 -1
  323. package/dist/esm/external-providers/operations/provider-operation-request.backend.js.map +1 -1
  324. package/dist/esm/external-providers/operations/provider-request-signing.backend.d.ts.map +1 -1
  325. package/dist/esm/external-providers/operations/provider-request-signing.backend.js +26 -7
  326. package/dist/esm/external-providers/operations/provider-request-signing.backend.js.map +1 -1
  327. package/dist/esm/external-providers/operations/provider-rest-call-client.backend.d.ts.map +1 -1
  328. package/dist/esm/external-providers/operations/provider-rest-call-client.backend.js.map +1 -1
  329. package/dist/esm/external-providers/services/__tests__/mock-external-providers-registry.service.d.ts.map +1 -1
  330. package/dist/esm/external-providers/services/__tests__/mock-external-providers-registry.service.js.map +1 -1
  331. package/dist/esm/external-providers/services/backend-provider-loader.backend.service.d.ts.map +1 -1
  332. package/dist/esm/external-providers/services/backend-provider-loader.backend.service.js.map +1 -1
  333. package/dist/esm/external-providers/services/backend-provider-registry.backend.service.d.ts.map +1 -1
  334. package/dist/esm/external-providers/services/backend-provider-registry.backend.service.js.map +1 -1
  335. package/dist/esm/external-providers/services/document-extraction.backend.service.d.ts +81 -34
  336. package/dist/esm/external-providers/services/document-extraction.backend.service.d.ts.map +1 -1
  337. package/dist/esm/external-providers/services/document-extraction.backend.service.js +179 -98
  338. package/dist/esm/external-providers/services/document-extraction.backend.service.js.map +1 -1
  339. package/dist/esm/external-providers/services/embeddings.backend.service.d.ts.map +1 -1
  340. package/dist/esm/external-providers/services/embeddings.backend.service.js.map +1 -1
  341. package/dist/esm/external-providers/services/external-api-handler.backend.service.d.ts.map +1 -1
  342. package/dist/esm/external-providers/services/external-providers-registry.backend.service.d.ts +121 -0
  343. package/dist/esm/external-providers/services/external-providers-registry.backend.service.d.ts.map +1 -1
  344. package/dist/esm/external-providers/services/external-providers-registry.backend.service.js +151 -0
  345. package/dist/esm/external-providers/services/external-providers-registry.backend.service.js.map +1 -1
  346. package/dist/esm/external-providers/services/frontend-bootstrap.backend.service.d.ts +15 -1
  347. package/dist/esm/external-providers/services/frontend-bootstrap.backend.service.d.ts.map +1 -1
  348. package/dist/esm/external-providers/services/frontend-bootstrap.backend.service.js +60 -4
  349. package/dist/esm/external-providers/services/frontend-bootstrap.backend.service.js.map +1 -1
  350. package/dist/esm/features/controllers/features.backend.controller.d.ts.map +1 -1
  351. package/dist/esm/features/services/__tests__/mock-feature-definition-registry.service.d.ts.map +1 -1
  352. package/dist/esm/features/services/__tests__/mock-feature-resolution.service.d.ts.map +1 -1
  353. package/dist/esm/features/services/application-features-admin-write-path.custom-impl.backend.service.d.ts.map +1 -1
  354. package/dist/esm/features/services/feature-definition-registry.backend.service.d.ts.map +1 -1
  355. package/dist/esm/features/services/feature-gate.backend.service.d.ts.map +1 -1
  356. package/dist/esm/features/services/feature-resolution.backend.service.d.ts.map +1 -1
  357. package/dist/esm/features/services/organization-features-admin-write-path.custom-impl.backend.service.d.ts.map +1 -1
  358. package/dist/esm/features/services/scope-feature-ledger-relationship.backend.utils.d.ts.map +1 -1
  359. package/dist/esm/features/services/scope-features-cache-invalidation.custom-impl.backend.service.d.ts.map +1 -1
  360. package/dist/esm/features/testing/feature-test-utils.d.ts.map +1 -1
  361. package/dist/esm/files/batches/files-cleanup.batch.backend.service.d.ts.map +1 -1
  362. package/dist/esm/files/constraints/file-analyzers.types.d.ts.map +1 -1
  363. package/dist/esm/files/constraints/file-constraint-resolver-chain.backend.service.d.ts.map +1 -1
  364. package/dist/esm/files/constraints/file-constraint.types.d.ts.map +1 -1
  365. package/dist/esm/files/constraints/file-validation.backend.service.d.ts.map +1 -1
  366. package/dist/esm/files/constraints/resource-field-constraint-resolver.backend.service.d.ts.map +1 -1
  367. package/dist/esm/files/controllers/file.controller.d.ts.map +1 -1
  368. package/dist/esm/files/controllers/file.controller.js.map +1 -1
  369. package/dist/esm/files/handlers/file-upload-route-locals.backend.types.d.ts.map +1 -1
  370. package/dist/esm/files/handlers/file-upload-route-locals.backend.types.js.map +1 -1
  371. package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.d.ts +37 -0
  372. package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.d.ts.map +1 -1
  373. package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.js +221 -21
  374. package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.js.map +1 -1
  375. package/dist/esm/files/scanning/clamav-scanner.backend.service.d.ts.map +1 -1
  376. package/dist/esm/files/scanning/file-scan.types.d.ts.map +1 -1
  377. package/dist/esm/files/scanning/yara-scanner.backend.service.d.ts.map +1 -1
  378. package/dist/esm/files/scanning/yara-scanner.backend.service.js +20 -2
  379. package/dist/esm/files/scanning/yara-scanner.backend.service.js.map +1 -1
  380. package/dist/esm/files/services/__tests__/mock-file-field-detection.service.d.ts.map +1 -1
  381. package/dist/esm/files/services/__tests__/mock-file-operation-handler.service.d.ts.map +1 -1
  382. package/dist/esm/files/services/__tests__/mock-file-repository.service.d.ts.map +1 -1
  383. package/dist/esm/files/services/file-field-detection.backend.service.d.ts.map +1 -1
  384. package/dist/esm/files/services/file-operation-handler.backend.service.d.ts.map +1 -1
  385. package/dist/esm/files/services/file-operation-handler.backend.service.js.map +1 -1
  386. package/dist/esm/files/services/file-population.backend.service.d.ts.map +1 -1
  387. package/dist/esm/files/services/file-scanning.backend.service.d.ts.map +1 -1
  388. package/dist/esm/files/services/file-scanning.backend.service.js +5 -0
  389. package/dist/esm/files/services/file-scanning.backend.service.js.map +1 -1
  390. package/dist/esm/files/services/file-text-extraction.backend.service.d.ts.map +1 -1
  391. package/dist/esm/files/services/file-text-extraction.backend.service.js +8 -5
  392. package/dist/esm/files/services/file-text-extraction.backend.service.js.map +1 -1
  393. package/dist/esm/files/services/file-upload-grant.backend.service.d.ts.map +1 -1
  394. package/dist/esm/files/services/file-upload-grant.backend.service.js.map +1 -1
  395. package/dist/esm/files/services/files.backend.service.d.ts.map +1 -1
  396. package/dist/esm/files/services/files.backend.service.js +3 -1
  397. package/dist/esm/files/services/files.backend.service.js.map +1 -1
  398. package/dist/esm/files/services/rag-source-field-detection.backend.service.d.ts.map +1 -1
  399. package/dist/esm/files/storage/application-storage-key.backend.utils.d.ts.map +1 -1
  400. package/dist/esm/files/storage/application-storage-key.backend.utils.js.map +1 -1
  401. package/dist/esm/files/storage/file-storage-path-resolver.backend.service.d.ts.map +1 -1
  402. package/dist/esm/files/storage/file-storage-provider.types.d.ts +36 -1
  403. package/dist/esm/files/storage/file-storage-provider.types.d.ts.map +1 -1
  404. package/dist/esm/files/storage/file-storage-provider.types.js.map +1 -1
  405. package/dist/esm/files/storage/file-storage-router.backend.service.d.ts +21 -3
  406. package/dist/esm/files/storage/file-storage-router.backend.service.d.ts.map +1 -1
  407. package/dist/esm/files/storage/file-storage-router.backend.service.js +38 -5
  408. package/dist/esm/files/storage/file-storage-router.backend.service.js.map +1 -1
  409. package/dist/esm/files/storage/google-drive-storage-provider.backend.service.d.ts +87 -0
  410. package/dist/esm/files/storage/google-drive-storage-provider.backend.service.d.ts.map +1 -0
  411. package/dist/esm/files/storage/google-drive-storage-provider.backend.service.js +340 -0
  412. package/dist/esm/files/storage/google-drive-storage-provider.backend.service.js.map +1 -0
  413. package/dist/esm/files/storage/local-directory-storage-provider.backend.service.d.ts.map +1 -1
  414. package/dist/esm/files/storage/local-directory-storage-provider.backend.service.js.map +1 -1
  415. package/dist/esm/files/storage/storage-credential-provider.backend.utils.d.ts.map +1 -1
  416. package/dist/esm/files/storage/storage-platform-sts-credential-resolver.backend.utils.d.ts.map +1 -1
  417. package/dist/esm/files/storage/storage-sts-credential-resolver.backend.utils.d.ts.map +1 -1
  418. package/dist/esm/files/storage/storage-sts-credential-resolver.backend.utils.js +10 -3
  419. package/dist/esm/files/storage/storage-sts-credential-resolver.backend.utils.js.map +1 -1
  420. package/dist/esm/files/storage/wildo-managed-storage-provider.backend.service.d.ts.map +1 -1
  421. package/dist/esm/files/storage/wildo-managed-storage-provider.backend.service.js.map +1 -1
  422. package/dist/esm/files/utils/file-field-schema-path.backend.utils.d.ts.map +1 -1
  423. package/dist/esm/files/utils/file-field-schema-path.backend.utils.js.map +1 -1
  424. package/dist/esm/files/utils/file-upload.utils.d.ts.map +1 -1
  425. package/dist/esm/files/utils/file-uploader.utils.d.ts.map +1 -1
  426. package/dist/esm/files/utils/file-uploader.utils.js.map +1 -1
  427. package/dist/esm/files/utils/file-validation.utils.d.ts.map +1 -1
  428. package/dist/esm/files/utils/image-derivation.backend.utils.d.ts.map +1 -1
  429. package/dist/esm/files/utils/image-thumbnail.backend.utils.d.ts.map +1 -1
  430. package/dist/esm/files/utils/office-document-text-extraction.backend.utils.d.ts.map +1 -1
  431. package/dist/esm/files/utils/office-document-text-extraction.backend.utils.js.map +1 -1
  432. package/dist/esm/files/utils/rag-source-field-schema-path.backend.utils.d.ts.map +1 -1
  433. package/dist/esm/files/utils/storage-application-identity.backend.utils.d.ts.map +1 -1
  434. package/dist/esm/flows-actors/a2a/batches/a2a-abandoned-task-sweep.batch.backend.service.d.ts.map +1 -1
  435. package/dist/esm/flows-actors/a2a/batches/a2a-abandoned-task-sweep.batch.backend.service.js.map +1 -1
  436. package/dist/esm/flows-actors/a2a/batches/a2a-push-delivery.batch.backend.service.d.ts.map +1 -1
  437. package/dist/esm/flows-actors/a2a/controllers/a2a.controller.d.ts.map +1 -1
  438. package/dist/esm/flows-actors/a2a/controllers/a2a.controller.js.map +1 -1
  439. package/dist/esm/flows-actors/a2a/models/a2a-dialect.backend.schemas.d.ts.map +1 -1
  440. package/dist/esm/flows-actors/a2a/models/a2a-push-notification-delivery.backend.utils.d.ts.map +1 -1
  441. package/dist/esm/flows-actors/a2a/models/a2a-push-notification.backend.schemas.d.ts.map +1 -1
  442. package/dist/esm/flows-actors/a2a/models/a2a.backend.schemas.d.ts.map +1 -1
  443. package/dist/esm/flows-actors/a2a/models/a2a.backend.schemas.js.map +1 -1
  444. package/dist/esm/flows-actors/a2a/services/a2a-push-delivery-log.repository.d.ts.map +1 -1
  445. package/dist/esm/flows-actors/a2a/services/a2a-push-dispatcher.backend.service.d.ts.map +1 -1
  446. package/dist/esm/flows-actors/a2a/services/a2a-task-cancellation.backend.service.d.ts.map +1 -1
  447. package/dist/esm/flows-actors/a2a/services/a2a-task-cancellation.backend.service.js.map +1 -1
  448. package/dist/esm/flows-actors/a2a/services/a2a-task.backend.service.d.ts.map +1 -1
  449. package/dist/esm/flows-actors/a2a/services/a2a-task.backend.service.js.map +1 -1
  450. package/dist/esm/flows-actors/a2a/services/a2a-token-budget.backend.service.d.ts.map +1 -1
  451. package/dist/esm/flows-actors/a2a/services/a2a-token-budget.backend.service.js.map +1 -1
  452. package/dist/esm/flows-actors/a2a/services/a2a.backend.service.d.ts.map +1 -1
  453. package/dist/esm/flows-actors/a2a/services/a2a.backend.service.js.map +1 -1
  454. package/dist/esm/flows-actors/controllers/flows-actors.controller.d.ts.map +1 -1
  455. package/dist/esm/flows-actors/models/agent-catalogs.backend.definitions.d.ts.map +1 -1
  456. package/dist/esm/flows-actors/models/agent-catalogs.backend.definitions.js.map +1 -1
  457. package/dist/esm/flows-actors/models/agent-facets.backend.definitions.d.ts.map +1 -1
  458. package/dist/esm/flows-actors/models/agents.backend.definitions.d.ts.map +1 -1
  459. package/dist/esm/flows-actors/models/core-facets.backend.definitions.d.ts.map +1 -1
  460. package/dist/esm/flows-actors/models/core-facets.backend.definitions.js.map +1 -1
  461. package/dist/esm/flows-actors/models/flows-actors.backend.definitions.d.ts.map +1 -1
  462. package/dist/esm/flows-actors/models/flows-actors.backend.schemas.d.ts.map +1 -1
  463. package/dist/esm/flows-actors/models/flows-actors.backend.schemas.js.map +1 -1
  464. package/dist/esm/flows-actors/models/function-tools.backend.definitions.d.ts +107 -16
  465. package/dist/esm/flows-actors/models/function-tools.backend.definitions.d.ts.map +1 -1
  466. package/dist/esm/flows-actors/models/function-tools.backend.definitions.js +118 -18
  467. package/dist/esm/flows-actors/models/function-tools.backend.definitions.js.map +1 -1
  468. package/dist/esm/flows-actors/models/market-generation.actors-system.backend.definitions.d.ts.map +1 -1
  469. package/dist/esm/flows-actors/models/market-generation.actors-system.backend.definitions.js.map +1 -1
  470. package/dist/esm/flows-actors/models/mcp-client.backend.definitions.d.ts.map +1 -1
  471. package/dist/esm/flows-actors/models/mcp-client.backend.definitions.js.map +1 -1
  472. package/dist/esm/flows-actors/services/__tests__/fixtures/meta-workflow-evaluation-treatment.test-fixture.d.ts.map +1 -1
  473. package/dist/esm/flows-actors/services/actors-system.backend.service.d.ts.map +1 -1
  474. package/dist/esm/flows-actors/services/actors-system.backend.service.js.map +1 -1
  475. package/dist/esm/flows-actors/services/agent-call-trace-sink.backend.d.ts.map +1 -1
  476. package/dist/esm/flows-actors/services/agent-facets.backend.service.d.ts.map +1 -1
  477. package/dist/esm/flows-actors/services/agents.backend.service.d.ts +104 -5
  478. package/dist/esm/flows-actors/services/agents.backend.service.d.ts.map +1 -1
  479. package/dist/esm/flows-actors/services/agents.backend.service.js +263 -31
  480. package/dist/esm/flows-actors/services/agents.backend.service.js.map +1 -1
  481. package/dist/esm/flows-actors/services/context-curation.backend.service.d.ts.map +1 -1
  482. package/dist/esm/flows-actors/services/conversational-execution.backend.service.d.ts +46 -1
  483. package/dist/esm/flows-actors/services/conversational-execution.backend.service.d.ts.map +1 -1
  484. package/dist/esm/flows-actors/services/conversational-execution.backend.service.js +193 -6
  485. package/dist/esm/flows-actors/services/conversational-execution.backend.service.js.map +1 -1
  486. package/dist/esm/flows-actors/services/flows-actors-registry.service.d.ts.map +1 -1
  487. package/dist/esm/flows-actors/services/flows-actors-registry.service.js.map +1 -1
  488. package/dist/esm/flows-actors/services/flows.backend.services.d.ts.map +1 -1
  489. package/dist/esm/flows-actors/services/flows.backend.services.js.map +1 -1
  490. package/dist/esm/flows-actors/services/llm-observability-agent-call-trace-sink.backend.d.ts.map +1 -1
  491. package/dist/esm/flows-actors/services/llm-observability-agent-call-trace-sink.backend.js.map +1 -1
  492. package/dist/esm/flows-actors/services/mcp-client.backend.service.d.ts.map +1 -1
  493. package/dist/esm/flows-actors/services/mcp-client.backend.service.js +3 -0
  494. package/dist/esm/flows-actors/services/mcp-client.backend.service.js.map +1 -1
  495. package/dist/esm/flows-actors/services/mcp-credential-resolver.backend.service.d.ts +99 -0
  496. package/dist/esm/flows-actors/services/mcp-credential-resolver.backend.service.d.ts.map +1 -0
  497. package/dist/esm/flows-actors/services/mcp-credential-resolver.backend.service.js +155 -0
  498. package/dist/esm/flows-actors/services/mcp-credential-resolver.backend.service.js.map +1 -0
  499. package/dist/esm/flows-actors/services/meta-workflow-evaluation-treatment-compiler.backend.service.d.ts.map +1 -1
  500. package/dist/esm/flows-actors/services/meta-workflow-standard-action-contracts.backend.service.d.ts.map +1 -1
  501. package/dist/esm/flows-actors/services/meta-workflow-standard-evaluation-contracts.backend.service.d.ts.map +1 -1
  502. package/dist/esm/flows-actors/services/meta-workflow-structured-artifact-action-compiler.backend.service.d.ts.map +1 -1
  503. package/dist/esm/flows-actors/services/prompt-compiler.backend.service.d.ts.map +1 -1
  504. package/dist/esm/flows-actors/services/prompt-compiler.backend.service.js.map +1 -1
  505. package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.d.ts.map +1 -1
  506. package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.js +9 -0
  507. package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.js.map +1 -1
  508. package/dist/esm/flows-actors/utils/bounded-subprocess.backend.utils.d.ts.map +1 -1
  509. package/dist/esm/flows-actors/utils/flows-actors-frontend-extractor.utils.d.ts.map +1 -1
  510. package/dist/esm/flows-actors/utils/meta-workflow-canonical-json.backend.utils.d.ts.map +1 -1
  511. package/dist/esm/flows-actors/utils/meta-workflow-canonical-json.backend.utils.js.map +1 -1
  512. package/dist/esm/flows-actors/utils/meta-workflow-structured-generation-plan.backend.utils.d.ts.map +1 -1
  513. package/dist/esm/flows-actors/utils/meta-workflow-structured-generation-plan.backend.utils.js.map +1 -1
  514. package/dist/esm/flows-actors/utils/prompt-ir-adapters.backend.utils.d.ts.map +1 -1
  515. package/dist/esm/flows-actors/utils/tool-approval-modification.backend.utils.d.ts +77 -0
  516. package/dist/esm/flows-actors/utils/tool-approval-modification.backend.utils.d.ts.map +1 -0
  517. package/dist/esm/flows-actors/utils/tool-approval-modification.backend.utils.js +164 -0
  518. package/dist/esm/flows-actors/utils/tool-approval-modification.backend.utils.js.map +1 -0
  519. package/dist/esm/flows-actors/utils/tool-approval-signing.backend.utils.d.ts +48 -0
  520. package/dist/esm/flows-actors/utils/tool-approval-signing.backend.utils.d.ts.map +1 -0
  521. package/dist/esm/flows-actors/utils/tool-approval-signing.backend.utils.js +101 -0
  522. package/dist/esm/flows-actors/utils/tool-approval-signing.backend.utils.js.map +1 -0
  523. package/dist/esm/guidance/batches/dormancy-detection.batch.backend.service.d.ts.map +1 -1
  524. package/dist/esm/guidance/services/guidance-trigger-evaluator.backend.service.d.ts.map +1 -1
  525. package/dist/esm/guidance/services/lifecycle-custom-implementations.backend.d.ts.map +1 -1
  526. package/dist/esm/guidance/services/lifecycle-evaluator.backend.service.d.ts.map +1 -1
  527. package/dist/esm/guidance/services/lifecycle-scope-id.backend.utils.d.ts.map +1 -1
  528. package/dist/esm/guidance/services/milestone-condition-registry.backend.service.d.ts.map +1 -1
  529. package/dist/esm/guidance/services/milestone-definition-registry.backend.service.d.ts.map +1 -1
  530. package/dist/esm/guidance/services/milestone-evaluator.backend.service.d.ts.map +1 -1
  531. package/dist/esm/guidance/services/milestone-evaluator.backend.service.js.map +1 -1
  532. package/dist/esm/guidance/services/progression-state-store.backend.service.d.ts.map +1 -1
  533. package/dist/esm/guidance/services/progression-state-store.backend.service.js.map +1 -1
  534. package/dist/esm/guidance/services/scoped-state-read-custom-implementations.backend.d.ts.map +1 -1
  535. package/dist/esm/i18n/controllers/i18n-controller.backend.service.d.ts.map +1 -1
  536. package/dist/esm/i18n/controllers/i18n-controller.backend.service.js.map +1 -1
  537. package/dist/esm/i18n/services/i18n.backend.service.d.ts.map +1 -1
  538. package/dist/esm/index.d.ts +0 -1
  539. package/dist/esm/index.d.ts.map +1 -1
  540. package/dist/esm/index.js +0 -1
  541. package/dist/esm/index.js.map +1 -1
  542. package/dist/esm/inject/models/container.d.ts +10 -0
  543. package/dist/esm/inject/models/container.d.ts.map +1 -1
  544. package/dist/esm/inject/models/container.js +49 -1
  545. package/dist/esm/inject/models/container.js.map +1 -1
  546. package/dist/esm/inject/models/service-types.d.ts +3 -0
  547. package/dist/esm/inject/models/service-types.d.ts.map +1 -1
  548. package/dist/esm/inject/models/service-types.js +3 -0
  549. package/dist/esm/inject/models/service-types.js.map +1 -1
  550. package/dist/esm/mcp/controllers/mcp.controller.d.ts.map +1 -1
  551. package/dist/esm/mcp/controllers/mcp.controller.js +50 -3
  552. package/dist/esm/mcp/controllers/mcp.controller.js.map +1 -1
  553. package/dist/esm/mcp/models/mcp-protocol.backend.schemas.d.ts.map +1 -1
  554. package/dist/esm/mcp/models/mcp-tool.backend.schemas.d.ts.map +1 -1
  555. package/dist/esm/mcp/models/mcp-tool.backend.schemas.js.map +1 -1
  556. package/dist/esm/mcp/services/mcp-server.backend.service.d.ts.map +1 -1
  557. package/dist/esm/mcp/services/mcp-server.backend.service.js.map +1 -1
  558. package/dist/esm/mcp/services/mcp-tool-adapter.backend.service.d.ts.map +1 -1
  559. package/dist/esm/mcp/services/mcp-tool-adapter.backend.service.js.map +1 -1
  560. package/dist/esm/mcp/services/resource-server-instances-registry.backend.service.d.ts.map +1 -1
  561. package/dist/esm/mcp/utils/zod-to-mcp-json-schema.backend.utils.d.ts.map +1 -1
  562. package/dist/esm/meta-workflow-runtime.exports.d.ts.map +1 -1
  563. package/dist/esm/monitoring/analytics/controllers/analytics.backend.controller.d.ts.map +1 -1
  564. package/dist/esm/monitoring/analytics/controllers/analytics.backend.controller.js.map +1 -1
  565. package/dist/esm/monitoring/analytics/services/value-moment-definition-registry.backend.service.d.ts.map +1 -1
  566. package/dist/esm/monitoring/analytics/services/value-moment-definition-registry.backend.service.js.map +1 -1
  567. package/dist/esm/monitoring/analytics/services/value-moment-engine.backend.service.d.ts.map +1 -1
  568. package/dist/esm/monitoring/analytics/services/value-moment-engine.backend.service.js.map +1 -1
  569. package/dist/esm/monitoring/analytics/services/value-moment-handler-registry.backend.service.d.ts.map +1 -1
  570. package/dist/esm/monitoring/analytics/services/value-moment-handler-registry.backend.service.js.map +1 -1
  571. package/dist/esm/monitoring/logger/models/logger.backend.schemas.d.ts.map +1 -1
  572. package/dist/esm/monitoring/logger/models/logger.backend.schemas.js.map +1 -1
  573. package/dist/esm/monitoring/logger/services/__tests__/mock-logger.service.d.ts.map +1 -1
  574. package/dist/esm/monitoring/logger/services/logger.service.d.ts +12 -0
  575. package/dist/esm/monitoring/logger/services/logger.service.d.ts.map +1 -1
  576. package/dist/esm/monitoring/logger/services/logger.service.js +3 -3
  577. package/dist/esm/monitoring/logger/services/logger.service.js.map +1 -1
  578. package/dist/esm/monitoring/logger/utils/log-severity-floor.backend.utils.d.ts.map +1 -1
  579. package/dist/esm/monitoring/logger/utils/log-severity-floor.backend.utils.js.map +1 -1
  580. package/dist/esm/monitoring/logger/utils/log-value-normalization.backend.utils.d.ts.map +1 -1
  581. package/dist/esm/monitoring/observability/audit-observation-emission.backend.d.ts +10 -6
  582. package/dist/esm/monitoring/observability/audit-observation-emission.backend.d.ts.map +1 -1
  583. package/dist/esm/monitoring/observability/audit-observation-emission.backend.js +10 -6
  584. package/dist/esm/monitoring/observability/audit-observation-emission.backend.js.map +1 -1
  585. package/dist/esm/monitoring/observability/models/observability.backend.schemas.d.ts.map +1 -1
  586. package/dist/esm/monitoring/observability/models/observability.backend.schemas.js.map +1 -1
  587. package/dist/esm/monitoring/observability/otel-preload.d.ts.map +1 -1
  588. package/dist/esm/monitoring/observability/otel-sdk-global-handle.d.ts.map +1 -1
  589. package/dist/esm/monitoring/observability/services/__tests__/mock-metrics.service.d.ts.map +1 -1
  590. package/dist/esm/monitoring/observability/services/metrics.service.d.ts.map +1 -1
  591. package/dist/esm/monitoring/observability/services/metrics.service.js.map +1 -1
  592. package/dist/esm/monitoring/observability/services/observability.backend.service.d.ts.map +1 -1
  593. package/dist/esm/notifications/email/components/email-components.d.ts.map +1 -1
  594. package/dist/esm/notifications/email/models/email-template-definition.d.ts.map +1 -1
  595. package/dist/esm/notifications/email/models/email-transport.backend.definitions.d.ts.map +1 -1
  596. package/dist/esm/notifications/email/services/email-batch-send.batch.backend.service.d.ts.map +1 -1
  597. package/dist/esm/notifications/email/services/email-template-registry.backend.service.d.ts.map +1 -1
  598. package/dist/esm/notifications/email/services/email-template-registry.backend.service.js.map +1 -1
  599. package/dist/esm/notifications/email/services/email-template-validator.backend.service.d.ts.map +1 -1
  600. package/dist/esm/notifications/email/services/email-template-validator.backend.service.js.map +1 -1
  601. package/dist/esm/notifications/email/services/email.backend.service.d.ts +47 -6
  602. package/dist/esm/notifications/email/services/email.backend.service.d.ts.map +1 -1
  603. package/dist/esm/notifications/email/services/email.backend.service.js +86 -36
  604. package/dist/esm/notifications/email/services/email.backend.service.js.map +1 -1
  605. package/dist/esm/notifications/email/utils/color-conversion.utils.d.ts.map +1 -1
  606. package/dist/esm/notifications/email/utils/color-conversion.utils.js.map +1 -1
  607. package/dist/esm/notifications/email/utils/interpolate-email-label.utils.d.ts.map +1 -1
  608. package/dist/esm/notifications/email/utils/zod-to-typescript.utils.d.ts.map +1 -1
  609. package/dist/esm/notifications/services/notification-badge.backend.service.d.ts.map +1 -1
  610. package/dist/esm/notifications/services/notification-badge.backend.service.js.map +1 -1
  611. package/dist/esm/notifications/services/notifications-dispatcher.backend.service.d.ts.map +1 -1
  612. package/dist/esm/notifications/services/notifications-dispatcher.backend.service.js.map +1 -1
  613. package/dist/esm/notifications/sms/models/sms-transport.backend.definitions.d.ts +32 -0
  614. package/dist/esm/notifications/sms/models/sms-transport.backend.definitions.d.ts.map +1 -0
  615. package/dist/esm/notifications/sms/models/sms-transport.backend.definitions.js +32 -0
  616. package/dist/esm/notifications/sms/models/sms-transport.backend.definitions.js.map +1 -0
  617. package/dist/esm/notifications/sms/services/sms.backend.service.d.ts +64 -10
  618. package/dist/esm/notifications/sms/services/sms.backend.service.d.ts.map +1 -1
  619. package/dist/esm/notifications/sms/services/sms.backend.service.js +277 -82
  620. package/dist/esm/notifications/sms/services/sms.backend.service.js.map +1 -1
  621. package/dist/esm/notifications/webhooks/controllers/webhook-auto-controller.backend.service.d.ts.map +1 -1
  622. package/dist/esm/notifications/webhooks/controllers/webhook-auto-controller.backend.service.js.map +1 -1
  623. package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.backend.service.d.ts.map +1 -1
  624. package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.backend.service.js.map +1 -1
  625. package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.utils.d.ts.map +1 -1
  626. package/dist/esm/notifications/webhooks/outbound/m2m-webhook-signed-request.backend.utils.d.ts.map +1 -1
  627. package/dist/esm/notifications/webhooks/outbound/m2m-webhook-signed-request.backend.utils.js.map +1 -1
  628. package/dist/esm/notifications/webhooks/outbound/services/m2m-webhook-delivery-log.custom-impl.backend.service.d.ts.map +1 -1
  629. package/dist/esm/notifications/webhooks/outbound/services/m2m-webhook-delivery-log.repository.d.ts.map +1 -1
  630. package/dist/esm/notifications/webhooks/outbound/services/m2m-webhook-dispatcher.backend.service.d.ts.map +1 -1
  631. package/dist/esm/notifications/webhooks/outbound/services/webhook-config-public-key.custom-impl.backend.service.d.ts.map +1 -1
  632. package/dist/esm/notifications/webhooks/outbound/services/webhook-config-test-endpoint.custom-impl.backend.service.d.ts.map +1 -1
  633. package/dist/esm/notifications/webhooks/outbound/services/webhook-config-test-endpoint.custom-impl.backend.service.js.map +1 -1
  634. package/dist/esm/notifications/webhooks/outbound/services/webhook-config.backend.service.d.ts.map +1 -1
  635. package/dist/esm/notifications/webhooks/services/polymorphic-lookup.backend.service.d.ts.map +1 -1
  636. package/dist/esm/notifications/webhooks/services/webhook-handler.backend.service.d.ts.map +1 -1
  637. package/dist/esm/notifications/webhooks/services/webhook-handler.backend.service.js.map +1 -1
  638. package/dist/esm/organizations/batches/organization-member-invitation-sweep.batch.backend.service.d.ts.map +1 -1
  639. package/dist/esm/organizations/batches/organization-purge.batch.backend.service.d.ts.map +1 -1
  640. package/dist/esm/organizations/batches/organization-purge.batch.backend.service.js.map +1 -1
  641. package/dist/esm/organizations/services/authority-change-audit.backend.utils.d.ts.map +1 -1
  642. package/dist/esm/organizations/services/invitation-acceptance.backend.utils.d.ts.map +1 -1
  643. package/dist/esm/organizations/services/org-creation-on-registration.backend.utils.d.ts.map +1 -1
  644. package/dist/esm/organizations/services/org-member-roles-validation.backend.utils.d.ts.map +1 -1
  645. package/dist/esm/organizations/services/organization-custom-implementation.backend.service.d.ts.map +1 -1
  646. package/dist/esm/organizations/services/organization-custom-implementation.backend.service.js.map +1 -1
  647. package/dist/esm/organizations/services/organization-deletion-audit.custom-impl.backend.service.d.ts.map +1 -1
  648. package/dist/esm/organizations/services/organization-member-custom-implementation.backend.service.d.ts.map +1 -1
  649. package/dist/esm/organizations/services/organization-onboarding-operation.backend.utils.d.ts.map +1 -1
  650. package/dist/esm/organizations/services/organization-unit-custom-implementation.backend.service.d.ts.map +1 -1
  651. package/dist/esm/organizations/services/organization-unit-member-custom-implementation.backend.service.d.ts.map +1 -1
  652. package/dist/esm/organizations/services/scim-provisioning-gate.backend.utils.d.ts.map +1 -1
  653. package/dist/esm/organizations/services/user-org-type-grant.backend.utils.d.ts.map +1 -1
  654. package/dist/esm/organizations/services/user-type-revocation-on-org-leave.backend.utils.d.ts.map +1 -1
  655. package/dist/esm/pdf-templates/__tests__/fixtures/tiny-pdf-template.fixture.d.ts.map +1 -1
  656. package/dist/esm/pdf-templates/models/pdf-template-binding.d.ts.map +1 -1
  657. package/dist/esm/pdf-templates/models/pdf-template-definition.d.ts.map +1 -1
  658. package/dist/esm/pdf-templates/services/pdf-generated-file-writer.backend.service.d.ts.map +1 -1
  659. package/dist/esm/pdf-templates/services/pdf-generation-orchestrator.backend.service.d.ts.map +1 -1
  660. package/dist/esm/pdf-templates/services/pdf-renderer.backend.service.d.ts.map +1 -1
  661. package/dist/esm/pdf-templates/services/pdf-template-binding.backend.service.d.ts.map +1 -1
  662. package/dist/esm/queue/adapters/in-memory-queue-adapter.backend.service.d.ts.map +1 -1
  663. package/dist/esm/queue/adapters/in-memory-queue-adapter.backend.service.js.map +1 -1
  664. package/dist/esm/queue/adapters/queue-adapter.backend.binding.d.ts.map +1 -1
  665. package/dist/esm/queue/adapters/queue-adapter.backend.binding.js.map +1 -1
  666. package/dist/esm/queue/adapters/queue-adapter.backend.interface.d.ts.map +1 -1
  667. package/dist/esm/queue/adapters/queue-adapter.backend.interface.js.map +1 -1
  668. package/dist/esm/queue/adapters/queue-adapter.backend.options.d.ts.map +1 -1
  669. package/dist/esm/queue/adapters/queue-adapter.backend.options.js.map +1 -1
  670. package/dist/esm/queue/adapters/rabbitmq-adapter.backend.service.d.ts.map +1 -1
  671. package/dist/esm/queue/adapters/rabbitmq-adapter.backend.service.js.map +1 -1
  672. package/dist/esm/queue/apps-crontabs-manager.backend.service.d.ts.map +1 -1
  673. package/dist/esm/queue/cron-job-sync.backend.service.d.ts.map +1 -1
  674. package/dist/esm/queue/domain-queue-consumer.backend.service.d.ts.map +1 -1
  675. package/dist/esm/queue/domain-queue-consumer.backend.service.js.map +1 -1
  676. package/dist/esm/queue/job-completion-registry.backend.service.d.ts.map +1 -1
  677. package/dist/esm/queue/job-consumer.backend.service.d.ts.map +1 -1
  678. package/dist/esm/queue/job-consumer.backend.service.js.map +1 -1
  679. package/dist/esm/queue/job-executor.backend.service.d.ts.map +1 -1
  680. package/dist/esm/queue/job-executor.backend.service.js.map +1 -1
  681. package/dist/esm/queue/job-payload-storage.backend.service.d.ts.map +1 -1
  682. package/dist/esm/queue/job-status-tracking.backend.service.d.ts.map +1 -1
  683. package/dist/esm/queue/queue-monitoring.backend.service.d.ts.map +1 -1
  684. package/dist/esm/queue/queue-monitoring.backend.service.js.map +1 -1
  685. package/dist/esm/queue/queue-worker-initializer.backend.service.d.ts.map +1 -1
  686. package/dist/esm/queue/queue-worker-initializer.backend.service.js.map +1 -1
  687. package/dist/esm/queue/queue.backend.service.d.ts.map +1 -1
  688. package/dist/esm/queue/queue.backend.service.js.map +1 -1
  689. package/dist/esm/queue/scheduled-message-verifier.backend.service.d.ts.map +1 -1
  690. package/dist/esm/queue/worker-shutdown-manager.backend.service.d.ts.map +1 -1
  691. package/dist/esm/queue/worker-shutdown-manager.backend.service.js.map +1 -1
  692. package/dist/esm/rag/batches/rag-embedding-drain.batch.backend.service.d.ts.map +1 -1
  693. package/dist/esm/rag/batches/rag-reconciliation-sweep.batch.backend.service.d.ts.map +1 -1
  694. package/dist/esm/rag/models/rag-chunk-store.backend.types.d.ts.map +1 -1
  695. package/dist/esm/rag/models/rag-retrieval.backend.types.d.ts.map +1 -1
  696. package/dist/esm/rag/services/mongodb-rag-chunk-store.backend.service.d.ts.map +1 -1
  697. package/dist/esm/rag/services/postgresql-rag-chunk-store.backend.service.d.ts.map +1 -1
  698. package/dist/esm/rag/services/rag-chunk-collection.mongodb-ddl.backend.d.ts.map +1 -1
  699. package/dist/esm/rag/services/rag-chunk-retrieval.mongodb-query.backend.d.ts.map +1 -1
  700. package/dist/esm/rag/services/rag-chunk-retrieval.postgresql-query.backend.d.ts.map +1 -1
  701. package/dist/esm/rag/services/rag-chunk-store.backend.service.d.ts.map +1 -1
  702. package/dist/esm/rag/services/rag-chunk-table.postgresql-ddl.backend.d.ts.map +1 -1
  703. package/dist/esm/rag/services/rag-ingestion.backend.service.d.ts.map +1 -1
  704. package/dist/esm/rag/services/rag-retrieval.backend.service.d.ts.map +1 -1
  705. package/dist/esm/rag/utils/rag-chunk-fusion.backend.utils.d.ts.map +1 -1
  706. package/dist/esm/rag/utils/rag-chunk-removal.backend.utils.d.ts.map +1 -1
  707. package/dist/esm/rag/utils/rag-chunk-row-shaping.backend.utils.d.ts.map +1 -1
  708. package/dist/esm/rag/utils/rag-chunking.backend.utils.d.ts.map +1 -1
  709. package/dist/esm/rag/utils/rag-chunking.backend.utils.js.map +1 -1
  710. package/dist/esm/rag/utils/rag-context-assembly.backend.utils.d.ts.map +1 -1
  711. package/dist/esm/rag/utils/rag-context-assembly.backend.utils.js.map +1 -1
  712. package/dist/esm/rag/utils/rag-ingestion-trigger.backend.utils.d.ts.map +1 -1
  713. package/dist/esm/rag/utils/rag-retrieval-scope.backend.utils.d.ts.map +1 -1
  714. package/dist/esm/rag/utils/rag-source-field-value.backend.utils.d.ts.map +1 -1
  715. package/dist/esm/requests/models/api-routes.backend.defintions.d.ts.map +1 -1
  716. package/dist/esm/requests/models/requests.backend.schemas.d.ts.map +1 -1
  717. package/dist/esm/requests/service/platform-mutualized-handler.backend.service.d.ts.map +1 -1
  718. package/dist/esm/requests/service/platform-requests.backend.utils.d.ts.map +1 -1
  719. package/dist/esm/requests/service/remote-client-base.backend.service.d.ts.map +1 -1
  720. package/dist/esm/requests/service/serverless-services-handler.backend.service.d.ts.map +1 -1
  721. package/dist/esm/requests/service/websocket.service.d.ts.map +1 -1
  722. package/dist/esm/requests/service/websocket.service.js +49 -1
  723. package/dist/esm/requests/service/websocket.service.js.map +1 -1
  724. package/dist/esm/resources/backend-resource-registry.exports.d.ts.map +1 -1
  725. package/dist/esm/resources/models/custom-service-implementations.backend.definition.d.ts.map +1 -1
  726. package/dist/esm/resources/models/custom-service-implementations.backend.definition.js +2 -0
  727. package/dist/esm/resources/models/custom-service-implementations.backend.definition.js.map +1 -1
  728. package/dist/esm/resources/models/index.d.ts.map +1 -1
  729. package/dist/esm/resources/models/resources-operations.backend.definitions.d.ts.map +1 -1
  730. package/dist/esm/resources/models/resources-operations.backend.definitions.js.map +1 -1
  731. package/dist/esm/resources/models/resources-relationships.backend.definitions.d.ts.map +1 -1
  732. package/dist/esm/resources/models/resources-relationships.backend.definitions.js.map +1 -1
  733. package/dist/esm/resources/models/resources-types.backend.schemas.d.ts.map +1 -1
  734. package/dist/esm/resources/models/resources-types.backend.schemas.js.map +1 -1
  735. package/dist/esm/resources/models/resources.backend.schemas.d.ts.map +1 -1
  736. package/dist/esm/resources/models/virtual-fields.backend.types.d.ts.map +1 -1
  737. package/dist/esm/resources/services/__tests__/mock-resources-registry.service.d.ts.map +1 -1
  738. package/dist/esm/resources/services/resource-context.backend.service.d.ts.map +1 -1
  739. package/dist/esm/resources/services/resource-id.backend.service.d.ts.map +1 -1
  740. package/dist/esm/resources/services/resource-population.backend.service.d.ts +17 -2
  741. package/dist/esm/resources/services/resource-population.backend.service.d.ts.map +1 -1
  742. package/dist/esm/resources/services/resource-population.backend.service.js +74 -18
  743. package/dist/esm/resources/services/resource-population.backend.service.js.map +1 -1
  744. package/dist/esm/resources/services/resources-registry.backend.service.d.ts +23 -0
  745. package/dist/esm/resources/services/resources-registry.backend.service.d.ts.map +1 -1
  746. package/dist/esm/resources/services/resources-registry.backend.service.js +31 -0
  747. package/dist/esm/resources/services/resources-registry.backend.service.js.map +1 -1
  748. package/dist/esm/resources/services/virtual-fields.backend.service.d.ts.map +1 -1
  749. package/dist/esm/resources/utils/resource-retention.backend.utils.d.ts.map +1 -1
  750. package/dist/esm/runtime/controllers/health-controller.backend.service.d.ts.map +1 -1
  751. package/dist/esm/runtime/controllers/health-controller.backend.service.js.map +1 -1
  752. package/dist/esm/runtime/domain-module.backend.definitions.d.ts.map +1 -1
  753. package/dist/esm/runtime/domain-module.backend.definitions.js.map +1 -1
  754. package/dist/esm/runtime/models/execution-context.backend.schemas.d.ts.map +1 -1
  755. package/dist/esm/runtime/models/request-context.als.backend.d.ts.map +1 -1
  756. package/dist/esm/runtime/models/runtime.backend.schemas.d.ts.map +1 -1
  757. package/dist/esm/runtime/services/execution-context-creator.backend.service.d.ts.map +1 -1
  758. package/dist/esm/runtime/services/execution-context-creator.backend.service.js.map +1 -1
  759. package/dist/esm/runtime/services/execution-context-handler.backend.service.d.ts.map +1 -1
  760. package/dist/esm/runtime/services/health-readiness-contributor.backend.interface.d.ts.map +1 -1
  761. package/dist/esm/runtime/services/health-readiness-contributor.backend.interface.js.map +1 -1
  762. package/dist/esm/runtime/services/http-server.backend.service.d.ts.map +1 -1
  763. package/dist/esm/runtime/services/http-server.backend.service.js +10 -0
  764. package/dist/esm/runtime/services/http-server.backend.service.js.map +1 -1
  765. package/dist/esm/runtime/services/start-application.backend.service.d.ts.map +1 -1
  766. package/dist/esm/runtime/services/start-application.backend.service.js +26 -12
  767. package/dist/esm/runtime/services/start-application.backend.service.js.map +1 -1
  768. package/dist/esm/runtime/services/utils/oauth-body-cap.backend.utils.d.ts.map +1 -1
  769. package/dist/esm/runtime/testing/execution-context-test-fixtures.d.ts.map +1 -1
  770. package/dist/esm/runtime/testing/mock-execution-context-creator.service.d.ts.map +1 -1
  771. package/dist/esm/runtime/utils/application-startup-config-access.backend.utils.d.ts.map +1 -1
  772. package/dist/esm/runtime/utils/feature-gated-core-resource-exclusions.backend.utils.d.ts.map +1 -1
  773. package/dist/esm/runtime/utils/request-client-ip.utils.d.ts.map +1 -1
  774. package/dist/esm/runtime/utils/scan-default-exports.backend.utils.d.ts.map +1 -1
  775. package/dist/esm/security/api-keys/api-key-generation.backend.utils.d.ts.map +1 -1
  776. package/dist/esm/security/api-keys/api-keys.custom-impl.backend.service.d.ts.map +1 -1
  777. package/dist/esm/security/api-keys/api-keys.custom-impl.backend.service.js.map +1 -1
  778. package/dist/esm/security/authentications/batches/anonymous-session-cleanup.batch.backend.service.d.ts.map +1 -1
  779. package/dist/esm/security/authentications/batches/anonymous-session-cleanup.batch.backend.service.js.map +1 -1
  780. package/dist/esm/security/authentications/controllers/auth-method-management-controller.backend.service.d.ts.map +1 -1
  781. package/dist/esm/security/authentications/controllers/authentication-controller.backend.service.d.ts +22 -0
  782. package/dist/esm/security/authentications/controllers/authentication-controller.backend.service.d.ts.map +1 -1
  783. package/dist/esm/security/authentications/controllers/authentication-controller.backend.service.js +84 -0
  784. package/dist/esm/security/authentications/controllers/authentication-controller.backend.service.js.map +1 -1
  785. package/dist/esm/security/authentications/controllers/oauth-provider-controller.backend.service.d.ts.map +1 -1
  786. package/dist/esm/security/authentications/controllers/oauth-provider-controller.backend.service.js.map +1 -1
  787. package/dist/esm/security/authentications/models/auth-constants.backend.d.ts.map +1 -1
  788. package/dist/esm/security/authentications/models/authentications.backend.schemas.d.ts.map +1 -1
  789. package/dist/esm/security/authentications/models/authorization-client.backend.schemas.d.ts.map +1 -1
  790. package/dist/esm/security/authentications/models/cimd.backend.schemas.d.ts.map +1 -1
  791. package/dist/esm/security/authentications/models/cimd.backend.schemas.js.map +1 -1
  792. package/dist/esm/security/authentications/models/federated-auth-transport.backend.definitions.d.ts +37 -0
  793. package/dist/esm/security/authentications/models/federated-auth-transport.backend.definitions.d.ts.map +1 -0
  794. package/dist/esm/security/authentications/models/federated-auth-transport.backend.definitions.js +37 -0
  795. package/dist/esm/security/authentications/models/federated-auth-transport.backend.definitions.js.map +1 -0
  796. package/dist/esm/security/authentications/models/identity-persistence-boundaries.backend.d.ts.map +1 -1
  797. package/dist/esm/security/authentications/models/jwt.backend.schemas.d.ts.map +1 -1
  798. package/dist/esm/security/authentications/models/oauth2-connection.backend.schemas.d.ts +15 -0
  799. package/dist/esm/security/authentications/models/oauth2-connection.backend.schemas.d.ts.map +1 -1
  800. package/dist/esm/security/authentications/models/oauth2-connection.backend.schemas.js.map +1 -1
  801. package/dist/esm/security/authentications/models/saml-authentication.backend.schemas.d.ts.map +1 -1
  802. package/dist/esm/security/authentications/models/sso-connection.backend.schemas.d.ts.map +1 -1
  803. package/dist/esm/security/authentications/models/user-authorization-version.backend.utils.d.ts.map +1 -1
  804. package/dist/esm/security/authentications/seeds/enterprise-config-defaults.seeds.d.ts.map +1 -1
  805. package/dist/esm/security/authentications/services/__tests__/mock-auth-execution-context-factory.service.d.ts.map +1 -1
  806. package/dist/esm/security/authentications/services/__tests__/mock-auth-token-issuer.service.d.ts.map +1 -1
  807. package/dist/esm/security/authentications/services/__tests__/oauth-provider-audit-spies.mock.d.ts.map +1 -1
  808. package/dist/esm/security/authentications/services/admin-config/__tests__/mock-domain-to-org-lookup.service.d.ts.map +1 -1
  809. package/dist/esm/security/authentications/services/admin-config/__tests__/mock-enterprise-user-provisioning.service.d.ts.map +1 -1
  810. package/dist/esm/security/authentications/services/admin-config/auth-organization-configuration.service.d.ts.map +1 -1
  811. package/dist/esm/security/authentications/services/admin-config/auth-organization-configuration.service.js.map +1 -1
  812. package/dist/esm/security/authentications/services/admin-config/domain-to-org-lookup.backend.service.d.ts.map +1 -1
  813. package/dist/esm/security/authentications/services/admin-config/domain-to-org-lookup.backend.service.js.map +1 -1
  814. package/dist/esm/security/authentications/services/admin-config/domain-verification.backend.service.d.ts.map +1 -1
  815. package/dist/esm/security/authentications/services/admin-config/domain-verification.backend.service.js.map +1 -1
  816. package/dist/esm/security/authentications/services/admin-config/enterprise-user-provisioning.backend.service.d.ts.map +1 -1
  817. package/dist/esm/security/authentications/services/admin-config/enterprise-user-provisioning.backend.service.js.map +1 -1
  818. package/dist/esm/security/authentications/services/admin-config/oidc-discovery.backend.service.d.ts.map +1 -1
  819. package/dist/esm/security/authentications/services/admin-config/oidc-discovery.backend.service.js +2 -1
  820. package/dist/esm/security/authentications/services/admin-config/oidc-discovery.backend.service.js.map +1 -1
  821. package/dist/esm/security/authentications/services/anonymous-session.backend.service.d.ts +9 -2
  822. package/dist/esm/security/authentications/services/anonymous-session.backend.service.d.ts.map +1 -1
  823. package/dist/esm/security/authentications/services/anonymous-session.backend.service.js +9 -2
  824. package/dist/esm/security/authentications/services/anonymous-session.backend.service.js.map +1 -1
  825. package/dist/esm/security/authentications/services/auth-credential-verifier.backend.service.d.ts.map +1 -1
  826. package/dist/esm/security/authentications/services/auth-execution-context-factory.backend.service.d.ts.map +1 -1
  827. package/dist/esm/security/authentications/services/auth-methods/auth-method-management.backend.service.d.ts.map +1 -1
  828. package/dist/esm/security/authentications/services/auth-methods/auth-method-management.backend.service.js.map +1 -1
  829. package/dist/esm/security/authentications/services/auth-methods/auth-mfa.backend.service.d.ts.map +1 -1
  830. package/dist/esm/security/authentications/services/auth-methods/auth-password-reset.backend.service.d.ts.map +1 -1
  831. package/dist/esm/security/authentications/services/auth-methods/auth-phone-verification.backend.service.d.ts.map +1 -1
  832. package/dist/esm/security/authentications/services/auth-methods/auth-registration.backend.service.d.ts.map +1 -1
  833. package/dist/esm/security/authentications/services/auth-methods/auth-registration.backend.service.js.map +1 -1
  834. package/dist/esm/security/authentications/services/auth-methods/oauth2-authentication.backend.service.d.ts +97 -0
  835. package/dist/esm/security/authentications/services/auth-methods/oauth2-authentication.backend.service.d.ts.map +1 -1
  836. package/dist/esm/security/authentications/services/auth-methods/oauth2-authentication.backend.service.js +218 -26
  837. package/dist/esm/security/authentications/services/auth-methods/oauth2-authentication.backend.service.js.map +1 -1
  838. package/dist/esm/security/authentications/services/auth-methods/oauth2-connection-resolver.backend.service.d.ts +14 -0
  839. package/dist/esm/security/authentications/services/auth-methods/oauth2-connection-resolver.backend.service.d.ts.map +1 -1
  840. package/dist/esm/security/authentications/services/auth-methods/oauth2-connection-resolver.backend.service.js +36 -0
  841. package/dist/esm/security/authentications/services/auth-methods/oauth2-connection-resolver.backend.service.js.map +1 -1
  842. package/dist/esm/security/authentications/services/auth-methods/saml-assertion-validator.backend.service.d.ts.map +1 -1
  843. package/dist/esm/security/authentications/services/auth-methods/saml-authentication.backend.service.d.ts.map +1 -1
  844. package/dist/esm/security/authentications/services/auth-methods/saml-metadata.backend.service.d.ts.map +1 -1
  845. package/dist/esm/security/authentications/services/auth-methods/saml-replay-guard.backend.service.d.ts.map +1 -1
  846. package/dist/esm/security/authentications/services/auth-methods/webauthn.backend.service.d.ts.map +1 -1
  847. package/dist/esm/security/authentications/services/auth-methods/webauthn.backend.service.js.map +1 -1
  848. package/dist/esm/security/authentications/services/auth-session-store.backend.service.d.ts.map +1 -1
  849. package/dist/esm/security/authentications/services/auth-token-issuer.backend.service.d.ts.map +1 -1
  850. package/dist/esm/security/authentications/services/auth-token-issuer.backend.service.js.map +1 -1
  851. package/dist/esm/security/authentications/services/authentication-orchestrator.backend.service.d.ts.map +1 -1
  852. package/dist/esm/security/authentications/services/authentication-orchestrator.backend.service.js.map +1 -1
  853. package/dist/esm/security/authentications/services/cimd-client-metadata.backend.service.d.ts.map +1 -1
  854. package/dist/esm/security/authentications/services/cimd-client-metadata.backend.service.js.map +1 -1
  855. package/dist/esm/security/authentications/services/custom-impls/auth-custom-implementations.backend.d.ts.map +1 -1
  856. package/dist/esm/security/authentications/services/custom-impls/auth-custom-implementations.backend.js.map +1 -1
  857. package/dist/esm/security/authentications/services/custom-impls/scim-tokens.custom-impl.backend.service.d.ts.map +1 -1
  858. package/dist/esm/security/authentications/services/custom-impls/siem-delivery-dlq.custom-impl.backend.service.d.ts.map +1 -1
  859. package/dist/esm/security/authentications/services/custom-impls/sso-config-domain-verification.custom-impl.backend.service.d.ts.map +1 -1
  860. package/dist/esm/security/authentications/services/custom-impls/sso-config-domain-verification.custom-impl.backend.service.js +57 -1
  861. package/dist/esm/security/authentications/services/custom-impls/sso-config-domain-verification.custom-impl.backend.service.js.map +1 -1
  862. package/dist/esm/security/authentications/services/custom-impls/sso-config.custom-impl.backend.service.d.ts.map +1 -1
  863. package/dist/esm/security/authentications/services/custom-impls/sso-config.custom-impl.backend.service.js.map +1 -1
  864. package/dist/esm/security/authentications/services/custom-impls/sso-connection.custom-impl.backend.service.d.ts.map +1 -1
  865. package/dist/esm/security/authentications/services/custom-impls/sso-connection.custom-impl.backend.service.js +11 -1
  866. package/dist/esm/security/authentications/services/custom-impls/sso-connection.custom-impl.backend.service.js.map +1 -1
  867. package/dist/esm/security/authentications/services/email-verification-initiator.backend.service.d.ts.map +1 -1
  868. package/dist/esm/security/authentications/services/machine-token-issuer.backend.service.d.ts.map +1 -1
  869. package/dist/esm/security/authentications/services/oauth-provider-token.backend.service.d.ts.map +1 -1
  870. package/dist/esm/security/authentications/services/oauth-provider-token.backend.service.js.map +1 -1
  871. package/dist/esm/security/authentications/services/oidc-authorization-code.backend.service.d.ts.map +1 -1
  872. package/dist/esm/security/authentications/services/oidc-authorization-code.backend.service.js.map +1 -1
  873. package/dist/esm/security/authentications/services/oidc-user-claims.backend.service.d.ts.map +1 -1
  874. package/dist/esm/security/authentications/services/resolve-active-member-orgs.backend.utils.d.ts.map +1 -1
  875. package/dist/esm/security/authentications/services/utils/__tests__/mock-auth-user-lookup.service.d.ts.map +1 -1
  876. package/dist/esm/security/authentications/services/utils/auth-controller.utils.d.ts.map +1 -1
  877. package/dist/esm/security/authentications/services/utils/auth-credential-ops.backend.service.d.ts.map +1 -1
  878. package/dist/esm/security/authentications/services/utils/auth-policy-resolution.backend.utils.d.ts.map +1 -1
  879. package/dist/esm/security/authentications/services/utils/auth-policy-resolution.backend.utils.js.map +1 -1
  880. package/dist/esm/security/authentications/services/utils/auth-response-helper.backend.service.d.ts.map +1 -1
  881. package/dist/esm/security/authentications/services/utils/auth-user-lookup.backend.service.d.ts.map +1 -1
  882. package/dist/esm/security/authentications/services/utils/auth-user-lookup.backend.service.js.map +1 -1
  883. package/dist/esm/security/authentications/services/utils/concurrent-session-eviction.backend.utils.d.ts.map +1 -1
  884. package/dist/esm/security/authentications/services/utils/ensure-user-profile.backend.utils.d.ts.map +1 -1
  885. package/dist/esm/security/authentications/services/utils/external-turn-rate-limit.backend.utils.d.ts.map +1 -1
  886. package/dist/esm/security/authentications/services/utils/external-turn-rate-limit.backend.utils.js.map +1 -1
  887. package/dist/esm/security/authentications/services/utils/machine-auth-rate-limit.backend.utils.d.ts.map +1 -1
  888. package/dist/esm/security/authentications/services/utils/pkce.backend.utils.d.ts.map +1 -1
  889. package/dist/esm/security/authentications/services/utils/saml-java-availability.d.ts.map +1 -1
  890. package/dist/esm/security/authentications/utils/application-auth-policy-audit.backend.utils.d.ts.map +1 -1
  891. package/dist/esm/security/authentications/utils/enterprise-sso-enforcement.backend.utils.d.ts.map +1 -1
  892. package/dist/esm/security/authentications/utils/enterprise-sso-enforcement.backend.utils.js.map +1 -1
  893. package/dist/esm/security/authentications/utils/one-off-session-lifetime.backend.utils.d.ts.map +1 -1
  894. package/dist/esm/security/authentications/utils/social-oauth2-purpose.backend.utils.d.ts.map +1 -1
  895. package/dist/esm/security/authorizations/access-grant-decision.factory.backend.d.ts +59 -0
  896. package/dist/esm/security/authorizations/access-grant-decision.factory.backend.d.ts.map +1 -0
  897. package/dist/esm/security/authorizations/access-grant-decision.factory.backend.js +111 -0
  898. package/dist/esm/security/authorizations/access-grant-decision.factory.backend.js.map +1 -0
  899. package/dist/esm/security/authorizations/access-grant-lifecycle-audit.backend.d.ts +57 -0
  900. package/dist/esm/security/authorizations/access-grant-lifecycle-audit.backend.d.ts.map +1 -0
  901. package/dist/esm/security/authorizations/access-grant-lifecycle-audit.backend.js +133 -0
  902. package/dist/esm/security/authorizations/access-grant-lifecycle-audit.backend.js.map +1 -0
  903. package/dist/esm/security/authorizations/application-access-grant-custom-implementation.backend.service.d.ts +41 -0
  904. package/dist/esm/security/authorizations/application-access-grant-custom-implementation.backend.service.d.ts.map +1 -0
  905. package/dist/esm/security/authorizations/application-access-grant-custom-implementation.backend.service.js +157 -0
  906. package/dist/esm/security/authorizations/application-access-grant-custom-implementation.backend.service.js.map +1 -0
  907. package/dist/esm/security/authorizations/application-wide-read-admission.backend.d.ts +84 -0
  908. package/dist/esm/security/authorizations/application-wide-read-admission.backend.d.ts.map +1 -0
  909. package/dist/esm/security/authorizations/application-wide-read-admission.backend.js +99 -0
  910. package/dist/esm/security/authorizations/application-wide-read-admission.backend.js.map +1 -0
  911. package/dist/esm/security/authorizations/authorization-denial-audit.backend.utils.d.ts.map +1 -1
  912. package/dist/esm/security/authorizations/cross-tenant-read-observation.backend.d.ts.map +1 -1
  913. package/dist/esm/security/authorizations/cross-tenant-read-observation.backend.js.map +1 -1
  914. package/dist/esm/security/authorizations/initiator-organization-confinement.backend.d.ts.map +1 -1
  915. package/dist/esm/security/authorizations/junction-scope-resolution.backend.d.ts.map +1 -1
  916. package/dist/esm/security/authorizations/organization-owner-floor.backend.utils.d.ts.map +1 -1
  917. package/dist/esm/security/authorizations/organization-owner-floor.backend.utils.js.map +1 -1
  918. package/dist/esm/security/authorizations/organization-unit-narrowing-enforcement.backend.d.ts.map +1 -1
  919. package/dist/esm/security/authorizations/platform-access-grant-custom-implementation.backend.service.d.ts.map +1 -1
  920. package/dist/esm/security/authorizations/platform-access-grant-custom-implementation.backend.service.js +20 -181
  921. package/dist/esm/security/authorizations/platform-access-grant-custom-implementation.backend.service.js.map +1 -1
  922. package/dist/esm/security/authorizations/privileged-access-review.backend.utils.d.ts.map +1 -1
  923. package/dist/esm/security/authorizations/relationship-foreign-key-filter.backend.d.ts.map +1 -1
  924. package/dist/esm/security/authorizations/role-ceiling.backend.utils.d.ts.map +1 -1
  925. package/dist/esm/security/authorizations/role-ceiling.backend.utils.js.map +1 -1
  926. package/dist/esm/security/authorizations/role-conferral.backend.utils.d.ts +40 -0
  927. package/dist/esm/security/authorizations/role-conferral.backend.utils.d.ts.map +1 -1
  928. package/dist/esm/security/authorizations/role-conferral.backend.utils.js +43 -1
  929. package/dist/esm/security/authorizations/role-conferral.backend.utils.js.map +1 -1
  930. package/dist/esm/security/authorizations/scope-root-collection-confinement.backend.d.ts +27 -17
  931. package/dist/esm/security/authorizations/scope-root-collection-confinement.backend.d.ts.map +1 -1
  932. package/dist/esm/security/authorizations/scope-root-collection-confinement.backend.js +27 -17
  933. package/dist/esm/security/authorizations/scope-root-collection-confinement.backend.js.map +1 -1
  934. package/dist/esm/security/authorizations/services/authorizations.backend.service.d.ts +72 -0
  935. package/dist/esm/security/authorizations/services/authorizations.backend.service.d.ts.map +1 -1
  936. package/dist/esm/security/authorizations/services/authorizations.backend.service.js +153 -10
  937. package/dist/esm/security/authorizations/services/authorizations.backend.service.js.map +1 -1
  938. package/dist/esm/security/authorizations/super-admin-floor.backend.utils.d.ts.map +1 -1
  939. package/dist/esm/security/authorizations/super-admin-floor.backend.utils.js.map +1 -1
  940. package/dist/esm/security/connected-accounts/connection-target-authorization.backend.d.ts.map +1 -1
  941. package/dist/esm/security/connected-accounts/connection-target-authorization.backend.js.map +1 -1
  942. package/dist/esm/security/connected-accounts/controllers/provider-connection.controller.backend.service.d.ts +139 -1
  943. package/dist/esm/security/connected-accounts/controllers/provider-connection.controller.backend.service.d.ts.map +1 -1
  944. package/dist/esm/security/connected-accounts/controllers/provider-connection.controller.backend.service.js +474 -33
  945. package/dist/esm/security/connected-accounts/controllers/provider-connection.controller.backend.service.js.map +1 -1
  946. package/dist/esm/security/connected-accounts/organization-provider-credential-resolver.port.d.ts +40 -0
  947. package/dist/esm/security/connected-accounts/organization-provider-credential-resolver.port.d.ts.map +1 -1
  948. package/dist/esm/security/connected-accounts/organization-provider-credential-resolver.port.js.map +1 -1
  949. package/dist/esm/security/connected-accounts/provider-oauth2-refresher.port.d.ts.map +1 -1
  950. package/dist/esm/security/connected-accounts/provider-oauth2-refresher.port.js.map +1 -1
  951. package/dist/esm/security/connected-accounts/services/organization-provider-credential-store.backend.service.d.ts +19 -0
  952. package/dist/esm/security/connected-accounts/services/organization-provider-credential-store.backend.service.d.ts.map +1 -1
  953. package/dist/esm/security/connected-accounts/services/organization-provider-credential-store.backend.service.js +38 -0
  954. package/dist/esm/security/connected-accounts/services/organization-provider-credential-store.backend.service.js.map +1 -1
  955. package/dist/esm/security/connected-accounts/services/organization-provider-credentials.custom-impl.backend.service.d.ts.map +1 -1
  956. package/dist/esm/security/connected-accounts/services/organization-provider-credentials.custom-impl.backend.service.js.map +1 -1
  957. package/dist/esm/security/connected-accounts/services/provider-oauth2-exchange.backend.d.ts.map +1 -1
  958. package/dist/esm/security/connected-accounts/services/provider-oauth2-exchange.backend.js +17 -1
  959. package/dist/esm/security/connected-accounts/services/provider-oauth2-exchange.backend.js.map +1 -1
  960. package/dist/esm/security/connected-accounts/services/provider-oauth2-pending-authorization.backend.service.d.ts +14 -0
  961. package/dist/esm/security/connected-accounts/services/provider-oauth2-pending-authorization.backend.service.d.ts.map +1 -1
  962. package/dist/esm/security/connected-accounts/services/provider-oauth2-pending-authorization.backend.service.js +16 -0
  963. package/dist/esm/security/connected-accounts/services/provider-oauth2-pending-authorization.backend.service.js.map +1 -1
  964. package/dist/esm/security/connected-accounts/services/provider-oauth2-refresher.backend.service.d.ts.map +1 -1
  965. package/dist/esm/security/connected-accounts/services/provider-oauth2-refresher.backend.service.js +1 -1
  966. package/dist/esm/security/connected-accounts/services/provider-oauth2-refresher.backend.service.js.map +1 -1
  967. package/dist/esm/security/connected-accounts/services/user-provider-credential-store.backend.service.d.ts +19 -0
  968. package/dist/esm/security/connected-accounts/services/user-provider-credential-store.backend.service.d.ts.map +1 -1
  969. package/dist/esm/security/connected-accounts/services/user-provider-credential-store.backend.service.js +45 -2
  970. package/dist/esm/security/connected-accounts/services/user-provider-credential-store.backend.service.js.map +1 -1
  971. package/dist/esm/security/connected-accounts/services/user-provider-credentials.custom-impl.backend.service.d.ts.map +1 -1
  972. package/dist/esm/security/connected-accounts/services/user-provider-credentials.custom-impl.backend.service.js.map +1 -1
  973. package/dist/esm/security/connected-accounts/user-provider-credential-resolver.port.d.ts +37 -1
  974. package/dist/esm/security/connected-accounts/user-provider-credential-resolver.port.d.ts.map +1 -1
  975. package/dist/esm/security/connected-accounts/user-provider-credential-resolver.port.js.map +1 -1
  976. package/dist/esm/security/connected-accounts/utils/provider-credential-envelope.backend.utils.d.ts.map +1 -1
  977. package/dist/esm/security/connected-accounts/utils/provider-credential-envelope.backend.utils.js.map +1 -1
  978. package/dist/esm/security/connected-accounts/utils/stored-credential-value.backend.utils.d.ts.map +1 -1
  979. package/dist/esm/security/connected-accounts/utils/stored-credential-value.backend.utils.js.map +1 -1
  980. package/dist/esm/security/connected-accounts/utils/user-delegated-access-token-slot.backend.utils.d.ts +34 -0
  981. package/dist/esm/security/connected-accounts/utils/user-delegated-access-token-slot.backend.utils.d.ts.map +1 -0
  982. package/dist/esm/security/connected-accounts/utils/user-delegated-access-token-slot.backend.utils.js +39 -0
  983. package/dist/esm/security/connected-accounts/utils/user-delegated-access-token-slot.backend.utils.js.map +1 -0
  984. package/dist/esm/security/consumable-tokens/batches/consumable-tokens-cleanup.batch.backend.service.d.ts.map +1 -1
  985. package/dist/esm/security/consumable-tokens/consumable-token-models.exports.d.ts.map +1 -1
  986. package/dist/esm/security/consumable-tokens/models/consumable-tokens.backend.resources-config.schemas.d.ts.map +1 -1
  987. package/dist/esm/security/consumable-tokens/models/consumable-tokens.shared.schemas.d.ts.map +1 -1
  988. package/dist/esm/security/consumable-tokens/models/index.d.ts.map +1 -1
  989. package/dist/esm/security/consumable-tokens/services/__tests__/mock-consumable-token.service.d.ts.map +1 -1
  990. package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.d.ts.map +1 -1
  991. package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.js.map +1 -1
  992. package/dist/esm/security/credential-rotation-grace.backend.utils.d.ts.map +1 -1
  993. package/dist/esm/security/credential-rotation-grace.backend.utils.js.map +1 -1
  994. package/dist/esm/security/jwt/services/auth-jwt-guard.backend.service.d.ts.map +1 -1
  995. package/dist/esm/security/jwt/services/jwt.backend.service.d.ts.map +1 -1
  996. package/dist/esm/security/jwt/services/wildo-worker-bootstrap-client.backend.service.d.ts +13 -0
  997. package/dist/esm/security/jwt/services/wildo-worker-bootstrap-client.backend.service.d.ts.map +1 -1
  998. package/dist/esm/security/jwt/services/wildo-worker-bootstrap-client.backend.service.js +14 -0
  999. package/dist/esm/security/jwt/services/wildo-worker-bootstrap-client.backend.service.js.map +1 -1
  1000. package/dist/esm/security/jwt/utils/jwt-verification-error-classification.backend.utils.d.ts.map +1 -1
  1001. package/dist/esm/security/oauth-clients/oauth-client-generation.backend.utils.d.ts.map +1 -1
  1002. package/dist/esm/security/oauth-clients/oauth-client-generation.backend.utils.js.map +1 -1
  1003. package/dist/esm/security/oauth-clients/oauth-clients.custom-impl.backend.service.d.ts.map +1 -1
  1004. package/dist/esm/security/oauth-clients/oauth-clients.custom-impl.backend.service.js.map +1 -1
  1005. package/dist/esm/security/outbound/outbound-request-deadline.backend.utils.d.ts +39 -0
  1006. package/dist/esm/security/outbound/outbound-request-deadline.backend.utils.d.ts.map +1 -0
  1007. package/dist/esm/security/outbound/outbound-request-deadline.backend.utils.js +60 -0
  1008. package/dist/esm/security/outbound/outbound-request-deadline.backend.utils.js.map +1 -0
  1009. package/dist/esm/security/outbound/outbound-request-headers.backend.utils.d.ts +66 -0
  1010. package/dist/esm/security/outbound/outbound-request-headers.backend.utils.d.ts.map +1 -0
  1011. package/dist/esm/security/outbound/outbound-request-headers.backend.utils.js +75 -0
  1012. package/dist/esm/security/outbound/outbound-request-headers.backend.utils.js.map +1 -0
  1013. package/dist/esm/security/scim/controllers/scim.backend.controller.d.ts.map +1 -1
  1014. package/dist/esm/security/scim/controllers/scim.backend.controller.js.map +1 -1
  1015. package/dist/esm/security/scim/models/scim-protocol.backend.schemas.d.ts.map +1 -1
  1016. package/dist/esm/security/scim/models/scim-protocol.backend.schemas.js.map +1 -1
  1017. package/dist/esm/security/scim/utils/scim-attribute-path-resolver.backend.utils.d.ts.map +1 -1
  1018. package/dist/esm/security/scim/utils/scim-filter-parser.d.ts.map +1 -1
  1019. package/dist/esm/security/scim/utils/scim-response-formatter.d.ts.map +1 -1
  1020. package/dist/esm/security/session-invalidation-fence.backend.utils.d.ts.map +1 -1
  1021. package/dist/esm/security/ssrf/outbound-target-guard.backend.utils.d.ts.map +1 -1
  1022. package/dist/esm/security/ssrf/outbound-target-guard.backend.utils.js.map +1 -1
  1023. package/dist/esm/security/ssrf/pinned-outbound-fetch.backend.utils.d.ts.map +1 -1
  1024. package/dist/esm/security/ssrf/pinned-outbound-fetch.backend.utils.js.map +1 -1
  1025. package/dist/esm/security/token-invalidation-fence.backend.utils.d.ts.map +1 -1
  1026. package/dist/esm/testing.d.ts.map +1 -1
  1027. package/dist/esm/users/services/inbound-contact-custom-implementation.backend.service.d.ts.map +1 -1
  1028. package/dist/esm/users/services/user-deletion-audit.custom-impl.backend.service.d.ts.map +1 -1
  1029. package/dist/esm/users/services/user-force-password-reset.custom-impl.backend.service.d.ts.map +1 -1
  1030. package/dist/esm/users/services/user-read-retained.custom-impl.backend.service.d.ts.map +1 -1
  1031. package/dist/esm/users/services/user-read-retained.custom-impl.backend.service.js.map +1 -1
  1032. package/dist/esm/users/services/user-role-administration.custom-impl.backend.service.d.ts.map +1 -1
  1033. package/dist/esm/users/services/user-self-custom-implementations.backend.d.ts.map +1 -1
  1034. package/dist/esm/users/services/user-super-admin-floor.custom-impl.backend.service.d.ts.map +1 -1
  1035. package/dist/tsconfig.build.tsbuildinfo +1 -1
  1036. package/package.json +9 -9
  1037. package/dist/esm/external-providers/services/flow-actor-design.backend.service.d.ts +0 -45
  1038. package/dist/esm/external-providers/services/flow-actor-design.backend.service.d.ts.map +0 -1
  1039. package/dist/esm/external-providers/services/flow-actor-design.backend.service.js +0 -22
  1040. package/dist/esm/external-providers/services/flow-actor-design.backend.service.js.map +0 -1
  1041. package/dist/esm/notifications/email/models/email-context-provider.interface.d.ts +0 -0
  1042. package/dist/esm/notifications/email/models/email-context-provider.interface.d.ts.map +0 -0
  1043. package/dist/esm/notifications/email/models/email-context-provider.interface.js +0 -0
  1044. package/dist/esm/notifications/email/models/email-context-provider.interface.js.map +0 -0
  1045. package/dist/esm/notifications/email/services/email-context-provider-registry.backend.service.d.ts +0 -0
  1046. package/dist/esm/notifications/email/services/email-context-provider-registry.backend.service.d.ts.map +0 -0
  1047. package/dist/esm/notifications/email/services/email-context-provider-registry.backend.service.js +0 -0
  1048. package/dist/esm/notifications/email/services/email-context-provider-registry.backend.service.js.map +0 -0
  1049. package/dist/esm/notifications/email/services/email-template-compiler.backend.service.d.ts +0 -0
  1050. package/dist/esm/notifications/email/services/email-template-compiler.backend.service.d.ts.map +0 -0
  1051. package/dist/esm/notifications/email/services/email-template-compiler.backend.service.js +0 -0
  1052. package/dist/esm/notifications/email/services/email-template-compiler.backend.service.js.map +0 -0
  1053. package/dist/esm/notifications/email/services/email-template-sandbox.backend.service.d.ts +0 -0
  1054. package/dist/esm/notifications/email/services/email-template-sandbox.backend.service.d.ts.map +0 -0
  1055. package/dist/esm/notifications/email/services/email-template-sandbox.backend.service.js +0 -0
  1056. package/dist/esm/notifications/email/services/email-template-sandbox.backend.service.js.map +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"sms.backend.service.js","sourceRoot":"","sources":["../../../../../../src/notifications/sms/services/sms.backend.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;;;;;;;;;;;;;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,gDAAgD,CAAC;AAGpF,OAAO,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,MAAM,8EAA8E,CAAC;AAGhJ,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACrF,OAAO,EACL,sCAAsC,EAGtC,2BAA2B,GAC5B,MAAM,sCAAsC,CAAC;AAqB9C,SAAS,mBAAmB,CAAC,WAAmB;IAC9C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAGpC,CAAC;QACF,IACE,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ;eAClC,MAAM,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC;eAC5B,OAAO,MAAM,CAAC,SAAS,KAAK,QAAQ;eACpC,MAAM,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAC9B,CAAC;YACD,OAAO;gBACL,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,SAAS,EAAE,MAAM,CAAC,SAAS;aAC5B,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,6CAA6C;IAC/C,CAAC;IAED,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC,GAAG,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC;QACvD,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;QAC3B,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAC9B,IAAI,UAAU,IAAI,SAAS,EAAE,CAAC;QAC5B,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC;IACnC,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,gFAAgF;AAChF,UAAU;AACV,gFAAgF;AAGzE,IAAM,iBAAiB,GAAvB,MAAM,iBAAiB;IAI0B;IACa;IACH;IACgB;IANtE,QAAQ,CAA+D;IAEjF,YACsD,MAAqB,EACR,YAAwC,EAC3C,aAAsC,EACtB,yBAAkE;QAH5F,WAAM,GAAN,MAAM,CAAe;QACR,iBAAY,GAAZ,YAAY,CAA4B;QAC3C,kBAAa,GAAb,aAAa,CAAyB;QACtB,8BAAyB,GAAzB,yBAAyB,CAAyC;QAEhJ,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,mBAAmB,CAAC,CAAC;IAC/D,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,IAAI,CAAC,EAAU,EAAE,IAAY,EAAE,IAAa;QACvD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE7B,IAAI,CAAC;YACH,0BAA0B;YAC1B,MAAM,cAAc,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAEjD,4BAA4B;YAC5B,MAAM,OAAO,GAA4B;gBACvC,EAAE;gBACF,IAAI;gBACJ,IAAI,EAAE,IAAI,IAAI,cAAc,CAAC,UAAU;aACxC,CAAC;YAEF,0BAA0B;YAC1B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,sBAAsB,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;YAE5E,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YAC1C,IAAI,CAAC,QAAQ,CAAC,uBAAuB,EAAE;gBACrC,EAAE;gBACF,UAAU,EAAE,cAAc,CAAC,UAAU;gBACrC,SAAS,EAAE,QAAQ,CAAC,SAAS;gBAC7B,UAAU;aACX,CAAC,CAAC;YAEH,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,SAAS,EAAE,QAAQ,CAAC,SAAS;gBAC7B,UAAU,EAAE,cAAc,CAAC,UAAU;aACtC,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YAC1C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,EAAE;gBACtC,EAAE;gBACF,GAAG,2BAA2B,CAAC,KAAK,CAAC;gBACrC,UAAU;aACX,CAAC,CAAC;YAEH,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,mBAAmB,CAAC,KAAK,CAAC;aAClC,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;OAGG;IACK,kBAAkB;QACxB,MAAM,UAAU,GAAG,IAAI,CAAC,yBAAyB,CAAC,qCAAqC,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC;QAE9G,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAChC,SAAS,CAAC,aAAa,EACvB,SAAS,EACT,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,gDAAgD,EAAE,UAAU,EAAE,gBAAgB,CAAC,GAAG,EAAE,EAAE,CAC7G,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,yBAAyB,CAAC,iBAAiB,CAAC,UAAU,EAAE,sCAAsC,CAAC,YAAY,CAAC,EAAE,CAAC;YACvH,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAChC,SAAS,CAAC,aAAa,EACvB,SAAS,EACT,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,gEAAgE,UAAU,EAAE,EAAE,UAAU,EAAE,EAAE,CACnH,CAAC;QACJ,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,yBAAyB,CAAC,8BAA8B,CAC7E,UAAU,EACV,sCAAsC,CAAC,YAAY,CACpD,CAAC;QACF,MAAM,kBAAkB,GAAG,SAAS;YAClC,CAAC,CAAC,IAAI,CAAC,yBAAyB,CAAC,iBAAiB,CAC9C,UAAU,EACV,sCAAsC,CAAC,YAAY,EACnD,SAAS,CACV;YACH,CAAC,CAAC,SAAS,CAAC;QACd,MAAM,iBAAiB,GAAG,kBAAkB;YAC1C,CAAC,CAAC,mBAAmB,CAAC,kBAAkB,CAAC;YACzC,CAAC,CAAC,IAAI,CAAC;QAET,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACvB,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAChC,SAAS,CAAC,aAAa,EACvB,SAAS,EACT;gBACE,OAAO,EAAE;oBACP,OAAO,EAAE,4DAA4D,UAAU,EAAE;oBACjF,UAAU;oBACV,UAAU,EAAE,gBAAgB,CAAC,GAAG;oBAChC,SAAS;iBACV;aACF,CACF,CAAC;QACJ,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,yBAAyB,CAAC,0BAA0B,CAC3E,UAAU,EACV,sCAAsC,CAAC,YAAY,CACpD,CAAC;QACF,IAAI,WAAW,EAAE,IAAI,KAAK,2BAA2B,CAAC,GAAG,EAAE,CAAC;YAC1D,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAChC,SAAS,CAAC,aAAa,EACvB,SAAS,EACT;gBACE,OAAO,EAAE;oBACP,OAAO,EAAE,wDAAwD,UAAU,EAAE;oBAC7E,UAAU;oBACV,UAAU,EAAE,gBAAgB,CAAC,GAAG;iBACjC;aACF,CACF,CAAC;QACJ,CAAC;QACD,yFAAyF;QACzF,gEAAgE;QAChE,iEAAiE;QACjE,4DAA4D;QAC5D,+DAA+D;QAC/D,gEAAgE;QAChE,+DAA+D;QAC/D,iCAAiC;QACjC,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,MAAiC,CAAC;QACvE,gDAAgD;QAChD,MAAM,eAAe,GAAG,SAAS,EAAE,sBAER,CAAC;QAC5B,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,sCAAsC,CAAC,YAAY,CAAC,CAAC;QAE1G,OAAO;YACL,UAAU;YACV,UAAU,EAAE,iBAAiB,CAAC,UAAU;YACxC,SAAS,EAAE,iBAAiB,CAAC,SAAS;YACtC,QAAQ,EAAE,WAAW,CAAC,OAAO;YAC7B,UAAU,EAAE,YAAY,EAAE,UAAU;SACrC,CAAC;IACJ,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,sBAAsB,CAClC,cAAiC,EACjC,OAAgC;QAEhC,mEAAmE;QACnE,MAAM,GAAG,GAAG,GAAG,cAAc,CAAC,QAAQ,aAAa,cAAc,CAAC,UAAU,gBAAgB,CAAC;QAE7F,0BAA0B;QAC1B,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,UAAU,IAAI,cAAc,CAAC,SAAS,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAE7G,kDAAkD;QAClD,MAAM,QAAQ,GAAG,IAAI,eAAe,CAAC;YACnC,EAAE,EAAE,OAAO,CAAC,EAAE;YACd,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAChD,CAAC,CAAC,QAAQ,EAAE,CAAC;QAEd,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,CAAC,eAAe,CAAC,YAAY,CAAC,EAAE,mCAAmC;gBACnE,CAAC,eAAe,CAAC,aAAa,CAAC,EAAE,SAAS,SAAS,EAAE;aACtD;YACD,IAAI,EAAE,QAAQ;SACf,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACxC,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAChC,SAAS,CAAC,gBAAgB,EAC1B,SAAS,EACT;gBACE,OAAO,EAAE;oBACP,OAAO,EAAE,gCAAgC,QAAQ,CAAC,MAAM,EAAE;oBAC1D,UAAU,EAAE,cAAc,CAAC,UAAU;oBACrC,UAAU,EAAE,QAAQ,CAAC,MAAM;oBAC3B,SAAS;iBACV;aACF,CACF,CAAC;QACJ,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,EAA6B,CAAC;QACtE,MAAM,gBAAgB,GAAG,YAAY,CAAC,UAAU,KAAK,SAAS,IAAI,YAAY,CAAC,UAAU,KAAK,IAAI,CAAC;QAEnG,OAAO;YACL,OAAO,EAAE,CAAC,gBAAgB;YAC1B,SAAS,EAAE,MAAM,CAAC,YAAY,CAAC,GAAG,IAAI,YAAY,CAAC,SAAS,IAAI,GAAG,cAAc,CAAC,UAAU,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;YAC7G,MAAM,EAAE,gBAAgB;gBACtB,CAAC,CAAC,QAAQ;gBACV,CAAC,CAAC,OAAO,YAAY,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,MAA4C,CAAC,CAAC,CAAC,SAAS;SACpH,CAAC;IACJ,CAAC;CACF,CAAA;AAvNY,iBAAiB;IAD7B,UAAU,EAAE;IAKR,WAAA,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAA;IACjC,WAAA,MAAM,CAAC,kBAAkB,CAAC,mBAAmB,CAAC,CAAA;IAC9C,WAAA,MAAM,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,CAAA;IAC3C,WAAA,MAAM,CAAC,kBAAkB,CAAC,gCAAgC,CAAC,CAAA;;GAPnD,iBAAiB,CAuN7B","sourcesContent":["/**\n * SMS Backend Service\n *\n * Main service for sending SMS messages. Orchestrates:\n * - Provider resolution via ExternalProvidersRegistryBackendService\n * - The provider's own `SMS_PROVIDER` runtime contract, read from the registry, which supplies the\n * endpoint and the request/response projection\n * - Raw HTTP execution (Basic Auth for Twilio)\n *\n * Mirrors the pattern of EmailBackendService for consistency.\n */\n\nimport { injectable, inject } from 'inversify';\nimport { SAAS_SERVICE_TYPES } from '~wildo-backend-lib/inject/models/service-types';\nimport type { LoggerService } from '~wildo-backend-lib/monitoring/logger/services/logger.service';\nimport type { ErrorBuilderBackendService } from '~wildo-backend-lib/errors/services/error-builder.backend.service';\nimport { describeCaughtError, projectCaughtErrorLogFields } from '~wildo-backend-lib/errors/utils/error-log-level-classification.backend.utils';\nimport type { AppConfigurationService } from '~wildo-backend-lib/config/services/app-configuration.backend.service';\nimport type { ExternalProvidersRegistryBackendService } from '~wildo-backend-lib/external-providers/services/external-providers-registry.backend.service';\nimport { EngineCapability, ErrorType, WildoHeaderKeys } from '@wildo-ai/saas-models';\nimport {\n ExternalProvider_ExchangeProtocol_Kind,\n type StandardSMS_SendRequest,\n type StandardSMS_SendResponse,\n ProviderProtocolRuntimeKind,\n} from '@wildo-ai/external-connectors-models';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// TYPES\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface SMSSendResult {\n success: boolean;\n messageId?: string;\n providerId?: string;\n error?: string;\n}\n\ninterface SMSProviderConfig {\n providerId: string;\n accountSid: string;\n authToken: string;\n endpoint: string;\n fromNumber?: string;\n}\n\nfunction parseSMSCredentials(secretValue: string): { accountSid: string; authToken: string } | null {\n try {\n const parsed = JSON.parse(secretValue) as {\n accountSid?: unknown;\n authToken?: unknown;\n };\n if (\n typeof parsed.accountSid === 'string'\n && parsed.accountSid.length > 0\n && typeof parsed.authToken === 'string'\n && parsed.authToken.length > 0\n ) {\n return {\n accountSid: parsed.accountSid,\n authToken: parsed.authToken,\n };\n }\n } catch {\n // Fallback below handles non-JSON encodings.\n }\n\n const [accountSid, authToken] = secretValue.includes('|')\n ? secretValue.split('|', 2)\n : secretValue.split(':', 2);\n if (accountSid && authToken) {\n return { accountSid, authToken };\n }\n\n return null;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// SERVICE\n// ─────────────────────────────────────────────────────────────────────────────\n\n@injectable()\nexport class SMSBackendService {\n protected 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.ErrorBuilderService) private readonly errorBuilder: ErrorBuilderBackendService,\n @inject(SAAS_SERVICE_TYPES.AppConfigService) private readonly configService: AppConfigurationService,\n @inject(SAAS_SERVICE_TYPES.ExternalProvidersRegistryService) private readonly externalProvidersRegistry: ExternalProvidersRegistryBackendService,\n ) {\n this.logDebug = this.logger.debugByType('SMSBackendService');\n }\n\n /**\n * Send an SMS message.\n *\n * @param to - Recipient phone number in E.164 format\n * @param body - Message body\n * @param from - Optional sender phone number (uses provider default if not set)\n */\n public async send(to: string, body: string, from?: string): Promise<SMSSendResult> {\n const startTime = Date.now();\n\n try {\n // 1. Resolve SMS provider\n const providerConfig = this.resolveSMSProvider();\n\n // 2. Build standard request\n const request: StandardSMS_SendRequest = {\n to,\n body,\n from: from ?? providerConfig.fromNumber,\n };\n\n // 3. Execute via provider\n const response = await this.executeProviderRequest(providerConfig, request);\n\n const durationMs = Date.now() - startTime;\n this.logDebug('SMS sent successfully', {\n to,\n providerId: providerConfig.providerId,\n messageId: response.messageId,\n durationMs,\n });\n\n return {\n success: true,\n messageId: response.messageId,\n providerId: providerConfig.providerId,\n };\n } catch (error) {\n const durationMs = Date.now() - startTime;\n this.logger.error('Failed to send SMS', {\n to,\n ...projectCaughtErrorLogFields(error),\n durationMs,\n });\n\n return {\n success: false,\n error: describeCaughtError(error),\n };\n }\n }\n\n /**\n * Resolve the SMS provider for the SMS capability.\n * Mirrors EmailBackendService.resolveEmailProvider() pattern.\n */\n private resolveSMSProvider(): SMSProviderConfig {\n const providerId = this.externalProvidersRegistry.getPrimaryProviderForEngineCapability(EngineCapability.SMS);\n\n if (!providerId) {\n throw this.errorBuilder.buildError(\n ErrorType.CONFIGURATION,\n undefined,\n { context: { message: 'No SMS provider configured for capability: SMS', capability: EngineCapability.SMS } }\n );\n }\n\n if (!this.externalProvidersRegistry.isProviderEnabled(providerId, ExternalProvider_ExchangeProtocol_Kind.SMS_PROVIDER)) {\n throw this.errorBuilder.buildError(\n ErrorType.CONFIGURATION,\n undefined,\n { context: { message: `SMS provider is disabled by external provider configuration: ${providerId}`, providerId } },\n );\n }\n\n const secretRef = this.externalProvidersRegistry.getConfiguredProviderSecretRef(\n providerId,\n ExternalProvider_ExchangeProtocol_Kind.SMS_PROVIDER,\n );\n const encodedCredentials = secretRef\n ? this.externalProvidersRegistry.getProviderSecret(\n providerId,\n ExternalProvider_ExchangeProtocol_Kind.SMS_PROVIDER,\n secretRef,\n )\n : undefined;\n const parsedCredentials = encodedCredentials\n ? parseSMSCredentials(encodedCredentials)\n : null;\n\n if (!parsedCredentials) {\n throw this.errorBuilder.buildError(\n ErrorType.CONFIGURATION,\n undefined,\n {\n context: {\n message: `No env-provided credentials configured for SMS provider: ${providerId}`,\n providerId,\n capability: EngineCapability.SMS,\n secretRef,\n },\n }\n );\n }\n\n const smsContract = this.externalProvidersRegistry.getProviderRuntimeContract(\n providerId,\n ExternalProvider_ExchangeProtocol_Kind.SMS_PROVIDER,\n );\n if (smsContract?.kind !== ProviderProtocolRuntimeKind.SMS) {\n throw this.errorBuilder.buildError(\n ErrorType.CONFIGURATION,\n undefined,\n {\n context: {\n message: `No SMS_PROVIDER runtime contract found for provider: ${providerId}`,\n providerId,\n capability: EngineCapability.SMS,\n },\n }\n );\n }\n // The framework currently ships a single `kind: ProviderProtocolRuntimeKind.SMS` runtime\n // contract (Twilio). The execute-request path below assumes the\n // Twilio REST API shape (`/Accounts/{AccountSid}/Messages.json`,\n // Basic Auth, form-encoded body). When a second SMS adapter\n // arrives, factor the provider-specific request shape into the\n // contract via `sdkFactory` / `buildSendPayload` (mirror of the\n // email surface) — do NOT reintroduce a `provider === '<ref>'`\n // literal at this consumer site.\n const appConfig = this.configService.config as Record<string, unknown>;\n // Get optional from number from provider config\n const providersConfig = appConfig?.providerConfigurations as Record<string, Record<string, {\n fromNumber?: string;\n }> | undefined> | undefined;\n const providerConf = providersConfig?.[providerId]?.[ExternalProvider_ExchangeProtocol_Kind.SMS_PROVIDER];\n\n return {\n providerId,\n accountSid: parsedCredentials.accountSid,\n authToken: parsedCredentials.authToken,\n endpoint: smsContract.baseUrl,\n fromNumber: providerConf?.fromNumber,\n };\n }\n\n /**\n * Execute the SMS send request via provider.\n * Uses raw fetch() with Basic Auth for Twilio's REST API (form-encoded).\n */\n private async executeProviderRequest(\n providerConfig: SMSProviderConfig,\n request: StandardSMS_SendRequest\n ): Promise<StandardSMS_SendResponse> {\n // Build the URL (Twilio uses /Accounts/{AccountSid}/Messages.json)\n const url = `${providerConfig.endpoint}/Accounts/${providerConfig.accountSid}/Messages.json`;\n\n // Build Basic Auth header\n const basicAuth = Buffer.from(`${providerConfig.accountSid}:${providerConfig.authToken}`).toString('base64');\n\n // Build form-encoded body from transformer output\n const formBody = new URLSearchParams({\n To: request.to,\n Body: request.body,\n ...(request.from ? { From: request.from } : {}),\n }).toString();\n\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n [WildoHeaderKeys.CONTENT_TYPE]: 'application/x-www-form-urlencoded',\n [WildoHeaderKeys.AUTHORIZATION]: `Basic ${basicAuth}`,\n },\n body: formBody,\n });\n\n if (!response.ok) {\n const errorBody = await response.text();\n throw this.errorBuilder.buildError(\n ErrorType.EXTERNAL_SERVICE,\n undefined,\n {\n context: {\n message: `SMS provider returned error: ${response.status}`,\n providerId: providerConfig.providerId,\n statusCode: response.status,\n errorBody,\n }\n }\n );\n }\n\n const responseData = await response.json() as Record<string, unknown>;\n const hasProviderError = responseData.error_code !== undefined && responseData.error_code !== null;\n\n return {\n success: !hasProviderError,\n messageId: String(responseData.sid ?? responseData.messageId ?? `${providerConfig.providerId}-${Date.now()}`),\n status: hasProviderError\n ? 'failed'\n : typeof responseData.status === 'string' ? responseData.status as StandardSMS_SendResponse['status'] : undefined,\n };\n }\n}\n"]}
1
+ {"version":3,"file":"sms.backend.service.js","sourceRoot":"","sources":["../../../../../src/notifications/sms/services/sms.backend.service.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * SMS Backend Service\n *\n * Sends one transactional SMS. Orchestrates:\n * - provider resolution via `ExternalProvidersRegistryBackendService`\n * - the provider's own `SMS_PROVIDER` runtime contract, read from the registry\n * - HTTP transport\n *\n * ## The line between engine and provider\n *\n * Until 2026-09-09 this service narrowed the runtime contract to\n * `kind: ProviderProtocolRuntimeKind.SMS` — a PROTOCOL many providers can speak — and then built\n * TWILIO's request unconditionally: `/Accounts/{AccountSid}/Messages.json`, Basic auth, a\n * form-encoded `To`/`Body`/`From` body, a response read for `sid` and `error_code`. A second\n * provider declaring `SMS_PROVIDER` would have been sent through Twilio's API carrying its own\n * credentials, and nothing would have refused it or logged it.\n *\n * It now mirrors `EmailBackendService`, which is the arm this problem already has a solved shape\n * for: the provider declares PURE FUNCTIONS on its contract and the engine owns transport.\n *\n * ENGINE (here) — resolve the secret, parse it per the declared `auth.credentialShape`,\n * compose the `Authorization` header, substitute `{accountId}` into the\n * contract's `sendEndpointPath`, issue the request, and validate the\n * provider's parsed response against `StandardSMS_SendResponseSchema`.\n * PROVIDER — the endpoint path shape, the request body and its `content-type`, and the\n * projection of the vendor response onto `StandardSMS_SendResponse`.\n *\n * There is deliberately no consumer-side adapter registry of the kind billing uses. That shape\n * exists only because a billing adapter is a CLASS in this package, which the provider package\n * cannot reach without a reverse dependency edge; an SMS provider owes functions over\n * `@wildo-ai/external-connectors-models` types, which it can supply directly.\n *\n * Every refusal below names the provider, so a misconfigured or unsupported second provider is a\n * legible failure rather than a silent send through somebody else's API.\n */\n\nimport { injectable, inject } from 'inversify';\nimport { SAAS_SERVICE_TYPES } from '~wildo-backend-lib/inject/models/service-types';\nimport type { LoggerService } from '~wildo-backend-lib/monitoring/logger/services/logger.service';\nimport type { ErrorBuilderBackendService } from '~wildo-backend-lib/errors/services/error-builder.backend.service';\nimport { describeCaughtError, projectCaughtErrorLogFields } from '~wildo-backend-lib/errors/utils/error-log-level-classification.backend.utils';\nimport type { AppConfigurationService } from '~wildo-backend-lib/config/services/app-configuration.backend.service';\nimport type { ExternalProvidersRegistryBackendService } from '~wildo-backend-lib/external-providers/services/external-providers-registry.backend.service';\nimport { EngineCapability, ErrorType, WildoHeaderKeys } from '@wildo-ai/saas-models';\nimport {\n ExternalProvider_ExchangeProtocol_Kind,\n SmsProviderCredentialShape,\n StandardSMS_SendResponseSchema,\n type StandardSMS_SendRequest,\n type StandardSMS_SendResponse,\n ProviderProtocolRuntimeKind,\n} from '@wildo-ai/external-connectors-models';\nimport type {\n SmsProviderSendRequest,\n SmsProviderSendResponseInput,\n} from '@wildo-ai/external-connectors-private/backend';\nimport { SMS_PROVIDER_TRANSPORT_TIMEOUT_MS } from '~wildo-backend-lib/notifications/sms/models/sms-transport.backend.definitions';\nimport { readResponseTextWithinDeadline } from '~wildo-backend-lib/security/outbound/outbound-request-deadline.backend.utils';\nimport { withEngineOwnedHeaders } from '~wildo-backend-lib/security/outbound/outbound-request-headers.backend.utils';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// TYPES\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface SMSSendResult {\n success: boolean;\n messageId?: string;\n providerId?: string;\n error?: string;\n}\n\n/**\n * A resolved SMS provider, carrying NO vendor-specific field.\n *\n * Contrast the shape this replaced, which held `accountSid` and `authToken` — Twilio's credential\n * parts, named in Twilio's words, on a type every SMS provider had to pass through. Those names\n * were the tell that one vendor's shape had become the framework's.\n */\ninterface SMSProviderConfig {\n providerId: string;\n /** Fully composed send URL: `baseUrl` + `sendEndpointPath`, with every token substituted. */\n endpoint: string;\n /** Value for the `Authorization` header, composed by the engine from the declared shape. */\n authorizationHeaderValue: string;\n buildSendRequest: (request: StandardSMS_SendRequest) => SmsProviderSendRequest;\n parseSendResponse: (response: SmsProviderSendResponseInput) => StandardSMS_SendResponse;\n fromNumber?: string;\n}\n\n/**\n * What the engine derives from a resolved secret, once it knows the declared shape.\n *\n * Both halves come out of ONE exhaustive `switch`, deliberately: authentication and path\n * substitution are two consequences of the same credential, and splitting them into two switches\n * is how a new shape comes to be handled in one place and not the other.\n *\n * `pathTokens` never carries secret material — an account identifier appears in a URL, a secret\n * must not.\n */\ninterface SMSResolvedCredential {\n authorizationHeaderValue: string;\n pathTokens: Readonly<Record<string, string>>;\n}\n\n/** Any `{token}` the contract's `sendEndpointPath` may carry. */\nconst ENDPOINT_PATH_TOKEN_PATTERN = /\\{([a-zA-Z0-9_]+)\\}/g;\n\n/**\n * Split a two-part credential bundle on the FIRST occurrence of `separator`, keeping the whole\n * remainder as the second part.\n *\n * `String.prototype.split(sep, 2)` truncates rather than keeping the remainder — `'a:b:c'` yields\n * `['a', 'b']` and silently drops `':c'` — so the previous implementation would have mangled any\n * secret containing the separator. Twilio's auth tokens are hex, which is why it never bit.\n */\nfunction splitOnFirst(value: string, separator: string): [string, string] | null {\n const index = value.indexOf(separator);\n if (index <= 0 || index === value.length - 1) {\n return null;\n }\n return [value.slice(0, index), value.slice(index + separator.length)];\n}\n\n/**\n * Parse an `ACCOUNT_ID_AND_SECRET` bundle out of the resolved secret value.\n *\n * Three operator-facing encodings are accepted, in order: a JSON object, `<accountId>|<secret>`,\n * and `<accountId>:<secret>`. They are the ENV VAR's format, not a per-provider branch — every\n * provider declaring this credential shape reads the same three.\n *\n * The JSON object accepts the SHAPE's own field names (`accountId` / `secret`) and, as an alias,\n * Twilio's (`accountSid` / `authToken`). The alias is there because deployments already hold\n * `TWILIO_CREDENTIALS` in that form and breaking every environment buys nothing; the generic names\n * are preferred because a shape called `ACCOUNT_ID_AND_SECRET` whose only object encoding spoke one\n * vendor's vocabulary would be the same defect this whole change removes, one level down — a second\n * provider declaring this shape would have had to tell its operator to write Twilio's key names.\n */\nfunction parseAccountIdAndSecret(secretValue: string): { accountId: string; secret: string } | null {\n try {\n const parsed = JSON.parse(secretValue) as {\n accountId?: unknown; secret?: unknown; accountSid?: unknown; authToken?: unknown;\n };\n const accountId = typeof parsed.accountId === 'string' && parsed.accountId.length > 0\n ? parsed.accountId\n : (typeof parsed.accountSid === 'string' && parsed.accountSid.length > 0 ? parsed.accountSid : undefined);\n const secret = typeof parsed.secret === 'string' && parsed.secret.length > 0\n ? parsed.secret\n : (typeof parsed.authToken === 'string' && parsed.authToken.length > 0 ? parsed.authToken : undefined);\n if (accountId !== undefined && secret !== undefined) {\n return { accountId, secret };\n }\n } catch {\n // Not JSON; the delimited encodings below are the fallback.\n }\n\n const parts = splitOnFirst(secretValue, '|') ?? splitOnFirst(secretValue, ':');\n return parts ? { accountId: parts[0], secret: parts[1] } : null;\n}\n\n/**\n * Derive the authorization header and the substitutable path tokens for a declared credential\n * shape, or `null` when the resolved secret does not parse to that shape.\n *\n * The `never` check is what makes this the enforcement point for the whole arm: a member added to\n * `SmsProviderCredentialShape` without a branch here fails COMPILATION, so the vocabulary cannot\n * grow a member the engine is unable to authenticate.\n */\nfunction resolveSMSCredential(\n credentialShape: SmsProviderCredentialShape,\n secretValue: string,\n): SMSResolvedCredential | null {\n switch (credentialShape) {\n case SmsProviderCredentialShape.ACCOUNT_ID_AND_SECRET: {\n const parsed = parseAccountIdAndSecret(secretValue);\n if (!parsed) {\n return null;\n }\n return {\n // spec-cite: RFC 7617 §2 — Basic credentials are the base64 of `user-id \":\" password`,\n // carried in the `Authorization` header.\n authorizationHeaderValue: `Basic ${Buffer.from(`${parsed.accountId}:${parsed.secret}`).toString('base64')}`,\n // The identifier only. The secret half never reaches a URL.\n pathTokens: { accountId: parsed.accountId },\n };\n }\n default: {\n const exhaustiveCheck: never = credentialShape;\n return exhaustiveCheck;\n }\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// SERVICE\n// ─────────────────────────────────────────────────────────────────────────────\n\n@injectable()\nexport class SMSBackendService {\n protected 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.ErrorBuilderService) private readonly errorBuilder: ErrorBuilderBackendService,\n @inject(SAAS_SERVICE_TYPES.AppConfigService) private readonly configService: AppConfigurationService,\n @inject(SAAS_SERVICE_TYPES.ExternalProvidersRegistryService) private readonly externalProvidersRegistry: ExternalProvidersRegistryBackendService,\n ) {\n this.logDebug = this.logger.debugByType('SMSBackendService');\n }\n\n /**\n * Send an SMS message.\n *\n * @param to - Recipient phone number in E.164 format\n * @param body - Message body\n * @param from - Optional sender phone number (uses provider default if not set)\n */\n public async send(to: string, body: string, from?: string): Promise<SMSSendResult> {\n const startTime = Date.now();\n\n try {\n // 1. Resolve SMS provider\n const providerConfig = this.resolveSMSProvider();\n\n // 2. Build standard request\n const request: StandardSMS_SendRequest = {\n to,\n body,\n from: from ?? providerConfig.fromNumber,\n };\n\n // 3. Execute via provider\n const response = await this.executeProviderRequest(providerConfig, request);\n\n const durationMs = Date.now() - startTime;\n this.logDebug('SMS sent successfully', {\n to,\n providerId: providerConfig.providerId,\n messageId: response.messageId,\n durationMs,\n });\n\n return {\n success: true,\n messageId: response.messageId,\n providerId: providerConfig.providerId,\n };\n } catch (error) {\n const durationMs = Date.now() - startTime;\n this.logger.error('Failed to send SMS', {\n to,\n ...projectCaughtErrorLogFields(error),\n durationMs,\n });\n\n return {\n success: false,\n error: describeCaughtError(error),\n };\n }\n }\n\n /**\n * Resolve the SMS provider for the SMS capability, reading every vendor-specific decision off\n * the provider's own runtime contract.\n *\n * Mirrors `EmailBackendService.resolveEmailProvider()`.\n */\n private resolveSMSProvider(): SMSProviderConfig {\n const providerId = this.externalProvidersRegistry.getPrimaryProviderForEngineCapability(EngineCapability.SMS);\n\n if (!providerId) {\n throw this.errorBuilder.buildError(\n ErrorType.CONFIGURATION,\n undefined,\n { context: { message: 'No SMS provider configured for capability: SMS', capability: EngineCapability.SMS } }\n );\n }\n\n if (!this.externalProvidersRegistry.isProviderEnabled(providerId, ExternalProvider_ExchangeProtocol_Kind.SMS_PROVIDER)) {\n throw this.errorBuilder.buildError(\n ErrorType.CONFIGURATION,\n undefined,\n { context: { message: `SMS provider is disabled by external provider configuration: ${providerId}`, providerId } },\n );\n }\n\n const smsContract = this.externalProvidersRegistry.getProviderRuntimeContract(\n providerId,\n ExternalProvider_ExchangeProtocol_Kind.SMS_PROVIDER,\n );\n if (smsContract?.kind !== ProviderProtocolRuntimeKind.SMS) {\n throw this.errorBuilder.buildError(\n ErrorType.CONFIGURATION,\n undefined,\n {\n context: {\n message: `No SMS_PROVIDER runtime contract found for provider: ${providerId}`,\n providerId,\n capability: EngineCapability.SMS,\n },\n }\n );\n }\n\n /*\n * A contract that reached the registry without an executable request shape.\n *\n * This is NOT belt-and-braces on top of the type system, and it must not be deleted as such.\n * A provider reaches a running application through a COMPANION CONTRIBUTION, and that wire\n * record is deliberately permissive at both ends:\n * `ProviderCompanionContributionSchema` (`@wildo-ai/saas-models`,\n * `src/companion/provider-discovery.shared.schemas.ts:120`) is a `z.looseObject` so a record\n * from a package version this repository never compiled rides through instead of failing the\n * parse, it announces its `protocols` as bare strings rather than the typed enum, and its\n * `runtimeImportPath` is resolved and imported at runtime. So the module supplying an SMS\n * contract can be one no compilation here ever checked.\n *\n * Without this guard that case is a `TypeError` from inside transport naming no provider.\n * With it, the compile-time requirement on the arm and this refusal together are what make\n * \"never silently handed another vendor's shape\" true for every declarer, not only the ones\n * built in this repository.\n */\n if (typeof smsContract.buildSendRequest !== 'function' || typeof smsContract.parseSendResponse !== 'function') {\n throw this.errorBuilder.buildError(\n ErrorType.CONFIGURATION,\n undefined,\n {\n context: {\n message: `SMS provider declares no send-request shape and cannot be used: ${providerId}. `\n + 'Its SMS_PROVIDER runtime contract must declare buildSendRequest and parseSendResponse.',\n providerId,\n capability: EngineCapability.SMS,\n },\n }\n );\n }\n\n const secretRef = this.externalProvidersRegistry.getConfiguredProviderSecretRef(\n providerId,\n ExternalProvider_ExchangeProtocol_Kind.SMS_PROVIDER,\n );\n const encodedCredentials = secretRef\n ? this.externalProvidersRegistry.getProviderSecret(\n providerId,\n ExternalProvider_ExchangeProtocol_Kind.SMS_PROVIDER,\n secretRef,\n )\n : undefined;\n const credential = encodedCredentials\n ? resolveSMSCredential(smsContract.auth.credentialShape, encodedCredentials)\n : null;\n\n if (!credential) {\n throw this.errorBuilder.buildError(\n ErrorType.CONFIGURATION,\n undefined,\n {\n context: {\n message: `No usable credentials configured for SMS provider: ${providerId}`,\n providerId,\n capability: EngineCapability.SMS,\n secretRef,\n // The SHAPE, never the value: it is what an operator needs to fix the env var.\n credentialShape: smsContract.auth.credentialShape,\n },\n }\n );\n }\n\n const endpoint = this.composeSendEndpoint(providerId, smsContract.baseUrl, smsContract.sendEndpointPath, credential.pathTokens);\n\n const appConfig = this.configService.config as Record<string, unknown>;\n // Get optional from number from provider config\n const providersConfig = appConfig?.providerConfigurations as Record<string, Record<string, {\n fromNumber?: string;\n }> | undefined> | undefined;\n const providerConf = providersConfig?.[providerId]?.[ExternalProvider_ExchangeProtocol_Kind.SMS_PROVIDER];\n\n return {\n providerId,\n endpoint,\n authorizationHeaderValue: credential.authorizationHeaderValue,\n buildSendRequest: smsContract.buildSendRequest,\n parseSendResponse: smsContract.parseSendResponse,\n fromNumber: providerConf?.fromNumber,\n };\n }\n\n /**\n * Compose the send URL from the contract's `baseUrl` and `sendEndpointPath`, substituting the\n * tokens the resolved credential supplies.\n *\n * Refuses a path still holding a `{token}` afterwards. There is no declared token LIST to check\n * against — this check IS the validation, and it is stronger than a list because it cannot drift\n * from what substitution actually produced. A misspelled token would otherwise travel to the\n * vendor as a literal path segment and come back as an opaque 404.\n */\n private composeSendEndpoint(\n providerId: string,\n baseUrl: string,\n sendEndpointPath: string,\n pathTokens: Readonly<Record<string, string>>,\n ): string {\n const substituted = sendEndpointPath.replace(\n ENDPOINT_PATH_TOKEN_PATTERN,\n (literal, token: string) => pathTokens[token] ?? literal,\n );\n\n const unsubstituted = substituted.match(ENDPOINT_PATH_TOKEN_PATTERN);\n if (unsubstituted) {\n throw this.errorBuilder.buildError(\n ErrorType.CONFIGURATION,\n undefined,\n {\n context: {\n message: `SMS provider declares an endpoint path with unsubstitutable tokens: ${providerId}`,\n providerId,\n sendEndpointPath,\n unsubstitutedTokens: unsubstituted,\n },\n }\n );\n }\n\n return `${baseUrl}${substituted}`;\n }\n\n /**\n * Issue the provider's own request and project its response.\n *\n * Every vendor-specific decision here comes off the contract. The engine contributes the\n * `Authorization` header and nothing else.\n *\n * That last promise is delivered by `withEngineOwnedHeaders`, and NOT by the ordering this JSDoc\n * used to cite. Until 2026-09-09 it read \"it is applied AFTER the provider's transport headers,\n * so a provider cannot take authentication over by naming that header\" — true only of an\n * identical spelling. Header names are case-insensitive on the wire and case-SENSITIVE as object\n * keys, so a provider naming `Authorization` against the engine's `authorization` produced two\n * keys that `fetch` combines into one comma-joined value, authenticating with neither. The shared\n * helper drops every spelling of an engine-owned name before the engine's own value is applied.\n */\n private async executeProviderRequest(\n providerConfig: SMSProviderConfig,\n request: StandardSMS_SendRequest\n ): Promise<StandardSMS_SendResponse> {\n const providerRequest = providerConfig.buildSendRequest(request);\n\n /*\n * THE DEADLINE, and it stays armed through response-body consumption.\n *\n * This request had no bound at all until 2026-09-09. It is reached synchronously from phone\n * verification and the SMS second factor, so a vendor that accepts a connection and then never\n * answers held a sign-in open for as long as the socket lived — Node's `fetch` imposes no\n * timeout of its own, and nothing above this frame imposed one either.\n *\n * `clearTimeout` sits in a `finally` that wraps BOTH the request and the body read, which is\n * the half that is easy to lose: a provider that returns headers and then stalls its body\n * retains the request exactly as effectively as one that never returns at all.\n */\n const abortController = new AbortController();\n const timeoutHandle = setTimeout(\n () => abortController.abort(\n new Error(`SMS provider request exceeded ${SMS_PROVIDER_TRANSPORT_TIMEOUT_MS}ms`),\n ),\n SMS_PROVIDER_TRANSPORT_TIMEOUT_MS,\n );\n\n let response: Response;\n let responseText: string;\n try {\n response = await fetch(providerConfig.endpoint, {\n method: 'POST',\n headers: withEngineOwnedHeaders(providerRequest.transportHeaders, {\n [WildoHeaderKeys.AUTHORIZATION]: providerConfig.authorizationHeaderValue,\n }),\n body: providerRequest.body,\n signal: abortController.signal,\n });\n\n responseText = await readResponseTextWithinDeadline(response, abortController.signal);\n } finally {\n clearTimeout(timeoutHandle);\n }\n\n const parserInput: SmsProviderSendResponseInput = {\n status: response.status,\n headers: this.responseHeadersToRecord(response.headers),\n body: this.bestEffortParseResponseBody(responseText),\n };\n\n /*\n * The provider decides acceptance, and the engine holds it to the standard shape.\n *\n * Both halves matter. Twilio reports a per-message failure inside a 2xx body, so an HTTP-status\n * check alone is not an answer — that is why the decision is the provider's. And the validation\n * replaces an unchecked `responseData.status as StandardSMS_SendResponse['status']` that let any\n * string through: Twilio's own `accepted` would have landed in a field whose vocabulary does not\n * contain it.\n */\n const parsed = StandardSMS_SendResponseSchema.safeParse(\n providerConfig.parseSendResponse(parserInput),\n );\n if (!parsed.success) {\n throw this.errorBuilder.buildError(\n ErrorType.EXTERNAL_SERVICE,\n undefined,\n {\n context: {\n message: `SMS provider response parser violated StandardSMS_SendResponse: ${providerConfig.providerId}`,\n providerId: providerConfig.providerId,\n statusCode: response.status,\n validationError: parsed.error.message,\n },\n }\n );\n }\n\n if (!parsed.data.success) {\n throw this.errorBuilder.buildError(\n ErrorType.EXTERNAL_SERVICE,\n undefined,\n {\n context: {\n message: `SMS provider rejected the message: ${providerConfig.providerId}`,\n providerId: providerConfig.providerId,\n statusCode: response.status,\n errorBody: responseText,\n }\n }\n );\n }\n\n return parsed.data;\n }\n\n /** Lower-cased header projection, so a provider's parser can index headers by a stable name. */\n private responseHeadersToRecord(headers: Headers): Record<string, string> {\n const result: Record<string, string> = {};\n headers.forEach((value, key) => {\n result[key.toLowerCase()] = value;\n });\n return result;\n }\n\n /**\n * Decode a response body without assuming it is JSON. A vendor error page is frequently HTML or\n * plain text, and handing the raw string to the provider's parser is more useful than throwing\n * before it gets a chance to classify.\n */\n private bestEffortParseResponseBody(responseText: string): unknown {\n if (responseText.length === 0) {\n return undefined;\n }\n try {\n return JSON.parse(responseText);\n } catch {\n return responseText;\n }\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"webhook-auto-controller.backend.service.d.ts","sourceRoot":"","sources":["../../../../../../src/notifications/webhooks/controllers/webhook-auto-controller.backend.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAKH,OAAO,EAGL,KAAK,wBAAwB,EAC9B,MAAM,sCAAsC,CAAC;AAI9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8DAA8D,CAAC;AAClG,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,kEAAkE,CAAC;AACnH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kEAAkE,CAAC;AAC5G,OAAO,KAAK,EAAE,qCAAqC,EAAE,MAAM,0FAA0F,CAAC;AACtJ,OAAO,KAAK,EAAE,uCAAuC,EAAE,MAAM,4FAA4F,CAAC;AAC1J,OAAO,EAAE,gCAAgC,EAAE,MAAM,0FAA0F,CAAC;AAC5I,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,oFAAoF,CAAC;AAEvI;;;;;;;GAOG;AACH,oBAAY,6BAA6B;IACvC;;;;OAIG;IACH,qBAAqB,0BAA0B;IAC/C;;;;OAIG;IACH,mBAAmB,wBAAwB;CAC5C;AAED,+EAA+E;AAC/E,MAAM,WAAW,uBAAuB;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,6BAA6B,EAAE,CAAC;CAC1C;AAED,qBACa,mCAAoC,SAAQ,gCAAgC;IAoC1B,OAAO,CAAC,QAAQ,CAAC,uBAAuB;IACtC,OAAO,CAAC,QAAQ,CAAC,yBAAyB;IAnCzG,uEAAuE;IACvE,OAAO,CAAC,kBAAkB,CAA+C;IAEzE,OAAO,CAAC,cAAc,CAA6C;IAEnE;;;;OAIG;IACH,OAAO,CAAC,eAAe,CAAsC;IAE7D,2EAA2E;IAC3E,OAAO,CAAC,oBAAoB,CAAgB;IAE5C;;;;OAIG;IACH,OAAO,CAAC,cAAc,CAAiC;IAEvD;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB,CAAS;gBAGI,MAAM,EAAE,aAAa,EACR,YAAY,EAAE,0BAA0B,EACxC,YAAY,EAAE,mBAAmB,EACL,uBAAuB,EAAE,qCAAqC,EAC5D,yBAAyB,EAAE,uCAAuC;IASlJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACU,UAAU,CACrB,cAAc,EAAE,4BAA4B,GAC3C,OAAO,CAAC,IAAI,CAAC;IAuDhB;;;;;;;;;;;;;OAaG;IACH,yBAAyB,CAAC,OAAO,EAAE,wBAAwB,GAAG,IAAI;IAoBlE;;;;OAIG;IACI,8BAA8B,IAAI,aAAa,CAAC,MAAM,CAAC;IAI9D;;;;OAIG;IACI,wBAAwB,IAAI,aAAa,CAAC,uBAAuB,CAAC;IAQzE;;;;;;;;OAQG;IACH,SAAS,CAAC,WAAW,IAAI,IAAI;IAI7B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6CG;IACH,OAAO,CAAC,qBAAqB;IA8D7B;;;;;;;;OAQG;IACH,OAAO,CAAC,0BAA0B;YAwBpB,oBAAoB;CAqFnC"}
1
+ {"version":3,"file":"webhook-auto-controller.backend.service.d.ts","sourceRoot":"","sources":["../../../../../src/notifications/webhooks/controllers/webhook-auto-controller.backend.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAKH,OAAO,EAGL,KAAK,wBAAwB,EAC9B,MAAM,sCAAsC,CAAC;AAI9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8DAA8D,CAAC;AAClG,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,kEAAkE,CAAC;AACnH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kEAAkE,CAAC;AAC5G,OAAO,KAAK,EAAE,qCAAqC,EAAE,MAAM,0FAA0F,CAAC;AACtJ,OAAO,KAAK,EAAE,uCAAuC,EAAE,MAAM,4FAA4F,CAAC;AAC1J,OAAO,EAAE,gCAAgC,EAAE,MAAM,0FAA0F,CAAC;AAC5I,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,oFAAoF,CAAC;AAEvI;;;;;;;GAOG;AACH,oBAAY,6BAA6B;IACvC;;;;OAIG;IACH,qBAAqB,0BAA0B;IAC/C;;;;OAIG;IACH,mBAAmB,wBAAwB;CAC5C;AAED,+EAA+E;AAC/E,MAAM,WAAW,uBAAuB;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,6BAA6B,EAAE,CAAC;CAC1C;AAED,qBACa,mCAAoC,SAAQ,gCAAgC;IAoC1B,OAAO,CAAC,QAAQ,CAAC,uBAAuB;IACtC,OAAO,CAAC,QAAQ,CAAC,yBAAyB;IAnCzG,uEAAuE;IACvE,OAAO,CAAC,kBAAkB,CAA+C;IAEzE,OAAO,CAAC,cAAc,CAA6C;IAEnE;;;;OAIG;IACH,OAAO,CAAC,eAAe,CAAsC;IAE7D,2EAA2E;IAC3E,OAAO,CAAC,oBAAoB,CAAgB;IAE5C;;;;OAIG;IACH,OAAO,CAAC,cAAc,CAAiC;IAEvD;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB,CAAS;gBAGI,MAAM,EAAE,aAAa,EACR,YAAY,EAAE,0BAA0B,EACxC,YAAY,EAAE,mBAAmB,EACL,uBAAuB,EAAE,qCAAqC,EAC5D,yBAAyB,EAAE,uCAAuC;IASlJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACU,UAAU,CACrB,cAAc,EAAE,4BAA4B,GAC3C,OAAO,CAAC,IAAI,CAAC;IAuDhB;;;;;;;;;;;;;OAaG;IACH,yBAAyB,CAAC,OAAO,EAAE,wBAAwB,GAAG,IAAI;IAoBlE;;;;OAIG;IACI,8BAA8B,IAAI,aAAa,CAAC,MAAM,CAAC;IAI9D;;;;OAIG;IACI,wBAAwB,IAAI,aAAa,CAAC,uBAAuB,CAAC;IAQzE;;;;;;;;OAQG;IACH,SAAS,CAAC,WAAW,IAAI,IAAI;IAI7B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6CG;IACH,OAAO,CAAC,qBAAqB;IA8D7B;;;;;;;;OAQG;IACH,OAAO,CAAC,0BAA0B;YAwBpB,oBAAoB;CAqFnC"}
@@ -1 +1 @@
1
- {"version":3,"file":"webhook-auto-controller.backend.service.js","sourceRoot":"","sources":["../../../../../../src/notifications/webhooks/controllers/webhook-auto-controller.backend.service.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Webhook Auto-Controller Backend Service\n *\n * Auto-registers webhook routes from provider registry definitions.\n * At startup, iterates all providers with WEBHOOK_ORIGINATOR protocol,\n * then iterates each provider's endpoints, and registers:\n * POST /webhooks/{providerRef}/{endpointKey}\n *\n * One provider declares the protocol today, and it declares one endpoint:\n * POST /webhooks/stripe/billing\n *\n * A second provider registers here the moment it declares `WEBHOOK_ORIGINATOR` with its own\n * `endpoints`; no edit to this controller is needed.\n *\n * This replaces manual per-provider webhook controllers (like BillingWebhookControllerBackendService).\n *\n * @see hook-protocol-webhook-callback.md\n */\n\nimport { injectable, inject } from 'inversify';\nimport express from 'express';\nimport type { Request, Response, NextFunction } from 'express';\nimport {\n ExternalProvider_ExchangeProtocol_Kind,\n type Hook_Endpoint,\n type WebhookCapabilityHandler,\n} from '@wildo-ai/external-connectors-models';\nimport { HttpMethod } from '@wildo-ai/saas-models';\n\nimport { SAAS_SERVICE_TYPES } from '~wildo-backend-lib/inject/models/service-types';\nimport type { LoggerService } from '~wildo-backend-lib/monitoring/logger/services/logger.service';\nimport type { ErrorBuilderBackendService } from '~wildo-backend-lib/errors/services/error-builder.backend.service';\nimport type { ErrorHandlerService } from '~wildo-backend-lib/errors/services/error-handler.backend.service';\nimport type { BackendProviderRegistryBackendService } from '~wildo-backend-lib/external-providers/services/backend-provider-registry.backend.service';\nimport type { ExternalProvidersRegistryBackendService } from '~wildo-backend-lib/external-providers/services/external-providers-registry.backend.service';\nimport { AbstractControllerBackendService } from '~wildo-backend-lib/base-classes/services/controllers/abstract-controller.backend.service';\nimport type { WebhookHandlerBackendService } from '~wildo-backend-lib/notifications/webhooks/services/webhook-handler.backend.service';\n\n/**\n * Why a declared webhook endpoint did NOT get an Express route.\n *\n * A closed vocabulary rather than a free string: each member names a DIFFERENT\n * missing registration, with a different remedy, and an operator reading the\n * startup log has to be able to tell them apart. The two are independent — an\n * endpoint can be missing either, or both.\n */\nexport enum WebhookRouteWithholdingReason {\n /**\n * No {@link WebhookCapabilityHandler} is registered for the endpoint's\n * `capability`. The route would reach `handleWebhookRequest`, complete\n * signature verification and idempotency claiming, then fail at dispatch.\n */\n NO_CAPABILITY_HANDLER = 'NO_CAPABILITY_HANDLER',\n /**\n * No `WebhookCapabilityAdapter` is registered for `providerRef:endpointKey`\n * on {@link WebhookHandlerBackendService}. The route would fail at the very\n * top of `processWebhook`, before signature verification.\n */\n NO_ENDPOINT_ADAPTER = 'NO_ENDPOINT_ADAPTER',\n}\n\n/** One declared endpoint whose route was deliberately not mounted, and why. */\nexport interface WebhookRouteWithholding {\n providerRef: string;\n endpointKey: string;\n capability: string;\n routePath: string;\n reasons: WebhookRouteWithholdingReason[];\n}\n\n@injectable()\nexport class WebhookAutoControllerBackendService extends AbstractControllerBackendService {\n\n /** Capability handlers keyed by capability string (e.g., 'billing') */\n private capabilityHandlers = new Map<string, WebhookCapabilityHandler>();\n\n private webhookHandler: WebhookHandlerBackendService | null = null;\n\n /**\n * Pre-loaded endpoint configurations per provider.\n * Populated during initialize() from first-class provider runtime contracts.\n * setupRoutes() reads from this cache (sync) to register routes.\n */\n private loadedEndpoints = new Map<string, Hook_Endpoint[]>();\n\n /** Route paths recorded only after Express accepted their registration. */\n private registeredRoutePaths: string[] = [];\n\n /**\n * Declared endpoints whose route was WITHHELD because the capability could\n * not be dispatched. Kept so the decision is inspectable after startup rather\n * than only visible in a log line that has already scrolled past.\n */\n private withheldRoutes: WebhookRouteWithholding[] = [];\n\n /**\n * Set once {@link registerWebhookRoutes} has run. The mount decision is taken\n * ONCE, from the registration state at that instant, so anything registered\n * afterwards cannot change which routes exist — see\n * {@link registerCapabilityHandler}, which refuses to let that be silent.\n */\n private routesRegistered = false;\n\n constructor(\n @inject(SAAS_SERVICE_TYPES.Logger) logger: LoggerService,\n @inject(SAAS_SERVICE_TYPES.ErrorBuilderService) errorBuilder: ErrorBuilderBackendService,\n @inject(SAAS_SERVICE_TYPES.ErrorHandlerService) errorHandler: ErrorHandlerService,\n @inject(SAAS_SERVICE_TYPES.BackendProviderRegistryService) private readonly backendProviderRegistry: BackendProviderRegistryBackendService,\n @inject(SAAS_SERVICE_TYPES.ExternalProvidersRegistryService) private readonly externalProvidersRegistry: ExternalProvidersRegistryBackendService,\n ) {\n super(logger, errorBuilder, errorHandler, 'WebhookAutoController');\n }\n\n // ════════════════════════════════════════════════════════════\n // Initialization\n // ════════════════════════════════════════════════════════════\n\n /**\n * Initialize with required dependencies, pre-load endpoint configs, AND\n * register the webhook routes.\n *\n * ── Why routes are registered HERE, not in `setupRoutes()` ──────────────\n *\n * `AbstractControllerBackendService` calls the abstract `setupRoutes()` hook\n * synchronously from *inside its own constructor* (`super(...)`). At that\n * point this controller has NOTHING to register:\n *\n * 1. The webhook handler is not injected via the constructor — it is\n * supplied to `initialize()` by `start-application` after the billing /\n * provider layers are wired.\n * 2. The route SET is data-dependent (one route per provider webhook\n * endpoint), and those endpoint contracts are only knowable after the\n * provider registries have been initialized (which happens later in the\n * startup sequence than DI construction).\n *\n * So `setupRoutes()` is a deliberate no-op (see its JSDoc) and the real,\n * data-dependent route registration runs here — the same lifecycle shape\n * `ControllerResourceBackendService` uses for its per-resource routes.\n *\n * `start-application` calls this BEFORE the controllers registry mounts the\n * router (via `getRouter()`), so the routes added here are present when the\n * master router mounts this controller's router by reference. Errors thrown\n * from webhook handlers propagate to the app-level error middleware\n * (`HttpServerBackendService`), so no router-scoped error handler is needed\n * after these routes.\n */\n public async initialize(\n webhookHandler: WebhookHandlerBackendService,\n ): Promise<void> {\n this.webhookHandler = webhookHandler;\n\n for (const provider of this.backendProviderRegistry.getProvidersWithProtocol(ExternalProvider_ExchangeProtocol_Kind.WEBHOOK_ORIGINATOR)) {\n const providerRef = provider.metadata.ref;\n try {\n if (\n !this.externalProvidersRegistry.isProviderEnabled(\n providerRef,\n ExternalProvider_ExchangeProtocol_Kind.WEBHOOK_ORIGINATOR,\n )\n ) {\n continue;\n }\n\n const config = this.externalProvidersRegistry.getProviderConfiguration(\n providerRef,\n ExternalProvider_ExchangeProtocol_Kind.WEBHOOK_ORIGINATOR,\n );\n // `config.endpoints` is `ReadonlyArray<Hook_Endpoint>` post the\n // 2026-05-06 webhook endpoint reshape: `Hook_Endpoint.displayName`\n // is now optional (matches the runtime emission) and the dead\n // extras (`providerRef` / `path` / `secretBinding`) were dropped\n // from `buildWebhookEndpoints`. The local cache is a\n // `Map<string, Hook_Endpoint[]>`, so we materialize a mutable\n // copy here — the cache was historically `Hook_Endpoint[]`\n // (mutable); preserving that semantics avoids touching every\n // downstream signature.\n const endpoints: Hook_Endpoint[] = [...(config?.endpoints ?? [])];\n if (endpoints.length > 0) {\n this.loadedEndpoints.set(providerRef, endpoints);\n this.logDebug(`Pre-loaded ${endpoints.length} webhook endpoint(s) for ${providerRef}`);\n } else {\n // Genuine contract fault (not the expected \"no webhook providers\"\n // case): the provider is ENABLED for WEBHOOK_ORIGINATOR yet exposes\n // zero endpoints, so it will silently never receive inbound webhooks\n // (e.g. Stripe would 404 on /webhooks/stripe/billing). Surface it\n // once, clearly — this is a mis-sequence, not steady-state noise.\n this.logger.warn(\n `WebhookAutoController: provider '${providerRef}' is enabled for WEBHOOK_ORIGINATOR but exposes no endpoints — no routes will be registered for it`,\n );\n }\n } catch (error) {\n this.logger.warn(`Failed to pre-load webhook protocol for ${providerRef}`, {\n error: (error as Error).message,\n });\n }\n }\n\n this.logDebug(`Webhook auto-controller initialized with ${this.loadedEndpoints.size} provider(s)`);\n\n // Register the routes now that the handler + endpoint contracts are known.\n this.registerWebhookRoutes();\n }\n\n /**\n * Register a capability handler for dispatching processed events.\n * Called at startup by capability modules (e.g., billing module).\n *\n * MUST be called before {@link initialize}. `start-application` satisfies this\n * ordering today — step 4.5 initializes capability modules (which register\n * here) and step 4.6 initializes this controller — and the guard below exists\n * so a future step inserted the other way round is LOUD instead of silent.\n *\n * The failure it catches is genuinely confusing without it: a late-registered\n * handler works perfectly at request time (the map is read per request), but\n * the route it would serve was already withheld at mount time, so the endpoint\n * answers 404 while a handler for it demonstrably exists.\n */\n registerCapabilityHandler(handler: WebhookCapabilityHandler): void {\n this.capabilityHandlers.set(handler.capability, handler);\n\n if (this.routesRegistered) {\n this.logger.error(\n `WebhookAutoController: capability handler for '${handler.capability}' was registered AFTER webhook routes were mounted. `\n + 'Route mounting is decided once, from the registrations present at that moment, so this handler cannot bring back any route '\n + 'that was withheld for a missing handler — those endpoints will keep answering 404. '\n + 'Register capability handlers before WebhookAutoControllerBackendService.initialize() runs.',\n {\n capability: handler.capability,\n withheldRoutes: this.withheldRoutes.map((withholding) => withholding.routePath),\n },\n );\n return;\n }\n\n this.logDebug(`Registered webhook capability handler for ${handler.capability}`);\n }\n\n /**\n * Return the sanitized inbound-provider routes that this controller actually\n * registered. Provider configuration, signature material, endpoint payloads,\n * and handler metadata are intentionally absent.\n */\n public getRegisteredWebhookRoutePaths(): ReadonlyArray<string> {\n return [...this.registeredRoutePaths];\n }\n\n /**\n * Return the declared endpoints whose route was deliberately NOT mounted,\n * with the reason. Carries no provider configuration or signature material —\n * only the route identity and which registration was missing.\n */\n public getWithheldWebhookRoutes(): ReadonlyArray<WebhookRouteWithholding> {\n return this.withheldRoutes.map((withholding) => ({ ...withholding, reasons: [...withholding.reasons] }));\n }\n\n // ════════════════════════════════════════════════════════════\n // Routes\n // ════════════════════════════════════════════════════════════\n\n /**\n * Required by `AbstractControllerBackendService`, which invokes this hook\n * synchronously from its constructor (`super(...)`). This controller\n * intentionally registers NOTHING here: its route set is data-dependent\n * (one route per provider webhook endpoint) and neither the webhook handler\n * nor the provider endpoint contracts exist at construction time. The real\n * registration happens in `initialize()` / `registerWebhookRoutes()` once\n * that data is available — see `initialize()`'s JSDoc for the full rationale.\n */\n protected setupRoutes(): void {\n // No-op by design — see JSDoc above and `registerWebhookRoutes()`.\n }\n\n /**\n * Register one Express route per pre-loaded provider webhook endpoint —\n * EXCEPT those whose capability cannot actually be dispatched.\n *\n * Invoked from `initialize()` after `webhookHandler` and `loadedEndpoints`\n * have been populated. Idempotent-safe against an empty cache; guards on the\n * handler so a mis-sequenced call fails visibly rather than registering dead\n * routes.\n *\n * ── Why an undispatchable endpoint is WITHHELD rather than mounted ────────\n *\n * A declared endpoint needs two registrations that this controller does not\n * own and cannot create: a `WebhookCapabilityAdapter` (verify + parse, on\n * `WebhookHandlerBackendService`) and a `WebhookCapabilityHandler` (dispatch,\n * here). Both are supplied by the capability module — for `billing`, inside\n * `start-application.initializeBillingServices`, which is deliberately\n * NON-FATAL: if it throws part-way, or if `billing.enabled` is false while the\n * provider is still enabled for `WEBHOOK_ORIGINATOR`, the application boots\n * with the provider's endpoint declared and neither registration present.\n *\n * Mounting a route in that state produces a 500 on every inbound delivery\n * (`No webhook adapter registered for ...`, or `No capability handler for ...`\n * below), and a 500 is precisely the answer that tells a vendor to RETRY — an\n * instruction that can never be satisfied, because no retry supplies a missing\n * startup registration. The endpoint therefore absorbs the vendor's full retry\n * schedule and eventually gets disabled on the vendor's side, while the only\n * local signal is a repeating error log.\n *\n * Not mounting says the true thing instead: this endpoint does not exist. The\n * vendor gets a 404 rather than a retry instruction, and the operator gets one\n * loud, remedy-naming error at startup — the moment the misconfiguration was\n * actually introduced.\n *\n * REJECTED — refusing at BOOT (throwing from here). It is the shape the rest of\n * the registry uses, and it is wrong at this site for three reasons. (1) It\n * would not even be loud: `start-application.initializeWebhookAutoController`\n * wraps `initialize()` in a non-fatal catch that downgrades a throw to a warn,\n * so the net effect would be a quieter log AND the loss of every OTHER\n * provider's working route. (2) It inverts a decision the engine already took\n * explicitly — billing initialization failure is documented as survivable\n * (\"the app can still run without billing\"); a failed optional subsystem must\n * not become a refusal to start. (3) `billing.enabled: false` beside a\n * registered Stripe provider is a COHERENT configuration, and refusing to boot\n * over it would be a false alarm. The check is per-endpoint, so a capability\n * that is wired keeps its route regardless of a sibling that is not.\n */\n private registerWebhookRoutes(): void {\n this.routesRegistered = true;\n\n if (!this.webhookHandler) {\n this.logger.warn('WebhookAutoController: initialize() ran without a webhook handler — no routes registered');\n return;\n }\n\n if (this.loadedEndpoints.size === 0) {\n this.logDebug('No webhook endpoints pre-loaded — no routes registered');\n return;\n }\n\n for (const [providerRef, endpoints] of this.loadedEndpoints) {\n for (const endpoint of endpoints) {\n const routePath = `/webhooks/${providerRef}/${endpoint.key}`;\n\n const withholding = this.assessRouteDispatchability(providerRef, endpoint, routePath);\n if (withholding) {\n this.withheldRoutes.push(withholding);\n this.logger.error(\n `WebhookAutoController: NOT registering POST ${routePath} — the endpoint is declared but cannot be dispatched `\n + `(${withholding.reasons.join(', ')}). A route mounted in this state can only ever answer 500, which instructs the `\n + 'vendor to retry an inbound event that no retry can make processable. Withholding the route so the vendor gets a '\n + '404 instead. Remedy: register the capability module that owns '\n + `'${endpoint.capability}' before WebhookAutoControllerBackendService.initialize() runs (for billing, check whether `\n + 'billing initialization was skipped or failed non-fatally earlier in startup), or disable the WEBHOOK_ORIGINATOR '\n + `protocol for provider '${providerRef}'.`,\n {\n providerRef,\n endpointKey: endpoint.key,\n capability: endpoint.capability,\n routePath,\n reasons: withholding.reasons,\n },\n );\n continue;\n }\n\n this.router.post(\n routePath,\n // Defense-in-depth for a future streaming mount. If this controller is\n // ever assigned the RAW_REQUEST_STREAM mount phase, this express.raw()\n // makes req.body the raw Buffer. Under the\n // current master-router mount it is an inert no-op: the global\n // express.json (HttpServerBackendService.setupBodyParsing) parses the\n // body first and sets req._body, so the signature-faithful bytes come\n // from req.rawBody — captured by that same express.json `verify` hook.\n // handleWebhookRequest reads rawBody first, then falls back to a Buffer\n // req.body for the streaming case.\n express.raw({ type: 'application/json' }),\n this.asyncHandler(async (req: Request, res: Response, _next: NextFunction) => {\n await this.handleWebhookRequest(providerRef, endpoint, req, res);\n }),\n );\n\n this.registeredRoutePaths.push(routePath);\n this.logger.info(`Webhook endpoint registered: POST ${routePath}`);\n }\n }\n }\n\n /**\n * Decide whether a declared endpoint can actually be served, and if not, say\n * which registration is missing.\n *\n * Returns `null` when the route is dispatchable. Both prerequisites are\n * evaluated (rather than short-circuiting on the first) so an operator gets\n * the WHOLE remedy in one log line instead of fixing one registration and\n * meeting the next on the following restart.\n */\n private assessRouteDispatchability(\n providerRef: string,\n endpoint: Hook_Endpoint,\n routePath: string,\n ): WebhookRouteWithholding | null {\n const reasons: WebhookRouteWithholdingReason[] = [];\n\n if (!this.capabilityHandlers.has(endpoint.capability)) {\n reasons.push(WebhookRouteWithholdingReason.NO_CAPABILITY_HANDLER);\n }\n if (!this.webhookHandler?.hasAdapter(providerRef, endpoint.key)) {\n reasons.push(WebhookRouteWithholdingReason.NO_ENDPOINT_ADAPTER);\n }\n\n if (reasons.length === 0) {\n return null;\n }\n return { providerRef, endpointKey: endpoint.key, capability: endpoint.capability, routePath, reasons };\n }\n\n // ════════════════════════════════════════════════════════════\n // Handler\n // ════════════════════════════════════════════════════════════\n\n private async handleWebhookRequest(\n providerRef: string,\n endpoint: Hook_Endpoint,\n req: Request,\n res: Response,\n ): Promise<void> {\n if (!this.webhookHandler) {\n res.status(503).json({ error: 'Webhook handler not initialized' });\n return;\n }\n\n // Raw request bytes for signature verification. Order matters:\n // 1. req.rawBody — captured by the global express.json `verify` hook\n // (HttpServerBackendService.setupBodyParsing). This is the provider's\n // EXACT original payload and the ONLY byte-faithful source under the\n // current master-router mount, where global express.json parses the\n // body before this route runs (making the per-route express.raw() a\n // no-op, so req.body is a parsed object here).\n // 2. Buffer req.body — only populated if this controller is ever\n // streaming-mounted before body parsing (per-route express.raw() fires).\n // 3. string / JSON.stringify — last-resort fallbacks; JSON.stringify will\n // NOT byte-match the provider (key ordering / whitespace), so it exists\n // only to avoid a crash, never as a correctness path for signatures.\n const rawBody = Buffer.isBuffer(req.rawBody)\n ? req.rawBody.toString('utf-8')\n : Buffer.isBuffer(req.body)\n ? req.body.toString('utf-8')\n : typeof req.body === 'string'\n ? req.body\n : JSON.stringify(req.body);\n\n let result: Awaited<ReturnType<WebhookHandlerBackendService['processWebhook']>> | null = null;\n try {\n result = await this.webhookHandler.processWebhook({\n providerRef,\n endpointKey: endpoint.key,\n endpoint,\n rawBody,\n headers: req.headers as Record<string, string>,\n });\n\n // null = idempotent duplicate or unparseable event — already acknowledged\n if (!result) {\n res.status(200).json({ received: true });\n return;\n }\n\n // Dispatch to capability handler.\n //\n // Defence in depth only: `registerWebhookRoutes` refuses to MOUNT a route\n // whose capability has no handler, so this branch is unreachable while that\n // gate holds — reaching it means the handler map was mutated after mounting\n // (which `registerCapabilityHandler` refuses to do silently). The throw is\n // kept rather than removed because the alternative — dispatching to\n // `undefined` — would 500 anyway, with no explanation.\n const handler = this.capabilityHandlers.get(endpoint.capability);\n if (handler) {\n await handler.handleEvent(result.executionContext, result.parsedEvent);\n } else {\n throw new Error(`No capability handler for ${endpoint.capability} on ${providerRef}/${endpoint.key}`);\n }\n\n await this.webhookHandler.markWebhookProcessed(result.idempotencyKey);\n res.status(200).json({ received: true });\n } catch (error) {\n const errorMessage = (error as Error).message ?? 'Unknown error';\n const errorType = (error as any)?.errorType;\n\n // Signature failure → 401\n if (errorType === 'AUTHORIZATION') {\n this.logDebug('Webhook signature verification failed', { providerRef, endpointKey: endpoint.key });\n res.status(401).json({ error: 'Invalid signature' });\n return;\n }\n\n // All other errors → 500 (trigger provider retry)\n this.logger.error('Webhook processing failed', {\n providerRef,\n endpointKey: endpoint.key,\n error: errorMessage,\n });\n await this.webhookHandler.releaseWebhookClaim(result?.idempotencyKey);\n res.status(500).json({ error: 'Processing failed' });\n }\n }\n}\n"]}
1
+ {"version":3,"file":"webhook-auto-controller.backend.service.js","sourceRoot":"","sources":["../../../../../src/notifications/webhooks/controllers/webhook-auto-controller.backend.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;;;;;;;;;;;;;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,OAAO,MAAM,SAAS,CAAC;AAE9B,OAAO,EACL,sCAAsC,GAGvC,MAAM,sCAAsC,CAAC;AAG9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,gDAAgD,CAAC;AAMpF,OAAO,EAAE,gCAAgC,EAAE,MAAM,0FAA0F,CAAC;AAG5I;;;;;;;GAOG;AACH,MAAM,CAAN,IAAY,6BAaX;AAbD,WAAY,6BAA6B;IACvC;;;;OAIG;IACH,gFAA+C,CAAA;IAC/C;;;;OAIG;IACH,4EAA2C,CAAA;AAC7C,CAAC,EAbW,6BAA6B,KAA7B,6BAA6B,QAaxC;AAYM,IAAM,mCAAmC,GAAzC,MAAM,mCAAoC,SAAQ,gCAAgC;IAoCT;IACE;IAnChF,uEAAuE;IAC/D,kBAAkB,GAAG,IAAI,GAAG,EAAoC,CAAC;IAEjE,cAAc,GAAwC,IAAI,CAAC;IAEnE;;;;OAIG;IACK,eAAe,GAAG,IAAI,GAAG,EAA2B,CAAC;IAE7D,2EAA2E;IACnE,oBAAoB,GAAa,EAAE,CAAC;IAE5C;;;;OAIG;IACK,cAAc,GAA8B,EAAE,CAAC;IAEvD;;;;;OAKG;IACK,gBAAgB,GAAG,KAAK,CAAC;IAEjC,YACqC,MAAqB,EACR,YAAwC,EACxC,YAAiC,EACL,uBAA8D,EAC5D,yBAAkE;QAEhJ,KAAK,CAAC,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,uBAAuB,CAAC,CAAC;QAHS,4BAAuB,GAAvB,uBAAuB,CAAuC;QAC5D,8BAAyB,GAAzB,yBAAyB,CAAyC;IAGlJ,CAAC;IAED,+DAA+D;IAC/D,iBAAiB;IACjB,+DAA+D;IAE/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACI,KAAK,CAAC,UAAU,CACrB,cAA4C;QAE5C,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;QAErC,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,uBAAuB,CAAC,wBAAwB,CAAC,sCAAsC,CAAC,kBAAkB,CAAC,EAAE,CAAC;YACxI,MAAM,WAAW,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC;YAC1C,IAAI,CAAC;gBACH,IACE,CAAC,IAAI,CAAC,yBAAyB,CAAC,iBAAiB,CAC/C,WAAW,EACX,sCAAsC,CAAC,kBAAkB,CAC1D,EACD,CAAC;oBACD,SAAS;gBACX,CAAC;gBAED,MAAM,MAAM,GAAG,IAAI,CAAC,yBAAyB,CAAC,wBAAwB,CACpE,WAAW,EACX,sCAAsC,CAAC,kBAAkB,CAC1D,CAAC;gBACF,gEAAgE;gBAChE,mEAAmE;gBACnE,8DAA8D;gBAC9D,iEAAiE;gBACjE,qDAAqD;gBACrD,8DAA8D;gBAC9D,2DAA2D;gBAC3D,6DAA6D;gBAC7D,wBAAwB;gBACxB,MAAM,SAAS,GAAoB,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,IAAI,EAAE,CAAC,CAAC,CAAC;gBAClE,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACzB,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;oBACjD,IAAI,CAAC,QAAQ,CAAC,cAAc,SAAS,CAAC,MAAM,4BAA4B,WAAW,EAAE,CAAC,CAAC;gBACzF,CAAC;qBAAM,CAAC;oBACN,kEAAkE;oBAClE,oEAAoE;oBACpE,qEAAqE;oBACrE,kEAAkE;oBAClE,kEAAkE;oBAClE,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,oCAAoC,WAAW,oGAAoG,CACpJ,CAAC;gBACJ,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,2CAA2C,WAAW,EAAE,EAAE;oBACzE,KAAK,EAAG,KAAe,CAAC,OAAO;iBAChC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,4CAA4C,IAAI,CAAC,eAAe,CAAC,IAAI,cAAc,CAAC,CAAC;QAEnG,2EAA2E;QAC3E,IAAI,CAAC,qBAAqB,EAAE,CAAC;IAC/B,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,yBAAyB,CAAC,OAAiC;QACzD,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAEzD,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1B,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,kDAAkD,OAAO,CAAC,UAAU,sDAAsD;kBACxH,6HAA6H;kBAC7H,qFAAqF;kBACrF,4FAA4F,EAC9F;gBACE,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,cAAc,EAAE,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC;aAChF,CACF,CAAC;YACF,OAAO;QACT,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,6CAA6C,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IACnF,CAAC;IAED;;;;OAIG;IACI,8BAA8B;QACnC,OAAO,CAAC,GAAG,IAAI,CAAC,oBAAoB,CAAC,CAAC;IACxC,CAAC;IAED;;;;OAIG;IACI,wBAAwB;QAC7B,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,WAAW,EAAE,OAAO,EAAE,CAAC,GAAG,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3G,CAAC;IAED,+DAA+D;IAC/D,SAAS;IACT,+DAA+D;IAE/D;;;;;;;;OAQG;IACO,WAAW;QACnB,mEAAmE;IACrE,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6CG;IACK,qBAAqB;QAC3B,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAE7B,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,0FAA0F,CAAC,CAAC;YAC7G,OAAO;QACT,CAAC;QAED,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACpC,IAAI,CAAC,QAAQ,CAAC,wDAAwD,CAAC,CAAC;YACxE,OAAO;QACT,CAAC;QAED,KAAK,MAAM,CAAC,WAAW,EAAE,SAAS,CAAC,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YAC5D,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;gBACjC,MAAM,SAAS,GAAG,aAAa,WAAW,IAAI,QAAQ,CAAC,GAAG,EAAE,CAAC;gBAE7D,MAAM,WAAW,GAAG,IAAI,CAAC,0BAA0B,CAAC,WAAW,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;gBACtF,IAAI,WAAW,EAAE,CAAC;oBAChB,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;oBACtC,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,+CAA+C,SAAS,uDAAuD;0BAC7G,IAAI,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,iFAAiF;0BACnH,kHAAkH;0BAClH,gEAAgE;0BAChE,IAAI,QAAQ,CAAC,UAAU,6FAA6F;0BACpH,kHAAkH;0BAClH,0BAA0B,WAAW,IAAI,EAC3C;wBACE,WAAW;wBACX,WAAW,EAAE,QAAQ,CAAC,GAAG;wBACzB,UAAU,EAAE,QAAQ,CAAC,UAAU;wBAC/B,SAAS;wBACT,OAAO,EAAE,WAAW,CAAC,OAAO;qBAC7B,CACF,CAAC;oBACF,SAAS;gBACX,CAAC;gBAED,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,SAAS;gBACT,uEAAuE;gBACvE,uEAAuE;gBACvE,2CAA2C;gBAC3C,+DAA+D;gBAC/D,sEAAsE;gBACtE,sEAAsE;gBACtE,uEAAuE;gBACvE,wEAAwE;gBACxE,mCAAmC;gBACnC,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EACzC,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,KAAmB,EAAE,EAAE;oBAC3E,MAAM,IAAI,CAAC,oBAAoB,CAAC,WAAW,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;gBACnE,CAAC,CAAC,CACH,CAAC;gBAEF,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAC1C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,qCAAqC,SAAS,EAAE,CAAC,CAAC;YACrE,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;;;;;;OAQG;IACK,0BAA0B,CAChC,WAAmB,EACnB,QAAuB,EACvB,SAAiB;QAEjB,MAAM,OAAO,GAAoC,EAAE,CAAC;QAEpD,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YACtD,OAAO,CAAC,IAAI,CAAC,6BAA6B,CAAC,qBAAqB,CAAC,CAAC;QACpE,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,UAAU,CAAC,WAAW,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAChE,OAAO,CAAC,IAAI,CAAC,6BAA6B,CAAC,mBAAmB,CAAC,CAAC;QAClE,CAAC;QAED,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,CAAC,GAAG,EAAE,UAAU,EAAE,QAAQ,CAAC,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;IACzG,CAAC;IAED,+DAA+D;IAC/D,UAAU;IACV,+DAA+D;IAEvD,KAAK,CAAC,oBAAoB,CAChC,WAAmB,EACnB,QAAuB,EACvB,GAAY,EACZ,GAAa;QAEb,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YACzB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,iCAAiC,EAAE,CAAC,CAAC;YACnE,OAAO;QACT,CAAC;QAED,+DAA+D;QAC/D,uEAAuE;QACvE,2EAA2E;QAC3E,0EAA0E;QAC1E,yEAAyE;QACzE,yEAAyE;QACzE,oDAAoD;QACpD,mEAAmE;QACnE,8EAA8E;QAC9E,4EAA4E;QAC5E,6EAA6E;QAC7E,0EAA0E;QAC1E,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC;YAC1C,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;YAC/B,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;gBACzB,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAC5B,CAAC,CAAC,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ;oBAC5B,CAAC,CAAC,GAAG,CAAC,IAAI;oBACV,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAEjC,IAAI,MAAM,GAA+E,IAAI,CAAC;QAC9F,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC;gBAChD,WAAW;gBACX,WAAW,EAAE,QAAQ,CAAC,GAAG;gBACzB,QAAQ;gBACR,OAAO;gBACP,OAAO,EAAE,GAAG,CAAC,OAAiC;aAC/C,CAAC,CAAC;YAEH,0EAA0E;YAC1E,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;gBACzC,OAAO;YACT,CAAC;YAED,kCAAkC;YAClC,EAAE;YACF,0EAA0E;YAC1E,4EAA4E;YAC5E,4EAA4E;YAC5E,2EAA2E;YAC3E,oEAAoE;YACpE,uDAAuD;YACvD,MAAM,OAAO,GAAG,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;YACjE,IAAI,OAAO,EAAE,CAAC;gBACZ,MAAM,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;YACzE,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,KAAK,CAAC,6BAA6B,QAAQ,CAAC,UAAU,OAAO,WAAW,IAAI,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC;YACxG,CAAC;YAED,MAAM,IAAI,CAAC,cAAc,CAAC,oBAAoB,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;YACtE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,YAAY,GAAI,KAAe,CAAC,OAAO,IAAI,eAAe,CAAC;YACjE,MAAM,SAAS,GAAI,KAAa,EAAE,SAAS,CAAC;YAE5C,0BAA0B;YAC1B,IAAI,SAAS,KAAK,eAAe,EAAE,CAAC;gBAClC,IAAI,CAAC,QAAQ,CAAC,uCAAuC,EAAE,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC;gBACnG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAC;gBACrD,OAAO;YACT,CAAC;YAED,kDAAkD;YAClD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,2BAA2B,EAAE;gBAC7C,WAAW;gBACX,WAAW,EAAE,QAAQ,CAAC,GAAG;gBACzB,KAAK,EAAE,YAAY;aACpB,CAAC,CAAC;YACH,MAAM,IAAI,CAAC,cAAc,CAAC,mBAAmB,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;YACtE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;CACF,CAAA;AA3aY,mCAAmC;IAD/C,UAAU,EAAE;IAkCR,WAAA,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAA;IACjC,WAAA,MAAM,CAAC,kBAAkB,CAAC,mBAAmB,CAAC,CAAA;IAC9C,WAAA,MAAM,CAAC,kBAAkB,CAAC,mBAAmB,CAAC,CAAA;IAC9C,WAAA,MAAM,CAAC,kBAAkB,CAAC,8BAA8B,CAAC,CAAA;IACzD,WAAA,MAAM,CAAC,kBAAkB,CAAC,gCAAgC,CAAC,CAAA;;GArCnD,mCAAmC,CA2a/C","sourcesContent":["/**\n * Webhook Auto-Controller Backend Service\n *\n * Auto-registers webhook routes from provider registry definitions.\n * At startup, iterates all providers with WEBHOOK_ORIGINATOR protocol,\n * then iterates each provider's endpoints, and registers:\n * POST /webhooks/{providerRef}/{endpointKey}\n *\n * One provider declares the protocol today, and it declares one endpoint:\n * POST /webhooks/stripe/billing\n *\n * A second provider registers here the moment it declares `WEBHOOK_ORIGINATOR` with its own\n * `endpoints`; no edit to this controller is needed.\n *\n * This replaces manual per-provider webhook controllers (like BillingWebhookControllerBackendService).\n *\n * @see hook-protocol-webhook-callback.md\n */\n\nimport { injectable, inject } from 'inversify';\nimport express from 'express';\nimport type { Request, Response, NextFunction } from 'express';\nimport {\n ExternalProvider_ExchangeProtocol_Kind,\n type Hook_Endpoint,\n type WebhookCapabilityHandler,\n} from '@wildo-ai/external-connectors-models';\nimport { HttpMethod } from '@wildo-ai/saas-models';\n\nimport { SAAS_SERVICE_TYPES } from '~wildo-backend-lib/inject/models/service-types';\nimport type { LoggerService } from '~wildo-backend-lib/monitoring/logger/services/logger.service';\nimport type { ErrorBuilderBackendService } from '~wildo-backend-lib/errors/services/error-builder.backend.service';\nimport type { ErrorHandlerService } from '~wildo-backend-lib/errors/services/error-handler.backend.service';\nimport type { BackendProviderRegistryBackendService } from '~wildo-backend-lib/external-providers/services/backend-provider-registry.backend.service';\nimport type { ExternalProvidersRegistryBackendService } from '~wildo-backend-lib/external-providers/services/external-providers-registry.backend.service';\nimport { AbstractControllerBackendService } from '~wildo-backend-lib/base-classes/services/controllers/abstract-controller.backend.service';\nimport type { WebhookHandlerBackendService } from '~wildo-backend-lib/notifications/webhooks/services/webhook-handler.backend.service';\n\n/**\n * Why a declared webhook endpoint did NOT get an Express route.\n *\n * A closed vocabulary rather than a free string: each member names a DIFFERENT\n * missing registration, with a different remedy, and an operator reading the\n * startup log has to be able to tell them apart. The two are independent — an\n * endpoint can be missing either, or both.\n */\nexport enum WebhookRouteWithholdingReason {\n /**\n * No {@link WebhookCapabilityHandler} is registered for the endpoint's\n * `capability`. The route would reach `handleWebhookRequest`, complete\n * signature verification and idempotency claiming, then fail at dispatch.\n */\n NO_CAPABILITY_HANDLER = 'NO_CAPABILITY_HANDLER',\n /**\n * No `WebhookCapabilityAdapter` is registered for `providerRef:endpointKey`\n * on {@link WebhookHandlerBackendService}. The route would fail at the very\n * top of `processWebhook`, before signature verification.\n */\n NO_ENDPOINT_ADAPTER = 'NO_ENDPOINT_ADAPTER',\n}\n\n/** One declared endpoint whose route was deliberately not mounted, and why. */\nexport interface WebhookRouteWithholding {\n providerRef: string;\n endpointKey: string;\n capability: string;\n routePath: string;\n reasons: WebhookRouteWithholdingReason[];\n}\n\n@injectable()\nexport class WebhookAutoControllerBackendService extends AbstractControllerBackendService {\n\n /** Capability handlers keyed by capability string (e.g., 'billing') */\n private capabilityHandlers = new Map<string, WebhookCapabilityHandler>();\n\n private webhookHandler: WebhookHandlerBackendService | null = null;\n\n /**\n * Pre-loaded endpoint configurations per provider.\n * Populated during initialize() from first-class provider runtime contracts.\n * setupRoutes() reads from this cache (sync) to register routes.\n */\n private loadedEndpoints = new Map<string, Hook_Endpoint[]>();\n\n /** Route paths recorded only after Express accepted their registration. */\n private registeredRoutePaths: string[] = [];\n\n /**\n * Declared endpoints whose route was WITHHELD because the capability could\n * not be dispatched. Kept so the decision is inspectable after startup rather\n * than only visible in a log line that has already scrolled past.\n */\n private withheldRoutes: WebhookRouteWithholding[] = [];\n\n /**\n * Set once {@link registerWebhookRoutes} has run. The mount decision is taken\n * ONCE, from the registration state at that instant, so anything registered\n * afterwards cannot change which routes exist — see\n * {@link registerCapabilityHandler}, which refuses to let that be silent.\n */\n private routesRegistered = false;\n\n constructor(\n @inject(SAAS_SERVICE_TYPES.Logger) logger: LoggerService,\n @inject(SAAS_SERVICE_TYPES.ErrorBuilderService) errorBuilder: ErrorBuilderBackendService,\n @inject(SAAS_SERVICE_TYPES.ErrorHandlerService) errorHandler: ErrorHandlerService,\n @inject(SAAS_SERVICE_TYPES.BackendProviderRegistryService) private readonly backendProviderRegistry: BackendProviderRegistryBackendService,\n @inject(SAAS_SERVICE_TYPES.ExternalProvidersRegistryService) private readonly externalProvidersRegistry: ExternalProvidersRegistryBackendService,\n ) {\n super(logger, errorBuilder, errorHandler, 'WebhookAutoController');\n }\n\n // ════════════════════════════════════════════════════════════\n // Initialization\n // ════════════════════════════════════════════════════════════\n\n /**\n * Initialize with required dependencies, pre-load endpoint configs, AND\n * register the webhook routes.\n *\n * ── Why routes are registered HERE, not in `setupRoutes()` ──────────────\n *\n * `AbstractControllerBackendService` calls the abstract `setupRoutes()` hook\n * synchronously from *inside its own constructor* (`super(...)`). At that\n * point this controller has NOTHING to register:\n *\n * 1. The webhook handler is not injected via the constructor — it is\n * supplied to `initialize()` by `start-application` after the billing /\n * provider layers are wired.\n * 2. The route SET is data-dependent (one route per provider webhook\n * endpoint), and those endpoint contracts are only knowable after the\n * provider registries have been initialized (which happens later in the\n * startup sequence than DI construction).\n *\n * So `setupRoutes()` is a deliberate no-op (see its JSDoc) and the real,\n * data-dependent route registration runs here — the same lifecycle shape\n * `ControllerResourceBackendService` uses for its per-resource routes.\n *\n * `start-application` calls this BEFORE the controllers registry mounts the\n * router (via `getRouter()`), so the routes added here are present when the\n * master router mounts this controller's router by reference. Errors thrown\n * from webhook handlers propagate to the app-level error middleware\n * (`HttpServerBackendService`), so no router-scoped error handler is needed\n * after these routes.\n */\n public async initialize(\n webhookHandler: WebhookHandlerBackendService,\n ): Promise<void> {\n this.webhookHandler = webhookHandler;\n\n for (const provider of this.backendProviderRegistry.getProvidersWithProtocol(ExternalProvider_ExchangeProtocol_Kind.WEBHOOK_ORIGINATOR)) {\n const providerRef = provider.metadata.ref;\n try {\n if (\n !this.externalProvidersRegistry.isProviderEnabled(\n providerRef,\n ExternalProvider_ExchangeProtocol_Kind.WEBHOOK_ORIGINATOR,\n )\n ) {\n continue;\n }\n\n const config = this.externalProvidersRegistry.getProviderConfiguration(\n providerRef,\n ExternalProvider_ExchangeProtocol_Kind.WEBHOOK_ORIGINATOR,\n );\n // `config.endpoints` is `ReadonlyArray<Hook_Endpoint>` post the\n // 2026-05-06 webhook endpoint reshape: `Hook_Endpoint.displayName`\n // is now optional (matches the runtime emission) and the dead\n // extras (`providerRef` / `path` / `secretBinding`) were dropped\n // from `buildWebhookEndpoints`. The local cache is a\n // `Map<string, Hook_Endpoint[]>`, so we materialize a mutable\n // copy here — the cache was historically `Hook_Endpoint[]`\n // (mutable); preserving that semantics avoids touching every\n // downstream signature.\n const endpoints: Hook_Endpoint[] = [...(config?.endpoints ?? [])];\n if (endpoints.length > 0) {\n this.loadedEndpoints.set(providerRef, endpoints);\n this.logDebug(`Pre-loaded ${endpoints.length} webhook endpoint(s) for ${providerRef}`);\n } else {\n // Genuine contract fault (not the expected \"no webhook providers\"\n // case): the provider is ENABLED for WEBHOOK_ORIGINATOR yet exposes\n // zero endpoints, so it will silently never receive inbound webhooks\n // (e.g. Stripe would 404 on /webhooks/stripe/billing). Surface it\n // once, clearly — this is a mis-sequence, not steady-state noise.\n this.logger.warn(\n `WebhookAutoController: provider '${providerRef}' is enabled for WEBHOOK_ORIGINATOR but exposes no endpoints — no routes will be registered for it`,\n );\n }\n } catch (error) {\n this.logger.warn(`Failed to pre-load webhook protocol for ${providerRef}`, {\n error: (error as Error).message,\n });\n }\n }\n\n this.logDebug(`Webhook auto-controller initialized with ${this.loadedEndpoints.size} provider(s)`);\n\n // Register the routes now that the handler + endpoint contracts are known.\n this.registerWebhookRoutes();\n }\n\n /**\n * Register a capability handler for dispatching processed events.\n * Called at startup by capability modules (e.g., billing module).\n *\n * MUST be called before {@link initialize}. `start-application` satisfies this\n * ordering today — step 4.5 initializes capability modules (which register\n * here) and step 4.6 initializes this controller — and the guard below exists\n * so a future step inserted the other way round is LOUD instead of silent.\n *\n * The failure it catches is genuinely confusing without it: a late-registered\n * handler works perfectly at request time (the map is read per request), but\n * the route it would serve was already withheld at mount time, so the endpoint\n * answers 404 while a handler for it demonstrably exists.\n */\n registerCapabilityHandler(handler: WebhookCapabilityHandler): void {\n this.capabilityHandlers.set(handler.capability, handler);\n\n if (this.routesRegistered) {\n this.logger.error(\n `WebhookAutoController: capability handler for '${handler.capability}' was registered AFTER webhook routes were mounted. `\n + 'Route mounting is decided once, from the registrations present at that moment, so this handler cannot bring back any route '\n + 'that was withheld for a missing handler — those endpoints will keep answering 404. '\n + 'Register capability handlers before WebhookAutoControllerBackendService.initialize() runs.',\n {\n capability: handler.capability,\n withheldRoutes: this.withheldRoutes.map((withholding) => withholding.routePath),\n },\n );\n return;\n }\n\n this.logDebug(`Registered webhook capability handler for ${handler.capability}`);\n }\n\n /**\n * Return the sanitized inbound-provider routes that this controller actually\n * registered. Provider configuration, signature material, endpoint payloads,\n * and handler metadata are intentionally absent.\n */\n public getRegisteredWebhookRoutePaths(): ReadonlyArray<string> {\n return [...this.registeredRoutePaths];\n }\n\n /**\n * Return the declared endpoints whose route was deliberately NOT mounted,\n * with the reason. Carries no provider configuration or signature material —\n * only the route identity and which registration was missing.\n */\n public getWithheldWebhookRoutes(): ReadonlyArray<WebhookRouteWithholding> {\n return this.withheldRoutes.map((withholding) => ({ ...withholding, reasons: [...withholding.reasons] }));\n }\n\n // ════════════════════════════════════════════════════════════\n // Routes\n // ════════════════════════════════════════════════════════════\n\n /**\n * Required by `AbstractControllerBackendService`, which invokes this hook\n * synchronously from its constructor (`super(...)`). This controller\n * intentionally registers NOTHING here: its route set is data-dependent\n * (one route per provider webhook endpoint) and neither the webhook handler\n * nor the provider endpoint contracts exist at construction time. The real\n * registration happens in `initialize()` / `registerWebhookRoutes()` once\n * that data is available — see `initialize()`'s JSDoc for the full rationale.\n */\n protected setupRoutes(): void {\n // No-op by design — see JSDoc above and `registerWebhookRoutes()`.\n }\n\n /**\n * Register one Express route per pre-loaded provider webhook endpoint —\n * EXCEPT those whose capability cannot actually be dispatched.\n *\n * Invoked from `initialize()` after `webhookHandler` and `loadedEndpoints`\n * have been populated. Idempotent-safe against an empty cache; guards on the\n * handler so a mis-sequenced call fails visibly rather than registering dead\n * routes.\n *\n * ── Why an undispatchable endpoint is WITHHELD rather than mounted ────────\n *\n * A declared endpoint needs two registrations that this controller does not\n * own and cannot create: a `WebhookCapabilityAdapter` (verify + parse, on\n * `WebhookHandlerBackendService`) and a `WebhookCapabilityHandler` (dispatch,\n * here). Both are supplied by the capability module — for `billing`, inside\n * `start-application.initializeBillingServices`, which is deliberately\n * NON-FATAL: if it throws part-way, or if `billing.enabled` is false while the\n * provider is still enabled for `WEBHOOK_ORIGINATOR`, the application boots\n * with the provider's endpoint declared and neither registration present.\n *\n * Mounting a route in that state produces a 500 on every inbound delivery\n * (`No webhook adapter registered for ...`, or `No capability handler for ...`\n * below), and a 500 is precisely the answer that tells a vendor to RETRY — an\n * instruction that can never be satisfied, because no retry supplies a missing\n * startup registration. The endpoint therefore absorbs the vendor's full retry\n * schedule and eventually gets disabled on the vendor's side, while the only\n * local signal is a repeating error log.\n *\n * Not mounting says the true thing instead: this endpoint does not exist. The\n * vendor gets a 404 rather than a retry instruction, and the operator gets one\n * loud, remedy-naming error at startup — the moment the misconfiguration was\n * actually introduced.\n *\n * REJECTED — refusing at BOOT (throwing from here). It is the shape the rest of\n * the registry uses, and it is wrong at this site for three reasons. (1) It\n * would not even be loud: `start-application.initializeWebhookAutoController`\n * wraps `initialize()` in a non-fatal catch that downgrades a throw to a warn,\n * so the net effect would be a quieter log AND the loss of every OTHER\n * provider's working route. (2) It inverts a decision the engine already took\n * explicitly — billing initialization failure is documented as survivable\n * (\"the app can still run without billing\"); a failed optional subsystem must\n * not become a refusal to start. (3) `billing.enabled: false` beside a\n * registered Stripe provider is a COHERENT configuration, and refusing to boot\n * over it would be a false alarm. The check is per-endpoint, so a capability\n * that is wired keeps its route regardless of a sibling that is not.\n */\n private registerWebhookRoutes(): void {\n this.routesRegistered = true;\n\n if (!this.webhookHandler) {\n this.logger.warn('WebhookAutoController: initialize() ran without a webhook handler — no routes registered');\n return;\n }\n\n if (this.loadedEndpoints.size === 0) {\n this.logDebug('No webhook endpoints pre-loaded — no routes registered');\n return;\n }\n\n for (const [providerRef, endpoints] of this.loadedEndpoints) {\n for (const endpoint of endpoints) {\n const routePath = `/webhooks/${providerRef}/${endpoint.key}`;\n\n const withholding = this.assessRouteDispatchability(providerRef, endpoint, routePath);\n if (withholding) {\n this.withheldRoutes.push(withholding);\n this.logger.error(\n `WebhookAutoController: NOT registering POST ${routePath} — the endpoint is declared but cannot be dispatched `\n + `(${withholding.reasons.join(', ')}). A route mounted in this state can only ever answer 500, which instructs the `\n + 'vendor to retry an inbound event that no retry can make processable. Withholding the route so the vendor gets a '\n + '404 instead. Remedy: register the capability module that owns '\n + `'${endpoint.capability}' before WebhookAutoControllerBackendService.initialize() runs (for billing, check whether `\n + 'billing initialization was skipped or failed non-fatally earlier in startup), or disable the WEBHOOK_ORIGINATOR '\n + `protocol for provider '${providerRef}'.`,\n {\n providerRef,\n endpointKey: endpoint.key,\n capability: endpoint.capability,\n routePath,\n reasons: withholding.reasons,\n },\n );\n continue;\n }\n\n this.router.post(\n routePath,\n // Defense-in-depth for a future streaming mount. If this controller is\n // ever assigned the RAW_REQUEST_STREAM mount phase, this express.raw()\n // makes req.body the raw Buffer. Under the\n // current master-router mount it is an inert no-op: the global\n // express.json (HttpServerBackendService.setupBodyParsing) parses the\n // body first and sets req._body, so the signature-faithful bytes come\n // from req.rawBody — captured by that same express.json `verify` hook.\n // handleWebhookRequest reads rawBody first, then falls back to a Buffer\n // req.body for the streaming case.\n express.raw({ type: 'application/json' }),\n this.asyncHandler(async (req: Request, res: Response, _next: NextFunction) => {\n await this.handleWebhookRequest(providerRef, endpoint, req, res);\n }),\n );\n\n this.registeredRoutePaths.push(routePath);\n this.logger.info(`Webhook endpoint registered: POST ${routePath}`);\n }\n }\n }\n\n /**\n * Decide whether a declared endpoint can actually be served, and if not, say\n * which registration is missing.\n *\n * Returns `null` when the route is dispatchable. Both prerequisites are\n * evaluated (rather than short-circuiting on the first) so an operator gets\n * the WHOLE remedy in one log line instead of fixing one registration and\n * meeting the next on the following restart.\n */\n private assessRouteDispatchability(\n providerRef: string,\n endpoint: Hook_Endpoint,\n routePath: string,\n ): WebhookRouteWithholding | null {\n const reasons: WebhookRouteWithholdingReason[] = [];\n\n if (!this.capabilityHandlers.has(endpoint.capability)) {\n reasons.push(WebhookRouteWithholdingReason.NO_CAPABILITY_HANDLER);\n }\n if (!this.webhookHandler?.hasAdapter(providerRef, endpoint.key)) {\n reasons.push(WebhookRouteWithholdingReason.NO_ENDPOINT_ADAPTER);\n }\n\n if (reasons.length === 0) {\n return null;\n }\n return { providerRef, endpointKey: endpoint.key, capability: endpoint.capability, routePath, reasons };\n }\n\n // ════════════════════════════════════════════════════════════\n // Handler\n // ════════════════════════════════════════════════════════════\n\n private async handleWebhookRequest(\n providerRef: string,\n endpoint: Hook_Endpoint,\n req: Request,\n res: Response,\n ): Promise<void> {\n if (!this.webhookHandler) {\n res.status(503).json({ error: 'Webhook handler not initialized' });\n return;\n }\n\n // Raw request bytes for signature verification. Order matters:\n // 1. req.rawBody — captured by the global express.json `verify` hook\n // (HttpServerBackendService.setupBodyParsing). This is the provider's\n // EXACT original payload and the ONLY byte-faithful source under the\n // current master-router mount, where global express.json parses the\n // body before this route runs (making the per-route express.raw() a\n // no-op, so req.body is a parsed object here).\n // 2. Buffer req.body — only populated if this controller is ever\n // streaming-mounted before body parsing (per-route express.raw() fires).\n // 3. string / JSON.stringify — last-resort fallbacks; JSON.stringify will\n // NOT byte-match the provider (key ordering / whitespace), so it exists\n // only to avoid a crash, never as a correctness path for signatures.\n const rawBody = Buffer.isBuffer(req.rawBody)\n ? req.rawBody.toString('utf-8')\n : Buffer.isBuffer(req.body)\n ? req.body.toString('utf-8')\n : typeof req.body === 'string'\n ? req.body\n : JSON.stringify(req.body);\n\n let result: Awaited<ReturnType<WebhookHandlerBackendService['processWebhook']>> | null = null;\n try {\n result = await this.webhookHandler.processWebhook({\n providerRef,\n endpointKey: endpoint.key,\n endpoint,\n rawBody,\n headers: req.headers as Record<string, string>,\n });\n\n // null = idempotent duplicate or unparseable event — already acknowledged\n if (!result) {\n res.status(200).json({ received: true });\n return;\n }\n\n // Dispatch to capability handler.\n //\n // Defence in depth only: `registerWebhookRoutes` refuses to MOUNT a route\n // whose capability has no handler, so this branch is unreachable while that\n // gate holds — reaching it means the handler map was mutated after mounting\n // (which `registerCapabilityHandler` refuses to do silently). The throw is\n // kept rather than removed because the alternative — dispatching to\n // `undefined` — would 500 anyway, with no explanation.\n const handler = this.capabilityHandlers.get(endpoint.capability);\n if (handler) {\n await handler.handleEvent(result.executionContext, result.parsedEvent);\n } else {\n throw new Error(`No capability handler for ${endpoint.capability} on ${providerRef}/${endpoint.key}`);\n }\n\n await this.webhookHandler.markWebhookProcessed(result.idempotencyKey);\n res.status(200).json({ received: true });\n } catch (error) {\n const errorMessage = (error as Error).message ?? 'Unknown error';\n const errorType = (error as any)?.errorType;\n\n // Signature failure → 401\n if (errorType === 'AUTHORIZATION') {\n this.logDebug('Webhook signature verification failed', { providerRef, endpointKey: endpoint.key });\n res.status(401).json({ error: 'Invalid signature' });\n return;\n }\n\n // All other errors → 500 (trigger provider retry)\n this.logger.error('Webhook processing failed', {\n providerRef,\n endpointKey: endpoint.key,\n error: errorMessage,\n });\n await this.webhookHandler.releaseWebhookClaim(result?.idempotencyKey);\n res.status(500).json({ error: 'Processing failed' });\n }\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"m2m-webhook-delivery.batch.backend.service.d.ts","sourceRoot":"","sources":["../../../../../../../src/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.backend.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,aAAa,EAId,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEL,KAAK,sCAAsC,EAC5C,MAAM,4FAA4F,CAAC;AAmDpG,eAAO,MAAM,kCAAkC;;;;;;iBAM7C,CAAC;AAEH,MAAM,MAAM,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kCAAkC,CAAC,CAAC;AAE9F,eAAO,MAAM,mCAAmC;;;;;;;;;;;;iBAiB9C,CAAC;AAEH,MAAM,MAAM,6BAA6B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mCAAmC,CAAC,CAAC;AAMhG,eAAO,MAAM,8BAA8B,EAAE,sCAAsC,CACjF,OAAO,kCAAkC,EACzC,OAAO,mCAAmC,CA8V1C,CAAC"}
1
+ {"version":3,"file":"m2m-webhook-delivery.batch.backend.service.d.ts","sourceRoot":"","sources":["../../../../../../src/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.backend.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,aAAa,EAId,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEL,KAAK,sCAAsC,EAC5C,MAAM,4FAA4F,CAAC;AAmDpG,eAAO,MAAM,kCAAkC;;;;;;iBAM7C,CAAC;AAEH,MAAM,MAAM,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kCAAkC,CAAC,CAAC;AAE9F,eAAO,MAAM,mCAAmC;;;;;;;;;;;;iBAiB9C,CAAC;AAEH,MAAM,MAAM,6BAA6B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mCAAmC,CAAC,CAAC;AAMhG,eAAO,MAAM,8BAA8B,EAAE,sCAAsC,CACjF,OAAO,kCAAkC,EACzC,OAAO,mCAAmC,CA8V1C,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"m2m-webhook-delivery.batch.backend.service.js","sourceRoot":"","sources":["../../../../../../../src/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.backend.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,aAAa,EACb,6BAA6B,EAC7B,8BAA8B,EAC9B,mCAAmC,GACpC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,iCAAiC,GAElC,MAAM,4FAA4F,CAAC;AACpG,OAAO,EAAE,0CAA0C,EAAE,MAAM,gFAAgF,CAAC;AAC5I,OAAO,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,MAAM,8EAA8E,CAAC;AAChJ,OAAO,EAAE,kBAAkB,EAAE,MAAM,gDAAgD,CAAC;AAEpF,OAAO,EAAE,cAAc,EAAE,MAAM,wEAAwE,CAAC;AAGxG,OAAO,EACL,YAAY,EACZ,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,+BAA+B,EAAE,wBAAwB,EAAE,MAAM,6CAA6C,CAAC;AAExH,8EAA8E;AAC9E,yBAAyB;AACzB,8EAA8E;AAE9E;;;;;GAKG;AACH;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,kCAAkC,GAAG,IAAI,GAAG,EAAU,CAAC;AAE7D,MAAM,CAAC,MAAM,kCAAkC,GAAG,CAAC,CAAC,MAAM,CAAC;IACzD,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;QACd,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC;QAC3B,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;KACtB,CAAC;IACF,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CACjC,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,mCAAmC,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1D,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE;IACzB;;;;OAIG;IACH,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC;QACd,WAAW;QACX,iBAAiB;QACjB,iBAAiB;QACjB,qBAAqB;QACrB,wBAAwB;KACzB,CAAC;IACF,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;IAC5C,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAC3C,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;CAC3C,CAAC,CAAC;AAIH,8EAA8E;AAC9E,gBAAgB;AAChB,8EAA8E;AAE9E,MAAM,CAAC,MAAM,8BAA8B,GAGvC,iCAAiC,CAAC;IACpC,KAAK,EAAE,kCAAkC;IACzC,MAAM,EAAE,mCAAmC;IAC3C,oBAAoB,EAAE;QACpB,iEAAiE;QACjE,wEAAwE;QACxE,qEAAqE;QACrE,iEAAiE;QACjE,6CAA6C;QAC7C,6CAA6C;QAC7C,sCAAsC;QACtC,6CAA6C;QAC7C,EAAE;QACF,4BAA4B;QAC5B,uEAAuE;QACvE,sEAAsE;QACtE,6DAA6D;QAC7D,oEAAoE;QACpE,uEAAuE;QACvE,sEAAsE;QACtE,mEAAmE;QACnE,8DAA8D;QAC9D,oEAAoE;QACpE,sEAAsE;QACtE,IAAI,EAAE,0CAA0C,CAAC,IAAI;QACrD,mBAAmB,EAAE,0CAA0C,CAAC,mBAAmB;QACnF,YAAY,EAAE,0CAA0C,CAAC,YAAY;KACtE;IACD,mBAAmB,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC;QACjC,UAAU,EAAE,GAAG,CACb,kBAAkB,CAAC,+BAA+B,CACnD;QACD,UAAU,EAAE,GAAG,CAAoB,kBAAkB,CAAC,iBAAiB,CAAC;QACxE,cAAc,EAAE,GAAG,CAAiB,kBAAkB,CAAC,cAAc,CAAC;KACvE,CAAC;IACF,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,gBAAgB,EAAE,YAAY,EAAE,EAAE,EAAE;QACpE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC,yBAAyB,CAAC,CAAC;QAC/D,MAAM,EACJ,UAAU,EAAE,IAAI,EAChB,UAAU,EACV,cAAc,GACf,GAAG,YAAY,CAAC;QAEjB;;;;;;;;;;;;;;;;;;;WAmBG;QACH,MAAM,eAAe,GAAG,CACtB,MAAqC,EACN,EAAE;YACjC,IAAI,CAAC;gBACH,cAAc,CAAC,+BAA+B,CAAC;oBAC7C,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI;oBACvB,OAAO,EAAE,MAAM,CAAC,OAAO;iBACxB,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,CAAC,IAAI,CAAC,sDAAsD,EAAE;oBAClE,aAAa,EAAE,KAAK,CAAC,aAAa;oBAClC,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI;oBAC3B,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE;oBACvB,OAAO,EAAE,MAAM,CAAC,OAAO;oBACvB,GAAG,2BAA2B,CAAC,KAAK,CAAC;iBACtC,CAAC,CAAC;YACL,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC;QAEF,8DAA8D;QAC9D,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,gBAAgB,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;QAChF,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,4DAA4D;YAC5D,+DAA+D;YAC/D,sDAAsD;YACtD,MAAM,CAAC,IAAI,CAAC,0CAA0C,EAAE;gBACtD,aAAa,EAAE,KAAK,CAAC,aAAa;gBAClC,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI;gBAC3B,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE;aACxB,CAAC,CAAC;YACH,OAAO,eAAe,CAAC;gBACrB,aAAa,EAAE,KAAK,CAAC,aAAa;gBAClC,OAAO,EAAE,qBAAqB;gBAC9B,YAAY,EAAE,CAAC;gBACf,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;aACnC,CAAC,CAAC;QACL,CAAC;QAED,MAAM,gBAAgB,GAAG,CAAC,GAAG,CAAC,YAAY,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAErD,8DAA8D;QAC9D,gEAAgE;QAChE,kEAAkE;QAClE,gEAAgE;QAChE,6DAA6D;QAC7D,0DAA0D;QAC1D,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,CACpC,KAAK,CAAC,KAAK,EACX,gBAAgB,EAChB,KAAK,CAAC,aAAa,EACnB,gBAAgB,CACjB,CAAC;QACF,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,CAAC,IAAI,CAAC,iEAAiE,EAAE;gBAC7E,aAAa,EAAE,KAAK,CAAC,aAAa;gBAClC,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI;gBAC3B,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE;gBACvB,UAAU,EAAE,GAAG,CAAC,UAAU;gBAC1B,OAAO,EAAE,GAAG,CAAC,OAAO;gBACpB,YAAY,EAAE,GAAG,CAAC,YAAY;gBAC9B,aAAa,EAAE,GAAG,CAAC,MAAM;aAC1B,CAAC,CAAC;YACH,OAAO,eAAe,CAAC;gBACrB,aAAa,EAAE,KAAK,CAAC,aAAa;gBAClC,OAAO,EAAE,wBAAwB;gBACjC,YAAY,EAAE,GAAG,CAAC,YAAY,IAAI,CAAC;gBACnC,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;aACnC,CAAC,CAAC;QACL,CAAC;QAED,8DAA8D;QAC9D,iEAAiE;QACjE,8DAA8D;QAC9D,iEAAiE;QACjE,2CAA2C;QAC3C,MAAM,MAAM,GAAG;YACb,8DAA8D;YAC9D,8DAA8D;YAC9D,2DAA2D;YAC3D,6DAA6D;YAC7D,gEAAgE;YAChE,kEAAkE;YAClE,uDAAuD;YACvD,wEAAwE;YACxE,0DAA0D;YAC1D,CAAC,6BAA6B,CAAC,eAAe,CAAC,UAAU,CAAC,EAAE,GAAG,CAAC,YAAY;YAC5E,CAAC,6BAA6B,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,WAAW;YACzE,CAAC,6BAA6B,CAAC,eAAe,CAAC,iBAAiB,CAAC,EAAE,+BAA+B;YAClG,CAAC,6BAA6B,CAAC,eAAe,CAAC,YAAY,CAAC,EAAE,GAAG,CAAC,OAAO;YACzE,CAAC,6BAA6B,CAAC,eAAe,CAAC,kBAAkB,CAAC,EAAE,GAAG,CAAC,kBAAkB;YAC1F,CAAC,6BAA6B,CAAC,eAAe,CAAC,mBAAmB,CAAC,EAAE,GAAG,CAAC,mBAAmB;YAC5F,uDAAuD;YACvD,4DAA4D;YAC5D,2DAA2D;YAC3D,6CAA6C;SAC9C,CAAC;QAEF,IAAI,SAAiB,CAAC;QACtB,IAAI,CAAC;YACH,SAAS,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,mBAAmB,CAAC,CAAC;QAChF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,6DAA6D;YAC7D,+DAA+D;YAC/D,gEAAgE;YAChE,oBAAoB;YACpB,MAAM,MAAM,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;YAC1C,MAAM,CAAC,KAAK,CAAC,0DAA0D,EAAE;gBACvE,aAAa,EAAE,KAAK,CAAC,aAAa;gBAClC,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI;gBAC3B,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE;gBACvB,UAAU,EAAE,GAAG,CAAC,UAAU;gBAC1B,OAAO,EAAE,GAAG,CAAC,OAAO;gBACpB,YAAY,EAAE,GAAG,CAAC,YAAY;gBAC9B,OAAO,EAAE,gBAAgB;gBACzB,KAAK;aACN,CAAC,CAAC;YACH,MAAM,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,KAAK,EAAE,gBAAgB,EAAE,KAAK,CAAC,aAAa,EAAE;gBAC/E,aAAa,EAAE,uBAAuB,MAAM,EAAE;aAC/C,CAAC,CAAC;YACH,OAAO,eAAe,CAAC;gBACrB,aAAa,EAAE,KAAK,CAAC,aAAa;gBAClC,OAAO,EAAE,iBAAiB;gBAC1B,YAAY,EAAE,gBAAgB;gBAC9B,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;aACnC,CAAC,CAAC;QACL,CAAC;QAED,8DAA8D;QAC9D,0DAA0D;QAC1D,mEAAmE;QACnE,sEAAsE;QACtE,6DAA6D;QAC7D,MAAM,SAAS,GACb,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAE9E,IAAI,mCAAmC,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YACrD,MAAM,SAAS,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,EAAE,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;YAC5E,IAAI,CAAC,kCAAkC,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;gBACvD,kCAAkC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;gBAClD,uFAAuF;gBACvF,4FAA4F;gBAC5F,2CAA2C;gBAC3C,MAAM,CAAC,IAAI,CAAC,4EAA4E,EAAE;oBACxF,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI;oBAC3B,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE;oBACvB,UAAU,EAAE,GAAG,CAAC,UAAU;oBAC1B,uFAAuF;oBACvF,wDAAwD;oBACxD,eAAe,EAAE,8BAA8B,CAAC,GAAG,CAAC,OAAO,CAAC;oBAC5D,QAAQ,EAAE,gFAAgF;0BACtF,+EAA+E;oBACnF,MAAM,EAAE,iDAAiD;iBAC1D,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,MAAM,EAAE,cAAc,EAAE,qBAAqB,EAAE,YAAY,EAAE,GAAG,MAAM,wBAAwB,CAAC;YAC7F,GAAG,EAAE,GAAG,CAAC,OAAO;YAChB,IAAI,EAAE,SAAS;YACf,SAAS;SACV,CAAC,CAAC;QAEH,2EAA2E;QAC3E,uEAAuE;QACvE,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QAE1C,8DAA8D;QAC9D,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;YACjC,MAAM,OAAO,GAAG,sBAAsB,CAAC,cAAc,CAAC,CAAC;YAEvD,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;gBAC5B,MAAM,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,KAAK,EAAE,gBAAgB,EAAE,KAAK,CAAC,aAAa,EAAE;oBAC3E,cAAc;oBACd,qBAAqB;iBACtB,CAAC,CAAC;gBACH,QAAQ,CAAC,mBAAmB,EAAE;oBAC5B,aAAa,EAAE,KAAK,CAAC,aAAa;oBAClC,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI;oBAC3B,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE;oBACvB,UAAU,EAAE,GAAG,CAAC,UAAU;oBAC1B,OAAO,EAAE,GAAG,CAAC,OAAO;oBACpB,YAAY,EAAE,GAAG,CAAC,YAAY;oBAC9B,UAAU,EAAE,cAAc;oBAC1B,UAAU;oBACV,OAAO,EAAE,gBAAgB;iBAC1B,CAAC,CAAC;gBACH,OAAO,eAAe,CAAC;oBACrB,aAAa,EAAE,KAAK,CAAC,aAAa;oBAClC,OAAO,EAAE,WAAW;oBACpB,YAAY,EAAE,gBAAgB;oBAC9B,cAAc;oBACd,UAAU;iBACX,CAAC,CAAC;YACL,CAAC;YAED,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;gBACxB,MAAM,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,KAAK,EAAE,gBAAgB,EAAE,KAAK,CAAC,aAAa,EAAE;oBAC/E,cAAc;oBACd,qBAAqB;oBACrB,aAAa,EAAE,6BAA6B,cAAc,EAAE;iBAC7D,CAAC,CAAC;gBACH,MAAM,CAAC,IAAI,CAAC,yCAAyC,EAAE;oBACrD,aAAa,EAAE,KAAK,CAAC,aAAa;oBAClC,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI;oBAC3B,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE;oBACvB,UAAU,EAAE,GAAG,CAAC,UAAU;oBAC1B,OAAO,EAAE,GAAG,CAAC,OAAO;oBACpB,YAAY,EAAE,GAAG,CAAC,YAAY;oBAC9B,UAAU,EAAE,cAAc;oBAC1B,UAAU;oBACV,OAAO,EAAE,gBAAgB;iBAC1B,CAAC,CAAC;gBACH,OAAO,eAAe,CAAC;oBACrB,aAAa,EAAE,KAAK,CAAC,aAAa;oBAClC,OAAO,EAAE,iBAAiB;oBAC1B,YAAY,EAAE,gBAAgB;oBAC9B,cAAc;oBACd,UAAU;iBACX,CAAC,CAAC;YACL,CAAC;YAED,gEAAgE;QAClE,CAAC;QAED,6DAA6D;QAC7D,oDAAoD;QACpD,MAAM,aAAa,GACjB,YAAY,IAAI,yBAAyB,cAAc,IAAI,SAAS,EAAE,CAAC;QAEzE,IAAI,gBAAgB,IAAI,YAAY,EAAE,CAAC;YACrC,MAAM,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,KAAK,EAAE,gBAAgB,EAAE,KAAK,CAAC,aAAa,EAAE;gBAC/E,cAAc;gBACd,qBAAqB;gBACrB,aAAa,EAAE,GAAG,aAAa,eAAe,YAAY,WAAW;aACtE,CAAC,CAAC;YACH,MAAM,CAAC,IAAI,CAAC,6CAA6C,EAAE;gBACzD,aAAa,EAAE,KAAK,CAAC,aAAa;gBAClC,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI;gBAC3B,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE;gBACvB,UAAU,EAAE,GAAG,CAAC,UAAU;gBAC1B,OAAO,EAAE,GAAG,CAAC,OAAO;gBACpB,YAAY,EAAE,GAAG,CAAC,YAAY;gBAC9B,UAAU,EAAE,cAAc;gBAC1B,UAAU;gBACV,OAAO,EAAE,gBAAgB;gBACzB,aAAa;aACd,CAAC,CAAC;YACH,OAAO,eAAe,CAAC;gBACrB,aAAa,EAAE,KAAK,CAAC,aAAa;gBAClC,OAAO,EAAE,iBAAiB;gBAC1B,YAAY,EAAE,gBAAgB;gBAC9B,cAAc;gBACd,UAAU;aACX,CAAC,CAAC;QACL,CAAC;QAED,MAAM,aAAa,GAAG,oBAAoB,CAAC,gBAAgB,CAAC,CAAC;QAC7D,MAAM,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,KAAK,EAAE,gBAAgB,EAAE,KAAK,CAAC,aAAa,EAAE;YAC/E,cAAc;YACd,qBAAqB;YACrB,aAAa;YACb,aAAa;SACd,CAAC,CAAC;QACH,QAAQ,CAAC,kCAAkC,EAAE;YAC3C,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI;YAC3B,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE;YACvB,UAAU,EAAE,GAAG,CAAC,UAAU;YAC1B,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,YAAY,EAAE,GAAG,CAAC,YAAY;YAC9B,UAAU,EAAE,cAAc;YAC1B,UAAU;YACV,OAAO,EAAE,gBAAgB;YACzB,aAAa,EAAE,aAAa,CAAC,WAAW,EAAE;YAC1C,aAAa;SACd,CAAC,CAAC;QACH,OAAO,eAAe,CAAC;YACrB,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,OAAO,EAAE,iBAAiB;YAC1B,YAAY,EAAE,gBAAgB;YAC9B,cAAc;YACd,UAAU;SACX,CAAC,CAAC;IACL,CAAC;CACF,CAAC,CAAC;AAEH,wEAAwE;AACxE,6EAA6E;AAC7E,qEAAqE;AACrE,sDAAsD","sourcesContent":["/**\n * M2M Webhook Delivery Batch Worker\n *\n * Event-triggered custom batch — one job per delivery row enqueued by\n * `M2MWebhookDispatcherBackendService.enqueueDelivery`. The worker:\n * 1. Re-reads the row from `M2MWebhookDeliveryLog` (ground truth —\n * we never trust in-flight queue state for the body or signature).\n * 2. Marks it `IN_FLIGHT` (incrementing `attemptCount`).\n * 3. Builds the JWT signature with `JwtPrivateKeys.APPLICATION_WEBHOOK`.\n * 4. POSTs the body with a 30s `AbortController` timeout.\n * 5. Classifies the response and records the terminal/intermediate\n * transition on the row.\n *\n * Status classification (D6):\n * - 2xx → DELIVERED (terminal success).\n * - 4xx, excluding 408 / 429 → FAILED (terminal — non-retryable).\n * - 408 / 429 / 5xx / network → mark failed attempt; if\n * `attemptCount >= MAX_ATTEMPTS`,\n * transition to FAILED.\n *\n * Custom batches are factory-created rather than constructor-injected. This\n * batch therefore declares its exact services through `resolveDependencies`;\n * the executor resolves them lazily for each invocation and `doHandle`\n * receives only the typed named result.\n *\n * @see m2m-webhook-organization-delivery.md — Phase 3 / Step 10\n * @see notifications/email/services/email-batch-send.batch.backend.service.ts\n * (precedent: same pattern for an event-triggered custom batch).\n */\n\nimport { z } from 'zod';\nimport {\n AuthScopeType,\n M2M_WEBHOOK_DELIVERY_CONTRACT,\n webhookEndpointDestinationHost,\n webhookEndpointTransportIsPlaintext,\n} from '@wildo-ai/saas-models';\nimport {\n createCustomBatchExecutionService,\n type BatchesCronjobsCustomExecution_Service,\n} from '~wildo-backend-lib/base-classes/services/batches/batches-cronjobs-custom-execution.service';\nimport { ENGINE_M2M_WEBHOOK_DELIVERY_BATCH_MANIFEST } from '~wildo-backend-lib/base-classes/services/batches/engine-custom-batch-manifests';\nimport { describeCaughtError, projectCaughtErrorLogFields } from '~wildo-backend-lib/errors/utils/error-log-level-classification.backend.utils';\nimport { SAAS_SERVICE_TYPES } from '~wildo-backend-lib/inject/models/service-types';\nimport type { JwtBackendService } from '~wildo-backend-lib/security/jwt/services/jwt.backend.service';\nimport { JwtPrivateKeys } from '~wildo-backend-lib/security/authentications/models/jwt.backend.schemas';\nimport type { MetricsService } from '~wildo-backend-lib/monitoring/observability/services/metrics.service';\nimport type { M2MWebhookDeliveryLogRepository } from '~wildo-backend-lib/notifications/webhooks/outbound/services/m2m-webhook-delivery-log.repository';\nimport {\n MAX_ATTEMPTS,\n classifyResponseStatus,\n computeNextAttemptAt,\n} from './m2m-webhook-delivery.batch.utils';\nimport { M2M_WEBHOOK_BODY_HASH_ALGORITHM, sendSignedWebhookRequest } from '../m2m-webhook-signed-request.backend.utils';\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Input / Output schemas\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * The dispatcher writes the row first, then enqueues this lightweight\n * payload. Keeping the payload minimal (id + scope) makes the worker\n * resilient to queue / DB race conditions: re-reading the row is the\n * source of truth.\n */\n/**\n * Endpoints already warned about in this process, so a permanently-plaintext destination costs one\n * line rather than one per delivery (#492).\n *\n * ## Why the warning is HERE, and why it is once\n *\n * Plaintext endpoints are ADMITTED — a commercial accommodation recorded on\n * `WebhookEndpointSchema.url` — and the cost of admitting them is that the decision becomes\n * invisible. The obvious place to say so is the moment an endpoint is SAVED, and that place does\n * not exist: `webhookConfig` declares CREATE and UPDATE `REPOSITORY_ONLY` with no admin route, and\n * the only writer that exists (data seeding) reaches the row through `upsertByBusinessKey`, a raw\n * repository call that no operation-pipeline hook observes. A postfix handler there would have been\n * a mechanism nothing runs — the shape this whole review exists to remove.\n *\n * The delivery IS the exposure, so this is where it can be stated truthfully: every POST over\n * `http://` puts the signature JWT on the wire in the clear, readable and replayable by anyone on\n * the path until it expires.\n *\n * Once per endpoint per process, because a webhook configuration is stable: a WARN on every\n * delivery would be a line an operator learns to filter, and a filtered warning is the same as no\n * warning. The set is bounded by the endpoint population and is deliberately NOT time-based — the\n * fact does not become news again after an hour, it becomes news again when the process restarts\n * and re-reads a configuration somebody may have changed.\n */\nconst PLAINTEXT_ENDPOINTS_ALREADY_WARNED = new Set<string>();\n\nexport const M2MWebhookDeliveryBatchInputSchema = z.object({\n scope: z.object({\n type: z.enum(AuthScopeType),\n id: z.string().min(1),\n }),\n deliveryLogId: z.string().min(1),\n});\n\nexport type M2MWebhookDeliveryBatchInput = z.infer<typeof M2MWebhookDeliveryBatchInputSchema>;\n\nexport const M2MWebhookDeliveryBatchOutputSchema = z.object({\n deliveryLogId: z.string(),\n /**\n * High-level outcome string. Stored only in the worker output for\n * cron / log inspection; the persisted truth lives on the row's\n * `status` field.\n */\n outcome: z.enum([\n 'delivered',\n 'retry_scheduled',\n 'failed_terminal',\n 'skipped_missing_row',\n 'skipped_already_leased',\n ]),\n attemptCount: z.number().int().nonnegative(),\n responseStatus: z.number().int().optional(),\n durationMs: z.number().int().nonnegative(),\n});\n\nexport type M2MWebhookDeliveryBatchOutput = z.infer<typeof M2MWebhookDeliveryBatchOutputSchema>;\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Batch Service\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport const m2mWebhookDeliveryBatchService: BatchesCronjobsCustomExecution_Service<\n typeof M2MWebhookDeliveryBatchInputSchema,\n typeof M2MWebhookDeliveryBatchOutputSchema\n> = createCustomBatchExecutionService({\n input: M2MWebhookDeliveryBatchInputSchema,\n output: M2MWebhookDeliveryBatchOutputSchema,\n batchCronjob_Context: {\n // Anchored on the `APPLICATION` primary scope rather than a fake\n // `ORGANIZATION_M2M_WEBHOOK_DELIVERY_LOG` operation: an event-triggered\n // polymorphic worker has no honest \"primary\" resource (each enqueued\n // row carries its own `scope: { type, id }` and routes to either\n // `ORGANIZATION_M2M_WEBHOOK_DELIVERY_LOG` or\n // `APPLICATION_M2M_WEBHOOK_DELIVERY_LOG` via\n // `resolveDeliveryLogResourceType` in\n // `m2m-webhook-delivery-log.repository.ts`).\n //\n // The bootstrap path inside\n // `ExecutionContextCreatorBackendService.createForInternalCustomBatch`\n // resolves an `APPLICATION.READ` operation, populates the application\n // id, then swaps in `notifications:m2m-webhook-delivery` via\n // `withOperation()`. Audit trails surface the honest batch identity\n // and authorization runs against `APP_ADMIN_SUPER_ADMIN @ APPLICATION`\n // (see `createInternalSystemRoles()`), exactly as before, but without\n // pretending the worker mutates the org-variant log on every job —\n // including for app-scoped deliveries where that anchor was a\n // flat-out lie. Per-row resource-type resolution (org vs app) stays\n // inside the worker and is driven off the per-row `input.scope.type`.\n kind: ENGINE_M2M_WEBHOOK_DELIVERY_BATCH_MANIFEST.kind,\n operationIdentifier: ENGINE_M2M_WEBHOOK_DELIVERY_BATCH_MANIFEST.operationIdentifier,\n primaryScope: ENGINE_M2M_WEBHOOK_DELIVERY_BATCH_MANIFEST.primaryScope,\n },\n resolveDependencies: ({ get }) => ({\n repository: get<M2MWebhookDeliveryLogRepository>(\n SAAS_SERVICE_TYPES.M2MWebhookDeliveryLogRepository,\n ),\n jwtService: get<JwtBackendService>(SAAS_SERVICE_TYPES.JwtBackendService),\n metricsService: get<MetricsService>(SAAS_SERVICE_TYPES.MetricsService),\n }),\n doHandle: async (input, { logger, executionContext, dependencies }) => {\n const startedAt = Date.now();\n const logDebug = logger.debugByType('M2MWebhookDeliveryBatch');\n const {\n repository: repo,\n jwtService,\n metricsService,\n } = dependencies;\n\n /**\n * Single funnel for every `doHandle` return-point. Mirrors the\n * batch output back to the caller while firing the Phase 5 /\n * Step 17 outcome counter exactly once per worker invocation.\n *\n * Kept inline (not extracted to a module-level helper) because it\n * closes over `metricsService` and `input.scope.type` — lifting it\n * would need re-threading both via parameters on every call site\n * and would dilute the fire-exactly-once contract this funnel\n * enforces.\n *\n * Metric emission is error-isolated for the same reason the audit\n * helper swallows its failures: observability MUST NEVER fail the\n * main flow. By the time `recordAndReturn` runs, the row has\n * already been persisted with the correct terminal/intermediate\n * status — letting an OpenTelemetry exporter glitch abort the\n * batch invocation here would leave the custom-batch runner\n * reporting the run as failed even though the real delivery\n * completed and the truth-source row reflects success.\n */\n const recordAndReturn = (\n output: M2MWebhookDeliveryBatchOutput,\n ): M2MWebhookDeliveryBatchOutput => {\n try {\n metricsService.recordM2MWebhookDeliveryOutcome({\n scope: input.scope.type,\n outcome: output.outcome,\n });\n } catch (error) {\n logger.warn('Failed to record M2M webhook delivery outcome metric', {\n deliveryLogId: input.deliveryLogId,\n scopeType: input.scope.type,\n scopeId: input.scope.id,\n outcome: output.outcome,\n ...projectCaughtErrorLogFields(error),\n });\n }\n return output;\n };\n\n // ── Load the row (ground truth) ────────────────────────────\n const row = await repo.read(input.scope, executionContext, input.deliveryLogId);\n if (!row) {\n // Possible if the row was purged between enqueue and worker\n // execution (admin `PURGE_OLD`). Quiet skip — there is nothing\n // to deliver and no caller to surface the absence to.\n logger.warn('Webhook delivery row not found; skipping', {\n deliveryLogId: input.deliveryLogId,\n scopeType: input.scope.type,\n scopeId: input.scope.id,\n });\n return recordAndReturn({\n deliveryLogId: input.deliveryLogId,\n outcome: 'skipped_missing_row',\n attemptCount: 0,\n durationMs: Date.now() - startedAt,\n });\n }\n\n const nextAttemptCount = (row.attemptCount ?? 0) + 1;\n\n // ── Lease the row (atomic CAS) ─────────────────────────────\n // `markInFlight` is a compare-and-swap on `status: PENDING`. If\n // another worker already leased the row (cron retry sweep + queue\n // redelivery race), the CAS returns false and we exit cleanly —\n // double-POSTs and double-counted attempts would corrupt the\n // retry budget and the consumer's idempotency guarantees.\n const leased = await repo.markInFlight(\n input.scope,\n executionContext,\n input.deliveryLogId,\n nextAttemptCount,\n );\n if (!leased) {\n logger.warn('Webhook delivery row already leased by another worker; skipping', {\n deliveryLogId: input.deliveryLogId,\n scopeType: input.scope.type,\n scopeId: input.scope.id,\n endpointId: row.endpointId,\n httpUrl: row.httpUrl,\n signatureJti: row.signatureJti,\n currentStatus: row.status,\n });\n return recordAndReturn({\n deliveryLogId: input.deliveryLogId,\n outcome: 'skipped_already_leased',\n attemptCount: row.attemptCount ?? 0,\n durationMs: Date.now() - startedAt,\n });\n }\n\n // ── Build the JWT signature (D5: claims-JWT) ───────────────\n // The body itself is NOT in the JWT — only its sha256 hash. This\n // keeps the header small (some HTTP intermediaries cap header\n // size) and lets consumers verify integrity independently of the\n // raw body bytes (which they can re-hash).\n const claims = {\n // `jti` is the consumer-facing dedup key. It is stable across\n // every retry of THIS delivery row (same value re-signed each\n // attempt) and unique across rows. Consumers MUST dedup on\n // `jti` — the rest of the token (`iat`, `exp`, signature) is\n // refreshed per attempt and so cannot serve as a replay marker.\n // See `m2m-webhook-dispatcher.backend.service.ts` (`signatureJti`\n // creation site) for the full consumer-contract JSDoc.\n // Claim NAMES come from the published receiver contract so the customer\n // documentation and this signing site cannot drift apart.\n [M2M_WEBHOOK_DELIVERY_CONTRACT.signatureClaims.deliveryId]: row.signatureJti,\n [M2M_WEBHOOK_DELIVERY_CONTRACT.signatureClaims.bodyHash]: row.payloadHash,\n [M2M_WEBHOOK_DELIVERY_CONTRACT.signatureClaims.bodyHashAlgorithm]: M2M_WEBHOOK_BODY_HASH_ALGORITHM,\n [M2M_WEBHOOK_DELIVERY_CONTRACT.signatureClaims.eventChannel]: row.channel,\n [M2M_WEBHOOK_DELIVERY_CONTRACT.signatureClaims.resourceIdentifier]: row.resourceIdentifier,\n [M2M_WEBHOOK_DELIVERY_CONTRACT.signatureClaims.operationIdentifier]: row.operationIdentifier,\n // `iss`, `iat`, `exp`, `aud`, `kid` defaults come from\n // `JwtPrivateKeySignOptions[APPLICATION_WEBHOOK]`. We don't\n // override them here — the consumer-facing contract is the\n // signing options table, not this call site.\n };\n\n let signature: string;\n try {\n signature = await jwtService.sign(claims, JwtPrivateKeys.APPLICATION_WEBHOOK);\n } catch (error) {\n // Signing failure is a configuration problem (missing key) —\n // re-trying won't help until the operator fixes secrets, so we\n // mark the row as terminally failed and let admin RETRY pick it\n // up after the fix.\n const reason = describeCaughtError(error);\n logger.error('Failed to sign webhook payload — marking delivery FAILED', {\n deliveryLogId: input.deliveryLogId,\n scopeType: input.scope.type,\n scopeId: input.scope.id,\n endpointId: row.endpointId,\n httpUrl: row.httpUrl,\n signatureJti: row.signatureJti,\n attempt: nextAttemptCount,\n error,\n });\n await repo.markFinallyFailed(input.scope, executionContext, input.deliveryLogId, {\n failureReason: `JWT signing failed: ${reason}`,\n });\n return recordAndReturn({\n deliveryLogId: input.deliveryLogId,\n outcome: 'failed_terminal',\n attemptCount: nextAttemptCount,\n durationMs: Date.now() - startedAt,\n });\n }\n\n // ── POST the body ──────────────────────────────────────────\n // Shared with the `webhookConfig.testEndpoint` probe (see\n // `../m2m-webhook-signed-request.backend.utils`). The admin-facing\n // connectivity test must exercise THIS transport, not a parallel one,\n // or a green test would prove nothing about real deliveries.\n const bodyBytes =\n typeof row.payload === 'string' ? row.payload : JSON.stringify(row.payload);\n\n if (webhookEndpointTransportIsPlaintext(row.httpUrl)) {\n const warnedKey = `${input.scope.type}:${input.scope.id}:${row.endpointId}`;\n if (!PLAINTEXT_ENDPOINTS_ALREADY_WARNED.has(warnedKey)) {\n PLAINTEXT_ENDPOINTS_ALREADY_WARNED.add(warnedKey);\n // NOT debug. The whole point is that an operator meets this without going looking, and\n // `AbstractControllerBackendService` disables the debug channel — the same trap that made a\n // readiness breakdown unreachable in #498.\n logger.warn('Webhook endpoint is plaintext: the delivery signature is sent in the clear', {\n scopeType: input.scope.type,\n scopeId: input.scope.id,\n endpointId: row.endpointId,\n // Host only, never the URL — a customer endpoint's path routinely carries a per-tenant\n // token, and this line reaches the ordinary log stream.\n destinationHost: webhookEndpointDestinationHost(row.httpUrl),\n exposure: 'The signature JWT is readable on the network path and replayable against this '\n + 'endpoint until it expires, so an observer of one delivery can forge the next.',\n remedy: 'Reconfigure this endpoint with an https:// URL.',\n });\n }\n }\n\n const { responseStatus, responseBodyTruncated, networkError } = await sendSignedWebhookRequest({\n url: row.httpUrl,\n body: bodyBytes,\n signature,\n });\n\n // Job-level duration: spans the row re-read and lease as well as the POST,\n // so it stays the batch's own measurement rather than the transport's.\n const durationMs = Date.now() - startedAt;\n\n // ── Classify + persist transition ──────────────────────────\n if (responseStatus !== undefined) {\n const verdict = classifyResponseStatus(responseStatus);\n\n if (verdict === 'delivered') {\n await repo.markDelivered(input.scope, executionContext, input.deliveryLogId, {\n responseStatus,\n responseBodyTruncated,\n });\n logDebug('Webhook delivered', {\n deliveryLogId: input.deliveryLogId,\n scopeType: input.scope.type,\n scopeId: input.scope.id,\n endpointId: row.endpointId,\n httpUrl: row.httpUrl,\n signatureJti: row.signatureJti,\n httpStatus: responseStatus,\n durationMs,\n attempt: nextAttemptCount,\n });\n return recordAndReturn({\n deliveryLogId: input.deliveryLogId,\n outcome: 'delivered',\n attemptCount: nextAttemptCount,\n responseStatus,\n durationMs,\n });\n }\n\n if (verdict === 'fatal') {\n await repo.markFinallyFailed(input.scope, executionContext, input.deliveryLogId, {\n responseStatus,\n responseBodyTruncated,\n failureReason: `non-retryable HTTP status ${responseStatus}`,\n });\n logger.warn('Webhook delivery failed (non-retryable)', {\n deliveryLogId: input.deliveryLogId,\n scopeType: input.scope.type,\n scopeId: input.scope.id,\n endpointId: row.endpointId,\n httpUrl: row.httpUrl,\n signatureJti: row.signatureJti,\n httpStatus: responseStatus,\n durationMs,\n attempt: nextAttemptCount,\n });\n return recordAndReturn({\n deliveryLogId: input.deliveryLogId,\n outcome: 'failed_terminal',\n attemptCount: nextAttemptCount,\n responseStatus,\n durationMs,\n });\n }\n\n // verdict === 'retry' — fall through to the retry branch below.\n }\n\n // Retryable failure (5xx, 408, 429, network/timeout). Decide\n // between scheduling another attempt and giving up.\n const failureReason =\n networkError ?? `retryable HTTP status ${responseStatus ?? 'unknown'}`;\n\n if (nextAttemptCount >= MAX_ATTEMPTS) {\n await repo.markFinallyFailed(input.scope, executionContext, input.deliveryLogId, {\n responseStatus,\n responseBodyTruncated,\n failureReason: `${failureReason} (retry cap ${MAX_ATTEMPTS} reached)`,\n });\n logger.warn('Webhook delivery failed (retry cap reached)', {\n deliveryLogId: input.deliveryLogId,\n scopeType: input.scope.type,\n scopeId: input.scope.id,\n endpointId: row.endpointId,\n httpUrl: row.httpUrl,\n signatureJti: row.signatureJti,\n httpStatus: responseStatus,\n durationMs,\n attempt: nextAttemptCount,\n failureReason,\n });\n return recordAndReturn({\n deliveryLogId: input.deliveryLogId,\n outcome: 'failed_terminal',\n attemptCount: nextAttemptCount,\n responseStatus,\n durationMs,\n });\n }\n\n const nextAttemptAt = computeNextAttemptAt(nextAttemptCount);\n await repo.markFailedAttempt(input.scope, executionContext, input.deliveryLogId, {\n responseStatus,\n responseBodyTruncated,\n failureReason,\n nextAttemptAt,\n });\n logDebug('Webhook delivery retry scheduled', {\n deliveryLogId: input.deliveryLogId,\n scopeType: input.scope.type,\n scopeId: input.scope.id,\n endpointId: row.endpointId,\n httpUrl: row.httpUrl,\n signatureJti: row.signatureJti,\n httpStatus: responseStatus,\n durationMs,\n attempt: nextAttemptCount,\n nextAttemptAt: nextAttemptAt.toISOString(),\n failureReason,\n });\n return recordAndReturn({\n deliveryLogId: input.deliveryLogId,\n outcome: 'retry_scheduled',\n attemptCount: nextAttemptCount,\n responseStatus,\n durationMs,\n });\n },\n});\n\n// Batch reference identifier lives in the declarative manifest registry\n// (`engine-custom-batch-manifests`); import `M2M_WEBHOOK_DELIVERY_BATCH_REF`\n// from there to keep a single source of truth across runtime wiring,\n// queue dispatch, and specification cross-validation.\n"]}
1
+ {"version":3,"file":"m2m-webhook-delivery.batch.backend.service.js","sourceRoot":"","sources":["../../../../../../src/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.backend.service.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * M2M Webhook Delivery Batch Worker\n *\n * Event-triggered custom batch — one job per delivery row enqueued by\n * `M2MWebhookDispatcherBackendService.enqueueDelivery`. The worker:\n * 1. Re-reads the row from `M2MWebhookDeliveryLog` (ground truth —\n * we never trust in-flight queue state for the body or signature).\n * 2. Marks it `IN_FLIGHT` (incrementing `attemptCount`).\n * 3. Builds the JWT signature with `JwtPrivateKeys.APPLICATION_WEBHOOK`.\n * 4. POSTs the body with a 30s `AbortController` timeout.\n * 5. Classifies the response and records the terminal/intermediate\n * transition on the row.\n *\n * Status classification (D6):\n * - 2xx → DELIVERED (terminal success).\n * - 4xx, excluding 408 / 429 → FAILED (terminal — non-retryable).\n * - 408 / 429 / 5xx / network → mark failed attempt; if\n * `attemptCount >= MAX_ATTEMPTS`,\n * transition to FAILED.\n *\n * Custom batches are factory-created rather than constructor-injected. This\n * batch therefore declares its exact services through `resolveDependencies`;\n * the executor resolves them lazily for each invocation and `doHandle`\n * receives only the typed named result.\n *\n * @see m2m-webhook-organization-delivery.md — Phase 3 / Step 10\n * @see notifications/email/services/email-batch-send.batch.backend.service.ts\n * (precedent: same pattern for an event-triggered custom batch).\n */\n\nimport { z } from 'zod';\nimport {\n AuthScopeType,\n M2M_WEBHOOK_DELIVERY_CONTRACT,\n webhookEndpointDestinationHost,\n webhookEndpointTransportIsPlaintext,\n} from '@wildo-ai/saas-models';\nimport {\n createCustomBatchExecutionService,\n type BatchesCronjobsCustomExecution_Service,\n} from '~wildo-backend-lib/base-classes/services/batches/batches-cronjobs-custom-execution.service';\nimport { ENGINE_M2M_WEBHOOK_DELIVERY_BATCH_MANIFEST } from '~wildo-backend-lib/base-classes/services/batches/engine-custom-batch-manifests';\nimport { describeCaughtError, projectCaughtErrorLogFields } from '~wildo-backend-lib/errors/utils/error-log-level-classification.backend.utils';\nimport { SAAS_SERVICE_TYPES } from '~wildo-backend-lib/inject/models/service-types';\nimport type { JwtBackendService } from '~wildo-backend-lib/security/jwt/services/jwt.backend.service';\nimport { JwtPrivateKeys } from '~wildo-backend-lib/security/authentications/models/jwt.backend.schemas';\nimport type { MetricsService } from '~wildo-backend-lib/monitoring/observability/services/metrics.service';\nimport type { M2MWebhookDeliveryLogRepository } from '~wildo-backend-lib/notifications/webhooks/outbound/services/m2m-webhook-delivery-log.repository';\nimport {\n MAX_ATTEMPTS,\n classifyResponseStatus,\n computeNextAttemptAt,\n} from './m2m-webhook-delivery.batch.utils';\nimport { M2M_WEBHOOK_BODY_HASH_ALGORITHM, sendSignedWebhookRequest } from '../m2m-webhook-signed-request.backend.utils';\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Input / Output schemas\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * The dispatcher writes the row first, then enqueues this lightweight\n * payload. Keeping the payload minimal (id + scope) makes the worker\n * resilient to queue / DB race conditions: re-reading the row is the\n * source of truth.\n */\n/**\n * Endpoints already warned about in this process, so a permanently-plaintext destination costs one\n * line rather than one per delivery (#492).\n *\n * ## Why the warning is HERE, and why it is once\n *\n * Plaintext endpoints are ADMITTED — a commercial accommodation recorded on\n * `WebhookEndpointSchema.url` — and the cost of admitting them is that the decision becomes\n * invisible. The obvious place to say so is the moment an endpoint is SAVED, and that place does\n * not exist: `webhookConfig` declares CREATE and UPDATE `REPOSITORY_ONLY` with no admin route, and\n * the only writer that exists (data seeding) reaches the row through `upsertByBusinessKey`, a raw\n * repository call that no operation-pipeline hook observes. A postfix handler there would have been\n * a mechanism nothing runs — the shape this whole review exists to remove.\n *\n * The delivery IS the exposure, so this is where it can be stated truthfully: every POST over\n * `http://` puts the signature JWT on the wire in the clear, readable and replayable by anyone on\n * the path until it expires.\n *\n * Once per endpoint per process, because a webhook configuration is stable: a WARN on every\n * delivery would be a line an operator learns to filter, and a filtered warning is the same as no\n * warning. The set is bounded by the endpoint population and is deliberately NOT time-based — the\n * fact does not become news again after an hour, it becomes news again when the process restarts\n * and re-reads a configuration somebody may have changed.\n */\nconst PLAINTEXT_ENDPOINTS_ALREADY_WARNED = new Set<string>();\n\nexport const M2MWebhookDeliveryBatchInputSchema = z.object({\n scope: z.object({\n type: z.enum(AuthScopeType),\n id: z.string().min(1),\n }),\n deliveryLogId: z.string().min(1),\n});\n\nexport type M2MWebhookDeliveryBatchInput = z.infer<typeof M2MWebhookDeliveryBatchInputSchema>;\n\nexport const M2MWebhookDeliveryBatchOutputSchema = z.object({\n deliveryLogId: z.string(),\n /**\n * High-level outcome string. Stored only in the worker output for\n * cron / log inspection; the persisted truth lives on the row's\n * `status` field.\n */\n outcome: z.enum([\n 'delivered',\n 'retry_scheduled',\n 'failed_terminal',\n 'skipped_missing_row',\n 'skipped_already_leased',\n ]),\n attemptCount: z.number().int().nonnegative(),\n responseStatus: z.number().int().optional(),\n durationMs: z.number().int().nonnegative(),\n});\n\nexport type M2MWebhookDeliveryBatchOutput = z.infer<typeof M2MWebhookDeliveryBatchOutputSchema>;\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Batch Service\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport const m2mWebhookDeliveryBatchService: BatchesCronjobsCustomExecution_Service<\n typeof M2MWebhookDeliveryBatchInputSchema,\n typeof M2MWebhookDeliveryBatchOutputSchema\n> = createCustomBatchExecutionService({\n input: M2MWebhookDeliveryBatchInputSchema,\n output: M2MWebhookDeliveryBatchOutputSchema,\n batchCronjob_Context: {\n // Anchored on the `APPLICATION` primary scope rather than a fake\n // `ORGANIZATION_M2M_WEBHOOK_DELIVERY_LOG` operation: an event-triggered\n // polymorphic worker has no honest \"primary\" resource (each enqueued\n // row carries its own `scope: { type, id }` and routes to either\n // `ORGANIZATION_M2M_WEBHOOK_DELIVERY_LOG` or\n // `APPLICATION_M2M_WEBHOOK_DELIVERY_LOG` via\n // `resolveDeliveryLogResourceType` in\n // `m2m-webhook-delivery-log.repository.ts`).\n //\n // The bootstrap path inside\n // `ExecutionContextCreatorBackendService.createForInternalCustomBatch`\n // resolves an `APPLICATION.READ` operation, populates the application\n // id, then swaps in `notifications:m2m-webhook-delivery` via\n // `withOperation()`. Audit trails surface the honest batch identity\n // and authorization runs against `APP_ADMIN_SUPER_ADMIN @ APPLICATION`\n // (see `createInternalSystemRoles()`), exactly as before, but without\n // pretending the worker mutates the org-variant log on every job —\n // including for app-scoped deliveries where that anchor was a\n // flat-out lie. Per-row resource-type resolution (org vs app) stays\n // inside the worker and is driven off the per-row `input.scope.type`.\n kind: ENGINE_M2M_WEBHOOK_DELIVERY_BATCH_MANIFEST.kind,\n operationIdentifier: ENGINE_M2M_WEBHOOK_DELIVERY_BATCH_MANIFEST.operationIdentifier,\n primaryScope: ENGINE_M2M_WEBHOOK_DELIVERY_BATCH_MANIFEST.primaryScope,\n },\n resolveDependencies: ({ get }) => ({\n repository: get<M2MWebhookDeliveryLogRepository>(\n SAAS_SERVICE_TYPES.M2MWebhookDeliveryLogRepository,\n ),\n jwtService: get<JwtBackendService>(SAAS_SERVICE_TYPES.JwtBackendService),\n metricsService: get<MetricsService>(SAAS_SERVICE_TYPES.MetricsService),\n }),\n doHandle: async (input, { logger, executionContext, dependencies }) => {\n const startedAt = Date.now();\n const logDebug = logger.debugByType('M2MWebhookDeliveryBatch');\n const {\n repository: repo,\n jwtService,\n metricsService,\n } = dependencies;\n\n /**\n * Single funnel for every `doHandle` return-point. Mirrors the\n * batch output back to the caller while firing the Phase 5 /\n * Step 17 outcome counter exactly once per worker invocation.\n *\n * Kept inline (not extracted to a module-level helper) because it\n * closes over `metricsService` and `input.scope.type` — lifting it\n * would need re-threading both via parameters on every call site\n * and would dilute the fire-exactly-once contract this funnel\n * enforces.\n *\n * Metric emission is error-isolated for the same reason the audit\n * helper swallows its failures: observability MUST NEVER fail the\n * main flow. By the time `recordAndReturn` runs, the row has\n * already been persisted with the correct terminal/intermediate\n * status — letting an OpenTelemetry exporter glitch abort the\n * batch invocation here would leave the custom-batch runner\n * reporting the run as failed even though the real delivery\n * completed and the truth-source row reflects success.\n */\n const recordAndReturn = (\n output: M2MWebhookDeliveryBatchOutput,\n ): M2MWebhookDeliveryBatchOutput => {\n try {\n metricsService.recordM2MWebhookDeliveryOutcome({\n scope: input.scope.type,\n outcome: output.outcome,\n });\n } catch (error) {\n logger.warn('Failed to record M2M webhook delivery outcome metric', {\n deliveryLogId: input.deliveryLogId,\n scopeType: input.scope.type,\n scopeId: input.scope.id,\n outcome: output.outcome,\n ...projectCaughtErrorLogFields(error),\n });\n }\n return output;\n };\n\n // ── Load the row (ground truth) ────────────────────────────\n const row = await repo.read(input.scope, executionContext, input.deliveryLogId);\n if (!row) {\n // Possible if the row was purged between enqueue and worker\n // execution (admin `PURGE_OLD`). Quiet skip — there is nothing\n // to deliver and no caller to surface the absence to.\n logger.warn('Webhook delivery row not found; skipping', {\n deliveryLogId: input.deliveryLogId,\n scopeType: input.scope.type,\n scopeId: input.scope.id,\n });\n return recordAndReturn({\n deliveryLogId: input.deliveryLogId,\n outcome: 'skipped_missing_row',\n attemptCount: 0,\n durationMs: Date.now() - startedAt,\n });\n }\n\n const nextAttemptCount = (row.attemptCount ?? 0) + 1;\n\n // ── Lease the row (atomic CAS) ─────────────────────────────\n // `markInFlight` is a compare-and-swap on `status: PENDING`. If\n // another worker already leased the row (cron retry sweep + queue\n // redelivery race), the CAS returns false and we exit cleanly —\n // double-POSTs and double-counted attempts would corrupt the\n // retry budget and the consumer's idempotency guarantees.\n const leased = await repo.markInFlight(\n input.scope,\n executionContext,\n input.deliveryLogId,\n nextAttemptCount,\n );\n if (!leased) {\n logger.warn('Webhook delivery row already leased by another worker; skipping', {\n deliveryLogId: input.deliveryLogId,\n scopeType: input.scope.type,\n scopeId: input.scope.id,\n endpointId: row.endpointId,\n httpUrl: row.httpUrl,\n signatureJti: row.signatureJti,\n currentStatus: row.status,\n });\n return recordAndReturn({\n deliveryLogId: input.deliveryLogId,\n outcome: 'skipped_already_leased',\n attemptCount: row.attemptCount ?? 0,\n durationMs: Date.now() - startedAt,\n });\n }\n\n // ── Build the JWT signature (D5: claims-JWT) ───────────────\n // The body itself is NOT in the JWT — only its sha256 hash. This\n // keeps the header small (some HTTP intermediaries cap header\n // size) and lets consumers verify integrity independently of the\n // raw body bytes (which they can re-hash).\n const claims = {\n // `jti` is the consumer-facing dedup key. It is stable across\n // every retry of THIS delivery row (same value re-signed each\n // attempt) and unique across rows. Consumers MUST dedup on\n // `jti` — the rest of the token (`iat`, `exp`, signature) is\n // refreshed per attempt and so cannot serve as a replay marker.\n // See `m2m-webhook-dispatcher.backend.service.ts` (`signatureJti`\n // creation site) for the full consumer-contract JSDoc.\n // Claim NAMES come from the published receiver contract so the customer\n // documentation and this signing site cannot drift apart.\n [M2M_WEBHOOK_DELIVERY_CONTRACT.signatureClaims.deliveryId]: row.signatureJti,\n [M2M_WEBHOOK_DELIVERY_CONTRACT.signatureClaims.bodyHash]: row.payloadHash,\n [M2M_WEBHOOK_DELIVERY_CONTRACT.signatureClaims.bodyHashAlgorithm]: M2M_WEBHOOK_BODY_HASH_ALGORITHM,\n [M2M_WEBHOOK_DELIVERY_CONTRACT.signatureClaims.eventChannel]: row.channel,\n [M2M_WEBHOOK_DELIVERY_CONTRACT.signatureClaims.resourceIdentifier]: row.resourceIdentifier,\n [M2M_WEBHOOK_DELIVERY_CONTRACT.signatureClaims.operationIdentifier]: row.operationIdentifier,\n // `iss`, `iat`, `exp`, `aud`, `kid` defaults come from\n // `JwtPrivateKeySignOptions[APPLICATION_WEBHOOK]`. We don't\n // override them here — the consumer-facing contract is the\n // signing options table, not this call site.\n };\n\n let signature: string;\n try {\n signature = await jwtService.sign(claims, JwtPrivateKeys.APPLICATION_WEBHOOK);\n } catch (error) {\n // Signing failure is a configuration problem (missing key) —\n // re-trying won't help until the operator fixes secrets, so we\n // mark the row as terminally failed and let admin RETRY pick it\n // up after the fix.\n const reason = describeCaughtError(error);\n logger.error('Failed to sign webhook payload — marking delivery FAILED', {\n deliveryLogId: input.deliveryLogId,\n scopeType: input.scope.type,\n scopeId: input.scope.id,\n endpointId: row.endpointId,\n httpUrl: row.httpUrl,\n signatureJti: row.signatureJti,\n attempt: nextAttemptCount,\n error,\n });\n await repo.markFinallyFailed(input.scope, executionContext, input.deliveryLogId, {\n failureReason: `JWT signing failed: ${reason}`,\n });\n return recordAndReturn({\n deliveryLogId: input.deliveryLogId,\n outcome: 'failed_terminal',\n attemptCount: nextAttemptCount,\n durationMs: Date.now() - startedAt,\n });\n }\n\n // ── POST the body ──────────────────────────────────────────\n // Shared with the `webhookConfig.testEndpoint` probe (see\n // `../m2m-webhook-signed-request.backend.utils`). The admin-facing\n // connectivity test must exercise THIS transport, not a parallel one,\n // or a green test would prove nothing about real deliveries.\n const bodyBytes =\n typeof row.payload === 'string' ? row.payload : JSON.stringify(row.payload);\n\n if (webhookEndpointTransportIsPlaintext(row.httpUrl)) {\n const warnedKey = `${input.scope.type}:${input.scope.id}:${row.endpointId}`;\n if (!PLAINTEXT_ENDPOINTS_ALREADY_WARNED.has(warnedKey)) {\n PLAINTEXT_ENDPOINTS_ALREADY_WARNED.add(warnedKey);\n // NOT debug. The whole point is that an operator meets this without going looking, and\n // `AbstractControllerBackendService` disables the debug channel — the same trap that made a\n // readiness breakdown unreachable in #498.\n logger.warn('Webhook endpoint is plaintext: the delivery signature is sent in the clear', {\n scopeType: input.scope.type,\n scopeId: input.scope.id,\n endpointId: row.endpointId,\n // Host only, never the URL — a customer endpoint's path routinely carries a per-tenant\n // token, and this line reaches the ordinary log stream.\n destinationHost: webhookEndpointDestinationHost(row.httpUrl),\n exposure: 'The signature JWT is readable on the network path and replayable against this '\n + 'endpoint until it expires, so an observer of one delivery can forge the next.',\n remedy: 'Reconfigure this endpoint with an https:// URL.',\n });\n }\n }\n\n const { responseStatus, responseBodyTruncated, networkError } = await sendSignedWebhookRequest({\n url: row.httpUrl,\n body: bodyBytes,\n signature,\n });\n\n // Job-level duration: spans the row re-read and lease as well as the POST,\n // so it stays the batch's own measurement rather than the transport's.\n const durationMs = Date.now() - startedAt;\n\n // ── Classify + persist transition ──────────────────────────\n if (responseStatus !== undefined) {\n const verdict = classifyResponseStatus(responseStatus);\n\n if (verdict === 'delivered') {\n await repo.markDelivered(input.scope, executionContext, input.deliveryLogId, {\n responseStatus,\n responseBodyTruncated,\n });\n logDebug('Webhook delivered', {\n deliveryLogId: input.deliveryLogId,\n scopeType: input.scope.type,\n scopeId: input.scope.id,\n endpointId: row.endpointId,\n httpUrl: row.httpUrl,\n signatureJti: row.signatureJti,\n httpStatus: responseStatus,\n durationMs,\n attempt: nextAttemptCount,\n });\n return recordAndReturn({\n deliveryLogId: input.deliveryLogId,\n outcome: 'delivered',\n attemptCount: nextAttemptCount,\n responseStatus,\n durationMs,\n });\n }\n\n if (verdict === 'fatal') {\n await repo.markFinallyFailed(input.scope, executionContext, input.deliveryLogId, {\n responseStatus,\n responseBodyTruncated,\n failureReason: `non-retryable HTTP status ${responseStatus}`,\n });\n logger.warn('Webhook delivery failed (non-retryable)', {\n deliveryLogId: input.deliveryLogId,\n scopeType: input.scope.type,\n scopeId: input.scope.id,\n endpointId: row.endpointId,\n httpUrl: row.httpUrl,\n signatureJti: row.signatureJti,\n httpStatus: responseStatus,\n durationMs,\n attempt: nextAttemptCount,\n });\n return recordAndReturn({\n deliveryLogId: input.deliveryLogId,\n outcome: 'failed_terminal',\n attemptCount: nextAttemptCount,\n responseStatus,\n durationMs,\n });\n }\n\n // verdict === 'retry' — fall through to the retry branch below.\n }\n\n // Retryable failure (5xx, 408, 429, network/timeout). Decide\n // between scheduling another attempt and giving up.\n const failureReason =\n networkError ?? `retryable HTTP status ${responseStatus ?? 'unknown'}`;\n\n if (nextAttemptCount >= MAX_ATTEMPTS) {\n await repo.markFinallyFailed(input.scope, executionContext, input.deliveryLogId, {\n responseStatus,\n responseBodyTruncated,\n failureReason: `${failureReason} (retry cap ${MAX_ATTEMPTS} reached)`,\n });\n logger.warn('Webhook delivery failed (retry cap reached)', {\n deliveryLogId: input.deliveryLogId,\n scopeType: input.scope.type,\n scopeId: input.scope.id,\n endpointId: row.endpointId,\n httpUrl: row.httpUrl,\n signatureJti: row.signatureJti,\n httpStatus: responseStatus,\n durationMs,\n attempt: nextAttemptCount,\n failureReason,\n });\n return recordAndReturn({\n deliveryLogId: input.deliveryLogId,\n outcome: 'failed_terminal',\n attemptCount: nextAttemptCount,\n responseStatus,\n durationMs,\n });\n }\n\n const nextAttemptAt = computeNextAttemptAt(nextAttemptCount);\n await repo.markFailedAttempt(input.scope, executionContext, input.deliveryLogId, {\n responseStatus,\n responseBodyTruncated,\n failureReason,\n nextAttemptAt,\n });\n logDebug('Webhook delivery retry scheduled', {\n deliveryLogId: input.deliveryLogId,\n scopeType: input.scope.type,\n scopeId: input.scope.id,\n endpointId: row.endpointId,\n httpUrl: row.httpUrl,\n signatureJti: row.signatureJti,\n httpStatus: responseStatus,\n durationMs,\n attempt: nextAttemptCount,\n nextAttemptAt: nextAttemptAt.toISOString(),\n failureReason,\n });\n return recordAndReturn({\n deliveryLogId: input.deliveryLogId,\n outcome: 'retry_scheduled',\n attemptCount: nextAttemptCount,\n responseStatus,\n durationMs,\n });\n },\n});\n\n// Batch reference identifier lives in the declarative manifest registry\n// (`engine-custom-batch-manifests`); import `M2M_WEBHOOK_DELIVERY_BATCH_REF`\n// from there to keep a single source of truth across runtime wiring,\n// queue dispatch, and specification cross-validation.\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"m2m-webhook-delivery.batch.utils.d.ts","sourceRoot":"","sources":["../../../../../../../src/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAWH,8DAA8D;AAC9D,eAAO,MAAM,YAAY,EAAE,MAAkD,CAAC;AAE9E,kDAAkD;AAClD,eAAO,MAAM,kBAAkB,EAAE,MAAuD,CAAC;AAEzF,uEAAuE;AACvE,eAAO,MAAM,8BAA8B,EAAE,MAAkE,CAAC;AAEhH,4DAA4D;AAC5D,eAAO,MAAM,kBAAkB,EAAE,MAAgD,CAAC;AAElF;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,EAAE,SAAS,MAAM,EAAyD,CAAC;AAIhH;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,GACb,WAAW,GAAG,OAAO,GAAG,OAAO,CASjC;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA0BjD;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAInE"}
1
+ {"version":3,"file":"m2m-webhook-delivery.batch.utils.d.ts","sourceRoot":"","sources":["../../../../../../src/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAWH,8DAA8D;AAC9D,eAAO,MAAM,YAAY,EAAE,MAAkD,CAAC;AAE9E,kDAAkD;AAClD,eAAO,MAAM,kBAAkB,EAAE,MAAuD,CAAC;AAEzF,uEAAuE;AACvE,eAAO,MAAM,8BAA8B,EAAE,MAAkE,CAAC;AAEhH,4DAA4D;AAC5D,eAAO,MAAM,kBAAkB,EAAE,MAAgD,CAAC;AAElF;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,EAAE,SAAS,MAAM,EAAyD,CAAC;AAIhH;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,GACb,WAAW,GAAG,OAAO,GAAG,OAAO,CASjC;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA0BjD;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAInE"}
@@ -1 +1 @@
1
- {"version":3,"file":"m2m-webhook-signed-request.backend.utils.d.ts","sourceRoot":"","sources":["../../../../../../src/notifications/webhooks/outbound/m2m-webhook-signed-request.backend.utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,6BAA6B,EAAmB,MAAM,uBAAuB,CAAC;AA4EvF,8EAA8E;AAC9E,eAAO,MAAM,+BAA+B,EAAE,OAAO,6BAA6B,CAAC,iBAAmE,CAAC;AAEvJ;;;;;;;;GAQG;AACH,MAAM,MAAM,0BAA0B,GAAG;IACvC,2DAA2D;IAC3D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,0FAA0F;IAC1F,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,uFAAuF;IACvF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iFAAiF;IACjF,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAuCF;;;;;;;;;GASG;AACH,wBAAsB,wBAAwB,CAAC,MAAM,EAAE;IACrD,gCAAgC;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAsEtC"}
1
+ {"version":3,"file":"m2m-webhook-signed-request.backend.utils.d.ts","sourceRoot":"","sources":["../../../../../src/notifications/webhooks/outbound/m2m-webhook-signed-request.backend.utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,6BAA6B,EAAmB,MAAM,uBAAuB,CAAC;AA4EvF,8EAA8E;AAC9E,eAAO,MAAM,+BAA+B,EAAE,OAAO,6BAA6B,CAAC,iBAAmE,CAAC;AAEvJ;;;;;;;;GAQG;AACH,MAAM,MAAM,0BAA0B,GAAG;IACvC,2DAA2D;IAC3D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,0FAA0F;IAC1F,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,uFAAuF;IACvF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iFAAiF;IACjF,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAuCF;;;;;;;;;GASG;AACH,wBAAsB,wBAAwB,CAAC,MAAM,EAAE;IACrD,gCAAgC;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAsEtC"}
@@ -1 +1 @@
1
- {"version":3,"file":"m2m-webhook-signed-request.backend.utils.js","sourceRoot":"","sources":["../../../../../../src/notifications/webhooks/outbound/m2m-webhook-signed-request.backend.utils.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The single outbound-transport primitive for M2M webhooks.\n *\n * Every signed request Wildo emits to a customer endpoint goes through\n * {@link sendSignedWebhookRequest} — the retry worker's real deliveries AND the\n * `webhookConfig.testEndpoint` synthetic probe. Two call sites, one implementation, on\n * purpose: a probe that reached the endpoint through a *different* code path would\n * validate that path rather than the delivery path, which is precisely the reassurance an\n * admin is asking for when they press \"test\". Timeout, User-Agent, signature header name,\n * and body-truncation behaviour are therefore not re-decided per caller.\n *\n * Scope boundary — this module owns the WIRE, nothing else. It does not sign (callers hold\n * their own claims), does not classify (see `classifyResponseStatus`), does not persist,\n * and never throws on a transport failure: an unreachable endpoint is data the caller must\n * report, not an exception. The only way to get an exception out of here is to pass\n * something that is not a valid request.\n *\n * The tunables come from `./batches/m2m-webhook-delivery.batch.utils`, which is\n * deliberately import-free so its pure-decision tests load without the DI graph. They are\n * left there rather than moved up here precisely to preserve that property — this module\n * performs I/O and would drag `@wildo-ai/saas-models` into those tests.\n *\n * @see batches/m2m-webhook-delivery.batch.backend.service.ts — real deliveries.\n * @see services/webhook-config-test-endpoint.custom-impl.backend.service.ts — synthetic probe.\n */\n\nimport { M2M_WEBHOOK_DELIVERY_CONTRACT, WildoHeaderKeys } from '@wildo-ai/saas-models';\nimport {\n OutboundTargetRejection,\n classifyOutboundTargetUrl,\n} from '~wildo-backend-lib/security/ssrf/outbound-target-guard.backend.utils';\nimport {\n REQUEST_TIMEOUT_MS,\n WEBHOOK_USER_AGENT,\n truncateBody,\n} from './batches/m2m-webhook-delivery.batch.utils';\n\n/**\n * Schemes an outbound webhook delivery may use.\n *\n * `http:` is admitted. DECIDED 2026-09-08 (#492): keep admitting it, and document the exposure where\n * a customer authors the endpoint — which is now done, on `WebhookEndpointSchema.url`.\n *\n * This is a COMMERCIAL accommodation, not a security assessment, and the distinction is the whole\n * point of writing it down. The A2A sibling requires HTTPS unconditionally and the same argument\n * applies here — the signature JWT in transit is a credential, readable on the path and replayable\n * until it expires, so an observer of one delivery can forge the next. What was chosen is not to break\n * endpoints that a previous version of the framework accepted.\n *\n * The two options NOT taken, either of which is the better security answer: require HTTPS with a\n * migration that identifies and notifies existing plaintext endpoints, or require it for new endpoints\n * and grandfather existing ones behind an explicit acknowledgement. The second is the one to revisit\n * first — it stops the plaintext population growing without breaking anyone today.\n *\n * Reopen on an observed interception, or on a customer compliance requirement. Do not reopen it as a\n * tidy-up: the asymmetry with the A2A caller is deliberate and is recorded at both sites.\n */\nconst M2M_WEBHOOK_ADMITTED_PROTOCOLS = ['https:', 'http:'] as const;\n\n/**\n * Refuse a destination that would turn this server into a request-forgery tool.\n *\n * ## Why the guard is HERE and not on the schema\n *\n * `WebhookEndpointSchema.url` validates shape (`z.url()`) and nothing else, so an admin could author\n * `http://169.254.169.254/latest/meta-data/` and the engine would POST signed payloads to the cloud\n * instance-metadata service — then capture the answer into the delivery log as\n * `responseBodyTruncated`. That makes it a READ primitive, not a blind SSRF, and\n * `webhookConfig.testEndpoint` is a low-friction oracle for it.\n *\n * A schema refine would leave two holes this placement does not have: it would not cover endpoints\n * ALREADY STORED before the refine existed, and it would not cover the A2A push-delivery worker,\n * which reaches this same primitive with a URL its own (separate) guard validated at configuration\n * time. Putting the check at the wire makes it unbypassable for every caller — present and future —\n * which is what `.claude/rules/invariant-call-site-enumeration.md` means by preferring one\n * chokepoint over N hand-applied predicates.\n *\n * ## What it cannot do\n *\n * An ordinary hostname is not resolved, so `hook.attacker.test` with an A record of `169.254.169.254`\n * still passes. That residual is inherited from the shared classifier and is stated there; closing it\n * needs either a resolving check (a check-then-connect, still open to rebinding) or egress-path\n * enforcement. It is a deliberate open item, not an oversight.\n */\nfunction refuseUnsafeWebhookTarget(url: string): string | undefined {\n const rejection = classifyOutboundTargetUrl(url, { admittedProtocols: M2M_WEBHOOK_ADMITTED_PROTOCOLS });\n switch (rejection) {\n case undefined:\n return undefined;\n case OutboundTargetRejection.NOT_ABSOLUTE_ADMITTED_SCHEME:\n return 'refused: endpoint is not an absolute http(s) URL';\n case OutboundTargetRejection.CREDENTIALS_IN_URL:\n // Credentials in the URL would be replayed on every delivery and would land in any log or\n // delivery row that records the target.\n return 'refused: endpoint URL carries embedded credentials';\n case OutboundTargetRejection.PRIVATE_OR_RESERVED_ADDRESS:\n return 'refused: endpoint resolves to a private, loopback, link-local or otherwise reserved address';\n case OutboundTargetRejection.RESERVED_SPECIAL_USE_HOSTNAME:\n return 'refused: endpoint uses a reserved special-use hostname';\n }\n}\n\n/** Consumer-facing digest algorithm carried in every outbound webhook JWT. */\nexport const M2M_WEBHOOK_BODY_HASH_ALGORITHM: typeof M2M_WEBHOOK_DELIVERY_CONTRACT.bodyHashAlgorithm = M2M_WEBHOOK_DELIVERY_CONTRACT.bodyHashAlgorithm;\n\n/**\n * Outcome of one attempt at the wire level.\n *\n * `responseStatus` and `networkError` are mutually exclusive and exhaustive: either the\n * endpoint produced an HTTP response or it did not. Callers classify from there — this\n * type deliberately carries no verdict of its own, because \"429 is retryable\" is a\n * delivery-policy question and \"429 means the endpoint is reachable\" is a probe question,\n * and the same status answers both differently.\n */\nexport type SignedWebhookRequestResult = {\n /** Set when the endpoint answered, whatever the status. */\n responseStatus?: number;\n /** Best-effort capture of the consumer's response body, truncated on a UTF-8 boundary. */\n responseBodyTruncated?: string;\n /** Set when no HTTP response was obtained (DNS/TLS/connection failure, or timeout). */\n networkError?: string;\n /** Wall-clock duration of this attempt alone, excluding any caller-side work. */\n durationMs: number;\n};\n\n/**\n * Render a `fetch` rejection into something an operator can act on.\n *\n * Node's `fetch` (undici) rejects with a flat `TypeError: fetch failed` and buries the actual\n * cause — `ECONNREFUSED`, `ENOTFOUND`, `EHOSTUNREACH`, a TLS failure — one or more levels down in\n * `error.cause`. Reporting only `error.message` tells an admin their endpoint failed without\n * telling them whether the hostname is wrong, the port is closed, or the certificate is bad; for a\n * diagnostic whose entire job is to explain a failure, that is barely better than the silent\n * success this operation used to return. So walk the cause chain and append what it names.\n *\n * `AggregateError` (emitted when every resolved address fails, e.g. happy-eyeballs against a dead\n * host) carries its detail in `errors[]` rather than `cause`, so that shape is unwrapped too.\n * Depth-capped and de-duplicated: the chain is attacker-adjacent input in the sense that a hostile\n * endpoint controls how deep it goes, and a repeated message adds nothing.\n */\nfunction describeFetchFailure(error: unknown): string {\n if (!(error instanceof Error)) return String(error);\n\n const parts: string[] = [];\n const seen = new Set<string>();\n let current: unknown = error;\n\n for (let depth = 0; depth < 4 && current instanceof Error; depth += 1) {\n // `code` is where Node puts the actionable token (ECONNREFUSED, …); the message often repeats it.\n const code = (current as NodeJS.ErrnoException).code;\n const label = code && !current.message.includes(code) ? `${current.message} (${code})` : current.message;\n if (label && !seen.has(label)) {\n seen.add(label);\n parts.push(label);\n }\n const aggregated = current instanceof AggregateError ? current.errors?.[0] : undefined;\n current = aggregated ?? (current as { cause?: unknown }).cause;\n }\n\n return parts.join(': ') || 'fetch failed';\n}\n\n/**\n * POST a pre-signed body to a webhook endpoint under a hard timeout.\n *\n * Never throws for a transport failure — a refused connection, a DNS miss and a timeout\n * all come back as `networkError`. A timeout is reported with its budget spelled out\n * because \"timed out\" alone sends an operator hunting for the wrong thing.\n *\n * Body capture is best-effort: a consumer that returns an unreadable body still produced a\n * valid status, and losing the body must not turn a successful attempt into a failed one.\n */\nexport async function sendSignedWebhookRequest(params: {\n /** Absolute destination URL. */\n url: string;\n /** Exact bytes to send — already the string whose hash the caller signed. */\n body: string;\n /**\n * Value for the `X-Webhook-Signature` header. Omit when the caller authenticates by another\n * mechanism and supplies its own {@link headers} — see below.\n */\n signature?: string;\n /**\n * Caller-supplied headers, MERGED OVER the defaults.\n *\n * Added for the A2A push-notification worker, which authenticates with the CLIENT's declared\n * scheme (`Authorization: {scheme} {credentials}`) and sends `application/a2a+json` rather than\n * Wildo's own ES256 signature and `application/json`.\n *\n * Widening this primitive instead of writing a second POST is deliberate, and follows the module\n * header's own claim to own THE WIRE: timeout, abort handling, failure description and body\n * truncation are the parts that are easy to get subtly wrong and expensive to have two of. What\n * varies between callers is authentication and media type — which are exactly the two things a\n * caller is in a position to decide. Purely additive: `signature` stays optional-by-absence for\n * the two existing M2M call sites, whose behaviour is byte-for-byte unchanged.\n */\n headers?: Record<string, string>;\n}): Promise<SignedWebhookRequestResult> {\n const startedAt = Date.now();\n\n // Refused BEFORE any timer or connection: a target the guard rejects must produce no DNS lookup,\n // no socket, and no signed body on the wire. Reported as `networkError` rather than thrown, because\n // this module's contract is that a destination problem is DATA the caller reports — the probe\n // surfaces it to the admin as UNREACHABLE and the delivery worker records it on the attempt row.\n const refusal = refuseUnsafeWebhookTarget(params.url);\n if (refusal) {\n return { networkError: refusal, durationMs: Date.now() - startedAt };\n }\n\n const abort = new AbortController();\n const timer = setTimeout(() => abort.abort(), REQUEST_TIMEOUT_MS);\n\n let responseStatus: number | undefined;\n let responseBodyTruncated: string | undefined;\n let networkError: string | undefined;\n\n try {\n const response = await fetch(params.url, {\n method: 'POST',\n signal: abort.signal,\n /**\n * A redirect is REPORTED, never followed.\n *\n * Following one re-points the request at a target the guard above never saw, which is the\n * guard's most obvious bypass — an admin authors a public URL that 302s to\n * `http://169.254.169.254/`. It also silently defeats a decision this subsystem had ALREADY\n * taken and could not enforce: `classifyResponseStatus` classifies 3xx as `fatal` and\n * `resolveProbeOutcome` classifies it as REJECTED (\"webhooks must not redirect, and a\n * CDN/proxy redirect on a wrong URL is one of the most common real misconfigurations an admin\n * uses this probe to find\") — but with `fetch`'s default follow behaviour neither of those\n * branches could ever execute, because a 3xx never reached them.\n *\n * `'manual'` rather than `'error'` on purpose: `'error'` would surface as an opaque network\n * failure, whereas `'manual'` hands back the 3xx status so both classifiers see the redirect\n * and tell the admin exactly what their endpoint did.\n */\n redirect: 'manual',\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': WEBHOOK_USER_AGENT,\n ...(params.signature ? { [WildoHeaderKeys.X_WEBHOOK_SIGNATURE]: params.signature } : {}),\n ...params.headers,\n },\n body: params.body,\n });\n responseStatus = response.status;\n try {\n const text = await response.text();\n responseBodyTruncated = text ? truncateBody(text) : undefined;\n } catch {\n // Best-effort body capture — never fail the attempt on a non-readable body.\n responseBodyTruncated = undefined;\n }\n } catch (error) {\n networkError = abort.signal.aborted\n ? `request timed out after ${REQUEST_TIMEOUT_MS}ms`\n : describeFetchFailure(error);\n } finally {\n clearTimeout(timer);\n }\n\n return {\n responseStatus,\n responseBodyTruncated,\n networkError,\n durationMs: Date.now() - startedAt,\n };\n}\n"]}
1
+ {"version":3,"file":"m2m-webhook-signed-request.backend.utils.js","sourceRoot":"","sources":["../../../../../src/notifications/webhooks/outbound/m2m-webhook-signed-request.backend.utils.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The single outbound-transport primitive for M2M webhooks.\n *\n * Every signed request Wildo emits to a customer endpoint goes through\n * {@link sendSignedWebhookRequest} — the retry worker's real deliveries AND the\n * `webhookConfig.testEndpoint` synthetic probe. Two call sites, one implementation, on\n * purpose: a probe that reached the endpoint through a *different* code path would\n * validate that path rather than the delivery path, which is precisely the reassurance an\n * admin is asking for when they press \"test\". Timeout, User-Agent, signature header name,\n * and body-truncation behaviour are therefore not re-decided per caller.\n *\n * Scope boundary — this module owns the WIRE, nothing else. It does not sign (callers hold\n * their own claims), does not classify (see `classifyResponseStatus`), does not persist,\n * and never throws on a transport failure: an unreachable endpoint is data the caller must\n * report, not an exception. The only way to get an exception out of here is to pass\n * something that is not a valid request.\n *\n * The tunables come from `./batches/m2m-webhook-delivery.batch.utils`, which is\n * deliberately import-free so its pure-decision tests load without the DI graph. They are\n * left there rather than moved up here precisely to preserve that property — this module\n * performs I/O and would drag `@wildo-ai/saas-models` into those tests.\n *\n * @see batches/m2m-webhook-delivery.batch.backend.service.ts — real deliveries.\n * @see services/webhook-config-test-endpoint.custom-impl.backend.service.ts — synthetic probe.\n */\n\nimport { M2M_WEBHOOK_DELIVERY_CONTRACT, WildoHeaderKeys } from '@wildo-ai/saas-models';\nimport {\n OutboundTargetRejection,\n classifyOutboundTargetUrl,\n} from '~wildo-backend-lib/security/ssrf/outbound-target-guard.backend.utils';\nimport {\n REQUEST_TIMEOUT_MS,\n WEBHOOK_USER_AGENT,\n truncateBody,\n} from './batches/m2m-webhook-delivery.batch.utils';\n\n/**\n * Schemes an outbound webhook delivery may use.\n *\n * `http:` is admitted. DECIDED 2026-09-08 (#492): keep admitting it, and document the exposure where\n * a customer authors the endpoint — which is now done, on `WebhookEndpointSchema.url`.\n *\n * This is a COMMERCIAL accommodation, not a security assessment, and the distinction is the whole\n * point of writing it down. The A2A sibling requires HTTPS unconditionally and the same argument\n * applies here — the signature JWT in transit is a credential, readable on the path and replayable\n * until it expires, so an observer of one delivery can forge the next. What was chosen is not to break\n * endpoints that a previous version of the framework accepted.\n *\n * The two options NOT taken, either of which is the better security answer: require HTTPS with a\n * migration that identifies and notifies existing plaintext endpoints, or require it for new endpoints\n * and grandfather existing ones behind an explicit acknowledgement. The second is the one to revisit\n * first — it stops the plaintext population growing without breaking anyone today.\n *\n * Reopen on an observed interception, or on a customer compliance requirement. Do not reopen it as a\n * tidy-up: the asymmetry with the A2A caller is deliberate and is recorded at both sites.\n */\nconst M2M_WEBHOOK_ADMITTED_PROTOCOLS = ['https:', 'http:'] as const;\n\n/**\n * Refuse a destination that would turn this server into a request-forgery tool.\n *\n * ## Why the guard is HERE and not on the schema\n *\n * `WebhookEndpointSchema.url` validates shape (`z.url()`) and nothing else, so an admin could author\n * `http://169.254.169.254/latest/meta-data/` and the engine would POST signed payloads to the cloud\n * instance-metadata service — then capture the answer into the delivery log as\n * `responseBodyTruncated`. That makes it a READ primitive, not a blind SSRF, and\n * `webhookConfig.testEndpoint` is a low-friction oracle for it.\n *\n * A schema refine would leave two holes this placement does not have: it would not cover endpoints\n * ALREADY STORED before the refine existed, and it would not cover the A2A push-delivery worker,\n * which reaches this same primitive with a URL its own (separate) guard validated at configuration\n * time. Putting the check at the wire makes it unbypassable for every caller — present and future —\n * which is what `.claude/rules/invariant-call-site-enumeration.md` means by preferring one\n * chokepoint over N hand-applied predicates.\n *\n * ## What it cannot do\n *\n * An ordinary hostname is not resolved, so `hook.attacker.test` with an A record of `169.254.169.254`\n * still passes. That residual is inherited from the shared classifier and is stated there; closing it\n * needs either a resolving check (a check-then-connect, still open to rebinding) or egress-path\n * enforcement. It is a deliberate open item, not an oversight.\n */\nfunction refuseUnsafeWebhookTarget(url: string): string | undefined {\n const rejection = classifyOutboundTargetUrl(url, { admittedProtocols: M2M_WEBHOOK_ADMITTED_PROTOCOLS });\n switch (rejection) {\n case undefined:\n return undefined;\n case OutboundTargetRejection.NOT_ABSOLUTE_ADMITTED_SCHEME:\n return 'refused: endpoint is not an absolute http(s) URL';\n case OutboundTargetRejection.CREDENTIALS_IN_URL:\n // Credentials in the URL would be replayed on every delivery and would land in any log or\n // delivery row that records the target.\n return 'refused: endpoint URL carries embedded credentials';\n case OutboundTargetRejection.PRIVATE_OR_RESERVED_ADDRESS:\n return 'refused: endpoint resolves to a private, loopback, link-local or otherwise reserved address';\n case OutboundTargetRejection.RESERVED_SPECIAL_USE_HOSTNAME:\n return 'refused: endpoint uses a reserved special-use hostname';\n }\n}\n\n/** Consumer-facing digest algorithm carried in every outbound webhook JWT. */\nexport const M2M_WEBHOOK_BODY_HASH_ALGORITHM: typeof M2M_WEBHOOK_DELIVERY_CONTRACT.bodyHashAlgorithm = M2M_WEBHOOK_DELIVERY_CONTRACT.bodyHashAlgorithm;\n\n/**\n * Outcome of one attempt at the wire level.\n *\n * `responseStatus` and `networkError` are mutually exclusive and exhaustive: either the\n * endpoint produced an HTTP response or it did not. Callers classify from there — this\n * type deliberately carries no verdict of its own, because \"429 is retryable\" is a\n * delivery-policy question and \"429 means the endpoint is reachable\" is a probe question,\n * and the same status answers both differently.\n */\nexport type SignedWebhookRequestResult = {\n /** Set when the endpoint answered, whatever the status. */\n responseStatus?: number;\n /** Best-effort capture of the consumer's response body, truncated on a UTF-8 boundary. */\n responseBodyTruncated?: string;\n /** Set when no HTTP response was obtained (DNS/TLS/connection failure, or timeout). */\n networkError?: string;\n /** Wall-clock duration of this attempt alone, excluding any caller-side work. */\n durationMs: number;\n};\n\n/**\n * Render a `fetch` rejection into something an operator can act on.\n *\n * Node's `fetch` (undici) rejects with a flat `TypeError: fetch failed` and buries the actual\n * cause — `ECONNREFUSED`, `ENOTFOUND`, `EHOSTUNREACH`, a TLS failure — one or more levels down in\n * `error.cause`. Reporting only `error.message` tells an admin their endpoint failed without\n * telling them whether the hostname is wrong, the port is closed, or the certificate is bad; for a\n * diagnostic whose entire job is to explain a failure, that is barely better than the silent\n * success this operation used to return. So walk the cause chain and append what it names.\n *\n * `AggregateError` (emitted when every resolved address fails, e.g. happy-eyeballs against a dead\n * host) carries its detail in `errors[]` rather than `cause`, so that shape is unwrapped too.\n * Depth-capped and de-duplicated: the chain is attacker-adjacent input in the sense that a hostile\n * endpoint controls how deep it goes, and a repeated message adds nothing.\n */\nfunction describeFetchFailure(error: unknown): string {\n if (!(error instanceof Error)) return String(error);\n\n const parts: string[] = [];\n const seen = new Set<string>();\n let current: unknown = error;\n\n for (let depth = 0; depth < 4 && current instanceof Error; depth += 1) {\n // `code` is where Node puts the actionable token (ECONNREFUSED, …); the message often repeats it.\n const code = (current as NodeJS.ErrnoException).code;\n const label = code && !current.message.includes(code) ? `${current.message} (${code})` : current.message;\n if (label && !seen.has(label)) {\n seen.add(label);\n parts.push(label);\n }\n const aggregated = current instanceof AggregateError ? current.errors?.[0] : undefined;\n current = aggregated ?? (current as { cause?: unknown }).cause;\n }\n\n return parts.join(': ') || 'fetch failed';\n}\n\n/**\n * POST a pre-signed body to a webhook endpoint under a hard timeout.\n *\n * Never throws for a transport failure — a refused connection, a DNS miss and a timeout\n * all come back as `networkError`. A timeout is reported with its budget spelled out\n * because \"timed out\" alone sends an operator hunting for the wrong thing.\n *\n * Body capture is best-effort: a consumer that returns an unreadable body still produced a\n * valid status, and losing the body must not turn a successful attempt into a failed one.\n */\nexport async function sendSignedWebhookRequest(params: {\n /** Absolute destination URL. */\n url: string;\n /** Exact bytes to send — already the string whose hash the caller signed. */\n body: string;\n /**\n * Value for the `X-Webhook-Signature` header. Omit when the caller authenticates by another\n * mechanism and supplies its own {@link headers} — see below.\n */\n signature?: string;\n /**\n * Caller-supplied headers, MERGED OVER the defaults.\n *\n * Added for the A2A push-notification worker, which authenticates with the CLIENT's declared\n * scheme (`Authorization: {scheme} {credentials}`) and sends `application/a2a+json` rather than\n * Wildo's own ES256 signature and `application/json`.\n *\n * Widening this primitive instead of writing a second POST is deliberate, and follows the module\n * header's own claim to own THE WIRE: timeout, abort handling, failure description and body\n * truncation are the parts that are easy to get subtly wrong and expensive to have two of. What\n * varies between callers is authentication and media type — which are exactly the two things a\n * caller is in a position to decide. Purely additive: `signature` stays optional-by-absence for\n * the two existing M2M call sites, whose behaviour is byte-for-byte unchanged.\n */\n headers?: Record<string, string>;\n}): Promise<SignedWebhookRequestResult> {\n const startedAt = Date.now();\n\n // Refused BEFORE any timer or connection: a target the guard rejects must produce no DNS lookup,\n // no socket, and no signed body on the wire. Reported as `networkError` rather than thrown, because\n // this module's contract is that a destination problem is DATA the caller reports — the probe\n // surfaces it to the admin as UNREACHABLE and the delivery worker records it on the attempt row.\n const refusal = refuseUnsafeWebhookTarget(params.url);\n if (refusal) {\n return { networkError: refusal, durationMs: Date.now() - startedAt };\n }\n\n const abort = new AbortController();\n const timer = setTimeout(() => abort.abort(), REQUEST_TIMEOUT_MS);\n\n let responseStatus: number | undefined;\n let responseBodyTruncated: string | undefined;\n let networkError: string | undefined;\n\n try {\n const response = await fetch(params.url, {\n method: 'POST',\n signal: abort.signal,\n /**\n * A redirect is REPORTED, never followed.\n *\n * Following one re-points the request at a target the guard above never saw, which is the\n * guard's most obvious bypass — an admin authors a public URL that 302s to\n * `http://169.254.169.254/`. It also silently defeats a decision this subsystem had ALREADY\n * taken and could not enforce: `classifyResponseStatus` classifies 3xx as `fatal` and\n * `resolveProbeOutcome` classifies it as REJECTED (\"webhooks must not redirect, and a\n * CDN/proxy redirect on a wrong URL is one of the most common real misconfigurations an admin\n * uses this probe to find\") — but with `fetch`'s default follow behaviour neither of those\n * branches could ever execute, because a 3xx never reached them.\n *\n * `'manual'` rather than `'error'` on purpose: `'error'` would surface as an opaque network\n * failure, whereas `'manual'` hands back the 3xx status so both classifiers see the redirect\n * and tell the admin exactly what their endpoint did.\n */\n redirect: 'manual',\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': WEBHOOK_USER_AGENT,\n ...(params.signature ? { [WildoHeaderKeys.X_WEBHOOK_SIGNATURE]: params.signature } : {}),\n ...params.headers,\n },\n body: params.body,\n });\n responseStatus = response.status;\n try {\n const text = await response.text();\n responseBodyTruncated = text ? truncateBody(text) : undefined;\n } catch {\n // Best-effort body capture — never fail the attempt on a non-readable body.\n responseBodyTruncated = undefined;\n }\n } catch (error) {\n networkError = abort.signal.aborted\n ? `request timed out after ${REQUEST_TIMEOUT_MS}ms`\n : describeFetchFailure(error);\n } finally {\n clearTimeout(timer);\n }\n\n return {\n responseStatus,\n responseBodyTruncated,\n networkError,\n durationMs: Date.now() - startedAt,\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"m2m-webhook-delivery-log.custom-impl.backend.service.d.ts","sourceRoot":"","sources":["../../../../../../../src/notifications/webhooks/outbound/services/m2m-webhook-delivery-log.custom-impl.backend.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAaH,OAAO,EAEL,KAAK,0CAA0C,EAChD,MAAM,4GAA4G,CAAC;AAiCpH,wBAAgB,yCAAyC,IAAI,0CAA0C,EAAE,CA2ExG;AAED,wBAAgB,4CAA4C,IAAI,0CAA0C,EAAE,CAyC3G"}
1
+ {"version":3,"file":"m2m-webhook-delivery-log.custom-impl.backend.service.d.ts","sourceRoot":"","sources":["../../../../../../src/notifications/webhooks/outbound/services/m2m-webhook-delivery-log.custom-impl.backend.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAaH,OAAO,EAEL,KAAK,0CAA0C,EAChD,MAAM,4GAA4G,CAAC;AAiCpH,wBAAgB,yCAAyC,IAAI,0CAA0C,EAAE,CA2ExG;AAED,wBAAgB,4CAA4C,IAAI,0CAA0C,EAAE,CAyC3G"}