@wildo-ai/saas-backend-lib 1.1.0 → 1.1.2

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 (265) hide show
  1. package/dist/esm/base-classes/services/controllers/controller-resource.backend.service.d.ts +14 -3
  2. package/dist/esm/base-classes/services/controllers/controller-resource.backend.service.d.ts.map +1 -1
  3. package/dist/esm/base-classes/services/controllers/controller-resource.backend.service.js +115 -22
  4. package/dist/esm/base-classes/services/controllers/controller-resource.backend.service.js.map +1 -1
  5. package/dist/esm/base-classes/services/controllers/controllers-registry-handler.backend.service.d.ts +3 -1
  6. package/dist/esm/base-classes/services/controllers/controllers-registry-handler.backend.service.d.ts.map +1 -1
  7. package/dist/esm/base-classes/services/controllers/controllers-registry-handler.backend.service.js +8 -3
  8. package/dist/esm/base-classes/services/controllers/controllers-registry-handler.backend.service.js.map +1 -1
  9. package/dist/esm/base-classes/services/repositories/field-clearing-partition.backend.d.ts +11 -0
  10. package/dist/esm/base-classes/services/repositories/field-clearing-partition.backend.d.ts.map +1 -1
  11. package/dist/esm/base-classes/services/repositories/field-clearing-partition.backend.js +11 -2
  12. package/dist/esm/base-classes/services/repositories/field-clearing-partition.backend.js.map +1 -1
  13. package/dist/esm/base-classes/services/repositories/http-api/http-api-resource-repository.backend.service.d.ts +1 -0
  14. package/dist/esm/base-classes/services/repositories/http-api/http-api-resource-repository.backend.service.d.ts.map +1 -1
  15. package/dist/esm/base-classes/services/repositories/http-api/http-api-resource-repository.backend.service.js +6 -1
  16. package/dist/esm/base-classes/services/repositories/http-api/http-api-resource-repository.backend.service.js.map +1 -1
  17. package/dist/esm/base-classes/services/repositories/http-api/odata-query-compiler.backend.d.ts.map +1 -1
  18. package/dist/esm/base-classes/services/repositories/http-api/odata-query-compiler.backend.js +16 -0
  19. package/dist/esm/base-classes/services/repositories/http-api/odata-query-compiler.backend.js.map +1 -1
  20. package/dist/esm/base-classes/services/repositories/infrastructure-tier-contract.backend.d.ts +20 -6
  21. package/dist/esm/base-classes/services/repositories/infrastructure-tier-contract.backend.d.ts.map +1 -1
  22. package/dist/esm/base-classes/services/repositories/infrastructure-tier-contract.backend.js +88 -32
  23. package/dist/esm/base-classes/services/repositories/infrastructure-tier-contract.backend.js.map +1 -1
  24. package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-repository.backend.service.d.ts +3 -1
  25. package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-repository.backend.service.d.ts.map +1 -1
  26. package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-repository.backend.service.js +32 -7
  27. package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-repository.backend.service.js.map +1 -1
  28. package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-source.backend.port.d.ts +8 -5
  29. package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-source.backend.port.d.ts.map +1 -1
  30. package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-source.backend.port.js.map +1 -1
  31. package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.d.ts +31 -0
  32. package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.d.ts.map +1 -1
  33. package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.js +127 -5
  34. package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.js.map +1 -1
  35. package/dist/esm/base-classes/services/repositories/repositories-registry-handler.backend.service.d.ts +71 -1
  36. package/dist/esm/base-classes/services/repositories/repositories-registry-handler.backend.service.d.ts.map +1 -1
  37. package/dist/esm/base-classes/services/repositories/repositories-registry-handler.backend.service.js +62 -2
  38. package/dist/esm/base-classes/services/repositories/repositories-registry-handler.backend.service.js.map +1 -1
  39. package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.d.ts +21 -0
  40. package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.d.ts.map +1 -1
  41. package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.js +126 -4
  42. package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.js.map +1 -1
  43. package/dist/esm/base-classes/services/services/resource-operation-implementation-coverage.backend.utils.d.ts +3 -26
  44. package/dist/esm/base-classes/services/services/resource-operation-implementation-coverage.backend.utils.d.ts.map +1 -1
  45. package/dist/esm/base-classes/services/services/resource-operation-implementation-coverage.backend.utils.js +3 -68
  46. package/dist/esm/base-classes/services/services/resource-operation-implementation-coverage.backend.utils.js.map +1 -1
  47. package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.d.ts.map +1 -1
  48. package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.js +4 -2
  49. package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.js.map +1 -1
  50. package/dist/esm/billing/services/custom-impl/billing-account.mutations.custom-impl.backend.service.js +6 -6
  51. package/dist/esm/billing/services/custom-impl/billing-account.mutations.custom-impl.backend.service.js.map +1 -1
  52. package/dist/esm/compliance/audit-trails/services/audit-event-dispatcher.backend.service.d.ts +38 -0
  53. package/dist/esm/compliance/audit-trails/services/audit-event-dispatcher.backend.service.d.ts.map +1 -1
  54. package/dist/esm/compliance/audit-trails/services/audit-event-dispatcher.backend.service.js +40 -0
  55. package/dist/esm/compliance/audit-trails/services/audit-event-dispatcher.backend.service.js.map +1 -1
  56. package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.d.ts +20 -0
  57. package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.d.ts.map +1 -1
  58. package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.js +28 -0
  59. package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.js.map +1 -1
  60. package/dist/esm/compliance/audit-trails/services/siem-export-config-cache-invalidation.custom-impl.backend.service.d.ts +12 -0
  61. package/dist/esm/compliance/audit-trails/services/siem-export-config-cache-invalidation.custom-impl.backend.service.d.ts.map +1 -0
  62. package/dist/esm/compliance/audit-trails/services/siem-export-config-cache-invalidation.custom-impl.backend.service.js +118 -0
  63. package/dist/esm/compliance/audit-trails/services/siem-export-config-cache-invalidation.custom-impl.backend.service.js.map +1 -0
  64. package/dist/esm/compliance/audit-trails/services/siem-webhook-delivery.backend.service.d.ts.map +1 -1
  65. package/dist/esm/compliance/audit-trails/services/siem-webhook-delivery.backend.service.js +8 -5
  66. package/dist/esm/compliance/audit-trails/services/siem-webhook-delivery.backend.service.js.map +1 -1
  67. package/dist/esm/compliance/audit-trails/services/utils/ocsf-activity-mapping.backend.utils.d.ts.map +1 -1
  68. package/dist/esm/compliance/audit-trails/services/utils/ocsf-activity-mapping.backend.utils.js +14 -0
  69. package/dist/esm/compliance/audit-trails/services/utils/ocsf-activity-mapping.backend.utils.js.map +1 -1
  70. package/dist/esm/config/custom/application-config-controller.backend.service.d.ts.map +1 -1
  71. package/dist/esm/config/custom/application-config-controller.backend.service.js +7 -1
  72. package/dist/esm/config/custom/application-config-controller.backend.service.js.map +1 -1
  73. package/dist/esm/config/models/app-config.backend.schemas.d.ts +4 -0
  74. package/dist/esm/config/models/app-config.backend.schemas.d.ts.map +1 -1
  75. package/dist/esm/config/services/app-configuration.backend.utils.d.ts +10 -1
  76. package/dist/esm/config/services/app-configuration.backend.utils.d.ts.map +1 -1
  77. package/dist/esm/config/services/app-configuration.backend.utils.js +13 -2
  78. package/dist/esm/config/services/app-configuration.backend.utils.js.map +1 -1
  79. package/dist/esm/data-seeding/services/shared/data-seed-scope-iteration.shared.utils.d.ts +2 -2
  80. package/dist/esm/data-seeding/services/shared/data-seed-scope-iteration.shared.utils.js +2 -2
  81. package/dist/esm/data-seeding/services/shared/data-seed-scope-iteration.shared.utils.js.map +1 -1
  82. package/dist/esm/databases/models/filter.backend.schemas.js +2 -2
  83. package/dist/esm/databases/models/filter.backend.schemas.js.map +1 -1
  84. package/dist/esm/databases/services/aggregation/aggregation-authorization.backend.service.d.ts.map +1 -1
  85. package/dist/esm/databases/services/aggregation/aggregation-authorization.backend.service.js +20 -1
  86. package/dist/esm/databases/services/aggregation/aggregation-authorization.backend.service.js.map +1 -1
  87. package/dist/esm/databases/services/redis.service.d.ts +27 -0
  88. package/dist/esm/databases/services/redis.service.d.ts.map +1 -1
  89. package/dist/esm/databases/services/redis.service.js +29 -0
  90. package/dist/esm/databases/services/redis.service.js.map +1 -1
  91. package/dist/esm/errors/services/error-handler.backend.service.d.ts.map +1 -1
  92. package/dist/esm/errors/services/error-handler.backend.service.js +5 -0
  93. package/dist/esm/errors/services/error-handler.backend.service.js.map +1 -1
  94. package/dist/esm/external-data/controllers/external-data-admin.backend.contracts.d.ts +41 -0
  95. package/dist/esm/external-data/controllers/external-data-admin.backend.contracts.d.ts.map +1 -0
  96. package/dist/esm/external-data/controllers/external-data-admin.backend.contracts.js +40 -0
  97. package/dist/esm/external-data/controllers/external-data-admin.backend.contracts.js.map +1 -0
  98. package/dist/esm/external-data/controllers/external-data-admin.backend.controller.d.ts +64 -0
  99. package/dist/esm/external-data/controllers/external-data-admin.backend.controller.d.ts.map +1 -0
  100. package/dist/esm/external-data/controllers/external-data-admin.backend.controller.js +193 -0
  101. package/dist/esm/external-data/controllers/external-data-admin.backend.controller.js.map +1 -0
  102. package/dist/esm/external-data/external-data-pipeline-run.backend.service.d.ts +13 -2
  103. package/dist/esm/external-data/external-data-pipeline-run.backend.service.d.ts.map +1 -1
  104. package/dist/esm/external-data/external-data-pipeline-run.backend.service.js +8 -2
  105. package/dist/esm/external-data/external-data-pipeline-run.backend.service.js.map +1 -1
  106. package/dist/esm/external-data/external-data-transform.backend.d.ts.map +1 -1
  107. package/dist/esm/external-data/external-data-transform.backend.js +7 -1
  108. package/dist/esm/external-data/external-data-transform.backend.js.map +1 -1
  109. package/dist/esm/external-data/models/external-data-pipeline-state.backend.schemas.d.ts +2 -0
  110. package/dist/esm/external-data/models/external-data-pipeline-state.backend.schemas.d.ts.map +1 -1
  111. package/dist/esm/external-data/models/external-data-pipeline-state.backend.schemas.js +13 -0
  112. package/dist/esm/external-data/models/external-data-pipeline-state.backend.schemas.js.map +1 -1
  113. package/dist/esm/external-providers/services/external-providers-registry.backend.service.d.ts +14 -0
  114. package/dist/esm/external-providers/services/external-providers-registry.backend.service.d.ts.map +1 -1
  115. package/dist/esm/external-providers/services/external-providers-registry.backend.service.js +6 -0
  116. package/dist/esm/external-providers/services/external-providers-registry.backend.service.js.map +1 -1
  117. package/dist/esm/files/controllers/file.controller.d.ts +24 -1
  118. package/dist/esm/files/controllers/file.controller.d.ts.map +1 -1
  119. package/dist/esm/files/controllers/file.controller.js +66 -2
  120. package/dist/esm/files/controllers/file.controller.js.map +1 -1
  121. package/dist/esm/files/handlers/file-upload-route-locals.backend.types.d.ts +17 -0
  122. package/dist/esm/files/handlers/file-upload-route-locals.backend.types.d.ts.map +1 -0
  123. package/dist/esm/files/handlers/file-upload-route-locals.backend.types.js +1 -0
  124. package/dist/esm/files/handlers/file-upload-route-locals.backend.types.js.map +1 -0
  125. package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.d.ts +5 -1
  126. package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.d.ts.map +1 -1
  127. package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.js +42 -3
  128. package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.js.map +1 -1
  129. package/dist/esm/files/services/file-operation-handler.backend.service.d.ts +18 -0
  130. package/dist/esm/files/services/file-operation-handler.backend.service.d.ts.map +1 -1
  131. package/dist/esm/files/services/file-operation-handler.backend.service.js +36 -28
  132. package/dist/esm/files/services/file-operation-handler.backend.service.js.map +1 -1
  133. package/dist/esm/files/services/file-upload-grant.backend.service.d.ts +163 -0
  134. package/dist/esm/files/services/file-upload-grant.backend.service.d.ts.map +1 -0
  135. package/dist/esm/files/services/file-upload-grant.backend.service.js +442 -0
  136. package/dist/esm/files/services/file-upload-grant.backend.service.js.map +1 -0
  137. package/dist/esm/files/services/files.backend.service.d.ts +19 -0
  138. package/dist/esm/files/services/files.backend.service.d.ts.map +1 -1
  139. package/dist/esm/files/services/files.backend.service.js +78 -15
  140. package/dist/esm/files/services/files.backend.service.js.map +1 -1
  141. package/dist/esm/files/utils/file-uploader.utils.d.ts.map +1 -1
  142. package/dist/esm/files/utils/file-uploader.utils.js +12 -0
  143. package/dist/esm/files/utils/file-uploader.utils.js.map +1 -1
  144. package/dist/esm/flows-actors/a2a/services/a2a-task-cancellation.backend.service.js +5 -5
  145. package/dist/esm/flows-actors/a2a/services/a2a-task-cancellation.backend.service.js.map +1 -1
  146. package/dist/esm/flows-actors/services/agents.backend.service.d.ts +79 -0
  147. package/dist/esm/flows-actors/services/agents.backend.service.d.ts.map +1 -1
  148. package/dist/esm/flows-actors/services/agents.backend.service.js +319 -42
  149. package/dist/esm/flows-actors/services/agents.backend.service.js.map +1 -1
  150. package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.d.ts +151 -41
  151. package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.d.ts.map +1 -1
  152. package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.js +300 -139
  153. package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.js.map +1 -1
  154. package/dist/esm/index.d.ts +4 -1
  155. package/dist/esm/index.d.ts.map +1 -1
  156. package/dist/esm/index.js +14 -1
  157. package/dist/esm/index.js.map +1 -1
  158. package/dist/esm/inject/models/container.d.ts.map +1 -1
  159. package/dist/esm/inject/models/container.js +4 -0
  160. package/dist/esm/inject/models/container.js.map +1 -1
  161. package/dist/esm/inject/models/service-types.d.ts +3 -0
  162. package/dist/esm/inject/models/service-types.d.ts.map +1 -1
  163. package/dist/esm/inject/models/service-types.js +2 -0
  164. package/dist/esm/inject/models/service-types.js.map +1 -1
  165. package/dist/esm/mcp/controllers/mcp.controller.d.ts.map +1 -1
  166. package/dist/esm/mcp/controllers/mcp.controller.js +12 -4
  167. package/dist/esm/mcp/controllers/mcp.controller.js.map +1 -1
  168. package/dist/esm/mcp/models/mcp-tool.backend.schemas.d.ts +34 -0
  169. package/dist/esm/mcp/models/mcp-tool.backend.schemas.d.ts.map +1 -1
  170. package/dist/esm/mcp/models/mcp-tool.backend.schemas.js +42 -0
  171. package/dist/esm/mcp/models/mcp-tool.backend.schemas.js.map +1 -1
  172. package/dist/esm/mcp/services/mcp-server.backend.service.d.ts +29 -1
  173. package/dist/esm/mcp/services/mcp-server.backend.service.d.ts.map +1 -1
  174. package/dist/esm/mcp/services/mcp-server.backend.service.js +131 -3
  175. package/dist/esm/mcp/services/mcp-server.backend.service.js.map +1 -1
  176. package/dist/esm/mcp/services/mcp-tool-adapter.backend.service.d.ts +64 -2
  177. package/dist/esm/mcp/services/mcp-tool-adapter.backend.service.d.ts.map +1 -1
  178. package/dist/esm/mcp/services/mcp-tool-adapter.backend.service.js +130 -6
  179. package/dist/esm/mcp/services/mcp-tool-adapter.backend.service.js.map +1 -1
  180. package/dist/esm/notifications/services/notifications-dispatcher.backend.service.d.ts +9 -0
  181. package/dist/esm/notifications/services/notifications-dispatcher.backend.service.d.ts.map +1 -1
  182. package/dist/esm/notifications/services/notifications-dispatcher.backend.service.js +11 -36
  183. package/dist/esm/notifications/services/notifications-dispatcher.backend.service.js.map +1 -1
  184. package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.backend.service.d.ts.map +1 -1
  185. package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.backend.service.js +9 -7
  186. package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.backend.service.js.map +1 -1
  187. package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.utils.d.ts +5 -5
  188. package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.utils.d.ts.map +1 -1
  189. package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.utils.js +14 -13
  190. package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.utils.js.map +1 -1
  191. package/dist/esm/notifications/webhooks/outbound/m2m-webhook-signed-request.backend.utils.d.ts +2 -1
  192. package/dist/esm/notifications/webhooks/outbound/m2m-webhook-signed-request.backend.utils.d.ts.map +1 -1
  193. package/dist/esm/notifications/webhooks/outbound/m2m-webhook-signed-request.backend.utils.js +2 -2
  194. package/dist/esm/notifications/webhooks/outbound/m2m-webhook-signed-request.backend.utils.js.map +1 -1
  195. package/dist/esm/notifications/webhooks/outbound/services/webhook-config-test-endpoint.custom-impl.backend.service.d.ts.map +1 -1
  196. package/dist/esm/notifications/webhooks/outbound/services/webhook-config-test-endpoint.custom-impl.backend.service.js +9 -7
  197. package/dist/esm/notifications/webhooks/outbound/services/webhook-config-test-endpoint.custom-impl.backend.service.js.map +1 -1
  198. package/dist/esm/organizations/services/organization-unit-custom-implementation.backend.service.d.ts.map +1 -1
  199. package/dist/esm/organizations/services/organization-unit-custom-implementation.backend.service.js +4 -1
  200. package/dist/esm/organizations/services/organization-unit-custom-implementation.backend.service.js.map +1 -1
  201. package/dist/esm/requests/service/websocket.service.d.ts.map +1 -1
  202. package/dist/esm/requests/service/websocket.service.js +56 -7
  203. package/dist/esm/requests/service/websocket.service.js.map +1 -1
  204. package/dist/esm/resources/models/custom-service-implementations.backend.definition.d.ts.map +1 -1
  205. package/dist/esm/resources/models/custom-service-implementations.backend.definition.js +2 -0
  206. package/dist/esm/resources/models/custom-service-implementations.backend.definition.js.map +1 -1
  207. package/dist/esm/resources/services/resource-id.backend.service.js +3 -3
  208. package/dist/esm/resources/services/resource-id.backend.service.js.map +1 -1
  209. package/dist/esm/resources/services/resources-registry.backend.service.js +1 -1
  210. package/dist/esm/resources/services/resources-registry.backend.service.js.map +1 -1
  211. package/dist/esm/runtime/services/execution-context-creator.backend.service.d.ts.map +1 -1
  212. package/dist/esm/runtime/services/execution-context-creator.backend.service.js +13 -7
  213. package/dist/esm/runtime/services/execution-context-creator.backend.service.js.map +1 -1
  214. package/dist/esm/runtime/services/start-application.backend.service.d.ts +28 -0
  215. package/dist/esm/runtime/services/start-application.backend.service.d.ts.map +1 -1
  216. package/dist/esm/runtime/services/start-application.backend.service.js +82 -0
  217. package/dist/esm/runtime/services/start-application.backend.service.js.map +1 -1
  218. package/dist/esm/security/authentications/models/jwt.backend.schemas.d.ts +3 -23
  219. package/dist/esm/security/authentications/models/jwt.backend.schemas.d.ts.map +1 -1
  220. package/dist/esm/security/authentications/models/jwt.backend.schemas.js +20 -45
  221. package/dist/esm/security/authentications/models/jwt.backend.schemas.js.map +1 -1
  222. package/dist/esm/security/authentications/services/auth-methods/auth-method-management.backend.service.d.ts +9 -1
  223. package/dist/esm/security/authentications/services/auth-methods/auth-method-management.backend.service.d.ts.map +1 -1
  224. package/dist/esm/security/authentications/services/auth-methods/auth-method-management.backend.service.js +9 -1
  225. package/dist/esm/security/authentications/services/auth-methods/auth-method-management.backend.service.js.map +1 -1
  226. package/dist/esm/security/authentications/services/auth-methods/auth-mfa.backend.service.d.ts.map +1 -1
  227. package/dist/esm/security/authentications/services/auth-methods/auth-mfa.backend.service.js +5 -3
  228. package/dist/esm/security/authentications/services/auth-methods/auth-mfa.backend.service.js.map +1 -1
  229. package/dist/esm/security/authentications/services/auth-token-issuer.backend.service.d.ts +25 -1
  230. package/dist/esm/security/authentications/services/auth-token-issuer.backend.service.d.ts.map +1 -1
  231. package/dist/esm/security/authentications/services/auth-token-issuer.backend.service.js +55 -4
  232. package/dist/esm/security/authentications/services/auth-token-issuer.backend.service.js.map +1 -1
  233. package/dist/esm/security/authorizations/initiator-organization-confinement.backend.d.ts.map +1 -1
  234. package/dist/esm/security/authorizations/initiator-organization-confinement.backend.js +24 -1
  235. package/dist/esm/security/authorizations/initiator-organization-confinement.backend.js.map +1 -1
  236. package/dist/esm/security/authorizations/privileged-access-review.backend.utils.d.ts +117 -0
  237. package/dist/esm/security/authorizations/privileged-access-review.backend.utils.d.ts.map +1 -0
  238. package/dist/esm/security/authorizations/privileged-access-review.backend.utils.js +104 -0
  239. package/dist/esm/security/authorizations/privileged-access-review.backend.utils.js.map +1 -0
  240. package/dist/esm/security/authorizations/services/authorizations.backend.service.d.ts +101 -6
  241. package/dist/esm/security/authorizations/services/authorizations.backend.service.d.ts.map +1 -1
  242. package/dist/esm/security/authorizations/services/authorizations.backend.service.js +210 -30
  243. package/dist/esm/security/authorizations/services/authorizations.backend.service.js.map +1 -1
  244. package/dist/esm/security/consumable-tokens/batches/consumable-tokens-cleanup.batch.backend.service.d.ts +18 -1
  245. package/dist/esm/security/consumable-tokens/batches/consumable-tokens-cleanup.batch.backend.service.d.ts.map +1 -1
  246. package/dist/esm/security/consumable-tokens/batches/consumable-tokens-cleanup.batch.backend.service.js +110 -74
  247. package/dist/esm/security/consumable-tokens/batches/consumable-tokens-cleanup.batch.backend.service.js.map +1 -1
  248. package/dist/esm/security/consumable-tokens/consumable-token-models.exports.d.ts +22 -0
  249. package/dist/esm/security/consumable-tokens/consumable-token-models.exports.d.ts.map +1 -0
  250. package/dist/esm/security/consumable-tokens/consumable-token-models.exports.js +22 -0
  251. package/dist/esm/security/consumable-tokens/consumable-token-models.exports.js.map +1 -0
  252. package/dist/esm/security/consumable-tokens/models/consumable-tokens.backend.resources-config.schemas.d.ts +17 -3
  253. package/dist/esm/security/consumable-tokens/models/consumable-tokens.backend.resources-config.schemas.d.ts.map +1 -1
  254. package/dist/esm/security/consumable-tokens/models/consumable-tokens.backend.resources-config.schemas.js +12 -0
  255. package/dist/esm/security/consumable-tokens/models/consumable-tokens.backend.resources-config.schemas.js.map +1 -1
  256. package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.d.ts +20 -0
  257. package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.d.ts.map +1 -1
  258. package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.js +58 -5
  259. package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.js.map +1 -1
  260. package/dist/esm/security/jwt/services/jwt.backend.service.d.ts.map +1 -1
  261. package/dist/esm/security/jwt/services/jwt.backend.service.js +1 -18
  262. package/dist/esm/security/jwt/services/jwt.backend.service.js.map +1 -1
  263. package/dist/tsconfig.build.tsbuildinfo +1 -1
  264. package/package.json +15 -9
  265. package/dist/esm/.builder.pid +0 -9
