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

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 +218 -218
  323. package/dist/ui/client/assets/index-CiHrf73J.css +2 -0
  324. package/dist/ui/client/assets/{index-BmJ2X468.js → index-mtJngmng.js} +1 -1
  325. package/dist/ui/client/index.html +2 -2
  326. package/dist/ui/server/server.js +534 -79
  327. package/package.json +26 -26
  328. package/dist/ui/client/assets/index-DiOvW76Q.css +0 -2
@@ -1 +1 @@
1
- {"version":3,"file":"session.mjs","names":["buildCacheKey","applyQuery","applyRealmScopeSelect","AuthenticationCachePrefix","SessionRepository","cache","repository","ctx","findOneById","id","session","get","prefix","SESSION","key","findOneBy","findMany","query","options","qb","createQueryBuilder","pagination","owner","andWhere","ownerSub","sub","ownerSubKind","subKind","entities","total","getManyAndCount","data","meta","findAllByOwner","where","getMany","findAllByQuery","save","input","create","set","ttl","Date","expiresAt","getTime","now","remove","drop","removeById"],"sources":["../../../../../src/app/modules/authentication/repositories/session.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 type { Session } from '@authup/core-kit';\nimport type { IQuery } from '@rapiq/core';\nimport type { EntityRepositoryFindManyResult, ICache } from '@authup/server-kit';\nimport { buildCacheKey } from '@authup/server-kit';\nimport type { Repository } from 'typeorm';\nimport { applyQuery } from '../../database/repositories/query.ts';\nimport type {\n ISessionRepository,\n SessionFindManyOptions,\n SessionOwner,\n} from '../../../../core/index.ts';\nimport { applyRealmScopeSelect } from '../../database/repositories/helpers.ts';\nimport { AuthenticationCachePrefix } from './constants.ts';\n\ntype SessionRepositoryContext = {\n repository: Repository<Session>,\n cache: ICache\n};\n\nexport class SessionRepository implements ISessionRepository {\n protected cache : ICache;\n\n protected repository : Repository<Session>;\n\n // -----------------------------------------------------\n\n constructor(ctx: SessionRepositoryContext) {\n this.cache = ctx.cache;\n this.repository = ctx.repository;\n }\n\n // -----------------------------------------------------\n\n async findOneById(id: string): Promise<Session | null> {\n const session = await this.cache.get<Session>(\n buildCacheKey({\n prefix: AuthenticationCachePrefix.SESSION,\n key: id, \n }),\n );\n\n if (session) {\n return session;\n }\n\n return this.repository.findOneBy({ id });\n }\n\n // -----------------------------------------------------\n\n async findMany(\n query: IQuery,\n options: SessionFindManyOptions = {},\n ): Promise<EntityRepositoryFindManyResult<Session>> {\n const qb = this.repository.createQueryBuilder('session');\n\n const { pagination } = applyQuery(qb, query);\n\n applyRealmScopeSelect(qb, 'session', ['sub', 'subKind']);\n\n if (options.owner) {\n // mandatory constraint — not overridable by a rapiq filter\n qb.andWhere('session.sub = :ownerSub AND session.subKind = :ownerSubKind', {\n ownerSub: options.owner.sub,\n ownerSubKind: options.owner.subKind,\n });\n }\n\n const [entities, total] = await qb.getManyAndCount();\n\n return {\n data: entities,\n meta: {\n total,\n ...pagination,\n },\n };\n }\n\n async findAllByOwner(owner: SessionOwner): Promise<Session[]> {\n return this.repository.createQueryBuilder('session')\n .where('session.sub = :sub AND session.subKind = :subKind', {\n sub: owner.sub,\n subKind: owner.subKind,\n })\n .getMany();\n }\n\n async findAllByQuery(query: IQuery): Promise<Session[]> {\n const qb = this.repository.createQueryBuilder('session');\n\n // NOTE: `parameters: ['filters']` — a bulk revoke must reach every\n // matching row. Applying the schema's `pagination.maxLimit` would\n // default the limit to that cap when the caller sends no page (rapiq\n // `finalizePagination`), silently truncating the delete.\n applyQuery(qb, query);\n\n applyRealmScopeSelect(qb, 'session', ['sub', 'subKind']);\n\n return qb.getMany();\n }\n\n // -----------------------------------------------------\n\n async save(input: Partial<Session>): Promise<Session> {\n const session = this.repository.create(input);\n await this.repository.save(session);\n\n await this.cache.set(\n buildCacheKey({\n prefix: AuthenticationCachePrefix.SESSION,\n key: session.id, \n }),\n session,\n { ttl: new Date(session.expiresAt).getTime() - Date.now() },\n );\n\n return session;\n }\n\n // -----------------------------------------------------\n\n async remove(session: Session): Promise<void> {\n await this.repository.remove(session);\n await this.cache.drop(\n buildCacheKey({\n prefix: AuthenticationCachePrefix.SESSION,\n key: session.id, \n }),\n );\n }\n\n async removeById(id: string): Promise<void> {\n const session = await this.findOneById(id);\n\n if (session) {\n await this.remove(session);\n }\n }\n}\n"],"mappings":";;;;;;;;AA0BA,IAAaI,oBAAb,MAAaA;CACCC;CAEAC;CAIV,YAAYC,KAA+B;EACvC,KAAKF,QAAQE,IAAIF;EACjB,KAAKC,aAAaC,IAAID;CAC1B;CAIA,MAAME,YAAYC,IAAqC;EACnD,MAAMC,UAAU,MAAM,KAAKL,MAAMM,IAC7BX,cAAc;GACVY,QAAQT,0BAA0BU;GAClCC,KAAKL;EACT,CAAA,CAAA;EAGJ,IAAIC,SACA,OAAOA;EAGX,OAAO,KAAKJ,WAAWS,UAAU,EAAEN,GAAG,CAAA;CAC1C;CAIA,MAAMO,SACFC,OACAC,UAAkC,CAAC,GACa;EAChD,MAAMC,KAAK,KAAKb,WAAWc,mBAAmB,SAAA;EAE9C,MAAM,EAAEC,eAAepB,WAAWkB,IAAIF,KAAAA;EAEtCf,sBAAsBiB,IAAI,WAAW,CAAC,OAAO,SAAA,CAAU;EAEvD,IAAID,QAAQI,OAERH,GAAGI,SAAS,+DAA+D;GACvEC,UAAUN,QAAQI,MAAMG;GACxBC,cAAcR,QAAQI,MAAMK;EAChC,CAAA;EAGJ,MAAM,CAACC,UAAUC,SAAS,MAAMV,GAAGW,gBAAe;EAElD,OAAO;GACHC,MAAMH;GACNI,MAAM;IACFH;IACA,GAAGR;GACP;EACJ;CACJ;CAEA,MAAMY,eAAeX,OAAyC;EAC1D,OAAO,KAAKhB,WAAWc,mBAAmB,SAAA,CAAA,CACrCc,MAAM,qDAAqD;GACxDT,KAAKH,MAAMG;GACXE,SAASL,MAAMK;EACnB,CAAA,CAAA,CACCQ,QAAO;CAChB;CAEA,MAAMC,eAAenB,OAAmC;EACpD,MAAME,KAAK,KAAKb,WAAWc,mBAAmB,SAAA;EAM9CnB,WAAWkB,IAAIF,KAAAA;EAEff,sBAAsBiB,IAAI,WAAW,CAAC,OAAO,SAAA,CAAU;EAEvD,OAAOA,GAAGgB,QAAO;CACrB;CAIA,MAAME,KAAKC,OAA2C;EAClD,MAAM5B,UAAU,KAAKJ,WAAWiC,OAAOD,KAAAA;EACvC,MAAM,KAAKhC,WAAW+B,KAAK3B,OAAAA;EAE3B,MAAM,KAAKL,MAAMmC,IACbxC,cAAc;GACVY,QAAQT,0BAA0BU;GAClCC,KAAKJ,QAAQD;EACjB,CAAA,GACAC,SACA,EAAE+B,KAAK,IAAIC,KAAKhC,QAAQiC,SAAS,CAAA,CAAEC,QAAO,IAAKF,KAAKG,IAAG,EAAG,CAAA;EAG9D,OAAOnC;CACX;CAIA,MAAMoC,OAAOpC,SAAiC;EAC1C,MAAM,KAAKJ,WAAWwC,OAAOpC,OAAAA;EAC7B,MAAM,KAAKL,MAAM0C,KACb/C,cAAc;GACVY,QAAQT,0BAA0BU;GAClCC,KAAKJ,QAAQD;EACjB,CAAA,CAAA;CAER;CAEA,MAAMuC,WAAWvC,IAA2B;EACxC,MAAMC,UAAU,MAAM,KAAKF,YAAYC,EAAAA;EAEvC,IAAIC,SACA,MAAM,KAAKoC,OAAOpC,OAAAA;CAE1B;AACJ"}
1
+ {"version":3,"file":"session.mjs","names":["buildCacheKey","applyQuery","applyRealmScopeSelect","AuthenticationCachePrefix","SessionRepository","cache","repository","ctx","findOneById","id","session","get","prefix","SESSION","key","findOneBy","findMany","query","options","qb","createQueryBuilder","pagination","owner","andWhere","ownerSub","sub","ownerSubKind","subKind","entities","total","getManyAndCount","data","meta","findAllByOwner","where","getMany","findAllByQuery","save","input","create","set","ttl","Date","expiresAt","getTime","now","remove","drop","removeById"],"sources":["../../../../../src/app/modules/authentication/repositories/session.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 type { Session } from '@authup/core-kit';\nimport type { IQuery } from '@rapiq/core';\nimport type { EntityRepositoryFindManyResult, ICache } from '@authup/server-kit';\nimport { buildCacheKey } from '@authup/server-kit';\nimport type { Repository } from 'typeorm';\nimport { applyQuery } from '../../database/repositories/query.ts';\nimport type {\n ISessionRepository,\n SessionFindManyOptions,\n SessionOwner,\n} from '../../../../core/index.ts';\nimport { applyRealmScopeSelect } from '../../database/repositories/helpers.ts';\nimport { AuthenticationCachePrefix } from './constants.ts';\n\ntype SessionRepositoryContext = {\n repository: Repository<Session>,\n cache: ICache\n};\n\nexport class SessionRepository implements ISessionRepository {\n protected cache : ICache;\n\n protected repository : Repository<Session>;\n\n // -----------------------------------------------------\n\n constructor(ctx: SessionRepositoryContext) {\n this.cache = ctx.cache;\n this.repository = ctx.repository;\n }\n\n // -----------------------------------------------------\n\n async findOneById(id: string): Promise<Session | null> {\n const session = await this.cache.get<Session>(\n buildCacheKey({\n prefix: AuthenticationCachePrefix.SESSION,\n key: id, \n }),\n );\n\n if (session) {\n return session;\n }\n\n return this.repository.findOneBy({ id });\n }\n\n // -----------------------------------------------------\n\n async findMany(\n query: IQuery,\n options: SessionFindManyOptions = {},\n ): Promise<EntityRepositoryFindManyResult<Session>> {\n const qb = this.repository.createQueryBuilder('session');\n\n const { pagination } = applyQuery(qb, query);\n\n applyRealmScopeSelect(qb, 'session', ['sub', 'subKind']);\n\n if (options.owner) {\n // mandatory constraint — not overridable by a rapiq filter\n qb.andWhere('session.sub = :ownerSub AND session.subKind = :ownerSubKind', {\n ownerSub: options.owner.sub,\n ownerSubKind: options.owner.subKind,\n });\n }\n\n const [entities, total] = await qb.getManyAndCount();\n\n return {\n data: entities,\n meta: {\n total,\n ...pagination,\n },\n };\n }\n\n async findAllByOwner(owner: SessionOwner): Promise<Session[]> {\n return this.repository.createQueryBuilder('session')\n .where('session.sub = :sub AND session.subKind = :subKind', {\n sub: owner.sub,\n subKind: owner.subKind,\n })\n .getMany();\n }\n\n async findAllByQuery(query: IQuery): Promise<Session[]> {\n const qb = this.repository.createQueryBuilder('session');\n\n // NOTE: `parameters: ['filters']` — a bulk revoke must reach every\n // matching row. Applying the schema's `pagination.maxLimit` would\n // default the limit to that cap when the caller sends no page (rapiq\n // `finalizePagination`), silently truncating the delete.\n applyQuery(qb, query);\n\n applyRealmScopeSelect(qb, 'session', ['sub', 'subKind']);\n\n return qb.getMany();\n }\n\n // -----------------------------------------------------\n\n async save(input: Partial<Session>): Promise<Session> {\n const session = this.repository.create(input);\n await this.repository.save(session);\n\n await this.cache.set(\n buildCacheKey({\n prefix: AuthenticationCachePrefix.SESSION,\n key: session.id, \n }),\n session,\n { ttl: new Date(session.expiresAt).getTime() - Date.now() },\n );\n\n return session;\n }\n\n // -----------------------------------------------------\n\n async remove(session: Session): Promise<void> {\n await this.repository.remove(session);\n await this.cache.drop(\n buildCacheKey({\n prefix: AuthenticationCachePrefix.SESSION,\n key: session.id, \n }),\n );\n }\n\n async removeById(id: string): Promise<void> {\n const session = await this.findOneById(id);\n\n if (session) {\n await this.remove(session);\n }\n }\n}\n"],"mappings":";;;;;;;;AA0BA,IAAaI,oBAAb,MAAaA;CACCC;CAEAC;CAIV,YAAYC,KAA+B;EACvC,KAAKF,QAAQE,IAAIF;EACjB,KAAKC,aAAaC,IAAID;CAC1B;CAIA,MAAME,YAAYC,IAAqC;EACnD,MAAMC,UAAU,MAAM,KAAKL,MAAMM,IAC7BX,cAAc;GACVY,QAAQT,0BAA0BU;GAClCC,KAAKL;EACT,CAAA,CAAA;EAGJ,IAAIC,SACA,OAAOA;EAGX,OAAO,KAAKJ,WAAWS,UAAU,EAAEN,GAAG,CAAA;CAC1C;CAIA,MAAMO,SACFC,OACAC,UAAkC,CAAC,GACa;EAChD,MAAMC,KAAK,KAAKb,WAAWc,mBAAmB,SAAA;EAE9C,MAAM,EAAEC,eAAepB,WAAWkB,IAAIF,KAAAA;EAEtCf,sBAAsBiB,IAAI,WAAW,CAAC,OAAO,SAAU,CAAA;EAEvD,IAAID,QAAQI,OAERH,GAAGI,SAAS,+DAA+D;GACvEC,UAAUN,QAAQI,MAAMG;GACxBC,cAAcR,QAAQI,MAAMK;EAChC,CAAA;EAGJ,MAAM,CAACC,UAAUC,SAAS,MAAMV,GAAGW,gBAAe;EAElD,OAAO;GACHC,MAAMH;GACNI,MAAM;IACFH;IACA,GAAGR;GACP;EACJ;CACJ;CAEA,MAAMY,eAAeX,OAAyC;EAC1D,OAAO,KAAKhB,WAAWc,mBAAmB,SAAA,CAAA,CACrCc,MAAM,qDAAqD;GACxDT,KAAKH,MAAMG;GACXE,SAASL,MAAMK;EACnB,CAAA,CAAA,CACCQ,QAAO;CAChB;CAEA,MAAMC,eAAenB,OAAmC;EACpD,MAAME,KAAK,KAAKb,WAAWc,mBAAmB,SAAA;EAM9CnB,WAAWkB,IAAIF,KAAAA;EAEff,sBAAsBiB,IAAI,WAAW,CAAC,OAAO,SAAU,CAAA;EAEvD,OAAOA,GAAGgB,QAAO;CACrB;CAIA,MAAME,KAAKC,OAA2C;EAClD,MAAM5B,UAAU,KAAKJ,WAAWiC,OAAOD,KAAAA;EACvC,MAAM,KAAKhC,WAAW+B,KAAK3B,OAAAA;EAE3B,MAAM,KAAKL,MAAMmC,IACbxC,cAAc;GACVY,QAAQT,0BAA0BU;GAClCC,KAAKJ,QAAQD;EACjB,CAAA,GACAC,SACA,EAAE+B,KAAK,IAAIC,KAAKhC,QAAQiC,SAAS,CAAA,CAAEC,QAAO,IAAKF,KAAKG,IAAG,EAAG,CAAA;EAG9D,OAAOnC;CACX;CAIA,MAAMoC,OAAOpC,SAAiC;EAC1C,MAAM,KAAKJ,WAAWwC,OAAOpC,OAAAA;EAC7B,MAAM,KAAKL,MAAM0C,KACb/C,cAAc;GACVY,QAAQT,0BAA0BU;GAClCC,KAAKJ,QAAQD;EACjB,CAAA,CAAA;CAER;CAEA,MAAMuC,WAAWvC,IAA2B;EACxC,MAAMC,UAAU,MAAM,KAAKF,YAAYC,EAAAA;EAEvC,IAAIC,SACA,MAAM,KAAKoC,OAAOpC,OAAAA;CAE1B;AACJ"}
@@ -1 +1 @@
1
- {"version":3,"file":"module.mjs","names":["MemoryCache","RedisCache","ModuleName","CacheInjectionKey","ConfigInjectionKey","CacheModule","name","dependencies","CACHE","CONFIG","setup","container","result","tryResolve","success","data","redis","register","useFactory"],"sources":["../../../../src/app/modules/cache/module.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 { MemoryCache, RedisCache } from '@authup/server-kit';\nimport type { IModule } from 'orkos';\nimport { ModuleName } from '../constants.ts';\nimport { CacheInjectionKey } from './constants.ts';\nimport { ConfigInjectionKey } from '../config/index.ts';\nimport type { IContainer } from 'eldin';\n\nexport class CacheModule implements IModule {\n readonly name: string;\n\n readonly dependencies: string[];\n\n constructor() {\n this.name = ModuleName.CACHE;\n this.dependencies = [ModuleName.CONFIG];\n }\n\n async setup(container: IContainer): Promise<void> {\n const result = container.tryResolve(ConfigInjectionKey);\n if (!result.success || !result.data.redis) {\n container.register(CacheInjectionKey, { useFactory: () => new MemoryCache() });\n\n return;\n }\n\n container.register(CacheInjectionKey, { useFactory: () => new RedisCache(result.data.redis) });\n }\n}\n"],"mappings":";;;;;;;;;AAcA,IAAaK,cAAb,MAAaA;CACAC;CAEAC;CAET,cAAc;EACV,KAAKD,OAAOJ,WAAWM;EACvB,KAAKD,eAAe,CAACL,WAAWO,MAAAA;CACpC;CAEA,MAAMC,MAAMC,WAAsC;EAC9C,MAAMC,SAASD,UAAUE,WAAWT,kBAAAA;EACpC,IAAI,CAACQ,OAAOE,WAAW,CAACF,OAAOG,KAAKC,OAAO;GACvCL,UAAUM,SAASd,mBAAmB,EAAEe,kBAAkB,IAAIlB,YAAAA,EAAc,CAAA;GAE5E;EACJ;EAEAW,UAAUM,SAASd,mBAAmB,EAAEe,kBAAkB,IAAIjB,WAAWW,OAAOG,KAAKC,KAAK,EAAE,CAAA;CAChG;AACJ"}
1
+ {"version":3,"file":"module.mjs","names":["MemoryCache","RedisCache","ModuleName","CacheInjectionKey","ConfigInjectionKey","CacheModule","name","dependencies","CACHE","CONFIG","setup","container","result","tryResolve","success","data","redis","register","useFactory"],"sources":["../../../../src/app/modules/cache/module.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 { MemoryCache, RedisCache } from '@authup/server-kit';\nimport type { IModule } from 'orkos';\nimport { ModuleName } from '../constants.ts';\nimport { CacheInjectionKey } from './constants.ts';\nimport { ConfigInjectionKey } from '../config/index.ts';\nimport type { IContainer } from 'eldin';\n\nexport class CacheModule implements IModule {\n readonly name: string;\n\n readonly dependencies: string[];\n\n constructor() {\n this.name = ModuleName.CACHE;\n this.dependencies = [ModuleName.CONFIG];\n }\n\n async setup(container: IContainer): Promise<void> {\n const result = container.tryResolve(ConfigInjectionKey);\n if (!result.success || !result.data.redis) {\n container.register(CacheInjectionKey, { useFactory: () => new MemoryCache() });\n\n return;\n }\n\n container.register(CacheInjectionKey, { useFactory: () => new RedisCache(result.data.redis) });\n }\n}\n"],"mappings":";;;;;;;;;AAcA,IAAaK,cAAb,MAAaA;CACAC;CAEAC;CAET,cAAc;EACV,KAAKD,OAAOJ,WAAWM;EACvB,KAAKD,eAAe,CAACL,WAAWO,MAAO;CAC3C;CAEA,MAAMC,MAAMC,WAAsC;EAC9C,MAAMC,SAASD,UAAUE,WAAWT,kBAAAA;EACpC,IAAI,CAACQ,OAAOE,WAAW,CAACF,OAAOG,KAAKC,OAAO;GACvCL,UAAUM,SAASd,mBAAmB,EAAEe,kBAAkB,IAAIlB,YAAAA,EAAc,CAAA;GAE5E;EACJ;EAEAW,UAAUM,SAASd,mBAAmB,EAAEe,kBAAkB,IAAIjB,WAAWW,OAAOG,KAAKC,KAAK,EAAE,CAAA;CAChG;AACJ"}
@@ -1 +1 @@
1
- {"version":3,"file":"module.mjs","names":["createDatabaseUniqueEntriesComponent","createEventCleanerComponent","createOAuth2CleanerComponent","ConfigInjectionKey","DatabaseInjectionKey","LoggerInjectionKey","ModuleName","ComponentsModule","name","dependencies","COMPONENTS","CONFIG","LOGGER","DATABASE","setup","container","config","resolve","dataSource","DataSource","logger","components","securitySweep","eventLogRetentionDays","entitySweep","eventLogEntityEnabled","eventLogEntityRetentionDays","eventLogEnabled","push","forEach","component","start","catch","e","error"],"sources":["../../../../src/app/modules/components/module.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 type { Component } from '../../../components/index.ts';\nimport {\n createDatabaseUniqueEntriesComponent,\n createEventCleanerComponent,\n createOAuth2CleanerComponent,\n} from '../../../components/index.ts';\nimport { ConfigInjectionKey } from '../config/index.ts';\nimport { DatabaseInjectionKey } from '../database/index.ts';\nimport { LoggerInjectionKey } from '../logger/index.ts';\nimport type { IModule } from 'orkos';\nimport { ModuleName } from '../constants.ts';\nimport type { IContainer } from 'eldin';\n\nexport class ComponentsModule implements IModule {\n readonly name: string;\n\n readonly dependencies: string[];\n\n constructor() {\n this.name = ModuleName.COMPONENTS;\n this.dependencies = [ModuleName.CONFIG, ModuleName.LOGGER, ModuleName.DATABASE];\n }\n\n async setup(container: IContainer): Promise<void> {\n const config = container.resolve(ConfigInjectionKey);\n const dataSource = container.resolve(DatabaseInjectionKey.DataSource);\n const logger = container.resolve(LoggerInjectionKey);\n\n const components: Component[] = [\n createOAuth2CleanerComponent(dataSource, logger),\n createDatabaseUniqueEntriesComponent(dataSource),\n ];\n\n // The sweep only exists when rows are written AND at least one row\n // family carries an expiry — security events (eventLogRetentionDays)\n // and entity-CRUD events (eventLogEntityRetentionDays) are stamped\n // independently, so either non-zero retention needs the cleaner.\n const securitySweep = config.eventLogRetentionDays > 0;\n const entitySweep = config.eventLogEntityEnabled && config.eventLogEntityRetentionDays > 0;\n if (config.eventLogEnabled && (securitySweep || entitySweep)) {\n components.push(createEventCleanerComponent(dataSource, logger));\n }\n\n // start() is deliberately fire-and-forget, so a rejection must be\n // caught here — an unhandled rejection is fatal on modern node.\n components.forEach((component) => {\n component.start().catch((e) => {\n logger.error('Starting a background component failed.');\n logger.error(e);\n });\n });\n }\n\n // ----------------------------------------------------\n}\n"],"mappings":";;;;;;;;;;;;;;;AAoBA,IAAaO,mBAAb,MAAaA;CACAC;CAEAC;CAET,cAAc;EACV,KAAKD,OAAOF,WAAWI;EACvB,KAAKD,eAAe;GAACH,WAAWK;GAAQL,WAAWM;GAAQN,WAAWO;;CAC1E;CAEA,MAAMC,MAAMC,WAAsC;EAC9C,MAAMC,SAASD,UAAUE,QAAQd,kBAAAA;EACjC,MAAMe,aAAaH,UAAUE,QAAQb,qBAAqBe,UAAU;EACpE,MAAMC,SAASL,UAAUE,QAAQZ,kBAAAA;EAEjC,MAAMgB,aAA0B,CAC5BnB,6BAA6BgB,YAAYE,MAAAA,GACzCpB,qCAAqCkB,UAAAA,CAAAA;EAOzC,MAAMI,gBAAgBN,OAAOO,wBAAwB;EACrD,MAAMC,cAAcR,OAAOS,yBAAyBT,OAAOU,8BAA8B;EACzF,IAAIV,OAAOW,oBAAoBL,iBAAiBE,cAC5CH,WAAWO,KAAK3B,4BAA4BiB,YAAYE,MAAAA,CAAAA;EAK5DC,WAAWQ,SAASC,cAAAA;GAChBA,UAAUC,MAAK,CAAA,CAAGC,OAAOC,MAAAA;IACrBb,OAAOc,MAAM,yCAAA;IACbd,OAAOc,MAAMD,CAAAA;GACjB,CAAA;EACJ,CAAA;CACJ;AAGJ"}
1
+ {"version":3,"file":"module.mjs","names":["createDatabaseUniqueEntriesComponent","createEventCleanerComponent","createOAuth2CleanerComponent","ConfigInjectionKey","DatabaseInjectionKey","LoggerInjectionKey","ModuleName","ComponentsModule","name","dependencies","COMPONENTS","CONFIG","LOGGER","DATABASE","setup","container","config","resolve","dataSource","DataSource","logger","components","securitySweep","eventLogRetentionDays","entitySweep","eventLogEntityEnabled","eventLogEntityRetentionDays","eventLogEnabled","push","forEach","component","start","catch","e","error"],"sources":["../../../../src/app/modules/components/module.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 type { Component } from '../../../components/index.ts';\nimport {\n createDatabaseUniqueEntriesComponent,\n createEventCleanerComponent,\n createOAuth2CleanerComponent,\n} from '../../../components/index.ts';\nimport { ConfigInjectionKey } from '../config/index.ts';\nimport { DatabaseInjectionKey } from '../database/index.ts';\nimport { LoggerInjectionKey } from '../logger/index.ts';\nimport type { IModule } from 'orkos';\nimport { ModuleName } from '../constants.ts';\nimport type { IContainer } from 'eldin';\n\nexport class ComponentsModule implements IModule {\n readonly name: string;\n\n readonly dependencies: string[];\n\n constructor() {\n this.name = ModuleName.COMPONENTS;\n this.dependencies = [ModuleName.CONFIG, ModuleName.LOGGER, ModuleName.DATABASE];\n }\n\n async setup(container: IContainer): Promise<void> {\n const config = container.resolve(ConfigInjectionKey);\n const dataSource = container.resolve(DatabaseInjectionKey.DataSource);\n const logger = container.resolve(LoggerInjectionKey);\n\n const components: Component[] = [\n createOAuth2CleanerComponent(dataSource, logger),\n createDatabaseUniqueEntriesComponent(dataSource),\n ];\n\n // The sweep only exists when rows are written AND at least one row\n // family carries an expiry — security events (eventLogRetentionDays)\n // and entity-CRUD events (eventLogEntityRetentionDays) are stamped\n // independently, so either non-zero retention needs the cleaner.\n const securitySweep = config.eventLogRetentionDays > 0;\n const entitySweep = config.eventLogEntityEnabled && config.eventLogEntityRetentionDays > 0;\n if (config.eventLogEnabled && (securitySweep || entitySweep)) {\n components.push(createEventCleanerComponent(dataSource, logger));\n }\n\n // start() is deliberately fire-and-forget, so a rejection must be\n // caught here — an unhandled rejection is fatal on modern node.\n components.forEach((component) => {\n component.start().catch((e) => {\n logger.error('Starting a background component failed.');\n logger.error(e);\n });\n });\n }\n\n // ----------------------------------------------------\n}\n"],"mappings":";;;;;;;;;;;;;;;AAoBA,IAAaO,mBAAb,MAAaA;CACAC;CAEAC;CAET,cAAc;EACV,KAAKD,OAAOF,WAAWI;EACvB,KAAKD,eAAe;GAACH,WAAWK;GAAQL,WAAWM;GAAQN,WAAWO;EAAS;CACnF;CAEA,MAAMC,MAAMC,WAAsC;EAC9C,MAAMC,SAASD,UAAUE,QAAQd,kBAAAA;EACjC,MAAMe,aAAaH,UAAUE,QAAQb,qBAAqBe,UAAU;EACpE,MAAMC,SAASL,UAAUE,QAAQZ,kBAAAA;EAEjC,MAAMgB,aAA0B,CAC5BnB,6BAA6BgB,YAAYE,MAAAA,GACzCpB,qCAAqCkB,UAAAA,CACxC;EAMD,MAAMI,gBAAgBN,OAAOO,wBAAwB;EACrD,MAAMC,cAAcR,OAAOS,yBAAyBT,OAAOU,8BAA8B;EACzF,IAAIV,OAAOW,oBAAoBL,iBAAiBE,cAC5CH,WAAWO,KAAK3B,4BAA4BiB,YAAYE,MAAAA,CAAAA;EAK5DC,WAAWQ,SAASC,cAAAA;GAChBA,UAAUC,MAAK,CAAA,CAAGC,OAAOC,MAAAA;IACrBb,OAAOc,MAAM,yCAAA;IACbd,OAAOc,MAAMD,CAAAA;GACjB,CAAA;EACJ,CAAA;CACJ;AAGJ"}
@@ -1 +1 @@
1
- {"version":3,"file":"constants.mjs","names":["TypedToken","ConfigInjectionKey","ConfigEnvironmentVariableName"],"sources":["../../../../src/app/modules/config/constants.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 { TypedToken } from 'eldin';\nimport type { Config } from './types.ts';\n\nexport const ConfigInjectionKey = new TypedToken<Config>('Config');\n\nexport enum ConfigEnvironmentVariableName {\n NODE_ENV = 'NODE_ENV',\n WRITABLE_DIRECTORY_PATH = 'WRITABLE_DIRECTORY_PATH',\n\n REDIS = 'REDIS',\n SMTP = 'SMTP',\n\n HOST = 'HOST',\n PORT = 'PORT',\n PUBLIC_URL = 'PUBLIC_URL',\n MTLS_PUBLIC_URL = 'MTLS_PUBLIC_URL',\n CERTIFICATE_SOURCE = 'CERTIFICATE_SOURCE',\n TRUSTED_ORIGINS = 'TRUSTED_ORIGINS',\n TOKEN_ACCESS_MAX_AGE = 'TOKEN_ACCESS_MAX_AGE',\n TOKEN_REFRESH_MAX_AGE = 'TOKEN_REFRESH_MAX_AGE',\n TOKEN_REFRESH_GRACE_PERIOD = 'TOKEN_REFRESH_GRACE_PERIOD',\n PROMPT_LOGIN_MAX_AGE = 'PROMPT_LOGIN_MAX_AGE',\n END_SESSION_HINT_GRACE_PERIOD = 'END_SESSION_HINT_GRACE_PERIOD',\n REGISTRATION_ENABLED = 'REGISTRATION_ENABLED',\n EMAIL_VERIFICATION_ENABLED = 'EMAIL_VERIFICATION_ENABLED',\n PASSWORD_RECOVERY_ENABLED = 'PASSWORD_RECOVERY_ENABLED',\n PASSWORD_MIN_LENGTH = 'PASSWORD_MIN_LENGTH',\n\n EVENT_LOG_ENABLED = 'EVENT_LOG_ENABLED',\n EVENT_LOG_RETENTION_DAYS = 'EVENT_LOG_RETENTION_DAYS',\n EVENT_LOG_ENTITY_ENABLED = 'EVENT_LOG_ENTITY_ENABLED',\n EVENT_LOG_ENTITY_RETENTION_DAYS = 'EVENT_LOG_ENTITY_RETENTION_DAYS',\n LOGIN_ATTEMPT_THROTTLE_ENABLED = 'LOGIN_ATTEMPT_THROTTLE_ENABLED',\n LOGIN_ATTEMPT_THRESHOLD = 'LOGIN_ATTEMPT_THRESHOLD',\n LOGIN_ATTEMPT_WINDOW = 'LOGIN_ATTEMPT_WINDOW',\n\n SECRETS_ENCRYPTION_KEY = 'SECRETS_ENCRYPTION_KEY',\n\n MFA_ENABLED = 'MFA_ENABLED',\n MFA_REQUIRED = 'MFA_REQUIRED',\n MFA_FRESHNESS_MAX_AGE = 'MFA_FRESHNESS_MAX_AGE',\n MFA_TICKET_MAX_AGE = 'MFA_TICKET_MAX_AGE',\n\n CLIENT_AUTH_BASIC = 'CLIENT_AUTH_BASIC',\n CLIENT_SYSTEM_ENABLED = 'CLIENT_SYSTEM_ENABLED',\n CLIENT_SYSTEM_SECRET = 'CLIENT_SYSTEM_SECRET',\n CLIENT_SYSTEM_SECRET_RESET = 'CLIENT_SYSTEM_SECRET_RESET',\n\n USER_AUTH_BASIC = 'USER_AUTH_BASIC',\n USER_ADMIN_ENABLED = 'USER_ADMIN_ENABLED',\n USER_ADMIN_PASSWORD = 'USER_ADMIN_PASSWORD',\n USER_ADMIN_PASSWORD_RESET = 'USER_ADMIN_PASSWORD_RESET',\n\n PERMISSIONS = 'PERMISSIONS',\n PERMISSIONS_DEFAULT_POLICY_ASSIGNMENT = 'PERMISSIONS_DEFAULT_POLICY_ASSIGNMENT',\n}\n"],"mappings":";;;;;AAUA,MAAaC,qBAAqB,IAAID,WAAmB,QAAA;AAEzD,IAAO,gCAAKE,uBAAAA,+BAAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAAAA"}
1
+ {"version":3,"file":"constants.mjs","names":["TypedToken","ConfigInjectionKey","ConfigEnvironmentVariableName"],"sources":["../../../../src/app/modules/config/constants.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 { TypedToken } from 'eldin';\nimport type { Config } from './types.ts';\n\nexport const ConfigInjectionKey = new TypedToken<Config>('Config');\n\nexport enum ConfigEnvironmentVariableName {\n NODE_ENV = 'NODE_ENV',\n WRITABLE_DIRECTORY_PATH = 'WRITABLE_DIRECTORY_PATH',\n\n REDIS = 'REDIS',\n SMTP = 'SMTP',\n\n HOST = 'HOST',\n PORT = 'PORT',\n PUBLIC_URL = 'PUBLIC_URL',\n MTLS_PUBLIC_URL = 'MTLS_PUBLIC_URL',\n CERTIFICATE_SOURCE = 'CERTIFICATE_SOURCE',\n TRUSTED_ORIGINS = 'TRUSTED_ORIGINS',\n TOKEN_ACCESS_MAX_AGE = 'TOKEN_ACCESS_MAX_AGE',\n TOKEN_REFRESH_MAX_AGE = 'TOKEN_REFRESH_MAX_AGE',\n TOKEN_REFRESH_GRACE_PERIOD = 'TOKEN_REFRESH_GRACE_PERIOD',\n PROMPT_LOGIN_MAX_AGE = 'PROMPT_LOGIN_MAX_AGE',\n END_SESSION_HINT_GRACE_PERIOD = 'END_SESSION_HINT_GRACE_PERIOD',\n REGISTRATION_ENABLED = 'REGISTRATION_ENABLED',\n EMAIL_VERIFICATION_ENABLED = 'EMAIL_VERIFICATION_ENABLED',\n PASSWORD_RECOVERY_ENABLED = 'PASSWORD_RECOVERY_ENABLED',\n PASSWORD_MIN_LENGTH = 'PASSWORD_MIN_LENGTH',\n\n EVENT_LOG_ENABLED = 'EVENT_LOG_ENABLED',\n EVENT_LOG_RETENTION_DAYS = 'EVENT_LOG_RETENTION_DAYS',\n EVENT_LOG_ENTITY_ENABLED = 'EVENT_LOG_ENTITY_ENABLED',\n EVENT_LOG_ENTITY_RETENTION_DAYS = 'EVENT_LOG_ENTITY_RETENTION_DAYS',\n LOGIN_ATTEMPT_THROTTLE_ENABLED = 'LOGIN_ATTEMPT_THROTTLE_ENABLED',\n LOGIN_ATTEMPT_THRESHOLD = 'LOGIN_ATTEMPT_THRESHOLD',\n LOGIN_ATTEMPT_WINDOW = 'LOGIN_ATTEMPT_WINDOW',\n\n SECRETS_ENCRYPTION_KEY = 'SECRETS_ENCRYPTION_KEY',\n\n MFA_ENABLED = 'MFA_ENABLED',\n MFA_REQUIRED = 'MFA_REQUIRED',\n MFA_FRESHNESS_MAX_AGE = 'MFA_FRESHNESS_MAX_AGE',\n MFA_TICKET_MAX_AGE = 'MFA_TICKET_MAX_AGE',\n\n CLIENT_AUTH_BASIC = 'CLIENT_AUTH_BASIC',\n CLIENT_SYSTEM_ENABLED = 'CLIENT_SYSTEM_ENABLED',\n CLIENT_SYSTEM_SECRET = 'CLIENT_SYSTEM_SECRET',\n CLIENT_SYSTEM_SECRET_RESET = 'CLIENT_SYSTEM_SECRET_RESET',\n\n USER_AUTH_BASIC = 'USER_AUTH_BASIC',\n USER_ADMIN_ENABLED = 'USER_ADMIN_ENABLED',\n USER_ADMIN_PASSWORD = 'USER_ADMIN_PASSWORD',\n USER_ADMIN_PASSWORD_RESET = 'USER_ADMIN_PASSWORD_RESET',\n\n PERMISSIONS = 'PERMISSIONS',\n PERMISSIONS_DEFAULT_POLICY_ASSIGNMENT = 'PERMISSIONS_DEFAULT_POLICY_ASSIGNMENT',\n}\n"],"mappings":";;;;;AAUA,MAAaC,qBAAqB,IAAID,WAAmB,QAAA;AAEzD,IAAO,gCAAKE,uBAAAA,+BAAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAAA,OAAAA;AAkDX,EAAA,CAAA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"origins.mjs","names":["URL","SCHEME_REGEX","ALLOWED_PROTOCOLS","expandToOrigins","value","test","url","includes","protocol","Error","origin","getAppOrigins","config","origins","Set","add","publicUrl","trustedOrigins","Array","from"],"sources":["../../../../src/app/modules/config/origins.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 { URL } from 'node:url';\nimport type { Config } from './types.ts';\n\nconst SCHEME_REGEX = /^[a-z][a-z0-9+.-]*:\\/\\//i;\n\nconst ALLOWED_PROTOCOLS = ['http:', 'https:'];\n\n/**\n * Expand a configured trusted-origin value to its canonical origin(s).\n *\n * A value with an explicit scheme contributes exactly that origin —\n * the way to restrict a host to https only. A bare host[:port]\n * (e.g. `hub.local`) contributes both the http and https origin.\n *\n * Only http(s) is accepted: other schemes either have no usable web\n * origin (`new URL('myapp://x').origin` is the literal string \"null\")\n * or are meaningless as a redirect target for the web client — letting\n * them through would put garbage into a security-sensitive allowlist.\n *\n * Throws on values that don't parse as a URL/host or use another scheme.\n */\nexport function expandToOrigins(value: string): string[] {\n if (SCHEME_REGEX.test(value)) {\n const url = new URL(value);\n if (!ALLOWED_PROTOCOLS.includes(url.protocol)) {\n throw new Error(`A trusted origin must use the http or https protocol, got: ${url.protocol}`);\n }\n\n return [url.origin];\n }\n\n return [\n new URL(`http://${value}`).origin,\n new URL(`https://${value}`).origin,\n ];\n}\n\n/**\n * Derive the set of trusted application origins (scheme://host[:port]).\n *\n * publicUrl may carry a path, so its origin is extracted; trustedOrigins\n * entries are canonical origins — normalizeConfig owns that invariant\n * (expansion + dedupe via expandToOrigins) — and are merged verbatim.\n */\nexport function getAppOrigins(config: Pick<Config, 'publicUrl' | 'trustedOrigins'>): string[] {\n const origins = new Set<string>();\n origins.add(new URL(config.publicUrl).origin);\n\n for (const origin of config.trustedOrigins ?? []) {\n origins.add(origin);\n }\n\n return Array.from(origins);\n}\n"],"mappings":";;;;;AAUA,MAAMC,eAAe;AAErB,MAAMC,oBAAoB,CAAC,SAAS,QAAA;;;;;;;;;;;;;;GAgBpC,SAAgBC,gBAAgBC,OAAa;CACzC,IAAIH,aAAaI,KAAKD,KAAAA,GAAQ;EAC1B,MAAME,MAAM,IAAIN,IAAII,KAAAA;EACpB,IAAI,CAACF,kBAAkBK,SAASD,IAAIE,QAAQ,GACxC,MAAM,IAAIC,MAAM,8DAA8DH,IAAIE,UAAU;EAGhG,OAAO,CAACF,IAAII,MAAAA;CAChB;CAEA,OAAO,CACH,IAAIV,IAAI,UAAUI,OAAO,CAAA,CAAEM,QAC3B,IAAIV,IAAI,WAAWI,OAAO,CAAA,CAAEM,MAAAA;AAEpC;;;;;;;GASA,SAAgBC,cAAcC,QAAoD;CAC9E,MAAMC,0BAAU,IAAIC,IAAAA;CACpBD,QAAQE,IAAI,IAAIf,IAAIY,OAAOI,SAAS,CAAA,CAAEN,MAAM;CAE5C,KAAK,MAAMA,UAAUE,OAAOK,kBAAkB,CAAA,GAC1CJ,QAAQE,IAAIL,MAAAA;CAGhB,OAAOQ,MAAMC,KAAKN,OAAAA;AACtB"}
1
+ {"version":3,"file":"origins.mjs","names":["URL","SCHEME_REGEX","ALLOWED_PROTOCOLS","expandToOrigins","value","test","url","includes","protocol","Error","origin","getAppOrigins","config","origins","Set","add","publicUrl","trustedOrigins","Array","from"],"sources":["../../../../src/app/modules/config/origins.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 { URL } from 'node:url';\nimport type { Config } from './types.ts';\n\nconst SCHEME_REGEX = /^[a-z][a-z0-9+.-]*:\\/\\//i;\n\nconst ALLOWED_PROTOCOLS = ['http:', 'https:'];\n\n/**\n * Expand a configured trusted-origin value to its canonical origin(s).\n *\n * A value with an explicit scheme contributes exactly that origin —\n * the way to restrict a host to https only. A bare host[:port]\n * (e.g. `hub.local`) contributes both the http and https origin.\n *\n * Only http(s) is accepted: other schemes either have no usable web\n * origin (`new URL('myapp://x').origin` is the literal string \"null\")\n * or are meaningless as a redirect target for the web client — letting\n * them through would put garbage into a security-sensitive allowlist.\n *\n * Throws on values that don't parse as a URL/host or use another scheme.\n */\nexport function expandToOrigins(value: string): string[] {\n if (SCHEME_REGEX.test(value)) {\n const url = new URL(value);\n if (!ALLOWED_PROTOCOLS.includes(url.protocol)) {\n throw new Error(`A trusted origin must use the http or https protocol, got: ${url.protocol}`);\n }\n\n return [url.origin];\n }\n\n return [\n new URL(`http://${value}`).origin,\n new URL(`https://${value}`).origin,\n ];\n}\n\n/**\n * Derive the set of trusted application origins (scheme://host[:port]).\n *\n * publicUrl may carry a path, so its origin is extracted; trustedOrigins\n * entries are canonical origins — normalizeConfig owns that invariant\n * (expansion + dedupe via expandToOrigins) — and are merged verbatim.\n */\nexport function getAppOrigins(config: Pick<Config, 'publicUrl' | 'trustedOrigins'>): string[] {\n const origins = new Set<string>();\n origins.add(new URL(config.publicUrl).origin);\n\n for (const origin of config.trustedOrigins ?? []) {\n origins.add(origin);\n }\n\n return Array.from(origins);\n}\n"],"mappings":";;;;;AAUA,MAAMC,eAAe;AAErB,MAAMC,oBAAoB,CAAC,SAAS,QAAS;;;;;;;;;;;;;;GAgB7C,SAAgBC,gBAAgBC,OAAa;CACzC,IAAIH,aAAaI,KAAKD,KAAAA,GAAQ;EAC1B,MAAME,MAAM,IAAIN,IAAII,KAAAA;EACpB,IAAI,CAACF,kBAAkBK,SAASD,IAAIE,QAAQ,GACxC,MAAM,IAAIC,MAAM,8DAA8DH,IAAIE,UAAU;EAGhG,OAAO,CAACF,IAAII,MAAO;CACvB;CAEA,OAAO,CACH,IAAIV,IAAI,UAAUI,OAAO,CAAA,CAAEM,QAC3B,IAAIV,IAAI,WAAWI,OAAO,CAAA,CAAEM,MAC/B;AACL;;;;;;;GASA,SAAgBC,cAAcC,QAAoD;CAC9E,MAAMC,0BAAU,IAAIC,IAAAA;CACpBD,QAAQE,IAAI,IAAIf,IAAIY,OAAOI,SAAS,CAAA,CAAEN,MAAM;CAE5C,KAAK,MAAMA,UAAUE,OAAOK,kBAAkB,CAAA,GAC1CJ,QAAQE,IAAIL,MAAAA;CAGhB,OAAOQ,MAAMC,KAAKN,OAAAA;AACtB"}
@@ -1 +1 @@
1
- {"version":3,"file":"env.mjs","names":["oneOf","read","readArray","readBool","readInt","hasEnvDataSourceOptions","readDataSourceOptionsFromEnv","ConfigEnvironmentVariableName","BOOLEAN_TRUE_VALUES","Set","BOOLEAN_FALSE_VALUES","readBoolStrict","name","raw","trim","length","undefined","normalized","toLowerCase","has","Error","readConfigRawFromEnv","options","env","NODE_ENV","writableDirectoryPath","WRITABLE_DIRECTORY_PATH","db","redis","REDIS","smtp","SMTP","host","HOST","port","PORT","publicURL","PUBLIC_URL","publicUrl","mtlsPublicURL","MTLS_PUBLIC_URL","mtlsPublicUrl","certificateSource","CERTIFICATE_SOURCE","trustedOrigins","TRUSTED_ORIGINS","tokenAccessMaxAge","TOKEN_ACCESS_MAX_AGE","tokenRefreshMaxAge","TOKEN_REFRESH_MAX_AGE","tokenRefreshGracePeriod","TOKEN_REFRESH_GRACE_PERIOD","promptLoginMaxAge","PROMPT_LOGIN_MAX_AGE","endSessionHintGracePeriod","END_SESSION_HINT_GRACE_PERIOD","registrationEnabled","REGISTRATION_ENABLED","emailVerificationEnabled","EMAIL_VERIFICATION_ENABLED","passwordRecoveryEnabled","PASSWORD_RECOVERY_ENABLED","passwordMinLength","PASSWORD_MIN_LENGTH","eventLogEnabled","EVENT_LOG_ENABLED","eventLogRetentionDays","EVENT_LOG_RETENTION_DAYS","eventLogEntityEnabled","EVENT_LOG_ENTITY_ENABLED","eventLogEntityRetentionDays","EVENT_LOG_ENTITY_RETENTION_DAYS","loginAttemptThrottleEnabled","LOGIN_ATTEMPT_THROTTLE_ENABLED","loginAttemptThreshold","LOGIN_ATTEMPT_THRESHOLD","loginAttemptWindow","LOGIN_ATTEMPT_WINDOW","mfaEnabled","MFA_ENABLED","mfaRequired","MFA_REQUIRED","mfaFreshnessMaxAge","MFA_FRESHNESS_MAX_AGE","mfaTicketMaxAge","MFA_TICKET_MAX_AGE","secretsEncryptionKey","SECRETS_ENCRYPTION_KEY","clientBasicAuth","CLIENT_AUTH_BASIC","clientAuthBasic","clientSystemEnabled","CLIENT_SYSTEM_ENABLED","clientAdminSecret","CLIENT_SYSTEM_SECRET","clientSystemSecret","clientAdminSecretReset","CLIENT_SYSTEM_SECRET_RESET","clientSystemSecretReset","userBasicAuth","USER_AUTH_BASIC","userAuthBasic","userAdminEnabled","USER_ADMIN_ENABLED","userAdminPassword","USER_ADMIN_PASSWORD","userAdminPasswordReset","USER_ADMIN_PASSWORD_RESET","permissions","PERMISSIONS","permissionsDefaultPolicyAssignment","PERMISSIONS_DEFAULT_POLICY_ASSIGNMENT"],"sources":["../../../../../src/app/modules/config/read/env.ts"],"sourcesContent":["/*\n * Copyright (c) 2022-2024.\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 oneOf,\n read,\n readArray,\n readBool,\n readInt,\n} from 'envix';\nimport { hasEnvDataSourceOptions, readDataSourceOptionsFromEnv } from 'typeorm-extension';\nimport type { BetterSqlite3DataSourceOptions } from 'typeorm/driver/better-sqlite3/BetterSqlite3DataSourceOptions.js';\nimport type { MysqlDataSourceOptions } from 'typeorm/driver/mysql/MysqlDataSourceOptions.js';\nimport type { PostgresDataSourceOptions } from 'typeorm/driver/postgres/PostgresDataSourceOptions.js';\n\nimport { ConfigEnvironmentVariableName } from '../constants.ts';\nimport type { ConfigInput } from '../types.ts';\n\nconst BOOLEAN_TRUE_VALUES = new Set(['true', 't', '1', 'yes', 'y', 'on']);\nconst BOOLEAN_FALSE_VALUES = new Set(['false', 'f', '0', 'no', 'n', 'off']);\n\n/**\n * Boolean env reader that FAILS LOUD on a set-but-unrecognized value instead\n * of silently falling back to the default (envix's `readBool` swallows e.g.\n * `MFA_REQUIRED=yes`). Reserved for security-relevant toggles where a silent\n * default is a weakened posture. Returns `undefined` when the var is unset.\n */\nfunction readBoolStrict(name: ConfigEnvironmentVariableName) : boolean | undefined {\n const raw = read(name);\n if (typeof raw !== 'string' || raw.trim().length === 0) {\n return undefined;\n }\n\n const normalized = raw.trim().toLowerCase();\n if (BOOLEAN_TRUE_VALUES.has(normalized)) {\n return true;\n }\n if (BOOLEAN_FALSE_VALUES.has(normalized)) {\n return false;\n }\n\n throw new Error(`The environment variable ${name} must be a boolean value (received \"${raw}\").`);\n}\n\nexport function readConfigRawFromEnv() : ConfigInput {\n const options : ConfigInput = {};\n\n const env = read(ConfigEnvironmentVariableName.NODE_ENV);\n if (env) {\n options.env = env;\n }\n\n const writableDirectoryPath = read(ConfigEnvironmentVariableName.WRITABLE_DIRECTORY_PATH);\n if (writableDirectoryPath) {\n options.writableDirectoryPath = writableDirectoryPath;\n }\n\n // -------------------------------------------------------------\n\n if (hasEnvDataSourceOptions()) {\n // todo: type casting should be avoided\n options.db = readDataSourceOptionsFromEnv() as MysqlDataSourceOptions |\n PostgresDataSourceOptions |\n BetterSqlite3DataSourceOptions;\n }\n\n const redis = oneOf([\n readBool(ConfigEnvironmentVariableName.REDIS),\n read(ConfigEnvironmentVariableName.REDIS),\n ]);\n if (typeof redis !== 'undefined') {\n options.redis = redis;\n }\n\n const smtp = oneOf([\n readBool(ConfigEnvironmentVariableName.SMTP),\n read(ConfigEnvironmentVariableName.SMTP),\n ]);\n if (typeof smtp !== 'undefined') {\n options.smtp = smtp;\n }\n\n // -------------------------------------------------------------\n\n const host = read(ConfigEnvironmentVariableName.HOST);\n if (host) {\n options.host = host;\n }\n\n const port = readInt(ConfigEnvironmentVariableName.PORT);\n if (typeof port !== 'undefined') {\n options.port = port;\n }\n\n const publicURL = read(ConfigEnvironmentVariableName.PUBLIC_URL);\n if (publicURL) {\n options.publicUrl = publicURL;\n }\n\n const mtlsPublicURL = read(ConfigEnvironmentVariableName.MTLS_PUBLIC_URL);\n if (mtlsPublicURL) {\n options.mtlsPublicUrl = mtlsPublicURL;\n }\n\n const certificateSource = read(ConfigEnvironmentVariableName.CERTIFICATE_SOURCE);\n if (certificateSource) {\n options.certificateSource = certificateSource as ConfigInput['certificateSource'];\n }\n\n const trustedOrigins = readArray(ConfigEnvironmentVariableName.TRUSTED_ORIGINS);\n if (trustedOrigins && trustedOrigins.length > 0) {\n options.trustedOrigins = trustedOrigins;\n }\n\n const tokenAccessMaxAge = readInt(ConfigEnvironmentVariableName.TOKEN_ACCESS_MAX_AGE);\n if (typeof tokenAccessMaxAge !== 'undefined') {\n options.tokenAccessMaxAge = tokenAccessMaxAge;\n }\n\n const tokenRefreshMaxAge = readInt(ConfigEnvironmentVariableName.TOKEN_REFRESH_MAX_AGE);\n if (typeof tokenRefreshMaxAge !== 'undefined') {\n options.tokenRefreshMaxAge = tokenRefreshMaxAge;\n }\n\n const tokenRefreshGracePeriod = readInt(ConfigEnvironmentVariableName.TOKEN_REFRESH_GRACE_PERIOD);\n if (typeof tokenRefreshGracePeriod !== 'undefined') {\n options.tokenRefreshGracePeriod = tokenRefreshGracePeriod;\n }\n\n const promptLoginMaxAge = readInt(ConfigEnvironmentVariableName.PROMPT_LOGIN_MAX_AGE);\n if (typeof promptLoginMaxAge !== 'undefined') {\n options.promptLoginMaxAge = promptLoginMaxAge;\n }\n\n const endSessionHintGracePeriod = readInt(ConfigEnvironmentVariableName.END_SESSION_HINT_GRACE_PERIOD);\n if (typeof endSessionHintGracePeriod !== 'undefined') {\n options.endSessionHintGracePeriod = endSessionHintGracePeriod;\n }\n\n const registrationEnabled = readBool(ConfigEnvironmentVariableName.REGISTRATION_ENABLED);\n if (typeof registrationEnabled !== 'undefined') {\n options.registrationEnabled = registrationEnabled;\n }\n\n const emailVerificationEnabled = readBool(ConfigEnvironmentVariableName.EMAIL_VERIFICATION_ENABLED);\n if (typeof emailVerificationEnabled !== 'undefined') {\n options.emailVerificationEnabled = emailVerificationEnabled;\n }\n\n const passwordRecoveryEnabled = readBool(ConfigEnvironmentVariableName.PASSWORD_RECOVERY_ENABLED);\n if (typeof passwordRecoveryEnabled !== 'undefined') {\n options.passwordRecoveryEnabled = passwordRecoveryEnabled;\n }\n\n const passwordMinLength = readInt(ConfigEnvironmentVariableName.PASSWORD_MIN_LENGTH);\n if (typeof passwordMinLength !== 'undefined') {\n options.passwordMinLength = passwordMinLength;\n }\n\n // ---------------------------------------------------------------\n\n const eventLogEnabled = readBoolStrict(ConfigEnvironmentVariableName.EVENT_LOG_ENABLED);\n if (typeof eventLogEnabled !== 'undefined') {\n options.eventLogEnabled = eventLogEnabled;\n }\n\n const eventLogRetentionDays = readInt(ConfigEnvironmentVariableName.EVENT_LOG_RETENTION_DAYS);\n if (typeof eventLogRetentionDays !== 'undefined') {\n options.eventLogRetentionDays = eventLogRetentionDays;\n }\n\n const eventLogEntityEnabled = readBoolStrict(ConfigEnvironmentVariableName.EVENT_LOG_ENTITY_ENABLED);\n if (typeof eventLogEntityEnabled !== 'undefined') {\n options.eventLogEntityEnabled = eventLogEntityEnabled;\n }\n\n const eventLogEntityRetentionDays = readInt(ConfigEnvironmentVariableName.EVENT_LOG_ENTITY_RETENTION_DAYS);\n if (typeof eventLogEntityRetentionDays !== 'undefined') {\n options.eventLogEntityRetentionDays = eventLogEntityRetentionDays;\n }\n\n const loginAttemptThrottleEnabled = readBoolStrict(ConfigEnvironmentVariableName.LOGIN_ATTEMPT_THROTTLE_ENABLED);\n if (typeof loginAttemptThrottleEnabled !== 'undefined') {\n options.loginAttemptThrottleEnabled = loginAttemptThrottleEnabled;\n }\n\n const loginAttemptThreshold = readInt(ConfigEnvironmentVariableName.LOGIN_ATTEMPT_THRESHOLD);\n if (typeof loginAttemptThreshold !== 'undefined') {\n options.loginAttemptThreshold = loginAttemptThreshold;\n }\n\n const loginAttemptWindow = readInt(ConfigEnvironmentVariableName.LOGIN_ATTEMPT_WINDOW);\n if (typeof loginAttemptWindow !== 'undefined') {\n options.loginAttemptWindow = loginAttemptWindow;\n }\n\n // ---------------------------------------------------------------\n\n const mfaEnabled = readBoolStrict(ConfigEnvironmentVariableName.MFA_ENABLED);\n if (typeof mfaEnabled !== 'undefined') {\n options.mfaEnabled = mfaEnabled;\n }\n\n const mfaRequired = readBoolStrict(ConfigEnvironmentVariableName.MFA_REQUIRED);\n if (typeof mfaRequired !== 'undefined') {\n options.mfaRequired = mfaRequired;\n }\n\n const mfaFreshnessMaxAge = readInt(ConfigEnvironmentVariableName.MFA_FRESHNESS_MAX_AGE);\n if (typeof mfaFreshnessMaxAge !== 'undefined') {\n options.mfaFreshnessMaxAge = mfaFreshnessMaxAge;\n }\n\n const mfaTicketMaxAge = readInt(ConfigEnvironmentVariableName.MFA_TICKET_MAX_AGE);\n if (typeof mfaTicketMaxAge !== 'undefined') {\n options.mfaTicketMaxAge = mfaTicketMaxAge;\n }\n\n const secretsEncryptionKey = read(ConfigEnvironmentVariableName.SECRETS_ENCRYPTION_KEY);\n if (secretsEncryptionKey) {\n options.secretsEncryptionKey = secretsEncryptionKey;\n }\n\n // ---------------------------------------------------------------\n\n const clientBasicAuth = readBool(ConfigEnvironmentVariableName.CLIENT_AUTH_BASIC);\n if (typeof clientBasicAuth !== 'undefined') {\n options.clientAuthBasic = clientBasicAuth;\n }\n\n const clientSystemEnabled = readBool(ConfigEnvironmentVariableName.CLIENT_SYSTEM_ENABLED);\n if (typeof clientSystemEnabled !== 'undefined') {\n options.clientSystemEnabled = clientSystemEnabled;\n }\n\n const clientAdminSecret = read(ConfigEnvironmentVariableName.CLIENT_SYSTEM_SECRET);\n if (clientAdminSecret) {\n options.clientSystemSecret = clientAdminSecret;\n }\n\n const clientAdminSecretReset = readBool(ConfigEnvironmentVariableName.CLIENT_SYSTEM_SECRET_RESET);\n if (typeof clientAdminSecretReset !== 'undefined') {\n options.clientSystemSecretReset = clientAdminSecretReset;\n }\n\n // ---------------------------------------------------------------\n\n const userBasicAuth = readBool(ConfigEnvironmentVariableName.USER_AUTH_BASIC);\n if (typeof userBasicAuth !== 'undefined') {\n options.userAuthBasic = userBasicAuth;\n }\n\n const userAdminEnabled = readBool(ConfigEnvironmentVariableName.USER_ADMIN_ENABLED);\n if (typeof userAdminEnabled !== 'undefined') {\n options.userAdminEnabled = userAdminEnabled;\n }\n\n const userAdminPassword = read(ConfigEnvironmentVariableName.USER_ADMIN_PASSWORD);\n if (userAdminPassword) {\n options.userAdminPassword = userAdminPassword;\n }\n\n const userAdminPasswordReset = readBool(ConfigEnvironmentVariableName.USER_ADMIN_PASSWORD_RESET);\n if (typeof userAdminPasswordReset !== 'undefined') {\n options.userAdminPasswordReset = userAdminPasswordReset;\n }\n\n // ---------------------------------------------------------------\n\n const permissions = readArray(ConfigEnvironmentVariableName.PERMISSIONS);\n if (permissions && permissions.length > 0) {\n options.permissions = permissions;\n }\n\n const permissionsDefaultPolicyAssignment = readBool(ConfigEnvironmentVariableName.PERMISSIONS_DEFAULT_POLICY_ASSIGNMENT);\n if (typeof permissionsDefaultPolicyAssignment !== 'undefined') {\n options.permissionsDefaultPolicyAssignment = permissionsDefaultPolicyAssignment;\n }\n\n return options;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"env.mjs","names":["oneOf","read","readArray","readBool","readInt","hasEnvDataSourceOptions","readDataSourceOptionsFromEnv","ConfigEnvironmentVariableName","BOOLEAN_TRUE_VALUES","Set","BOOLEAN_FALSE_VALUES","readBoolStrict","name","raw","trim","length","undefined","normalized","toLowerCase","has","Error","readConfigRawFromEnv","options","env","NODE_ENV","writableDirectoryPath","WRITABLE_DIRECTORY_PATH","db","redis","REDIS","smtp","SMTP","host","HOST","port","PORT","publicURL","PUBLIC_URL","publicUrl","mtlsPublicURL","MTLS_PUBLIC_URL","mtlsPublicUrl","certificateSource","CERTIFICATE_SOURCE","trustedOrigins","TRUSTED_ORIGINS","tokenAccessMaxAge","TOKEN_ACCESS_MAX_AGE","tokenRefreshMaxAge","TOKEN_REFRESH_MAX_AGE","tokenRefreshGracePeriod","TOKEN_REFRESH_GRACE_PERIOD","promptLoginMaxAge","PROMPT_LOGIN_MAX_AGE","endSessionHintGracePeriod","END_SESSION_HINT_GRACE_PERIOD","registrationEnabled","REGISTRATION_ENABLED","emailVerificationEnabled","EMAIL_VERIFICATION_ENABLED","passwordRecoveryEnabled","PASSWORD_RECOVERY_ENABLED","passwordMinLength","PASSWORD_MIN_LENGTH","eventLogEnabled","EVENT_LOG_ENABLED","eventLogRetentionDays","EVENT_LOG_RETENTION_DAYS","eventLogEntityEnabled","EVENT_LOG_ENTITY_ENABLED","eventLogEntityRetentionDays","EVENT_LOG_ENTITY_RETENTION_DAYS","loginAttemptThrottleEnabled","LOGIN_ATTEMPT_THROTTLE_ENABLED","loginAttemptThreshold","LOGIN_ATTEMPT_THRESHOLD","loginAttemptWindow","LOGIN_ATTEMPT_WINDOW","mfaEnabled","MFA_ENABLED","mfaRequired","MFA_REQUIRED","mfaFreshnessMaxAge","MFA_FRESHNESS_MAX_AGE","mfaTicketMaxAge","MFA_TICKET_MAX_AGE","secretsEncryptionKey","SECRETS_ENCRYPTION_KEY","clientBasicAuth","CLIENT_AUTH_BASIC","clientAuthBasic","clientSystemEnabled","CLIENT_SYSTEM_ENABLED","clientAdminSecret","CLIENT_SYSTEM_SECRET","clientSystemSecret","clientAdminSecretReset","CLIENT_SYSTEM_SECRET_RESET","clientSystemSecretReset","userBasicAuth","USER_AUTH_BASIC","userAuthBasic","userAdminEnabled","USER_ADMIN_ENABLED","userAdminPassword","USER_ADMIN_PASSWORD","userAdminPasswordReset","USER_ADMIN_PASSWORD_RESET","permissions","PERMISSIONS","permissionsDefaultPolicyAssignment","PERMISSIONS_DEFAULT_POLICY_ASSIGNMENT"],"sources":["../../../../../src/app/modules/config/read/env.ts"],"sourcesContent":["/*\n * Copyright (c) 2022-2024.\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 oneOf,\n read,\n readArray,\n readBool,\n readInt,\n} from 'envix';\nimport { hasEnvDataSourceOptions, readDataSourceOptionsFromEnv } from 'typeorm-extension';\nimport type { BetterSqlite3DataSourceOptions } from 'typeorm/driver/better-sqlite3/BetterSqlite3DataSourceOptions.js';\nimport type { MysqlDataSourceOptions } from 'typeorm/driver/mysql/MysqlDataSourceOptions.js';\nimport type { PostgresDataSourceOptions } from 'typeorm/driver/postgres/PostgresDataSourceOptions.js';\n\nimport { ConfigEnvironmentVariableName } from '../constants.ts';\nimport type { ConfigInput } from '../types.ts';\n\nconst BOOLEAN_TRUE_VALUES = new Set(['true', 't', '1', 'yes', 'y', 'on']);\nconst BOOLEAN_FALSE_VALUES = new Set(['false', 'f', '0', 'no', 'n', 'off']);\n\n/**\n * Boolean env reader that FAILS LOUD on a set-but-unrecognized value instead\n * of silently falling back to the default (envix's `readBool` swallows e.g.\n * `MFA_REQUIRED=yes`). Reserved for security-relevant toggles where a silent\n * default is a weakened posture. Returns `undefined` when the var is unset.\n */\nfunction readBoolStrict(name: ConfigEnvironmentVariableName) : boolean | undefined {\n const raw = read(name);\n if (typeof raw !== 'string' || raw.trim().length === 0) {\n return undefined;\n }\n\n const normalized = raw.trim().toLowerCase();\n if (BOOLEAN_TRUE_VALUES.has(normalized)) {\n return true;\n }\n if (BOOLEAN_FALSE_VALUES.has(normalized)) {\n return false;\n }\n\n throw new Error(`The environment variable ${name} must be a boolean value (received \"${raw}\").`);\n}\n\nexport function readConfigRawFromEnv() : ConfigInput {\n const options : ConfigInput = {};\n\n const env = read(ConfigEnvironmentVariableName.NODE_ENV);\n if (env) {\n options.env = env;\n }\n\n const writableDirectoryPath = read(ConfigEnvironmentVariableName.WRITABLE_DIRECTORY_PATH);\n if (writableDirectoryPath) {\n options.writableDirectoryPath = writableDirectoryPath;\n }\n\n // -------------------------------------------------------------\n\n if (hasEnvDataSourceOptions()) {\n // todo: type casting should be avoided\n options.db = readDataSourceOptionsFromEnv() as MysqlDataSourceOptions |\n PostgresDataSourceOptions |\n BetterSqlite3DataSourceOptions;\n }\n\n const redis = oneOf([\n readBool(ConfigEnvironmentVariableName.REDIS),\n read(ConfigEnvironmentVariableName.REDIS),\n ]);\n if (typeof redis !== 'undefined') {\n options.redis = redis;\n }\n\n const smtp = oneOf([\n readBool(ConfigEnvironmentVariableName.SMTP),\n read(ConfigEnvironmentVariableName.SMTP),\n ]);\n if (typeof smtp !== 'undefined') {\n options.smtp = smtp;\n }\n\n // -------------------------------------------------------------\n\n const host = read(ConfigEnvironmentVariableName.HOST);\n if (host) {\n options.host = host;\n }\n\n const port = readInt(ConfigEnvironmentVariableName.PORT);\n if (typeof port !== 'undefined') {\n options.port = port;\n }\n\n const publicURL = read(ConfigEnvironmentVariableName.PUBLIC_URL);\n if (publicURL) {\n options.publicUrl = publicURL;\n }\n\n const mtlsPublicURL = read(ConfigEnvironmentVariableName.MTLS_PUBLIC_URL);\n if (mtlsPublicURL) {\n options.mtlsPublicUrl = mtlsPublicURL;\n }\n\n const certificateSource = read(ConfigEnvironmentVariableName.CERTIFICATE_SOURCE);\n if (certificateSource) {\n options.certificateSource = certificateSource as ConfigInput['certificateSource'];\n }\n\n const trustedOrigins = readArray(ConfigEnvironmentVariableName.TRUSTED_ORIGINS);\n if (trustedOrigins && trustedOrigins.length > 0) {\n options.trustedOrigins = trustedOrigins;\n }\n\n const tokenAccessMaxAge = readInt(ConfigEnvironmentVariableName.TOKEN_ACCESS_MAX_AGE);\n if (typeof tokenAccessMaxAge !== 'undefined') {\n options.tokenAccessMaxAge = tokenAccessMaxAge;\n }\n\n const tokenRefreshMaxAge = readInt(ConfigEnvironmentVariableName.TOKEN_REFRESH_MAX_AGE);\n if (typeof tokenRefreshMaxAge !== 'undefined') {\n options.tokenRefreshMaxAge = tokenRefreshMaxAge;\n }\n\n const tokenRefreshGracePeriod = readInt(ConfigEnvironmentVariableName.TOKEN_REFRESH_GRACE_PERIOD);\n if (typeof tokenRefreshGracePeriod !== 'undefined') {\n options.tokenRefreshGracePeriod = tokenRefreshGracePeriod;\n }\n\n const promptLoginMaxAge = readInt(ConfigEnvironmentVariableName.PROMPT_LOGIN_MAX_AGE);\n if (typeof promptLoginMaxAge !== 'undefined') {\n options.promptLoginMaxAge = promptLoginMaxAge;\n }\n\n const endSessionHintGracePeriod = readInt(ConfigEnvironmentVariableName.END_SESSION_HINT_GRACE_PERIOD);\n if (typeof endSessionHintGracePeriod !== 'undefined') {\n options.endSessionHintGracePeriod = endSessionHintGracePeriod;\n }\n\n const registrationEnabled = readBool(ConfigEnvironmentVariableName.REGISTRATION_ENABLED);\n if (typeof registrationEnabled !== 'undefined') {\n options.registrationEnabled = registrationEnabled;\n }\n\n const emailVerificationEnabled = readBool(ConfigEnvironmentVariableName.EMAIL_VERIFICATION_ENABLED);\n if (typeof emailVerificationEnabled !== 'undefined') {\n options.emailVerificationEnabled = emailVerificationEnabled;\n }\n\n const passwordRecoveryEnabled = readBool(ConfigEnvironmentVariableName.PASSWORD_RECOVERY_ENABLED);\n if (typeof passwordRecoveryEnabled !== 'undefined') {\n options.passwordRecoveryEnabled = passwordRecoveryEnabled;\n }\n\n const passwordMinLength = readInt(ConfigEnvironmentVariableName.PASSWORD_MIN_LENGTH);\n if (typeof passwordMinLength !== 'undefined') {\n options.passwordMinLength = passwordMinLength;\n }\n\n // ---------------------------------------------------------------\n\n const eventLogEnabled = readBoolStrict(ConfigEnvironmentVariableName.EVENT_LOG_ENABLED);\n if (typeof eventLogEnabled !== 'undefined') {\n options.eventLogEnabled = eventLogEnabled;\n }\n\n const eventLogRetentionDays = readInt(ConfigEnvironmentVariableName.EVENT_LOG_RETENTION_DAYS);\n if (typeof eventLogRetentionDays !== 'undefined') {\n options.eventLogRetentionDays = eventLogRetentionDays;\n }\n\n const eventLogEntityEnabled = readBoolStrict(ConfigEnvironmentVariableName.EVENT_LOG_ENTITY_ENABLED);\n if (typeof eventLogEntityEnabled !== 'undefined') {\n options.eventLogEntityEnabled = eventLogEntityEnabled;\n }\n\n const eventLogEntityRetentionDays = readInt(ConfigEnvironmentVariableName.EVENT_LOG_ENTITY_RETENTION_DAYS);\n if (typeof eventLogEntityRetentionDays !== 'undefined') {\n options.eventLogEntityRetentionDays = eventLogEntityRetentionDays;\n }\n\n const loginAttemptThrottleEnabled = readBoolStrict(ConfigEnvironmentVariableName.LOGIN_ATTEMPT_THROTTLE_ENABLED);\n if (typeof loginAttemptThrottleEnabled !== 'undefined') {\n options.loginAttemptThrottleEnabled = loginAttemptThrottleEnabled;\n }\n\n const loginAttemptThreshold = readInt(ConfigEnvironmentVariableName.LOGIN_ATTEMPT_THRESHOLD);\n if (typeof loginAttemptThreshold !== 'undefined') {\n options.loginAttemptThreshold = loginAttemptThreshold;\n }\n\n const loginAttemptWindow = readInt(ConfigEnvironmentVariableName.LOGIN_ATTEMPT_WINDOW);\n if (typeof loginAttemptWindow !== 'undefined') {\n options.loginAttemptWindow = loginAttemptWindow;\n }\n\n // ---------------------------------------------------------------\n\n const mfaEnabled = readBoolStrict(ConfigEnvironmentVariableName.MFA_ENABLED);\n if (typeof mfaEnabled !== 'undefined') {\n options.mfaEnabled = mfaEnabled;\n }\n\n const mfaRequired = readBoolStrict(ConfigEnvironmentVariableName.MFA_REQUIRED);\n if (typeof mfaRequired !== 'undefined') {\n options.mfaRequired = mfaRequired;\n }\n\n const mfaFreshnessMaxAge = readInt(ConfigEnvironmentVariableName.MFA_FRESHNESS_MAX_AGE);\n if (typeof mfaFreshnessMaxAge !== 'undefined') {\n options.mfaFreshnessMaxAge = mfaFreshnessMaxAge;\n }\n\n const mfaTicketMaxAge = readInt(ConfigEnvironmentVariableName.MFA_TICKET_MAX_AGE);\n if (typeof mfaTicketMaxAge !== 'undefined') {\n options.mfaTicketMaxAge = mfaTicketMaxAge;\n }\n\n const secretsEncryptionKey = read(ConfigEnvironmentVariableName.SECRETS_ENCRYPTION_KEY);\n if (secretsEncryptionKey) {\n options.secretsEncryptionKey = secretsEncryptionKey;\n }\n\n // ---------------------------------------------------------------\n\n const clientBasicAuth = readBool(ConfigEnvironmentVariableName.CLIENT_AUTH_BASIC);\n if (typeof clientBasicAuth !== 'undefined') {\n options.clientAuthBasic = clientBasicAuth;\n }\n\n const clientSystemEnabled = readBool(ConfigEnvironmentVariableName.CLIENT_SYSTEM_ENABLED);\n if (typeof clientSystemEnabled !== 'undefined') {\n options.clientSystemEnabled = clientSystemEnabled;\n }\n\n const clientAdminSecret = read(ConfigEnvironmentVariableName.CLIENT_SYSTEM_SECRET);\n if (clientAdminSecret) {\n options.clientSystemSecret = clientAdminSecret;\n }\n\n const clientAdminSecretReset = readBool(ConfigEnvironmentVariableName.CLIENT_SYSTEM_SECRET_RESET);\n if (typeof clientAdminSecretReset !== 'undefined') {\n options.clientSystemSecretReset = clientAdminSecretReset;\n }\n\n // ---------------------------------------------------------------\n\n const userBasicAuth = readBool(ConfigEnvironmentVariableName.USER_AUTH_BASIC);\n if (typeof userBasicAuth !== 'undefined') {\n options.userAuthBasic = userBasicAuth;\n }\n\n const userAdminEnabled = readBool(ConfigEnvironmentVariableName.USER_ADMIN_ENABLED);\n if (typeof userAdminEnabled !== 'undefined') {\n options.userAdminEnabled = userAdminEnabled;\n }\n\n const userAdminPassword = read(ConfigEnvironmentVariableName.USER_ADMIN_PASSWORD);\n if (userAdminPassword) {\n options.userAdminPassword = userAdminPassword;\n }\n\n const userAdminPasswordReset = readBool(ConfigEnvironmentVariableName.USER_ADMIN_PASSWORD_RESET);\n if (typeof userAdminPasswordReset !== 'undefined') {\n options.userAdminPasswordReset = userAdminPasswordReset;\n }\n\n // ---------------------------------------------------------------\n\n const permissions = readArray(ConfigEnvironmentVariableName.PERMISSIONS);\n if (permissions && permissions.length > 0) {\n options.permissions = permissions;\n }\n\n const permissionsDefaultPolicyAssignment = readBool(ConfigEnvironmentVariableName.PERMISSIONS_DEFAULT_POLICY_ASSIGNMENT);\n if (typeof permissionsDefaultPolicyAssignment !== 'undefined') {\n options.permissionsDefaultPolicyAssignment = permissionsDefaultPolicyAssignment;\n }\n\n return options;\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"fs.mjs","names":["Container","readConfigRawFromFS","options","container","prefix","cwd","file","loadFile","load","raw","get","db","redis","smtp"],"sources":["../../../../../src/app/modules/config/read/fs.ts"],"sourcesContent":["/*\n * Copyright (c) 2024.\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 { Container } from 'confinity';\nimport type { ConfigInput } from '../types.ts';\nimport type { ConfigReadFsOptions } from './types.ts';\n\nexport async function readConfigRawFromFS(options: ConfigReadFsOptions = {}) {\n const container = new Container({\n prefix: 'authup',\n cwd: options.cwd,\n });\n\n if (options.file) {\n await container.loadFile(options.file);\n } else {\n await container.load();\n }\n\n const raw : ConfigInput = container.get('server.core') || {};\n\n const db = container.get([\n 'db',\n 'server.db',\n 'server.core.db',\n ]);\n if (db) {\n raw.db = db;\n }\n\n const redis = container.get([\n 'redis',\n 'server.redis',\n 'server.core.redis',\n ]);\n if (redis) {\n raw.redis = redis;\n }\n\n const smtp = container.get([\n 'smtp',\n 'server.smtp',\n 'server.core.smtp',\n ]);\n if (smtp) {\n raw.smtp = smtp;\n }\n\n return raw;\n}\n"],"mappings":";;;;;AAWA,eAAsBC,oBAAoBC,UAA+B,CAAC,GAAC;CACvE,MAAMC,YAAY,IAAIH,UAAU;EAC5BI,QAAQ;EACRC,KAAKH,QAAQG;CACjB,CAAA;CAEA,IAAIH,QAAQI,MACR,MAAMH,UAAUI,SAASL,QAAQI,IAAI;MAErC,MAAMH,UAAUK,KAAI;CAGxB,MAAMC,MAAoBN,UAAUO,IAAI,aAAA,KAAkB,CAAC;CAE3D,MAAMC,KAAKR,UAAUO,IAAI;EACrB;EACA;EACA;EACH;CACD,IAAIC,IACAF,IAAIE,KAAKA;CAGb,MAAMC,QAAQT,UAAUO,IAAI;EACxB;EACA;EACA;EACH;CACD,IAAIE,OACAH,IAAIG,QAAQA;CAGhB,MAAMC,OAAOV,UAAUO,IAAI;EACvB;EACA;EACA;EACH;CACD,IAAIG,MACAJ,IAAII,OAAOA;CAGf,OAAOJ;AACX"}
1
+ {"version":3,"file":"fs.mjs","names":["Container","readConfigRawFromFS","options","container","prefix","cwd","file","loadFile","load","raw","get","db","redis","smtp"],"sources":["../../../../../src/app/modules/config/read/fs.ts"],"sourcesContent":["/*\n * Copyright (c) 2024.\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 { Container } from 'confinity';\nimport type { ConfigInput } from '../types.ts';\nimport type { ConfigReadFsOptions } from './types.ts';\n\nexport async function readConfigRawFromFS(options: ConfigReadFsOptions = {}) {\n const container = new Container({\n prefix: 'authup',\n cwd: options.cwd,\n });\n\n if (options.file) {\n await container.loadFile(options.file);\n } else {\n await container.load();\n }\n\n const raw : ConfigInput = container.get('server.core') || {};\n\n const db = container.get([\n 'db',\n 'server.db',\n 'server.core.db',\n ]);\n if (db) {\n raw.db = db;\n }\n\n const redis = container.get([\n 'redis',\n 'server.redis',\n 'server.core.redis',\n ]);\n if (redis) {\n raw.redis = redis;\n }\n\n const smtp = container.get([\n 'smtp',\n 'server.smtp',\n 'server.core.smtp',\n ]);\n if (smtp) {\n raw.smtp = smtp;\n }\n\n return raw;\n}\n"],"mappings":";;;;;AAWA,eAAsBC,oBAAoBC,UAA+B,CAAC,GAAC;CACvE,MAAMC,YAAY,IAAIH,UAAU;EAC5BI,QAAQ;EACRC,KAAKH,QAAQG;CACjB,CAAA;CAEA,IAAIH,QAAQI,MACR,MAAMH,UAAUI,SAASL,QAAQI,IAAI;MAErC,MAAMH,UAAUK,KAAI;CAGxB,MAAMC,MAAoBN,UAAUO,IAAI,aAAA,KAAkB,CAAC;CAE3D,MAAMC,KAAKR,UAAUO,IAAI;EACrB;EACA;EACA;CACH,CAAA;CACD,IAAIC,IACAF,IAAIE,KAAKA;CAGb,MAAMC,QAAQT,UAAUO,IAAI;EACxB;EACA;EACA;CACH,CAAA;CACD,IAAIE,OACAH,IAAIG,QAAQA;CAGhB,MAAMC,OAAOV,UAAUO,IAAI;EACvB;EACA;EACA;CACH,CAAA;CACD,IAAIG,MACAJ,IAAII,OAAOA;CAGf,OAAOJ;AACX"}
@@ -1 +1 @@
1
- {"version":3,"file":"validator.mjs","names":["USER_PASSWORD_MAX_LENGTH","isObject","createValidator","Container","z","expandToOrigins","CERTIFICATE_SOURCES","ConfigValidator","initialize","stringValidator","string","booleanValidator","boolean","nonNegativeNumberValidator","number","nonnegative","secretValidator","min","max","middlewareValidator","or","record","any","serviceValidator","custom","value","validators","env","rootPath","writableDirectoryPath","logger","db","redis","smtp","port","host","publicUrl","url","mtlsPublicUrl","nullable","certificateSource","enum","trustedOrigins","array","refine","middlewareBody","middlewareCors","middlewareCookie","middlewareQuery","middlewarePrometheus","middlewareRateLimit","middlewareSwagger","tokenAccessMaxAge","tokenRefreshMaxAge","tokenRefreshGracePeriod","promptLoginMaxAge","endSessionHintGracePeriod","registrationEnabled","emailVerificationEnabled","passwordRecoveryEnabled","passwordMinLength","int","positive","eventLogEnabled","eventLogRetentionDays","eventLogEntityEnabled","eventLogEntityRetentionDays","loginAttemptThrottleEnabled","loginAttemptThreshold","loginAttemptWindow","secretsEncryptionKey","union","literal","base64","mfaEnabled","mfaRequired","mfaFreshnessMaxAge","mfaTicketMaxAge","clientAuthBasic","clientSystemEnabled","clientSystemSecret","clientSystemSecretReset","userAuthBasic","userAdminEnabled","userAdminPassword","userAdminPasswordReset","permissions","permissionsDefaultPolicyAssignment","keys","Object","key","mount","optional"],"sources":["../../../../src/app/modules/config/validator.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 { USER_PASSWORD_MAX_LENGTH } from '@authup/core-kit';\nimport { isObject } from '@authup/kit';\nimport { createValidator } from '@validup/zod';\nimport type { BetterSqlite3DataSourceOptions } from 'typeorm/driver/better-sqlite3/BetterSqlite3DataSourceOptions.js';\nimport type { MysqlDataSourceOptions } from 'typeorm/driver/mysql/MysqlDataSourceOptions.js';\nimport type { PostgresDataSourceOptions } from 'typeorm/driver/postgres/PostgresDataSourceOptions.js';\nimport type { ValidatorDescriptor } from 'validup';\nimport { Container } from 'validup';\nimport { z } from 'zod';\nimport { expandToOrigins } from './origins.ts';\nimport type { Config } from './types.ts';\nimport { CERTIFICATE_SOURCES } from '../../../adapters/http/request/index.ts';\n\nexport class ConfigValidator extends Container<Config> {\n protected override initialize() {\n super.initialize();\n\n const stringValidator = createValidator(z.string());\n const booleanValidator = createValidator(z.boolean());\n const nonNegativeNumberValidator = createValidator(z.number().nonnegative());\n const secretValidator = createValidator(z.string().min(3).max(256));\n const middlewareValidator = createValidator(\n z.boolean().or(z.record(z.string(), z.any())),\n );\n const serviceValidator = createValidator(\n z.string()\n .or(z.boolean())\n .or(z.custom<Record<string, any>>((value) => isObject(value))),\n );\n\n // Record<keyof Config, ...> is the compile-time exhaustiveness\n // guard: a Config key without a validator here fails the build\n // instead of being silently stripped by run().\n const validators: Record<keyof Config, ValidatorDescriptor> = {\n env: stringValidator,\n rootPath: stringValidator,\n writableDirectoryPath: stringValidator,\n\n logger: booleanValidator,\n db: createValidator(\n z.custom<MysqlDataSourceOptions | PostgresDataSourceOptions | BetterSqlite3DataSourceOptions>(\n (value) => isObject(value),\n ),\n ),\n redis: serviceValidator,\n smtp: serviceValidator,\n\n port: nonNegativeNumberValidator,\n host: stringValidator,\n publicUrl: createValidator(z.url()),\n mtlsPublicUrl: createValidator(z.url().nullable()),\n certificateSource: createValidator(z.enum(CERTIFICATE_SOURCES)),\n trustedOrigins: createValidator(\n z.array(z.string().refine((value) => {\n try {\n expandToOrigins(value);\n return true;\n } catch {\n return false;\n }\n }, 'must be a http(s) origin or a bare host[:port]')),\n ),\n\n middlewareBody: middlewareValidator,\n middlewareCors: middlewareValidator,\n middlewareCookie: middlewareValidator,\n middlewareQuery: middlewareValidator,\n middlewarePrometheus: middlewareValidator,\n middlewareRateLimit: middlewareValidator,\n middlewareSwagger: booleanValidator,\n\n tokenAccessMaxAge: nonNegativeNumberValidator,\n tokenRefreshMaxAge: nonNegativeNumberValidator,\n tokenRefreshGracePeriod: nonNegativeNumberValidator,\n promptLoginMaxAge: nonNegativeNumberValidator,\n endSessionHintGracePeriod: nonNegativeNumberValidator,\n registrationEnabled: booleanValidator,\n emailVerificationEnabled: booleanValidator,\n passwordRecoveryEnabled: booleanValidator,\n passwordMinLength: createValidator(\n z.number().int().positive().max(USER_PASSWORD_MAX_LENGTH),\n ),\n\n eventLogEnabled: booleanValidator,\n eventLogRetentionDays: nonNegativeNumberValidator,\n eventLogEntityEnabled: booleanValidator,\n eventLogEntityRetentionDays: nonNegativeNumberValidator,\n loginAttemptThrottleEnabled: booleanValidator,\n loginAttemptThreshold: createValidator(z.number().int().positive()),\n loginAttemptWindow: createValidator(z.number().int().positive()),\n\n // '' = unset; otherwise a base64 string (normalizeConfig enforces\n // the decoded 32-byte length at boot).\n secretsEncryptionKey: createValidator(z.union([z.literal(''), z.base64()])),\n\n mfaEnabled: booleanValidator,\n mfaRequired: booleanValidator,\n mfaFreshnessMaxAge: nonNegativeNumberValidator,\n mfaTicketMaxAge: createValidator(z.number().int().positive()),\n\n clientAuthBasic: booleanValidator,\n clientSystemEnabled: booleanValidator,\n clientSystemSecret: secretValidator,\n clientSystemSecretReset: booleanValidator,\n\n userAuthBasic: booleanValidator,\n userAdminEnabled: booleanValidator,\n userAdminPassword: secretValidator,\n userAdminPasswordReset: booleanValidator,\n\n permissions: createValidator(\n z.string().or(z.array(z.string())),\n ),\n permissionsDefaultPolicyAssignment: booleanValidator,\n };\n\n const keys = Object.keys(validators) as (keyof Config)[];\n for (const key of keys) {\n this.mount(key, { optional: true }, validators[key]);\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"validator.mjs","names":["USER_PASSWORD_MAX_LENGTH","isObject","createValidator","Container","z","expandToOrigins","CERTIFICATE_SOURCES","ConfigValidator","initialize","stringValidator","string","booleanValidator","boolean","nonNegativeNumberValidator","number","nonnegative","secretValidator","min","max","middlewareValidator","or","record","any","serviceValidator","custom","value","validators","env","rootPath","writableDirectoryPath","logger","db","redis","smtp","port","host","publicUrl","url","mtlsPublicUrl","nullable","certificateSource","enum","trustedOrigins","array","refine","middlewareBody","middlewareCors","middlewareCookie","middlewareQuery","middlewarePrometheus","middlewareRateLimit","middlewareSwagger","tokenAccessMaxAge","tokenRefreshMaxAge","tokenRefreshGracePeriod","promptLoginMaxAge","endSessionHintGracePeriod","registrationEnabled","emailVerificationEnabled","passwordRecoveryEnabled","passwordMinLength","int","positive","eventLogEnabled","eventLogRetentionDays","eventLogEntityEnabled","eventLogEntityRetentionDays","loginAttemptThrottleEnabled","loginAttemptThreshold","loginAttemptWindow","secretsEncryptionKey","union","literal","base64","mfaEnabled","mfaRequired","mfaFreshnessMaxAge","mfaTicketMaxAge","clientAuthBasic","clientSystemEnabled","clientSystemSecret","clientSystemSecretReset","userAuthBasic","userAdminEnabled","userAdminPassword","userAdminPasswordReset","permissions","permissionsDefaultPolicyAssignment","keys","Object","key","mount","optional"],"sources":["../../../../src/app/modules/config/validator.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 { USER_PASSWORD_MAX_LENGTH } from '@authup/core-kit';\nimport { isObject } from '@authup/kit';\nimport { createValidator } from '@validup/zod';\nimport type { BetterSqlite3DataSourceOptions } from 'typeorm/driver/better-sqlite3/BetterSqlite3DataSourceOptions.js';\nimport type { MysqlDataSourceOptions } from 'typeorm/driver/mysql/MysqlDataSourceOptions.js';\nimport type { PostgresDataSourceOptions } from 'typeorm/driver/postgres/PostgresDataSourceOptions.js';\nimport type { ValidatorDescriptor } from 'validup';\nimport { Container } from 'validup';\nimport { z } from 'zod';\nimport { expandToOrigins } from './origins.ts';\nimport type { Config } from './types.ts';\nimport { CERTIFICATE_SOURCES } from '../../../adapters/http/request/index.ts';\n\nexport class ConfigValidator extends Container<Config> {\n protected override initialize() {\n super.initialize();\n\n const stringValidator = createValidator(z.string());\n const booleanValidator = createValidator(z.boolean());\n const nonNegativeNumberValidator = createValidator(z.number().nonnegative());\n const secretValidator = createValidator(z.string().min(3).max(256));\n const middlewareValidator = createValidator(\n z.boolean().or(z.record(z.string(), z.any())),\n );\n const serviceValidator = createValidator(\n z.string()\n .or(z.boolean())\n .or(z.custom<Record<string, any>>((value) => isObject(value))),\n );\n\n // Record<keyof Config, ...> is the compile-time exhaustiveness\n // guard: a Config key without a validator here fails the build\n // instead of being silently stripped by run().\n const validators: Record<keyof Config, ValidatorDescriptor> = {\n env: stringValidator,\n rootPath: stringValidator,\n writableDirectoryPath: stringValidator,\n\n logger: booleanValidator,\n db: createValidator(\n z.custom<MysqlDataSourceOptions | PostgresDataSourceOptions | BetterSqlite3DataSourceOptions>(\n (value) => isObject(value),\n ),\n ),\n redis: serviceValidator,\n smtp: serviceValidator,\n\n port: nonNegativeNumberValidator,\n host: stringValidator,\n publicUrl: createValidator(z.url()),\n mtlsPublicUrl: createValidator(z.url().nullable()),\n certificateSource: createValidator(z.enum(CERTIFICATE_SOURCES)),\n trustedOrigins: createValidator(\n z.array(z.string().refine((value) => {\n try {\n expandToOrigins(value);\n return true;\n } catch {\n return false;\n }\n }, 'must be a http(s) origin or a bare host[:port]')),\n ),\n\n middlewareBody: middlewareValidator,\n middlewareCors: middlewareValidator,\n middlewareCookie: middlewareValidator,\n middlewareQuery: middlewareValidator,\n middlewarePrometheus: middlewareValidator,\n middlewareRateLimit: middlewareValidator,\n middlewareSwagger: booleanValidator,\n\n tokenAccessMaxAge: nonNegativeNumberValidator,\n tokenRefreshMaxAge: nonNegativeNumberValidator,\n tokenRefreshGracePeriod: nonNegativeNumberValidator,\n promptLoginMaxAge: nonNegativeNumberValidator,\n endSessionHintGracePeriod: nonNegativeNumberValidator,\n registrationEnabled: booleanValidator,\n emailVerificationEnabled: booleanValidator,\n passwordRecoveryEnabled: booleanValidator,\n passwordMinLength: createValidator(\n z.number().int().positive().max(USER_PASSWORD_MAX_LENGTH),\n ),\n\n eventLogEnabled: booleanValidator,\n eventLogRetentionDays: nonNegativeNumberValidator,\n eventLogEntityEnabled: booleanValidator,\n eventLogEntityRetentionDays: nonNegativeNumberValidator,\n loginAttemptThrottleEnabled: booleanValidator,\n loginAttemptThreshold: createValidator(z.number().int().positive()),\n loginAttemptWindow: createValidator(z.number().int().positive()),\n\n // '' = unset; otherwise a base64 string (normalizeConfig enforces\n // the decoded 32-byte length at boot).\n secretsEncryptionKey: createValidator(z.union([z.literal(''), z.base64()])),\n\n mfaEnabled: booleanValidator,\n mfaRequired: booleanValidator,\n mfaFreshnessMaxAge: nonNegativeNumberValidator,\n mfaTicketMaxAge: createValidator(z.number().int().positive()),\n\n clientAuthBasic: booleanValidator,\n clientSystemEnabled: booleanValidator,\n clientSystemSecret: secretValidator,\n clientSystemSecretReset: booleanValidator,\n\n userAuthBasic: booleanValidator,\n userAdminEnabled: booleanValidator,\n userAdminPassword: secretValidator,\n userAdminPasswordReset: booleanValidator,\n\n permissions: createValidator(\n z.string().or(z.array(z.string())),\n ),\n permissionsDefaultPolicyAssignment: booleanValidator,\n };\n\n const keys = Object.keys(validators) as (keyof Config)[];\n for (const key of keys) {\n this.mount(key, { optional: true }, validators[key]);\n }\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"module.mjs","names":["DomainEventPublisher","DomainEventRedisHandler","DomainEventSocketHandler","createRedisClient","AuthupError","DataSource","InstanceChecker","checkDatabase","createDatabase","synchronizeDatabaseSchema","DataSourceOptionsBuilder","DatabaseQueryResultCache","EntitySubscriber","EventEntity","isDatabaseTypeSupported","isDatabaseTypeSupportedForEnvironment","EntityEventHandler","EventService","useRequestEventContext","EventRepositoryAdapter","validateEntitySchemas","CacheInjectionKey","ModuleName","DatabaseInjectionKey","ConfigInjectionKey","LoggerInjectionKey","DatabaseModule","name","dependencies","optionsBuilder","options","eventRedisClient","eventPublisher","DATABASE","CONFIG","LOGGER","setup","container","logger","resolve","prepareBuild","dataSourceOptions","buildDataSourceOptions","setupDatabase","dataSource","debug","initialize","migrate","registerRepositories","registerEvents","registerEventPublisher","register","useValue","e","isInitialized","destroy","disposeEventPublisher","cleanupError","warn","teardown","tryResolve","success","data","unregister","EventRepository","dispose","undefined","disconnect","check","exists","synchronize","ifNotExist","config","db","buildWith","buildWithEnv","type","env","cacheResult","Object","assign","cache","provider","entities","Array","isArray","entity","isEntitySchema","useFactory","getRepository","publisher","redis","client","eventLogEnabled","eventLogEntityEnabled","eventService","requestContext","retentionDays","eventLogEntityRetentionDays","i","subscribers","length","subscriber","setPublisher","repository","service","enabled","eventLogRetentionDays"],"sources":["../../../../src/app/modules/database/module.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 DomainEventPublisher,\n DomainEventRedisHandler,\n DomainEventSocketHandler,\n createRedisClient,\n} from '@authup/server-kit';\nimport type { RedisClient } from '@authup/server-kit';\nimport { AuthupError } from '@authup/errors';\nimport type { DataSourceOptions } from 'typeorm';\nimport { DataSource, InstanceChecker } from 'typeorm';\nimport {\n checkDatabase,\n createDatabase,\n synchronizeDatabaseSchema,\n} from 'typeorm-extension';\nimport {\n DataSourceOptionsBuilder,\n DatabaseQueryResultCache,\n EntitySubscriber,\n EventEntity,\n isDatabaseTypeSupported,\n isDatabaseTypeSupportedForEnvironment,\n} from '../../../adapters/database/index.ts';\nimport type { Event } from '@authup/core-kit';\nimport { EntityEventHandler, EventService } from '../../../core/index.ts';\nimport { useRequestEventContext } from '../../../adapters/http/request/index.ts';\nimport { EventRepositoryAdapter } from './repositories/index.ts';\nimport { validateEntitySchemas } from './repositories/schema-validation.ts';\nimport { CacheInjectionKey } from '../cache/index.ts';\nimport type { IModule } from 'orkos';\nimport { ModuleName } from '../constants.ts';\nimport { DatabaseInjectionKey } from './constants.ts';\nimport { ConfigInjectionKey } from '../config/index.ts';\nimport type { IContainer } from 'eldin';\nimport { LoggerInjectionKey } from '../logger/index.ts';\n\nexport type DatabaseModuleOptions = {\n prepareBuild?: (container: IContainer) => Promise<void>;\n setup?: (container: IContainer, options: DataSourceOptions) => Promise<void>;\n migrate?: (container: IContainer, dataSource: DataSource) => Promise<void>;\n};\n\nexport class DatabaseModule implements IModule {\n readonly name: string;\n\n readonly dependencies: string[];\n\n protected optionsBuilder : DataSourceOptionsBuilder;\n\n protected options: DatabaseModuleOptions;\n\n protected eventRedisClient? : RedisClient;\n\n protected eventPublisher? : DomainEventPublisher;\n\n constructor(options: DatabaseModuleOptions = {}) {\n this.name = ModuleName.DATABASE;\n this.dependencies = [ModuleName.CONFIG, ModuleName.LOGGER];\n\n this.optionsBuilder = new DataSourceOptionsBuilder();\n this.options = options;\n }\n\n async setup(container: IContainer): Promise<void> {\n const logger = container.resolve(LoggerInjectionKey);\n\n if (this.options.prepareBuild) {\n await this.options.prepareBuild(container);\n }\n\n const dataSourceOptions = await this.buildDataSourceOptions(container);\n\n if (this.options.setup) {\n await this.options.setup(container, dataSourceOptions);\n } else {\n await this.setupDatabase(container, dataSourceOptions);\n }\n\n const dataSource = new DataSource(dataSourceOptions);\n\n logger.debug('Establishing database connection...');\n await dataSource.initialize();\n logger.debug('Established database connection.');\n\n try {\n if (this.options.migrate) {\n await this.options.migrate(container, dataSource);\n } else {\n await this.migrate(container, dataSource);\n }\n\n validateEntitySchemas(dataSource);\n this.registerRepositories(container, dataSource);\n // the event service must exist before the publisher wiring — the\n // entity-CRUD bridge handler resolves it from the container.\n this.registerEvents(container, dataSource);\n this.registerEventPublisher(container, dataSource);\n\n container.register(DatabaseInjectionKey.DataSource, { useValue: dataSource });\n } catch (e) {\n // teardown() is skipped for a module that fails its own setup(),\n // so release the connection pool and any event-publisher handles\n // here. Guard cleanup so it can never mask the original error.\n try {\n if (dataSource.isInitialized) {\n await dataSource.destroy();\n }\n\n await this.disposeEventPublisher();\n } catch (cleanupError) {\n logger.warn(`Failed to clean up database resources after setup error: ${cleanupError}`);\n }\n\n throw e;\n }\n }\n\n async teardown(container: IContainer): Promise<void> {\n const dataSource = container.tryResolve(DatabaseInjectionKey.DataSource);\n if (dataSource.success) {\n if (dataSource.data.isInitialized) {\n await dataSource.data.destroy();\n }\n\n container.unregister(DatabaseInjectionKey.DataSource);\n }\n\n container.unregister(DatabaseInjectionKey.DomainEventPublisher);\n container.unregister(DatabaseInjectionKey.EventRepository);\n container.unregister(DatabaseInjectionKey.EventService);\n\n await this.disposeEventPublisher();\n }\n\n protected async disposeEventPublisher(): Promise<void> {\n if (this.eventPublisher) {\n await this.eventPublisher.dispose();\n this.eventPublisher = undefined;\n }\n\n if (this.eventRedisClient) {\n this.eventRedisClient.disconnect();\n this.eventRedisClient = undefined;\n }\n }\n\n // ----------------------------------------------------\n\n protected async setupDatabase(container: IContainer, options: DataSourceOptions): Promise<void> {\n const logger = container.resolve(LoggerInjectionKey);\n\n const check = await checkDatabase({ options });\n\n if (!check.exists) {\n logger.debug('Creating database...');\n await createDatabase({\n options,\n synchronize: false,\n ifNotExist: true, \n });\n logger.debug('Created database');\n }\n }\n\n protected async migrate(container: IContainer, dataSource: DataSource): Promise<void> {\n const logger = container.resolve(LoggerInjectionKey);\n\n logger.debug('Migrating database...');\n await synchronizeDatabaseSchema(dataSource);\n logger.debug('Migrated database');\n }\n\n // ----------------------------------------------------\n\n /**\n * Load data source options for connection.\n *\n * @protected\n */\n protected async buildDataSourceOptions(container: IContainer) : Promise<DataSourceOptions> {\n const config = container.resolve(ConfigInjectionKey);\n\n let options : DataSourceOptions | undefined;\n if (config.db) {\n options = this.optionsBuilder.buildWith(config.db);\n } else {\n options = this.optionsBuilder.buildWithEnv();\n }\n\n if (!isDatabaseTypeSupported(options.type)) {\n throw new AuthupError(`Database type ${options.type} is not supported (only: mysql, better-sqlite3 and postgres).`);\n }\n\n if (!isDatabaseTypeSupportedForEnvironment(options.type, config.env)) {\n throw new AuthupError(`Database type ${options.type} is not supported for ${config.env}.`);\n }\n\n const cacheResult = container.tryResolve(CacheInjectionKey);\n if (cacheResult.success) {\n Object.assign(options, {\n cache: {\n provider() {\n return new DatabaseQueryResultCache(cacheResult.data);\n },\n },\n } satisfies Partial<DataSourceOptions>);\n }\n\n return options;\n }\n\n protected registerRepositories(container: IContainer, dataSource: DataSource) : void {\n const entities = dataSource.options.entities || [];\n if (!Array.isArray(entities)) {\n return;\n }\n\n for (const entity of entities) {\n if (InstanceChecker.isEntitySchema(entity)) {\n continue;\n }\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n container.register(entity, { useFactory: () => dataSource.getRepository(entity) });\n }\n }\n\n protected registerEventPublisher(container: IContainer, dataSource: DataSource) {\n const config = container.resolve(ConfigInjectionKey);\n const logger = container.resolve(LoggerInjectionKey);\n\n const publisher = new DomainEventPublisher({ logger });\n this.eventPublisher = publisher;\n if (config.redis) {\n const client = createRedisClient(config.redis);\n if (client !== config.redis) {\n this.eventRedisClient = client;\n }\n\n publisher.register(new DomainEventRedisHandler(client));\n publisher.register(new DomainEventSocketHandler(client));\n }\n\n if (config.eventLogEnabled && config.eventLogEntityEnabled) {\n publisher.register(new EntityEventHandler({\n eventService: container.resolve(DatabaseInjectionKey.EventService),\n requestContext: useRequestEventContext,\n options: { retentionDays: config.eventLogEntityRetentionDays },\n }));\n }\n\n container.register(DatabaseInjectionKey.DomainEventPublisher, { useValue: publisher });\n\n for (let i = 0; i < dataSource.subscribers.length; i++) {\n const subscriber = dataSource.subscribers[i];\n if (subscriber instanceof EntitySubscriber) {\n subscriber.setPublisher(publisher);\n }\n }\n }\n\n protected registerEvents(container: IContainer, dataSource: DataSource) {\n const config = container.resolve(ConfigInjectionKey);\n const logger = container.resolve(LoggerInjectionKey);\n\n const repository = new EventRepositoryAdapter(\n dataSource.getRepository<Event>(EventEntity),\n );\n container.register(DatabaseInjectionKey.EventRepository, { useValue: repository });\n\n const service = new EventService({\n repository,\n options: {\n enabled: config.eventLogEnabled,\n retentionDays: config.eventLogRetentionDays,\n },\n logger,\n });\n container.register(DatabaseInjectionKey.EventService, { useValue: service });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"module.mjs","names":["DomainEventPublisher","DomainEventRedisHandler","DomainEventSocketHandler","createRedisClient","AuthupError","DataSource","InstanceChecker","checkDatabase","createDatabase","synchronizeDatabaseSchema","DataSourceOptionsBuilder","DatabaseQueryResultCache","EntitySubscriber","EventEntity","isDatabaseTypeSupported","isDatabaseTypeSupportedForEnvironment","EntityEventHandler","EventService","useRequestEventContext","EventRepositoryAdapter","validateEntitySchemas","CacheInjectionKey","ModuleName","DatabaseInjectionKey","ConfigInjectionKey","LoggerInjectionKey","DatabaseModule","name","dependencies","optionsBuilder","options","eventRedisClient","eventPublisher","DATABASE","CONFIG","LOGGER","setup","container","logger","resolve","prepareBuild","dataSourceOptions","buildDataSourceOptions","setupDatabase","dataSource","debug","initialize","migrate","registerRepositories","registerEvents","registerEventPublisher","register","useValue","e","isInitialized","destroy","disposeEventPublisher","cleanupError","warn","teardown","tryResolve","success","data","unregister","EventRepository","dispose","undefined","disconnect","check","exists","synchronize","ifNotExist","config","db","buildWith","buildWithEnv","type","env","cacheResult","Object","assign","cache","provider","entities","Array","isArray","entity","isEntitySchema","useFactory","getRepository","publisher","redis","client","eventLogEnabled","eventLogEntityEnabled","eventService","requestContext","retentionDays","eventLogEntityRetentionDays","i","subscribers","length","subscriber","setPublisher","repository","service","enabled","eventLogRetentionDays"],"sources":["../../../../src/app/modules/database/module.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 DomainEventPublisher,\n DomainEventRedisHandler,\n DomainEventSocketHandler,\n createRedisClient,\n} from '@authup/server-kit';\nimport type { RedisClient } from '@authup/server-kit';\nimport { AuthupError } from '@authup/errors';\nimport type { DataSourceOptions } from 'typeorm';\nimport { DataSource, InstanceChecker } from 'typeorm';\nimport {\n checkDatabase,\n createDatabase,\n synchronizeDatabaseSchema,\n} from 'typeorm-extension';\nimport {\n DataSourceOptionsBuilder,\n DatabaseQueryResultCache,\n EntitySubscriber,\n EventEntity,\n isDatabaseTypeSupported,\n isDatabaseTypeSupportedForEnvironment,\n} from '../../../adapters/database/index.ts';\nimport type { Event } from '@authup/core-kit';\nimport { EntityEventHandler, EventService } from '../../../core/index.ts';\nimport { useRequestEventContext } from '../../../adapters/http/request/index.ts';\nimport { EventRepositoryAdapter } from './repositories/index.ts';\nimport { validateEntitySchemas } from './repositories/schema-validation.ts';\nimport { CacheInjectionKey } from '../cache/index.ts';\nimport type { IModule } from 'orkos';\nimport { ModuleName } from '../constants.ts';\nimport { DatabaseInjectionKey } from './constants.ts';\nimport { ConfigInjectionKey } from '../config/index.ts';\nimport type { IContainer } from 'eldin';\nimport { LoggerInjectionKey } from '../logger/index.ts';\n\nexport type DatabaseModuleOptions = {\n prepareBuild?: (container: IContainer) => Promise<void>;\n setup?: (container: IContainer, options: DataSourceOptions) => Promise<void>;\n migrate?: (container: IContainer, dataSource: DataSource) => Promise<void>;\n};\n\nexport class DatabaseModule implements IModule {\n readonly name: string;\n\n readonly dependencies: string[];\n\n protected optionsBuilder : DataSourceOptionsBuilder;\n\n protected options: DatabaseModuleOptions;\n\n protected eventRedisClient? : RedisClient;\n\n protected eventPublisher? : DomainEventPublisher;\n\n constructor(options: DatabaseModuleOptions = {}) {\n this.name = ModuleName.DATABASE;\n this.dependencies = [ModuleName.CONFIG, ModuleName.LOGGER];\n\n this.optionsBuilder = new DataSourceOptionsBuilder();\n this.options = options;\n }\n\n async setup(container: IContainer): Promise<void> {\n const logger = container.resolve(LoggerInjectionKey);\n\n if (this.options.prepareBuild) {\n await this.options.prepareBuild(container);\n }\n\n const dataSourceOptions = await this.buildDataSourceOptions(container);\n\n if (this.options.setup) {\n await this.options.setup(container, dataSourceOptions);\n } else {\n await this.setupDatabase(container, dataSourceOptions);\n }\n\n const dataSource = new DataSource(dataSourceOptions);\n\n logger.debug('Establishing database connection...');\n await dataSource.initialize();\n logger.debug('Established database connection.');\n\n try {\n if (this.options.migrate) {\n await this.options.migrate(container, dataSource);\n } else {\n await this.migrate(container, dataSource);\n }\n\n validateEntitySchemas(dataSource);\n this.registerRepositories(container, dataSource);\n // the event service must exist before the publisher wiring — the\n // entity-CRUD bridge handler resolves it from the container.\n this.registerEvents(container, dataSource);\n this.registerEventPublisher(container, dataSource);\n\n container.register(DatabaseInjectionKey.DataSource, { useValue: dataSource });\n } catch (e) {\n // teardown() is skipped for a module that fails its own setup(),\n // so release the connection pool and any event-publisher handles\n // here. Guard cleanup so it can never mask the original error.\n try {\n if (dataSource.isInitialized) {\n await dataSource.destroy();\n }\n\n await this.disposeEventPublisher();\n } catch (cleanupError) {\n logger.warn(`Failed to clean up database resources after setup error: ${cleanupError}`);\n }\n\n throw e;\n }\n }\n\n async teardown(container: IContainer): Promise<void> {\n const dataSource = container.tryResolve(DatabaseInjectionKey.DataSource);\n if (dataSource.success) {\n if (dataSource.data.isInitialized) {\n await dataSource.data.destroy();\n }\n\n container.unregister(DatabaseInjectionKey.DataSource);\n }\n\n container.unregister(DatabaseInjectionKey.DomainEventPublisher);\n container.unregister(DatabaseInjectionKey.EventRepository);\n container.unregister(DatabaseInjectionKey.EventService);\n\n await this.disposeEventPublisher();\n }\n\n protected async disposeEventPublisher(): Promise<void> {\n if (this.eventPublisher) {\n await this.eventPublisher.dispose();\n this.eventPublisher = undefined;\n }\n\n if (this.eventRedisClient) {\n this.eventRedisClient.disconnect();\n this.eventRedisClient = undefined;\n }\n }\n\n // ----------------------------------------------------\n\n protected async setupDatabase(container: IContainer, options: DataSourceOptions): Promise<void> {\n const logger = container.resolve(LoggerInjectionKey);\n\n const check = await checkDatabase({ options });\n\n if (!check.exists) {\n logger.debug('Creating database...');\n await createDatabase({\n options,\n synchronize: false,\n ifNotExist: true, \n });\n logger.debug('Created database');\n }\n }\n\n protected async migrate(container: IContainer, dataSource: DataSource): Promise<void> {\n const logger = container.resolve(LoggerInjectionKey);\n\n logger.debug('Migrating database...');\n await synchronizeDatabaseSchema(dataSource);\n logger.debug('Migrated database');\n }\n\n // ----------------------------------------------------\n\n /**\n * Load data source options for connection.\n *\n * @protected\n */\n protected async buildDataSourceOptions(container: IContainer) : Promise<DataSourceOptions> {\n const config = container.resolve(ConfigInjectionKey);\n\n let options : DataSourceOptions | undefined;\n if (config.db) {\n options = this.optionsBuilder.buildWith(config.db);\n } else {\n options = this.optionsBuilder.buildWithEnv();\n }\n\n if (!isDatabaseTypeSupported(options.type)) {\n throw new AuthupError(`Database type ${options.type} is not supported (only: mysql, better-sqlite3 and postgres).`);\n }\n\n if (!isDatabaseTypeSupportedForEnvironment(options.type, config.env)) {\n throw new AuthupError(`Database type ${options.type} is not supported for ${config.env}.`);\n }\n\n const cacheResult = container.tryResolve(CacheInjectionKey);\n if (cacheResult.success) {\n Object.assign(options, {\n cache: {\n provider() {\n return new DatabaseQueryResultCache(cacheResult.data);\n },\n },\n } satisfies Partial<DataSourceOptions>);\n }\n\n return options;\n }\n\n protected registerRepositories(container: IContainer, dataSource: DataSource) : void {\n const entities = dataSource.options.entities || [];\n if (!Array.isArray(entities)) {\n return;\n }\n\n for (const entity of entities) {\n if (InstanceChecker.isEntitySchema(entity)) {\n continue;\n }\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n container.register(entity, { useFactory: () => dataSource.getRepository(entity) });\n }\n }\n\n protected registerEventPublisher(container: IContainer, dataSource: DataSource) {\n const config = container.resolve(ConfigInjectionKey);\n const logger = container.resolve(LoggerInjectionKey);\n\n const publisher = new DomainEventPublisher({ logger });\n this.eventPublisher = publisher;\n if (config.redis) {\n const client = createRedisClient(config.redis);\n if (client !== config.redis) {\n this.eventRedisClient = client;\n }\n\n publisher.register(new DomainEventRedisHandler(client));\n publisher.register(new DomainEventSocketHandler(client));\n }\n\n if (config.eventLogEnabled && config.eventLogEntityEnabled) {\n publisher.register(new EntityEventHandler({\n eventService: container.resolve(DatabaseInjectionKey.EventService),\n requestContext: useRequestEventContext,\n options: { retentionDays: config.eventLogEntityRetentionDays },\n }));\n }\n\n container.register(DatabaseInjectionKey.DomainEventPublisher, { useValue: publisher });\n\n for (let i = 0; i < dataSource.subscribers.length; i++) {\n const subscriber = dataSource.subscribers[i];\n if (subscriber instanceof EntitySubscriber) {\n subscriber.setPublisher(publisher);\n }\n }\n }\n\n protected registerEvents(container: IContainer, dataSource: DataSource) {\n const config = container.resolve(ConfigInjectionKey);\n const logger = container.resolve(LoggerInjectionKey);\n\n const repository = new EventRepositoryAdapter(\n dataSource.getRepository<Event>(EventEntity),\n );\n container.register(DatabaseInjectionKey.EventRepository, { useValue: repository });\n\n const service = new EventService({\n repository,\n options: {\n enabled: config.eventLogEnabled,\n retentionDays: config.eventLogRetentionDays,\n },\n logger,\n });\n container.register(DatabaseInjectionKey.EventService, { useValue: service });\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"bindings.mjs","names":["RealmScope","buildRedisKeyPath","PolicyRepository","loadBoundPermissions","options","repository","manager","getRepository","junctionTarget","relations","permission","entries","find","where","cache","id","prefix","cachePrefix","key","cacheKey","milliseconds","policyIds","Set","entry","policyId","add","policyTrees","loadPolicyTrees","map","policies","push","length","undefined","realmScope","OWN","policyRepository","trees","Promise","all","findDescendantsTreeById","then","tree","result"],"sources":["../../../../../src/app/modules/database/repositories/bindings.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 type {\n EntityManager,\n EntityTarget,\n FindOptionsRelations,\n FindOptionsWhere,\n ObjectLiteral,\n} from 'typeorm';\nimport type { BasePolicy, PermissionPolicyBinding } from '@authup/access';\nimport { RealmScope } from '@authup/access';\nimport type { Permission } from '@authup/core-kit';\nimport { buildRedisKeyPath } from '@authup/server-kit';\nimport { PolicyRepository } from '../../../../adapters/database/domains/policy/index.ts';\n\nexport type LoadBoundPermissionsOptions<E extends ObjectLiteral> = {\n manager: EntityManager;\n junctionTarget: EntityTarget<E>;\n where: FindOptionsWhere<E>;\n cachePrefix: string;\n cacheKey: string;\n};\n\ntype PermissionJunction = {\n permission: Permission;\n policyId?: string | null;\n realmScope?: `${RealmScope}` | null;\n};\n\nexport async function loadBoundPermissions<E extends PermissionJunction & ObjectLiteral>(\n options: LoadBoundPermissionsOptions<E>,\n): Promise<PermissionPolicyBinding[]> {\n const repository = options.manager.getRepository(options.junctionTarget);\n const relations = { permission: true } as FindOptionsRelations<E>;\n\n const entries = await repository.find({\n where: options.where,\n relations,\n cache: {\n id: buildRedisKeyPath({ prefix: options.cachePrefix, key: options.cacheKey }),\n milliseconds: 60_000,\n },\n });\n\n const policyIds = new Set<string>();\n for (const entry of entries) {\n if (entry.policyId) {\n policyIds.add(entry.policyId);\n }\n }\n\n const policyTrees = await loadPolicyTrees(options.manager, [...policyIds]);\n\n return entries.map((entry) => {\n const policies: BasePolicy[] = [];\n if (entry.policyId && policyTrees[entry.policyId]) {\n policies.push(policyTrees[entry.policyId]);\n }\n\n return {\n permission: entry.permission,\n policies: policies.length > 0 ? policies : undefined,\n // Fail-closed coercion: a missing column (stale cache / pre-migration row)\n // becomes the most restrictive `own`.\n realmScope: entry.realmScope ?? RealmScope.OWN,\n };\n });\n}\n\nasync function loadPolicyTrees(\n manager: EntityManager,\n policyIds: string[],\n): Promise<Record<string, BasePolicy>> {\n if (policyIds.length === 0) {\n return {};\n }\n\n const policyRepository = new PolicyRepository(manager);\n const trees = await Promise.all(\n policyIds.map((id) => policyRepository.findDescendantsTreeById(id)\n .then((tree) => [id, tree] as const)),\n );\n\n const result: Record<string, BasePolicy> = {};\n for (const [id, tree] of trees) {\n if (tree) {\n result[id] = tree;\n }\n }\n return result;\n}\n"],"mappings":";;;;;;;;AAkCA,eAAsBG,qBAClBC,SAAuC;CAKvC,MAAMO,UAAU,MAHGP,QAAQE,QAAQC,cAAcH,QAAQI,cAGnCH,CAAAA,CAAWO,KAAK;EAClCC,OAAOT,QAAQS;EACfJ,WAAAA,EAJgBC,YAAY,KAI5BD;EACAK,OAAO;GACHC,IAAId,kBAAkB;IAAEe,QAAQZ,QAAQa;IAAaC,KAAKd,QAAQe;GAAS,CAAA;GAC3EC,cAAc;EAClB;CACJ,CAAA;CAEA,MAAMC,4BAAY,IAAIC,IAAAA;CACtB,KAAK,MAAMC,SAASZ,SAChB,IAAIY,MAAMC,UACNH,UAAUI,IAAIF,MAAMC,QAAQ;CAIpC,MAAME,cAAc,MAAMC,gBAAgBvB,QAAQE,SAAS,CAAA,GAAIe,SAAAA,CAAU;CAEzE,OAAOV,QAAQiB,KAAKL,UAAAA;EAChB,MAAMM,WAAyB,CAAA;EAC/B,IAAIN,MAAMC,YAAYE,YAAYH,MAAMC,WACpCK,SAASC,KAAKJ,YAAYH,MAAMC,SAAS;EAG7C,OAAO;GACHd,YAAYa,MAAMb;GAClBmB,UAAUA,SAASE,SAAS,IAAIF,WAAWG,KAAAA;GAG3CC,YAAYV,MAAMU,cAAcjC,WAAWkC;EAC/C;CACJ,CAAA;AACJ;AAEA,eAAeP,gBACXrB,SACAe,WAAmB;CAEnB,IAAIA,UAAUU,WAAW,GACrB,OAAO,CAAC;CAGZ,MAAMI,mBAAmB,IAAIjC,iBAAiBI,OAAAA;CAC9C,MAAM8B,QAAQ,MAAMC,QAAQC,IACxBjB,UAAUO,KAAKb,OAAOoB,iBAAiBI,wBAAwBxB,EAAAA,CAAAA,CAC1DyB,MAAMC,SAAS,CAAC1B,IAAI0B,IAAAA,CAAK,CAAA,CAAA;CAGlC,MAAMC,SAAqC,CAAC;CAC5C,KAAK,MAAM,CAAC3B,IAAI0B,SAASL,OACrB,IAAIK,MACAC,OAAO3B,MAAM0B;CAGrB,OAAOC;AACX"}
1
+ {"version":3,"file":"bindings.mjs","names":["RealmScope","buildRedisKeyPath","PolicyRepository","loadBoundPermissions","options","repository","manager","getRepository","junctionTarget","relations","permission","entries","find","where","cache","id","prefix","cachePrefix","key","cacheKey","milliseconds","policyIds","Set","entry","policyId","add","policyTrees","loadPolicyTrees","map","policies","push","length","undefined","realmScope","OWN","policyRepository","trees","Promise","all","findDescendantsTreeById","then","tree","result"],"sources":["../../../../../src/app/modules/database/repositories/bindings.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 type {\n EntityManager,\n EntityTarget,\n FindOptionsRelations,\n FindOptionsWhere,\n ObjectLiteral,\n} from 'typeorm';\nimport type { BasePolicy, PermissionPolicyBinding } from '@authup/access';\nimport { RealmScope } from '@authup/access';\nimport type { Permission } from '@authup/core-kit';\nimport { buildRedisKeyPath } from '@authup/server-kit';\nimport { PolicyRepository } from '../../../../adapters/database/domains/policy/index.ts';\n\nexport type LoadBoundPermissionsOptions<E extends ObjectLiteral> = {\n manager: EntityManager;\n junctionTarget: EntityTarget<E>;\n where: FindOptionsWhere<E>;\n cachePrefix: string;\n cacheKey: string;\n};\n\ntype PermissionJunction = {\n permission: Permission;\n policyId?: string | null;\n realmScope?: `${RealmScope}` | null;\n};\n\nexport async function loadBoundPermissions<E extends PermissionJunction & ObjectLiteral>(\n options: LoadBoundPermissionsOptions<E>,\n): Promise<PermissionPolicyBinding[]> {\n const repository = options.manager.getRepository(options.junctionTarget);\n const relations = { permission: true } as FindOptionsRelations<E>;\n\n const entries = await repository.find({\n where: options.where,\n relations,\n cache: {\n id: buildRedisKeyPath({ prefix: options.cachePrefix, key: options.cacheKey }),\n milliseconds: 60_000,\n },\n });\n\n const policyIds = new Set<string>();\n for (const entry of entries) {\n if (entry.policyId) {\n policyIds.add(entry.policyId);\n }\n }\n\n const policyTrees = await loadPolicyTrees(options.manager, [...policyIds]);\n\n return entries.map((entry) => {\n const policies: BasePolicy[] = [];\n if (entry.policyId && policyTrees[entry.policyId]) {\n policies.push(policyTrees[entry.policyId]);\n }\n\n return {\n permission: entry.permission,\n policies: policies.length > 0 ? policies : undefined,\n // Fail-closed coercion: a missing column (stale cache / pre-migration row)\n // becomes the most restrictive `own`.\n realmScope: entry.realmScope ?? RealmScope.OWN,\n };\n });\n}\n\nasync function loadPolicyTrees(\n manager: EntityManager,\n policyIds: string[],\n): Promise<Record<string, BasePolicy>> {\n if (policyIds.length === 0) {\n return {};\n }\n\n const policyRepository = new PolicyRepository(manager);\n const trees = await Promise.all(\n policyIds.map((id) => policyRepository.findDescendantsTreeById(id)\n .then((tree) => [id, tree] as const)),\n );\n\n const result: Record<string, BasePolicy> = {};\n for (const [id, tree] of trees) {\n if (tree) {\n result[id] = tree;\n }\n }\n return result;\n}\n"],"mappings":";;;;;;;;AAkCA,eAAsBG,qBAClBC,SAAuC;CAKvC,MAAMO,UAAU,MAHGP,QAAQE,QAAQC,cAAcH,QAAQI,cAGnCH,CAAAA,CAAWO,KAAK;EAClCC,OAAOT,QAAQS;EACfJ,WAAAA,EAJgBC,YAAY,KAI5BD;EACAK,OAAO;GACHC,IAAId,kBAAkB;IAAEe,QAAQZ,QAAQa;IAAaC,KAAKd,QAAQe;GAAS,CAAA;GAC3EC,cAAc;EAClB;CACJ,CAAA;CAEA,MAAMC,4BAAY,IAAIC,IAAAA;CACtB,KAAK,MAAMC,SAASZ,SAChB,IAAIY,MAAMC,UACNH,UAAUI,IAAIF,MAAMC,QAAQ;CAIpC,MAAME,cAAc,MAAMC,gBAAgBvB,QAAQE,SAAS,CAAIe,GAAAA,SAAU,CAAA;CAEzE,OAAOV,QAAQiB,KAAKL,UAAAA;EAChB,MAAMM,WAAyB,CAAA;EAC/B,IAAIN,MAAMC,YAAYE,YAAYH,MAAMC,WACpCK,SAASC,KAAKJ,YAAYH,MAAMC,SAAS;EAG7C,OAAO;GACHd,YAAYa,MAAMb;GAClBmB,UAAUA,SAASE,SAAS,IAAIF,WAAWG,KAAAA;GAG3CC,YAAYV,MAAMU,cAAcjC,WAAWkC;EAC/C;CACJ,CAAA;AACJ;AAEA,eAAeP,gBACXrB,SACAe,WAAmB;CAEnB,IAAIA,UAAUU,WAAW,GACrB,OAAO,CAAC;CAGZ,MAAMI,mBAAmB,IAAIjC,iBAAiBI,OAAAA;CAC9C,MAAM8B,QAAQ,MAAMC,QAAQC,IACxBjB,UAAUO,KAAKb,OAAOoB,iBAAiBI,wBAAwBxB,EAAAA,CAAAA,CAC1DyB,MAAMC,SAAS,CAAC1B,IAAI0B,IAAK,CAAA,CAAA,CAAA;CAGlC,MAAMC,SAAqC,CAAC;CAC5C,KAAK,MAAM,CAAC3B,IAAI0B,SAASL,OACrB,IAAIK,MACAC,OAAO3B,MAAM0B;CAGrB,OAAOC;AACX"}
@@ -1 +1 @@
1
- {"version":3,"file":"repository.mjs","names":["buildRedisKeyPath","isUUID","validateEntityJoinColumns","applyQuery","DatabaseConflictError","applyRealmScopeSelect","isEntityUnique","translateWhereConditions","loadBoundPermissions","CachePrefix","ClientEntity","ClientPermissionEntity","ClientRoleEntity","RealmRepositoryAdapter","ClientRepositoryAdapter","repository","realmRepository","ctx","findMany","query","qb","createQueryBuilder","groupBy","pagination","entities","total","getManyAndCount","data","meta","findOneById","id","findOneBy","findOneByName","name","realmKey","where","realmId","resolveId","andWhere","getOne","findOne","findOneByIdOrName","idOrName","realm","findManyBy","findBy","findOneWithSecret","Object","entries","forEach","key","value","addSelect","create","merge","entity","save","remove","validateJoinColumns","dataSource","manager","connection","entityTarget","checkUniqueness","existing","isUnique","entityExisting","getBoundRoles","getRepository","find","clientId","relations","role","cache","prefix","CLIENT_OWNED_ROLES","milliseconds","map","entry","getBoundPermissions","junctionTarget","cachePrefix","CLIENT_OWNED_PERMISSIONS","cacheKey"],"sources":["../../../../../../src/app/modules/database/repositories/client/repository.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 type { Client, Realm, Role } from '@authup/core-kit';\nimport type { IQuery } from '@rapiq/core';\nimport type { PermissionPolicyBinding } from '@authup/access';\nimport { buildRedisKeyPath } from '@authup/server-kit';\nimport { isUUID } from '@authup/kit';\nimport type { Repository } from 'typeorm';\nimport { validateEntityJoinColumns } from 'typeorm-extension';\nimport { applyQuery } from '../query.ts';\nimport type { EntityRepositoryFindManyResult } from '@authup/server-kit';\nimport type { IClientRepository, IRealmRepository } from '../../../../../core/index.ts';\nimport { DatabaseConflictError } from '../../../../../adapters/database/index.ts';\nimport { applyRealmScopeSelect, isEntityUnique, translateWhereConditions } from '../helpers.ts';\nimport { loadBoundPermissions } from '../bindings.ts';\nimport {\n CachePrefix,\n ClientEntity,\n ClientPermissionEntity,\n ClientRoleEntity,\n} from '../../../../../adapters/database/domains/index.ts';\nimport { RealmRepositoryAdapter } from '../realm/repository.ts';\n\nexport type ClientRepositoryAdapterContext = {\n repository: Repository<Client>,\n realmRepository: Repository<Realm>,\n};\n\nexport class ClientRepositoryAdapter implements IClientRepository {\n private readonly repository: Repository<Client>;\n\n private readonly realmRepository: IRealmRepository;\n\n constructor(ctx: ClientRepositoryAdapterContext) {\n this.repository = ctx.repository;\n this.realmRepository = new RealmRepositoryAdapter(ctx.realmRepository);\n }\n\n async findMany(query: IQuery): Promise<EntityRepositoryFindManyResult<Client>> {\n const qb = this.repository.createQueryBuilder('client');\n qb.groupBy('client.id');\n\n const { pagination } = applyQuery(qb, query);\n\n applyRealmScopeSelect(qb, 'client', ['secretHashed', 'secretEncrypted']);\n\n const [entities, total] = await qb.getManyAndCount();\n\n return {\n data: entities,\n meta: {\n total,\n ...pagination,\n },\n };\n }\n\n findOneById(id: string): Promise<Client | null> {\n return this.findOneBy({ id });\n }\n\n async findOneByName(name: string, realmKey?: string): Promise<Client | null> {\n const qb = this.repository.createQueryBuilder('client');\n qb.where('client.name = :name', { name });\n\n if (realmKey) {\n const realmId = await this.realmRepository.resolveId(realmKey);\n if (!realmId) {\n return null;\n }\n qb.andWhere('client.realmId = :realmId', { realmId });\n }\n\n return qb.getOne();\n }\n\n async findOne(id: string, query?: IQuery, realmKey?: string): Promise<Client | null> {\n const qb = this.repository.createQueryBuilder('client');\n\n if (isUUID(id)) {\n qb.where('client.id = :id', { id });\n } else {\n qb.where('client.name = :name', { name: id });\n\n if (realmKey) {\n const realmId = await this.realmRepository.resolveId(realmKey);\n if (!realmId) {\n return null;\n }\n qb.andWhere('client.realmId = :realmId', { realmId });\n }\n }\n\n applyQuery(qb, query);\n\n return qb.getOne();\n }\n\n async findOneByIdOrName(idOrName: string, realm?: string): Promise<Client | null> {\n return isUUID(idOrName) ?\n this.findOneById(idOrName) :\n this.findOneByName(idOrName, realm);\n }\n\n async findManyBy(where: Record<string, any>): Promise<Client[]> {\n return this.repository.findBy(translateWhereConditions(where));\n }\n\n async findOneBy(where: Record<string, any>): Promise<Client | null> {\n return this.repository.findOneBy(translateWhereConditions(where));\n }\n\n async findOneWithSecret(where: Record<string, any>): Promise<Client | null> {\n const qb = this.repository.createQueryBuilder('client');\n\n Object.entries(where).forEach(([key, value]) => {\n qb.andWhere(`client.${key} = :${key}`, { [key]: value });\n });\n\n qb.addSelect('client.secret');\n\n return qb.getOne();\n }\n\n create(data: Partial<Client>): Client {\n return this.repository.create(data);\n }\n\n merge(entity: Client, data: Partial<Client>): Client {\n return this.repository.merge(entity, data);\n }\n\n async save(entity: Client): Promise<Client> {\n return this.repository.save(entity);\n }\n\n async remove(entity: Client): Promise<void> {\n await this.repository.remove(entity);\n }\n\n async validateJoinColumns(data: Partial<Client>): Promise<void> {\n await validateEntityJoinColumns(data, {\n dataSource: this.repository.manager.connection,\n entityTarget: ClientEntity,\n });\n }\n\n async checkUniqueness(data: Partial<Client>, existing?: Client): Promise<void> {\n const isUnique = await isEntityUnique({\n dataSource: this.repository.manager.connection,\n entityTarget: ClientEntity,\n entity: data,\n entityExisting: existing,\n });\n\n if (!isUnique) {\n throw new DatabaseConflictError();\n }\n }\n\n async getBoundRoles(entity: string | Client): Promise<Role[]> {\n const id = typeof entity === 'string' ? entity : entity.id;\n const entries = await this.repository.manager\n .getRepository(ClientRoleEntity)\n .find({\n where: { clientId: id },\n relations: { role: true },\n cache: {\n id: buildRedisKeyPath({\n prefix: CachePrefix.CLIENT_OWNED_ROLES,\n key: id,\n }),\n milliseconds: 60_000,\n },\n });\n\n return entries.map((entry) => entry.role);\n }\n\n async getBoundPermissions(entity: string | Client): Promise<PermissionPolicyBinding[]> {\n const id = typeof entity === 'string' ? entity : entity.id;\n return loadBoundPermissions({\n manager: this.repository.manager,\n junctionTarget: ClientPermissionEntity,\n where: { clientId: id },\n cachePrefix: CachePrefix.CLIENT_OWNED_PERMISSIONS,\n cacheKey: id,\n });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"repository.mjs","names":["buildRedisKeyPath","isUUID","validateEntityJoinColumns","applyQuery","DatabaseConflictError","applyRealmScopeSelect","isEntityUnique","translateWhereConditions","loadBoundPermissions","CachePrefix","ClientEntity","ClientPermissionEntity","ClientRoleEntity","RealmRepositoryAdapter","ClientRepositoryAdapter","repository","realmRepository","ctx","findMany","query","qb","createQueryBuilder","groupBy","pagination","entities","total","getManyAndCount","data","meta","findOneById","id","findOneBy","findOneByName","name","realmKey","where","realmId","resolveId","andWhere","getOne","findOne","findOneByIdOrName","idOrName","realm","findManyBy","findBy","findOneWithSecret","Object","entries","forEach","key","value","addSelect","create","merge","entity","save","remove","validateJoinColumns","dataSource","manager","connection","entityTarget","checkUniqueness","existing","isUnique","entityExisting","getBoundRoles","getRepository","find","clientId","relations","role","cache","prefix","CLIENT_OWNED_ROLES","milliseconds","map","entry","getBoundPermissions","junctionTarget","cachePrefix","CLIENT_OWNED_PERMISSIONS","cacheKey"],"sources":["../../../../../../src/app/modules/database/repositories/client/repository.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 type { Client, Realm, Role } from '@authup/core-kit';\nimport type { IQuery } from '@rapiq/core';\nimport type { PermissionPolicyBinding } from '@authup/access';\nimport { buildRedisKeyPath } from '@authup/server-kit';\nimport { isUUID } from '@authup/kit';\nimport type { Repository } from 'typeorm';\nimport { validateEntityJoinColumns } from 'typeorm-extension';\nimport { applyQuery } from '../query.ts';\nimport type { EntityRepositoryFindManyResult } from '@authup/server-kit';\nimport type { IClientRepository, IRealmRepository } from '../../../../../core/index.ts';\nimport { DatabaseConflictError } from '../../../../../adapters/database/index.ts';\nimport { applyRealmScopeSelect, isEntityUnique, translateWhereConditions } from '../helpers.ts';\nimport { loadBoundPermissions } from '../bindings.ts';\nimport {\n CachePrefix,\n ClientEntity,\n ClientPermissionEntity,\n ClientRoleEntity,\n} from '../../../../../adapters/database/domains/index.ts';\nimport { RealmRepositoryAdapter } from '../realm/repository.ts';\n\nexport type ClientRepositoryAdapterContext = {\n repository: Repository<Client>,\n realmRepository: Repository<Realm>,\n};\n\nexport class ClientRepositoryAdapter implements IClientRepository {\n private readonly repository: Repository<Client>;\n\n private readonly realmRepository: IRealmRepository;\n\n constructor(ctx: ClientRepositoryAdapterContext) {\n this.repository = ctx.repository;\n this.realmRepository = new RealmRepositoryAdapter(ctx.realmRepository);\n }\n\n async findMany(query: IQuery): Promise<EntityRepositoryFindManyResult<Client>> {\n const qb = this.repository.createQueryBuilder('client');\n qb.groupBy('client.id');\n\n const { pagination } = applyQuery(qb, query);\n\n applyRealmScopeSelect(qb, 'client', ['secretHashed', 'secretEncrypted']);\n\n const [entities, total] = await qb.getManyAndCount();\n\n return {\n data: entities,\n meta: {\n total,\n ...pagination,\n },\n };\n }\n\n findOneById(id: string): Promise<Client | null> {\n return this.findOneBy({ id });\n }\n\n async findOneByName(name: string, realmKey?: string): Promise<Client | null> {\n const qb = this.repository.createQueryBuilder('client');\n qb.where('client.name = :name', { name });\n\n if (realmKey) {\n const realmId = await this.realmRepository.resolveId(realmKey);\n if (!realmId) {\n return null;\n }\n qb.andWhere('client.realmId = :realmId', { realmId });\n }\n\n return qb.getOne();\n }\n\n async findOne(id: string, query?: IQuery, realmKey?: string): Promise<Client | null> {\n const qb = this.repository.createQueryBuilder('client');\n\n if (isUUID(id)) {\n qb.where('client.id = :id', { id });\n } else {\n qb.where('client.name = :name', { name: id });\n\n if (realmKey) {\n const realmId = await this.realmRepository.resolveId(realmKey);\n if (!realmId) {\n return null;\n }\n qb.andWhere('client.realmId = :realmId', { realmId });\n }\n }\n\n applyQuery(qb, query);\n\n return qb.getOne();\n }\n\n async findOneByIdOrName(idOrName: string, realm?: string): Promise<Client | null> {\n return isUUID(idOrName) ?\n this.findOneById(idOrName) :\n this.findOneByName(idOrName, realm);\n }\n\n async findManyBy(where: Record<string, any>): Promise<Client[]> {\n return this.repository.findBy(translateWhereConditions(where));\n }\n\n async findOneBy(where: Record<string, any>): Promise<Client | null> {\n return this.repository.findOneBy(translateWhereConditions(where));\n }\n\n async findOneWithSecret(where: Record<string, any>): Promise<Client | null> {\n const qb = this.repository.createQueryBuilder('client');\n\n Object.entries(where).forEach(([key, value]) => {\n qb.andWhere(`client.${key} = :${key}`, { [key]: value });\n });\n\n qb.addSelect('client.secret');\n\n return qb.getOne();\n }\n\n create(data: Partial<Client>): Client {\n return this.repository.create(data);\n }\n\n merge(entity: Client, data: Partial<Client>): Client {\n return this.repository.merge(entity, data);\n }\n\n async save(entity: Client): Promise<Client> {\n return this.repository.save(entity);\n }\n\n async remove(entity: Client): Promise<void> {\n await this.repository.remove(entity);\n }\n\n async validateJoinColumns(data: Partial<Client>): Promise<void> {\n await validateEntityJoinColumns(data, {\n dataSource: this.repository.manager.connection,\n entityTarget: ClientEntity,\n });\n }\n\n async checkUniqueness(data: Partial<Client>, existing?: Client): Promise<void> {\n const isUnique = await isEntityUnique({\n dataSource: this.repository.manager.connection,\n entityTarget: ClientEntity,\n entity: data,\n entityExisting: existing,\n });\n\n if (!isUnique) {\n throw new DatabaseConflictError();\n }\n }\n\n async getBoundRoles(entity: string | Client): Promise<Role[]> {\n const id = typeof entity === 'string' ? entity : entity.id;\n const entries = await this.repository.manager\n .getRepository(ClientRoleEntity)\n .find({\n where: { clientId: id },\n relations: { role: true },\n cache: {\n id: buildRedisKeyPath({\n prefix: CachePrefix.CLIENT_OWNED_ROLES,\n key: id,\n }),\n milliseconds: 60_000,\n },\n });\n\n return entries.map((entry) => entry.role);\n }\n\n async getBoundPermissions(entity: string | Client): Promise<PermissionPolicyBinding[]> {\n const id = typeof entity === 'string' ? entity : entity.id;\n return loadBoundPermissions({\n manager: this.repository.manager,\n junctionTarget: ClientPermissionEntity,\n where: { clientId: id },\n cachePrefix: CachePrefix.CLIENT_OWNED_PERMISSIONS,\n cacheKey: id,\n });\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"repository.mjs","names":["LessThan","applyQuery","applyRealmScopeSelect","EventRepositoryAdapter","repository","create","data","save","entity","findOneById","id","findOneBy","findMany","query","options","qb","createQueryBuilder","pagination","owner","andWhere","ownerActorId","actorId","ownerActorType","actorType","realmId","routeRealmId","visibility","constraints","parameters","realmIds","filter","length","push","visibleRealmIds","includes","visibleActorId","visibleActorType","join","entities","total","getManyAndCount","meta","countRecent","where","name","since","Date","actorName","requestIpAddress","getCount","deleteExpired","now","result","delete","expiring","expiresAt","affected"],"sources":["../../../../../../src/app/modules/database/repositories/event/repository.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 type { Event } from '@authup/core-kit';\nimport type { IQuery } from '@rapiq/core';\nimport type { Repository } from 'typeorm';\nimport { LessThan } from 'typeorm';\nimport { applyQuery } from '../query.ts';\nimport type { EntityRepositoryFindManyResult } from '@authup/server-kit';\nimport type {\n EventCountRecentFilter,\n EventFindManyOptions,\n IEventRepository,\n} from '../../../../../core/index.ts';\nimport { applyRealmScopeSelect } from '../helpers.ts';\n\nexport class EventRepositoryAdapter implements IEventRepository {\n private readonly repository: Repository<Event>;\n\n constructor(repository: Repository<Event>) {\n this.repository = repository;\n }\n\n create(data: Partial<Event>): Event {\n return this.repository.create(data);\n }\n\n async save(entity: Event): Promise<Event> {\n return this.repository.save(entity);\n }\n\n async findOneById(id: string): Promise<Event | null> {\n return this.repository.findOneBy({ id });\n }\n\n async findMany(\n query: IQuery,\n options: EventFindManyOptions = {},\n ): Promise<EntityRepositoryFindManyResult<Event>> {\n const qb = this.repository.createQueryBuilder('event');\n\n const { pagination } = applyQuery(qb, query);\n\n applyRealmScopeSelect(qb, 'event', ['actorId', 'actorType']);\n\n if (options.owner) {\n // mandatory constraint — not overridable by a rapiq filter\n qb.andWhere('event.actorId = :ownerActorId AND event.actorType = :ownerActorType', {\n ownerActorId: options.owner.actorId,\n ownerActorType: options.owner.actorType,\n });\n }\n\n if (options.realmId) {\n qb.andWhere('event.realmId = :routeRealmId', { routeRealmId: options.realmId });\n }\n\n if (options.visibility) {\n const constraints: string[] = [];\n const parameters: Record<string, unknown> = {};\n const realmIds = options.visibility.realmIds\n .filter((realmId): realmId is string => realmId !== null);\n\n if (realmIds.length > 0) {\n constraints.push('event.realmId IN (:...visibleRealmIds)');\n parameters.visibleRealmIds = realmIds;\n }\n if (options.visibility.realmIds.includes(null)) {\n constraints.push('event.realmId IS NULL');\n }\n if (options.visibility.owner) {\n constraints.push('(event.actorId = :visibleActorId AND event.actorType = :visibleActorType)');\n parameters.visibleActorId = options.visibility.owner.actorId;\n parameters.visibleActorType = options.visibility.owner.actorType;\n }\n\n qb.andWhere(`(${constraints.length > 0 ? constraints.join(' OR ') : '1 = 0'})`, parameters);\n }\n\n const [entities, total] = await qb.getManyAndCount();\n\n return {\n data: entities,\n meta: {\n total,\n ...pagination,\n },\n };\n }\n\n async countRecent(filter: EventCountRecentFilter): Promise<number> {\n const qb = this.repository.createQueryBuilder('event')\n .where('event.name = :name', { name: filter.name })\n .andWhere('event.createdAt > :since', { since: new Date(filter.since) });\n\n if (filter.actorName) {\n qb.andWhere('event.actorName = :actorName', { actorName: filter.actorName });\n }\n\n if (filter.requestIpAddress) {\n qb.andWhere('event.requestIpAddress = :requestIpAddress', { requestIpAddress: filter.requestIpAddress });\n }\n\n if (typeof filter.realmId !== 'undefined') {\n if (filter.realmId === null) {\n qb.andWhere('event.realmId IS NULL');\n } else {\n qb.andWhere('event.realmId = :realmId', { realmId: filter.realmId });\n }\n }\n\n return qb.getCount();\n }\n\n async deleteExpired(now: string): Promise<number> {\n const result = await this.repository.delete({\n expiring: true,\n expiresAt: LessThan(now),\n });\n\n return result.affected ?? 0;\n }\n}\n"],"mappings":";;;;;;;AAoBA,IAAaG,yBAAb,MAAaA;CACQC;CAEjB,YAAYA,YAA+B;EACvC,KAAKA,aAAaA;CACtB;CAEAC,OAAOC,MAA6B;EAChC,OAAO,KAAKF,WAAWC,OAAOC,IAAAA;CAClC;CAEA,MAAMC,KAAKC,QAA+B;EACtC,OAAO,KAAKJ,WAAWG,KAAKC,MAAAA;CAChC;CAEA,MAAMC,YAAYC,IAAmC;EACjD,OAAO,KAAKN,WAAWO,UAAU,EAAED,GAAG,CAAA;CAC1C;CAEA,MAAME,SACFC,OACAC,UAAgC,CAAC,GACa;EAC9C,MAAMC,KAAK,KAAKX,WAAWY,mBAAmB,OAAA;EAE9C,MAAM,EAAEC,eAAehB,WAAWc,IAAIF,KAAAA;EAEtCX,sBAAsBa,IAAI,SAAS,CAAC,WAAW,WAAA,CAAY;EAE3D,IAAID,QAAQI,OAERH,GAAGI,SAAS,uEAAuE;GAC/EC,cAAcN,QAAQI,MAAMG;GAC5BC,gBAAgBR,QAAQI,MAAMK;EAClC,CAAA;EAGJ,IAAIT,QAAQU,SACRT,GAAGI,SAAS,iCAAiC,EAAEM,cAAcX,QAAQU,QAAQ,CAAA;EAGjF,IAAIV,QAAQY,YAAY;GACpB,MAAMC,cAAwB,CAAA;GAC9B,MAAMC,aAAsC,CAAC;GAC7C,MAAMC,WAAWf,QAAQY,WAAWG,SAC/BC,QAAQN,YAA+BA,YAAY,IAAA;GAExD,IAAIK,SAASE,SAAS,GAAG;IACrBJ,YAAYK,KAAK,wCAAA;IACjBJ,WAAWK,kBAAkBJ;GACjC;GACA,IAAIf,QAAQY,WAAWG,SAASK,SAAS,IAAA,GACrCP,YAAYK,KAAK,uBAAA;GAErB,IAAIlB,QAAQY,WAAWR,OAAO;IAC1BS,YAAYK,KAAK,2EAAA;IACjBJ,WAAWO,iBAAiBrB,QAAQY,WAAWR,MAAMG;IACrDO,WAAWQ,mBAAmBtB,QAAQY,WAAWR,MAAMK;GAC3D;GAEAR,GAAGI,SAAS,IAAIQ,YAAYI,SAAS,IAAIJ,YAAYU,KAAK,MAAA,IAAU,QAAQ,IAAIT,UAAAA;EACpF;EAEA,MAAM,CAACU,UAAUC,SAAS,MAAMxB,GAAGyB,gBAAe;EAElD,OAAO;GACHlC,MAAMgC;GACNG,MAAM;IACFF;IACA,GAAGtB;GACP;EACJ;CACJ;CAEA,MAAMyB,YAAYZ,QAAiD;EAC/D,MAAMf,KAAK,KAAKX,WAAWY,mBAAmB,OAAA,CAAA,CACzC2B,MAAM,sBAAsB,EAAEC,MAAMd,OAAOc,KAAK,CAAA,CAAA,CAChDzB,SAAS,4BAA4B,EAAE0B,OAAO,IAAIC,KAAKhB,OAAOe,KAAK,EAAE,CAAA;EAE1E,IAAIf,OAAOiB,WACPhC,GAAGI,SAAS,gCAAgC,EAAE4B,WAAWjB,OAAOiB,UAAU,CAAA;EAG9E,IAAIjB,OAAOkB,kBACPjC,GAAGI,SAAS,8CAA8C,EAAE6B,kBAAkBlB,OAAOkB,iBAAiB,CAAA;EAG1G,IAAI,OAAOlB,OAAON,YAAY,aAC1B,IAAIM,OAAON,YAAY,MACnBT,GAAGI,SAAS,uBAAA;OAEZJ,GAAGI,SAAS,4BAA4B,EAAEK,SAASM,OAAON,QAAQ,CAAA;EAI1E,OAAOT,GAAGkC,SAAQ;CACtB;CAEA,MAAMC,cAAcC,KAA8B;EAM9C,QAAOC,MALc,KAAKhD,WAAWiD,OAAO;GACxCC,UAAU;GACVC,WAAWvD,SAASmD,GAAAA;EACxB,CAAA,EAAA,CAEcK,YAAY;CAC9B;AACJ"}
1
+ {"version":3,"file":"repository.mjs","names":["LessThan","applyQuery","applyRealmScopeSelect","EventRepositoryAdapter","repository","create","data","save","entity","findOneById","id","findOneBy","findMany","query","options","qb","createQueryBuilder","pagination","owner","andWhere","ownerActorId","actorId","ownerActorType","actorType","realmId","routeRealmId","visibility","constraints","parameters","realmIds","filter","length","push","visibleRealmIds","includes","visibleActorId","visibleActorType","join","entities","total","getManyAndCount","meta","countRecent","where","name","since","Date","actorName","requestIpAddress","getCount","deleteExpired","now","result","delete","expiring","expiresAt","affected"],"sources":["../../../../../../src/app/modules/database/repositories/event/repository.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 type { Event } from '@authup/core-kit';\nimport type { IQuery } from '@rapiq/core';\nimport type { Repository } from 'typeorm';\nimport { LessThan } from 'typeorm';\nimport { applyQuery } from '../query.ts';\nimport type { EntityRepositoryFindManyResult } from '@authup/server-kit';\nimport type {\n EventCountRecentFilter,\n EventFindManyOptions,\n IEventRepository,\n} from '../../../../../core/index.ts';\nimport { applyRealmScopeSelect } from '../helpers.ts';\n\nexport class EventRepositoryAdapter implements IEventRepository {\n private readonly repository: Repository<Event>;\n\n constructor(repository: Repository<Event>) {\n this.repository = repository;\n }\n\n create(data: Partial<Event>): Event {\n return this.repository.create(data);\n }\n\n async save(entity: Event): Promise<Event> {\n return this.repository.save(entity);\n }\n\n async findOneById(id: string): Promise<Event | null> {\n return this.repository.findOneBy({ id });\n }\n\n async findMany(\n query: IQuery,\n options: EventFindManyOptions = {},\n ): Promise<EntityRepositoryFindManyResult<Event>> {\n const qb = this.repository.createQueryBuilder('event');\n\n const { pagination } = applyQuery(qb, query);\n\n applyRealmScopeSelect(qb, 'event', ['actorId', 'actorType']);\n\n if (options.owner) {\n // mandatory constraint — not overridable by a rapiq filter\n qb.andWhere('event.actorId = :ownerActorId AND event.actorType = :ownerActorType', {\n ownerActorId: options.owner.actorId,\n ownerActorType: options.owner.actorType,\n });\n }\n\n if (options.realmId) {\n qb.andWhere('event.realmId = :routeRealmId', { routeRealmId: options.realmId });\n }\n\n if (options.visibility) {\n const constraints: string[] = [];\n const parameters: Record<string, unknown> = {};\n const realmIds = options.visibility.realmIds\n .filter((realmId): realmId is string => realmId !== null);\n\n if (realmIds.length > 0) {\n constraints.push('event.realmId IN (:...visibleRealmIds)');\n parameters.visibleRealmIds = realmIds;\n }\n if (options.visibility.realmIds.includes(null)) {\n constraints.push('event.realmId IS NULL');\n }\n if (options.visibility.owner) {\n constraints.push('(event.actorId = :visibleActorId AND event.actorType = :visibleActorType)');\n parameters.visibleActorId = options.visibility.owner.actorId;\n parameters.visibleActorType = options.visibility.owner.actorType;\n }\n\n qb.andWhere(`(${constraints.length > 0 ? constraints.join(' OR ') : '1 = 0'})`, parameters);\n }\n\n const [entities, total] = await qb.getManyAndCount();\n\n return {\n data: entities,\n meta: {\n total,\n ...pagination,\n },\n };\n }\n\n async countRecent(filter: EventCountRecentFilter): Promise<number> {\n const qb = this.repository.createQueryBuilder('event')\n .where('event.name = :name', { name: filter.name })\n .andWhere('event.createdAt > :since', { since: new Date(filter.since) });\n\n if (filter.actorName) {\n qb.andWhere('event.actorName = :actorName', { actorName: filter.actorName });\n }\n\n if (filter.requestIpAddress) {\n qb.andWhere('event.requestIpAddress = :requestIpAddress', { requestIpAddress: filter.requestIpAddress });\n }\n\n if (typeof filter.realmId !== 'undefined') {\n if (filter.realmId === null) {\n qb.andWhere('event.realmId IS NULL');\n } else {\n qb.andWhere('event.realmId = :realmId', { realmId: filter.realmId });\n }\n }\n\n return qb.getCount();\n }\n\n async deleteExpired(now: string): Promise<number> {\n const result = await this.repository.delete({\n expiring: true,\n expiresAt: LessThan(now),\n });\n\n return result.affected ?? 0;\n }\n}\n"],"mappings":";;;;;;;AAoBA,IAAaG,yBAAb,MAAaA;CACQC;CAEjB,YAAYA,YAA+B;EACvC,KAAKA,aAAaA;CACtB;CAEAC,OAAOC,MAA6B;EAChC,OAAO,KAAKF,WAAWC,OAAOC,IAAAA;CAClC;CAEA,MAAMC,KAAKC,QAA+B;EACtC,OAAO,KAAKJ,WAAWG,KAAKC,MAAAA;CAChC;CAEA,MAAMC,YAAYC,IAAmC;EACjD,OAAO,KAAKN,WAAWO,UAAU,EAAED,GAAG,CAAA;CAC1C;CAEA,MAAME,SACFC,OACAC,UAAgC,CAAC,GACa;EAC9C,MAAMC,KAAK,KAAKX,WAAWY,mBAAmB,OAAA;EAE9C,MAAM,EAAEC,eAAehB,WAAWc,IAAIF,KAAAA;EAEtCX,sBAAsBa,IAAI,SAAS,CAAC,WAAW,WAAY,CAAA;EAE3D,IAAID,QAAQI,OAERH,GAAGI,SAAS,uEAAuE;GAC/EC,cAAcN,QAAQI,MAAMG;GAC5BC,gBAAgBR,QAAQI,MAAMK;EAClC,CAAA;EAGJ,IAAIT,QAAQU,SACRT,GAAGI,SAAS,iCAAiC,EAAEM,cAAcX,QAAQU,QAAQ,CAAA;EAGjF,IAAIV,QAAQY,YAAY;GACpB,MAAMC,cAAwB,CAAA;GAC9B,MAAMC,aAAsC,CAAC;GAC7C,MAAMC,WAAWf,QAAQY,WAAWG,SAC/BC,QAAQN,YAA+BA,YAAY,IAAA;GAExD,IAAIK,SAASE,SAAS,GAAG;IACrBJ,YAAYK,KAAK,wCAAA;IACjBJ,WAAWK,kBAAkBJ;GACjC;GACA,IAAIf,QAAQY,WAAWG,SAASK,SAAS,IAAA,GACrCP,YAAYK,KAAK,uBAAA;GAErB,IAAIlB,QAAQY,WAAWR,OAAO;IAC1BS,YAAYK,KAAK,2EAAA;IACjBJ,WAAWO,iBAAiBrB,QAAQY,WAAWR,MAAMG;IACrDO,WAAWQ,mBAAmBtB,QAAQY,WAAWR,MAAMK;GAC3D;GAEAR,GAAGI,SAAS,IAAIQ,YAAYI,SAAS,IAAIJ,YAAYU,KAAK,MAAA,IAAU,QAAQ,IAAIT,UAAAA;EACpF;EAEA,MAAM,CAACU,UAAUC,SAAS,MAAMxB,GAAGyB,gBAAe;EAElD,OAAO;GACHlC,MAAMgC;GACNG,MAAM;IACFF;IACA,GAAGtB;GACP;EACJ;CACJ;CAEA,MAAMyB,YAAYZ,QAAiD;EAC/D,MAAMf,KAAK,KAAKX,WAAWY,mBAAmB,OAAA,CAAA,CACzC2B,MAAM,sBAAsB,EAAEC,MAAMd,OAAOc,KAAK,CAAA,CAAA,CAChDzB,SAAS,4BAA4B,EAAE0B,OAAO,IAAIC,KAAKhB,OAAOe,KAAK,EAAE,CAAA;EAE1E,IAAIf,OAAOiB,WACPhC,GAAGI,SAAS,gCAAgC,EAAE4B,WAAWjB,OAAOiB,UAAU,CAAA;EAG9E,IAAIjB,OAAOkB,kBACPjC,GAAGI,SAAS,8CAA8C,EAAE6B,kBAAkBlB,OAAOkB,iBAAiB,CAAA;EAG1G,IAAI,OAAOlB,OAAON,YAAY,aAC1B,IAAIM,OAAON,YAAY,MACnBT,GAAGI,SAAS,uBAAA;OAEZJ,GAAGI,SAAS,4BAA4B,EAAEK,SAASM,OAAON,QAAQ,CAAA;EAI1E,OAAOT,GAAGkC,SAAQ;CACtB;CAEA,MAAMC,cAAcC,KAA8B;EAM9C,QAAOC,MALc,KAAKhD,WAAWiD,OAAO;GACxCC,UAAU;GACVC,WAAWvD,SAASmD,GAAAA;EACxB,CAAA,EAAA,CAEcK,YAAY;CAC9B;AACJ"}
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.mjs","names":["Brackets","In","IsNull","applyRealmScopeSelect","qb","alias","extraColumns","existing","Set","expressionMap","selects","map","select","selection","selections","column","filter","has","length","addSelect","isEntityUnique","options","metadata","dataSource","getMetadata","entityTarget","repository","getRepository","columnGroups","ownUniques","unique","columns","propertyName","indices","index","isUnique","entityMetadata","target","primaryKeys","primaryColumns","group","createQueryBuilder","where","inner","key","value","entity","andWhere","entityExisting","getOne","translateWhereConditions","result","Object","entries","forEach","Array","isArray"],"sources":["../../../../../src/app/modules/database/repositories/helpers.ts"],"sourcesContent":["/*\n * Copyright (c) 2025-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 type {\n DataSource, \n EntityTarget, \n ObjectLiteral, \n SelectQueryBuilder,\n} from 'typeorm';\nimport { Brackets, In, IsNull } from 'typeorm';\n\n/**\n * Force-load the columns a realm-gated `getMany` per-row check depends on.\n * rapiq honors a client `fields` projection over the adapter `default`, so a\n * projection omitting `realmId` would otherwise leave the per-row\n * `resourceRealmMatch` with no realm to match — neutralizing the realmScope\n * reach factor and leaking cross-realm rows to an own/ownOrNull-scoped reader.\n * Call it AFTER `applyQuery`. Columns already in the projection must be\n * skipped: `addSelect` emits a second identically-aliased column, and under a\n * join + take (the DISTINCT id-subquery) postgres then rejects the wrapper's\n * `ORDER BY \"<alias>_id\"` as ambiguous (mysql: duplicate column name).\n */\nexport function applyRealmScopeSelect<T extends ObjectLiteral>(\n qb: SelectQueryBuilder<T>,\n alias: string,\n extraColumns: string[] = [],\n): void {\n const existing = new Set(qb.expressionMap.selects.map((select) => select.selection));\n const selections = ['realmId', ...extraColumns]\n .map((column) => `${alias}.${column}`)\n .filter((selection) => !existing.has(selection));\n\n if (selections.length > 0) {\n qb.addSelect(selections);\n }\n}\n\n/**\n * Naming-strategy-safe replacement for typeorm-extension's `isEntityUnique`:\n * the upstream helper interpolates bare property names into the WHERE clause,\n * which no longer resolve as columns once the snake_case naming strategy\n * decouples property names (`realmId`) from column names (`realm_id`).\n * Alias-qualified property paths (`entity.realmId`) let TypeORM translate\n * them through the entity metadata instead.\n */\nexport async function isEntityUnique<T extends ObjectLiteral>(options: {\n dataSource: DataSource,\n entityTarget: EntityTarget<T>,\n entity: Partial<T>,\n entityExisting?: T | null,\n}): Promise<boolean> {\n const metadata = options.dataSource.getMetadata(options.entityTarget);\n const repository = options.dataSource.getRepository<T>(options.entityTarget);\n\n const columnGroups : string[][] = metadata.ownUniques.length > 0 ?\n metadata.ownUniques.map(\n (unique) => unique.columns.map((column) => column.propertyName),\n ) :\n metadata.indices\n .filter((index) => index.isUnique && index.entityMetadata.target === metadata.target)\n .map((index) => index.columns.map((column) => column.propertyName));\n\n const primaryKeys = metadata.primaryColumns.map((column) => column.propertyName);\n\n for (const group of columnGroups) {\n const qb = repository.createQueryBuilder('entity');\n\n qb.where(new Brackets((inner) => {\n for (const key of group) {\n const value = (options.entity as ObjectLiteral)[key] ?? null;\n if (value === null) {\n inner.andWhere(`entity.${key} IS NULL`);\n } else {\n inner.andWhere(`entity.${key} = :target_${key}`, { [`target_${key}`]: value });\n }\n }\n }));\n\n if (options.entityExisting) {\n const existing = options.entityExisting as ObjectLiteral;\n qb.andWhere(new Brackets((inner) => {\n for (const key of primaryKeys) {\n const value = existing[key] ?? null;\n if (value === null) {\n inner.andWhere(`entity.${key} IS NOT NULL`);\n } else {\n inner.andWhere(`entity.${key} != :source_${key}`, { [`source_${key}`]: value });\n }\n }\n }));\n }\n\n \n const entity = await qb.getOne();\n if (entity) {\n return false;\n }\n }\n\n return true;\n}\n\nexport function translateWhereConditions(where: Record<string, any>): Record<string, any> {\n const result: Record<string, any> = {};\n Object.entries(where).forEach(([key, value]) => {\n if (value === null) {\n result[key] = IsNull();\n } else if (Array.isArray(value)) {\n result[key] = In(value);\n } else {\n result[key] = value;\n }\n });\n return result;\n}\n"],"mappings":";;;;;;;;;;;;;;;GA0BA,SAAgBG,sBACZC,IACAC,OACAC,eAAyB,CAAA,GAAE;CAE3B,MAAMC,WAAW,IAAIC,IAAIJ,GAAGK,cAAcC,QAAQC,KAAKC,WAAWA,OAAOC,SAAS,CAAA;CAClF,MAAMC,aAAa,CAAC,WAAA,GAAcR,YAAAA,CAAa,CAC1CK,KAAKI,WAAW,GAAGV,MAAM,GAAGU,QAAQ,CAAA,CACpCC,QAAQH,cAAc,CAACN,SAASU,IAAIJ,SAAAA,CAAAA;CAEzC,IAAIC,WAAWI,SAAS,GACpBd,GAAGe,UAAUL,UAAAA;AAErB;;;;;;;;GAUA,eAAsBM,eAAwCC,SAK7D;CACG,MAAMC,WAAWD,QAAQE,WAAWC,YAAYH,QAAQI,YAAY;CACpE,MAAMC,aAAaL,QAAQE,WAAWI,cAAiBN,QAAQI,YAAY;CAE3E,MAAMG,eAA4BN,SAASO,WAAWX,SAAS,IAC3DI,SAASO,WAAWlB,KACfmB,WAAWA,OAAOC,QAAQpB,KAAKI,WAAWA,OAAOiB,YAAY,CAAA,IAElEV,SAASW,QACJjB,QAAQkB,UAAUA,MAAMC,YAAYD,MAAME,eAAeC,WAAWf,SAASe,MAAM,CAAA,CACnF1B,KAAKuB,UAAUA,MAAMH,QAAQpB,KAAKI,WAAWA,OAAOiB,YAAY,CAAA;CAEzE,MAAMM,cAAchB,SAASiB,eAAe5B,KAAKI,WAAWA,OAAOiB,YAAY;CAE/E,KAAK,MAAMQ,SAASZ,cAAc;EAC9B,MAAMxB,KAAKsB,WAAWe,mBAAmB,QAAA;EAEzCrC,GAAGsC,MAAM,IAAI1C,UAAU2C,UAAAA;GACnB,KAAK,MAAMC,OAAOJ,OAAO;IACrB,MAAMK,QAAQ,QAASC,OAAyBF,QAAQ;IACxD,IAAIC,UAAU,MACVF,MAAMI,SAAS,UAAUH,IAAI,SAAS;SAEtCD,MAAMI,SAAS,UAAUH,IAAI,aAAaA,OAAO,GAAG,UAAUA,QAAQC,MAAM,CAAA;GAEpF;EACJ,CAAA,CAAA;EAEA,IAAIxB,QAAQ2B,gBAAgB;GACxB,MAAMzC,WAAWc,QAAQ2B;GACzB5C,GAAG2C,SAAS,IAAI/C,UAAU2C,UAAAA;IACtB,KAAK,MAAMC,OAAON,aAAa;KAC3B,MAAMO,QAAQtC,SAASqC,QAAQ;KAC/B,IAAIC,UAAU,MACVF,MAAMI,SAAS,UAAUH,IAAI,aAAa;UAE1CD,MAAMI,SAAS,UAAUH,IAAI,cAAcA,OAAO,GAAG,UAAUA,QAAQC,MAAM,CAAA;IAErF;GACJ,CAAA,CAAA;EACJ;EAIA,IAAIC,MADiB1C,GAAG6C,OAAM,GAE1B,OAAO;CAEf;CAEA,OAAO;AACX;AAEA,SAAgBC,yBAAyBR,OAA0B;CAC/D,MAAMS,SAA8B,CAAC;CACrCC,OAAOC,QAAQX,KAAAA,CAAAA,CAAOY,SAAS,CAACV,KAAKC,WAAM;EACvC,IAAIA,UAAU,MACVM,OAAOP,OAAO1C,OAAAA;OACX,IAAIqD,MAAMC,QAAQX,KAAAA,GACrBM,OAAOP,OAAO3C,GAAG4C,KAAAA;OAEjBM,OAAOP,OAAOC;CAEtB,CAAA;CACA,OAAOM;AACX"}
1
+ {"version":3,"file":"helpers.mjs","names":["Brackets","In","IsNull","applyRealmScopeSelect","qb","alias","extraColumns","existing","Set","expressionMap","selects","map","select","selection","selections","column","filter","has","length","addSelect","isEntityUnique","options","metadata","dataSource","getMetadata","entityTarget","repository","getRepository","columnGroups","ownUniques","unique","columns","propertyName","indices","index","isUnique","entityMetadata","target","primaryKeys","primaryColumns","group","createQueryBuilder","where","inner","key","value","entity","andWhere","entityExisting","getOne","translateWhereConditions","result","Object","entries","forEach","Array","isArray"],"sources":["../../../../../src/app/modules/database/repositories/helpers.ts"],"sourcesContent":["/*\n * Copyright (c) 2025-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 type {\n DataSource, \n EntityTarget, \n ObjectLiteral, \n SelectQueryBuilder,\n} from 'typeorm';\nimport { Brackets, In, IsNull } from 'typeorm';\n\n/**\n * Force-load the columns a realm-gated `getMany` per-row check depends on.\n * rapiq honors a client `fields` projection over the adapter `default`, so a\n * projection omitting `realmId` would otherwise leave the per-row\n * `resourceRealmMatch` with no realm to match — neutralizing the realmScope\n * reach factor and leaking cross-realm rows to an own/ownOrNull-scoped reader.\n * Call it AFTER `applyQuery`. Columns already in the projection must be\n * skipped: `addSelect` emits a second identically-aliased column, and under a\n * join + take (the DISTINCT id-subquery) postgres then rejects the wrapper's\n * `ORDER BY \"<alias>_id\"` as ambiguous (mysql: duplicate column name).\n */\nexport function applyRealmScopeSelect<T extends ObjectLiteral>(\n qb: SelectQueryBuilder<T>,\n alias: string,\n extraColumns: string[] = [],\n): void {\n const existing = new Set(qb.expressionMap.selects.map((select) => select.selection));\n const selections = ['realmId', ...extraColumns]\n .map((column) => `${alias}.${column}`)\n .filter((selection) => !existing.has(selection));\n\n if (selections.length > 0) {\n qb.addSelect(selections);\n }\n}\n\n/**\n * Naming-strategy-safe replacement for typeorm-extension's `isEntityUnique`:\n * the upstream helper interpolates bare property names into the WHERE clause,\n * which no longer resolve as columns once the snake_case naming strategy\n * decouples property names (`realmId`) from column names (`realm_id`).\n * Alias-qualified property paths (`entity.realmId`) let TypeORM translate\n * them through the entity metadata instead.\n */\nexport async function isEntityUnique<T extends ObjectLiteral>(options: {\n dataSource: DataSource,\n entityTarget: EntityTarget<T>,\n entity: Partial<T>,\n entityExisting?: T | null,\n}): Promise<boolean> {\n const metadata = options.dataSource.getMetadata(options.entityTarget);\n const repository = options.dataSource.getRepository<T>(options.entityTarget);\n\n const columnGroups : string[][] = metadata.ownUniques.length > 0 ?\n metadata.ownUniques.map(\n (unique) => unique.columns.map((column) => column.propertyName),\n ) :\n metadata.indices\n .filter((index) => index.isUnique && index.entityMetadata.target === metadata.target)\n .map((index) => index.columns.map((column) => column.propertyName));\n\n const primaryKeys = metadata.primaryColumns.map((column) => column.propertyName);\n\n for (const group of columnGroups) {\n const qb = repository.createQueryBuilder('entity');\n\n qb.where(new Brackets((inner) => {\n for (const key of group) {\n const value = (options.entity as ObjectLiteral)[key] ?? null;\n if (value === null) {\n inner.andWhere(`entity.${key} IS NULL`);\n } else {\n inner.andWhere(`entity.${key} = :target_${key}`, { [`target_${key}`]: value });\n }\n }\n }));\n\n if (options.entityExisting) {\n const existing = options.entityExisting as ObjectLiteral;\n qb.andWhere(new Brackets((inner) => {\n for (const key of primaryKeys) {\n const value = existing[key] ?? null;\n if (value === null) {\n inner.andWhere(`entity.${key} IS NOT NULL`);\n } else {\n inner.andWhere(`entity.${key} != :source_${key}`, { [`source_${key}`]: value });\n }\n }\n }));\n }\n\n \n const entity = await qb.getOne();\n if (entity) {\n return false;\n }\n }\n\n return true;\n}\n\nexport function translateWhereConditions(where: Record<string, any>): Record<string, any> {\n const result: Record<string, any> = {};\n Object.entries(where).forEach(([key, value]) => {\n if (value === null) {\n result[key] = IsNull();\n } else if (Array.isArray(value)) {\n result[key] = In(value);\n } else {\n result[key] = value;\n }\n });\n return result;\n}\n"],"mappings":";;;;;;;;;;;;;;;GA0BA,SAAgBG,sBACZC,IACAC,OACAC,eAAyB,CAAA,GAAE;CAE3B,MAAMC,WAAW,IAAIC,IAAIJ,GAAGK,cAAcC,QAAQC,KAAKC,WAAWA,OAAOC,SAAS,CAAA;CAClF,MAAMC,aAAa,CAAC,WAAcR,GAAAA,YAAa,CAAA,CAC1CK,KAAKI,WAAW,GAAGV,MAAM,GAAGU,QAAQ,CAAA,CACpCC,QAAQH,cAAc,CAACN,SAASU,IAAIJ,SAAAA,CAAAA;CAEzC,IAAIC,WAAWI,SAAS,GACpBd,GAAGe,UAAUL,UAAAA;AAErB;;;;;;;;GAUA,eAAsBM,eAAwCC,SAK7D;CACG,MAAMC,WAAWD,QAAQE,WAAWC,YAAYH,QAAQI,YAAY;CACpE,MAAMC,aAAaL,QAAQE,WAAWI,cAAiBN,QAAQI,YAAY;CAE3E,MAAMG,eAA4BN,SAASO,WAAWX,SAAS,IAC3DI,SAASO,WAAWlB,KACfmB,WAAWA,OAAOC,QAAQpB,KAAKI,WAAWA,OAAOiB,YAAY,CAAA,IAElEV,SAASW,QACJjB,QAAQkB,UAAUA,MAAMC,YAAYD,MAAME,eAAeC,WAAWf,SAASe,MAAM,CAAA,CACnF1B,KAAKuB,UAAUA,MAAMH,QAAQpB,KAAKI,WAAWA,OAAOiB,YAAY,CAAA;CAEzE,MAAMM,cAAchB,SAASiB,eAAe5B,KAAKI,WAAWA,OAAOiB,YAAY;CAE/E,KAAK,MAAMQ,SAASZ,cAAc;EAC9B,MAAMxB,KAAKsB,WAAWe,mBAAmB,QAAA;EAEzCrC,GAAGsC,MAAM,IAAI1C,UAAU2C,UAAAA;GACnB,KAAK,MAAMC,OAAOJ,OAAO;IACrB,MAAMK,QAAQ,QAASC,OAAyBF,QAAQ;IACxD,IAAIC,UAAU,MACVF,MAAMI,SAAS,UAAUH,IAAI,SAAS;SAEtCD,MAAMI,SAAS,UAAUH,IAAI,aAAaA,OAAO,GAAG,UAAUA,QAAQC,MAAM,CAAA;GAEpF;EACJ,CAAA,CAAA;EAEA,IAAIxB,QAAQ2B,gBAAgB;GACxB,MAAMzC,WAAWc,QAAQ2B;GACzB5C,GAAG2C,SAAS,IAAI/C,UAAU2C,UAAAA;IACtB,KAAK,MAAMC,OAAON,aAAa;KAC3B,MAAMO,QAAQtC,SAASqC,QAAQ;KAC/B,IAAIC,UAAU,MACVF,MAAMI,SAAS,UAAUH,IAAI,aAAa;UAE1CD,MAAMI,SAAS,UAAUH,IAAI,cAAcA,OAAO,GAAG,UAAUA,QAAQC,MAAM,CAAA;IAErF;GACJ,CAAA,CAAA;EACJ;EAIA,IAAIC,MADiB1C,GAAG6C,OAAM,GAE1B,OAAO;CAEf;CAEA,OAAO;AACX;AAEA,SAAgBC,yBAAyBR,OAA0B;CAC/D,MAAMS,SAA8B,CAAC;CACrCC,OAAOC,QAAQX,KAAAA,CAAAA,CAAOY,SAAS,CAACV,KAAKC,WAAM;EACvC,IAAIA,UAAU,MACVM,OAAOP,OAAO1C,OAAAA;OACX,IAAIqD,MAAMC,QAAQX,KAAAA,GACrBM,OAAOP,OAAO3C,GAAG4C,KAAAA;OAEjBM,OAAOP,OAAOC;CAEtB,CAAA;CACA,OAAOM;AACX"}
@@ -1 +1 @@
1
- {"version":3,"file":"module.mjs","names":["aggregatePermissionPolicyBindings","buildPermissionKey","buildCacheKey","IsNull","CachePrefix","PermissionEntity","PermissionPolicyEntity","PolicyRepository","PermissionDatabaseProvider","dataSource","repository","permissionPolicyRepository","policyRepository","getRepository","findOne","options","where","name","clientId","realmId","entity","cache","id","prefix","PERMISSION","key","milliseconds","junctions","find","permissionId","relations","policy","policies","junction","tree","findDescendantsTree","push","aggregated","permission","length","undefined"],"sources":["../../../../../../src/app/modules/database/repositories/permission-provider/module.ts"],"sourcesContent":["/*\n * Copyright (c) 2024.\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 type {\n BasePolicy,\n IPermissionProvider,\n PermissionGetOptions,\n PermissionPolicyBindingAggregated,\n} from '@authup/access';\nimport {\n aggregatePermissionPolicyBindings,\n buildPermissionKey,\n} from '@authup/access';\nimport { buildCacheKey } from '@authup/server-kit';\nimport type { DataSource, FindOptionsWhere, Repository } from 'typeorm';\nimport { IsNull } from 'typeorm';\nimport {\n CachePrefix,\n PermissionEntity,\n PermissionPolicyEntity,\n PolicyRepository,\n} from '../../../../../adapters/database/domains/index.ts';\n\nexport class PermissionDatabaseProvider implements IPermissionProvider {\n protected dataSource: DataSource;\n\n protected repository : Repository<PermissionEntity>;\n\n protected permissionPolicyRepository : Repository<PermissionPolicyEntity>;\n\n protected policyRepository: PolicyRepository;\n\n constructor(dataSource: DataSource) {\n this.dataSource = dataSource;\n this.repository = this.dataSource.getRepository(PermissionEntity);\n this.permissionPolicyRepository = this.dataSource.getRepository(PermissionPolicyEntity);\n this.policyRepository = new PolicyRepository(this.dataSource);\n }\n\n async findOne(options: PermissionGetOptions) : Promise<PermissionPolicyBindingAggregated | null> {\n const where : FindOptionsWhere<PermissionEntity> = { name: options.name };\n\n if (typeof options.clientId !== 'undefined') {\n where.clientId = options.clientId === null ? IsNull() : options.clientId;\n }\n\n if (typeof options.realmId !== 'undefined') {\n where.realmId = options.realmId === null ? IsNull() : options.realmId;\n }\n\n const entity = await this.repository.findOne({\n where,\n cache: {\n id: buildCacheKey({\n prefix: CachePrefix.PERMISSION,\n key: buildPermissionKey({\n name: options.name,\n clientId: options.clientId,\n realmId: options.realmId,\n }),\n }),\n milliseconds: 60_000,\n },\n });\n\n if (entity) {\n const junctions = await this.permissionPolicyRepository.find({\n where: { permissionId: entity.id },\n relations: { policy: true },\n });\n\n const policies : BasePolicy[] = [];\n for (const junction of junctions) {\n if (junction.policy) {\n const tree = await this.policyRepository.findDescendantsTree(junction.policy);\n if (tree) {\n policies.push(tree);\n }\n }\n }\n\n const [aggregated] = aggregatePermissionPolicyBindings([\n {\n permission: entity,\n policies: policies.length > 0 ? policies : undefined,\n },\n ]);\n\n return aggregated ?? null;\n }\n\n return null;\n }\n}\n"],"mappings":";;;;;;;;;;;;AA2BA,IAAaQ,6BAAb,MAAaA;CACCC;CAEAC;CAEAC;CAEAC;CAEV,YAAYH,YAAwB;EAChC,KAAKA,aAAaA;EAClB,KAAKC,aAAa,KAAKD,WAAWI,cAAcR,gBAAAA;EAChD,KAAKM,6BAA6B,KAAKF,WAAWI,cAAcP,sBAAAA;EAChE,KAAKM,mBAAmB,IAAIL,iBAAiB,KAAKE,UAAU;CAChE;CAEA,MAAMK,QAAQC,SAAmF;EAC7F,MAAMC,QAA6C,EAAEC,MAAMF,QAAQE,KAAK;EAExE,IAAI,OAAOF,QAAQG,aAAa,aAC5BF,MAAME,WAAWH,QAAQG,aAAa,OAAOf,OAAAA,IAAWY,QAAQG;EAGpE,IAAI,OAAOH,QAAQI,YAAY,aAC3BH,MAAMG,UAAUJ,QAAQI,YAAY,OAAOhB,OAAAA,IAAWY,QAAQI;EAGlE,MAAMC,SAAS,MAAM,KAAKV,WAAWI,QAAQ;GACzCE;GACAK,OAAO;IACHC,IAAIpB,cAAc;KACdqB,QAAQnB,YAAYoB;KACpBC,KAAKxB,mBAAmB;MACpBgB,MAAMF,QAAQE;MACdC,UAAUH,QAAQG;MAClBC,SAASJ,QAAQI;KACrB,CAAA;IACJ,CAAA;IACAO,cAAc;GAClB;EACJ,CAAA;EAEA,IAAIN,QAAQ;GACR,MAAMO,YAAY,MAAM,KAAKhB,2BAA2BiB,KAAK;IACzDZ,OAAO,EAAEa,cAAcT,OAAOE,GAAG;IACjCQ,WAAW,EAAEC,QAAQ,KAAK;GAC9B,CAAA;GAEA,MAAMC,WAA0B,CAAA;GAChC,KAAK,MAAMC,YAAYN,WACnB,IAAIM,SAASF,QAAQ;IACjB,MAAMG,OAAO,MAAM,KAAKtB,iBAAiBuB,oBAAoBF,SAASF,MAAM;IAC5E,IAAIG,MACAF,SAASI,KAAKF,IAAAA;GAEtB;GAGJ,MAAM,CAACG,cAAcrC,kCAAkC,CACnD;IACIsC,YAAYlB;IACZY,UAAUA,SAASO,SAAS,IAAIP,WAAWQ,KAAAA;GAC/C,CAAA,CACH;GAED,OAAOH,cAAc;EACzB;EAEA,OAAO;CACX;AACJ"}
1
+ {"version":3,"file":"module.mjs","names":["aggregatePermissionPolicyBindings","buildPermissionKey","buildCacheKey","IsNull","CachePrefix","PermissionEntity","PermissionPolicyEntity","PolicyRepository","PermissionDatabaseProvider","dataSource","repository","permissionPolicyRepository","policyRepository","getRepository","findOne","options","where","name","clientId","realmId","entity","cache","id","prefix","PERMISSION","key","milliseconds","junctions","find","permissionId","relations","policy","policies","junction","tree","findDescendantsTree","push","aggregated","permission","length","undefined"],"sources":["../../../../../../src/app/modules/database/repositories/permission-provider/module.ts"],"sourcesContent":["/*\n * Copyright (c) 2024.\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 type {\n BasePolicy,\n IPermissionProvider,\n PermissionGetOptions,\n PermissionPolicyBindingAggregated,\n} from '@authup/access';\nimport {\n aggregatePermissionPolicyBindings,\n buildPermissionKey,\n} from '@authup/access';\nimport { buildCacheKey } from '@authup/server-kit';\nimport type { DataSource, FindOptionsWhere, Repository } from 'typeorm';\nimport { IsNull } from 'typeorm';\nimport {\n CachePrefix,\n PermissionEntity,\n PermissionPolicyEntity,\n PolicyRepository,\n} from '../../../../../adapters/database/domains/index.ts';\n\nexport class PermissionDatabaseProvider implements IPermissionProvider {\n protected dataSource: DataSource;\n\n protected repository : Repository<PermissionEntity>;\n\n protected permissionPolicyRepository : Repository<PermissionPolicyEntity>;\n\n protected policyRepository: PolicyRepository;\n\n constructor(dataSource: DataSource) {\n this.dataSource = dataSource;\n this.repository = this.dataSource.getRepository(PermissionEntity);\n this.permissionPolicyRepository = this.dataSource.getRepository(PermissionPolicyEntity);\n this.policyRepository = new PolicyRepository(this.dataSource);\n }\n\n async findOne(options: PermissionGetOptions) : Promise<PermissionPolicyBindingAggregated | null> {\n const where : FindOptionsWhere<PermissionEntity> = { name: options.name };\n\n if (typeof options.clientId !== 'undefined') {\n where.clientId = options.clientId === null ? IsNull() : options.clientId;\n }\n\n if (typeof options.realmId !== 'undefined') {\n where.realmId = options.realmId === null ? IsNull() : options.realmId;\n }\n\n const entity = await this.repository.findOne({\n where,\n cache: {\n id: buildCacheKey({\n prefix: CachePrefix.PERMISSION,\n key: buildPermissionKey({\n name: options.name,\n clientId: options.clientId,\n realmId: options.realmId,\n }),\n }),\n milliseconds: 60_000,\n },\n });\n\n if (entity) {\n const junctions = await this.permissionPolicyRepository.find({\n where: { permissionId: entity.id },\n relations: { policy: true },\n });\n\n const policies : BasePolicy[] = [];\n for (const junction of junctions) {\n if (junction.policy) {\n const tree = await this.policyRepository.findDescendantsTree(junction.policy);\n if (tree) {\n policies.push(tree);\n }\n }\n }\n\n const [aggregated] = aggregatePermissionPolicyBindings([\n {\n permission: entity,\n policies: policies.length > 0 ? policies : undefined,\n },\n ]);\n\n return aggregated ?? null;\n }\n\n return null;\n }\n}\n"],"mappings":";;;;;;;;;;;;AA2BA,IAAaQ,6BAAb,MAAaA;CACCC;CAEAC;CAEAC;CAEAC;CAEV,YAAYH,YAAwB;EAChC,KAAKA,aAAaA;EAClB,KAAKC,aAAa,KAAKD,WAAWI,cAAcR,gBAAAA;EAChD,KAAKM,6BAA6B,KAAKF,WAAWI,cAAcP,sBAAAA;EAChE,KAAKM,mBAAmB,IAAIL,iBAAiB,KAAKE,UAAU;CAChE;CAEA,MAAMK,QAAQC,SAAmF;EAC7F,MAAMC,QAA6C,EAAEC,MAAMF,QAAQE,KAAK;EAExE,IAAI,OAAOF,QAAQG,aAAa,aAC5BF,MAAME,WAAWH,QAAQG,aAAa,OAAOf,OAAAA,IAAWY,QAAQG;EAGpE,IAAI,OAAOH,QAAQI,YAAY,aAC3BH,MAAMG,UAAUJ,QAAQI,YAAY,OAAOhB,OAAAA,IAAWY,QAAQI;EAGlE,MAAMC,SAAS,MAAM,KAAKV,WAAWI,QAAQ;GACzCE;GACAK,OAAO;IACHC,IAAIpB,cAAc;KACdqB,QAAQnB,YAAYoB;KACpBC,KAAKxB,mBAAmB;MACpBgB,MAAMF,QAAQE;MACdC,UAAUH,QAAQG;MAClBC,SAASJ,QAAQI;KACrB,CAAA;IACJ,CAAA;IACAO,cAAc;GAClB;EACJ,CAAA;EAEA,IAAIN,QAAQ;GACR,MAAMO,YAAY,MAAM,KAAKhB,2BAA2BiB,KAAK;IACzDZ,OAAO,EAAEa,cAAcT,OAAOE,GAAG;IACjCQ,WAAW,EAAEC,QAAQ,KAAK;GAC9B,CAAA;GAEA,MAAMC,WAA0B,CAAA;GAChC,KAAK,MAAMC,YAAYN,WACnB,IAAIM,SAASF,QAAQ;IACjB,MAAMG,OAAO,MAAM,KAAKtB,iBAAiBuB,oBAAoBF,SAASF,MAAM;IAC5E,IAAIG,MACAF,SAASI,KAAKF,IAAAA;GAEtB;GAGJ,MAAM,CAACG,cAAcrC,kCAAkC,CACnD;IACIsC,YAAYlB;IACZY,UAAUA,SAASO,SAAS,IAAIP,WAAWQ,KAAAA;GAC/C,CACH,CAAA;GAED,OAAOH,cAAc;EACzB;EAEA,OAAO;CACX;AACJ"}