@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
@@ -11,13 +11,13 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
11
11
  return function (target, key) { decorator(target, key, paramIndex); }
12
12
  };
13
13
  import { inject, injectable, optional } from "inversify";
14
- import { anyOrganizationUnitGrantInheritsDownward, CORE_APP_ROLES, expandOrganizationUnitGrantThroughInheritance, isOrganizationWideRoleInfo, OrganizationUnitNarrowingDecisionKind, resolveOrganizationUnitNarrowingDecision, isWildoBackendError, } from "@wildo-ai/saas-models";
14
+ import { anyOrganizationUnitGrantInheritsDownward, CORE_APP_ROLES, expandOrganizationUnitGrantThroughInheritance, isOrganizationWideRoleInfo, OrganizationUnitNarrowingDecisionKind, requiredRolesDeclarePublicAccess, resolveOrganizationUnitNarrowingDecision, isWildoBackendError, } from "@wildo-ai/saas-models";
15
15
  import { SAAS_SERVICE_TYPES } from "../../../inject/models/service-types.js";
16
16
  import { LoggerService } from "../../../monitoring/logger/services/logger.service.js";
17
17
  import { ErrorBuilderBackendService } from "../../../errors/services/error-builder.backend.service.js";
18
18
  import { describeCaughtError, projectCaughtErrorLogFields } from "../../../errors/utils/error-log-level-classification.backend.utils.js";
19
19
  import { RepositoriesRegistryHandlerBackendService } from "../../../base-classes/services/repositories/repositories-registry-handler.backend.service.js";
20
- import { CoreResourceType, coreResourceShared_FieldIdentifier, PlatformAccessGrantStatus, PlatformAccessGrants_Operations, ResourcePrimaryScope, isPlatformAccessGrantUsable, PRIMARY_SCOPE_TO_CORE_RESOURCE_TYPE, ErrorType, ErrorCustomMessageReference, DEFAULT_APP_ROLE_CONFIGURATION, DEFAULT_ORGANIZATION_ROLES, CoreResourceOperation, ExecutionContext_ExecutionType, ResourceOperationDenialReason, ResourceOperationRiskLevel } from "@wildo-ai/saas-models";
20
+ import { CoreResourceType, IntrospectionTenancyStance, PersistenceAdapter, coreResourceShared_FieldIdentifier, PlatformAccessGrantStatus, PlatformAccessGrants_Operations, ResourcePrimaryScope, isPlatformAccessGrantUsable, PRIMARY_SCOPE_TO_CORE_RESOURCE_TYPE, ErrorType, ErrorCustomMessageReference, DEFAULT_APP_ROLE_CONFIGURATION, DEFAULT_ORGANIZATION_ROLES, CoreResourceOperation, ResourceOperationDenialReason, ResourceOperationRiskLevel } from "@wildo-ai/saas-models";
21
21
  import { classifyAuthorizationDenial, resolveDenialAuditEmissionDecision } from "../../../security/authorizations/authorization-denial-audit.backend.utils.js";
22
22
  import { isOwnScopeRootResource } from "../../../security/authorizations/scope-root-collection-confinement.backend.js";
