@authup/server-core 1.0.0-beta.54 → 1.0.0-beta.56

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 (328) hide show
  1. package/dist/adapters/database/data-source/options/module.mjs.map +1 -1
  2. package/dist/adapters/database/domains/client/entity.mjs +2 -2
  3. package/dist/adapters/database/domains/client/entity.mjs.map +1 -1
  4. package/dist/adapters/database/domains/client/subscriber.mjs +2 -2
  5. package/dist/adapters/database/domains/client/subscriber.mjs.map +1 -1
  6. package/dist/adapters/database/domains/client-permission/entity.mjs +2 -2
  7. package/dist/adapters/database/domains/client-permission/entity.mjs.map +1 -1
  8. package/dist/adapters/database/domains/client-permission/subscriber.mjs +2 -2
  9. package/dist/adapters/database/domains/client-permission/subscriber.mjs.map +1 -1
  10. package/dist/adapters/database/domains/client-role/entity.mjs +2 -2
  11. package/dist/adapters/database/domains/client-role/entity.mjs.map +1 -1
  12. package/dist/adapters/database/domains/client-role/subscriber.mjs +2 -2
  13. package/dist/adapters/database/domains/client-role/subscriber.mjs.map +1 -1
  14. package/dist/adapters/database/domains/client-scope/entity.mjs +2 -2
  15. package/dist/adapters/database/domains/client-scope/entity.mjs.map +1 -1
  16. package/dist/adapters/database/domains/client-scope/subscriber.mjs +2 -2
  17. package/dist/adapters/database/domains/client-scope/subscriber.mjs.map +1 -1
  18. package/dist/adapters/database/domains/consent/entity.mjs +2 -2
  19. package/dist/adapters/database/domains/consent/entity.mjs.map +1 -1
  20. package/dist/adapters/database/domains/consent/subscriber.mjs +2 -2
  21. package/dist/adapters/database/domains/consent/subscriber.mjs.map +1 -1
  22. package/dist/adapters/database/domains/constants.mjs.map +1 -1
  23. package/dist/adapters/database/domains/event/entity.mjs +2 -2
  24. package/dist/adapters/database/domains/event/entity.mjs.map +1 -1
  25. package/dist/adapters/database/domains/identity-provider/entity.mjs +2 -2
  26. package/dist/adapters/database/domains/identity-provider/entity.mjs.map +1 -1
  27. package/dist/adapters/database/domains/identity-provider/subscriber.mjs +2 -2
  28. package/dist/adapters/database/domains/identity-provider/subscriber.mjs.map +1 -1
  29. package/dist/adapters/database/domains/identity-provider-account/entity.mjs +2 -2
  30. package/dist/adapters/database/domains/identity-provider-account/entity.mjs.map +1 -1
  31. package/dist/adapters/database/domains/identity-provider-account/subscriber.mjs +2 -2
  32. package/dist/adapters/database/domains/identity-provider-account/subscriber.mjs.map +1 -1
  33. package/dist/adapters/database/domains/identity-provider-attribute/entity.mjs +2 -2
  34. package/dist/adapters/database/domains/identity-provider-attribute/entity.mjs.map +1 -1
  35. package/dist/adapters/database/domains/identity-provider-attribute/subscriber.mjs +2 -2
  36. package/dist/adapters/database/domains/identity-provider-attribute/subscriber.mjs.map +1 -1
  37. package/dist/adapters/database/domains/identity-provider-attribute-mapping/entity.mjs +2 -2
  38. package/dist/adapters/database/domains/identity-provider-attribute-mapping/entity.mjs.map +1 -1
  39. package/dist/adapters/database/domains/identity-provider-permission-mapping/entity.mjs +2 -2
  40. package/dist/adapters/database/domains/identity-provider-permission-mapping/entity.mjs.map +1 -1
  41. package/dist/adapters/database/domains/identity-provider-role-mapping/entity.mjs +2 -2
  42. package/dist/adapters/database/domains/identity-provider-role-mapping/entity.mjs.map +1 -1
  43. package/dist/adapters/database/domains/identity-provider-role-mapping/subscriber.mjs +2 -2
  44. package/dist/adapters/database/domains/identity-provider-role-mapping/subscriber.mjs.map +1 -1
  45. package/dist/adapters/database/domains/key/entity.mjs +2 -2
  46. package/dist/adapters/database/domains/key/entity.mjs.map +1 -1
  47. package/dist/adapters/database/domains/permission/entity.mjs +2 -2
  48. package/dist/adapters/database/domains/permission/entity.mjs.map +1 -1
  49. package/dist/adapters/database/domains/permission/subscriber.mjs +2 -2
  50. package/dist/adapters/database/domains/permission/subscriber.mjs.map +1 -1
  51. package/dist/adapters/database/domains/permission-policy/entity.mjs +2 -2
  52. package/dist/adapters/database/domains/permission-policy/entity.mjs.map +1 -1
  53. package/dist/adapters/database/domains/policy/entity.mjs +2 -2
  54. package/dist/adapters/database/domains/policy/entity.mjs.map +1 -1
  55. package/dist/adapters/database/domains/policy/subscriber.mjs +2 -2
  56. package/dist/adapters/database/domains/policy/subscriber.mjs.map +1 -1
  57. package/dist/adapters/database/domains/policy-attribute/entity.mjs +2 -2
  58. package/dist/adapters/database/domains/policy-attribute/entity.mjs.map +1 -1
  59. package/dist/adapters/database/domains/policy-attribute/subscriber.mjs +2 -2
  60. package/dist/adapters/database/domains/policy-attribute/subscriber.mjs.map +1 -1
  61. package/dist/adapters/database/domains/realm/entity.mjs +2 -2
  62. package/dist/adapters/database/domains/realm/entity.mjs.map +1 -1
  63. package/dist/adapters/database/domains/realm/subscriber.mjs +2 -2
  64. package/dist/adapters/database/domains/realm/subscriber.mjs.map +1 -1
  65. package/dist/adapters/database/domains/role/entity.mjs +2 -2
  66. package/dist/adapters/database/domains/role/entity.mjs.map +1 -1
  67. package/dist/adapters/database/domains/role/subscriber.mjs +2 -2
  68. package/dist/adapters/database/domains/role/subscriber.mjs.map +1 -1
  69. package/dist/adapters/database/domains/role-attribute/entity.mjs +2 -2
  70. package/dist/adapters/database/domains/role-attribute/entity.mjs.map +1 -1
  71. package/dist/adapters/database/domains/role-attribute/subscriber.mjs +2 -2
  72. package/dist/adapters/database/domains/role-attribute/subscriber.mjs.map +1 -1
  73. package/dist/adapters/database/domains/role-permission/entity.mjs +2 -2
  74. package/dist/adapters/database/domains/role-permission/entity.mjs.map +1 -1
  75. package/dist/adapters/database/domains/role-permission/subscriber.mjs +2 -2
  76. package/dist/adapters/database/domains/role-permission/subscriber.mjs.map +1 -1
  77. package/dist/adapters/database/domains/scope/entity.mjs +2 -2
  78. package/dist/adapters/database/domains/scope/entity.mjs.map +1 -1
  79. package/dist/adapters/database/domains/scope/subscriber.mjs +2 -2
  80. package/dist/adapters/database/domains/scope/subscriber.mjs.map +1 -1
  81. package/dist/adapters/database/domains/session/entity.mjs +2 -2
  82. package/dist/adapters/database/domains/session/entity.mjs.map +1 -1
  83. package/dist/adapters/database/domains/session-token/entity.mjs +2 -2
  84. package/dist/adapters/database/domains/session-token/entity.mjs.map +1 -1
  85. package/dist/adapters/database/domains/trust-anchor/entity.mjs +2 -2
  86. package/dist/adapters/database/domains/trust-anchor/entity.mjs.map +1 -1
  87. package/dist/adapters/database/domains/user/entity.mjs +2 -2
  88. package/dist/adapters/database/domains/user/entity.mjs.map +1 -1
  89. package/dist/adapters/database/domains/user/subscriber.mjs +2 -2
  90. package/dist/adapters/database/domains/user/subscriber.mjs.map +1 -1
  91. package/dist/adapters/database/domains/user-attribute/entity.mjs +2 -2
  92. package/dist/adapters/database/domains/user-attribute/entity.mjs.map +1 -1
  93. package/dist/adapters/database/domains/user-attribute/subscriber.mjs +2 -2
  94. package/dist/adapters/database/domains/user-attribute/subscriber.mjs.map +1 -1
  95. package/dist/adapters/database/domains/user-authenticator/entity.mjs +2 -2
  96. package/dist/adapters/database/domains/user-authenticator/entity.mjs.map +1 -1
  97. package/dist/adapters/database/domains/user-permission/entity.mjs +2 -2
  98. package/dist/adapters/database/domains/user-permission/entity.mjs.map +1 -1
  99. package/dist/adapters/database/domains/user-permission/subscriber.mjs +2 -2
  100. package/dist/adapters/database/domains/user-permission/subscriber.mjs.map +1 -1
  101. package/dist/adapters/database/domains/user-role/entity.mjs +2 -2
  102. package/dist/adapters/database/domains/user-role/entity.mjs.map +1 -1
  103. package/dist/adapters/database/domains/user-role/subscriber.mjs +2 -2
  104. package/dist/adapters/database/domains/user-role/subscriber.mjs.map +1 -1
  105. package/dist/adapters/database/errors/driver.mjs.map +1 -1
  106. package/dist/adapters/database/extra-attribute-repository/adapter.mjs.map +1 -1
  107. package/dist/adapters/database/extra-attribute-repository/tree/adapter.mjs.map +1 -1
  108. package/dist/adapters/database/extra-attribute-repository/tree/repository.mjs.map +1 -1
  109. package/dist/adapters/database/migrations/mysql/1779267068441-Default.mjs.map +1 -1
  110. package/dist/adapters/database/migrations/mysql/1779300000000-Default.mjs.map +1 -1
  111. package/dist/adapters/database/migrations/mysql/1784289540000-CamelCaseAttributes.mjs.map +1 -1
  112. package/dist/adapters/database/migrations/postgres/1779267068441-Default.mjs.map +1 -1
  113. package/dist/adapters/database/migrations/postgres/1779300000000-Default.mjs.map +1 -1
  114. package/dist/adapters/database/migrations/postgres/1784289540000-CamelCaseAttributes.mjs.map +1 -1
  115. package/dist/adapters/database/subscriber/module.mjs.map +1 -1
  116. package/dist/adapters/http/adapters/oauth2/authorization/module.mjs.map +1 -1
  117. package/dist/adapters/http/adapters/oauth2/grant-types/utils/realm.mjs.map +1 -1
  118. package/dist/adapters/http/controllers/entities/client/module.mjs +2 -2
  119. package/dist/adapters/http/controllers/entities/client/module.mjs.map +1 -1
  120. package/dist/adapters/http/controllers/entities/client-permission/module.mjs +2 -2
  121. package/dist/adapters/http/controllers/entities/client-permission/module.mjs.map +1 -1
  122. package/dist/adapters/http/controllers/entities/client-role/module.mjs +2 -2
  123. package/dist/adapters/http/controllers/entities/client-role/module.mjs.map +1 -1
  124. package/dist/adapters/http/controllers/entities/client-scope/module.mjs +2 -2
  125. package/dist/adapters/http/controllers/entities/client-scope/module.mjs.map +1 -1
  126. package/dist/adapters/http/controllers/entities/consent/module.mjs +2 -2
  127. package/dist/adapters/http/controllers/entities/consent/module.mjs.map +1 -1
  128. package/dist/adapters/http/controllers/entities/event/module.mjs +2 -2
  129. package/dist/adapters/http/controllers/entities/event/module.mjs.map +1 -1
  130. package/dist/adapters/http/controllers/entities/identity-provide-role/module.mjs +2 -2
  131. package/dist/adapters/http/controllers/entities/identity-provide-role/module.mjs.map +1 -1
  132. package/dist/adapters/http/controllers/entities/identity-provider/module.mjs +2 -2
  133. package/dist/adapters/http/controllers/entities/identity-provider/module.mjs.map +1 -1
  134. package/dist/adapters/http/controllers/entities/key/module.mjs +2 -2
  135. package/dist/adapters/http/controllers/entities/key/module.mjs.map +1 -1
  136. package/dist/adapters/http/controllers/entities/permission/module.mjs +2 -2
  137. package/dist/adapters/http/controllers/entities/permission/module.mjs.map +1 -1
  138. package/dist/adapters/http/controllers/entities/permission-policy/module.mjs +2 -2
  139. package/dist/adapters/http/controllers/entities/permission-policy/module.mjs.map +1 -1
  140. package/dist/adapters/http/controllers/entities/policy/module.mjs +2 -2
  141. package/dist/adapters/http/controllers/entities/policy/module.mjs.map +1 -1
  142. package/dist/adapters/http/controllers/entities/realm/module.mjs +2 -2
  143. package/dist/adapters/http/controllers/entities/realm/module.mjs.map +1 -1
  144. package/dist/adapters/http/controllers/entities/role/module.mjs +2 -2
  145. package/dist/adapters/http/controllers/entities/role/module.mjs.map +1 -1
  146. package/dist/adapters/http/controllers/entities/role-attribute/module.mjs +2 -2
  147. package/dist/adapters/http/controllers/entities/role-attribute/module.mjs.map +1 -1
  148. package/dist/adapters/http/controllers/entities/role-permission/module.mjs +2 -2
  149. package/dist/adapters/http/controllers/entities/role-permission/module.mjs.map +1 -1
  150. package/dist/adapters/http/controllers/entities/scope/module.mjs +2 -2
  151. package/dist/adapters/http/controllers/entities/scope/module.mjs.map +1 -1
  152. package/dist/adapters/http/controllers/entities/session/module.mjs +2 -2
  153. package/dist/adapters/http/controllers/entities/session/module.mjs.map +1 -1
  154. package/dist/adapters/http/controllers/entities/trust-anchor/module.mjs +2 -2
  155. package/dist/adapters/http/controllers/entities/trust-anchor/module.mjs.map +1 -1
  156. package/dist/adapters/http/controllers/entities/user/module.mjs +2 -2
  157. package/dist/adapters/http/controllers/entities/user/module.mjs.map +1 -1
  158. package/dist/adapters/http/controllers/entities/user-attribute/module.mjs +2 -2
  159. package/dist/adapters/http/controllers/entities/user-attribute/module.mjs.map +1 -1
  160. package/dist/adapters/http/controllers/entities/user-authenticator/module.mjs +2 -2
  161. package/dist/adapters/http/controllers/entities/user-authenticator/module.mjs.map +1 -1
  162. package/dist/adapters/http/controllers/entities/user-permission/module.mjs +2 -2
  163. package/dist/adapters/http/controllers/entities/user-permission/module.mjs.map +1 -1
  164. package/dist/adapters/http/controllers/entities/user-role/module.mjs +2 -2
  165. package/dist/adapters/http/controllers/entities/user-role/module.mjs.map +1 -1
  166. package/dist/adapters/http/controllers/workflows/activate/module.mjs +2 -2
  167. package/dist/adapters/http/controllers/workflows/authenticator-challenge/module.mjs +2 -2
  168. package/dist/adapters/http/controllers/workflows/authorize/module.mjs +2 -2
  169. package/dist/adapters/http/controllers/workflows/authorize/module.mjs.map +1 -1
  170. package/dist/adapters/http/controllers/workflows/jwks/handlers/read.mjs.map +1 -1
  171. package/dist/adapters/http/controllers/workflows/jwks/module.mjs +2 -2
  172. package/dist/adapters/http/controllers/workflows/jwks/module.mjs.map +1 -1
  173. package/dist/adapters/http/controllers/workflows/logout/module.mjs +2 -2
  174. package/dist/adapters/http/controllers/workflows/logout/module.mjs.map +1 -1
  175. package/dist/adapters/http/controllers/workflows/openid/module.mjs +2 -2
  176. package/dist/adapters/http/controllers/workflows/password-forgot/module.mjs +2 -2
  177. package/dist/adapters/http/controllers/workflows/password-reset/module.mjs +2 -2
  178. package/dist/adapters/http/controllers/workflows/register/module.mjs +2 -2
  179. package/dist/adapters/http/controllers/workflows/status/module.mjs +2 -2
  180. package/dist/adapters/http/controllers/workflows/token/module.mjs +2 -2
  181. package/dist/adapters/http/controllers/workflows/token/utils/extract.mjs.map +1 -1
  182. package/dist/adapters/http/middleware/built-in/authorization/module.mjs.map +1 -1
  183. package/dist/adapters/http/middleware/built-in/cors.mjs.map +1 -1
  184. package/dist/adapters/http/middleware/built-in/logger.mjs.map +1 -1
  185. package/dist/adapters/http/request/constants.mjs.map +1 -1
  186. package/dist/adapters/http/request/helpers/param-id.mjs.map +1 -1
  187. package/dist/adapters/http/request/helpers/redirect.mjs.map +1 -1
  188. package/dist/app/factory.mjs.map +1 -1
  189. package/dist/app/modules/authentication/module.mjs.map +1 -1
  190. package/dist/app/modules/authentication/repositories/constants.mjs.map +1 -1
  191. package/dist/app/modules/authentication/repositories/session.mjs.map +1 -1
  192. package/dist/app/modules/cache/module.mjs.map +1 -1
  193. package/dist/app/modules/components/module.mjs.map +1 -1
  194. package/dist/app/modules/config/constants.mjs.map +1 -1
  195. package/dist/app/modules/config/origins.mjs.map +1 -1
  196. package/dist/app/modules/config/read/env.mjs.map +1 -1
  197. package/dist/app/modules/config/read/fs.mjs.map +1 -1
  198. package/dist/app/modules/config/validator.mjs.map +1 -1
  199. package/dist/app/modules/database/module.mjs.map +1 -1
  200. package/dist/app/modules/database/repositories/bindings.mjs.map +1 -1
  201. package/dist/app/modules/database/repositories/client/repository.mjs.map +1 -1
  202. package/dist/app/modules/database/repositories/event/repository.mjs.map +1 -1
  203. package/dist/app/modules/database/repositories/helpers.mjs.map +1 -1
  204. package/dist/app/modules/database/repositories/permission-provider/module.mjs.map +1 -1
  205. package/dist/app/modules/database/repositories/user/repository.mjs.map +1 -1
  206. package/dist/app/modules/database/repositories/user-attribute/repository.mjs.map +1 -1
  207. package/dist/app/modules/database/repositories/user-authenticator/repository.mjs.map +1 -1
  208. package/dist/app/modules/http/module.mjs.map +1 -1
  209. package/dist/app/modules/http/modules/controller.mjs.map +1 -1
  210. package/dist/app/modules/identity/module.mjs.map +1 -1
  211. package/dist/app/modules/logger/module.mjs.map +1 -1
  212. package/dist/app/modules/mail/module.mjs.map +1 -1
  213. package/dist/app/modules/metrics/prom.mjs.map +1 -1
  214. package/dist/app/modules/oauth2/module.mjs.map +1 -1
  215. package/dist/app/modules/oauth2/repositories/consent/repository.mjs.map +1 -1
  216. package/dist/app/modules/oauth2/repositories/constants.mjs.map +1 -1
  217. package/dist/app/modules/provisioning/module.mjs.map +1 -1
  218. package/dist/app/modules/provisioning/sources/composite/module.mjs.map +1 -1
  219. package/dist/app/modules/provisioning/sources/default/module.mjs.map +1 -1
  220. package/dist/app/modules/provisioning/sources/file/module.mjs.map +1 -1
  221. package/dist/app/modules/runtime/module.mjs.map +1 -1
  222. package/dist/cli/commands/migration.mjs.map +1 -1
  223. package/dist/components/database/unique-entries/module.mjs.map +1 -1
  224. package/dist/core/authentication/entities/client/module.mjs.map +1 -1
  225. package/dist/core/authentication/session/module.mjs.map +1 -1
  226. package/dist/core/authentication/session/types.mjs.map +1 -1
  227. package/dist/core/client-certificate/module.mjs.map +1 -1
  228. package/dist/core/entities/client/schema.mjs.map +1 -1
  229. package/dist/core/entities/client/service.mjs.map +1 -1
  230. package/dist/core/entities/client-permission/schema.mjs.map +1 -1
  231. package/dist/core/entities/client-permission/service.mjs.map +1 -1
  232. package/dist/core/entities/client-role/schema.mjs.map +1 -1
  233. package/dist/core/entities/client-role/service.mjs.map +1 -1
  234. package/dist/core/entities/client-scope/schema.mjs.map +1 -1
  235. package/dist/core/entities/client-scope/service.mjs.map +1 -1
  236. package/dist/core/entities/consent/schema.mjs.map +1 -1
  237. package/dist/core/entities/consent/types.mjs.map +1 -1
  238. package/dist/core/entities/event/diff.mjs.map +1 -1
  239. package/dist/core/entities/event/sanitize.mjs.map +1 -1
  240. package/dist/core/entities/event/schema.mjs.map +1 -1
  241. package/dist/core/entities/event/service.mjs.map +1 -1
  242. package/dist/core/entities/identity-provider/schema.mjs.map +1 -1
  243. package/dist/core/entities/identity-provider-role-mapping/schema.mjs.map +1 -1
  244. package/dist/core/entities/identity-provider-role-mapping/service.mjs.map +1 -1
  245. package/dist/core/entities/key/schema.mjs.map +1 -1
  246. package/dist/core/entities/key/service.mjs.map +1 -1
  247. package/dist/core/entities/permission/schema.d.ts.map +1 -1
  248. package/dist/core/entities/permission/schema.mjs +12 -0
  249. package/dist/core/entities/permission/schema.mjs.map +1 -1
  250. package/dist/core/entities/permission/service.mjs.map +1 -1
  251. package/dist/core/entities/permission-policy/schema.mjs.map +1 -1
  252. package/dist/core/entities/permission-policy/service.mjs.map +1 -1
  253. package/dist/core/entities/policy/schema.mjs.map +1 -1
  254. package/dist/core/entities/policy/service.mjs.map +1 -1
  255. package/dist/core/entities/realm/schema.mjs.map +1 -1
  256. package/dist/core/entities/role/schema.mjs.map +1 -1
  257. package/dist/core/entities/role/service.mjs.map +1 -1
  258. package/dist/core/entities/role-attribute/schema.mjs.map +1 -1
  259. package/dist/core/entities/role-attribute/service.mjs.map +1 -1
  260. package/dist/core/entities/role-permission/schema.mjs.map +1 -1
  261. package/dist/core/entities/role-permission/service.mjs.map +1 -1
  262. package/dist/core/entities/scope/schema.mjs.map +1 -1
  263. package/dist/core/entities/scope/service.mjs.map +1 -1
  264. package/dist/core/entities/session/schema.mjs.map +1 -1
  265. package/dist/core/entities/session/service.mjs.map +1 -1
  266. package/dist/core/entities/trust-anchor/schema.mjs.map +1 -1
  267. package/dist/core/entities/trust-anchor/service.mjs.map +1 -1
  268. package/dist/core/entities/user/schema.mjs.map +1 -1
  269. package/dist/core/entities/user/service.mjs.map +1 -1
  270. package/dist/core/entities/user-attribute/schema.mjs.map +1 -1
  271. package/dist/core/entities/user-attribute/service.mjs.map +1 -1
  272. package/dist/core/entities/user-authenticator/schema.mjs.map +1 -1
  273. package/dist/core/entities/user-authenticator/service.mjs.map +1 -1
  274. package/dist/core/entities/user-authenticator/types.mjs.map +1 -1
  275. package/dist/core/entities/user-permission/schema.mjs.map +1 -1
  276. package/dist/core/entities/user-permission/service.mjs.map +1 -1
  277. package/dist/core/entities/user-role/schema.mjs.map +1 -1
  278. package/dist/core/entities/user-role/service.mjs.map +1 -1
  279. package/dist/core/identity/permission/junction-grant.mjs.map +1 -1
  280. package/dist/core/identity/permission/module.mjs.map +1 -1
  281. package/dist/core/identity/provider/authentication/presets/facebook.mjs.map +1 -1
  282. package/dist/core/identity/provider/authentication/presets/github.mjs.map +1 -1
  283. package/dist/core/identity/provider/authentication/presets/google.mjs.map +1 -1
  284. package/dist/core/identity/provider/authentication/presets/instagram.mjs.map +1 -1
  285. package/dist/core/identity/provider/authentication/presets/paypal.mjs.map +1 -1
  286. package/dist/core/identity/provider/authentication/protocols/ldap/module.mjs.map +1 -1
  287. package/dist/core/identity/provider/authentication/protocols/oauth2/module.mjs.map +1 -1
  288. package/dist/core/identity/provider/authentication/protocols/open-id/module.mjs.map +1 -1
  289. package/dist/core/identity/provider/constants.mjs.map +1 -1
  290. package/dist/core/identity/provider/mapper/base.mjs.map +1 -1
  291. package/dist/core/identity/provider/mapper/constants.mjs.map +1 -1
  292. package/dist/core/identity/registration/service.mjs.map +1 -1
  293. package/dist/core/key/provisioner.mjs.map +1 -1
  294. package/dist/core/key/realm-cipher.mjs.map +1 -1
  295. package/dist/core/mail/template/templates/mfa-email-otp.mjs.map +1 -1
  296. package/dist/core/mail/template/templates/password-reset.mjs.map +1 -1
  297. package/dist/core/mail/template/templates/registration-activation.mjs.map +1 -1
  298. package/dist/core/mail/template/types.mjs.map +1 -1
  299. package/dist/core/oauth2/authorization/code/verifier/module.mjs.map +1 -1
  300. package/dist/core/oauth2/authorization/code-request/verifier/module.mjs.map +1 -1
  301. package/dist/core/oauth2/authorization/module.mjs.map +1 -1
  302. package/dist/core/oauth2/end-session/service.mjs.map +1 -1
  303. package/dist/core/oauth2/grant-types/refresh-token.mjs.map +1 -1
  304. package/dist/core/oauth2/mfa-login/module.mjs.map +1 -1
  305. package/dist/core/oauth2/openid/claims.mjs.map +1 -1
  306. package/dist/core/oauth2/scope/resolver.mjs.map +1 -1
  307. package/dist/core/oauth2/token/issuer/access/module.mjs.map +1 -1
  308. package/dist/core/oauth2/token/issuer/mfa/module.mjs.map +1 -1
  309. package/dist/core/oauth2/token/issuer/open-id/module.mjs.map +1 -1
  310. package/dist/core/oauth2/token/issuer/refresh/module.mjs.map +1 -1
  311. package/dist/core/oauth2/token/verifier/module.mjs.map +1 -1
  312. package/dist/core/provisioning/entities/policy/validator.mjs.map +1 -1
  313. package/dist/core/provisioning/entities/utils.mjs.map +1 -1
  314. package/dist/core/provisioning/strategy/constants.mjs.map +1 -1
  315. package/dist/core/provisioning/strategy/validator.mjs.map +1 -1
  316. package/dist/core/provisioning/synchronizer/client/module.mjs.map +1 -1
  317. package/dist/core/provisioning/synchronizer/role/module.mjs.map +1 -1
  318. package/dist/core/provisioning/synchronizer/user/module.mjs.map +1 -1
  319. package/dist/core/query/module.mjs.map +1 -1
  320. package/dist/core/query/relations.mjs.map +1 -1
  321. package/dist/core/security/policy/evaluator.mjs.map +1 -1
  322. package/dist/ui/client/.vite/ssr-manifest.json +2 -2
  323. package/dist/ui/client/assets/{index-BmJ2X468.js → index-C05uGFDe.js} +5 -5
  324. package/dist/ui/client/assets/index-CiHrf73J.css +2 -0
  325. package/dist/ui/client/index.html +2 -2
  326. package/dist/ui/server/server.js +26961 -26463
  327. package/package.json +26 -26
  328. package/dist/ui/client/assets/index-DiOvW76Q.css +0 -2