@@ -0,0 +1,442 @@
1
+ /**
2
+ * File Upload Grant Backend Service
3
+ *
4
+ * The ONE mint function behind both doors — the REST sibling route (`…/files/<field>/grant`) and the
5
+ * MCP derived tool — plus the route-binding check the upload middleware runs, the public status read,
6
+ * revocation, and the post-redemption write-back. Issue #312.
7
+ *
8
+ * ## What a grant is
9
+ *
10
+ * A `SINGLE_USE` consumable token of type `FILE_UPLOAD_GRANT` that lets whoever holds it perform ONE
11
+ * upload into ONE resource file field with the MINTER's authority. Nothing durable is created at mint
12
+ * but the token. The upload goes through the resource's EXISTING file-upload route: the token becomes
13
+ * an ordinary `CONSUMABLE_TOKEN` execution context (typed fields → identity) and the ordinary
14
+ * authorizer decides. This service never decides "may this principal put a file here" — the upload
15
+ * middleware does, once, for mint and upload alike, which is what makes mint-authority ≡
16
+ * upload-authority by construction.
17
+ *
18
+ * ## Why the route binding lives in `metadata` and is checked HERE
19
+ *
20
+ * `createExecutionContextFromRequest` turns the token's TYPED fields (`userId`, `organizationId`,
21
+ * `roles`, `resourceIdentifier`, `relatedId`) into identity and deliberately reads nothing from
22
+ * `metadata`. Which field, which operation kind, which concrete upload URL — those are ROUTE facts,
23
+ * and the upload middleware asks this service to check them against the route the token was
24
+ * presented on. Identity and route stay separate concerns.
25
+ */
26
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
27
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
28
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
29
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
30
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
31
+ };
32
+ var __metadata = (this && this.__metadata) || function (k, v) {
33
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
34
+ };
35
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
36
+ return function (target, key) { decorator(target, key, paramIndex); }
37
+ };
38
+ import { injectable, inject, optional } from 'inversify';
39
+ import { ConsumableToken_ConsumptionMode, CoreAuditableEventType, CoreConsumableTokenTypes, CORE_APP_ROLES, ErrorCustomMessageReference, ErrorType, ExecutionContext_ExecutionType, FILE_UPLOAD_GRANT_DEFAULT_MINUTES, FILE_UPLOAD_GRANT_PAGE_PATH, FileUploadGrantMetadataSchema, FileUploadGrantState, ResourceOperationRiskLevel, TokenAuthenticationPolicy, WildoHeaderKeys, CoreResourceType, CoreResourceOperation, } from '@wildo-ai/saas-models';
40
+ import { DurationUnit, FileGenerationSource } from '@wildo-ai/zod-decorators';
41
+ import { SAAS_SERVICE_TYPES } from '../../inject/models/service-types.js';
42
+ import { ErrorBuilderBackendService } from '../../errors/services/error-builder.backend.service.js';
43
+ import { projectCaughtErrorLogFields } from '../../errors/utils/error-log-level-classification.backend.utils.js';
44
+ import { AppConfigurationService } from '../../config/services/app-configuration.backend.service.js';
45
+ import { ConsumableTokenBackendService } from '../../security/consumable-tokens/services/consumable-token.backend.service.js';
46
+ import { FileConstraintResolverChain } from '../../files/constraints/file-constraint-resolver-chain.backend.service.js';
47
+ import { FileFieldDetectionBackendService } from '../../files/services/file-field-detection.backend.service.js';
48
+ import { ExecutionContextCreatorBackendService } from '../../runtime/services/execution-context-creator.backend.service.js';
49
+ import { RepositoriesRegistryHandlerBackendService } from '../../base-classes/services/repositories/repositories-registry-handler.backend.service.js';
50
+ import { resolveFileUploaderPrincipal } from '../../files/utils/file-uploader.utils.js';
51
+ import { AuthControllerUtils } from '../../security/authentications/services/utils/auth-controller.utils.js';
52
+ let FileUploadGrantBackendService = class FileUploadGrantBackendService {
53
+ logger;
54
+ errorBuilder;
55
+ consumableTokenService;
56
+ constraintResolver;
57
+ fileFieldDetection;
58
+ executionContextCreator;
59
+ repositoriesRegistry;
60
+ appConfigService;
61
+ auditLogsService;
62
+ logDebug;
63
+ constructor(logger, errorBuilder, consumableTokenService, constraintResolver, fileFieldDetection, executionContextCreator, repositoriesRegistry, appConfigService, auditLogsService) {
64
+ this.logger = logger;
65
+ this.errorBuilder = errorBuilder;
66
+ this.consumableTokenService = consumableTokenService;
67
+ this.constraintResolver = constraintResolver;
68
+ this.fileFieldDetection = fileFieldDetection;
69
+ this.executionContextCreator = executionContextCreator;
70
+ this.repositoriesRegistry = repositoriesRegistry;
71
+ this.appConfigService = appConfigService;
72
+ this.auditLogsService = auditLogsService;
73
+ this.logDebug = this.logger.debugByType('FileUploadGrantBackendService');
74
+ this.logger.setDebugTypeLogging('FileUploadGrantBackendService', false);
75
+ }
76
+ /**
77
+ * The operation the upload routes hand to the execution-context creator (issue #312, D4).
78
+ *
79
+ * `tokenAuthentication` lives on the OPERATION, so declaring it on the authored CREATE/UPDATE would
80
+ * let a grant perform the whole JSON write. Instead the `…/files/<field>` and `…/files/<field>/grant`
81
+ * routes — and ONLY those — get this derived copy, which accepts the grant type as an ALTERNATIVE
82
+ * credential beside whatever the author declared. The JSON routes keep the authored operation, so a
83
+ * grant presented there is refused by GATE 1 (`CONSUMABLE_TOKEN_NOT_ACCEPTED_FOR_OPERATION`).
84
+ *
85
+ * An authored ADDITIVE policy is NOT preserved as ADDITIVE here: the upload route's own authorizer
86
+ * decides on the resulting context either way, and an additive token on a multipart upload is not a
87
+ * case any resource declares today. If one appears, this is the seam to widen — do not widen the
88
+ * authored operation.
89
+ */
90
+ static withUploadGrantAcceptance(operation) {
91
+ const authored = 'tokenAuthentication' in operation ? operation.tokenAuthentication : undefined;
92
+ const authoredTypes = authored?.policy === TokenAuthenticationPolicy.ALTERNATIVE ? (authored.types ?? []) : [];
93
+ return {
94
+ ...operation,
95
+ tokenAuthentication: {
96
+ types: [...authoredTypes, CoreConsumableTokenTypes.FILE_UPLOAD_GRANT],
97
+ policy: TokenAuthenticationPolicy.ALTERNATIVE,
98
+ },
99
+ };
100
+ }
101
+ /**
102
+ * Mint a grant for the target the caller has JUST been authorized on.
103
+ *
104
+ * Refuses two minter kinds: a `CONSUMABLE_TOKEN` context (a grant may not mint a grant — no
105
+ * delegation chains) and an `ANONYMOUS_SESSION` (no stable subject to attribute the file to, no
106
+ * roles worth snapshotting). `USER_REQUEST` and both machine principals mint.
107
+ */
108
+ async mint(params) {
109
+ const { executionContext, target } = params;
110
+ if (executionContext.executionType === ExecutionContext_ExecutionType.CONSUMABLE_TOKEN
111
+ || executionContext.executionType === ExecutionContext_ExecutionType.ANONYMOUS_SESSION) {
112
+ throw this.errorBuilder.buildError(ErrorType.AUTHORIZATION, executionContext, {
113
+ customMessageReference: ErrorCustomMessageReference.FILE_UPLOAD_GRANT_MINTER_NOT_ELIGIBLE,
114
+ context: { executionType: executionContext.executionType }, // diagnostic (log-only)
115
+ });
116
+ }
117
+ const minter = resolveFileUploaderPrincipal(executionContext);
118
+ if (!minter) {
119
+ // A principal the uploader resolver cannot name cannot be the file's owner either.
120
+ throw this.errorBuilder.buildError(ErrorType.AUTHORIZATION, executionContext, {
121
+ customMessageReference: ErrorCustomMessageReference.FILE_UPLOAD_GRANT_MINTER_NOT_ELIGIBLE,
122
+ context: { executionType: executionContext.executionType, reason: 'no uploader principal' }, // diagnostic (log-only)
123
+ });
124
+ }
125
+ const fieldMeta = this.fileFieldDetection.getFileFieldMetadata(target.resourceType, target.fieldName);
126
+ if (!fieldMeta) {
127
+ throw this.errorBuilder.buildError(ErrorType.VALIDATION, executionContext, {
128
+ customMessageReference: ErrorCustomMessageReference.VALIDATION,
129
+ context: { message: 'Not a file field', resourceType: target.resourceType, fieldName: target.fieldName }, // diagnostic (log-only)
130
+ });
131
+ }
132
+ if (fieldMeta.fileMetadata.generation?.source === FileGenerationSource.PDF_TEMPLATE) {
133
+ // Same refusal the upload handler makes, made EARLY: a grant for a field that can never receive a
134
+ // user upload would be a link that fails on redemption for a reason knowable at mint.
135
+ throw this.errorBuilder.buildError(ErrorType.BUSINESS_RULE, executionContext, {
136
+ customMessageReference: ErrorCustomMessageReference.FILE_GENERATED_FIELD_NOT_WRITABLE,
137
+ context: { resourceType: target.resourceType, fieldName: target.fieldName }, // diagnostic (log-only)
138
+ });
139
+ }
140
+ const constraint = await this.constraintResolver.resolve({ resourceType: target.resourceType, fieldName: target.fieldName });
141
+ const expiresInMinutes = params.expiresInMinutes ?? FILE_UPLOAD_GRANT_DEFAULT_MINUTES;
142
+ const metadataWithoutUrl = {
143
+ fieldName: target.fieldName,
144
+ operation: target.operation,
145
+ minter: { entityType: minter.uploadedByEntityType, id: minter.uploadedBy },
146
+ };
147
+ // assurance-control: WILDO.IDENTITY.DELEGATED_AUTHORIZATION — a principal delegates ONE upload, into
148
+ // ONE field, under its own authority, to whoever holds the grant. The ceiling and SINGLE_USE are
149
+ // enforced inside createToken; the audit row below is what makes the delegation accountable.
150
+ const token = await this.consumableTokenService.createToken({
151
+ tokenType: CoreConsumableTokenTypes.FILE_UPLOAD_GRANT,
152
+ consumptionMode: ConsumableToken_ConsumptionMode.SINGLE_USE,
153
+ expiresIn: { value: expiresInMinutes, unit: DurationUnit.MINUTES },
154
+ organizationId: executionContext.initiatorIds?.organizationId,
155
+ userId: executionContext.initiatorIds?.userId,
156
+ resourceIdentifier: String(target.resourceType),
157
+ relatedId: target.resourceId,
158
+ roles: [...(executionContext.initiatorRoles ?? [])],
159
+ metadata: { ...metadataWithoutUrl, uploadUrl: params.uploadUrl },
160
+ });
161
+ const grantId = token._id;
162
+ const tokenValue = token.token;
163
+ const uploadPageUrl = this.resolveUploadPageUrl(tokenValue);
164
+ const statusUrl = `${params.apiBaseUrl}/files/upload-grants/${encodeURIComponent(tokenValue)}`;
165
+ const headerName = WildoHeaderKeys.CONSUMABLE_TOKEN;
166
+ const fileHint = this.suggestFileName(target.fieldName, constraint.allowedMimeTypes);
167
+ const grant = {
168
+ grantId,
169
+ state: FileUploadGrantState.PENDING,
170
+ expiresAt: token.expiresAt.toISOString(),
171
+ singleUse: true,
172
+ target: {
173
+ resourceType: String(target.resourceType),
174
+ fieldName: target.fieldName,
175
+ operation: target.operation,
176
+ resourceId: target.resourceId ?? null,
177
+ },
178
+ constraints: {
179
+ maxBytes: constraint.maxSize,
180
+ allowedMimeTypes: constraint.allowedMimeTypes ?? [],
181
+ },
182
+ uploadUrl: params.uploadUrl,
183
+ uploadHeader: { name: headerName, value: tokenValue },
184
+ // No `-f`: on a refusal the JSON error body is the only thing that tells the caller why.
185
+ uploadCommand: `curl -sS -H "${headerName}: ${tokenValue}" -F "file=@/path/to/${fileHint}" "${params.uploadUrl}"`,
186
+ // In PowerShell `curl` aliases Invoke-WebRequest, which does not understand -F; the real binary is curl.exe.
187
+ uploadCommandPowerShell: `curl.exe -sS -H "${headerName}: ${tokenValue}" -F "file=@C:\\path\\to\\${fileHint}" "${params.uploadUrl}"`,
188
+ uploadPageUrl,
189
+ statusUrl,
190
+ note: this.buildNote(target, uploadPageUrl !== null),
191
+ };
192
+ await this.audit(executionContext, CoreAuditableEventType.FILE_UPLOAD_GRANT_ISSUED, ResourceOperationRiskLevel.MEDIUM, {
193
+ grantId,
194
+ resourceType: String(target.resourceType),
195
+ fieldName: target.fieldName,
196
+ operation: target.operation,
197
+ resourceId: target.resourceId ?? null,
198
+ expiresAt: grant.expiresAt,
199
+ minter: metadataWithoutUrl.minter,
200
+ ipAddress: params.requestProvenance?.ipAddress,
201
+ userAgent: params.requestProvenance?.userAgent,
202
+ });
203
+ this.logDebug('File upload grant minted', { grantId, resourceType: target.resourceType, fieldName: target.fieldName, operation: target.operation });
204
+ return grant;
205
+ }
206
+ /**
207
+ * The upload middleware's question: is the token this context was built from a grant for THIS route?
208
+ *
209
+ * Returns `undefined` when the context is not a grant context at all — a JWT/API-key upload, or an
210
+ * authored non-grant ALTERNATIVE token, which keeps behaving as it did. Throws
211
+ * `FILE_UPLOAD_GRANT_TARGET_MISMATCH` when it IS a grant minted for a different resource, field,
212
+ * operation kind or row. Mirrors `validateFileToken` on the download twin: type pinned AND target
213
+ * pinned; a grant with no binding unlocks nothing.
214
+ *
215
+ * For UPDATE the creator has already coherence-checked `relatedId` against the URL id; the check is
216
+ * repeated here because CREATE has no id, so this is the one place both kinds are decided.
217
+ */
218
+ async assertGrantMatchesRoute(executionContext, target) {
219
+ if (executionContext.executionType !== ExecutionContext_ExecutionType.CONSUMABLE_TOKEN)
220
+ return undefined;
221
+ const tokenValue = executionContext.consumableTokenValue;
222
+ if (!tokenValue)
223
+ return undefined;
224
+ const token = await this.consumableTokenService.validateToken(tokenValue);
225
+ if (token.tokenType !== CoreConsumableTokenTypes.FILE_UPLOAD_GRANT)
226
+ return undefined;
227
+ const parsed = FileUploadGrantMetadataSchema.safeParse(token.metadata);
228
+ const mismatch = (reason) => this.errorBuilder.buildError(ErrorType.AUTHENTICATION, executionContext, {
229
+ customMessageReference: ErrorCustomMessageReference.FILE_UPLOAD_GRANT_TARGET_MISMATCH,
230
+ context: {
231
+ // diagnostic (log-only)
232
+ grantId: token._id,
233
+ reason,
234
+ routeTarget: target,
235
+ grantTarget: { resourceIdentifier: token.resourceIdentifier, relatedId: token.relatedId, metadata: parsed.success ? parsed.data : undefined },
236
+ },
237
+ });
238
+ if (!parsed.success)
239
+ throw mismatch('unparseable grant metadata');
240
+ const metadata = parsed.data;
241
+ if (token.resourceIdentifier !== String(target.resourceType))
242
+ throw mismatch('resource');
243
+ if (metadata.fieldName !== target.fieldName)
244
+ throw mismatch('field');
245
+ if (metadata.operation !== target.operation)
246
+ throw mismatch('operation');
247
+ if (target.operation === CoreResourceOperation.UPDATE ? token.relatedId !== target.resourceId : token.relatedId != null)
248
+ throw mismatch('resourceId');
249
+ return { token, metadata };
250
+ }
251
+ /** The uploader the redeemed file is attributed to: the MINTER, from the grant, never the grant itself. */
252
+ resolveUploaderFromGrant(metadata) {
253
+ return { uploadedBy: metadata.minter.id, uploadedByEntityType: metadata.minter.entityType };
254
+ }
255
+ /**
256
+ * After the one upload landed: write the produced fileId back and audit the redemption. Best-effort
257
+ * by contract — the upload has succeeded; a failure here is logged and the status read degrades to
258
+ * "REDEEMED, file unknown".
259
+ */
260
+ async recordRedemption(grant, file, executionContext) {
261
+ try {
262
+ await this.consumableTokenService.recordFileUploadGrantProducedFile(grant.token._id, file.fileId);
263
+ }
264
+ catch (error) {
265
+ this.logger.warn('File upload grant: produced-file write-back failed; status read will not name the file', {
266
+ grantId: grant.token._id, fileId: file.fileId, ...projectCaughtErrorLogFields(error),
267
+ });
268
+ }
269
+ await this.audit(executionContext, CoreAuditableEventType.FILE_UPLOAD_GRANT_REDEEMED, ResourceOperationRiskLevel.LOW, {
270
+ grantId: grant.token._id,
271
+ fileId: file.fileId,
272
+ mimeType: file.mimeType,
273
+ size: file.size,
274
+ minter: grant.metadata.minter,
275
+ });
276
+ }
277
+ /**
278
+ * Public status read: the token IS the credential, so anyone holding it learns the grant's state,
279
+ * the target and constraints (what the drop page renders), and — after redemption — the `fileId`
280
+ * and file status (what the agent needs). Never the file's name.
281
+ */
282
+ async readStatus(tokenValue) {
283
+ const token = await this.consumableTokenService.findTokenByValue(tokenValue);
284
+ if (!token || token.tokenType !== CoreConsumableTokenTypes.FILE_UPLOAD_GRANT) {
285
+ throw this.errorBuilder.buildError(ErrorType.NOT_FOUND, undefined, {
286
+ customMessageReference: ErrorCustomMessageReference.FILE_UPLOAD_GRANT_NOT_FOUND,
287
+ });
288
+ }
289
+ const parsed = FileUploadGrantMetadataSchema.safeParse(token.metadata);
290
+ if (!parsed.success) {
291
+ throw this.errorBuilder.buildError(ErrorType.NOT_FOUND, undefined, {
292
+ customMessageReference: ErrorCustomMessageReference.FILE_UPLOAD_GRANT_NOT_FOUND,
293
+ context: { grantId: token._id, reason: 'unparseable grant metadata' }, // diagnostic (log-only)
294
+ });
295
+ }
296
+ const metadata = parsed.data;
297
+ const resourceType = token.resourceIdentifier;
298
+ const constraint = await this.constraintResolver.resolve({ resourceType, fieldName: metadata.fieldName });
299
+ let file = null;
300
+ if (metadata.producedFileId) {
301
+ const produced = await this.readProducedFile(metadata.producedFileId);
302
+ if (produced)
303
+ file = { fileId: produced.fileId, status: produced.status };
304
+ }
305
+ return {
306
+ grantId: token._id,
307
+ state: this.deriveState(token),
308
+ expiresAt: token.expiresAt.toISOString(),
309
+ target: {
310
+ resourceType: String(resourceType),
311
+ fieldName: metadata.fieldName,
312
+ operation: metadata.operation,
313
+ resourceId: token.relatedId ?? null,
314
+ },
315
+ constraints: { maxBytes: constraint.maxSize, allowedMimeTypes: constraint.allowedMimeTypes ?? [] },
316
+ uploadUrl: metadata.uploadUrl,
317
+ uploadHeaderName: WildoHeaderKeys.CONSUMABLE_TOKEN,
318
+ file,
319
+ };
320
+ }
321
+ /**
322
+ * Revoke an unredeemed grant — by ID, never by value, and AUTHENTICATED: the minter, or a platform
323
+ * super-administrator. Revoke-by-value on a public route was rejected: anyone holding the link could
324
+ * burn it (harmless) while learning that it existed (not).
325
+ */
326
+ async revoke(grantId, executionContext) {
327
+ const token = await this.consumableTokenService.findTokenById(grantId);
328
+ if (!token || token.tokenType !== CoreConsumableTokenTypes.FILE_UPLOAD_GRANT) {
329
+ throw this.errorBuilder.buildError(ErrorType.NOT_FOUND, executionContext, {
330
+ customMessageReference: ErrorCustomMessageReference.FILE_UPLOAD_GRANT_NOT_FOUND,
331
+ });
332
+ }
333
+ const parsed = FileUploadGrantMetadataSchema.safeParse(token.metadata);
334
+ const caller = resolveFileUploaderPrincipal(executionContext);
335
+ const isMinter = parsed.success && caller !== undefined
336
+ && caller.uploadedBy === parsed.data.minter.id && caller.uploadedByEntityType === parsed.data.minter.entityType;
337
+ const isSuperAdmin = (executionContext.initiatorRoles ?? []).some((entry) => entry.roles.includes(CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN));
338
+ if (!isMinter && !isSuperAdmin) {
339
+ throw this.errorBuilder.buildError(ErrorType.AUTHORIZATION, executionContext, {
340
+ customMessageReference: ErrorCustomMessageReference.AUTHORIZATIONS_ACCESS_DENIED,
341
+ context: { grantId }, // diagnostic (log-only)
342
+ });
343
+ }
344
+ const revoked = await this.consumableTokenService.revokeToken(grantId);
345
+ if (revoked) {
346
+ await this.audit(executionContext, CoreAuditableEventType.FILE_UPLOAD_GRANT_REVOKED, ResourceOperationRiskLevel.LOW, {
347
+ grantId,
348
+ revokedBy: caller ? { entityType: caller.uploadedByEntityType, id: caller.uploadedBy } : null,
349
+ asSuperAdmin: !isMinter && isSuperAdmin,
350
+ });
351
+ }
352
+ return revoked;
353
+ }
354
+ // ── helpers ────────────────────────────────────────────────────────────────
355
+ /**
356
+ * Read the produced FILES row with no caller context — the status route is public and the token is
357
+ * the credential. Same mechanism as the file controller's token-access download path (an internal
358
+ * system context against the FILES repository, keyed on `_id`); only `fileId` and `status` leave here.
359
+ */
360
+ async readProducedFile(fileId) {
361
+ const internalContext = await this.executionContextCreator.createForInternalSystemOperation();
362
+ const filesRepository = this.repositoriesRegistry.getRepositoryOrThrow(CoreResourceType.FILES, internalContext);
363
+ const file = await filesRepository.read(internalContext, { _id: fileId });
364
+ return file ? { fileId: file.fileId, status: file.status } : null;
365
+ }
366
+ deriveState(token) {
367
+ if (token.revokedAt)
368
+ return FileUploadGrantState.REVOKED;
369
+ if (token.isConsumed)
370
+ return FileUploadGrantState.REDEEMED;
371
+ if (token.expiresAt.getTime() <= Date.now())
372
+ return FileUploadGrantState.EXPIRED;
373
+ return FileUploadGrantState.PENDING;
374
+ }
375
+ /** `null` for a headless application (no frontend service declared) — there is no page to hand a human. */
376
+ resolveUploadPageUrl(tokenValue) {
377
+ const config = this.appConfigService.config;
378
+ const frontendServiceName = this.appConfigService.resolveDefaultFrontendServiceName();
379
+ const base = frontendServiceName ? AuthControllerUtils.lookupFrontendPublicUrl(config, frontendServiceName) : null;
380
+ if (!base)
381
+ return null;
382
+ const trimmed = base.endsWith('/') ? base.slice(0, -1) : base;
383
+ return `${trimmed}${FILE_UPLOAD_GRANT_PAGE_PATH}/${encodeURIComponent(tokenValue)}`;
384
+ }
385
+ /** A plausible file name for the curl example, from the field name and the first allowed MIME type. */
386
+ suggestFileName(fieldName, allowedMimeTypes) {
387
+ const stem = fieldName.replace(/[^\w.-]+/g, '_').replace(/\./g, '-').slice(0, 40) || 'file';
388
+ const first = allowedMimeTypes?.find((m) => !m.endsWith('/*'));
389
+ const ext = first ? first.split('/')[1]?.replace(/^x-/, '').replace(/\+.*$/, '') : undefined;
390
+ return ext && /^[a-z0-9]{2,5}$/i.test(ext) ? `${stem}.${ext}` : stem;
391
+ }
392
+ buildNote(target, hasPage) {
393
+ const attach = target.operation === CoreResourceOperation.UPDATE
394
+ ? `then pass the returned fileId as "${target.fieldName}.fileId" when updating ${String(target.resourceType)} ${target.resourceId}`
395
+ : `then pass the returned fileId as "${target.fieldName}.fileId" when creating the ${String(target.resourceType)} record`;
396
+ const human = hasPage ? 'or show uploadPageUrl to the user so they can drop the file in their browser, ' : '';
397
+ return `Run uploadCommand if you can execute commands and the file is on your filesystem, ${human}${attach}. `
398
+ + 'The link is single-use and bound to this one field: if it expires or the upload is refused, mint a new one. '
399
+ + 'The header value is not your credential — it unlocks exactly one upload.';
400
+ }
401
+ async audit(executionContext, eventType, riskLevel, eventData) {
402
+ if (!this.auditLogsService) {
403
+ this.logger.warn('File upload grant: audit service unbound; event not recorded', { eventType });
404
+ return;
405
+ }
406
+ try {
407
+ await this.auditLogsService.logGenericEvent({
408
+ userId: executionContext.initiatorIds?.userId,
409
+ organizationId: executionContext.initiatorIds?.organizationId,
410
+ riskLevel,
411
+ eventType,
412
+ eventData,
413
+ }, executionContext);
414
+ }
415
+ catch (error) {
416
+ // An audit failure never fails the operation it observes; it is logged so it is not silent.
417
+ this.logger.warn('File upload grant: audit emission failed', { eventType, ...projectCaughtErrorLogFields(error) });
418
+ }
419
+ }
420
+ };
421
+ FileUploadGrantBackendService = __decorate([
422
+ injectable(),
423
+ __param(0, inject(SAAS_SERVICE_TYPES.Logger)),
424
+ __param(1, inject(SAAS_SERVICE_TYPES.ErrorBuilderService)),
425
+ __param(2, inject(SAAS_SERVICE_TYPES.ConsumableTokenService)),
426
+ __param(3, inject(SAAS_SERVICE_TYPES.FileConstraintResolverChain)),
427
+ __param(4, inject(SAAS_SERVICE_TYPES.FileFieldDetectionService)),
428
+ __param(5, inject(SAAS_SERVICE_TYPES.ExecutionContextCreatorBackendService)),
429
+ __param(6, inject(SAAS_SERVICE_TYPES.RepositoriesRegistryHandlerService)),
430
+ __param(7, inject(SAAS_SERVICE_TYPES.AppConfigService)),
431
+ __param(8, inject(SAAS_SERVICE_TYPES.AuditLogsService)),
432
+ __param(8, optional()),
433
+ __metadata("design:paramtypes", [Function, ErrorBuilderBackendService,
434
+ ConsumableTokenBackendService,
435
+ FileConstraintResolverChain,
436
+ FileFieldDetectionBackendService,
437
+ ExecutionContextCreatorBackendService,
438
+ RepositoriesRegistryHandlerBackendService,
439
+ AppConfigurationService, Function])
440
+ ], FileUploadGrantBackendService);
441
+ export { FileUploadGrantBackendService };
442
+ //# sourceMappingURL=file-upload-grant.backend.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-upload-grant.backend.service.js","sourceRoot":"","sources":["../../../../../src/files/services/file-upload-grant.backend.service.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * File Upload Grant Backend Service\n *\n * The ONE mint function behind both doors — the REST sibling route (`…/files/<field>/grant`) and the\n * MCP derived tool — plus the route-binding check the upload middleware runs, the public status read,\n * revocation, and the post-redemption write-back. Issue #312.\n *\n * ## What a grant is\n *\n * A `SINGLE_USE` consumable token of type `FILE_UPLOAD_GRANT` that lets whoever holds it perform ONE\n * upload into ONE resource file field with the MINTER's authority. Nothing durable is created at mint\n * but the token. The upload goes through the resource's EXISTING file-upload route: the token becomes\n * an ordinary `CONSUMABLE_TOKEN` execution context (typed fields → identity) and the ordinary\n * authorizer decides. This service never decides \"may this principal put a file here\" — the upload\n * middleware does, once, for mint and upload alike, which is what makes mint-authority ≡\n * upload-authority by construction.\n *\n * ## Why the route binding lives in `metadata` and is checked HERE\n *\n * `createExecutionContextFromRequest` turns the token's TYPED fields (`userId`, `organizationId`,\n * `roles`, `resourceIdentifier`, `relatedId`) into identity and deliberately reads nothing from\n * `metadata`. Which field, which operation kind, which concrete upload URL — those are ROUTE facts,\n * and the upload middleware asks this service to check them against the route the token was\n * presented on. Identity and route stay separate concerns.\n */\n\nimport { injectable, inject, optional } from 'inversify';\nimport {\n BackendApiType,\n ConsumableToken_ConsumptionMode,\n CoreAuditableEventType,\n CoreConsumableTokenTypes,\n CORE_APP_ROLES,\n ErrorCustomMessageReference,\n ErrorType,\n ExecutionContext_ExecutionType,\n FILE_UPLOAD_GRANT_DEFAULT_MINUTES,\n FILE_UPLOAD_GRANT_PAGE_PATH,\n FileUploadGrantMetadataSchema,\n FileUploadGrantState,\n ResourceOperationRiskLevel,\n TokenAuthenticationPolicy,\n WildoHeaderKeys,\n type FileUploadGrant,\n type FileUploadGrantMetadata,\n type FileUploadGrantOperation,\n type FileUploadGrantStatus,\n type ResourceConfiguration_Operation,\n type ResourceType,\n CoreResourceType,\n CoreResourceOperation,\n type File,\n} from '@wildo-ai/saas-models';\nimport { DurationUnit, FileGenerationSource } from '@wildo-ai/zod-decorators';\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 { ErrorBuilderBackendService } from '~wildo-backend-lib/errors/services/error-builder.backend.service';\nimport { projectCaughtErrorLogFields } from '~wildo-backend-lib/errors/utils/error-log-level-classification.backend.utils';\nimport { AppConfigurationService } from '~wildo-backend-lib/config/services/app-configuration.backend.service';\nimport type { ExecutionContext } from '~wildo-backend-lib/runtime/models/execution-context.backend.schemas';\nimport { ConsumableTokenBackendService } from '~wildo-backend-lib/security/consumable-tokens/services/consumable-token.backend.service';\nimport type { ConsumableToken } from '~wildo-backend-lib/security/consumable-tokens/models/consumable-tokens.shared.schemas';\nimport { FileConstraintResolverChain } from '~wildo-backend-lib/files/constraints/file-constraint-resolver-chain.backend.service';\nimport { FileFieldDetectionBackendService } from '~wildo-backend-lib/files/services/file-field-detection.backend.service';\nimport { ExecutionContextCreatorBackendService } from '~wildo-backend-lib/runtime/services/execution-context-creator.backend.service';\nimport { RepositoriesRegistryHandlerBackendService } from '~wildo-backend-lib/base-classes/services/repositories/repositories-registry-handler.backend.service';\nimport { resolveFileUploaderPrincipal, type FileUploaderPrincipal } from '~wildo-backend-lib/files/utils/file-uploader.utils';\nimport { AuthControllerUtils } from '~wildo-backend-lib/security/authentications/services/utils/auth-controller.utils';\nimport type { AuditLogsBackendService } from '~wildo-backend-lib/compliance/audit-trails/services/audit-logs.backend.service';\n\n/** The route facts a grant is bound to, as the upload middleware knows them. */\nexport interface FileUploadGrantTarget {\n resourceType: ResourceType;\n fieldName: string;\n operation: FileUploadGrantOperation;\n resourceId?: string;\n}\n\nexport interface MintFileUploadGrantParams {\n /** The MINTER's context, produced by the upload route's own authorization middleware. */\n executionContext: ExecutionContext<any>;\n target: FileUploadGrantTarget;\n /** Requested lifetime; the engine ceiling is enforced at `createToken`, rejecting never clamping. */\n expiresInMinutes?: number;\n /** The concrete, absolute URL of the upload route this grant is for (the request's own URL minus `/grant`). */\n uploadUrl: string;\n /** Absolute API base including the mount prefix (e.g. `https://api.example.com/api/v1`), for the status URL. */\n apiBaseUrl: string;\n /** Request provenance for the audit row; never the token. */\n requestProvenance?: { ipAddress?: string; userAgent?: string };\n}\n\n@injectable()\nexport class FileUploadGrantBackendService {\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.ConsumableTokenService) private readonly consumableTokenService: ConsumableTokenBackendService,\n @inject(SAAS_SERVICE_TYPES.FileConstraintResolverChain) private readonly constraintResolver: FileConstraintResolverChain,\n @inject(SAAS_SERVICE_TYPES.FileFieldDetectionService) private readonly fileFieldDetection: FileFieldDetectionBackendService,\n @inject(SAAS_SERVICE_TYPES.ExecutionContextCreatorBackendService) private readonly executionContextCreator: ExecutionContextCreatorBackendService,\n @inject(SAAS_SERVICE_TYPES.RepositoriesRegistryHandlerService) private readonly repositoriesRegistry: RepositoriesRegistryHandlerBackendService,\n @inject(SAAS_SERVICE_TYPES.AppConfigService) private readonly appConfigService: AppConfigurationService,\n /**\n * Optional so a harness without the audit stack can construct this service; in production the\n * container always binds it. A missing service is logged at WARN on first use, never silent.\n */\n @inject(SAAS_SERVICE_TYPES.AuditLogsService) @optional() private readonly auditLogsService?: AuditLogsBackendService,\n ) {\n this.logDebug = this.logger.debugByType('FileUploadGrantBackendService');\n this.logger.setDebugTypeLogging('FileUploadGrantBackendService', false);\n }\n\n /**\n * The operation the upload routes hand to the execution-context creator (issue #312, D4).\n *\n * `tokenAuthentication` lives on the OPERATION, so declaring it on the authored CREATE/UPDATE would\n * let a grant perform the whole JSON write. Instead the `…/files/<field>` and `…/files/<field>/grant`\n * routes — and ONLY those — get this derived copy, which accepts the grant type as an ALTERNATIVE\n * credential beside whatever the author declared. The JSON routes keep the authored operation, so a\n * grant presented there is refused by GATE 1 (`CONSUMABLE_TOKEN_NOT_ACCEPTED_FOR_OPERATION`).\n *\n * An authored ADDITIVE policy is NOT preserved as ADDITIVE here: the upload route's own authorizer\n * decides on the resulting context either way, and an additive token on a multipart upload is not a\n * case any resource declares today. If one appears, this is the seam to widen — do not widen the\n * authored operation.\n */\n static withUploadGrantAcceptance<T extends ResourceConfiguration_Operation<any, any, any>>(operation: T): T {\n const authored = 'tokenAuthentication' in operation ? operation.tokenAuthentication : undefined;\n const authoredTypes = authored?.policy === TokenAuthenticationPolicy.ALTERNATIVE ? (authored.types ?? []) : [];\n return {\n ...operation,\n tokenAuthentication: {\n types: [...authoredTypes, CoreConsumableTokenTypes.FILE_UPLOAD_GRANT],\n policy: TokenAuthenticationPolicy.ALTERNATIVE,\n },\n } as T;\n }\n\n /**\n * Mint a grant for the target the caller has JUST been authorized on.\n *\n * Refuses two minter kinds: a `CONSUMABLE_TOKEN` context (a grant may not mint a grant — no\n * delegation chains) and an `ANONYMOUS_SESSION` (no stable subject to attribute the file to, no\n * roles worth snapshotting). `USER_REQUEST` and both machine principals mint.\n */\n async mint(params: MintFileUploadGrantParams): Promise<FileUploadGrant> {\n const { executionContext, target } = params;\n\n if (\n executionContext.executionType === ExecutionContext_ExecutionType.CONSUMABLE_TOKEN\n || executionContext.executionType === ExecutionContext_ExecutionType.ANONYMOUS_SESSION\n ) {\n throw this.errorBuilder.buildError(ErrorType.AUTHORIZATION, executionContext, {\n customMessageReference: ErrorCustomMessageReference.FILE_UPLOAD_GRANT_MINTER_NOT_ELIGIBLE,\n context: { executionType: executionContext.executionType }, // diagnostic (log-only)\n });\n }\n\n const minter = resolveFileUploaderPrincipal(executionContext);\n if (!minter) {\n // A principal the uploader resolver cannot name cannot be the file's owner either.\n throw this.errorBuilder.buildError(ErrorType.AUTHORIZATION, executionContext, {\n customMessageReference: ErrorCustomMessageReference.FILE_UPLOAD_GRANT_MINTER_NOT_ELIGIBLE,\n context: { executionType: executionContext.executionType, reason: 'no uploader principal' }, // diagnostic (log-only)\n });\n }\n\n const fieldMeta = this.fileFieldDetection.getFileFieldMetadata(target.resourceType, target.fieldName);\n if (!fieldMeta) {\n throw this.errorBuilder.buildError(ErrorType.VALIDATION, executionContext, {\n customMessageReference: ErrorCustomMessageReference.VALIDATION,\n context: { message: 'Not a file field', resourceType: target.resourceType, fieldName: target.fieldName }, // diagnostic (log-only)\n });\n }\n if (fieldMeta.fileMetadata.generation?.source === FileGenerationSource.PDF_TEMPLATE) {\n // Same refusal the upload handler makes, made EARLY: a grant for a field that can never receive a\n // user upload would be a link that fails on redemption for a reason knowable at mint.\n throw this.errorBuilder.buildError(ErrorType.BUSINESS_RULE, executionContext, {\n customMessageReference: ErrorCustomMessageReference.FILE_GENERATED_FIELD_NOT_WRITABLE,\n context: { resourceType: target.resourceType, fieldName: target.fieldName }, // diagnostic (log-only)\n });\n }\n\n const constraint = await this.constraintResolver.resolve({ resourceType: target.resourceType, fieldName: target.fieldName });\n const expiresInMinutes = params.expiresInMinutes ?? FILE_UPLOAD_GRANT_DEFAULT_MINUTES;\n\n const metadataWithoutUrl: Omit<FileUploadGrantMetadata, 'uploadUrl' | 'producedFileId'> = {\n fieldName: target.fieldName,\n operation: target.operation,\n minter: { entityType: minter.uploadedByEntityType, id: minter.uploadedBy },\n };\n\n // assurance-control: WILDO.IDENTITY.DELEGATED_AUTHORIZATION — a principal delegates ONE upload, into\n // ONE field, under its own authority, to whoever holds the grant. The ceiling and SINGLE_USE are\n // enforced inside createToken; the audit row below is what makes the delegation accountable.\n const token = await this.consumableTokenService.createToken({\n tokenType: CoreConsumableTokenTypes.FILE_UPLOAD_GRANT,\n consumptionMode: ConsumableToken_ConsumptionMode.SINGLE_USE,\n expiresIn: { value: expiresInMinutes, unit: DurationUnit.MINUTES },\n organizationId: executionContext.initiatorIds?.organizationId,\n userId: executionContext.initiatorIds?.userId,\n resourceIdentifier: String(target.resourceType),\n relatedId: target.resourceId,\n roles: [...(executionContext.initiatorRoles ?? [])],\n metadata: { ...metadataWithoutUrl, uploadUrl: params.uploadUrl },\n });\n\n const grantId = token._id;\n const tokenValue = token.token;\n const uploadPageUrl = this.resolveUploadPageUrl(tokenValue);\n const statusUrl = `${params.apiBaseUrl}/files/upload-grants/${encodeURIComponent(tokenValue)}`;\n const headerName = WildoHeaderKeys.CONSUMABLE_TOKEN;\n const fileHint = this.suggestFileName(target.fieldName, constraint.allowedMimeTypes);\n\n const grant: FileUploadGrant = {\n grantId,\n state: FileUploadGrantState.PENDING,\n expiresAt: token.expiresAt.toISOString(),\n singleUse: true,\n target: {\n resourceType: String(target.resourceType),\n fieldName: target.fieldName,\n operation: target.operation,\n resourceId: target.resourceId ?? null,\n },\n constraints: {\n maxBytes: constraint.maxSize,\n allowedMimeTypes: constraint.allowedMimeTypes ?? [],\n },\n uploadUrl: params.uploadUrl,\n uploadHeader: { name: headerName, value: tokenValue },\n // No `-f`: on a refusal the JSON error body is the only thing that tells the caller why.\n uploadCommand: `curl -sS -H \"${headerName}: ${tokenValue}\" -F \"file=@/path/to/${fileHint}\" \"${params.uploadUrl}\"`,\n // In PowerShell `curl` aliases Invoke-WebRequest, which does not understand -F; the real binary is curl.exe.\n uploadCommandPowerShell: `curl.exe -sS -H \"${headerName}: ${tokenValue}\" -F \"file=@C:\\\\path\\\\to\\\\${fileHint}\" \"${params.uploadUrl}\"`,\n uploadPageUrl,\n statusUrl,\n note: this.buildNote(target, uploadPageUrl !== null),\n };\n\n await this.audit(executionContext, CoreAuditableEventType.FILE_UPLOAD_GRANT_ISSUED, ResourceOperationRiskLevel.MEDIUM, {\n grantId,\n resourceType: String(target.resourceType),\n fieldName: target.fieldName,\n operation: target.operation,\n resourceId: target.resourceId ?? null,\n expiresAt: grant.expiresAt,\n minter: metadataWithoutUrl.minter,\n ipAddress: params.requestProvenance?.ipAddress,\n userAgent: params.requestProvenance?.userAgent,\n });\n\n this.logDebug('File upload grant minted', { grantId, resourceType: target.resourceType, fieldName: target.fieldName, operation: target.operation });\n return grant;\n }\n\n /**\n * The upload middleware's question: is the token this context was built from a grant for THIS route?\n *\n * Returns `undefined` when the context is not a grant context at all — a JWT/API-key upload, or an\n * authored non-grant ALTERNATIVE token, which keeps behaving as it did. Throws\n * `FILE_UPLOAD_GRANT_TARGET_MISMATCH` when it IS a grant minted for a different resource, field,\n * operation kind or row. Mirrors `validateFileToken` on the download twin: type pinned AND target\n * pinned; a grant with no binding unlocks nothing.\n *\n * For UPDATE the creator has already coherence-checked `relatedId` against the URL id; the check is\n * repeated here because CREATE has no id, so this is the one place both kinds are decided.\n */\n async assertGrantMatchesRoute(\n executionContext: ExecutionContext<any>,\n target: FileUploadGrantTarget,\n ): Promise<{ token: ConsumableToken; metadata: FileUploadGrantMetadata } | undefined> {\n if (executionContext.executionType !== ExecutionContext_ExecutionType.CONSUMABLE_TOKEN) return undefined;\n const tokenValue = executionContext.consumableTokenValue;\n if (!tokenValue) return undefined;\n\n const token = await this.consumableTokenService.validateToken(tokenValue);\n if (token.tokenType !== CoreConsumableTokenTypes.FILE_UPLOAD_GRANT) return undefined;\n\n const parsed = FileUploadGrantMetadataSchema.safeParse(token.metadata);\n const mismatch = (reason: string) => this.errorBuilder.buildError(ErrorType.AUTHENTICATION, executionContext, {\n customMessageReference: ErrorCustomMessageReference.FILE_UPLOAD_GRANT_TARGET_MISMATCH,\n context: {\n // diagnostic (log-only)\n grantId: token._id,\n reason,\n routeTarget: target,\n grantTarget: { resourceIdentifier: token.resourceIdentifier, relatedId: token.relatedId, metadata: parsed.success ? parsed.data : undefined },\n },\n });\n\n if (!parsed.success) throw mismatch('unparseable grant metadata');\n const metadata = parsed.data;\n if (token.resourceIdentifier !== String(target.resourceType)) throw mismatch('resource');\n if (metadata.fieldName !== target.fieldName) throw mismatch('field');\n if (metadata.operation !== target.operation) throw mismatch('operation');\n if (target.operation === CoreResourceOperation.UPDATE ? token.relatedId !== target.resourceId : token.relatedId != null) throw mismatch('resourceId');\n\n return { token, metadata };\n }\n\n /** The uploader the redeemed file is attributed to: the MINTER, from the grant, never the grant itself. */\n resolveUploaderFromGrant(metadata: FileUploadGrantMetadata): FileUploaderPrincipal {\n return { uploadedBy: metadata.minter.id, uploadedByEntityType: metadata.minter.entityType as FileUploaderPrincipal['uploadedByEntityType'] };\n }\n\n /**\n * After the one upload landed: write the produced fileId back and audit the redemption. Best-effort\n * by contract — the upload has succeeded; a failure here is logged and the status read degrades to\n * \"REDEEMED, file unknown\".\n */\n async recordRedemption(\n grant: { token: ConsumableToken; metadata: FileUploadGrantMetadata },\n file: { fileId: string; mimeType: string; size: number },\n executionContext: ExecutionContext<any>,\n ): Promise<void> {\n try {\n await this.consumableTokenService.recordFileUploadGrantProducedFile(grant.token._id, file.fileId);\n } catch (error) {\n this.logger.warn('File upload grant: produced-file write-back failed; status read will not name the file', {\n grantId: grant.token._id, fileId: file.fileId, ...projectCaughtErrorLogFields(error),\n });\n }\n await this.audit(executionContext, CoreAuditableEventType.FILE_UPLOAD_GRANT_REDEEMED, ResourceOperationRiskLevel.LOW, {\n grantId: grant.token._id,\n fileId: file.fileId,\n mimeType: file.mimeType,\n size: file.size,\n minter: grant.metadata.minter,\n });\n }\n\n /**\n * Public status read: the token IS the credential, so anyone holding it learns the grant's state,\n * the target and constraints (what the drop page renders), and — after redemption — the `fileId`\n * and file status (what the agent needs). Never the file's name.\n */\n async readStatus(tokenValue: string): Promise<FileUploadGrantStatus> {\n const token = await this.consumableTokenService.findTokenByValue(tokenValue);\n if (!token || token.tokenType !== CoreConsumableTokenTypes.FILE_UPLOAD_GRANT) {\n throw this.errorBuilder.buildError(ErrorType.NOT_FOUND, undefined, {\n customMessageReference: ErrorCustomMessageReference.FILE_UPLOAD_GRANT_NOT_FOUND,\n });\n }\n const parsed = FileUploadGrantMetadataSchema.safeParse(token.metadata);\n if (!parsed.success) {\n throw this.errorBuilder.buildError(ErrorType.NOT_FOUND, undefined, {\n customMessageReference: ErrorCustomMessageReference.FILE_UPLOAD_GRANT_NOT_FOUND,\n context: { grantId: token._id, reason: 'unparseable grant metadata' }, // diagnostic (log-only)\n });\n }\n const metadata = parsed.data;\n const resourceType = token.resourceIdentifier as ResourceType;\n const constraint = await this.constraintResolver.resolve({ resourceType, fieldName: metadata.fieldName });\n\n let file: FileUploadGrantStatus['file'] = null;\n if (metadata.producedFileId) {\n const produced = await this.readProducedFile(metadata.producedFileId);\n if (produced) file = { fileId: produced.fileId, status: produced.status };\n }\n\n return {\n grantId: token._id,\n state: this.deriveState(token),\n expiresAt: token.expiresAt.toISOString(),\n target: {\n resourceType: String(resourceType),\n fieldName: metadata.fieldName,\n operation: metadata.operation,\n resourceId: token.relatedId ?? null,\n },\n constraints: { maxBytes: constraint.maxSize, allowedMimeTypes: constraint.allowedMimeTypes ?? [] },\n uploadUrl: metadata.uploadUrl,\n uploadHeaderName: WildoHeaderKeys.CONSUMABLE_TOKEN,\n file,\n };\n }\n\n /**\n * Revoke an unredeemed grant — by ID, never by value, and AUTHENTICATED: the minter, or a platform\n * super-administrator. Revoke-by-value on a public route was rejected: anyone holding the link could\n * burn it (harmless) while learning that it existed (not).\n */\n async revoke(grantId: string, executionContext: ExecutionContext<any>): Promise<boolean> {\n const token = await this.consumableTokenService.findTokenById(grantId);\n if (!token || token.tokenType !== CoreConsumableTokenTypes.FILE_UPLOAD_GRANT) {\n throw this.errorBuilder.buildError(ErrorType.NOT_FOUND, executionContext, {\n customMessageReference: ErrorCustomMessageReference.FILE_UPLOAD_GRANT_NOT_FOUND,\n });\n }\n const parsed = FileUploadGrantMetadataSchema.safeParse(token.metadata);\n const caller = resolveFileUploaderPrincipal(executionContext);\n const isMinter = parsed.success && caller !== undefined\n && caller.uploadedBy === parsed.data.minter.id && caller.uploadedByEntityType === parsed.data.minter.entityType;\n const isSuperAdmin = (executionContext.initiatorRoles ?? []).some((entry) => entry.roles.includes(CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN));\n if (!isMinter && !isSuperAdmin) {\n throw this.errorBuilder.buildError(ErrorType.AUTHORIZATION, executionContext, {\n customMessageReference: ErrorCustomMessageReference.AUTHORIZATIONS_ACCESS_DENIED,\n context: { grantId }, // diagnostic (log-only)\n });\n }\n const revoked = await this.consumableTokenService.revokeToken(grantId);\n if (revoked) {\n await this.audit(executionContext, CoreAuditableEventType.FILE_UPLOAD_GRANT_REVOKED, ResourceOperationRiskLevel.LOW, {\n grantId,\n revokedBy: caller ? { entityType: caller.uploadedByEntityType, id: caller.uploadedBy } : null,\n asSuperAdmin: !isMinter && isSuperAdmin,\n });\n }\n return revoked;\n }\n\n // ── helpers ────────────────────────────────────────────────────────────────\n\n /**\n * Read the produced FILES row with no caller context — the status route is public and the token is\n * the credential. Same mechanism as the file controller's token-access download path (an internal\n * system context against the FILES repository, keyed on `_id`); only `fileId` and `status` leave here.\n */\n private async readProducedFile(fileId: string): Promise<Pick<File, 'fileId' | 'status'> | null> {\n const internalContext = await this.executionContextCreator.createForInternalSystemOperation();\n const filesRepository = this.repositoriesRegistry.getRepositoryOrThrow(CoreResourceType.FILES, internalContext);\n const file = await filesRepository.read<File>(internalContext, { _id: fileId });\n return file ? { fileId: file.fileId, status: file.status } : null;\n }\n\n private deriveState(token: ConsumableToken): FileUploadGrantState {\n if (token.revokedAt) return FileUploadGrantState.REVOKED;\n if (token.isConsumed) return FileUploadGrantState.REDEEMED;\n if (token.expiresAt.getTime() <= Date.now()) return FileUploadGrantState.EXPIRED;\n return FileUploadGrantState.PENDING;\n }\n\n /** `null` for a headless application (no frontend service declared) — there is no page to hand a human. */\n private resolveUploadPageUrl(tokenValue: string): string | null {\n const config = this.appConfigService.config;\n const frontendServiceName = this.appConfigService.resolveDefaultFrontendServiceName();\n const base = frontendServiceName ? AuthControllerUtils.lookupFrontendPublicUrl(config, frontendServiceName) : null;\n if (!base) return null;\n const trimmed = base.endsWith('/') ? base.slice(0, -1) : base;\n return `${trimmed}${FILE_UPLOAD_GRANT_PAGE_PATH}/${encodeURIComponent(tokenValue)}`;\n }\n\n /** A plausible file name for the curl example, from the field name and the first allowed MIME type. */\n private suggestFileName(fieldName: string, allowedMimeTypes: string[] | undefined): string {\n const stem = fieldName.replace(/[^\\w.-]+/g, '_').replace(/\\./g, '-').slice(0, 40) || 'file';\n const first = allowedMimeTypes?.find((m) => !m.endsWith('/*'));\n const ext = first ? first.split('/')[1]?.replace(/^x-/, '').replace(/\\+.*$/, '') : undefined;\n return ext && /^[a-z0-9]{2,5}$/i.test(ext) ? `${stem}.${ext}` : stem;\n }\n\n private buildNote(target: FileUploadGrantTarget, hasPage: boolean): string {\n const attach = target.operation === CoreResourceOperation.UPDATE\n ? `then pass the returned fileId as \"${target.fieldName}.fileId\" when updating ${String(target.resourceType)} ${target.resourceId}`\n : `then pass the returned fileId as \"${target.fieldName}.fileId\" when creating the ${String(target.resourceType)} record`;\n const human = hasPage ? 'or show uploadPageUrl to the user so they can drop the file in their browser, ' : '';\n return `Run uploadCommand if you can execute commands and the file is on your filesystem, ${human}${attach}. `\n + 'The link is single-use and bound to this one field: if it expires or the upload is refused, mint a new one. '\n + 'The header value is not your credential — it unlocks exactly one upload.';\n }\n\n private async audit(\n executionContext: ExecutionContext<any>,\n eventType: CoreAuditableEventType,\n riskLevel: ResourceOperationRiskLevel,\n eventData: Record<string, unknown>,\n ): Promise<void> {\n if (!this.auditLogsService) {\n this.logger.warn('File upload grant: audit service unbound; event not recorded', { eventType });\n return;\n }\n try {\n await this.auditLogsService.logGenericEvent({\n userId: executionContext.initiatorIds?.userId,\n organizationId: executionContext.initiatorIds?.organizationId,\n riskLevel,\n eventType,\n eventData,\n }, executionContext);\n } catch (error) {\n // An audit failure never fails the operation it observes; it is logged so it is not silent.\n this.logger.warn('File upload grant: audit emission failed', { eventType, ...projectCaughtErrorLogFields(error) });\n }\n }\n}\n"]}
@@ -346,6 +346,25 @@ export declare class FilesBackendService {
346
346
  * @param executionContext - Execution context
347
347
  * @returns Access scope information with all identifiers
348
348
  */
349
+ /**
350
+ * Does the caller hold ORGANIZATION-WIDE membership of this exact organization?
351
+ *
352
+ * Answered only from `initiatorRoles`, the one input a request cannot author for itself.
353
+ *
354
+ * **A unit-scoped entry does not count, and that is a decision rather than an oversight.**
355
+ * `ExecutionContext_RoleInfo.organizationUnitId` marks a grant that is live authority inside ONE unit,
356
+ * and its own schema is explicit that reading such an entry as tenant-wide is "a privilege escalation,
357
+ * not a convenience". Membership of the tenant is arguably implied either way — a unit member is a
358
+ * member — but this route serves a file scoped to the WHOLE organization, so the narrower reading is
359
+ * the safe one and {@link isOrganizationWideRoleInfo} is the single definition of it. If a unit-scoped
360
+ * caller should reach an organization-scoped file, argue it and change it here, once.
361
+ *
362
+ * A platform administrator who is not a member gets nothing from this, which is also deliberate: the
363
+ * cross-tenant admission model is per-operation-variant (`admitsCrossTenantPlatformAdministration` plus
364
+ * a usable platform-access grant), these controller routes are not resource operations, and granting
365
+ * reach by position in the request path is exactly the ambient privilege that model removed.
366
+ */
367
+ private callerHoldsOrganizationWideMembership;
349
368
  protected deriveAccessScope(executionContext: ExecutionContext<any>): {
350
369
  applicationId?: string;
351
370
  organizationId?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"files.backend.service.d.ts","sourceRoot":"","sources":["../../../../../src/files/services/files.backend.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"files.backend.service.d.ts","sourceRoot":"","sources":["../../../../../src/files/services/files.backend.service.ts"],"names":[],"mappings":"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"}