23
23
  let AuthorizationsBackendService = class AuthorizationsBackendService {
@@ -352,10 +352,16 @@ let AuthorizationsBackendService = class AuthorizationsBackendService {
352
352
  *
353
353
  * Read from the OPERATION rather than inferred from the context, so the public carve-out above
354
354
  * cannot be satisfied by the caller's side of the request alone.
355
+ *
356
+ * Delegates to {@link requiredRolesDeclarePublicAccess}, the ONE named source for what
357
+ * `APP_PUBLIC` means. This used to be a private re-derivation of the same two-line test, and it
358
+ * was one of FOUR such copies (this one, the authentication tier's `operationAdmitsPublicAccess`,
359
+ * and the two role gates that did not have one and therefore refused credentialed callers). A
360
+ * policy expressed as a module-private constant reaches exactly the sites that already agree with
361
+ * it — see `.claude/rules/invariant-call-site-enumeration.md` #13.
355
362
  */
356
363
  operationDeclaresPublicAccess(operation) {
357
- const roles = operation.roles;
358
- return Array.isArray(roles) && roles.includes(CORE_APP_ROLES.APP_PUBLIC);
364
+ return requiredRolesDeclarePublicAccess(operation.roles);
359
365
  }
360
366
  async authorizeInRepositoryAndService(id_or_ids, operation, executionContext) {
361
367
  const { resourceIdentifier, operationIdentifier, variantType, resourcePrimaryScope, roles: operationRoles } = operation;
@@ -391,11 +397,22 @@ let AuthorizationsBackendService = class AuthorizationsBackendService {
391
397
  * does not declare `APP_PUBLIC` cannot reach here, because `ExecutionContextCreator` only mints a
392
398
  * public context for an operation that does.
393
399
  *
394
- * BOTH conditions are required on purpose. Keying on the context alone would let any future
395
- * public-context path reach a non-public operation; keying on the operation alone would admit a
400
+ * BOTH conditions are required on purpose, and the reason has NARROWED since this was written.
401
+ * Keying on the context alone would let any future public-context path reach a non-public
402
+ * operation — that half is unchanged and is the security-relevant one.
403
+ *
404
+ * The other half used to be argued as "keying on the operation alone would admit a
396
405
  * credentialed-but-unauthorized caller to a public operation's addressed form without their roles
397
- * being examined. Together they say exactly one thing: nobody claimed an identity, and none was
398
- * required.
406
+ * being examined". That framing is retired (#153): a credentialed caller IS now admitted to a
407
+ * publicly-declared operation — `validateOperationRoles` treats `APP_PUBLIC` as imposing no
408
+ * positive role requirement, because a declaration that reduced access for presenting a valid
409
+ * credential was the defect, not the design.
410
+ *
411
+ * What the `isPublicExecution()` half still buys is that the credentialed caller takes the FULL
412
+ * path rather than this shortcut: their row pre-fetch runs, their FK-path and parent-scope gates
413
+ * run, and their roles are examined and found to require nothing. This carve-out remains what it
414
+ * says — nobody claimed an identity, and none was required — and is not the mechanism by which an
415
+ * authenticated caller reaches a public operation.
399
416
  */
400
417
  if (executionContext.isPublicExecution() && this.operationDeclaresPublicAccess(operation)) {
401
418
  this.logDebug('Public execution of a publicly-declared operation — no principal to authorize; '
@@ -544,7 +561,49 @@ let AuthorizationsBackendService = class AuthorizationsBackendService {
544
561
  resourceObjects = (idsArray.length === 1) ? [obj_s] : obj_s;
545
562
  }
546
563
  catch (error) {
547
- const authError = this.errorBuilder.buildError(ErrorType.NOT_FOUND, executionContext, {
564
+ /**
565
+ * "No rows" and "could not look" are DIFFERENT ANSWERS, and this catch used to
566
+ * destroy the difference.
567
+ *
568
+ * It classified every failure of the authorization pre-fetch as `NOT_FOUND`, so an
569
+ * infrastructure fault reached the client as a missing row. Measured on the dogfood
570
+ * stack 2026-09-01: **78 of 78** recent 404s carried
571
+ * `authorizations_validation_failed`, and NOT ONE of them was an absent record —
572
+ * every one was `introspection_derivation_failed`, the introspection repository
573
+ * refusing because the target application had not been built. That producer takes
574
+ * explicit care to distinguish the two ("This is reported rather than returned as an
575
+ * empty result, because 'no rows' and 'could not look' are different answers") and
576
+ * the distinction died here, four frames later.
577
+ *
578
+ * The cost is not cosmetic. It sends every reader to the database for a fault that is
579
+ * in the build; it reports a SERVER fault as a CLIENT error, so a 4xx/5xx alert split
580
+ * cannot see it; and it makes a broken deployment indistinguishable from an empty one.
581
+ *
582
+ * ## Why re-classifying here is safe for the existence oracle
583
+ *
584
+ * The anti-enumeration refusals are ELSEWHERE and are untouched: a row that is absent
585
+ * OR invisible is caught by the `resourceObjects.length !== idsArray.length` check
586
+ * below, which answers `NOT_FOUND` with this same message reference on purpose.
587
+ * Genuine absence never reaches THIS catch — it arrives as a successful read returning
588
+ * fewer rows, not as a throw.
589
+ *
590
+ * So this block only ever sees a fetch that FAILED, and a failure that is independent
591
+ * of the id (a broken build, a dead connection, a missing operation key) reveals
592
+ * nothing about any particular row. A cause that IS `NOT_FOUND` still answers
593
+ * `NOT_FOUND`, unchanged, so the repository's own filtered-out refusal keeps its
594
+ * indistinguishability.
595
+ *
596
+ * The `customMessageReference` is deliberately the SAME in every branch: the sibling
597
+ * refusal at `buildSubjectNotResolvableError` notes that a different reference would
598
+ * restore the oracle one field lower down, and that reasoning binds here too.
599
+ */
600
+ const causeErrorType = isWildoBackendError(error) ? error.type : undefined;
601
+ const fetchFailureErrorType = causeErrorType === undefined
602
+ // Not one of ours — a driver error, a TypeError. A server fault by definition, and
603
+ // the one case where the old behavior was least defensible.
604
+ ? ErrorType.INTERNAL
605
+ : causeErrorType;
606
+ const authError = this.errorBuilder.buildError(fetchFailureErrorType, executionContext, {
548
607
  customMessageReference: ErrorCustomMessageReference.AUTHORIZATIONS_VALIDATION_FAILED,
549
608
  context: {
550
609
  message: `Failed to fetch resource objects for authorization: ${describeCaughtError(error)}`,
@@ -1074,10 +1133,65 @@ let AuthorizationsBackendService = class AuthorizationsBackendService {
1074
1133
  }
1075
1134
  }
1076
1135
  }
1136
+ /**
1137
+ * Does this resource DERIVE tenant-anchorless rows rather than store rows under the application?
1138
+ *
1139
+ * An INTROSPECTION resource declaring {@link IntrospectionTenancyStance.APPLICATION_STRUCTURE} or
1140
+ * {@link IntrospectionTenancyStance.APPLICATION_RUNTIME} has no per-row application anchor, and
1141
+ * that is its contract rather than an omission: its rows are DERIVED per read (from a companion
1142
+ * behavior over the application's source, or from the companion's own runtime services), there is
1143
+ * no store to hold a foreign key, and both stances say outright that there is no tenant dimension
1144
+ * for a scope predicate to filter on. What separates the two stances is the READ POSTURE
1145
+ * (structure may be `APP_PUBLIC`; runtime must be role-gated), which is the operation variants'
1146
+ * job and ran before this method — not the anchor question answered here.
1147
+ *
1148
+ * Fails CLOSED in both directions that matter. With no registry bound the answer is `false`, so
1149
+ * the anchor check below still runs; and the stance must be one of the two enumerated anchorless
1150
+ * members, so an introspection resource that projects anything else — including a future scoped
1151
+ * stance — keeps the check.
1152
+ */
1153
+ projectsAnchorlessIntrospection(resourceIdentifier) {
1154
+ const configuration = this.resourcesRegistry?.tryGetResourceConfiguration(resourceIdentifier);
1155
+ const tenancy = configuration?.introspectionBinding?.tenancy;
1156
+ return configuration?.persistenceAdapter === PersistenceAdapter.INTROSPECTION
1157
+ && (tenancy === IntrospectionTenancyStance.APPLICATION_STRUCTURE
1158
+ || tenancy === IntrospectionTenancyStance.APPLICATION_RUNTIME);
1159
+ }
1077
1160
  /**
1078
1161
  * Authorize APPLICATION scope
1162
+ *
1163
+ * ## What the per-row anchor check does, and what it cannot do
1164
+ *
1165
+ * The application is a SINGLETON per database — `ExecutionContextCreator.getApplicationId()` reads
1166
+ * the APPLICATION row with an empty filter, on the stated grounds that "there is one APPLICATION
1167
+ * row, so nothing can usefully narrow this read". So `appIdFromResource !== applicationId` cannot
1168
+ * discriminate between applications within a database: both sides resolve to the same row. It is a
1169
+ * consistency assertion about correctly-populated rows, not a cross-application isolation control.
1170
+ *
1171
+ * The `!appIdFromResource` branch is the one with teeth, and for a STORED resource it is right —
1172
+ * every `APPLICATION`-anchored resource in the engine declares
1173
+ * `parentFieldIdentifier: coreResourceShared_FieldIdentifier[CoreResourceType.APPLICATION]`, so its
1174
+ * rows carry the FK and a row without one is malformed.
1175
+ *
1176
+ * A projection cannot satisfy it at all, which is why the stance is consulted first. Measured
1177
+ * before the carve-out existed: an addressed READ on `workbenchApplicationModules` answered 200 to
1178
+ * an anonymous caller (the public-execution path returns before this method) and 403 to an
1179
+ * authenticated one, while LIST answered 200 to both (collection operations run no row check). The
1180
+ * resource could not be fixed from the application side without inventing a field its schema does
1181
+ * not declare.
1079
1182
  */
1080
1183
  async authorizeApplication(resourceObject, resourceIdentifier, initiatorIds, executionContext) {
1184
+ /*
1185
+ * Read as: this resource's rows ARE the application, so there is no row-level membership left to
1186
+ * check. Deliberately NOT an opt-out flag an operation can declare — a stored resource that
1187
+ * simply forgot its FK must keep failing, and only a declared tenancy stance can tell the two
1188
+ * apart. Nothing else is relaxed: the operation's `roles` gate ran before this, and the
1189
+ * repository's contextual filter runs underneath.
1190
+ */
1191
+ if (this.projectsAnchorlessIntrospection(resourceIdentifier)) {
1192
+ this.logDebug('Anchorless introspection projection — no per-row anchor to authorize', { resourceIdentifier });
1193
+ return;
1194
+ }
1081
1195
  if (resourceIdentifier === CoreResourceType.APPLICATION) {
1082
1196
  // For application resources, check that the resource _id matches the initiator applicationId
1083
1197
  if (resourceObject._id !== initiatorIds.applicationId) {
@@ -1130,6 +1244,29 @@ let AuthorizationsBackendService = class AuthorizationsBackendService {
1130
1244
  */
1131
1245
  narrowableResourceIdentifier) {
1132
1246
  const { initiatorRoles } = executionContext;
1247
+ /*
1248
+ * A PUBLICLY-DECLARED operation imposes no positive role requirement — on ANY caller.
1249
+ *
1250
+ * This is the ROLE half of `APP_PUBLIC`, and it is separate from the public-EXECUTION carve-out
1251
+ * at the top of `authorizeInRepositoryAndService`. That one answers "there is no principal to
1252
+ * authorize"; this one answers "there is a principal, and the operation asks nothing of them".
1253
+ * Both are needed, and having only the first is what produced the defect this closes: an
1254
+ * anonymous probe was admitted by the carve-out while the SAME request carrying a valid token
1255
+ * fell through to here and was refused, because `APP_PUBLIC` is in nobody's granted role set.
1256
+ *
1257
+ * Placed BEFORE the org-wide grant computation deliberately. A public declaration is a statement
1258
+ * about the OPERATION, so it cannot depend on which grants the caller happens to hold, on the
1259
+ * scope those grants resolve against, or on whether a unit-narrowing stamp exists — every one of
1260
+ * which is an input the computation below reads and none of which can change the answer.
1261
+ *
1262
+ * It relaxes the ROLE question only. `validateParentScopeAccess`, `validateFKRelationshipAccess`
1263
+ * and the repository's contextual filter all still run, so a public declaration never widens
1264
+ * WHICH ROWS a caller reaches — only whether they may ask.
1265
+ */
1266
+ if (requiredRolesDeclarePublicAccess(operationRoles)) {
1267
+ this.logDebug('Operation declares APP_PUBLIC — no positive role requirement for any caller', { operationRoles });
1268
+ return;
1269
+ }
1133
1270
  // ORGANIZATION-WIDE GRANTS ONLY in this computation. A unit-scoped entry (`organizationUnitId`
1134
1271
  // present) confers authority inside ONE organization unit, so it must not satisfy an operation
1135
1272
  // gate that asks an organization-wide question — otherwise "ORG_MANAGER of Sales" would pass every
@@ -1313,6 +1450,32 @@ let AuthorizationsBackendService = class AuthorizationsBackendService {
1313
1450
  * - id_or_ids must be a valid string or array
1314
1451
  * - Authorization additionally verifies access to the specific resource(s)
1315
1452
  */
1453
+ /**
1454
+ * Authorize an operation on ROLES ALONE, with no row to fetch.
1455
+ *
1456
+ * ## Why this exists, and why it is deliberately narrow
1457
+ *
1458
+ * Every other entry point here authorizes an operation against ROWS — it pre-fetches them, checks
1459
+ * scope, checks FK reachability, then checks roles. That is right whenever there is a row.
1460
+ *
1461
+ * A WebSocket SCOPE subscription has none. It says "tell me when anything of this type changes
1462
+ * under this scope", which addresses no instance, so the row-shaped questions have no subject and
1463
+ * only the role question remains. Passing a scope id in the row's place is the trap this avoids:
1464
+ * it would authorize a READ of a row of the subscribed type whose id happens to be an application
1465
+ * id, which is not a question anyone asked and which fails for the wrong reason.
1466
+ *
1467
+ * **This is strictly WEAKER than `authorizeInController` and must never be substituted for it on a
1468
+ * path that has an id.** It answers "may this principal invoke this operation at all", not "may
1469
+ * this principal reach this row". Its only caller is the scope-subscription gate, where the
1470
+ * notification it admits carries row identities the caller could have listed anyway.
1471
+ *
1472
+ * Unit narrowing still applies: `resourceIdentifier` is forwarded, so a unit-scoped grant can
1473
+ * rescue a failing role check exactly as it does everywhere else.
1474
+ */
1475
+ async authorizeOperationRolesOnly(operation, executionContext) {
1476
+ const { roles: operationRoles, resourceIdentifier } = operation;
1477
+ await this.validateOperationRoles(operationRoles, executionContext, resourceIdentifier);
1478
+ }
1316
1479
  async authorizeInController(id_or_ids, executionContext) {
1317
1480
  // Extract operation from execution context
1318
1481
  const operation = executionContext.operation;
@@ -1498,11 +1661,24 @@ let AuthorizationsBackendService = class AuthorizationsBackendService {
1498
1661
  * This prevents users from accessing resources assigned to or created by other users
1499
1662
  * by manipulating the URL path.
1500
1663
  *
1501
- * Authorization behavior by execution type:
1502
- * - USER_REQUEST: Must match the authenticated user's ID
1503
- * - API_KEY: Allowed - API keys have broader access within their scope
1504
- * - INTERNAL: Allowed - internal operations bypass FK validation
1505
- * - PUBLIC: Allowed - public operations don't have identity context
1664
+ * The gate is on IDENTITY, not on execution type (issue #321). A context is admitted on a user-FK
1665
+ * path when it carries a `userId` AND that id equals the one in the path — whatever established the
1666
+ * identity. Two execution types carry a `userId`:
1667
+ * - USER_REQUEST — the session's own user;
1668
+ * - CONSUMABLE_TOKEN — the `userId` the token was MINTED for (`createExecutionContextFromRequest`
1669
+ * copies `consumableTokenObject.userId` onto `initiatorIds`). It is server-minted, so a bearer can
1670
+ * only act as that subject on that path — the same trust a session confers.
1671
+ * Machine principals, INTERNAL, PUBLIC, WEBHOOK and ANONYMOUS_SESSION never reach the gate: the
1672
+ * early return below skips FK matching for them entirely (machine principals have broader access
1673
+ * within their scope; the others carry no person to match). So the identity gate is evaluated for
1674
+ * exactly two execution types — USER_REQUEST and CONSUMABLE_TOKEN — and a context of either kind
1675
+ * WITHOUT a `userId` is refused: a user-FK path names a person, and a caller with no person cannot
1676
+ * be that person.
1677
+ *
1678
+ * History: after the early return, this used to refuse every non-USER_REQUEST type — which, given
1679
+ * that return, meant exactly CONSUMABLE_TOKEN — on the stated premise that "only USER_REQUEST has a
1680
+ * userId". The premise was false when written (the token bridge already set it); the effect was
1681
+ * that no token could act on a user-FK path even for the very user it was minted for.
1506
1682
  */
1507
1683
  async validateFKRelationshipAccess(executionContext) {
1508
1684
  const { relationshipContexts, initiatorIds, executionType } = executionContext;
@@ -1538,21 +1714,9 @@ let AuthorizationsBackendService = class AuthorizationsBackendService {
1538
1714
  }
1539
1715
  // Validate based on the target resource type
1540
1716
  if (resourceType === CoreResourceType.USERS || resourceType === CoreResourceType.USER_SELF) {
1541
- // User FK paths require the authenticated user to match the URL userId
1542
- // Only USER_REQUEST type has userId in initiatorIds
1543
- if (executionType !== ExecutionContext_ExecutionType.USER_REQUEST) {
1544
- // Consumable tokens cannot access user FK paths
1545
- throw this.errorBuilder.buildError(ErrorType.AUTHORIZATION, executionContext, {
1546
- customMessageReference: ErrorCustomMessageReference.AUTHORIZATIONS_ACCESS_DENIED,
1547
- context: {
1548
- // diagnostic (log-only)
1549
- relationshipField,
1550
- resourceIdInUrl: resourceId,
1551
- executionType
1552
- }
1553
- });
1554
- }
1555
- // User must be authenticated
1717
+ // A user-FK path names a person. Admission requires a `userId` on the context (USER_REQUEST
1718
+ // session or CONSUMABLE_TOKEN minted for that user) that EQUALS the one in the path. There is
1719
+ // deliberately no execution-type branch here — see the method JSDoc (issue #321).
1556
1720
  if (!initiatorIds?.userId) {
1557
1721
  throw this.errorBuilder.buildError(ErrorType.AUTHORIZATION, executionContext, {
1558
1722
  customMessageReference: ErrorCustomMessageReference.AUTHORIZATIONS_ACCESS_DENIED,
@@ -1805,9 +1969,25 @@ let AuthorizationsBackendService = class AuthorizationsBackendService {
1805
1969
  * Validate that user's roles satisfy the required operation roles
1806
1970
  * Considers role hierarchy within the given scope
1807
1971
  *
1808
- * @returns true if user has at least one of the required roles
1972
+ * The SECOND role gate in this class, and the reason the `APP_PUBLIC` admission below is repeated
1973
+ * rather than inherited: an ORGANIZATIONS-scoped operation resolves its roles HERE, inside
1974
+ * `validateParentScopeAccess`, and never reaches {@link validateOperationRoles} —
1975
+ * `authorizeCollectionOperation` skips that call for ORGANIZATIONS scope precisely because this
1976
+ * branch has already answered the question. A public declaration honoured at only one of the two
1977
+ * would mean `APP_PUBLIC` worked on APPLICATION-scoped resources and refused on organization-scoped
1978
+ * ones, which is the same defect one scope over.
1979
+ *
1980
+ * The caller has ALREADY proven tenancy by the time this runs — the ORGANIZATIONS branch resolves
1981
+ * an `orgRoleInfo` for this specific organization, and the scope-root branch confines the read
1982
+ * separately — so admitting on a public declaration here grants the right to ASK, never a wider
1983
+ * set of rows.
1984
+ *
1985
+ * @returns true if user has at least one of the required roles, or the operation declares public
1986
+ * access (in which case it requires none)
1809
1987
  */
1810
1988
  validateRolesForScope(requiredRoles, userRoles, scope) {
1989
+ if (requiredRolesDeclarePublicAccess(requiredRoles))
1990
+ return true;
1811
1991
  return requiredRoles.some(requiredRole => userRoles.some(userRole => {
1812
1992
  const hierarchy = this.getRoleHierarchy(userRole, scope);
1813
1993
  return hierarchy.includes(requiredRole);