@@ -1 +1 @@
1
- {"version":3,"file":"sanitize.mjs","names":["isObject","EVENT_DIFF_SECRET_KEY_REGEX","DATA_KEY_ALLOW_LIST","DATA_VALUE_MAX_LENGTH","isDiffScalar","value","truncateDiffScalar","length","substring","sanitizeDiff","input","output","key","entry","Object","entries","test","next","previous","keys","sanitizeEventData","diff"],"sources":["../../../../src/core/entities/event/sanitize.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { isObject } from '@authup/kit';\nimport { EVENT_DIFF_SECRET_KEY_REGEX } from './diff.ts';\n\n/**\n * The central PII/credential write boundary for event context data.\n *\n * Allowlist-first: only these keys survive, and only with scalar values —\n * objects and arrays are dropped outright, so a nested structure can never\n * smuggle a secret past the boundary (this subsumes a denylist: password,\n * client_secret, code, code_verifier, *token* etc. are simply never listed).\n * sessionId / jti / revokedSessionId are opaque correlation ids, not PII.\n * name / use / status / enabled / force describe key & trust-anchor lifecycle\n * operations (issue #3269) — canonical identifiers and enum/flag metadata,\n * never material. kind is the MFA authenticator kind (totp/email/...).\n *\n * The single structured exception is `diff` (entity-CRUD bridge): it survives\n * only as a one-level object of `{ next, previous }` scalar pairs, keys\n * re-checked against the diff secret denylist — the write boundary stays the\n * choke point even though buildEntityDiff pre-sanitizes.\n */\nconst DATA_KEY_ALLOW_LIST = [\n 'grantType',\n 'scope',\n 'responseType',\n 'prompt',\n 'error',\n 'errorCode',\n 'reason',\n 'clientName',\n 'realmName',\n 'sessionId',\n 'jti',\n 'revokedSessionId',\n 'name',\n 'use',\n 'status',\n 'enabled',\n 'force',\n 'kind',\n] as const;\n\nconst DATA_VALUE_MAX_LENGTH = 512;\n\nfunction isDiffScalar(value: unknown): value is string | number | boolean | null {\n return value === null ||\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean';\n}\n\nfunction truncateDiffScalar(\n value: string | number | boolean | null,\n): string | number | boolean | null {\n if (typeof value === 'string' && value.length > DATA_VALUE_MAX_LENGTH) {\n return value.substring(0, DATA_VALUE_MAX_LENGTH);\n }\n\n return value;\n}\n\nfunction sanitizeDiff(input: unknown): Record<string, any> | null {\n if (!isObject(input)) {\n return null;\n }\n\n const output: Record<string, any> = {};\n\n for (const [key, entry] of Object.entries(input)) {\n if (EVENT_DIFF_SECRET_KEY_REGEX.test(key)) {\n continue;\n }\n\n if (!isObject(entry)) {\n continue;\n }\n\n const { next, previous } = entry;\n if (!isDiffScalar(next) || !isDiffScalar(previous)) {\n continue;\n }\n\n output[key] = {\n next: truncateDiffScalar(next),\n previous: truncateDiffScalar(previous),\n };\n }\n\n if (Object.keys(output).length === 0) {\n return null;\n }\n\n return output;\n}\n\nexport function sanitizeEventData(\n input?: Record<string, any> | null,\n): Record<string, any> | null {\n if (!input) {\n return null;\n }\n\n const output: Record<string, any> = {};\n\n for (const key of DATA_KEY_ALLOW_LIST) {\n const value = input[key];\n\n if (typeof value === 'string') {\n output[key] = value.length > DATA_VALUE_MAX_LENGTH ?\n value.substring(0, DATA_VALUE_MAX_LENGTH) :\n value;\n } else if (typeof value === 'number' || typeof value === 'boolean') {\n output[key] = value;\n }\n }\n\n const diff = sanitizeDiff(input.diff);\n if (diff) {\n output.diff = diff;\n }\n\n if (Object.keys(output).length === 0) {\n return null;\n }\n\n return output;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;GA2BA,MAAME,sBAAsB;CACxB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;;AAGJ,MAAMC,wBAAwB;AAE9B,SAASC,aAAaC,OAAc;CAChC,OAAOA,UAAU,QACb,OAAOA,UAAU,YACjB,OAAOA,UAAU,YACjB,OAAOA,UAAU;AACzB;AAEA,SAASC,mBACLD,OAAuC;CAEvC,IAAI,OAAOA,UAAU,YAAYA,MAAME,SAASJ,uBAC5C,OAAOE,MAAMG,UAAU,GAAGL,qBAAAA;CAG9B,OAAOE;AACX;AAEA,SAASI,aAAaC,OAAc;CAChC,IAAI,CAACV,SAASU,KAAAA,GACV,OAAO;CAGX,MAAMC,SAA8B,CAAC;CAErC,KAAK,MAAM,CAACC,KAAKC,UAAUC,OAAOC,QAAQL,KAAAA,GAAQ;EAC9C,IAAIT,4BAA4Be,KAAKJ,GAAAA,GACjC;EAGJ,IAAI,CAACZ,SAASa,KAAAA,GACV;EAGJ,MAAM,EAAEI,MAAMC,aAAaL;EAC3B,IAAI,CAACT,aAAaa,IAAAA,KAAS,CAACb,aAAac,QAAAA,GACrC;EAGJP,OAAOC,OAAO;GACVK,MAAMX,mBAAmBW,IAAAA;GACzBC,UAAUZ,mBAAmBY,QAAAA;EACjC;CACJ;CAEA,IAAIJ,OAAOK,KAAKR,MAAAA,CAAAA,CAAQJ,WAAW,GAC/B,OAAO;CAGX,OAAOI;AACX;AAEA,SAAgBS,kBACZV,OAAkC;CAElC,IAAI,CAACA,OACD,OAAO;CAGX,MAAMC,SAA8B,CAAC;CAErC,KAAK,MAAMC,OAAOV,qBAAqB;EACnC,MAAMG,QAAQK,MAAME;EAEpB,IAAI,OAAOP,UAAU,UACjBM,OAAOC,OAAOP,MAAME,SAASJ,wBACzBE,MAAMG,UAAU,GAAGL,qBAAAA,IACnBE;OACD,IAAI,OAAOA,UAAU,YAAY,OAAOA,UAAU,WACrDM,OAAOC,OAAOP;CAEtB;CAEA,MAAMgB,OAAOZ,aAAaC,MAAMW,IAAI;CACpC,IAAIA,MACAV,OAAOU,OAAOA;CAGlB,IAAIP,OAAOK,KAAKR,MAAAA,CAAAA,CAAQJ,WAAW,GAC/B,OAAO;CAGX,OAAOI;AACX"}
1
+ {"version":3,"file":"sanitize.mjs","names":["isObject","EVENT_DIFF_SECRET_KEY_REGEX","DATA_KEY_ALLOW_LIST","DATA_VALUE_MAX_LENGTH","isDiffScalar","value","truncateDiffScalar","length","substring","sanitizeDiff","input","output","key","entry","Object","entries","test","next","previous","keys","sanitizeEventData","diff"],"sources":["../../../../src/core/entities/event/sanitize.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { isObject } from '@authup/kit';\nimport { EVENT_DIFF_SECRET_KEY_REGEX } from './diff.ts';\n\n/**\n * The central PII/credential write boundary for event context data.\n *\n * Allowlist-first: only these keys survive, and only with scalar values —\n * objects and arrays are dropped outright, so a nested structure can never\n * smuggle a secret past the boundary (this subsumes a denylist: password,\n * client_secret, code, code_verifier, *token* etc. are simply never listed).\n * sessionId / jti / revokedSessionId are opaque correlation ids, not PII.\n * name / use / status / enabled / force describe key & trust-anchor lifecycle\n * operations (issue #3269) — canonical identifiers and enum/flag metadata,\n * never material. kind is the MFA authenticator kind (totp/email/...).\n *\n * The single structured exception is `diff` (entity-CRUD bridge): it survives\n * only as a one-level object of `{ next, previous }` scalar pairs, keys\n * re-checked against the diff secret denylist — the write boundary stays the\n * choke point even though buildEntityDiff pre-sanitizes.\n */\nconst DATA_KEY_ALLOW_LIST = [\n 'grantType',\n 'scope',\n 'responseType',\n 'prompt',\n 'error',\n 'errorCode',\n 'reason',\n 'clientName',\n 'realmName',\n 'sessionId',\n 'jti',\n 'revokedSessionId',\n 'name',\n 'use',\n 'status',\n 'enabled',\n 'force',\n 'kind',\n] as const;\n\nconst DATA_VALUE_MAX_LENGTH = 512;\n\nfunction isDiffScalar(value: unknown): value is string | number | boolean | null {\n return value === null ||\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean';\n}\n\nfunction truncateDiffScalar(\n value: string | number | boolean | null,\n): string | number | boolean | null {\n if (typeof value === 'string' && value.length > DATA_VALUE_MAX_LENGTH) {\n return value.substring(0, DATA_VALUE_MAX_LENGTH);\n }\n\n return value;\n}\n\nfunction sanitizeDiff(input: unknown): Record<string, any> | null {\n if (!isObject(input)) {\n return null;\n }\n\n const output: Record<string, any> = {};\n\n for (const [key, entry] of Object.entries(input)) {\n if (EVENT_DIFF_SECRET_KEY_REGEX.test(key)) {\n continue;\n }\n\n if (!isObject(entry)) {\n continue;\n }\n\n const { next, previous } = entry;\n if (!isDiffScalar(next) || !isDiffScalar(previous)) {\n continue;\n }\n\n output[key] = {\n next: truncateDiffScalar(next),\n previous: truncateDiffScalar(previous),\n };\n }\n\n if (Object.keys(output).length === 0) {\n return null;\n }\n\n return output;\n}\n\nexport function sanitizeEventData(\n input?: Record<string, any> | null,\n): Record<string, any> | null {\n if (!input) {\n return null;\n }\n\n const output: Record<string, any> = {};\n\n for (const key of DATA_KEY_ALLOW_LIST) {\n const value = input[key];\n\n if (typeof value === 'string') {\n output[key] = value.length > DATA_VALUE_MAX_LENGTH ?\n value.substring(0, DATA_VALUE_MAX_LENGTH) :\n value;\n } else if (typeof value === 'number' || typeof value === 'boolean') {\n output[key] = value;\n }\n }\n\n const diff = sanitizeDiff(input.diff);\n if (diff) {\n output.diff = diff;\n }\n\n if (Object.keys(output).length === 0) {\n return null;\n }\n\n return output;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;GA2BA,MAAME,sBAAsB;CACxB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACH;AAED,MAAMC,wBAAwB;AAE9B,SAASC,aAAaC,OAAc;CAChC,OAAOA,UAAU,QACb,OAAOA,UAAU,YACjB,OAAOA,UAAU,YACjB,OAAOA,UAAU;AACzB;AAEA,SAASC,mBACLD,OAAuC;CAEvC,IAAI,OAAOA,UAAU,YAAYA,MAAME,SAASJ,uBAC5C,OAAOE,MAAMG,UAAU,GAAGL,qBAAAA;CAG9B,OAAOE;AACX;AAEA,SAASI,aAAaC,OAAc;CAChC,IAAI,CAACV,SAASU,KAAAA,GACV,OAAO;CAGX,MAAMC,SAA8B,CAAC;CAErC,KAAK,MAAM,CAACC,KAAKC,UAAUC,OAAOC,QAAQL,KAAAA,GAAQ;EAC9C,IAAIT,4BAA4Be,KAAKJ,GAAAA,GACjC;EAGJ,IAAI,CAACZ,SAASa,KAAAA,GACV;EAGJ,MAAM,EAAEI,MAAMC,aAAaL;EAC3B,IAAI,CAACT,aAAaa,IAAAA,KAAS,CAACb,aAAac,QAAAA,GACrC;EAGJP,OAAOC,OAAO;GACVK,MAAMX,mBAAmBW,IAAAA;GACzBC,UAAUZ,mBAAmBY,QAAAA;EACjC;CACJ;CAEA,IAAIJ,OAAOK,KAAKR,MAAAA,CAAAA,CAAQJ,WAAW,GAC/B,OAAO;CAGX,OAAOI;AACX;AAEA,SAAgBS,kBACZV,OAAkC;CAElC,IAAI,CAACA,OACD,OAAO;CAGX,MAAMC,SAA8B,CAAC;CAErC,KAAK,MAAMC,OAAOV,qBAAqB;EACnC,MAAMG,QAAQK,MAAME;EAEpB,IAAI,OAAOP,UAAU,UACjBM,OAAOC,OAAOP,MAAME,SAASJ,wBACzBE,MAAMG,UAAU,GAAGL,qBAAAA,IACnBE;OACD,IAAI,OAAOA,UAAU,YAAY,OAAOA,UAAU,WACrDM,OAAOC,OAAOP;CAEtB;CAEA,MAAMgB,OAAOZ,aAAaC,MAAMW,IAAI;CACpC,IAAIA,MACAV,OAAOU,OAAOA;CAGlB,IAAIP,OAAOK,KAAKR,MAAAA,CAAAA,CAAQJ,WAAW,GAC/B,OAAO;CAGX,OAAOI;AACX"}
@@ -1 +1 @@
1
- {"version":3,"file":"schema.mjs","names":["defineSchema","EntityType","eventSchema","name","EVENT","fields","allowed","filters","relations","sort","pagination","maxLimit"],"sources":["../../../../src/core/entities/event/schema.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { defineSchema } from '@rapiq/core';\nimport type { Event } from '@authup/core-kit';\nimport { EntityType } from '@authup/core-kit';\n\nexport const eventSchema = defineSchema<Event>({\n name: EntityType.EVENT,\n fields: {\n allowed: [\n 'id',\n 'scope',\n 'name',\n 'refType',\n 'refId',\n 'clientId',\n 'actorType',\n 'actorId',\n 'actorName',\n 'requestPath',\n 'requestMethod',\n 'requestIpAddress',\n 'requestUserAgent',\n 'realmId',\n 'data',\n 'expiring',\n 'expiresAt',\n 'createdAt',\n ],\n },\n filters: {\n allowed: [\n 'id',\n 'scope',\n 'name',\n 'refType',\n 'refId',\n 'clientId',\n 'actorType',\n 'actorId',\n 'actorName',\n 'requestIpAddress',\n 'realmId',\n 'expiring',\n 'createdAt',\n ], \n },\n relations: { allowed: [] },\n sort: { allowed: ['createdAt'] },\n pagination: { maxLimit: 50 },\n});\n"],"mappings":";;;;;;AAWA,MAAaE,cAAcF,aAAoB;CAC3CG,MAAMF,WAAWG;CACjBC,QAAQ,EACJC,SAAS;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;GAER;CACAC,SAAS,EACLD,SAAS;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;GAER;CACAE,WAAW,EAAEF,SAAS,CAAA,EAAG;CACzBG,MAAM,EAAEH,SAAS,CAAC,WAAA,EAAa;CAC/BI,YAAY,EAAEC,UAAU,GAAG;AAC/B,CAAA"}
1
+ {"version":3,"file":"schema.mjs","names":["defineSchema","EntityType","eventSchema","name","EVENT","fields","allowed","filters","relations","sort","pagination","maxLimit"],"sources":["../../../../src/core/entities/event/schema.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { defineSchema } from '@rapiq/core';\nimport type { Event } from '@authup/core-kit';\nimport { EntityType } from '@authup/core-kit';\n\nexport const eventSchema = defineSchema<Event>({\n name: EntityType.EVENT,\n fields: {\n allowed: [\n 'id',\n 'scope',\n 'name',\n 'refType',\n 'refId',\n 'clientId',\n 'actorType',\n 'actorId',\n 'actorName',\n 'requestPath',\n 'requestMethod',\n 'requestIpAddress',\n 'requestUserAgent',\n 'realmId',\n 'data',\n 'expiring',\n 'expiresAt',\n 'createdAt',\n ],\n },\n filters: {\n allowed: [\n 'id',\n 'scope',\n 'name',\n 'refType',\n 'refId',\n 'clientId',\n 'actorType',\n 'actorId',\n 'actorName',\n 'requestIpAddress',\n 'realmId',\n 'expiring',\n 'createdAt',\n ], \n },\n relations: { allowed: [] },\n sort: { allowed: ['createdAt'] },\n pagination: { maxLimit: 50 },\n});\n"],"mappings":";;;;;;AAWA,MAAaE,cAAcF,aAAoB;CAC3CG,MAAMF,WAAWG;CACjBC,QAAQ,EACJC,SAAS;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACH,EACL;CACAC,SAAS,EACLD,SAAS;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACH,EACL;CACAE,WAAW,EAAEF,SAAS,CAAA,EAAG;CACzBG,MAAM,EAAEH,SAAS,CAAC,WAAY,EAAC;CAC/BI,YAAY,EAAEC,UAAU,GAAG;AAC/B,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"service.mjs","names":["randomUUID","BuiltInPolicyType","definePolicyData","and","eq","inArray","or","PermissionName","EntityNotFoundError","AbstractEntityService","EVENT_LOG_RETENTION_DAYS_DEFAULT","sanitizeEventData","appendQueryConditions","decodeQuery","eventSchema","DAY_IN_MS","EventService","repository","options","logger","ctx","isOwnedBy","entity","actor","identity","actorId","data","id","actorType","type","canReadRealm","realmId","permissionEvaluator","evaluate","name","EVENT_READ","REALM_MATCH","policiesIncluded","COMPOSITE","PERMISSION_BINDING","resolveReadVisibility","actorRealmId","getActorRealmId","foreignRealmId","undefined","realmIds","push","owner","record","input","info","scope","refType","refId","clientId","enabled","retentionDays","create","truncate","actorName","requestPath","requestMethod","requestIpAddress","requestUserAgent","expiring","expiresAt","Date","now","toISOString","save","warn","getMany","query","parsed","schema","canReadAll","preEvaluate","e","findMany","compiled","compile","verdict","ownership","scoped","condition","visibility","entities","meta","ATTRIBUTES","resourceRealmMatch","total","length","getOne","findOneById","value","maxLength","substring"],"sources":["../../../../src/core/entities/event/service.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { randomUUID } from 'node:crypto';\nimport { BuiltInPolicyType, definePolicyData } from '@authup/access';\nimport {\n and, \n eq, \n inArray, \n or,\n} from '@rapiq/core';\nimport { PermissionName } from '@authup/core-kit';\nimport type { Event } from '@authup/core-kit';\nimport { EntityNotFoundError } from '@authup/errors';\nimport { AbstractEntityService } from '@authup/server-kit';\nimport type { ActorContext, EntityRepositoryFindManyResult, Logger } from '@authup/server-kit';\nimport { EVENT_LOG_RETENTION_DAYS_DEFAULT } from './constants.ts';\nimport { sanitizeEventData } from './sanitize.ts';\nimport type {\n EventReadVisibility,\n EventRecordInput,\n EventServiceOptions,\n EventServiceReadOptions,\n IEventRepository,\n IEventService,\n} from './types.ts';\nimport { appendQueryConditions, decodeQuery } from '../../query/index.ts';\nimport { eventSchema } from './schema.ts';\n\nexport type EventServiceContext = {\n repository: IEventRepository,\n options?: EventServiceOptions,\n logger?: Logger,\n};\n\nconst DAY_IN_MS = 86_400_000;\n\nexport class EventService extends AbstractEntityService implements IEventService {\n protected repository: IEventRepository;\n\n protected options: EventServiceOptions;\n\n protected logger?: Logger;\n\n constructor(ctx: EventServiceContext) {\n super();\n\n this.repository = ctx.repository;\n this.options = ctx.options ?? {};\n this.logger = ctx.logger;\n }\n\n protected isOwnedBy(entity: Event, actor: ActorContext): boolean {\n return !!actor.identity &&\n !!entity.actorId &&\n entity.actorId === actor.identity.data.id &&\n entity.actorType === actor.identity.type;\n }\n\n protected async canReadRealm(actor: ActorContext, realmId: string | null): Promise<boolean> {\n try {\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.EVENT_READ,\n data: definePolicyData({ [BuiltInPolicyType.REALM_MATCH]: realmId }),\n options: {\n policiesIncluded: [\n BuiltInPolicyType.COMPOSITE,\n BuiltInPolicyType.PERMISSION_BINDING,\n BuiltInPolicyType.REALM_MATCH,\n ],\n },\n });\n return true;\n } catch {\n return false;\n }\n }\n\n protected async resolveReadVisibility(actor: ActorContext): Promise<EventReadVisibility | undefined> {\n const actorRealmId = this.getActorRealmId(actor);\n let foreignRealmId = randomUUID();\n while (foreignRealmId === actorRealmId) {\n foreignRealmId = randomUUID();\n }\n\n if (await this.canReadRealm(actor, foreignRealmId)) {\n return undefined;\n }\n\n const realmIds: Array<string | null> = [];\n if (actorRealmId && await this.canReadRealm(actor, actorRealmId)) {\n realmIds.push(actorRealmId);\n }\n if (await this.canReadRealm(actor, null)) {\n realmIds.push(null);\n }\n\n return {\n realmIds,\n ...(actor.identity ? {\n owner: {\n actorId: actor.identity.data.id,\n actorType: actor.identity.type,\n },\n } : {}),\n };\n }\n\n async record(input: EventRecordInput): Promise<void> {\n const data = sanitizeEventData(input.data);\n\n // complementary structured log line — fires even when persistence is\n // disabled, so a SIEM/Loki pipeline can pick the events up for free.\n this.logger?.info(`audit: ${input.scope}.${input.name}`, {\n scope: input.scope,\n name: input.name,\n refType: input.refType ?? null,\n refId: input.refId ?? null,\n clientId: input.clientId ?? null,\n actorType: input.actorType ?? null,\n actorId: input.actorId ?? null,\n realmId: input.realmId ?? null,\n ...(data ? { data } : {}),\n });\n\n if (this.options.enabled === false) {\n return;\n }\n\n try {\n const retentionDays = input.retentionDays ?? this.options.retentionDays ?? EVENT_LOG_RETENTION_DAYS_DEFAULT;\n\n const entity = this.repository.create({\n id: randomUUID(),\n scope: input.scope,\n name: input.name,\n refType: truncate(input.refType, 64),\n refId: truncate(input.refId, 64),\n clientId: input.clientId ?? null,\n actorType: input.actorType ?? null,\n actorId: input.actorId ?? null,\n actorName: truncate(input.actorName, 128),\n requestPath: truncate(input.requestPath, 256),\n requestMethod: truncate(input.requestMethod, 10),\n requestIpAddress: truncate(input.requestIpAddress, 45),\n requestUserAgent: truncate(input.requestUserAgent, 512),\n realmId: input.realmId ?? null,\n data,\n expiring: retentionDays > 0,\n expiresAt: retentionDays > 0 ?\n new Date(Date.now() + (retentionDays * DAY_IN_MS)).toISOString() :\n null,\n });\n\n await this.repository.save(entity);\n } catch {\n // an audit write failure must never fail the originating operation\n this.logger?.warn(`Recording the audit event ${input.scope}.${input.name} failed.`);\n }\n }\n\n async getMany(\n query: Record<string, any>,\n actor: ActorContext,\n options: EventServiceReadOptions = {},\n ): Promise<EntityRepositoryFindManyResult<Event>> {\n const parsed = await decodeQuery(query, { schema: eventSchema, actor });\n\n let canReadAll = true;\n try {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.EVENT_READ });\n } catch (e) {\n if (!actor.identity) {\n throw e;\n }\n canReadAll = false;\n }\n\n if (!canReadAll) {\n // self-service: only the actor's own rows (\"my sign-in history\")\n return this.repository.findMany(parsed, {\n owner: {\n actorId: actor.identity!.data.id,\n actorType: actor.identity!.type,\n },\n ...(options.realmId ? { realmId: options.realmId } : {}),\n });\n }\n\n // Compile EVENT_READ into a row condition (#3286 phase 3). Own rows are\n // always readable, so ownership composes as an OR-alternative — the whole\n // gate runs as WHERE (replacing the probe-based visibility derivation, and\n // additionally covering junction ATTRIBUTES policies the probe excluded)\n // and pagination/totals stay exact. A non-expressible policy falls back to\n // the probe + per-row loop below.\n const compiled = await actor.permissionEvaluator.compile({ name: PermissionName.EVENT_READ });\n if (compiled.verdict !== 'post') {\n const ownership = actor.identity ?\n and(eq('actorId', actor.identity.data.id), eq('actorType', actor.identity.type)) :\n null;\n\n let scoped = parsed;\n if (compiled.verdict === 'deny') {\n scoped = appendQueryConditions(parsed, ownership ?? inArray('id', []));\n } else if (compiled.verdict === 'conditional') {\n scoped = appendQueryConditions(\n parsed,\n ownership ? or(ownership, compiled.condition) : compiled.condition,\n );\n }\n\n return this.repository.findMany(scoped, { ...(options.realmId ? { realmId: options.realmId } : {}) });\n }\n\n const visibility = await this.resolveReadVisibility(actor);\n const { data: entities, meta } = await this.repository.findMany(parsed, {\n ...(options.realmId ? { realmId: options.realmId } : {}),\n ...(visibility ? { visibility } : {}),\n });\n\n const data: Event[] = [];\n\n for (const entity of entities) {\n if (this.isOwnedBy(entity, actor)) {\n data.push(entity);\n continue;\n }\n\n try {\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.EVENT_READ,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: entity,\n ...this.resourceRealmMatch(entity),\n }),\n });\n data.push(entity);\n } catch {\n continue;\n }\n }\n\n return {\n data,\n meta: {\n ...meta,\n total: meta.total - (entities.length - data.length),\n },\n };\n }\n\n async getOne(id: string, actor: ActorContext, options: EventServiceReadOptions = {}): Promise<Event> {\n const entity = await this.repository.findOneById(id);\n if (!entity || (options.realmId && entity.realmId !== options.realmId)) {\n throw new EntityNotFoundError();\n }\n\n if (!this.isOwnedBy(entity, actor)) {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.EVENT_READ });\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.EVENT_READ,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: entity,\n ...this.resourceRealmMatch(entity),\n }),\n });\n }\n\n return entity;\n }\n}\n\nfunction truncate(value: string | null | undefined, maxLength: number): string | null {\n if (typeof value !== 'string') {\n return null;\n }\n\n if (value.length <= maxLength) {\n return value;\n }\n\n return value.substring(0, maxLength);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"service.mjs","names":["randomUUID","BuiltInPolicyType","definePolicyData","and","eq","inArray","or","PermissionName","EntityNotFoundError","AbstractEntityService","EVENT_LOG_RETENTION_DAYS_DEFAULT","sanitizeEventData","appendQueryConditions","decodeQuery","eventSchema","DAY_IN_MS","EventService","repository","options","logger","ctx","isOwnedBy","entity","actor","identity","actorId","data","id","actorType","type","canReadRealm","realmId","permissionEvaluator","evaluate","name","EVENT_READ","REALM_MATCH","policiesIncluded","COMPOSITE","PERMISSION_BINDING","resolveReadVisibility","actorRealmId","getActorRealmId","foreignRealmId","undefined","realmIds","push","owner","record","input","info","scope","refType","refId","clientId","enabled","retentionDays","create","truncate","actorName","requestPath","requestMethod","requestIpAddress","requestUserAgent","expiring","expiresAt","Date","now","toISOString","save","warn","getMany","query","parsed","schema","canReadAll","preEvaluate","e","findMany","compiled","compile","verdict","ownership","scoped","condition","visibility","entities","meta","ATTRIBUTES","resourceRealmMatch","total","length","getOne","findOneById","value","maxLength","substring"],"sources":["../../../../src/core/entities/event/service.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { randomUUID } from 'node:crypto';\nimport { BuiltInPolicyType, definePolicyData } from '@authup/access';\nimport {\n and, \n eq, \n inArray, \n or,\n} from '@rapiq/core';\nimport { PermissionName } from '@authup/core-kit';\nimport type { Event } from '@authup/core-kit';\nimport { EntityNotFoundError } from '@authup/errors';\nimport { AbstractEntityService } from '@authup/server-kit';\nimport type { ActorContext, EntityRepositoryFindManyResult, Logger } from '@authup/server-kit';\nimport { EVENT_LOG_RETENTION_DAYS_DEFAULT } from './constants.ts';\nimport { sanitizeEventData } from './sanitize.ts';\nimport type {\n EventReadVisibility,\n EventRecordInput,\n EventServiceOptions,\n EventServiceReadOptions,\n IEventRepository,\n IEventService,\n} from './types.ts';\nimport { appendQueryConditions, decodeQuery } from '../../query/index.ts';\nimport { eventSchema } from './schema.ts';\n\nexport type EventServiceContext = {\n repository: IEventRepository,\n options?: EventServiceOptions,\n logger?: Logger,\n};\n\nconst DAY_IN_MS = 86_400_000;\n\nexport class EventService extends AbstractEntityService implements IEventService {\n protected repository: IEventRepository;\n\n protected options: EventServiceOptions;\n\n protected logger?: Logger;\n\n constructor(ctx: EventServiceContext) {\n super();\n\n this.repository = ctx.repository;\n this.options = ctx.options ?? {};\n this.logger = ctx.logger;\n }\n\n protected isOwnedBy(entity: Event, actor: ActorContext): boolean {\n return !!actor.identity &&\n !!entity.actorId &&\n entity.actorId === actor.identity.data.id &&\n entity.actorType === actor.identity.type;\n }\n\n protected async canReadRealm(actor: ActorContext, realmId: string | null): Promise<boolean> {\n try {\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.EVENT_READ,\n data: definePolicyData({ [BuiltInPolicyType.REALM_MATCH]: realmId }),\n options: {\n policiesIncluded: [\n BuiltInPolicyType.COMPOSITE,\n BuiltInPolicyType.PERMISSION_BINDING,\n BuiltInPolicyType.REALM_MATCH,\n ],\n },\n });\n return true;\n } catch {\n return false;\n }\n }\n\n protected async resolveReadVisibility(actor: ActorContext): Promise<EventReadVisibility | undefined> {\n const actorRealmId = this.getActorRealmId(actor);\n let foreignRealmId = randomUUID();\n while (foreignRealmId === actorRealmId) {\n foreignRealmId = randomUUID();\n }\n\n if (await this.canReadRealm(actor, foreignRealmId)) {\n return undefined;\n }\n\n const realmIds: Array<string | null> = [];\n if (actorRealmId && await this.canReadRealm(actor, actorRealmId)) {\n realmIds.push(actorRealmId);\n }\n if (await this.canReadRealm(actor, null)) {\n realmIds.push(null);\n }\n\n return {\n realmIds,\n ...(actor.identity ? {\n owner: {\n actorId: actor.identity.data.id,\n actorType: actor.identity.type,\n },\n } : {}),\n };\n }\n\n async record(input: EventRecordInput): Promise<void> {\n const data = sanitizeEventData(input.data);\n\n // complementary structured log line — fires even when persistence is\n // disabled, so a SIEM/Loki pipeline can pick the events up for free.\n this.logger?.info(`audit: ${input.scope}.${input.name}`, {\n scope: input.scope,\n name: input.name,\n refType: input.refType ?? null,\n refId: input.refId ?? null,\n clientId: input.clientId ?? null,\n actorType: input.actorType ?? null,\n actorId: input.actorId ?? null,\n realmId: input.realmId ?? null,\n ...(data ? { data } : {}),\n });\n\n if (this.options.enabled === false) {\n return;\n }\n\n try {\n const retentionDays = input.retentionDays ?? this.options.retentionDays ?? EVENT_LOG_RETENTION_DAYS_DEFAULT;\n\n const entity = this.repository.create({\n id: randomUUID(),\n scope: input.scope,\n name: input.name,\n refType: truncate(input.refType, 64),\n refId: truncate(input.refId, 64),\n clientId: input.clientId ?? null,\n actorType: input.actorType ?? null,\n actorId: input.actorId ?? null,\n actorName: truncate(input.actorName, 128),\n requestPath: truncate(input.requestPath, 256),\n requestMethod: truncate(input.requestMethod, 10),\n requestIpAddress: truncate(input.requestIpAddress, 45),\n requestUserAgent: truncate(input.requestUserAgent, 512),\n realmId: input.realmId ?? null,\n data,\n expiring: retentionDays > 0,\n expiresAt: retentionDays > 0 ?\n new Date(Date.now() + (retentionDays * DAY_IN_MS)).toISOString() :\n null,\n });\n\n await this.repository.save(entity);\n } catch {\n // an audit write failure must never fail the originating operation\n this.logger?.warn(`Recording the audit event ${input.scope}.${input.name} failed.`);\n }\n }\n\n async getMany(\n query: Record<string, any>,\n actor: ActorContext,\n options: EventServiceReadOptions = {},\n ): Promise<EntityRepositoryFindManyResult<Event>> {\n const parsed = await decodeQuery(query, { schema: eventSchema, actor });\n\n let canReadAll = true;\n try {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.EVENT_READ });\n } catch (e) {\n if (!actor.identity) {\n throw e;\n }\n canReadAll = false;\n }\n\n if (!canReadAll) {\n // self-service: only the actor's own rows (\"my sign-in history\")\n return this.repository.findMany(parsed, {\n owner: {\n actorId: actor.identity!.data.id,\n actorType: actor.identity!.type,\n },\n ...(options.realmId ? { realmId: options.realmId } : {}),\n });\n }\n\n // Compile EVENT_READ into a row condition (#3286 phase 3). Own rows are\n // always readable, so ownership composes as an OR-alternative — the whole\n // gate runs as WHERE (replacing the probe-based visibility derivation, and\n // additionally covering junction ATTRIBUTES policies the probe excluded)\n // and pagination/totals stay exact. A non-expressible policy falls back to\n // the probe + per-row loop below.\n const compiled = await actor.permissionEvaluator.compile({ name: PermissionName.EVENT_READ });\n if (compiled.verdict !== 'post') {\n const ownership = actor.identity ?\n and(eq('actorId', actor.identity.data.id), eq('actorType', actor.identity.type)) :\n null;\n\n let scoped = parsed;\n if (compiled.verdict === 'deny') {\n scoped = appendQueryConditions(parsed, ownership ?? inArray('id', []));\n } else if (compiled.verdict === 'conditional') {\n scoped = appendQueryConditions(\n parsed,\n ownership ? or(ownership, compiled.condition) : compiled.condition,\n );\n }\n\n return this.repository.findMany(scoped, { ...(options.realmId ? { realmId: options.realmId } : {}) });\n }\n\n const visibility = await this.resolveReadVisibility(actor);\n const { data: entities, meta } = await this.repository.findMany(parsed, {\n ...(options.realmId ? { realmId: options.realmId } : {}),\n ...(visibility ? { visibility } : {}),\n });\n\n const data: Event[] = [];\n\n for (const entity of entities) {\n if (this.isOwnedBy(entity, actor)) {\n data.push(entity);\n continue;\n }\n\n try {\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.EVENT_READ,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: entity,\n ...this.resourceRealmMatch(entity),\n }),\n });\n data.push(entity);\n } catch {\n continue;\n }\n }\n\n return {\n data,\n meta: {\n ...meta,\n total: meta.total - (entities.length - data.length),\n },\n };\n }\n\n async getOne(id: string, actor: ActorContext, options: EventServiceReadOptions = {}): Promise<Event> {\n const entity = await this.repository.findOneById(id);\n if (!entity || (options.realmId && entity.realmId !== options.realmId)) {\n throw new EntityNotFoundError();\n }\n\n if (!this.isOwnedBy(entity, actor)) {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.EVENT_READ });\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.EVENT_READ,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: entity,\n ...this.resourceRealmMatch(entity),\n }),\n });\n }\n\n return entity;\n }\n}\n\nfunction truncate(value: string | null | undefined, maxLength: number): string | null {\n if (typeof value !== 'string') {\n return null;\n }\n\n if (value.length <= maxLength) {\n return value;\n }\n\n return value.substring(0, maxLength);\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"schema.mjs","names":["defineSchema","EntityType","createRelationsReadGate","schemaMapping","realm","REALM","identityProviderSchema","name","IDENTITY_PROVIDER","fields","default","filters","allowed","relations","validate","sort","pagination","maxLimit"],"sources":["../../../../src/core/entities/identity-provider/schema.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { defineSchema } from '@rapiq/core';\nimport type { IdentityProvider } from '@authup/core-kit';\nimport { EntityType } from '@authup/core-kit';\nimport { createRelationsReadGate } from '../../query/relations.ts';\n\nconst schemaMapping = { realm: EntityType.REALM };\n\nexport const identityProviderSchema = defineSchema<IdentityProvider>({\n name: EntityType.IDENTITY_PROVIDER,\n fields: {\n default: [\n 'id',\n 'name',\n 'displayName',\n 'protocol',\n 'preset',\n 'enabled',\n 'realmId',\n 'createdAt',\n 'updatedAt',\n ],\n },\n filters: { allowed: ['name', 'protocol', 'enabled', 'realmId'] },\n relations: { allowed: ['realm'], validate: createRelationsReadGate(schemaMapping) },\n sort: { allowed: ['id', 'createdAt', 'updatedAt'] },\n pagination: { maxLimit: 50 },\n schemaMapping,\n});\n"],"mappings":";;;;;;;AAYA,MAAMG,gBAAgB,EAAEC,OAAOH,WAAWI,MAAM;AAEhD,MAAaC,yBAAyBN,aAA+B;CACjEO,MAAMN,WAAWO;CACjBC,QAAQ,EACJC,SAAS;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;GAER;CACAC,SAAS,EAAEC,SAAS;EAAC;EAAQ;EAAY;EAAW;GAAW;CAC/DC,WAAW;EAAED,SAAS,CAAC,OAAA;EAAUE,UAAUZ,wBAAwBC,aAAAA;CAAe;CAClFY,MAAM,EAAEH,SAAS;EAAC;EAAM;EAAa;GAAa;CAClDI,YAAY,EAAEC,UAAU,GAAG;CAC3Bd;AACJ,CAAA"}
1
+ {"version":3,"file":"schema.mjs","names":["defineSchema","EntityType","createRelationsReadGate","schemaMapping","realm","REALM","identityProviderSchema","name","IDENTITY_PROVIDER","fields","default","filters","allowed","relations","validate","sort","pagination","maxLimit"],"sources":["../../../../src/core/entities/identity-provider/schema.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { defineSchema } from '@rapiq/core';\nimport type { IdentityProvider } from '@authup/core-kit';\nimport { EntityType } from '@authup/core-kit';\nimport { createRelationsReadGate } from '../../query/relations.ts';\n\nconst schemaMapping = { realm: EntityType.REALM };\n\nexport const identityProviderSchema = defineSchema<IdentityProvider>({\n name: EntityType.IDENTITY_PROVIDER,\n fields: {\n default: [\n 'id',\n 'name',\n 'displayName',\n 'protocol',\n 'preset',\n 'enabled',\n 'realmId',\n 'createdAt',\n 'updatedAt',\n ],\n },\n filters: { allowed: ['name', 'protocol', 'enabled', 'realmId'] },\n relations: { allowed: ['realm'], validate: createRelationsReadGate(schemaMapping) },\n sort: { allowed: ['id', 'createdAt', 'updatedAt'] },\n pagination: { maxLimit: 50 },\n schemaMapping,\n});\n"],"mappings":";;;;;;;AAYA,MAAMG,gBAAgB,EAAEC,OAAOH,WAAWI,MAAM;AAEhD,MAAaC,yBAAyBN,aAA+B;CACjEO,MAAMN,WAAWO;CACjBC,QAAQ,EACJC,SAAS;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACH,EACL;CACAC,SAAS,EAAEC,SAAS;EAAC;EAAQ;EAAY;EAAW;CAAU,EAAC;CAC/DC,WAAW;EAAED,SAAS,CAAC,OAAQ;EAAEE,UAAUZ,wBAAwBC,aAAAA;CAAe;CAClFY,MAAM,EAAEH,SAAS;EAAC;EAAM;EAAa;CAAY,EAAC;CAClDI,YAAY,EAAEC,UAAU,GAAG;CAC3Bd;AACJ,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"schema.mjs","names":["defineSchema","EntityType","createRelationsReadGate","schemaMapping","role","ROLE","provider","IDENTITY_PROVIDER","identityProviderRoleMappingSchema","name","IDENTITY_PROVIDER_ROLE_MAPPING","fields","default","filters","allowed","relations","validate","sort","pagination","maxLimit"],"sources":["../../../../src/core/entities/identity-provider-role-mapping/schema.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { defineSchema } from '@rapiq/core';\nimport type { IdentityProviderRoleMapping } from '@authup/core-kit';\nimport { EntityType } from '@authup/core-kit';\nimport { createRelationsReadGate } from '../../query/relations.ts';\n\nconst schemaMapping = { role: EntityType.ROLE, provider: EntityType.IDENTITY_PROVIDER };\n\nexport const identityProviderRoleMappingSchema = defineSchema<IdentityProviderRoleMapping>({\n name: EntityType.IDENTITY_PROVIDER_ROLE_MAPPING,\n // see user-role schema — explicit root projection for include= decodes\n fields: {\n default: [\n 'id',\n 'name',\n 'value',\n 'valueIsRegex',\n 'synchronizationMode',\n 'providerId',\n 'providerRealmId',\n 'roleId',\n 'roleRealmId',\n 'createdAt',\n 'updatedAt',\n ],\n },\n filters: { allowed: ['roleId', 'providerId'] },\n relations: { allowed: ['role', 'provider'], validate: createRelationsReadGate(schemaMapping) },\n sort: { allowed: ['id', 'createdAt', 'updatedAt'] },\n pagination: { maxLimit: 50 },\n schemaMapping,\n});\n"],"mappings":";;;;;;;AAYA,MAAMG,gBAAgB;CAAEC,MAAMH,WAAWI;CAAMC,UAAUL,WAAWM;AAAkB;AAEtF,MAAaC,oCAAoCR,aAA0C;CACvFS,MAAMR,WAAWS;CAEjBC,QAAQ,EACJC,SAAS;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;GAER;CACAC,SAAS,EAAEC,SAAS,CAAC,UAAU,YAAA,EAAc;CAC7CC,WAAW;EAAED,SAAS,CAAC,QAAQ,UAAA;EAAaE,UAAUd,wBAAwBC,aAAAA;CAAe;CAC7Fc,MAAM,EAAEH,SAAS;EAAC;EAAM;EAAa;GAAa;CAClDI,YAAY,EAAEC,UAAU,GAAG;CAC3BhB;AACJ,CAAA"}
1
+ {"version":3,"file":"schema.mjs","names":["defineSchema","EntityType","createRelationsReadGate","schemaMapping","role","ROLE","provider","IDENTITY_PROVIDER","identityProviderRoleMappingSchema","name","IDENTITY_PROVIDER_ROLE_MAPPING","fields","default","filters","allowed","relations","validate","sort","pagination","maxLimit"],"sources":["../../../../src/core/entities/identity-provider-role-mapping/schema.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { defineSchema } from '@rapiq/core';\nimport type { IdentityProviderRoleMapping } from '@authup/core-kit';\nimport { EntityType } from '@authup/core-kit';\nimport { createRelationsReadGate } from '../../query/relations.ts';\n\nconst schemaMapping = { role: EntityType.ROLE, provider: EntityType.IDENTITY_PROVIDER };\n\nexport const identityProviderRoleMappingSchema = defineSchema<IdentityProviderRoleMapping>({\n name: EntityType.IDENTITY_PROVIDER_ROLE_MAPPING,\n // see user-role schema — explicit root projection for include= decodes\n fields: {\n default: [\n 'id',\n 'name',\n 'value',\n 'valueIsRegex',\n 'synchronizationMode',\n 'providerId',\n 'providerRealmId',\n 'roleId',\n 'roleRealmId',\n 'createdAt',\n 'updatedAt',\n ],\n },\n filters: { allowed: ['roleId', 'providerId'] },\n relations: { allowed: ['role', 'provider'], validate: createRelationsReadGate(schemaMapping) },\n sort: { allowed: ['id', 'createdAt', 'updatedAt'] },\n pagination: { maxLimit: 50 },\n schemaMapping,\n});\n"],"mappings":";;;;;;;AAYA,MAAMG,gBAAgB;CAAEC,MAAMH,WAAWI;CAAMC,UAAUL,WAAWM;AAAkB;AAEtF,MAAaC,oCAAoCR,aAA0C;CACvFS,MAAMR,WAAWS;CAEjBC,QAAQ,EACJC,SAAS;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACH,EACL;CACAC,SAAS,EAAEC,SAAS,CAAC,UAAU,YAAa,EAAC;CAC7CC,WAAW;EAAED,SAAS,CAAC,QAAQ,UAAW;EAAEE,UAAUd,wBAAwBC,aAAAA;CAAe;CAC7Fc,MAAM,EAAEH,SAAS;EAAC;EAAM;EAAa;CAAY,EAAC;CAClDI,YAAY,EAAEC,UAAU,GAAG;CAC3BhB;AACJ,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"service.mjs","names":["BuiltInPolicyType","PermissionError","definePolicyData","EntityConflictError","EntityNotFoundError","ValidationError","ValidatorGroup","IdentityProviderRoleMappingValidator","PermissionName","JunctionEntityService","decodeQuery","identityProviderRoleMappingSchema","IdentityProviderRoleMappingService","ownerRealmKey","repository","roleRepository","identityPermissionProvider","validator","ctx","getMany","query","actor","permissionEvaluator","preEvaluateOneOf","name","IDENTITY_PROVIDER_ROLE_READ","IDENTITY_PROVIDER_READ","IDENTITY_PROVIDER_UPDATE","IDENTITY_PROVIDER_DELETE","findMany","schema","getOne","id","entity","findOneBy","create","data","preEvaluate","IDENTITY_PROVIDER_ROLE_CREATE","validated","run","group","CREATE","validateJoinColumns","existing","providerId","roleId","provider","providerRealmId","realmId","role","roleRealmId","identity","hasPermissions","isSuperset","type","clientId","message","evaluate","ATTRIBUTES","junctionAttributes","REALM_MATCH","junctionResourceRealm","save","update","IDENTITY_PROVIDER_ROLE_UPDATE","UPDATE","findOneById","merged","merge","delete","IDENTITY_PROVIDER_ROLE_DELETE","entityId","remove"],"sources":["../../../../src/core/entities/identity-provider-role-mapping/service.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { BuiltInPolicyType, PermissionError, definePolicyData } from '@authup/access';\nimport { EntityConflictError, EntityNotFoundError, ValidationError } from '@authup/errors';\nimport { ValidatorGroup } from '@authup/kit';\nimport { IdentityProviderRoleMappingValidator, PermissionName } from '@authup/core-kit';\nimport type { IdentityProviderRoleMapping, Role } from '@authup/core-kit';\nimport type { ActorContext, EntityRepositoryFindManyResult, IEntityRepository } from '@authup/server-kit';\nimport { JunctionEntityService } from '@authup/server-kit';\nimport type { IIdentityPermissionProvider } from '../../identity/permission/types.ts';\nimport type { IIdentityProviderRoleMappingRepository, IIdentityProviderRoleMappingService } from './types.ts';\nimport { decodeQuery } from '../../query/index.ts';\nimport { identityProviderRoleMappingSchema } from './schema.ts';\n\nexport type IdentityProviderRoleMappingServiceContext = {\n repository: IIdentityProviderRoleMappingRepository;\n roleRepository: IEntityRepository<Role>;\n identityPermissionProvider: IIdentityPermissionProvider;\n};\n\nexport class IdentityProviderRoleMappingService extends JunctionEntityService implements IIdentityProviderRoleMappingService {\n protected readonly ownerRealmKey = 'providerRealmId';\n\n protected repository: IIdentityProviderRoleMappingRepository;\n\n protected roleRepository: IEntityRepository<Role>;\n\n protected identityPermissionProvider: IIdentityPermissionProvider;\n\n protected validator: IdentityProviderRoleMappingValidator;\n\n constructor(ctx: IdentityProviderRoleMappingServiceContext) {\n super();\n this.repository = ctx.repository;\n this.roleRepository = ctx.roleRepository;\n this.identityPermissionProvider = ctx.identityPermissionProvider;\n this.validator = new IdentityProviderRoleMappingValidator();\n }\n\n async getMany(\n query: Record<string, any>,\n actor: ActorContext,\n ): Promise<EntityRepositoryFindManyResult<IdentityProviderRoleMapping>> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.IDENTITY_PROVIDER_ROLE_READ,\n PermissionName.IDENTITY_PROVIDER_READ,\n PermissionName.IDENTITY_PROVIDER_UPDATE,\n PermissionName.IDENTITY_PROVIDER_DELETE,\n ],\n });\n\n return this.repository.findMany(await decodeQuery(query, { schema: identityProviderRoleMappingSchema, actor }));\n }\n\n async getOne(\n id: string,\n actor: ActorContext,\n ): Promise<IdentityProviderRoleMapping> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.IDENTITY_PROVIDER_ROLE_READ,\n PermissionName.IDENTITY_PROVIDER_READ,\n PermissionName.IDENTITY_PROVIDER_UPDATE,\n PermissionName.IDENTITY_PROVIDER_DELETE,\n ],\n });\n\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n return entity;\n }\n\n async create(\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<IdentityProviderRoleMapping> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.IDENTITY_PROVIDER_ROLE_CREATE });\n\n const validated = await this.validator.run(data, { group: ValidatorGroup.CREATE });\n\n await this.repository.validateJoinColumns(validated);\n\n const existing = await this.repository.findOneBy({\n providerId: validated.providerId,\n roleId: validated.roleId,\n });\n if (existing) {\n throw new EntityConflictError({ entity: 'identity-provider-role-mapping' });\n }\n\n if (validated.provider) {\n validated.providerRealmId = validated.provider.realmId;\n }\n\n if (validated.role) {\n validated.roleRealmId = validated.role.realmId;\n }\n\n if (\n validated.roleRealmId &&\n validated.providerRealmId &&\n validated.roleRealmId !== validated.providerRealmId\n ) {\n throw new ValidationError('It is not possible to map an identity provider to a role of another realm.');\n }\n\n if (validated.role && actor.identity) {\n const hasPermissions = await this.identityPermissionProvider.isSuperset(\n {\n type: actor.identity.type,\n id: actor.identity.data.id,\n },\n {\n type: 'role',\n id: validated.roleId,\n clientId: validated.role.clientId,\n },\n );\n if (!hasPermissions) {\n throw new PermissionError({ message: 'You don\\'t own the required permissions.' });\n }\n }\n\n // Stamp the owner (identity-provider) realm so the realmScope factor gates cross-realm writes.\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.IDENTITY_PROVIDER_ROLE_CREATE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: this.junctionAttributes(validated),\n [BuiltInPolicyType.REALM_MATCH]: this.junctionResourceRealm(validated),\n }),\n });\n\n let entity = this.repository.create(validated);\n entity = await this.repository.save(entity);\n\n return entity;\n }\n\n async update(\n id: string,\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<IdentityProviderRoleMapping> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.IDENTITY_PROVIDER_ROLE_UPDATE });\n\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n const validated = await this.validator.run(data, { group: ValidatorGroup.UPDATE });\n\n await this.repository.validateJoinColumns(validated);\n\n // `roleId` is immutable on update (CREATE-group only in the validator), so the conferred\n // role never changes here — only the attribute-matching criteria do. Still re-verify the\n // actor OWNS that role before letting it edit (e.g. broaden) the mapping, mirroring create()\n // and the permission-junction member gate (#3164): you may not modify a role-conferring\n // mapping for a role you no longer own.\n const role = await this.roleRepository.findOneById(entity.roleId);\n if (role && actor.identity) {\n const hasPermissions = await this.identityPermissionProvider.isSuperset(\n {\n type: actor.identity.type,\n id: actor.identity.data.id,\n },\n {\n type: 'role',\n id: role.id,\n clientId: role.clientId,\n },\n );\n if (!hasPermissions) {\n throw new PermissionError({ message: 'You don\\'t own the required permissions.' });\n }\n }\n\n const merged = this.repository.merge(entity, validated);\n\n // Stamp the owner (identity-provider) realm so the realmScope factor gates cross-realm writes.\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.IDENTITY_PROVIDER_ROLE_UPDATE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: this.junctionAttributes(merged),\n [BuiltInPolicyType.REALM_MATCH]: this.junctionResourceRealm(merged),\n }),\n });\n\n return this.repository.save(merged);\n }\n\n async delete(\n id: string,\n actor: ActorContext,\n ): Promise<IdentityProviderRoleMapping> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.IDENTITY_PROVIDER_ROLE_DELETE });\n\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n // Stamp the owner (identity-provider) realm so the realmScope factor gates cross-realm writes.\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.IDENTITY_PROVIDER_ROLE_DELETE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: this.junctionAttributes(entity),\n [BuiltInPolicyType.REALM_MATCH]: this.junctionResourceRealm(entity),\n }),\n });\n\n const { id: entityId } = entity;\n await this.repository.remove(entity);\n entity.id = entityId;\n\n return entity;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"service.mjs","names":["BuiltInPolicyType","PermissionError","definePolicyData","EntityConflictError","EntityNotFoundError","ValidationError","ValidatorGroup","IdentityProviderRoleMappingValidator","PermissionName","JunctionEntityService","decodeQuery","identityProviderRoleMappingSchema","IdentityProviderRoleMappingService","ownerRealmKey","repository","roleRepository","identityPermissionProvider","validator","ctx","getMany","query","actor","permissionEvaluator","preEvaluateOneOf","name","IDENTITY_PROVIDER_ROLE_READ","IDENTITY_PROVIDER_READ","IDENTITY_PROVIDER_UPDATE","IDENTITY_PROVIDER_DELETE","findMany","schema","getOne","id","entity","findOneBy","create","data","preEvaluate","IDENTITY_PROVIDER_ROLE_CREATE","validated","run","group","CREATE","validateJoinColumns","existing","providerId","roleId","provider","providerRealmId","realmId","role","roleRealmId","identity","hasPermissions","isSuperset","type","clientId","message","evaluate","ATTRIBUTES","junctionAttributes","REALM_MATCH","junctionResourceRealm","save","update","IDENTITY_PROVIDER_ROLE_UPDATE","UPDATE","findOneById","merged","merge","delete","IDENTITY_PROVIDER_ROLE_DELETE","entityId","remove"],"sources":["../../../../src/core/entities/identity-provider-role-mapping/service.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { BuiltInPolicyType, PermissionError, definePolicyData } from '@authup/access';\nimport { EntityConflictError, EntityNotFoundError, ValidationError } from '@authup/errors';\nimport { ValidatorGroup } from '@authup/kit';\nimport { IdentityProviderRoleMappingValidator, PermissionName } from '@authup/core-kit';\nimport type { IdentityProviderRoleMapping, Role } from '@authup/core-kit';\nimport type { ActorContext, EntityRepositoryFindManyResult, IEntityRepository } from '@authup/server-kit';\nimport { JunctionEntityService } from '@authup/server-kit';\nimport type { IIdentityPermissionProvider } from '../../identity/permission/types.ts';\nimport type { IIdentityProviderRoleMappingRepository, IIdentityProviderRoleMappingService } from './types.ts';\nimport { decodeQuery } from '../../query/index.ts';\nimport { identityProviderRoleMappingSchema } from './schema.ts';\n\nexport type IdentityProviderRoleMappingServiceContext = {\n repository: IIdentityProviderRoleMappingRepository;\n roleRepository: IEntityRepository<Role>;\n identityPermissionProvider: IIdentityPermissionProvider;\n};\n\nexport class IdentityProviderRoleMappingService extends JunctionEntityService implements IIdentityProviderRoleMappingService {\n protected readonly ownerRealmKey = 'providerRealmId';\n\n protected repository: IIdentityProviderRoleMappingRepository;\n\n protected roleRepository: IEntityRepository<Role>;\n\n protected identityPermissionProvider: IIdentityPermissionProvider;\n\n protected validator: IdentityProviderRoleMappingValidator;\n\n constructor(ctx: IdentityProviderRoleMappingServiceContext) {\n super();\n this.repository = ctx.repository;\n this.roleRepository = ctx.roleRepository;\n this.identityPermissionProvider = ctx.identityPermissionProvider;\n this.validator = new IdentityProviderRoleMappingValidator();\n }\n\n async getMany(\n query: Record<string, any>,\n actor: ActorContext,\n ): Promise<EntityRepositoryFindManyResult<IdentityProviderRoleMapping>> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.IDENTITY_PROVIDER_ROLE_READ,\n PermissionName.IDENTITY_PROVIDER_READ,\n PermissionName.IDENTITY_PROVIDER_UPDATE,\n PermissionName.IDENTITY_PROVIDER_DELETE,\n ],\n });\n\n return this.repository.findMany(await decodeQuery(query, { schema: identityProviderRoleMappingSchema, actor }));\n }\n\n async getOne(\n id: string,\n actor: ActorContext,\n ): Promise<IdentityProviderRoleMapping> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.IDENTITY_PROVIDER_ROLE_READ,\n PermissionName.IDENTITY_PROVIDER_READ,\n PermissionName.IDENTITY_PROVIDER_UPDATE,\n PermissionName.IDENTITY_PROVIDER_DELETE,\n ],\n });\n\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n return entity;\n }\n\n async create(\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<IdentityProviderRoleMapping> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.IDENTITY_PROVIDER_ROLE_CREATE });\n\n const validated = await this.validator.run(data, { group: ValidatorGroup.CREATE });\n\n await this.repository.validateJoinColumns(validated);\n\n const existing = await this.repository.findOneBy({\n providerId: validated.providerId,\n roleId: validated.roleId,\n });\n if (existing) {\n throw new EntityConflictError({ entity: 'identity-provider-role-mapping' });\n }\n\n if (validated.provider) {\n validated.providerRealmId = validated.provider.realmId;\n }\n\n if (validated.role) {\n validated.roleRealmId = validated.role.realmId;\n }\n\n if (\n validated.roleRealmId &&\n validated.providerRealmId &&\n validated.roleRealmId !== validated.providerRealmId\n ) {\n throw new ValidationError('It is not possible to map an identity provider to a role of another realm.');\n }\n\n if (validated.role && actor.identity) {\n const hasPermissions = await this.identityPermissionProvider.isSuperset(\n {\n type: actor.identity.type,\n id: actor.identity.data.id,\n },\n {\n type: 'role',\n id: validated.roleId,\n clientId: validated.role.clientId,\n },\n );\n if (!hasPermissions) {\n throw new PermissionError({ message: 'You don\\'t own the required permissions.' });\n }\n }\n\n // Stamp the owner (identity-provider) realm so the realmScope factor gates cross-realm writes.\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.IDENTITY_PROVIDER_ROLE_CREATE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: this.junctionAttributes(validated),\n [BuiltInPolicyType.REALM_MATCH]: this.junctionResourceRealm(validated),\n }),\n });\n\n let entity = this.repository.create(validated);\n entity = await this.repository.save(entity);\n\n return entity;\n }\n\n async update(\n id: string,\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<IdentityProviderRoleMapping> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.IDENTITY_PROVIDER_ROLE_UPDATE });\n\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n const validated = await this.validator.run(data, { group: ValidatorGroup.UPDATE });\n\n await this.repository.validateJoinColumns(validated);\n\n // `roleId` is immutable on update (CREATE-group only in the validator), so the conferred\n // role never changes here — only the attribute-matching criteria do. Still re-verify the\n // actor OWNS that role before letting it edit (e.g. broaden) the mapping, mirroring create()\n // and the permission-junction member gate (#3164): you may not modify a role-conferring\n // mapping for a role you no longer own.\n const role = await this.roleRepository.findOneById(entity.roleId);\n if (role && actor.identity) {\n const hasPermissions = await this.identityPermissionProvider.isSuperset(\n {\n type: actor.identity.type,\n id: actor.identity.data.id,\n },\n {\n type: 'role',\n id: role.id,\n clientId: role.clientId,\n },\n );\n if (!hasPermissions) {\n throw new PermissionError({ message: 'You don\\'t own the required permissions.' });\n }\n }\n\n const merged = this.repository.merge(entity, validated);\n\n // Stamp the owner (identity-provider) realm so the realmScope factor gates cross-realm writes.\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.IDENTITY_PROVIDER_ROLE_UPDATE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: this.junctionAttributes(merged),\n [BuiltInPolicyType.REALM_MATCH]: this.junctionResourceRealm(merged),\n }),\n });\n\n return this.repository.save(merged);\n }\n\n async delete(\n id: string,\n actor: ActorContext,\n ): Promise<IdentityProviderRoleMapping> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.IDENTITY_PROVIDER_ROLE_DELETE });\n\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n // Stamp the owner (identity-provider) realm so the realmScope factor gates cross-realm writes.\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.IDENTITY_PROVIDER_ROLE_DELETE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: this.junctionAttributes(entity),\n [BuiltInPolicyType.REALM_MATCH]: this.junctionResourceRealm(entity),\n }),\n });\n\n const { id: entityId } = entity;\n await this.repository.remove(entity);\n entity.id = entityId;\n\n return entity;\n }\n}\n"],"mappings":";;;;;;;;;;;;AAyBA,IAAaY,qCAAb,cAAwDH,sBAAAA;CACjCI,gBAAgB;CAEzBC;CAEAC;CAEAC;CAEAC;CAEV,YAAYC,KAAgD;EACxD,MAAK;EACL,KAAKJ,aAAaI,IAAIJ;EACtB,KAAKC,iBAAiBG,IAAIH;EAC1B,KAAKC,6BAA6BE,IAAIF;EACtC,KAAKC,YAAY,IAAIV,qCAAAA;CACzB;CAEA,MAAMY,QACFC,OACAC,OACoE;EACpE,MAAMA,MAAMC,oBAAoBC,iBAAiB,EAC7CC,MAAM;GACFhB,eAAeiB;GACfjB,eAAekB;GACflB,eAAemB;GACfnB,eAAeoB;EAClB,EACL,CAAA;EAEA,OAAO,KAAKd,WAAWe,SAAS,MAAMnB,YAAYU,OAAO;GAAEU,QAAQnB;GAAmCU;EAAM,CAAA,CAAA;CAChH;CAEA,MAAMU,OACFC,IACAX,OACoC;EACpC,MAAMA,MAAMC,oBAAoBC,iBAAiB,EAC7CC,MAAM;GACFhB,eAAeiB;GACfjB,eAAekB;GACflB,eAAemB;GACfnB,eAAeoB;EAClB,EACL,CAAA;EAEA,MAAMK,SAAS,MAAM,KAAKnB,WAAWoB,UAAU,EAAEF,GAAG,CAAA;EACpD,IAAI,CAACC,QACD,MAAM,IAAI7B,oBAAAA;EAGd,OAAO6B;CACX;CAEA,MAAME,OACFC,MACAf,OACoC;EACpC,MAAMA,MAAMC,oBAAoBe,YAAY,EAAEb,MAAMhB,eAAe8B,8BAA8B,CAAA;EAEjG,MAAMC,YAAY,MAAM,KAAKtB,UAAUuB,IAAIJ,MAAM,EAAEK,OAAOnC,eAAeoC,OAAO,CAAA;EAEhF,MAAM,KAAK5B,WAAW6B,oBAAoBJ,SAAAA;EAM1C,IAAIK,MAJmB,KAAK9B,WAAWoB,UAAU;GAC7CW,YAAYN,UAAUM;GACtBC,QAAQP,UAAUO;EACtB,CAAA,GAEI,MAAM,IAAI3C,oBAAoB,EAAE8B,QAAQ,iCAAiC,CAAA;EAG7E,IAAIM,UAAUQ,UACVR,UAAUS,kBAAkBT,UAAUQ,SAASE;EAGnD,IAAIV,UAAUW,MACVX,UAAUY,cAAcZ,UAAUW,KAAKD;EAG3C,IACIV,UAAUY,eACVZ,UAAUS,mBACVT,UAAUY,gBAAgBZ,UAAUS,iBAEpC,MAAM,IAAI3C,gBAAgB,4EAAA;EAG9B,IAAIkC,UAAUW,QAAQ7B,MAAM+B,UAYpB;OAAA,CAACC,MAXwB,KAAKrC,2BAA2BsC,WACzD;IACIC,MAAMlC,MAAM+B,SAASG;IACrBvB,IAAIX,MAAM+B,SAAShB,KAAKJ;GAC5B,GACA;IACIuB,MAAM;IACNvB,IAAIO,UAAUO;IACdU,UAAUjB,UAAUW,KAAKM;GAC7B,CAAA,GAGA,MAAM,IAAIvD,gBAAgB,EAAEwD,SAAS,0CAA2C,CAAA;EAAA;EAKxF,MAAMpC,MAAMC,oBAAoBoC,SAAS;GACrClC,MAAMhB,eAAe8B;GACrBF,MAAMlC,iBAAiB;KAClBF,kBAAkB2D,aAAa,KAAKC,mBAAmBrB,SAAAA;KACvDvC,kBAAkB6D,cAAc,KAAKC,sBAAsBvB,SAAAA;GAChE,CAAA;EACJ,CAAA;EAEA,IAAIN,SAAS,KAAKnB,WAAWqB,OAAOI,SAAAA;EACpCN,SAAS,MAAM,KAAKnB,WAAWiD,KAAK9B,MAAAA;EAEpC,OAAOA;CACX;CAEA,MAAM+B,OACFhC,IACAI,MACAf,OACoC;EACpC,MAAMA,MAAMC,oBAAoBe,YAAY,EAAEb,MAAMhB,eAAeyD,8BAA8B,CAAA;EAEjG,MAAMhC,SAAS,MAAM,KAAKnB,WAAWoB,UAAU,EAAEF,GAAG,CAAA;EACpD,IAAI,CAACC,QACD,MAAM,IAAI7B,oBAAAA;EAGd,MAAMmC,YAAY,MAAM,KAAKtB,UAAUuB,IAAIJ,MAAM,EAAEK,OAAOnC,eAAe4D,OAAO,CAAA;EAEhF,MAAM,KAAKpD,WAAW6B,oBAAoBJ,SAAAA;EAO1C,MAAMW,OAAO,MAAM,KAAKnC,eAAeoD,YAAYlC,OAAOa,MAAM;EAChE,IAAII,QAAQ7B,MAAM+B,UAYV;OAAA,CAACC,MAXwB,KAAKrC,2BAA2BsC,WACzD;IACIC,MAAMlC,MAAM+B,SAASG;IACrBvB,IAAIX,MAAM+B,SAAShB,KAAKJ;GAC5B,GACA;IACIuB,MAAM;IACNvB,IAAIkB,KAAKlB;IACTwB,UAAUN,KAAKM;GACnB,CAAA,GAGA,MAAM,IAAIvD,gBAAgB,EAAEwD,SAAS,0CAA2C,CAAA;EAAA;EAIxF,MAAMW,SAAS,KAAKtD,WAAWuD,MAAMpC,QAAQM,SAAAA;EAG7C,MAAMlB,MAAMC,oBAAoBoC,SAAS;GACrClC,MAAMhB,eAAeyD;GACrB7B,MAAMlC,iBAAiB;KAClBF,kBAAkB2D,aAAa,KAAKC,mBAAmBQ,MAAAA;KACvDpE,kBAAkB6D,cAAc,KAAKC,sBAAsBM,MAAAA;GAChE,CAAA;EACJ,CAAA;EAEA,OAAO,KAAKtD,WAAWiD,KAAKK,MAAAA;CAChC;CAEA,MAAME,OACFtC,IACAX,OACoC;EACpC,MAAMA,MAAMC,oBAAoBe,YAAY,EAAEb,MAAMhB,eAAe+D,8BAA8B,CAAA;EAEjG,MAAMtC,SAAS,MAAM,KAAKnB,WAAWoB,UAAU,EAAEF,GAAG,CAAA;EACpD,IAAI,CAACC,QACD,MAAM,IAAI7B,oBAAAA;EAId,MAAMiB,MAAMC,oBAAoBoC,SAAS;GACrClC,MAAMhB,eAAe+D;GACrBnC,MAAMlC,iBAAiB;KAClBF,kBAAkB2D,aAAa,KAAKC,mBAAmB3B,MAAAA;KACvDjC,kBAAkB6D,cAAc,KAAKC,sBAAsB7B,MAAAA;GAChE,CAAA;EACJ,CAAA;EAEA,MAAM,EAAED,IAAIwC,aAAavC;EACzB,MAAM,KAAKnB,WAAW2D,OAAOxC,MAAAA;EAC7BA,OAAOD,KAAKwC;EAEZ,OAAOvC;CACX;AACJ"}
@@ -1 +1 @@
1
- {"version":3,"file":"schema.mjs","names":["defineSchema","EntityType","createRelationsReadGate","schemaMapping","realm","REALM","keySchema","name","KEY","fields","default","allowed","filters","relations","validate","sort","pagination","maxLimit"],"sources":["../../../../src/core/entities/key/schema.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { defineSchema } from '@rapiq/core';\nimport type { Key } from '@authup/core-kit';\nimport { EntityType } from '@authup/core-kit';\nimport { createRelationsReadGate } from '../../query/relations.ts';\n\nconst schemaMapping = { realm: EntityType.REALM };\n\nexport const keySchema = defineSchema<Key>({\n name: EntityType.KEY,\n fields: {\n default: [\n 'id',\n 'name',\n 'type',\n 'use',\n 'priority',\n 'status',\n 'signatureAlgorithm',\n 'realmId',\n 'createdAt',\n 'updatedAt',\n ],\n allowed: ['encryptionKey', 'certificate'],\n },\n filters: {\n allowed: [\n 'id',\n 'name',\n 'type',\n 'use',\n 'status',\n 'realmId',\n ], \n },\n relations: { allowed: ['realm'], validate: createRelationsReadGate(schemaMapping) },\n sort: {\n allowed: [\n 'id',\n 'name',\n 'priority',\n 'use',\n 'status',\n 'createdAt',\n 'updatedAt',\n ],\n },\n pagination: { maxLimit: 50 },\n schemaMapping,\n});\n"],"mappings":";;;;;;;AAYA,MAAMG,gBAAgB,EAAEC,OAAOH,WAAWI,MAAM;AAEhD,MAAaC,YAAYN,aAAkB;CACvCO,MAAMN,WAAWO;CACjBC,QAAQ;EACJC,SAAS;GACL;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;;EAEJC,SAAS,CAAC,iBAAiB,aAAA;CAC/B;CACAC,SAAS,EACLD,SAAS;EACL;EACA;EACA;EACA;EACA;EACA;GAER;CACAE,WAAW;EAAEF,SAAS,CAAC,OAAA;EAAUG,UAAUZ,wBAAwBC,aAAAA;CAAe;CAClFY,MAAM,EACFJ,SAAS;EACL;EACA;EACA;EACA;EACA;EACA;EACA;GAER;CACAK,YAAY,EAAEC,UAAU,GAAG;CAC3Bd;AACJ,CAAA"}
1
+ {"version":3,"file":"schema.mjs","names":["defineSchema","EntityType","createRelationsReadGate","schemaMapping","realm","REALM","keySchema","name","KEY","fields","default","allowed","filters","relations","validate","sort","pagination","maxLimit"],"sources":["../../../../src/core/entities/key/schema.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { defineSchema } from '@rapiq/core';\nimport type { Key } from '@authup/core-kit';\nimport { EntityType } from '@authup/core-kit';\nimport { createRelationsReadGate } from '../../query/relations.ts';\n\nconst schemaMapping = { realm: EntityType.REALM };\n\nexport const keySchema = defineSchema<Key>({\n name: EntityType.KEY,\n fields: {\n default: [\n 'id',\n 'name',\n 'type',\n 'use',\n 'priority',\n 'status',\n 'signatureAlgorithm',\n 'realmId',\n 'createdAt',\n 'updatedAt',\n ],\n allowed: ['encryptionKey', 'certificate'],\n },\n filters: {\n allowed: [\n 'id',\n 'name',\n 'type',\n 'use',\n 'status',\n 'realmId',\n ], \n },\n relations: { allowed: ['realm'], validate: createRelationsReadGate(schemaMapping) },\n sort: {\n allowed: [\n 'id',\n 'name',\n 'priority',\n 'use',\n 'status',\n 'createdAt',\n 'updatedAt',\n ],\n },\n pagination: { maxLimit: 50 },\n schemaMapping,\n});\n"],"mappings":";;;;;;;AAYA,MAAMG,gBAAgB,EAAEC,OAAOH,WAAWI,MAAM;AAEhD,MAAaC,YAAYN,aAAkB;CACvCO,MAAMN,WAAWO;CACjBC,QAAQ;EACJC,SAAS;GACL;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACH;EACDC,SAAS,CAAC,iBAAiB,aAAc;CAC7C;CACAC,SAAS,EACLD,SAAS;EACL;EACA;EACA;EACA;EACA;EACA;CACH,EACL;CACAE,WAAW;EAAEF,SAAS,CAAC,OAAQ;EAAEG,UAAUZ,wBAAwBC,aAAAA;CAAe;CAClFY,MAAM,EACFJ,SAAS;EACL;EACA;EACA;EACA;EACA;EACA;EACA;CACH,EACL;CACAK,YAAY,EAAEC,UAAU,GAAG;CAC3Bd;AACJ,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"service.mjs","names":["BuiltInPolicyType","definePolicyData","eq","inArray","EntityConflictError","EntityNotFoundError","ValidationError","isError","isRawError","EntityType","EventName","EventScope","KeyStatus","KeyValidator","PermissionName","ValidatorGroup","arrayBufferToBase64","base64ToArrayBuffer","createNanoID","AbstractEntityService","AsymmetricKey","createAsymmetricKeyPair","JWKType","JWKUse","JWTAlgorithm","getRandomValues","buildEntityDiff","assertCertificateMatchesKey","isWrappedKeyMaterial","parseCertificateChain","appendQueryConditions","decodeQuery","keySchema","PERMISSION_NAMES","KEY_READ","KEY_UPDATE","KEY_DELETE","KeyService","repository","validator","eventService","requestContext","ctx","getMany","query","actor","options","permissionEvaluator","preEvaluateOneOf","name","parsed","schema","realmId","compiled","compile","verdict","condition","data","entities","meta","findMany","entity","decryptionKey","total","evaluateOneOf","ATTRIBUTES","resourceRealmMatch","push","getOne","idOrName","findOneByIdOrName","create","preEvaluate","KEY_CREATE","validated","run","group","CREATE","use","validateJoinColumns","identity","actorRealmId","getActorRealmId","evaluate","checkUniqueness","priority","highest","findHighestPriority","status","ACTIVE","certificate","SIGNATURE","material","importMaterial","generateMaterial","encryptionKey","chain","e","message","type","signatureAlgorithm","save","recordEvent","CREATED","update","UPDATE","previous","pickAuditFields","merge","diff","UPDATED","Object","keys","length","delete","id","findOneBy","ENCRYPTION","force","references","countBlobReferences","entityId","remove","forcedCryptoShred","DELETED","undefined","record","scope","ENTITY","refType","KEY","refId","actorType","actorId","actorName","requestPath","requestMethod","requestIpAddress","requestUserAgent","raw","Uint8Array","OCT","buffer","algorithm","RS256","buildAsymmetricOptions","keyPair","startsWith","EC","RSA","privateKey","toBase64","publicKey","trim","normalizeMaterial","byteLength","privateJwk","publicJwk","fromBase64","format","key","toJWK","components","mismatch","some","component","test","buildImportOptionsForJWTAlgorithm","value","includes","replace"],"sources":["../../../../src/core/entities/key/service.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { BuiltInPolicyType, definePolicyData } from '@authup/access';\nimport { eq, inArray } from '@rapiq/core';\nimport {\n EntityConflictError,\n EntityNotFoundError,\n ValidationError,\n isError as isRawError,\n} from '@authup/errors';\nimport type { Key } from '@authup/core-kit';\nimport {\n EntityType,\n EventName,\n EventScope,\n KeyStatus,\n KeyValidator,\n PermissionName,\n} from '@authup/core-kit';\nimport {\n ValidatorGroup,\n arrayBufferToBase64,\n base64ToArrayBuffer,\n createNanoID,\n} from '@authup/kit';\nimport type { ActorContext, EntityRepositoryFindManyResult } from '@authup/server-kit';\nimport { AbstractEntityService, AsymmetricKey, createAsymmetricKeyPair } from '@authup/server-kit';\nimport { JWKType, JWKUse, JWTAlgorithm } from '@authup/specs';\nimport { getRandomValues } from 'uncrypto';\nimport { buildEntityDiff } from '../event/index.ts';\nimport type { EventRequestContext, IEventService } from '../event/index.ts';\nimport { assertCertificateMatchesKey, isWrappedKeyMaterial, parseCertificateChain } from '../../key/index.ts';\nimport type {\n IKeyRepository, \n IKeyService, \n KeyDeleteOptions, \n KeyServiceReadOptions,\n} from './types.ts';\nimport { appendQueryConditions, decodeQuery } from '../../query/index.ts';\nimport { keySchema } from './schema.ts';\n\nexport type KeyServiceContext = {\n repository: IKeyRepository;\n eventService?: IEventService;\n requestContext?: () => EventRequestContext | undefined;\n};\n\nconst PERMISSION_NAMES = [\n PermissionName.KEY_READ,\n PermissionName.KEY_UPDATE,\n PermissionName.KEY_DELETE,\n];\n\nexport class KeyService extends AbstractEntityService implements IKeyService {\n protected repository: IKeyRepository;\n\n protected validator: KeyValidator;\n\n protected eventService?: IEventService;\n\n protected requestContext?: () => EventRequestContext | undefined;\n\n constructor(ctx: KeyServiceContext) {\n super();\n this.repository = ctx.repository;\n this.validator = new KeyValidator();\n this.eventService = ctx.eventService;\n this.requestContext = ctx.requestContext;\n }\n\n async getMany(\n query: Record<string, any>,\n actor: ActorContext,\n options: KeyServiceReadOptions = {},\n ): Promise<EntityRepositoryFindManyResult<Key>> {\n await actor.permissionEvaluator.preEvaluateOneOf({ name: PERMISSION_NAMES });\n\n let parsed = await decodeQuery(query, { schema: keySchema, actor });\n if (options.realmId) {\n parsed = appendQueryConditions(parsed, eq('realmId', options.realmId));\n }\n\n // Compile the read permissions against the knowns (actor identity) into a\n // row condition (issue #3286 phase 3): the authorization runs as WHERE, so\n // pagination and totals stay exact. Non-expressible policies fall back to\n // the per-row post-evaluation below.\n const compiled = await actor.permissionEvaluator.compile({ name: PERMISSION_NAMES });\n if (compiled.verdict === 'deny') {\n // no row can pass — a constant-false condition keeps the meta shape\n parsed = appendQueryConditions(parsed, inArray('id', []));\n } else if (compiled.verdict === 'conditional') {\n parsed = appendQueryConditions(parsed, compiled.condition);\n }\n\n const { data: entities, meta } = await this.repository.findMany(parsed);\n\n if (compiled.verdict !== 'post') {\n for (const entity of entities) {\n // Belt-and-braces: the read projection never selects private\n // material, but null it explicitly so no future adapter change\n // can leak it onto a read surface (cf. authentik CVE-2024-42490).\n entity.decryptionKey = null;\n }\n\n return { data: entities, meta };\n }\n\n const data: Key[] = [];\n let { total } = meta;\n\n for (const entity of entities) {\n try {\n await actor.permissionEvaluator.evaluateOneOf({\n name: PERMISSION_NAMES,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: entity,\n ...this.resourceRealmMatch(entity),\n }),\n });\n entity.decryptionKey = null;\n data.push(entity);\n } catch {\n total -= 1;\n }\n }\n\n return {\n data,\n meta: {\n ...meta,\n total,\n },\n };\n }\n\n async getOne(\n idOrName: string,\n actor: ActorContext,\n realmId?: string,\n ): Promise<Key> {\n await actor.permissionEvaluator.preEvaluateOneOf({ name: PERMISSION_NAMES });\n\n const entity = await this.repository.findOneByIdOrName(idOrName, realmId);\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n await actor.permissionEvaluator.evaluateOneOf({\n name: PERMISSION_NAMES,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: entity,\n ...this.resourceRealmMatch(entity),\n }),\n });\n\n // Belt-and-braces null of private material (see getMany).\n entity.decryptionKey = null;\n\n return entity;\n }\n\n async create(\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<Key> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.KEY_CREATE });\n\n const validated = await this.validator.run(data, { group: ValidatorGroup.CREATE });\n const { use } = validated;\n if (!use) {\n throw new ValidationError('A key use must be specified.');\n }\n\n await this.repository.validateJoinColumns(validated);\n\n if (!validated.realmId && actor.identity) {\n const actorRealmId = this.getActorRealmId(actor);\n if (actorRealmId) {\n validated.realmId = actorRealmId;\n }\n }\n\n // keys are realm-bound infrastructure — no global (null realm) keys\n // via the API.\n if (!validated.realmId) {\n throw new ValidationError('A realm must be specified.');\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.KEY_CREATE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: validated,\n ...this.resourceRealmMatch(validated),\n }),\n });\n\n if (!validated.name) {\n validated.name = `${use}-${createNanoID(10)}`;\n }\n\n await this.repository.checkUniqueness(validated);\n\n if (typeof validated.priority !== 'number') {\n const highest = await this.repository.findHighestPriority(validated.realmId, use);\n // generate doubles as rotate: a new key outranks the current one.\n validated.priority = typeof highest === 'number' ? highest + 1 : 0;\n }\n\n if (!validated.status) {\n validated.status = KeyStatus.ACTIVE;\n }\n\n const certificate = typeof validated.certificate === 'string' ? validated.certificate : null;\n if (certificate && (!validated.decryptionKey || use !== JWKUse.SIGNATURE)) {\n throw new ValidationError('A certificate requires imported signature key material.');\n }\n\n const material = validated.decryptionKey ?\n await this.importMaterial(validated, use) :\n await this.generateMaterial(validated, use);\n\n if (certificate) {\n if (!material.encryptionKey) {\n throw new ValidationError('A certificate requires imported signature key material.');\n }\n\n try {\n const chain = parseCertificateChain(certificate);\n assertCertificateMatchesKey(chain, material.encryptionKey);\n } catch (e) {\n throw new ValidationError(\n isRawError(e) ?\n e.message :\n 'The certificate could not be matched against the imported key material.',\n );\n }\n }\n\n let entity = this.repository.create({\n ...validated,\n type: material.type,\n signatureAlgorithm: material.signatureAlgorithm,\n decryptionKey: material.decryptionKey,\n encryptionKey: material.encryptionKey,\n });\n\n entity = await this.repository.save(entity);\n\n // private material never leaves the server — the response carries\n // metadata + public part only (authentik CVE-2024-42490).\n entity.decryptionKey = null;\n\n await this.recordEvent(EventName.CREATED, entity, actor);\n\n return entity;\n }\n\n async update(\n idOrName: string,\n data: Record<string, any>,\n actor: ActorContext,\n realmId?: string,\n ): Promise<Key> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.KEY_UPDATE });\n\n let entity = await this.repository.findOneByIdOrName(idOrName, realmId);\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n // only name / priority / status are mounted for UPDATE — material,\n // use, type and realm are immutable.\n const validated = await this.validator.run(data, { group: ValidatorGroup.UPDATE });\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.KEY_UPDATE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: {\n ...entity,\n ...validated,\n },\n ...this.resourceRealmMatch(entity),\n }),\n });\n\n if (validated.name && validated.name !== entity.name) {\n await this.repository.checkUniqueness({\n name: validated.name,\n realmId: entity.realmId,\n }, entity);\n }\n\n const previous = this.pickAuditFields(entity);\n\n entity = this.repository.merge(entity, validated);\n await this.repository.save(entity);\n\n entity.decryptionKey = null;\n\n const diff = buildEntityDiff(this.pickAuditFields(entity), previous);\n await this.recordEvent(EventName.UPDATED, entity, actor, { ...(Object.keys(diff).length > 0 ? { diff } : {}) });\n\n return entity;\n }\n\n async delete(\n id: string,\n actor: ActorContext,\n options: KeyDeleteOptions = {},\n ): Promise<Key> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.KEY_DELETE });\n\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.KEY_DELETE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: entity,\n ...this.resourceRealmMatch(entity),\n }),\n });\n\n if (entity.use === JWKUse.ENCRYPTION && !options.force) {\n const references = await this.repository.countBlobReferences(entity.id);\n if (references > 0) {\n throw new EntityConflictError({\n message: `The encryption key is still referenced by ${references} encrypted secret(s) — ` +\n 'deleting it makes them unrecoverable. Repeat with force to crypto-shred them.',\n data: { references },\n });\n }\n }\n\n const { id: entityId } = entity;\n await this.repository.remove(entity);\n entity.id = entityId;\n entity.decryptionKey = null;\n\n // force only carries crypto-shred semantics for encryption keys — a\n // sig-key delete with a stray force flag must not read as a shred.\n const forcedCryptoShred = entity.use === JWKUse.ENCRYPTION && !!options.force;\n await this.recordEvent(EventName.DELETED, entity, actor, { ...(forcedCryptoShred ? { force: true } : {}) });\n\n return entity;\n }\n\n // ------------------------------------------------------------------\n\n /**\n * Metadata-only audit trail for key lifecycle operations (issue #3269) —\n * keys deliberately have no entity subscriber (private material must stay\n * off the realtime/audit bus), so the security-relevant mutations are\n * recorded explicitly. The payload never carries key material.\n */\n protected async recordEvent(\n name: `${EventName}`,\n entity: Key,\n actor: ActorContext,\n data: Record<string, any> = {},\n ): Promise<void> {\n const requestContext = this.requestContext ?\n this.requestContext() :\n undefined;\n\n await this.eventService?.record({\n scope: EventScope.ENTITY,\n name,\n refType: EntityType.KEY,\n refId: entity.id,\n realmId: entity.realmId ?? null,\n actorType: actor.identity?.type ?? null,\n actorId: actor.identity?.data.id ?? null,\n actorName: actor.identity?.data.name ?? null,\n requestPath: requestContext?.requestPath ?? null,\n requestMethod: requestContext?.requestMethod ?? null,\n requestIpAddress: requestContext?.requestIpAddress ?? null,\n requestUserAgent: requestContext?.requestUserAgent ?? null,\n data: {\n name: entity.name,\n use: entity.use,\n status: entity.status,\n ...data,\n },\n });\n }\n\n protected pickAuditFields(entity: Key): Record<string, any> {\n return {\n name: entity.name,\n priority: entity.priority,\n status: entity.status,\n };\n }\n\n protected async generateMaterial(\n validated: Partial<Key>,\n use: `${JWKUse}`,\n ) : Promise<{\n type: `${JWKType}`,\n signatureAlgorithm: `${JWTAlgorithm}` | null,\n decryptionKey: string,\n encryptionKey: string | null,\n }> {\n if (use === JWKUse.ENCRYPTION) {\n if (validated.signatureAlgorithm) {\n throw new ValidationError('An encryption key can not carry a signature algorithm.');\n }\n\n const raw = new Uint8Array(32);\n getRandomValues(raw);\n\n return {\n type: JWKType.OCT,\n signatureAlgorithm: null,\n decryptionKey: arrayBufferToBase64(raw.buffer),\n encryptionKey: null,\n };\n }\n\n const algorithm = validated.signatureAlgorithm ?? JWTAlgorithm.RS256;\n const options = this.buildAsymmetricOptions(algorithm);\n\n const keyPair = await createAsymmetricKeyPair(options);\n\n return {\n type: algorithm.startsWith('ES') ? JWKType.EC : JWKType.RSA,\n signatureAlgorithm: algorithm,\n decryptionKey: await new AsymmetricKey(keyPair.privateKey).toBase64(),\n encryptionKey: await new AsymmetricKey(keyPair.publicKey).toBase64(),\n };\n }\n\n protected async importMaterial(\n validated: Partial<Key>,\n use: `${JWKUse}`,\n ) : Promise<{\n type: `${JWKType}`,\n signatureAlgorithm: `${JWTAlgorithm}` | null,\n decryptionKey: string,\n encryptionKey: string | null,\n }> {\n if (!validated.decryptionKey) {\n throw new ValidationError('Importing key material requires its private part (decryptionKey).');\n }\n\n // Reject material masquerading as an at-rest KEK-wrapped blob — it\n // would be treated as wrapped on the next read (and, with a KEK,\n // fail GCM authentication).\n if (isWrappedKeyMaterial(validated.decryptionKey.trim())) {\n throw new ValidationError('The imported key material is not valid.');\n }\n\n const decryptionKey = this.normalizeMaterial(validated.decryptionKey);\n\n if (use === JWKUse.ENCRYPTION) {\n if (validated.signatureAlgorithm) {\n throw new ValidationError('An encryption key can not carry a signature algorithm.');\n }\n\n if (validated.encryptionKey) {\n throw new ValidationError('An encryption key holds no public part.');\n }\n\n let byteLength : number;\n try {\n byteLength = base64ToArrayBuffer(decryptionKey).byteLength;\n } catch {\n throw new ValidationError('The key material is not valid base64.');\n }\n\n if (byteLength !== 32) {\n throw new ValidationError('The key material must be 32 base64-encoded bytes.');\n }\n\n return {\n type: JWKType.OCT,\n signatureAlgorithm: null,\n decryptionKey,\n encryptionKey: null,\n };\n }\n\n if (!validated.encryptionKey) {\n throw new ValidationError('Importing a signature key requires its public part (encryptionKey, SPKI).');\n }\n\n const encryptionKey = this.normalizeMaterial(validated.encryptionKey);\n const algorithm = validated.signatureAlgorithm ?? JWTAlgorithm.RS256;\n const options = this.buildAsymmetricOptions(algorithm);\n\n let privateJwk : JsonWebKey;\n let publicJwk : JsonWebKey;\n\n try {\n const privateKey = await AsymmetricKey.fromBase64({\n format: 'pkcs8',\n key: decryptionKey,\n options,\n });\n const publicKey = await AsymmetricKey.fromBase64({\n format: 'spki',\n key: encryptionKey,\n options,\n });\n\n privateJwk = await privateKey.toJWK();\n publicJwk = await publicKey.toJWK();\n } catch {\n throw new ValidationError(`The key material could not be imported for ${algorithm}.`);\n }\n\n // the public components (RSA: n/e, EC: crv/x/y) must agree — a\n // private key paired with a foreign public part would publish a\n // wrong JWKS entry and break verification of every token it signs.\n const components : (keyof JsonWebKey)[] = ['kty', 'n', 'e', 'crv', 'x', 'y'];\n const mismatch = components.some(\n (component) => publicJwk[component] !== undefined &&\n publicJwk[component] !== privateJwk[component],\n );\n if (mismatch) {\n throw new ValidationError('The private and public key material do not form a pair.');\n }\n\n return {\n type: algorithm.startsWith('ES') ? JWKType.EC : JWKType.RSA,\n signatureAlgorithm: algorithm,\n decryptionKey,\n encryptionKey,\n };\n }\n\n protected buildAsymmetricOptions(algorithm: `${JWTAlgorithm}`) {\n if (!/^(RS|ES)(256|384|512)$/.test(algorithm)) {\n throw new ValidationError(`The signature algorithm ${algorithm} is not supported for stored keys.`);\n }\n\n return AsymmetricKey.buildImportOptionsForJWTAlgorithm(algorithm);\n }\n\n protected normalizeMaterial(value: string) : string {\n if (value.includes('-----BEGIN')) {\n // PEM body IS base64 DER — strip armor + whitespace.\n return value\n .replace(/-----(BEGIN|END)[^-]+-----/g, '')\n .replace(/\\s+/g, '');\n }\n\n return value.trim();\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"service.mjs","names":["BuiltInPolicyType","definePolicyData","eq","inArray","EntityConflictError","EntityNotFoundError","ValidationError","isError","isRawError","EntityType","EventName","EventScope","KeyStatus","KeyValidator","PermissionName","ValidatorGroup","arrayBufferToBase64","base64ToArrayBuffer","createNanoID","AbstractEntityService","AsymmetricKey","createAsymmetricKeyPair","JWKType","JWKUse","JWTAlgorithm","getRandomValues","buildEntityDiff","assertCertificateMatchesKey","isWrappedKeyMaterial","parseCertificateChain","appendQueryConditions","decodeQuery","keySchema","PERMISSION_NAMES","KEY_READ","KEY_UPDATE","KEY_DELETE","KeyService","repository","validator","eventService","requestContext","ctx","getMany","query","actor","options","permissionEvaluator","preEvaluateOneOf","name","parsed","schema","realmId","compiled","compile","verdict","condition","data","entities","meta","findMany","entity","decryptionKey","total","evaluateOneOf","ATTRIBUTES","resourceRealmMatch","push","getOne","idOrName","findOneByIdOrName","create","preEvaluate","KEY_CREATE","validated","run","group","CREATE","use","validateJoinColumns","identity","actorRealmId","getActorRealmId","evaluate","checkUniqueness","priority","highest","findHighestPriority","status","ACTIVE","certificate","SIGNATURE","material","importMaterial","generateMaterial","encryptionKey","chain","e","message","type","signatureAlgorithm","save","recordEvent","CREATED","update","UPDATE","previous","pickAuditFields","merge","diff","UPDATED","Object","keys","length","delete","id","findOneBy","ENCRYPTION","force","references","countBlobReferences","entityId","remove","forcedCryptoShred","DELETED","undefined","record","scope","ENTITY","refType","KEY","refId","actorType","actorId","actorName","requestPath","requestMethod","requestIpAddress","requestUserAgent","raw","Uint8Array","OCT","buffer","algorithm","RS256","buildAsymmetricOptions","keyPair","startsWith","EC","RSA","privateKey","toBase64","publicKey","trim","normalizeMaterial","byteLength","privateJwk","publicJwk","fromBase64","format","key","toJWK","components","mismatch","some","component","test","buildImportOptionsForJWTAlgorithm","value","includes","replace"],"sources":["../../../../src/core/entities/key/service.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { BuiltInPolicyType, definePolicyData } from '@authup/access';\nimport { eq, inArray } from '@rapiq/core';\nimport {\n EntityConflictError,\n EntityNotFoundError,\n ValidationError,\n isError as isRawError,\n} from '@authup/errors';\nimport type { Key } from '@authup/core-kit';\nimport {\n EntityType,\n EventName,\n EventScope,\n KeyStatus,\n KeyValidator,\n PermissionName,\n} from '@authup/core-kit';\nimport {\n ValidatorGroup,\n arrayBufferToBase64,\n base64ToArrayBuffer,\n createNanoID,\n} from '@authup/kit';\nimport type { ActorContext, EntityRepositoryFindManyResult } from '@authup/server-kit';\nimport { AbstractEntityService, AsymmetricKey, createAsymmetricKeyPair } from '@authup/server-kit';\nimport { JWKType, JWKUse, JWTAlgorithm } from '@authup/specs';\nimport { getRandomValues } from 'uncrypto';\nimport { buildEntityDiff } from '../event/index.ts';\nimport type { EventRequestContext, IEventService } from '../event/index.ts';\nimport { assertCertificateMatchesKey, isWrappedKeyMaterial, parseCertificateChain } from '../../key/index.ts';\nimport type {\n IKeyRepository, \n IKeyService, \n KeyDeleteOptions, \n KeyServiceReadOptions,\n} from './types.ts';\nimport { appendQueryConditions, decodeQuery } from '../../query/index.ts';\nimport { keySchema } from './schema.ts';\n\nexport type KeyServiceContext = {\n repository: IKeyRepository;\n eventService?: IEventService;\n requestContext?: () => EventRequestContext | undefined;\n};\n\nconst PERMISSION_NAMES = [\n PermissionName.KEY_READ,\n PermissionName.KEY_UPDATE,\n PermissionName.KEY_DELETE,\n];\n\nexport class KeyService extends AbstractEntityService implements IKeyService {\n protected repository: IKeyRepository;\n\n protected validator: KeyValidator;\n\n protected eventService?: IEventService;\n\n protected requestContext?: () => EventRequestContext | undefined;\n\n constructor(ctx: KeyServiceContext) {\n super();\n this.repository = ctx.repository;\n this.validator = new KeyValidator();\n this.eventService = ctx.eventService;\n this.requestContext = ctx.requestContext;\n }\n\n async getMany(\n query: Record<string, any>,\n actor: ActorContext,\n options: KeyServiceReadOptions = {},\n ): Promise<EntityRepositoryFindManyResult<Key>> {\n await actor.permissionEvaluator.preEvaluateOneOf({ name: PERMISSION_NAMES });\n\n let parsed = await decodeQuery(query, { schema: keySchema, actor });\n if (options.realmId) {\n parsed = appendQueryConditions(parsed, eq('realmId', options.realmId));\n }\n\n // Compile the read permissions against the knowns (actor identity) into a\n // row condition (issue #3286 phase 3): the authorization runs as WHERE, so\n // pagination and totals stay exact. Non-expressible policies fall back to\n // the per-row post-evaluation below.\n const compiled = await actor.permissionEvaluator.compile({ name: PERMISSION_NAMES });\n if (compiled.verdict === 'deny') {\n // no row can pass — a constant-false condition keeps the meta shape\n parsed = appendQueryConditions(parsed, inArray('id', []));\n } else if (compiled.verdict === 'conditional') {\n parsed = appendQueryConditions(parsed, compiled.condition);\n }\n\n const { data: entities, meta } = await this.repository.findMany(parsed);\n\n if (compiled.verdict !== 'post') {\n for (const entity of entities) {\n // Belt-and-braces: the read projection never selects private\n // material, but null it explicitly so no future adapter change\n // can leak it onto a read surface (cf. authentik CVE-2024-42490).\n entity.decryptionKey = null;\n }\n\n return { data: entities, meta };\n }\n\n const data: Key[] = [];\n let { total } = meta;\n\n for (const entity of entities) {\n try {\n await actor.permissionEvaluator.evaluateOneOf({\n name: PERMISSION_NAMES,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: entity,\n ...this.resourceRealmMatch(entity),\n }),\n });\n entity.decryptionKey = null;\n data.push(entity);\n } catch {\n total -= 1;\n }\n }\n\n return {\n data,\n meta: {\n ...meta,\n total,\n },\n };\n }\n\n async getOne(\n idOrName: string,\n actor: ActorContext,\n realmId?: string,\n ): Promise<Key> {\n await actor.permissionEvaluator.preEvaluateOneOf({ name: PERMISSION_NAMES });\n\n const entity = await this.repository.findOneByIdOrName(idOrName, realmId);\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n await actor.permissionEvaluator.evaluateOneOf({\n name: PERMISSION_NAMES,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: entity,\n ...this.resourceRealmMatch(entity),\n }),\n });\n\n // Belt-and-braces null of private material (see getMany).\n entity.decryptionKey = null;\n\n return entity;\n }\n\n async create(\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<Key> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.KEY_CREATE });\n\n const validated = await this.validator.run(data, { group: ValidatorGroup.CREATE });\n const { use } = validated;\n if (!use) {\n throw new ValidationError('A key use must be specified.');\n }\n\n await this.repository.validateJoinColumns(validated);\n\n if (!validated.realmId && actor.identity) {\n const actorRealmId = this.getActorRealmId(actor);\n if (actorRealmId) {\n validated.realmId = actorRealmId;\n }\n }\n\n // keys are realm-bound infrastructure — no global (null realm) keys\n // via the API.\n if (!validated.realmId) {\n throw new ValidationError('A realm must be specified.');\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.KEY_CREATE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: validated,\n ...this.resourceRealmMatch(validated),\n }),\n });\n\n if (!validated.name) {\n validated.name = `${use}-${createNanoID(10)}`;\n }\n\n await this.repository.checkUniqueness(validated);\n\n if (typeof validated.priority !== 'number') {\n const highest = await this.repository.findHighestPriority(validated.realmId, use);\n // generate doubles as rotate: a new key outranks the current one.\n validated.priority = typeof highest === 'number' ? highest + 1 : 0;\n }\n\n if (!validated.status) {\n validated.status = KeyStatus.ACTIVE;\n }\n\n const certificate = typeof validated.certificate === 'string' ? validated.certificate : null;\n if (certificate && (!validated.decryptionKey || use !== JWKUse.SIGNATURE)) {\n throw new ValidationError('A certificate requires imported signature key material.');\n }\n\n const material = validated.decryptionKey ?\n await this.importMaterial(validated, use) :\n await this.generateMaterial(validated, use);\n\n if (certificate) {\n if (!material.encryptionKey) {\n throw new ValidationError('A certificate requires imported signature key material.');\n }\n\n try {\n const chain = parseCertificateChain(certificate);\n assertCertificateMatchesKey(chain, material.encryptionKey);\n } catch (e) {\n throw new ValidationError(\n isRawError(e) ?\n e.message :\n 'The certificate could not be matched against the imported key material.',\n );\n }\n }\n\n let entity = this.repository.create({\n ...validated,\n type: material.type,\n signatureAlgorithm: material.signatureAlgorithm,\n decryptionKey: material.decryptionKey,\n encryptionKey: material.encryptionKey,\n });\n\n entity = await this.repository.save(entity);\n\n // private material never leaves the server — the response carries\n // metadata + public part only (authentik CVE-2024-42490).\n entity.decryptionKey = null;\n\n await this.recordEvent(EventName.CREATED, entity, actor);\n\n return entity;\n }\n\n async update(\n idOrName: string,\n data: Record<string, any>,\n actor: ActorContext,\n realmId?: string,\n ): Promise<Key> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.KEY_UPDATE });\n\n let entity = await this.repository.findOneByIdOrName(idOrName, realmId);\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n // only name / priority / status are mounted for UPDATE — material,\n // use, type and realm are immutable.\n const validated = await this.validator.run(data, { group: ValidatorGroup.UPDATE });\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.KEY_UPDATE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: {\n ...entity,\n ...validated,\n },\n ...this.resourceRealmMatch(entity),\n }),\n });\n\n if (validated.name && validated.name !== entity.name) {\n await this.repository.checkUniqueness({\n name: validated.name,\n realmId: entity.realmId,\n }, entity);\n }\n\n const previous = this.pickAuditFields(entity);\n\n entity = this.repository.merge(entity, validated);\n await this.repository.save(entity);\n\n entity.decryptionKey = null;\n\n const diff = buildEntityDiff(this.pickAuditFields(entity), previous);\n await this.recordEvent(EventName.UPDATED, entity, actor, { ...(Object.keys(diff).length > 0 ? { diff } : {}) });\n\n return entity;\n }\n\n async delete(\n id: string,\n actor: ActorContext,\n options: KeyDeleteOptions = {},\n ): Promise<Key> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.KEY_DELETE });\n\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.KEY_DELETE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: entity,\n ...this.resourceRealmMatch(entity),\n }),\n });\n\n if (entity.use === JWKUse.ENCRYPTION && !options.force) {\n const references = await this.repository.countBlobReferences(entity.id);\n if (references > 0) {\n throw new EntityConflictError({\n message: `The encryption key is still referenced by ${references} encrypted secret(s) — ` +\n 'deleting it makes them unrecoverable. Repeat with force to crypto-shred them.',\n data: { references },\n });\n }\n }\n\n const { id: entityId } = entity;\n await this.repository.remove(entity);\n entity.id = entityId;\n entity.decryptionKey = null;\n\n // force only carries crypto-shred semantics for encryption keys — a\n // sig-key delete with a stray force flag must not read as a shred.\n const forcedCryptoShred = entity.use === JWKUse.ENCRYPTION && !!options.force;\n await this.recordEvent(EventName.DELETED, entity, actor, { ...(forcedCryptoShred ? { force: true } : {}) });\n\n return entity;\n }\n\n // ------------------------------------------------------------------\n\n /**\n * Metadata-only audit trail for key lifecycle operations (issue #3269) —\n * keys deliberately have no entity subscriber (private material must stay\n * off the realtime/audit bus), so the security-relevant mutations are\n * recorded explicitly. The payload never carries key material.\n */\n protected async recordEvent(\n name: `${EventName}`,\n entity: Key,\n actor: ActorContext,\n data: Record<string, any> = {},\n ): Promise<void> {\n const requestContext = this.requestContext ?\n this.requestContext() :\n undefined;\n\n await this.eventService?.record({\n scope: EventScope.ENTITY,\n name,\n refType: EntityType.KEY,\n refId: entity.id,\n realmId: entity.realmId ?? null,\n actorType: actor.identity?.type ?? null,\n actorId: actor.identity?.data.id ?? null,\n actorName: actor.identity?.data.name ?? null,\n requestPath: requestContext?.requestPath ?? null,\n requestMethod: requestContext?.requestMethod ?? null,\n requestIpAddress: requestContext?.requestIpAddress ?? null,\n requestUserAgent: requestContext?.requestUserAgent ?? null,\n data: {\n name: entity.name,\n use: entity.use,\n status: entity.status,\n ...data,\n },\n });\n }\n\n protected pickAuditFields(entity: Key): Record<string, any> {\n return {\n name: entity.name,\n priority: entity.priority,\n status: entity.status,\n };\n }\n\n protected async generateMaterial(\n validated: Partial<Key>,\n use: `${JWKUse}`,\n ) : Promise<{\n type: `${JWKType}`,\n signatureAlgorithm: `${JWTAlgorithm}` | null,\n decryptionKey: string,\n encryptionKey: string | null,\n }> {\n if (use === JWKUse.ENCRYPTION) {\n if (validated.signatureAlgorithm) {\n throw new ValidationError('An encryption key can not carry a signature algorithm.');\n }\n\n const raw = new Uint8Array(32);\n getRandomValues(raw);\n\n return {\n type: JWKType.OCT,\n signatureAlgorithm: null,\n decryptionKey: arrayBufferToBase64(raw.buffer),\n encryptionKey: null,\n };\n }\n\n const algorithm = validated.signatureAlgorithm ?? JWTAlgorithm.RS256;\n const options = this.buildAsymmetricOptions(algorithm);\n\n const keyPair = await createAsymmetricKeyPair(options);\n\n return {\n type: algorithm.startsWith('ES') ? JWKType.EC : JWKType.RSA,\n signatureAlgorithm: algorithm,\n decryptionKey: await new AsymmetricKey(keyPair.privateKey).toBase64(),\n encryptionKey: await new AsymmetricKey(keyPair.publicKey).toBase64(),\n };\n }\n\n protected async importMaterial(\n validated: Partial<Key>,\n use: `${JWKUse}`,\n ) : Promise<{\n type: `${JWKType}`,\n signatureAlgorithm: `${JWTAlgorithm}` | null,\n decryptionKey: string,\n encryptionKey: string | null,\n }> {\n if (!validated.decryptionKey) {\n throw new ValidationError('Importing key material requires its private part (decryptionKey).');\n }\n\n // Reject material masquerading as an at-rest KEK-wrapped blob — it\n // would be treated as wrapped on the next read (and, with a KEK,\n // fail GCM authentication).\n if (isWrappedKeyMaterial(validated.decryptionKey.trim())) {\n throw new ValidationError('The imported key material is not valid.');\n }\n\n const decryptionKey = this.normalizeMaterial(validated.decryptionKey);\n\n if (use === JWKUse.ENCRYPTION) {\n if (validated.signatureAlgorithm) {\n throw new ValidationError('An encryption key can not carry a signature algorithm.');\n }\n\n if (validated.encryptionKey) {\n throw new ValidationError('An encryption key holds no public part.');\n }\n\n let byteLength : number;\n try {\n byteLength = base64ToArrayBuffer(decryptionKey).byteLength;\n } catch {\n throw new ValidationError('The key material is not valid base64.');\n }\n\n if (byteLength !== 32) {\n throw new ValidationError('The key material must be 32 base64-encoded bytes.');\n }\n\n return {\n type: JWKType.OCT,\n signatureAlgorithm: null,\n decryptionKey,\n encryptionKey: null,\n };\n }\n\n if (!validated.encryptionKey) {\n throw new ValidationError('Importing a signature key requires its public part (encryptionKey, SPKI).');\n }\n\n const encryptionKey = this.normalizeMaterial(validated.encryptionKey);\n const algorithm = validated.signatureAlgorithm ?? JWTAlgorithm.RS256;\n const options = this.buildAsymmetricOptions(algorithm);\n\n let privateJwk : JsonWebKey;\n let publicJwk : JsonWebKey;\n\n try {\n const privateKey = await AsymmetricKey.fromBase64({\n format: 'pkcs8',\n key: decryptionKey,\n options,\n });\n const publicKey = await AsymmetricKey.fromBase64({\n format: 'spki',\n key: encryptionKey,\n options,\n });\n\n privateJwk = await privateKey.toJWK();\n publicJwk = await publicKey.toJWK();\n } catch {\n throw new ValidationError(`The key material could not be imported for ${algorithm}.`);\n }\n\n // the public components (RSA: n/e, EC: crv/x/y) must agree — a\n // private key paired with a foreign public part would publish a\n // wrong JWKS entry and break verification of every token it signs.\n const components : (keyof JsonWebKey)[] = ['kty', 'n', 'e', 'crv', 'x', 'y'];\n const mismatch = components.some(\n (component) => publicJwk[component] !== undefined &&\n publicJwk[component] !== privateJwk[component],\n );\n if (mismatch) {\n throw new ValidationError('The private and public key material do not form a pair.');\n }\n\n return {\n type: algorithm.startsWith('ES') ? JWKType.EC : JWKType.RSA,\n signatureAlgorithm: algorithm,\n decryptionKey,\n encryptionKey,\n };\n }\n\n protected buildAsymmetricOptions(algorithm: `${JWTAlgorithm}`) {\n if (!/^(RS|ES)(256|384|512)$/.test(algorithm)) {\n throw new ValidationError(`The signature algorithm ${algorithm} is not supported for stored keys.`);\n }\n\n return AsymmetricKey.buildImportOptionsForJWTAlgorithm(algorithm);\n }\n\n protected normalizeMaterial(value: string) : string {\n if (value.includes('-----BEGIN')) {\n // PEM body IS base64 DER — strip armor + whitespace.\n return value\n .replace(/-----(BEGIN|END)[^-]+-----/g, '')\n .replace(/\\s+/g, '');\n }\n\n return value.trim();\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../../src/core/entities/permission/schema.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAGnD,eAAO,MAAM,gBAAgB,+CAM3B,CAAC"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../../src/core/entities/permission/schema.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAGnD,eAAO,MAAM,gBAAgB,+CAuB3B,CAAC"}
@@ -6,6 +6,18 @@ import { defineSchema } from "@rapiq/core";
6
6
  //#region src/core/entities/permission/schema.ts
7
7
  const permissionSchema = defineSchema({
8
8
  name: EntityType.PERMISSION,
9
+ fields: { allowed: [
10
+ "id",
11
+ "builtIn",
12
+ "name",
13
+ "displayName",
14
+ "description",
15
+ "decisionStrategy",
16
+ "clientId",
17
+ "realmId",
18
+ "createdAt",
19
+ "updatedAt"
20
+ ] },
9
21
  filters: { allowed: [
10
22
  "id",
11
23
  "displayName",
@@ -1 +1 @@
1
- {"version":3,"file":"schema.mjs","names":["defineSchema","EntityType","permissionSchema","name","PERMISSION","filters","allowed","relations","sort","pagination","maxLimit"],"sources":["../../../../src/core/entities/permission/schema.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { defineSchema } from '@rapiq/core';\nimport type { Permission } from '@authup/core-kit';\nimport { EntityType } from '@authup/core-kit';\n\nexport const permissionSchema = defineSchema<Permission>({\n name: EntityType.PERMISSION,\n filters: { allowed: ['id', 'displayName', 'name', 'builtIn', 'realmId'] },\n relations: { allowed: [] },\n sort: { allowed: ['id', 'name', 'createdAt', 'updatedAt'] },\n pagination: { maxLimit: 50 },\n});\n"],"mappings":";;;;;;AAWA,MAAaE,mBAAmBF,aAAyB;CACrDG,MAAMF,WAAWG;CACjBC,SAAS,EAAEC,SAAS;EAAC;EAAM;EAAe;EAAQ;EAAW;GAAW;CACxEC,WAAW,EAAED,SAAS,CAAA,EAAG;CACzBE,MAAM,EAAEF,SAAS;EAAC;EAAM;EAAQ;EAAa;GAAa;CAC1DG,YAAY,EAAEC,UAAU,GAAG;AAC/B,CAAA"}
1
+ {"version":3,"file":"schema.mjs","names":["defineSchema","EntityType","permissionSchema","name","PERMISSION","fields","allowed","filters","relations","sort","pagination","maxLimit"],"sources":["../../../../src/core/entities/permission/schema.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { defineSchema } from '@rapiq/core';\nimport type { Permission } from '@authup/core-kit';\nimport { EntityType } from '@authup/core-kit';\n\nexport const permissionSchema = defineSchema<Permission>({\n name: EntityType.PERMISSION,\n // explicit root projection so an include=permission decodes columns\n // (a schema without fields selects all as a query root but nothing as\n // an include child — see client-permission/user-role schema comments)\n fields: {\n allowed: [\n 'id',\n 'builtIn',\n 'name',\n 'displayName',\n 'description',\n 'decisionStrategy',\n 'clientId',\n 'realmId',\n 'createdAt',\n 'updatedAt',\n ],\n },\n filters: { allowed: ['id', 'displayName', 'name', 'builtIn', 'realmId'] },\n relations: { allowed: [] },\n sort: { allowed: ['id', 'name', 'createdAt', 'updatedAt'] },\n pagination: { maxLimit: 50 },\n});\n"],"mappings":";;;;;;AAWA,MAAaE,mBAAmBF,aAAyB;CACrDG,MAAMF,WAAWG;CAIjBC,QAAQ,EACJC,SAAS;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACH,EACL;CACAC,SAAS,EAAED,SAAS;EAAC;EAAM;EAAe;EAAQ;EAAW;CAAU,EAAC;CACxEE,WAAW,EAAEF,SAAS,CAAA,EAAG;CACzBG,MAAM,EAAEH,SAAS;EAAC;EAAM;EAAQ;EAAa;CAAY,EAAC;CAC1DI,YAAY,EAAEC,UAAU,GAAG;AAC/B,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"service.mjs","names":["BuiltInPolicyType","RealmScope","SystemPolicyName","definePolicyData","ValidatorGroup","isPropertySet","isUUID","AuthupError","EntityNotFoundError","ValidationError","PermissionName","PermissionValidator","ROLE_ADMIN_NAME","ROLE_REALM_ADMIN_NAME","AbstractEntityService","decodeQuery","permissionSchema","REALM_ADMIN_EXCLUDED_PERMISSIONS","REALM_CREATE","REALM_UPDATE","REALM_DELETE","REALM_ADMIN_BOUND_PERMISSIONS","CLIENT_CREATE","CLIENT_UPDATE","CLIENT_DELETE","IDENTITY_PROVIDER_CREATE","IDENTITY_PROVIDER_UPDATE","IDENTITY_PROVIDER_DELETE","PERMISSION_CREATE","PERMISSION_UPDATE","PERMISSION_DELETE","ROLE_CREATE","ROLE_UPDATE","ROLE_DELETE","SCOPE_CREATE","SCOPE_UPDATE","SCOPE_DELETE","USER_CREATE","USER_UPDATE","USER_DELETE","PermissionService","repository","realmRepository","roleRepository","rolePermissionRepository","policyRepository","permissionPolicyRepository","validator","ctx","getMany","query","actor","permissionEvaluator","preEvaluateOneOf","name","PERMISSION_READ","findMany","schema","getOne","idOrName","realm","entity","findOneByIdOrName","create","data","save","undefined","update","updateOnly","options","group","realmId","resolve","where","id","findOneBy","preEvaluate","UPDATE","CREATE","validated","run","validateJoinColumns","builtIn","evaluate","ATTRIBUTES","REALM_MATCH","checkUniqueness","merge","created","identity","getActorRealmId","resourceRealmMatch","assignToAdminRole","assignToRealmAdminRoles","assignDefaultPolicy","e","remove","catch","delete","entityId","permission","defaultPolicy","findOneByName","DEFAULT","existing","permissionId","policyId","entry","permissionRealmId","policyRealmId","adminRole","roleId","roleRealmId","realmScope","ANY","includes","isBuiltIn","Object","values","OWN","OWN_OR_NULL","realmAdminRoles","findManyBy","role"],"sources":["../../../../src/core/entities/permission/service.ts"],"sourcesContent":["/*\n * Copyright (c) 2025.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { \n BuiltInPolicyType, \n RealmScope, \n SystemPolicyName, \n definePolicyData, \n} from '@authup/access';\nimport { ValidatorGroup, isPropertySet, isUUID } from '@authup/kit';\nimport { AuthupError, EntityNotFoundError, ValidationError } from '@authup/errors';\nimport {\n PermissionName,\n PermissionValidator,\n ROLE_ADMIN_NAME,\n ROLE_REALM_ADMIN_NAME,\n} from '@authup/core-kit';\nimport type { Permission } from '@authup/core-kit';\nimport type { ActorContext, EntityRepositoryFindManyResult } from '@authup/server-kit';\nimport type { IPermissionPolicyRepository } from '../permission-policy/types.ts';\nimport type { IPolicyRepository } from '../policy/types.ts';\nimport type { IRealmRepository } from '../realm/types.ts';\nimport type { IRoleRepository } from '../role/types.ts';\nimport type { IRolePermissionRepository } from '../role-permission/types.ts';\nimport { AbstractEntityService } from '@authup/server-kit';\nimport type { IPermissionRepository, IPermissionService } from './types.ts';\nimport { decodeQuery } from '../../query/index.ts';\nimport { permissionSchema } from './schema.ts';\n\nconst REALM_ADMIN_EXCLUDED_PERMISSIONS = [\n PermissionName.REALM_CREATE,\n PermissionName.REALM_UPDATE,\n PermissionName.REALM_DELETE,\n];\n\n/**\n * Direct-entity CUD permissions that realm_admin grants at `realmScope: own`\n * (strictly the actor's own realm — see line 372). Every other realm_admin\n * permission defaults to `ownOrNull` (own realm OR global/null resources) so it\n * can act on global building blocks.\n *\n * Junction CUD (e.g. user_role, role_permission) is intentionally NOT listed here:\n * it stays `ownOrNull` because a junction can legitimately reference a global\n * side (realmId: null) — a strict `own` would reject those.\n */\nconst REALM_ADMIN_BOUND_PERMISSIONS = [\n PermissionName.CLIENT_CREATE,\n PermissionName.CLIENT_UPDATE,\n PermissionName.CLIENT_DELETE,\n PermissionName.IDENTITY_PROVIDER_CREATE,\n PermissionName.IDENTITY_PROVIDER_UPDATE,\n PermissionName.IDENTITY_PROVIDER_DELETE,\n PermissionName.PERMISSION_CREATE,\n PermissionName.PERMISSION_UPDATE,\n PermissionName.PERMISSION_DELETE,\n PermissionName.ROLE_CREATE,\n PermissionName.ROLE_UPDATE,\n PermissionName.ROLE_DELETE,\n PermissionName.SCOPE_CREATE,\n PermissionName.SCOPE_UPDATE,\n PermissionName.SCOPE_DELETE,\n PermissionName.USER_CREATE,\n PermissionName.USER_UPDATE,\n PermissionName.USER_DELETE,\n];\n\nexport type PermissionServiceContext = {\n repository: IPermissionRepository;\n realmRepository: IRealmRepository;\n roleRepository: IRoleRepository;\n rolePermissionRepository: IRolePermissionRepository;\n policyRepository: IPolicyRepository;\n permissionPolicyRepository: IPermissionPolicyRepository;\n};\n\nexport class PermissionService extends AbstractEntityService implements IPermissionService {\n protected repository: IPermissionRepository;\n\n protected realmRepository: IRealmRepository;\n\n protected roleRepository: IRoleRepository;\n\n protected rolePermissionRepository: IRolePermissionRepository;\n\n protected policyRepository: IPolicyRepository;\n\n protected permissionPolicyRepository: IPermissionPolicyRepository;\n\n protected validator: PermissionValidator;\n\n constructor(ctx: PermissionServiceContext) {\n super();\n this.repository = ctx.repository;\n this.realmRepository = ctx.realmRepository;\n this.roleRepository = ctx.roleRepository;\n this.rolePermissionRepository = ctx.rolePermissionRepository;\n this.policyRepository = ctx.policyRepository;\n this.permissionPolicyRepository = ctx.permissionPolicyRepository;\n this.validator = new PermissionValidator();\n }\n\n async getMany(\n query: Record<string, any>,\n actor: ActorContext,\n ): Promise<EntityRepositoryFindManyResult<Permission>> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.PERMISSION_READ,\n PermissionName.PERMISSION_UPDATE,\n PermissionName.PERMISSION_DELETE,\n ],\n });\n\n return this.repository.findMany(await decodeQuery(query, { schema: permissionSchema, actor }));\n }\n\n async getOne(\n idOrName: string,\n actor: ActorContext,\n realm?: string,\n ): Promise<Permission> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.PERMISSION_READ,\n PermissionName.PERMISSION_UPDATE,\n PermissionName.PERMISSION_DELETE,\n ],\n });\n\n const entity = await this.repository.findOneByIdOrName(idOrName, realm);\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n return entity;\n }\n\n async create(\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<Permission> {\n const { entity } = await this.save(undefined, data, actor);\n return entity;\n }\n\n async update(\n idOrName: string,\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<Permission> {\n const { entity } = await this.save(idOrName, data, actor, { updateOnly: true });\n return entity;\n }\n\n async save(\n idOrName: string | undefined,\n data: Record<string, any>,\n actor: ActorContext,\n options: { updateOnly?: boolean } = {},\n ): Promise<{\n entity: Permission,\n created: boolean\n }> {\n let group: string;\n\n const realm = typeof data.realmId === 'string' ?\n await this.realmRepository.resolve(data.realmId) :\n undefined;\n\n let entity: Permission | null | undefined;\n if (idOrName) {\n const where: Record<string, any> = {};\n if (isUUID(idOrName)) {\n where.id = idOrName;\n } else {\n where.name = idOrName;\n }\n\n if (realm) {\n where.realmId = realm.id;\n }\n\n entity = await this.repository.findOneBy(where);\n if (!entity && options.updateOnly) {\n throw new EntityNotFoundError();\n }\n } else if (options.updateOnly) {\n throw new EntityNotFoundError();\n }\n\n if (entity) {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.PERMISSION_UPDATE });\n group = ValidatorGroup.UPDATE;\n } else {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.PERMISSION_CREATE });\n group = ValidatorGroup.CREATE;\n }\n\n const validated = await this.validator.run(data, { group });\n\n await this.repository.validateJoinColumns(validated);\n\n if (entity) {\n if (\n entity.builtIn &&\n isPropertySet(validated, 'name') &&\n entity.name !== validated.name\n ) {\n throw new ValidationError('The name of a built-in permission can not be changed.');\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.PERMISSION_UPDATE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: {\n ...entity,\n ...validated,\n },\n [BuiltInPolicyType.REALM_MATCH]: validated.realmId ?? entity.realmId ?? null,\n }),\n });\n\n await this.repository.checkUniqueness(validated, entity);\n\n entity = this.repository.merge(entity, validated);\n\n await this.repository.save(entity);\n\n return {\n entity,\n created: false,\n };\n }\n\n if (!isPropertySet(validated, 'realmId') && actor.identity) {\n validated.realmId = this.getActorRealmId(actor) || null;\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.PERMISSION_CREATE,\n data: definePolicyData({ [BuiltInPolicyType.ATTRIBUTES]: validated, ...this.resourceRealmMatch(validated) }),\n });\n\n await this.repository.checkUniqueness(validated);\n\n entity = this.repository.create(validated);\n entity = await this.repository.save(entity);\n\n // The permission row is now committed, but its security wiring — the\n // admin/realm_admin grants and the system.default binding — is written\n // through separate repositories with no shared transaction. A failure\n // partway through would strand the permission bound by system.default\n // yet held by nobody, which the uniform member gate on\n // POST /role-permissions then makes permanently un-grantable (#3303).\n // Two safeguards:\n // 1. Establish the grants BEFORE binding system.default, so even an\n // un-compensated interruption (a hard process crash) cannot produce\n // the bound-but-ungranted strand — at worst a benign, still-grantable\n // permission that lacks its baseline policy.\n // 2. On any thrown failure, remove the just-created permission — its\n // CASCADE foreign keys drop any partial junction/binding rows — and\n // rethrow so the caller sees the failure instead of a stale record.\n try {\n await this.assignToAdminRole(entity);\n await this.assignToRealmAdminRoles(entity);\n await this.assignDefaultPolicy(entity);\n } catch (e) {\n await this.repository.remove(entity).catch(() => { /* best-effort rollback */ });\n throw e;\n }\n\n return {\n entity,\n created: true,\n };\n }\n\n async delete(\n id: string,\n actor: ActorContext,\n ): Promise<Permission> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.PERMISSION_DELETE });\n\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n if (entity.builtIn) {\n throw new ValidationError('A built-in permission can not be deleted.');\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.PERMISSION_DELETE,\n data: definePolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity, ...this.resourceRealmMatch(entity) }),\n });\n\n const { id: entityId } = entity;\n await this.repository.remove(entity);\n entity.id = entityId;\n\n return entity;\n }\n\n /**\n * Assign the system.default policy to a newly created permission.\n * This ensures all permissions are evaluated with the baseline security\n * policy (identity, permission-binding, realm-match) by default.\n */\n private async assignDefaultPolicy(permission: Permission): Promise<void> {\n const defaultPolicy = await this.policyRepository.findOneByName(SystemPolicyName.DEFAULT);\n if (!defaultPolicy) {\n throw new AuthupError(`The ${SystemPolicyName.DEFAULT} policy is not provisioned. Cannot create permissions without the default security policy.`);\n }\n\n const existing = await this.permissionPolicyRepository.findOneBy({\n permissionId: permission.id,\n policyId: defaultPolicy.id,\n });\n if (existing) {\n return;\n }\n\n const entry = this.permissionPolicyRepository.create({\n permissionId: permission.id,\n permissionRealmId: permission.realmId,\n policyId: defaultPolicy.id,\n policyRealmId: defaultPolicy.realmId,\n });\n await this.permissionPolicyRepository.save(entry);\n }\n\n /**\n * Assign a newly created permission to the global admin role.\n * The admin role receives every permission without policy restrictions.\n *\n * Throws when the admin role is not provisioned: without an admin grant the\n * permission is bound by `system.default` yet held by nobody, and the uniform\n * member gate on junction creation makes it permanently un-grantable (even by\n * admin). Fail loud so the stranded state is surfaced instead of swallowed.\n */\n private async assignToAdminRole(permission: Permission): Promise<void> {\n const adminRole = await this.roleRepository.findOneByName(ROLE_ADMIN_NAME);\n if (!adminRole) {\n throw new AuthupError(`The ${ROLE_ADMIN_NAME} role is not provisioned. Cannot grant the created permission to the administrator role.`);\n }\n\n const existing = await this.rolePermissionRepository.findOneBy({\n roleId: adminRole.id,\n permissionId: permission.id,\n });\n if (existing) {\n return;\n }\n\n const entry = this.rolePermissionRepository.create({\n roleId: adminRole.id,\n roleRealmId: adminRole.realmId,\n permissionId: permission.id,\n permissionRealmId: permission.realmId,\n // Global admin: unrestricted realm reach.\n realmScope: RealmScope.ANY,\n });\n await this.rolePermissionRepository.save(entry);\n }\n\n /**\n * Assign a newly created permission to all matching realm_admin roles.\n *\n * Uses differentiated realmScope on the junction:\n * - CUD on global-capable entity types → own (strictly own realm)\n * - Everything else → ownOrNull (own realm + null/global resources)\n *\n * Eligible permissions:\n * - Built-in authup permissions (global) — assigned to all realm_admin roles\n * - Realm-scoped permissions — assigned to the realm_admin in the matching realm\n *\n * Excluded:\n * - Realm CRUD permissions (realm_create, realm_update, realm_delete)\n * - Custom global permissions (non-built-in with realmId: null)\n */\n private async assignToRealmAdminRoles(permission: Permission): Promise<void> {\n if (REALM_ADMIN_EXCLUDED_PERMISSIONS.includes(permission.name as PermissionName)) {\n return;\n }\n\n const isBuiltIn = (Object.values(PermissionName) as string[]).includes(permission.name);\n if (!permission.realmId && !isBuiltIn) {\n return;\n }\n\n const realmScope = REALM_ADMIN_BOUND_PERMISSIONS.includes(permission.name as PermissionName) ?\n RealmScope.OWN :\n RealmScope.OWN_OR_NULL;\n\n const realmAdminRoles = await this.roleRepository.findManyBy({ name: ROLE_REALM_ADMIN_NAME });\n\n for (const role of realmAdminRoles) {\n if (permission.realmId && permission.realmId !== role.realmId) {\n continue;\n }\n\n const existing = await this.rolePermissionRepository.findOneBy({\n roleId: role.id,\n permissionId: permission.id,\n });\n if (existing) {\n continue;\n }\n\n const entry = this.rolePermissionRepository.create({\n roleId: role.id,\n roleRealmId: role.realmId,\n permissionId: permission.id,\n permissionRealmId: permission.realmId,\n realmScope,\n });\n await this.rolePermissionRepository.save(entry);\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"service.mjs","names":["BuiltInPolicyType","RealmScope","SystemPolicyName","definePolicyData","ValidatorGroup","isPropertySet","isUUID","AuthupError","EntityNotFoundError","ValidationError","PermissionName","PermissionValidator","ROLE_ADMIN_NAME","ROLE_REALM_ADMIN_NAME","AbstractEntityService","decodeQuery","permissionSchema","REALM_ADMIN_EXCLUDED_PERMISSIONS","REALM_CREATE","REALM_UPDATE","REALM_DELETE","REALM_ADMIN_BOUND_PERMISSIONS","CLIENT_CREATE","CLIENT_UPDATE","CLIENT_DELETE","IDENTITY_PROVIDER_CREATE","IDENTITY_PROVIDER_UPDATE","IDENTITY_PROVIDER_DELETE","PERMISSION_CREATE","PERMISSION_UPDATE","PERMISSION_DELETE","ROLE_CREATE","ROLE_UPDATE","ROLE_DELETE","SCOPE_CREATE","SCOPE_UPDATE","SCOPE_DELETE","USER_CREATE","USER_UPDATE","USER_DELETE","PermissionService","repository","realmRepository","roleRepository","rolePermissionRepository","policyRepository","permissionPolicyRepository","validator","ctx","getMany","query","actor","permissionEvaluator","preEvaluateOneOf","name","PERMISSION_READ","findMany","schema","getOne","idOrName","realm","entity","findOneByIdOrName","create","data","save","undefined","update","updateOnly","options","group","realmId","resolve","where","id","findOneBy","preEvaluate","UPDATE","CREATE","validated","run","validateJoinColumns","builtIn","evaluate","ATTRIBUTES","REALM_MATCH","checkUniqueness","merge","created","identity","getActorRealmId","resourceRealmMatch","assignToAdminRole","assignToRealmAdminRoles","assignDefaultPolicy","e","remove","catch","delete","entityId","permission","defaultPolicy","findOneByName","DEFAULT","existing","permissionId","policyId","entry","permissionRealmId","policyRealmId","adminRole","roleId","roleRealmId","realmScope","ANY","includes","isBuiltIn","Object","values","OWN","OWN_OR_NULL","realmAdminRoles","findManyBy","role"],"sources":["../../../../src/core/entities/permission/service.ts"],"sourcesContent":["/*\n * Copyright (c) 2025.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { \n BuiltInPolicyType, \n RealmScope, \n SystemPolicyName, \n definePolicyData, \n} from '@authup/access';\nimport { ValidatorGroup, isPropertySet, isUUID } from '@authup/kit';\nimport { AuthupError, EntityNotFoundError, ValidationError } from '@authup/errors';\nimport {\n PermissionName,\n PermissionValidator,\n ROLE_ADMIN_NAME,\n ROLE_REALM_ADMIN_NAME,\n} from '@authup/core-kit';\nimport type { Permission } from '@authup/core-kit';\nimport type { ActorContext, EntityRepositoryFindManyResult } from '@authup/server-kit';\nimport type { IPermissionPolicyRepository } from '../permission-policy/types.ts';\nimport type { IPolicyRepository } from '../policy/types.ts';\nimport type { IRealmRepository } from '../realm/types.ts';\nimport type { IRoleRepository } from '../role/types.ts';\nimport type { IRolePermissionRepository } from '../role-permission/types.ts';\nimport { AbstractEntityService } from '@authup/server-kit';\nimport type { IPermissionRepository, IPermissionService } from './types.ts';\nimport { decodeQuery } from '../../query/index.ts';\nimport { permissionSchema } from './schema.ts';\n\nconst REALM_ADMIN_EXCLUDED_PERMISSIONS = [\n PermissionName.REALM_CREATE,\n PermissionName.REALM_UPDATE,\n PermissionName.REALM_DELETE,\n];\n\n/**\n * Direct-entity CUD permissions that realm_admin grants at `realmScope: own`\n * (strictly the actor's own realm — see line 372). Every other realm_admin\n * permission defaults to `ownOrNull` (own realm OR global/null resources) so it\n * can act on global building blocks.\n *\n * Junction CUD (e.g. user_role, role_permission) is intentionally NOT listed here:\n * it stays `ownOrNull` because a junction can legitimately reference a global\n * side (realmId: null) — a strict `own` would reject those.\n */\nconst REALM_ADMIN_BOUND_PERMISSIONS = [\n PermissionName.CLIENT_CREATE,\n PermissionName.CLIENT_UPDATE,\n PermissionName.CLIENT_DELETE,\n PermissionName.IDENTITY_PROVIDER_CREATE,\n PermissionName.IDENTITY_PROVIDER_UPDATE,\n PermissionName.IDENTITY_PROVIDER_DELETE,\n PermissionName.PERMISSION_CREATE,\n PermissionName.PERMISSION_UPDATE,\n PermissionName.PERMISSION_DELETE,\n PermissionName.ROLE_CREATE,\n PermissionName.ROLE_UPDATE,\n PermissionName.ROLE_DELETE,\n PermissionName.SCOPE_CREATE,\n PermissionName.SCOPE_UPDATE,\n PermissionName.SCOPE_DELETE,\n PermissionName.USER_CREATE,\n PermissionName.USER_UPDATE,\n PermissionName.USER_DELETE,\n];\n\nexport type PermissionServiceContext = {\n repository: IPermissionRepository;\n realmRepository: IRealmRepository;\n roleRepository: IRoleRepository;\n rolePermissionRepository: IRolePermissionRepository;\n policyRepository: IPolicyRepository;\n permissionPolicyRepository: IPermissionPolicyRepository;\n};\n\nexport class PermissionService extends AbstractEntityService implements IPermissionService {\n protected repository: IPermissionRepository;\n\n protected realmRepository: IRealmRepository;\n\n protected roleRepository: IRoleRepository;\n\n protected rolePermissionRepository: IRolePermissionRepository;\n\n protected policyRepository: IPolicyRepository;\n\n protected permissionPolicyRepository: IPermissionPolicyRepository;\n\n protected validator: PermissionValidator;\n\n constructor(ctx: PermissionServiceContext) {\n super();\n this.repository = ctx.repository;\n this.realmRepository = ctx.realmRepository;\n this.roleRepository = ctx.roleRepository;\n this.rolePermissionRepository = ctx.rolePermissionRepository;\n this.policyRepository = ctx.policyRepository;\n this.permissionPolicyRepository = ctx.permissionPolicyRepository;\n this.validator = new PermissionValidator();\n }\n\n async getMany(\n query: Record<string, any>,\n actor: ActorContext,\n ): Promise<EntityRepositoryFindManyResult<Permission>> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.PERMISSION_READ,\n PermissionName.PERMISSION_UPDATE,\n PermissionName.PERMISSION_DELETE,\n ],\n });\n\n return this.repository.findMany(await decodeQuery(query, { schema: permissionSchema, actor }));\n }\n\n async getOne(\n idOrName: string,\n actor: ActorContext,\n realm?: string,\n ): Promise<Permission> {\n await actor.permissionEvaluator.preEvaluateOneOf({\n name: [\n PermissionName.PERMISSION_READ,\n PermissionName.PERMISSION_UPDATE,\n PermissionName.PERMISSION_DELETE,\n ],\n });\n\n const entity = await this.repository.findOneByIdOrName(idOrName, realm);\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n return entity;\n }\n\n async create(\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<Permission> {\n const { entity } = await this.save(undefined, data, actor);\n return entity;\n }\n\n async update(\n idOrName: string,\n data: Record<string, any>,\n actor: ActorContext,\n ): Promise<Permission> {\n const { entity } = await this.save(idOrName, data, actor, { updateOnly: true });\n return entity;\n }\n\n async save(\n idOrName: string | undefined,\n data: Record<string, any>,\n actor: ActorContext,\n options: { updateOnly?: boolean } = {},\n ): Promise<{\n entity: Permission,\n created: boolean\n }> {\n let group: string;\n\n const realm = typeof data.realmId === 'string' ?\n await this.realmRepository.resolve(data.realmId) :\n undefined;\n\n let entity: Permission | null | undefined;\n if (idOrName) {\n const where: Record<string, any> = {};\n if (isUUID(idOrName)) {\n where.id = idOrName;\n } else {\n where.name = idOrName;\n }\n\n if (realm) {\n where.realmId = realm.id;\n }\n\n entity = await this.repository.findOneBy(where);\n if (!entity && options.updateOnly) {\n throw new EntityNotFoundError();\n }\n } else if (options.updateOnly) {\n throw new EntityNotFoundError();\n }\n\n if (entity) {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.PERMISSION_UPDATE });\n group = ValidatorGroup.UPDATE;\n } else {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.PERMISSION_CREATE });\n group = ValidatorGroup.CREATE;\n }\n\n const validated = await this.validator.run(data, { group });\n\n await this.repository.validateJoinColumns(validated);\n\n if (entity) {\n if (\n entity.builtIn &&\n isPropertySet(validated, 'name') &&\n entity.name !== validated.name\n ) {\n throw new ValidationError('The name of a built-in permission can not be changed.');\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.PERMISSION_UPDATE,\n data: definePolicyData({\n [BuiltInPolicyType.ATTRIBUTES]: {\n ...entity,\n ...validated,\n },\n [BuiltInPolicyType.REALM_MATCH]: validated.realmId ?? entity.realmId ?? null,\n }),\n });\n\n await this.repository.checkUniqueness(validated, entity);\n\n entity = this.repository.merge(entity, validated);\n\n await this.repository.save(entity);\n\n return {\n entity,\n created: false,\n };\n }\n\n if (!isPropertySet(validated, 'realmId') && actor.identity) {\n validated.realmId = this.getActorRealmId(actor) || null;\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.PERMISSION_CREATE,\n data: definePolicyData({ [BuiltInPolicyType.ATTRIBUTES]: validated, ...this.resourceRealmMatch(validated) }),\n });\n\n await this.repository.checkUniqueness(validated);\n\n entity = this.repository.create(validated);\n entity = await this.repository.save(entity);\n\n // The permission row is now committed, but its security wiring — the\n // admin/realm_admin grants and the system.default binding — is written\n // through separate repositories with no shared transaction. A failure\n // partway through would strand the permission bound by system.default\n // yet held by nobody, which the uniform member gate on\n // POST /role-permissions then makes permanently un-grantable (#3303).\n // Two safeguards:\n // 1. Establish the grants BEFORE binding system.default, so even an\n // un-compensated interruption (a hard process crash) cannot produce\n // the bound-but-ungranted strand — at worst a benign, still-grantable\n // permission that lacks its baseline policy.\n // 2. On any thrown failure, remove the just-created permission — its\n // CASCADE foreign keys drop any partial junction/binding rows — and\n // rethrow so the caller sees the failure instead of a stale record.\n try {\n await this.assignToAdminRole(entity);\n await this.assignToRealmAdminRoles(entity);\n await this.assignDefaultPolicy(entity);\n } catch (e) {\n await this.repository.remove(entity).catch(() => { /* best-effort rollback */ });\n throw e;\n }\n\n return {\n entity,\n created: true,\n };\n }\n\n async delete(\n id: string,\n actor: ActorContext,\n ): Promise<Permission> {\n await actor.permissionEvaluator.preEvaluate({ name: PermissionName.PERMISSION_DELETE });\n\n const entity = await this.repository.findOneBy({ id });\n if (!entity) {\n throw new EntityNotFoundError();\n }\n\n if (entity.builtIn) {\n throw new ValidationError('A built-in permission can not be deleted.');\n }\n\n await actor.permissionEvaluator.evaluate({\n name: PermissionName.PERMISSION_DELETE,\n data: definePolicyData({ [BuiltInPolicyType.ATTRIBUTES]: entity, ...this.resourceRealmMatch(entity) }),\n });\n\n const { id: entityId } = entity;\n await this.repository.remove(entity);\n entity.id = entityId;\n\n return entity;\n }\n\n /**\n * Assign the system.default policy to a newly created permission.\n * This ensures all permissions are evaluated with the baseline security\n * policy (identity, permission-binding, realm-match) by default.\n */\n private async assignDefaultPolicy(permission: Permission): Promise<void> {\n const defaultPolicy = await this.policyRepository.findOneByName(SystemPolicyName.DEFAULT);\n if (!defaultPolicy) {\n throw new AuthupError(`The ${SystemPolicyName.DEFAULT} policy is not provisioned. Cannot create permissions without the default security policy.`);\n }\n\n const existing = await this.permissionPolicyRepository.findOneBy({\n permissionId: permission.id,\n policyId: defaultPolicy.id,\n });\n if (existing) {\n return;\n }\n\n const entry = this.permissionPolicyRepository.create({\n permissionId: permission.id,\n permissionRealmId: permission.realmId,\n policyId: defaultPolicy.id,\n policyRealmId: defaultPolicy.realmId,\n });\n await this.permissionPolicyRepository.save(entry);\n }\n\n /**\n * Assign a newly created permission to the global admin role.\n * The admin role receives every permission without policy restrictions.\n *\n * Throws when the admin role is not provisioned: without an admin grant the\n * permission is bound by `system.default` yet held by nobody, and the uniform\n * member gate on junction creation makes it permanently un-grantable (even by\n * admin). Fail loud so the stranded state is surfaced instead of swallowed.\n */\n private async assignToAdminRole(permission: Permission): Promise<void> {\n const adminRole = await this.roleRepository.findOneByName(ROLE_ADMIN_NAME);\n if (!adminRole) {\n throw new AuthupError(`The ${ROLE_ADMIN_NAME} role is not provisioned. Cannot grant the created permission to the administrator role.`);\n }\n\n const existing = await this.rolePermissionRepository.findOneBy({\n roleId: adminRole.id,\n permissionId: permission.id,\n });\n if (existing) {\n return;\n }\n\n const entry = this.rolePermissionRepository.create({\n roleId: adminRole.id,\n roleRealmId: adminRole.realmId,\n permissionId: permission.id,\n permissionRealmId: permission.realmId,\n // Global admin: unrestricted realm reach.\n realmScope: RealmScope.ANY,\n });\n await this.rolePermissionRepository.save(entry);\n }\n\n /**\n * Assign a newly created permission to all matching realm_admin roles.\n *\n * Uses differentiated realmScope on the junction:\n * - CUD on global-capable entity types → own (strictly own realm)\n * - Everything else → ownOrNull (own realm + null/global resources)\n *\n * Eligible permissions:\n * - Built-in authup permissions (global) — assigned to all realm_admin roles\n * - Realm-scoped permissions — assigned to the realm_admin in the matching realm\n *\n * Excluded:\n * - Realm CRUD permissions (realm_create, realm_update, realm_delete)\n * - Custom global permissions (non-built-in with realmId: null)\n */\n private async assignToRealmAdminRoles(permission: Permission): Promise<void> {\n if (REALM_ADMIN_EXCLUDED_PERMISSIONS.includes(permission.name as PermissionName)) {\n return;\n }\n\n const isBuiltIn = (Object.values(PermissionName) as string[]).includes(permission.name);\n if (!permission.realmId && !isBuiltIn) {\n return;\n }\n\n const realmScope = REALM_ADMIN_BOUND_PERMISSIONS.includes(permission.name as PermissionName) ?\n RealmScope.OWN :\n RealmScope.OWN_OR_NULL;\n\n const realmAdminRoles = await this.roleRepository.findManyBy({ name: ROLE_REALM_ADMIN_NAME });\n\n for (const role of realmAdminRoles) {\n if (permission.realmId && permission.realmId !== role.realmId) {\n continue;\n }\n\n const existing = await this.rolePermissionRepository.findOneBy({\n roleId: role.id,\n permissionId: permission.id,\n });\n if (existing) {\n continue;\n }\n\n const entry = this.rolePermissionRepository.create({\n roleId: role.id,\n roleRealmId: role.realmId,\n permissionId: permission.id,\n permissionRealmId: permission.realmId,\n realmScope,\n });\n await this.rolePermissionRepository.save(entry);\n }\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"schema.mjs","names":["defineSchema","EntityType","createRelationsReadGate","schemaMapping","permission","PERMISSION","policy","POLICY","permissionPolicySchema","name","PERMISSION_POLICY","fields","default","filters","allowed","relations","validate","sort","pagination","maxLimit"],"sources":["../../../../src/core/entities/permission-policy/schema.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { defineSchema } from '@rapiq/core';\nimport type { PermissionPolicy } from '@authup/core-kit';\nimport { EntityType } from '@authup/core-kit';\nimport { createRelationsReadGate } from '../../query/relations.ts';\n\nconst schemaMapping = { permission: EntityType.PERMISSION, policy: EntityType.POLICY };\n\nexport const permissionPolicySchema = defineSchema<PermissionPolicy>({\n name: EntityType.PERMISSION_POLICY,\n // see user-role schema — explicit root projection for include= decodes\n fields: {\n default: [\n 'id',\n 'permissionId',\n 'permissionRealmId',\n 'policyId',\n 'policyRealmId',\n 'createdAt',\n 'updatedAt',\n ],\n },\n filters: { allowed: ['permissionId', 'policyId'] },\n relations: { allowed: ['permission', 'policy'], validate: createRelationsReadGate(schemaMapping) },\n sort: { allowed: ['id', 'createdAt', 'updatedAt'] },\n pagination: { maxLimit: 50 },\n schemaMapping,\n});\n"],"mappings":";;;;;;;AAYA,MAAMG,gBAAgB;CAAEC,YAAYH,WAAWI;CAAYC,QAAQL,WAAWM;AAAO;AAErF,MAAaC,yBAAyBR,aAA+B;CACjES,MAAMR,WAAWS;CAEjBC,QAAQ,EACJC,SAAS;EACL;EACA;EACA;EACA;EACA;EACA;EACA;GAER;CACAC,SAAS,EAAEC,SAAS,CAAC,gBAAgB,UAAA,EAAY;CACjDC,WAAW;EAAED,SAAS,CAAC,cAAc,QAAA;EAAWE,UAAUd,wBAAwBC,aAAAA;CAAe;CACjGc,MAAM,EAAEH,SAAS;EAAC;EAAM;EAAa;GAAa;CAClDI,YAAY,EAAEC,UAAU,GAAG;CAC3BhB;AACJ,CAAA"}
1
+ {"version":3,"file":"schema.mjs","names":["defineSchema","EntityType","createRelationsReadGate","schemaMapping","permission","PERMISSION","policy","POLICY","permissionPolicySchema","name","PERMISSION_POLICY","fields","default","filters","allowed","relations","validate","sort","pagination","maxLimit"],"sources":["../../../../src/core/entities/permission-policy/schema.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { defineSchema } from '@rapiq/core';\nimport type { PermissionPolicy } from '@authup/core-kit';\nimport { EntityType } from '@authup/core-kit';\nimport { createRelationsReadGate } from '../../query/relations.ts';\n\nconst schemaMapping = { permission: EntityType.PERMISSION, policy: EntityType.POLICY };\n\nexport const permissionPolicySchema = defineSchema<PermissionPolicy>({\n name: EntityType.PERMISSION_POLICY,\n // see user-role schema — explicit root projection for include= decodes\n fields: {\n default: [\n 'id',\n 'permissionId',\n 'permissionRealmId',\n 'policyId',\n 'policyRealmId',\n 'createdAt',\n 'updatedAt',\n ],\n },\n filters: { allowed: ['permissionId', 'policyId'] },\n relations: { allowed: ['permission', 'policy'], validate: createRelationsReadGate(schemaMapping) },\n sort: { allowed: ['id', 'createdAt', 'updatedAt'] },\n pagination: { maxLimit: 50 },\n schemaMapping,\n});\n"],"mappings":";;;;;;;AAYA,MAAMG,gBAAgB;CAAEC,YAAYH,WAAWI;CAAYC,QAAQL,WAAWM;AAAO;AAErF,MAAaC,yBAAyBR,aAA+B;CACjES,MAAMR,WAAWS;CAEjBC,QAAQ,EACJC,SAAS;EACL;EACA;EACA;EACA;EACA;EACA;EACA;CACH,EACL;CACAC,SAAS,EAAEC,SAAS,CAAC,gBAAgB,UAAW,EAAC;CACjDC,WAAW;EAAED,SAAS,CAAC,cAAc,QAAS;EAAEE,UAAUd,wBAAwBC,aAAAA;CAAe;CACjGc,MAAM,EAAEH,SAAS;EAAC;EAAM;EAAa;CAAY,EAAC;CAClDI,YAAY,EAAEC,UAAU,GAAG;CAC3BhB;AACJ,CAAA"}